mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
Merge pull request #2303 from proddy/dev
show ntp time in status, use useInterval everywhere instead of alova'…
This commit is contained in:
@@ -35,7 +35,7 @@
|
|||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-icons": "^5.4.0",
|
"react-icons": "^5.4.0",
|
||||||
"react-router": "^7.0.2",
|
"react-router": "^7.1.0",
|
||||||
"react-toastify": "^11.0.2",
|
"react-toastify": "^11.0.2",
|
||||||
"typesafe-i18n": "^5.26.2",
|
"typesafe-i18n": "^5.26.2",
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const CustomEntities = () => {
|
|||||||
if (!dialogOpen && !numChanges) {
|
if (!dialogOpen && !numChanges) {
|
||||||
void fetchEntities();
|
void fetchEntities();
|
||||||
}
|
}
|
||||||
}, 3000);
|
});
|
||||||
|
|
||||||
const { send: writeEntities } = useRequest(
|
const { send: writeEntities } = useRequest(
|
||||||
(data: Entities) => writeCustomEntities(data),
|
(data: Entities) => writeCustomEntities(data),
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ const Dashboard = () => {
|
|||||||
if (!deviceValueDialogOpen) {
|
if (!deviceValueDialogOpen) {
|
||||||
void fetchDashboard();
|
void fetchDashboard();
|
||||||
}
|
}
|
||||||
}, 3000);
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
showAll
|
showAll
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ const Devices = () => {
|
|||||||
if (!deviceValueDialogOpen) {
|
if (!deviceValueDialogOpen) {
|
||||||
selectedDevice ? void sendDeviceData(selectedDevice) : void sendCoreData();
|
selectedDevice ? void sendDeviceData(selectedDevice) : void sendCoreData();
|
||||||
}
|
}
|
||||||
}, 3000);
|
});
|
||||||
|
|
||||||
const deviceValueDialogSave = async (devicevalue: DeviceValue) => {
|
const deviceValueDialogSave = async (devicevalue: DeviceValue) => {
|
||||||
const id = Number(device_select.state.id);
|
const id = Number(device_select.state.id);
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ const Sensors = () => {
|
|||||||
if (!temperatureDialogOpen && !analogDialogOpen) {
|
if (!temperatureDialogOpen && !analogDialogOpen) {
|
||||||
void fetchSensorData();
|
void fetchSensorData();
|
||||||
}
|
}
|
||||||
}, 3000);
|
});
|
||||||
|
|
||||||
const common_theme = useTheme({
|
const common_theme = useTheme({
|
||||||
BaseRow: `
|
BaseRow: `
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ import type { Theme } from '@mui/material';
|
|||||||
|
|
||||||
import * as APApi from 'api/ap';
|
import * as APApi from 'api/ap';
|
||||||
|
|
||||||
import { useAutoRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { APStatusType } from 'types';
|
import type { APStatusType } from 'types';
|
||||||
import { APNetworkStatus } from 'types';
|
import { APNetworkStatus } from 'types';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
|
||||||
export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => {
|
export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@@ -34,11 +35,11 @@ export const apStatusHighlight = ({ status }: APStatusType, theme: Theme) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const APStatus = () => {
|
const APStatus = () => {
|
||||||
const {
|
const { data, send: loadData, error } = useRequest(APApi.readAPStatus);
|
||||||
data,
|
|
||||||
send: loadData,
|
useInterval(() => {
|
||||||
error
|
void loadData();
|
||||||
} = useAutoRequest(APApi.readAPStatus, { pollingTime: 3000 });
|
});
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.ACCESS_POINT(0));
|
useLayoutTitle(LL.ACCESS_POINT(0));
|
||||||
|
|||||||
@@ -8,20 +8,21 @@ import {
|
|||||||
Table
|
Table
|
||||||
} from '@table-library/react-table-library/table';
|
} from '@table-library/react-table-library/table';
|
||||||
import { useTheme as tableTheme } from '@table-library/react-table-library/theme';
|
import { useTheme as tableTheme } from '@table-library/react-table-library/theme';
|
||||||
import { useAutoRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { Translation } from 'i18n/i18n-types';
|
import type { Translation } from 'i18n/i18n-types';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
|
||||||
import { readActivity } from '../../api/app';
|
import { readActivity } from '../../api/app';
|
||||||
import type { Stat } from '../main/types';
|
import type { Stat } from '../main/types';
|
||||||
|
|
||||||
const SystemActivity = () => {
|
const SystemActivity = () => {
|
||||||
const {
|
const { data, send: loadData, error } = useRequest(readActivity);
|
||||||
data,
|
|
||||||
send: loadData,
|
useInterval(() => {
|
||||||
error
|
void loadData();
|
||||||
} = useAutoRequest(readActivity, { pollingTime: 3000 });
|
});
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,10 @@ import {
|
|||||||
|
|
||||||
import * as SystemApi from 'api/system';
|
import * as SystemApi from 'api/system';
|
||||||
|
|
||||||
import { useAutoRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
|
||||||
import BBQKeesIcon from './bbqkees.svg';
|
import BBQKeesIcon from './bbqkees.svg';
|
||||||
|
|
||||||
@@ -32,11 +33,11 @@ const HardwareStatus = () => {
|
|||||||
|
|
||||||
useLayoutTitle(LL.HARDWARE());
|
useLayoutTitle(LL.HARDWARE());
|
||||||
|
|
||||||
const {
|
const { data, send: loadData, error } = useRequest(SystemApi.readSystemStatus);
|
||||||
data,
|
|
||||||
send: loadData,
|
useInterval(() => {
|
||||||
error
|
void loadData();
|
||||||
} = useAutoRequest(SystemApi.readSystemStatus, { pollingTime: 3000 });
|
});
|
||||||
|
|
||||||
const content = () => {
|
const content = () => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
|||||||
@@ -15,11 +15,12 @@ import type { Theme } from '@mui/material';
|
|||||||
|
|
||||||
import * as MqttApi from 'api/mqtt';
|
import * as MqttApi from 'api/mqtt';
|
||||||
|
|
||||||
import { useAutoRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { MqttStatusType } from 'types';
|
import type { MqttStatusType } from 'types';
|
||||||
import { MqttDisconnectReason } from 'types';
|
import { MqttDisconnectReason } from 'types';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
|
||||||
export const mqttStatusHighlight = (
|
export const mqttStatusHighlight = (
|
||||||
{ enabled, connected }: MqttStatusType,
|
{ enabled, connected }: MqttStatusType,
|
||||||
@@ -54,11 +55,11 @@ export const mqttQueueHighlight = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const MqttStatus = () => {
|
const MqttStatus = () => {
|
||||||
const {
|
const { data, send: loadData, error } = useRequest(MqttApi.readMqttStatus);
|
||||||
data,
|
|
||||||
send: loadData,
|
useInterval(() => {
|
||||||
error
|
void loadData();
|
||||||
} = useAutoRequest(MqttApi.readMqttStatus, { pollingTime: 3000 });
|
});
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle('MQTT');
|
useLayoutTitle('MQTT');
|
||||||
|
|||||||
@@ -28,19 +28,20 @@ import type { Theme } from '@mui/material';
|
|||||||
import * as NTPApi from 'api/ntp';
|
import * as NTPApi from 'api/ntp';
|
||||||
|
|
||||||
import { dialogStyle } from 'CustomTheme';
|
import { dialogStyle } from 'CustomTheme';
|
||||||
import { useAutoRequest, useRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { NTPStatusType, Time } from 'types';
|
import type { NTPStatusType, Time } from 'types';
|
||||||
import { NTPSyncStatus } from 'types';
|
import { NTPSyncStatus } from 'types';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
import { formatDateTime, formatLocalDateTime } from 'utils';
|
import { formatDateTime, formatLocalDateTime } from 'utils';
|
||||||
|
|
||||||
const NTPStatus = () => {
|
const NTPStatus = () => {
|
||||||
const {
|
const { data, send: loadData, error } = useRequest(NTPApi.readNTPStatus);
|
||||||
data,
|
|
||||||
send: loadData,
|
useInterval(() => {
|
||||||
error
|
void loadData();
|
||||||
} = useAutoRequest(NTPApi.readNTPStatus, { pollingTime: 3000 });
|
});
|
||||||
|
|
||||||
const [localTime, setLocalTime] = useState<string>('');
|
const [localTime, setLocalTime] = useState<string>('');
|
||||||
const [settingTime, setSettingTime] = useState<boolean>(false);
|
const [settingTime, setSettingTime] = useState<boolean>(false);
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ import type { Theme } from '@mui/material';
|
|||||||
|
|
||||||
import * as NetworkApi from 'api/network';
|
import * as NetworkApi from 'api/network';
|
||||||
|
|
||||||
import { useAutoRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import type { NetworkStatusType } from 'types';
|
import type { NetworkStatusType } from 'types';
|
||||||
import { NetworkConnectionStatus } from 'types';
|
import { NetworkConnectionStatus } from 'types';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
|
||||||
const isConnected = ({ status }: NetworkStatusType) =>
|
const isConnected = ({ status }: NetworkStatusType) =>
|
||||||
status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED ||
|
status === NetworkConnectionStatus.WIFI_STATUS_CONNECTED ||
|
||||||
@@ -81,11 +82,11 @@ const IPs = (status: NetworkStatusType) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const NetworkStatus = () => {
|
const NetworkStatus = () => {
|
||||||
const {
|
const { data, send: loadData, error } = useRequest(NetworkApi.readNetworkStatus);
|
||||||
data,
|
|
||||||
send: loadData,
|
useInterval(() => {
|
||||||
error
|
void loadData();
|
||||||
} = useAutoRequest(NetworkApi.readNetworkStatus, { pollingTime: 3000 });
|
});
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
useLayoutTitle(LL.NETWORK(1));
|
useLayoutTitle(LL.NETWORK(1));
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ import {
|
|||||||
import { readSystemStatus } from 'api/system';
|
import { readSystemStatus } from 'api/system';
|
||||||
|
|
||||||
import { dialogStyle } from 'CustomTheme';
|
import { dialogStyle } from 'CustomTheme';
|
||||||
import { useAutoRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import MessageBox from 'components/MessageBox';
|
import MessageBox from 'components/MessageBox';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
|
||||||
const RestartMonitor = () => {
|
const RestartMonitor = () => {
|
||||||
const [errorMessage, setErrorMessage] = useState<string>();
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
@@ -22,8 +23,7 @@ const RestartMonitor = () => {
|
|||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
const { data } = useAutoRequest(readSystemStatus, {
|
const { data, send } = useRequest(readSystemStatus, {
|
||||||
pollingTime: 1000,
|
|
||||||
force: true,
|
force: true,
|
||||||
initialData: { status: 'Getting ready...' },
|
initialData: { status: 'Getting ready...' },
|
||||||
async middleware(_, next) {
|
async middleware(_, next) {
|
||||||
@@ -42,6 +42,10 @@ const RestartMonitor = () => {
|
|||||||
setErrorMessage(error.message);
|
setErrorMessage(error.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useInterval(() => {
|
||||||
|
void send();
|
||||||
|
}, 1000); // check every second
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog fullWidth={true} sx={dialogStyle} open={true}>
|
<Dialog fullWidth={true} sx={dialogStyle} open={true}>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
|
|||||||
@@ -30,13 +30,15 @@ import { API } from 'api/app';
|
|||||||
import { readSystemStatus } from 'api/system';
|
import { readSystemStatus } from 'api/system';
|
||||||
|
|
||||||
import { dialogStyle } from 'CustomTheme';
|
import { dialogStyle } from 'CustomTheme';
|
||||||
import { useAutoRequest, useRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { type APIcall, busConnectionStatus } from 'app/main/types';
|
import { type APIcall, busConnectionStatus } from 'app/main/types';
|
||||||
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
import { FormLoader, SectionContent, useLayoutTitle } from 'components';
|
||||||
import ListMenuItem from 'components/layout/ListMenuItem';
|
import ListMenuItem from 'components/layout/ListMenuItem';
|
||||||
import { AuthenticatedContext } from 'contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { NTPSyncStatus, NetworkConnectionStatus } from 'types';
|
import { NTPSyncStatus, NetworkConnectionStatus } from 'types';
|
||||||
|
import { useInterval } from 'utils';
|
||||||
|
import { formatDateTime } from 'utils/time';
|
||||||
|
|
||||||
import RestartMonitor from './RestartMonitor';
|
import RestartMonitor from './RestartMonitor';
|
||||||
|
|
||||||
@@ -58,9 +60,8 @@ const SystemStatus = () => {
|
|||||||
data,
|
data,
|
||||||
send: loadData,
|
send: loadData,
|
||||||
error
|
error
|
||||||
} = useAutoRequest(readSystemStatus, {
|
} = useRequest(readSystemStatus, {
|
||||||
initialData: [],
|
initialData: [],
|
||||||
pollingTime: 3000,
|
|
||||||
async middleware(_, next) {
|
async middleware(_, next) {
|
||||||
if (!restarting) {
|
if (!restarting) {
|
||||||
await next();
|
await next();
|
||||||
@@ -68,6 +69,10 @@ const SystemStatus = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useInterval(() => {
|
||||||
|
void loadData();
|
||||||
|
});
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const formatDurationSec = (duration_sec: number) => {
|
const formatDurationSec = (duration_sec: number) => {
|
||||||
@@ -134,7 +139,7 @@ const SystemStatus = () => {
|
|||||||
case NTPSyncStatus.NTP_INACTIVE:
|
case NTPSyncStatus.NTP_INACTIVE:
|
||||||
return LL.INACTIVE(0);
|
return LL.INACTIVE(0);
|
||||||
case NTPSyncStatus.NTP_ACTIVE:
|
case NTPSyncStatus.NTP_ACTIVE:
|
||||||
return LL.ACTIVE();
|
return LL.ACTIVE() + ' (' + formatDateTime(data.ntp_time ?? '') + ')';
|
||||||
default:
|
default:
|
||||||
return LL.UNKNOWN();
|
return LL.UNKNOWN();
|
||||||
}
|
}
|
||||||
@@ -301,7 +306,7 @@ const SystemStatus = () => {
|
|||||||
icon={DeviceHubIcon}
|
icon={DeviceHubIcon}
|
||||||
bgcolor={activeHighlight(data.mqtt_status)}
|
bgcolor={activeHighlight(data.mqtt_status)}
|
||||||
label="MQTT"
|
label="MQTT"
|
||||||
text={data.mqtt_status ? LL.ACTIVE() : LL.INACTIVE(0)}
|
text={data.mqtt_status ? LL.CONNECTED(0) : LL.INACTIVE(0)}
|
||||||
to="/status/mqtt"
|
to="/status/mqtt"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface SystemStatus {
|
|||||||
num_sensors: number;
|
num_sensors: number;
|
||||||
num_analogs: number;
|
num_analogs: number;
|
||||||
ntp_status: number;
|
ntp_status: number;
|
||||||
|
ntp_time?: string;
|
||||||
mqtt_status: boolean;
|
mqtt_status: boolean;
|
||||||
ap_status: boolean;
|
ap_status: boolean;
|
||||||
network_status: NetworkConnectionStatus;
|
network_status: NetworkConnectionStatus;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
const DEFAULT_DELAY = 3000;
|
||||||
|
|
||||||
// adapted from https://www.joshwcomeau.com/snippets/react-hooks/use-interval/
|
// adapted from https://www.joshwcomeau.com/snippets/react-hooks/use-interval/
|
||||||
export const useInterval = (callback: () => void, delay: number) => {
|
export const useInterval = (callback: () => void, delay: number = DEFAULT_DELAY) => {
|
||||||
const intervalRef = useRef<number | null>(null);
|
const intervalRef = useRef<number | null>(null);
|
||||||
const savedCallback = useRef<() => void>(callback);
|
const savedCallback = useRef<() => void>(callback);
|
||||||
|
|
||||||
@@ -11,14 +13,12 @@ export const useInterval = (callback: () => void, delay: number) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const tick = () => savedCallback.current();
|
const tick = () => savedCallback.current();
|
||||||
if (typeof delay === 'number') {
|
intervalRef.current = window.setInterval(tick, delay);
|
||||||
intervalRef.current = window.setInterval(tick, delay);
|
return () => {
|
||||||
return () => {
|
if (intervalRef.current !== null) {
|
||||||
if (intervalRef.current !== null) {
|
window.clearInterval(intervalRef.current);
|
||||||
window.clearInterval(intervalRef.current);
|
}
|
||||||
}
|
};
|
||||||
};
|
|
||||||
}
|
|
||||||
}, [delay]);
|
}, [delay]);
|
||||||
|
|
||||||
return intervalRef;
|
return intervalRef;
|
||||||
|
|||||||
@@ -1607,7 +1607,7 @@ __metadata:
|
|||||||
react: "npm:^19.0.0"
|
react: "npm:^19.0.0"
|
||||||
react-dom: "npm:^19.0.0"
|
react-dom: "npm:^19.0.0"
|
||||||
react-icons: "npm:^5.4.0"
|
react-icons: "npm:^5.4.0"
|
||||||
react-router: "npm:^7.0.2"
|
react-router: "npm:^7.1.0"
|
||||||
react-toastify: "npm:^11.0.2"
|
react-toastify: "npm:^11.0.2"
|
||||||
rollup-plugin-visualizer: "npm:^5.12.0"
|
rollup-plugin-visualizer: "npm:^5.12.0"
|
||||||
terser: "npm:^5.37.0"
|
terser: "npm:^5.37.0"
|
||||||
@@ -5589,9 +5589,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"react-router@npm:^7.0.2":
|
"react-router@npm:^7.1.0":
|
||||||
version: 7.0.2
|
version: 7.1.0
|
||||||
resolution: "react-router@npm:7.0.2"
|
resolution: "react-router@npm:7.1.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/cookie": "npm:^0.6.0"
|
"@types/cookie": "npm:^0.6.0"
|
||||||
cookie: "npm:^1.0.1"
|
cookie: "npm:^1.0.1"
|
||||||
@@ -5603,7 +5603,7 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
react-dom:
|
react-dom:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 10c0/f6c04939218a3d7f2b03b215c2299eab4dbb0dea4a16e0acfd8bf181ec69ff42d66abdba10a25cc3297c514f052a0d03bfb80431225eb763bb27e4e5b0b4a106
|
checksum: 10c0/c4f4c76dc885cb2b351575052417f0a95ad454ae7cc27f42e5dcde993697b206eab9f5eb3f9a3acb1284331d41f8667bd4d10e246d463c3debd7d4de3edaa50b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ let system_status = {
|
|||||||
num_analogs: 1,
|
num_analogs: 1,
|
||||||
free_heap: 143,
|
free_heap: 143,
|
||||||
ntp_status: 2,
|
ntp_status: 2,
|
||||||
|
ntp_time: '2021-04-01T14:25:42Z',
|
||||||
mqtt_status: true,
|
mqtt_status: true,
|
||||||
ap_status: false,
|
ap_status: false,
|
||||||
network_status: 3, // wifi connected
|
network_status: 3, // wifi connected
|
||||||
|
|||||||
Reference in New Issue
Block a user