import { type FC, useContext, useState } from 'react'; import { toast } from 'react-toastify'; import AccessTimeIcon from '@mui/icons-material/AccessTime'; import BuildIcon from '@mui/icons-material/Build'; import CancelIcon from '@mui/icons-material/Cancel'; import DeviceHubIcon from '@mui/icons-material/DeviceHub'; import DirectionsBusIcon from '@mui/icons-material/DirectionsBus'; import MemoryIcon from '@mui/icons-material/Memory'; import PermScanWifiIcon from '@mui/icons-material/PermScanWifi'; import RefreshIcon from '@mui/icons-material/Refresh'; import SettingsInputAntennaIcon from '@mui/icons-material/SettingsInputAntenna'; import TimerIcon from '@mui/icons-material/Timer'; import { Avatar, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Divider, List, ListItem, ListItemAvatar, ListItemText, useTheme } from '@mui/material'; import * as SystemApi from 'api/system'; import * as EMSESP from 'project/api'; import { dialogStyle } from 'CustomTheme'; import { useRequest } from 'alova'; import { FormLoader, SectionContent, useLayoutTitle } from 'components'; import ListMenuItem from 'components/layout/ListMenuItem'; import { AuthenticatedContext } from 'contexts/authentication'; import { useI18nContext } from 'i18n/i18n-react'; import { busConnectionStatus } from 'project/types'; import { NTPSyncStatus } from 'types'; const SystemStatus: FC = () => { const { LL } = useI18nContext(); useLayoutTitle(LL.STATUS_OF('')); const { me } = useContext(AuthenticatedContext); const [confirmScan, setConfirmScan] = useState(false); const { data: data, send: loadData, error } = useRequest(SystemApi.readSystemStatus, { force: true }); const { send: scanDevices } = useRequest(EMSESP.scanDevices, { immediate: false }); const theme = useTheme(); const formatDurationSec = (duration_sec: number) => { const days = Math.trunc((duration_sec * 1000) / 86400000); const hours = Math.trunc((duration_sec * 1000) / 3600000) % 24; const minutes = Math.trunc((duration_sec * 1000) / 60000) % 60; const seconds = Math.trunc((duration_sec * 1000) / 1000) % 60; let formatted = ''; if (days) { formatted += LL.NUM_DAYS({ num: days }) + ' '; } if (hours) { formatted += LL.NUM_HOURS({ num: hours }) + ' '; } if (minutes) { formatted += LL.NUM_MINUTES({ num: minutes }) + ' '; } formatted += LL.NUM_SECONDS({ num: seconds }); return formatted; }; function formatNumber(num: number) { return new Intl.NumberFormat().format(num); } const busStatus = () => { if (data) { switch (data.status) { case busConnectionStatus.BUS_STATUS_CONNECTED: return LL.CONNECTED(0) + ' (' + formatDurationSec(data.bus_uptime) + ')'; case busConnectionStatus.BUS_STATUS_TX_ERRORS: return LL.TX_ISSUES(); case busConnectionStatus.BUS_STATUS_OFFLINE: return LL.DISCONNECTED(); } } return 'Unknown'; }; const busStatusHighlight = () => { switch (data.status) { case busConnectionStatus.BUS_STATUS_TX_ERRORS: return theme.palette.warning.main; case busConnectionStatus.BUS_STATUS_CONNECTED: return theme.palette.success.main; case busConnectionStatus.BUS_STATUS_OFFLINE: return theme.palette.error.main; default: return theme.palette.warning.main; } }; const ntpStatus = () => { switch (data.ntp_status) { case NTPSyncStatus.NTP_DISABLED: return LL.NOT_ENABLED(); case NTPSyncStatus.NTP_INACTIVE: return LL.INACTIVE(0); case NTPSyncStatus.NTP_ACTIVE: return LL.ACTIVE(); default: return LL.UNKNOWN(); } }; const ntpStatusHighlight = () => { switch (data.ntp_status) { case NTPSyncStatus.NTP_DISABLED: return theme.palette.info.main; case NTPSyncStatus.NTP_INACTIVE: return theme.palette.error.main; case NTPSyncStatus.NTP_ACTIVE: return theme.palette.success.main; default: return theme.palette.error.main; } }; const activeHighlight = (value: boolean) => value ? theme.palette.success.main : theme.palette.info.main; const scan = async () => { await scanDevices() .then(() => { toast.info(LL.SCANNING() + '...'); }) .catch((error: Error) => { toast.error(error.message); }); setConfirmScan(false); }; const renderScanDialog = () => ( setConfirmScan(false)} > {LL.SCAN_DEVICES()} {LL.EMS_SCAN()} ); const content = () => { if (!data) { return ; } return ( <> {me.admin && ( )} {renderScanDialog()} ); }; return {content()}; }; export default SystemStatus;