mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
update #6
This commit is contained in:
@@ -23,14 +23,14 @@
|
|||||||
"@emotion/react": "^11.11.1",
|
"@emotion/react": "^11.11.1",
|
||||||
"@emotion/styled": "^11.11.0",
|
"@emotion/styled": "^11.11.0",
|
||||||
"@mui/icons-material": "^5.11.16",
|
"@mui/icons-material": "^5.11.16",
|
||||||
"@mui/material": "^5.13.4",
|
"@mui/material": "^5.13.5",
|
||||||
"@table-library/react-table-library": "4.1.4",
|
"@table-library/react-table-library": "4.1.4",
|
||||||
"@types/lodash-es": "^4.17.7",
|
"@types/lodash-es": "^4.17.7",
|
||||||
"@types/node": "^20.3.0",
|
"@types/node": "^20.3.1",
|
||||||
"@types/react": "^18.2.11",
|
"@types/react": "^18.2.12",
|
||||||
"@types/react-dom": "^18.2.4",
|
"@types/react-dom": "^18.2.5",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"alova": "^2.6.0",
|
"alova": "^2.6.1",
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"history": "^5.3.0",
|
"history": "^5.3.0",
|
||||||
@@ -47,8 +47,8 @@
|
|||||||
"typescript": "^5.1.3"
|
"typescript": "^5.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||||
"@typescript-eslint/parser": "^5.59.9",
|
"@typescript-eslint/parser": "^5.59.11",
|
||||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||||
"eslint": "^8.42.0",
|
"eslint": "^8.42.0",
|
||||||
"eslint-config-airbnb": "^19.0.4",
|
"eslint-config-airbnb": "^19.0.4",
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"rollup-plugin-visualizer": "^5.9.2",
|
"rollup-plugin-visualizer": "^5.9.2",
|
||||||
"terser": "^5.17.7",
|
"terser": "^5.18.0",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"vite-plugin-svgr": "^3.2.0",
|
"vite-plugin-svgr": "^3.2.0",
|
||||||
"vite-tsconfig-paths": "^4.2.0"
|
"vite-tsconfig-paths": "^4.2.0"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type { APSettings, APStatus } from 'types';
|
|||||||
|
|
||||||
export const readAPStatus = () => alovaInstance.Get<APStatus>('/apStatus');
|
export const readAPStatus = () => alovaInstance.Get<APStatus>('/apStatus');
|
||||||
|
|
||||||
|
// TODO change AXIOS to Alova
|
||||||
export function readAPSettings(): AxiosPromise<APSettings> {
|
export function readAPSettings(): AxiosPromise<APSettings> {
|
||||||
return AXIOS.get('/apSettings');
|
return AXIOS.get('/apSettings');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ export const alovaInstance = createAlova({
|
|||||||
|
|
||||||
responded: {
|
responded: {
|
||||||
onSuccess: async (response) => {
|
onSuccess: async (response) => {
|
||||||
if (response.status == 202) {
|
if (response.status == 205) {
|
||||||
throw new Error('Reboot required');
|
throw new Error('Reboot required');
|
||||||
} else if (response.status === 400) {
|
} else if (response.status === 400) {
|
||||||
throw new Error('Invalid command');
|
throw new Error('Request Failed');
|
||||||
} else if (response.status >= 400) {
|
} else if (response.status >= 400) {
|
||||||
throw new Error(response.statusText);
|
throw new Error(response.statusText);
|
||||||
}
|
}
|
||||||
@@ -114,8 +114,7 @@ export const AXIOS_BIN = axios.create({
|
|||||||
transformResponse: [(data) => unpack(data)]
|
transformResponse: [(data) => unpack(data)]
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO replace with alova
|
// TODO replace upload with alova, see https://alova.js.org/next-step/download-upload-progress
|
||||||
// TODO see https://alova.js.org/next-step/download-upload-progress
|
|
||||||
export interface FileUploadConfig {
|
export interface FileUploadConfig {
|
||||||
cancelToken?: CancelToken;
|
cancelToken?: CancelToken;
|
||||||
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const APStatusForm: FC = () => {
|
const APStatusForm: FC = () => {
|
||||||
// TODO missing update!
|
|
||||||
const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus());
|
const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus());
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: T
|
|||||||
|
|
||||||
export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatus, theme: Theme) => {
|
export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatus, theme: Theme) => {
|
||||||
if (mqtt_fails === 0) return theme.palette.success.main;
|
if (mqtt_fails === 0) return theme.palette.success.main;
|
||||||
|
|
||||||
if (mqtt_fails < 10) return theme.palette.warning.main;
|
if (mqtt_fails < 10) return theme.palette.warning.main;
|
||||||
|
|
||||||
return theme.palette.error.main;
|
return theme.palette.error.main;
|
||||||
@@ -39,8 +38,7 @@ export const mqttQueueHighlight = ({ mqtt_queued }: MqttStatus, theme: Theme) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
const MqttStatusForm: FC = () => {
|
const MqttStatusForm: FC = () => {
|
||||||
// TODO missing update!
|
// TODO replace with const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus());
|
||||||
|
|
||||||
const { loadData, data, errorMessage } = useRest<MqttStatus>({ read: MqttApi.readMqttStatus });
|
const { loadData, data, errorMessage } = useRest<MqttStatus>({ read: MqttApi.readMqttStatus });
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ const IPs = (status: NetworkStatus) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const NetworkStatusForm: FC = () => {
|
const NetworkStatusForm: FC = () => {
|
||||||
// TODO missing update!
|
// TODO replace with const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus());
|
||||||
|
|
||||||
const { loadData, data, errorMessage } = useRest<NetworkStatus>({ read: NetworkApi.readNetworkStatus });
|
const { loadData, data, errorMessage } = useRest<NetworkStatus>({ read: NetworkApi.readNetworkStatus });
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|||||||
@@ -52,9 +52,9 @@ export const ntpStatusHighlight = ({ status }: NTPStatus, theme: Theme) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const NTPStatusForm: FC = () => {
|
const NTPStatusForm: FC = () => {
|
||||||
// TODO missing update!
|
// TODO replace with const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus());
|
||||||
|
|
||||||
const { loadData, data, errorMessage } = useRest<NTPStatus>({ read: NTPApi.readNTPStatus });
|
const { loadData, data, errorMessage } = useRest<NTPStatus>({ read: NTPApi.readNTPStatus });
|
||||||
|
|
||||||
const [localTime, setLocalTime] = useState<string>('');
|
const [localTime, setLocalTime] = useState<string>('');
|
||||||
const [settingTime, setSettingTime] = useState<boolean>(false);
|
const [settingTime, setSettingTime] = useState<boolean>(false);
|
||||||
const [processing, setProcessing] = useState<boolean>(false);
|
const [processing, setProcessing] = useState<boolean>(false);
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ const levelLabel = (level: LogLevel) => {
|
|||||||
const SystemLog: FC = () => {
|
const SystemLog: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
// TODO missing update!
|
// TODO replace with const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus());
|
||||||
|
|
||||||
const { loadData, data, setData, origData, dirtyFlags, blocker, setDirtyFlags, setOrigData } = useRest<LogSettings>({
|
const { loadData, data, setData, origData, dirtyFlags, blocker, setDirtyFlags, setOrigData } = useRest<LogSettings>({
|
||||||
read: SystemApi.readLogSettings
|
read: SystemApi.readLogSettings
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ const SystemStatusForm: FC = () => {
|
|||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
const [restarting, setRestarting] = useState<boolean>();
|
const [restarting, setRestarting] = useState<boolean>();
|
||||||
|
|
||||||
// TODO missing update!
|
// TODO replace with const { data: data, send: loadData, error } = useRequest(APApi.readAPStatus());
|
||||||
|
|
||||||
const { loadData, data, errorMessage } = useRest<SystemStatus>({ read: SystemApi.readSystemStatus });
|
const { loadData, data, errorMessage } = useRest<SystemStatus>({ read: SystemApi.readSystemStatus });
|
||||||
|
|
||||||
const { me } = useContext(AuthenticatedContext);
|
const { me } = useContext(AuthenticatedContext);
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const DashboardDevices: FC = () => {
|
|||||||
immediate: true
|
immediate: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: deviceData, send: readDeviceData } = useRequest((data) => EMSESP.readDeviceData(data), {
|
const { data: deviceData, send: readDeviceData } = useRequest((id) => EMSESP.readDeviceData(id), {
|
||||||
initialData: {
|
initialData: {
|
||||||
data: []
|
data: []
|
||||||
},
|
},
|
||||||
@@ -444,7 +444,7 @@ const DashboardDevices: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderDeviceData = () => {
|
const renderDeviceData = () => {
|
||||||
if (!selectedDevice || deviceData.data === undefined) {
|
if (!selectedDevice) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ import { Button, Typography, Box } from '@mui/material';
|
|||||||
import { useSort, SortToggleType } from '@table-library/react-table-library/sort';
|
import { useSort, SortToggleType } from '@table-library/react-table-library/sort';
|
||||||
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
import { useTheme } from '@table-library/react-table-library/theme';
|
import { useTheme } from '@table-library/react-table-library/theme';
|
||||||
import { useState, useContext, useCallback, useEffect } from 'react';
|
import { useRequest } from 'alova';
|
||||||
|
import { useState, useContext, useEffect } from 'react';
|
||||||
|
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
@@ -17,24 +18,40 @@ import * as EMSESP from './api';
|
|||||||
|
|
||||||
import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames } from './types';
|
import { DeviceValueUOM, DeviceValueUOM_s, AnalogTypeNames } from './types';
|
||||||
import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators';
|
import { temperatureSensorItemValidation, analogSensorItemValidation } from './validators';
|
||||||
import type { SensorData, TemperatureSensor, AnalogSensor } from './types';
|
import type { TemperatureSensor, AnalogSensor } from './types';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { ButtonRow, SectionContent } from 'components';
|
import { ButtonRow, SectionContent } from 'components';
|
||||||
|
|
||||||
import { AuthenticatedContext } from 'contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { extractErrorMessage } from 'utils';
|
|
||||||
|
|
||||||
const DashboardSensors: FC = () => {
|
const DashboardSensors: FC = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
const { me } = useContext(AuthenticatedContext);
|
const { me } = useContext(AuthenticatedContext);
|
||||||
const [sensorData, setSensorData] = useState<SensorData>({ ts: [], as: [], analog_enabled: false });
|
|
||||||
const [selectedTemperatureSensor, setSelectedTemperatureSensor] = useState<TemperatureSensor>();
|
const [selectedTemperatureSensor, setSelectedTemperatureSensor] = useState<TemperatureSensor>();
|
||||||
const [selectedAnalogSensor, setSelectedAnalogSensor] = useState<AnalogSensor>();
|
const [selectedAnalogSensor, setSelectedAnalogSensor] = useState<AnalogSensor>();
|
||||||
const [temperatureDialogOpen, setTemperatureDialogOpen] = useState<boolean>(false);
|
const [temperatureDialogOpen, setTemperatureDialogOpen] = useState<boolean>(false);
|
||||||
const [analogDialogOpen, setAnalogDialogOpen] = useState<boolean>(false);
|
const [analogDialogOpen, setAnalogDialogOpen] = useState<boolean>(false);
|
||||||
const [creating, setCreating] = useState<boolean>(false);
|
const [creating, setCreating] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const { data: sensorData, send: fetchSensorData } = useRequest(() => EMSESP.readSensorData(), {
|
||||||
|
initialData: {
|
||||||
|
ts: [],
|
||||||
|
as: [],
|
||||||
|
analog_enabled: false
|
||||||
|
},
|
||||||
|
force: true,
|
||||||
|
immediate: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const { send: writeTemperatureSensor } = useRequest((data) => EMSESP.writeTemperatureSensor(data), {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const { send: writeAnalogSensor } = useRequest((data) => EMSESP.writeAnalogSensor(data), {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
const isAdmin = me.admin;
|
const isAdmin = me.admin;
|
||||||
|
|
||||||
const common_theme = useTheme({
|
const common_theme = useTheme({
|
||||||
@@ -101,20 +118,6 @@ const DashboardSensors: FC = () => {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const fetchSensorData = useCallback(async () => {
|
|
||||||
if (!analogDialogOpen && !temperatureDialogOpen) {
|
|
||||||
try {
|
|
||||||
setSensorData((await EMSESP.readSensorData()).data);
|
|
||||||
} catch (error) {
|
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_LOADING()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [LL, analogDialogOpen, temperatureDialogOpen]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
void fetchSensorData();
|
|
||||||
}, [fetchSensorData]);
|
|
||||||
|
|
||||||
const getSortIcon = (state: any, sortKey: any) => {
|
const getSortIcon = (state: any, sortKey: any) => {
|
||||||
if (state.sortKey === sortKey && state.reverse) {
|
if (state.sortKey === sortKey && state.reverse) {
|
||||||
return <KeyboardArrowDownOutlinedIcon />;
|
return <KeyboardArrowDownOutlinedIcon />;
|
||||||
@@ -229,27 +232,18 @@ const DashboardSensors: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onTemperatureDialogSave = async (ts: TemperatureSensor) => {
|
const onTemperatureDialogSave = async (ts: TemperatureSensor) => {
|
||||||
try {
|
await writeTemperatureSensor({ id: ts.id, name: ts.n, offset: ts.o })
|
||||||
const response = await EMSESP.writeTemperatureSensor({
|
.then(() => {
|
||||||
id: ts.id,
|
|
||||||
name: ts.n,
|
|
||||||
offset: ts.o
|
|
||||||
});
|
|
||||||
if (response.status === 204) {
|
|
||||||
toast.error(LL.UPDATE_OF(LL.SENSOR(2)) + ' ' + LL.FAILED(1));
|
|
||||||
} else if (response.status === 403) {
|
|
||||||
// TODO fix
|
|
||||||
toast.error(LL.HTTP_ERROR('poep'));
|
|
||||||
} else {
|
|
||||||
toast.success(LL.UPDATED_OF(LL.SENSOR(1)));
|
toast.success(LL.UPDATED_OF(LL.SENSOR(1)));
|
||||||
}
|
})
|
||||||
} catch (error) {
|
.catch(() => {
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
toast.error(LL.UPDATE_OF(LL.SENSOR(2)) + ' ' + LL.FAILED(1));
|
||||||
} finally {
|
})
|
||||||
|
.finally(async () => {
|
||||||
setTemperatureDialogOpen(false);
|
setTemperatureDialogOpen(false);
|
||||||
setSelectedTemperatureSensor(undefined);
|
setSelectedTemperatureSensor(undefined);
|
||||||
await fetchSensorData();
|
await fetchSensorData();
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateAnalogSensor = (as: AnalogSensor) => {
|
const updateAnalogSensor = (as: AnalogSensor) => {
|
||||||
@@ -281,8 +275,7 @@ const DashboardSensors: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onAnalogDialogSave = async (as: AnalogSensor) => {
|
const onAnalogDialogSave = async (as: AnalogSensor) => {
|
||||||
try {
|
await writeAnalogSensor({
|
||||||
const response = await EMSESP.writeAnalogSensor({
|
|
||||||
id: as.id,
|
id: as.id,
|
||||||
gpio: as.g,
|
gpio: as.g,
|
||||||
name: as.n,
|
name: as.n,
|
||||||
@@ -291,23 +284,18 @@ const DashboardSensors: FC = () => {
|
|||||||
uom: as.u,
|
uom: as.u,
|
||||||
type: as.t,
|
type: as.t,
|
||||||
deleted: as.d
|
deleted: as.d
|
||||||
});
|
})
|
||||||
|
.then(() => {
|
||||||
if (response.status === 204) {
|
|
||||||
toast.error(LL.UPDATE_OF(LL.ANALOG_SENSOR(5)) + ' ' + LL.FAILED(1));
|
|
||||||
} else if (response.status === 403) {
|
|
||||||
// TODO fix
|
|
||||||
toast.error(LL.HTTP_ERROR('poep'));
|
|
||||||
} else {
|
|
||||||
toast.success(LL.UPDATED_OF(LL.ANALOG_SENSOR(2)));
|
toast.success(LL.UPDATED_OF(LL.ANALOG_SENSOR(2)));
|
||||||
}
|
})
|
||||||
} catch (error) {
|
.catch(() => {
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
toast.error(LL.UPDATE_OF(LL.ANALOG_SENSOR(5)) + ' ' + LL.FAILED(1));
|
||||||
} finally {
|
})
|
||||||
|
.finally(async () => {
|
||||||
setAnalogDialogOpen(false);
|
setAnalogDialogOpen(false);
|
||||||
setSelectedAnalogSensor(undefined);
|
setSelectedAnalogSensor(undefined);
|
||||||
await fetchSensorData();
|
await fetchSensorData();
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const RenderTemperatureSensors = () => (
|
const RenderTemperatureSensors = () => (
|
||||||
@@ -433,7 +421,7 @@ const DashboardSensors: FC = () => {
|
|||||||
{sensorData?.analog_enabled === true && (
|
{sensorData?.analog_enabled === true && (
|
||||||
<>
|
<>
|
||||||
<Typography sx={{ pt: 4, pb: 1 }} variant="h6" color="secondary">
|
<Typography sx={{ pt: 4, pb: 1 }} variant="h6" color="secondary">
|
||||||
{LL.ANALOG_SENSORS(0)}
|
{LL.ANALOG_SENSORS()}
|
||||||
</Typography>
|
</Typography>
|
||||||
<RenderAnalogSensors />
|
<RenderAnalogSensors />
|
||||||
{selectedAnalogSensor && (
|
{selectedAnalogSensor && (
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Body, Cell, Header, HeaderCell, HeaderRow, Row, Table } from '@table-library/react-table-library/table';
|
import { Body, Cell, Header, HeaderCell, HeaderRow, Row, 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 { useRequest } from 'alova';
|
||||||
import { useContext, useEffect, useState } from 'react';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
@@ -32,7 +33,6 @@ import type { FC } from 'react';
|
|||||||
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
import { ButtonRow, FormLoader, SectionContent } from 'components';
|
||||||
import { AuthenticatedContext } from 'contexts/authentication';
|
import { AuthenticatedContext } from 'contexts/authentication';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { extractErrorMessage, useRest } from 'utils';
|
|
||||||
|
|
||||||
export const isConnected = ({ status }: Status) => status !== busConnectionStatus.BUS_STATUS_OFFLINE;
|
export const isConnected = ({ status }: Status) => status !== busConnectionStatus.BUS_STATUS_OFFLINE;
|
||||||
|
|
||||||
@@ -64,9 +64,7 @@ const showQuality = (stat: Stat) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const DashboardStatus: FC = () => {
|
const DashboardStatus: FC = () => {
|
||||||
// TODO missing update!
|
const { data: data, send: loadData, error } = useRequest(EMSESP.readStatus, { force: true });
|
||||||
|
|
||||||
const { loadData, data, errorMessage } = useRest<Status>({ read: EMSESP.readStatus });
|
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
@@ -75,6 +73,10 @@ const DashboardStatus: FC = () => {
|
|||||||
|
|
||||||
const { me } = useContext(AuthenticatedContext);
|
const { me } = useContext(AuthenticatedContext);
|
||||||
|
|
||||||
|
const { send: scanDevices } = useRequest(EMSESP.scanDevices, {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
const stats_theme = tableTheme({
|
const stats_theme = tableTheme({
|
||||||
Table: `
|
Table: `
|
||||||
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 90px 80px;
|
--data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 90px 80px;
|
||||||
@@ -160,14 +162,23 @@ const DashboardStatus: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const scan = async () => {
|
const scan = async () => {
|
||||||
try {
|
await scanDevices()
|
||||||
await EMSESP.scanDevices();
|
.then(() => {
|
||||||
toast.info(LL.SCANNING() + '...');
|
toast.info(LL.SCANNING() + '...');
|
||||||
} catch (error) {
|
})
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
.catch((err) => {
|
||||||
} finally {
|
toast.error(err.message);
|
||||||
|
});
|
||||||
setConfirmScan(false);
|
setConfirmScan(false);
|
||||||
}
|
|
||||||
|
// try {
|
||||||
|
// await EMSESP.scanDevices();
|
||||||
|
// toast.info(LL.SCANNING() + '...');
|
||||||
|
// } catch (error) {
|
||||||
|
// toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
||||||
|
// } finally {
|
||||||
|
// setConfirmScan(false);
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderScanDialog = () => (
|
const renderScanDialog = () => (
|
||||||
@@ -187,7 +198,7 @@ const DashboardStatus: FC = () => {
|
|||||||
|
|
||||||
const content = () => {
|
const content = () => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return <FormLoader onRetry={loadData} errorMessage={errorMessage} />;
|
return <FormLoader onRetry={loadData} errorMessage={error?.message} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import CancelIcon from '@mui/icons-material/Cancel';
|
|||||||
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
import PowerSettingsNewIcon from '@mui/icons-material/PowerSettingsNew';
|
||||||
import WarningIcon from '@mui/icons-material/Warning';
|
import WarningIcon from '@mui/icons-material/Warning';
|
||||||
import { Box, Button, Checkbox, MenuItem, Grid, Typography, Divider, InputAdornment, TextField } from '@mui/material';
|
import { Box, Button, Checkbox, MenuItem, Grid, Typography, Divider, InputAdornment, TextField } from '@mui/material';
|
||||||
|
import { useRequest } from 'alova';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ import {
|
|||||||
|
|
||||||
import RestartMonitor from 'framework/system/RestartMonitor';
|
import RestartMonitor from 'framework/system/RestartMonitor';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { numberValue, extractErrorMessage, updateValueDirty, useRest2 } from 'utils';
|
import { numberValue, updateValueDirty, useRest2 } from 'utils';
|
||||||
import { validate } from 'validators';
|
import { validate } from 'validators';
|
||||||
|
|
||||||
export function boardProfileSelectItems() {
|
export function boardProfileSelectItems() {
|
||||||
@@ -39,7 +40,7 @@ const SettingsApplication: FC = () => {
|
|||||||
loadData,
|
loadData,
|
||||||
saveData,
|
saveData,
|
||||||
saving,
|
saving,
|
||||||
setData,
|
updateDataValue,
|
||||||
data,
|
data,
|
||||||
origData,
|
origData,
|
||||||
dirtyFlags,
|
dirtyFlags,
|
||||||
@@ -51,45 +52,48 @@ const SettingsApplication: FC = () => {
|
|||||||
read: EMSESP.readSettings,
|
read: EMSESP.readSettings,
|
||||||
update: EMSESP.writeSettings
|
update: EMSESP.writeSettings
|
||||||
});
|
});
|
||||||
|
|
||||||
const [restarting, setRestarting] = useState<boolean>();
|
const [restarting, setRestarting] = useState<boolean>();
|
||||||
|
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, setData);
|
const updateFormValue = updateValueDirty(origData, dirtyFlags, setDirtyFlags, updateDataValue);
|
||||||
|
|
||||||
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
const [fieldErrors, setFieldErrors] = useState<ValidateFieldsError>();
|
||||||
const [processingBoard, setProcessingBoard] = useState<boolean>(false);
|
|
||||||
|
|
||||||
// TODO remove - just for testing loaddata
|
const {
|
||||||
// useEffect(() => {
|
loading: processingBoard,
|
||||||
// void loadData();
|
send: readBoardProfile,
|
||||||
// }, []);
|
onSuccess: onSuccessBoardProfile
|
||||||
|
} = useRequest((boardProfile) => EMSESP.getBoardProfile(boardProfile), {
|
||||||
// TODO replace with Alova!
|
immediate: false
|
||||||
const updateBoardProfile = async (boardProfile: string) => {
|
});
|
||||||
setProcessingBoard(true);
|
|
||||||
try {
|
const { send: restartCommand } = useRequest(EMSESP.restart(), {
|
||||||
const response = await EMSESP.getBoardProfile({ board_profile: boardProfile });
|
immediate: false
|
||||||
if (data) {
|
});
|
||||||
setData({
|
|
||||||
...data,
|
onSuccessBoardProfile((event) => {
|
||||||
board_profile: boardProfile,
|
const response = event.data as unknown as Settings;
|
||||||
led_gpio: response.data.led_gpio,
|
updateDataValue({
|
||||||
dallas_gpio: response.data.dallas_gpio,
|
...data,
|
||||||
rx_gpio: response.data.rx_gpio,
|
board_profile: response.board_profile,
|
||||||
tx_gpio: response.data.tx_gpio,
|
led_gpio: response.led_gpio,
|
||||||
pbutton_gpio: response.data.pbutton_gpio,
|
dallas_gpio: response.dallas_gpio,
|
||||||
phy_type: response.data.phy_type,
|
rx_gpio: response.rx_gpio,
|
||||||
eth_power: response.data.eth_power,
|
tx_gpio: response.tx_gpio,
|
||||||
eth_phy_addr: response.data.eth_phy_addr,
|
pbutton_gpio: response.pbutton_gpio,
|
||||||
eth_clock_mode: response.data.eth_clock_mode
|
phy_type: response.phy_type,
|
||||||
|
eth_power: response.eth_power,
|
||||||
|
eth_phy_addr: response.eth_phy_addr,
|
||||||
|
eth_clock_mode: response.eth_clock_mode
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateBoardProfile = async (board_profile: string) => {
|
||||||
|
await readBoardProfile(board_profile).catch((error) => {
|
||||||
|
toast.error(error.message);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
|
||||||
} finally {
|
|
||||||
setProcessingBoard(false);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const content = () => {
|
const content = () => {
|
||||||
@@ -101,9 +105,10 @@ const SettingsApplication: FC = () => {
|
|||||||
try {
|
try {
|
||||||
setFieldErrors(undefined);
|
setFieldErrors(undefined);
|
||||||
await validate(createSettingsValidator(data), data);
|
await validate(createSettingsValidator(data), data);
|
||||||
await saveData();
|
|
||||||
} catch (errors: any) {
|
} catch (errors: any) {
|
||||||
setFieldErrors(errors);
|
setFieldErrors(errors);
|
||||||
|
} finally {
|
||||||
|
await saveData();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,7 +116,7 @@ const SettingsApplication: FC = () => {
|
|||||||
const boardProfile = event.target.value;
|
const boardProfile = event.target.value;
|
||||||
updateFormValue(event);
|
updateFormValue(event);
|
||||||
if (boardProfile === 'CUSTOM') {
|
if (boardProfile === 'CUSTOM') {
|
||||||
setData({
|
updateDataValue({
|
||||||
...data,
|
...data,
|
||||||
board_profile: boardProfile
|
board_profile: boardProfile
|
||||||
});
|
});
|
||||||
@@ -122,12 +127,10 @@ const SettingsApplication: FC = () => {
|
|||||||
|
|
||||||
const restart = async () => {
|
const restart = async () => {
|
||||||
await validateAndSubmit();
|
await validateAndSubmit();
|
||||||
try {
|
await restartCommand().catch((error) => {
|
||||||
await EMSESP.restart();
|
toast.error(error.message);
|
||||||
|
});
|
||||||
setRestarting(true);
|
setRestarting(true);
|
||||||
} catch (error) {
|
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
import { Table, Header, HeaderRow, HeaderCell, Body, Row, Cell } from '@table-library/react-table-library/table';
|
||||||
import { useTheme } from '@table-library/react-table-library/theme';
|
import { useTheme } from '@table-library/react-table-library/theme';
|
||||||
|
import { useRequest } from 'alova';
|
||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { unstable_useBlocker as useBlocker } from 'react-router-dom';
|
import { unstable_useBlocker as useBlocker } from 'react-router-dom';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
@@ -32,13 +33,12 @@ import SettingsCustomizationDialog from './SettingsCustomizationDialog';
|
|||||||
import * as EMSESP from './api';
|
import * as EMSESP from './api';
|
||||||
|
|
||||||
import { DeviceEntityMask } from './types';
|
import { DeviceEntityMask } from './types';
|
||||||
import type { DeviceShort, Devices, DeviceEntity } from './types';
|
import type { DeviceShort, DeviceEntity } from './types';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
import { ButtonRow, FormLoader, SectionContent, MessageBox, BlockNavigation } from 'components';
|
import { ButtonRow, SectionContent, MessageBox, BlockNavigation } from 'components';
|
||||||
|
|
||||||
import RestartMonitor from 'framework/system/RestartMonitor';
|
import RestartMonitor from 'framework/system/RestartMonitor';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
import { extractErrorMessage } from 'utils';
|
|
||||||
|
|
||||||
export const APIURL = window.location.origin + '/api/';
|
export const APIURL = window.location.origin + '/api/';
|
||||||
|
|
||||||
@@ -46,11 +46,10 @@ const SettingsCustomization: FC = () => {
|
|||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
const [numChanges, setNumChanges] = useState<number>(0);
|
const [numChanges, setNumChanges] = useState<number>(0);
|
||||||
const blocker = useBlocker(numChanges !== 0);
|
const blocker = useBlocker(numChanges !== 0);
|
||||||
|
|
||||||
const [restarting, setRestarting] = useState<boolean>(false);
|
const [restarting, setRestarting] = useState<boolean>(false);
|
||||||
const [restartNeeded, setRestartNeeded] = useState<boolean>(false);
|
const [restartNeeded, setRestartNeeded] = useState<boolean>(false);
|
||||||
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>();
|
const [deviceEntities, setDeviceEntities] = useState<DeviceEntity[]>([]);
|
||||||
const [devices, setDevices] = useState<Devices>();
|
|
||||||
const [errorMessage, setErrorMessage] = useState<string>();
|
|
||||||
const [selectedDevice, setSelectedDevice] = useState<number>(-1);
|
const [selectedDevice, setSelectedDevice] = useState<number>(-1);
|
||||||
const [confirmReset, setConfirmReset] = useState<boolean>(false);
|
const [confirmReset, setConfirmReset] = useState<boolean>(false);
|
||||||
const [selectedFilters, setSelectedFilters] = useState<number>(0);
|
const [selectedFilters, setSelectedFilters] = useState<number>(0);
|
||||||
@@ -58,6 +57,36 @@ const SettingsCustomization: FC = () => {
|
|||||||
const [selectedDeviceEntity, setSelectedDeviceEntity] = useState<DeviceEntity>();
|
const [selectedDeviceEntity, setSelectedDeviceEntity] = useState<DeviceEntity>();
|
||||||
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
|
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const { send: resetCustomizations } = useRequest(EMSESP.resetCustomizations(), {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data: devices } = useRequest(EMSESP.readDevices());
|
||||||
|
|
||||||
|
const { send: writeCustomEntities } = useRequest((data) => EMSESP.writeCustomEntities(data), { immediate: false });
|
||||||
|
|
||||||
|
const {
|
||||||
|
send: readDeviceEntities,
|
||||||
|
update: updateDeviceEntities,
|
||||||
|
onSuccess: onSuccess
|
||||||
|
} = useRequest((data) => EMSESP.readDeviceEntities(data), {
|
||||||
|
initialData: [],
|
||||||
|
immediate: false,
|
||||||
|
force: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const setOriginalSettings = (data: DeviceEntity[]) => {
|
||||||
|
setDeviceEntities(data.map((de) => ({ ...de, o_m: de.m, o_cn: de.cn, o_mi: de.mi, o_ma: de.ma })));
|
||||||
|
};
|
||||||
|
|
||||||
|
onSuccess((event) => {
|
||||||
|
setOriginalSettings(event.data);
|
||||||
|
});
|
||||||
|
|
||||||
|
const { send: restartCommand } = useRequest(EMSESP.restart(), {
|
||||||
|
immediate: false
|
||||||
|
});
|
||||||
|
|
||||||
const entities_theme = useTheme({
|
const entities_theme = useTheme({
|
||||||
Table: `
|
Table: `
|
||||||
--data-table-library_grid-template-columns: 150px repeat(1, minmax(80px, 1fr)) 45px minmax(45px, auto) minmax(120px, auto);
|
--data-table-library_grid-template-columns: 150px repeat(1, minmax(80px, 1fr)) 45px minmax(45px, auto) minmax(120px, auto);
|
||||||
@@ -131,7 +160,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (deviceEntities) {
|
if (deviceEntities.length) {
|
||||||
setNumChanges(
|
setNumChanges(
|
||||||
deviceEntities
|
deviceEntities
|
||||||
.filter((de) => hasEntityChanged(de))
|
.filter((de) => hasEntityChanged(de))
|
||||||
@@ -148,29 +177,11 @@ const SettingsCustomization: FC = () => {
|
|||||||
}
|
}
|
||||||
}, [deviceEntities]);
|
}, [deviceEntities]);
|
||||||
|
|
||||||
const fetchDevices = useCallback(async () => {
|
const restart = async () => {
|
||||||
try {
|
await restartCommand().catch((error) => {
|
||||||
setDevices((await EMSESP.readDevices()).data);
|
toast.error(error.message);
|
||||||
} catch (error) {
|
});
|
||||||
setErrorMessage(extractErrorMessage(error, LL.PROBLEM_LOADING()));
|
setRestarting(true);
|
||||||
}
|
|
||||||
}, [LL]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
void fetchDevices();
|
|
||||||
}, [fetchDevices]);
|
|
||||||
|
|
||||||
const setOriginalSettings = (data: DeviceEntity[]) => {
|
|
||||||
setDeviceEntities(data.map((de) => ({ ...de, o_m: de.m, o_cn: de.cn, o_mi: de.mi, o_ma: de.ma })));
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchDeviceEntities = async (unique_id: number) => {
|
|
||||||
try {
|
|
||||||
const new_deviceEntities = (await EMSESP.readDeviceEntities({ id: unique_id })).data;
|
|
||||||
setOriginalSettings(new_deviceEntities);
|
|
||||||
} catch (error) {
|
|
||||||
setErrorMessage(extractErrorMessage(error, LL.PROBLEM_LOADING()));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function formatValue(value: any) {
|
function formatValue(value: any) {
|
||||||
@@ -225,7 +236,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const maskDisabled = (set: boolean) => {
|
const maskDisabled = (set: boolean) => {
|
||||||
setDeviceEntities(
|
updateDeviceEntities(
|
||||||
deviceEntities?.map(function (de) {
|
deviceEntities?.map(function (de) {
|
||||||
if ((de.m & selectedFilters || !selectedFilters) && de.id.toLowerCase().includes(search.toLowerCase())) {
|
if ((de.m & selectedFilters || !selectedFilters) && de.id.toLowerCase().includes(search.toLowerCase())) {
|
||||||
return {
|
return {
|
||||||
@@ -246,31 +257,22 @@ const SettingsCustomization: FC = () => {
|
|||||||
const selected_device = parseInt(event.target.value, 10);
|
const selected_device = parseInt(event.target.value, 10);
|
||||||
setSelectedDevice(selected_device);
|
setSelectedDevice(selected_device);
|
||||||
setNumChanges(0);
|
setNumChanges(0);
|
||||||
void fetchDeviceEntities(devices?.devices[selected_device].i);
|
void readDeviceEntities(devices?.devices[selected_device].i);
|
||||||
setRestartNeeded(false);
|
setRestartNeeded(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetCustomization = async () => {
|
const resetCustomization = async () => {
|
||||||
try {
|
try {
|
||||||
await EMSESP.resetCustomizations();
|
await resetCustomizations();
|
||||||
toast.info(LL.CUSTOMIZATIONS_RESTART());
|
toast.info(LL.CUSTOMIZATIONS_RESTART());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
toast.error(error.message);
|
||||||
} finally {
|
} finally {
|
||||||
setConfirmReset(false);
|
setConfirmReset(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const restart = async () => {
|
|
||||||
try {
|
|
||||||
await EMSESP.restart();
|
|
||||||
setRestarting(true);
|
|
||||||
} catch (error) {
|
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDialogClose = () => {
|
const onDialogClose = () => {
|
||||||
setDialogOpen(false);
|
setDialogOpen(false);
|
||||||
};
|
};
|
||||||
@@ -300,7 +302,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
const saveCustomization = async () => {
|
const saveCustomization = async () => {
|
||||||
if (devices && deviceEntities && selectedDevice !== -1) {
|
if (devices && deviceEntities && selectedDevice !== -1) {
|
||||||
const masked_entities = deviceEntities
|
const masked_entities = deviceEntities
|
||||||
.filter((de) => hasEntityChanged(de))
|
.filter((de: DeviceEntity) => hasEntityChanged(de))
|
||||||
.map(
|
.map(
|
||||||
(new_de) =>
|
(new_de) =>
|
||||||
new_de.m.toString(16).padStart(2, '0') +
|
new_de.m.toString(16).padStart(2, '0') +
|
||||||
@@ -318,31 +320,21 @@ const SettingsCustomization: FC = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await writeCustomEntities({ id: devices?.devices[selectedDevice].i, entity_ids: masked_entities }).catch(
|
||||||
const response = await EMSESP.writeCustomEntities({
|
(error) => {
|
||||||
id: devices?.devices[selectedDevice].i,
|
if (error.message === 'Reboot required') {
|
||||||
entity_ids: masked_entities
|
|
||||||
});
|
|
||||||
if (response.status === 200) {
|
|
||||||
toast.success(LL.CUSTOMIZATIONS_SAVED());
|
|
||||||
} else if (response.status === 201) {
|
|
||||||
setRestartNeeded(true);
|
setRestartNeeded(true);
|
||||||
} else {
|
} else {
|
||||||
toast.error(LL.PROBLEM_UPDATING());
|
toast.error(error.message);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
toast.error(extractErrorMessage(error, LL.PROBLEM_UPDATING()));
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
// does this work or use onSuccess hook?
|
||||||
setOriginalSettings(deviceEntities);
|
setOriginalSettings(deviceEntities);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderDeviceList = () => {
|
const renderDeviceList = () => (
|
||||||
if (!devices) {
|
|
||||||
return <FormLoader errorMessage={errorMessage} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
<>
|
||||||
<Box mb={2} color="warning.main">
|
<Box mb={2} color="warning.main">
|
||||||
<Typography variant="body2">{LL.CUSTOMIZATIONS_HELP_1()}.</Typography>
|
<Typography variant="body2">{LL.CUSTOMIZATIONS_HELP_1()}.</Typography>
|
||||||
@@ -376,14 +368,9 @@ const SettingsCustomization: FC = () => {
|
|||||||
</TextField>
|
</TextField>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const renderDeviceData = () => {
|
const renderDeviceData = () => {
|
||||||
if (!deviceEntities) {
|
if (deviceEntities.length === 0) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (devices?.devices.length === 0 || deviceEntities[0].id === '') {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +508,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
|
<Typography sx={{ pt: 2, pb: 2 }} variant="h6" color="primary">
|
||||||
{LL.DEVICE_ENTITIES()}
|
{LL.DEVICE_ENTITIES()}
|
||||||
</Typography>
|
</Typography>
|
||||||
{renderDeviceList()}
|
{devices && renderDeviceList()}
|
||||||
{renderDeviceData()}
|
{renderDeviceData()}
|
||||||
{restartNeeded && (
|
{restartNeeded && (
|
||||||
<MessageBox my={2} level="warning" message={LL.RESTART_TEXT()}>
|
<MessageBox my={2} level="warning" message={LL.RESTART_TEXT()}>
|
||||||
@@ -539,7 +526,7 @@ const SettingsCustomization: FC = () => {
|
|||||||
startIcon={<CancelIcon />}
|
startIcon={<CancelIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
onClick={() => devices && fetchDeviceEntities(devices.devices[selectedDevice].i)}
|
onClick={() => devices && readDeviceEntities(devices.devices[selectedDevice].i)}
|
||||||
>
|
>
|
||||||
{LL.CANCEL()}
|
{LL.CANCEL()}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,86 +1,63 @@
|
|||||||
import type {
|
import type {
|
||||||
BoardProfile,
|
|
||||||
BoardProfileName,
|
|
||||||
APIcall,
|
APIcall,
|
||||||
Settings,
|
Settings,
|
||||||
Status,
|
Status,
|
||||||
CoreData,
|
CoreData,
|
||||||
Devices,
|
Devices,
|
||||||
DeviceData,
|
|
||||||
DeviceEntity,
|
DeviceEntity,
|
||||||
UniqueID,
|
|
||||||
CustomEntities,
|
|
||||||
WriteTemperatureSensor,
|
WriteTemperatureSensor,
|
||||||
WriteAnalogSensor,
|
WriteAnalogSensor,
|
||||||
SensorData,
|
SensorData,
|
||||||
Schedule,
|
Schedule,
|
||||||
Entities
|
Entities,
|
||||||
|
DeviceData
|
||||||
} from './types';
|
} from './types';
|
||||||
import type { AxiosPromise } from 'axios';
|
import type { AxiosPromise } from 'axios';
|
||||||
import { AXIOS, AXIOS_API, AXIOS_BIN, alovaInstance } from 'api/endpoints';
|
import { AXIOS, AXIOS_API, alovaInstance } from 'api/endpoints';
|
||||||
|
|
||||||
|
// DashboardDevices
|
||||||
export const readCoreData = () => alovaInstance.Get<CoreData>(`/coreData`);
|
export const readCoreData = () => alovaInstance.Get<CoreData>(`/coreData`);
|
||||||
|
|
||||||
export const readDeviceData = (id: number) =>
|
export const readDeviceData = (id: number) =>
|
||||||
alovaInstance.Get<DeviceData>('/deviceData', {
|
alovaInstance.Get<DeviceData>('/deviceData', {
|
||||||
params: { id },
|
params: { id },
|
||||||
responseType: 'arraybuffer' // uses msgpack
|
responseType: 'arraybuffer' // uses msgpack
|
||||||
});
|
});
|
||||||
|
|
||||||
export const writeDeviceValue = (data: any) => alovaInstance.Post('/writeDeviceValue', data);
|
export const writeDeviceValue = (data: any) => alovaInstance.Post('/writeDeviceValue', data);
|
||||||
|
|
||||||
// SettingsApplication
|
// SettingsApplication
|
||||||
export const readSettings = () => alovaInstance.Get<Settings>('/settings');
|
export const readSettings = () => alovaInstance.Get<Settings>('/settings');
|
||||||
export const writeSettings = (data: any) => alovaInstance.Post('/settings', data);
|
export const writeSettings = (data: any) => alovaInstance.Post('/settings', data);
|
||||||
|
export const getBoardProfile = (boardProfile: string) =>
|
||||||
|
alovaInstance.Get('/boardProfile', {
|
||||||
|
params: { boardProfile }
|
||||||
|
});
|
||||||
|
export const restart = () => alovaInstance.Post('/restart');
|
||||||
|
|
||||||
//
|
// SettingsCustomization
|
||||||
// TODO change below to use alova
|
export const readDeviceEntities = (id: number) =>
|
||||||
//
|
alovaInstance.Get<DeviceEntity[]>('/deviceEntities', {
|
||||||
|
params: { id },
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
transformData(rawData: any) {
|
||||||
|
return rawData.map((de: DeviceEntity) => ({ ...de, o_m: de.m, o_cn: de.cn, o_mi: de.mi, o_ma: de.ma }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
export const readDevices = () => alovaInstance.Get<Devices>('/devices');
|
||||||
|
export const resetCustomizations = () => alovaInstance.Post('/resetCustomizations');
|
||||||
|
export const writeCustomEntities = (data: any) => alovaInstance.Post('/customEntities', data);
|
||||||
|
|
||||||
export function restart(): AxiosPromise<void> {
|
// DashboardSensors
|
||||||
return AXIOS.post('/restart');
|
export const readSensorData = () => alovaInstance.Get<SensorData>('/sensorData');
|
||||||
}
|
export const writeTemperatureSensor = (ts: WriteTemperatureSensor) => alovaInstance.Post('/writeTemperatureSensor', ts);
|
||||||
|
export const writeAnalogSensor = (as: WriteAnalogSensor) => alovaInstance.Post('/writeAnalogSensor', as);
|
||||||
|
|
||||||
// TODO change to GET
|
// TODO think about naming, get... and not get etc...
|
||||||
export function getBoardProfile(boardProfile: BoardProfileName): AxiosPromise<BoardProfile> {
|
|
||||||
return AXIOS.post('/boardProfile', boardProfile);
|
|
||||||
}
|
|
||||||
// TODO change to GET
|
|
||||||
export function readDeviceEntities(unique_id: UniqueID): AxiosPromise<DeviceEntity[]> {
|
|
||||||
return AXIOS_BIN.post('/deviceEntities', unique_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function readStatus(): AxiosPromise<Status> {
|
// DashboardStatus
|
||||||
return AXIOS.get('/status');
|
export const readStatus = () => alovaInstance.Get<Status>('/status');
|
||||||
}
|
export const scanDevices = () => alovaInstance.Post('/scanDevices');
|
||||||
|
|
||||||
export function readDevices(): AxiosPromise<Devices> {
|
// ALOVA goes here....
|
||||||
return AXIOS.get('/devices');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function scanDevices(): AxiosPromise<void> {
|
|
||||||
return AXIOS.post('/scanDevices'); // call command
|
|
||||||
}
|
|
||||||
|
|
||||||
export function readSensorData(): AxiosPromise<SensorData> {
|
|
||||||
return AXIOS.get('/sensorData');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function writeCustomEntities(customEntities: CustomEntities): AxiosPromise<void> {
|
|
||||||
return AXIOS.post('/customEntities', customEntities);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function writeTemperatureSensor(ts: WriteTemperatureSensor): AxiosPromise<void> {
|
|
||||||
return AXIOS.post('/writeTemperatureSensor', ts);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function writeAnalogSensor(as: WriteAnalogSensor): AxiosPromise<void> {
|
|
||||||
return AXIOS.post('/writeAnalogSensor', as);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resetCustomizations(): AxiosPromise<void> {
|
|
||||||
return AXIOS.post('/resetCustomizations'); // command
|
|
||||||
}
|
|
||||||
|
|
||||||
export function API(apiCall: APIcall): AxiosPromise<void> {
|
export function API(apiCall: APIcall): AxiosPromise<void> {
|
||||||
return AXIOS_API.post('/', apiCall); // command
|
return AXIOS_API.post('/', apiCall); // command
|
||||||
|
|||||||
@@ -131,8 +131,6 @@ export interface DeviceValue {
|
|||||||
m?: number; // min, optional
|
m?: number; // min, optional
|
||||||
x?: number; // max, optional
|
x?: number; // max, optional
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO can be refacvtored to DeviceValue[]?
|
|
||||||
export interface DeviceData {
|
export interface DeviceData {
|
||||||
data: DeviceValue[];
|
data: DeviceValue[];
|
||||||
}
|
}
|
||||||
@@ -152,16 +150,6 @@ export interface DeviceEntity {
|
|||||||
o_ma?: number; // original max value
|
o_ma?: number; // original max value
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CustomEntities {
|
|
||||||
id: number;
|
|
||||||
entity_ids: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO can be removed?
|
|
||||||
export interface UniqueID {
|
|
||||||
id: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum DeviceValueUOM {
|
export enum DeviceValueUOM {
|
||||||
NONE = 0,
|
NONE = 0,
|
||||||
DEGREES,
|
DEGREES,
|
||||||
@@ -258,10 +246,6 @@ export const BOARD_PROFILES: BoardProfiles = {
|
|||||||
S3MINI: 'Liligo S3'
|
S3MINI: 'Liligo S3'
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface BoardProfileName {
|
|
||||||
board_profile: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface BoardProfile {
|
export interface BoardProfile {
|
||||||
board_profile: string;
|
board_profile: string;
|
||||||
led_gpio: number;
|
led_gpio: number;
|
||||||
|
|||||||
@@ -23,14 +23,13 @@ export const updateValue =
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const updateValueDirty =
|
export const updateValueDirty =
|
||||||
<S>(origData: any, dirtyFlags: any, setDirtyFlags: any, updateEntity: any) =>
|
(origData: any, dirtyFlags: any, setDirtyFlags: any, updateDataValue: any) =>
|
||||||
// <S>(origData: any, dirtyFlags: any, setDirtyFlags: any, updateEntity: UpdateEntity<S>) =>
|
|
||||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const updated_value = extractEventValue(event);
|
const updated_value = extractEventValue(event);
|
||||||
const name = event.target.name;
|
const name = event.target.name;
|
||||||
|
|
||||||
// TODO not sure how this is even working!!
|
// TODO not sure how this is even working!!
|
||||||
updateEntity((prevState) => ({
|
updateDataValue((prevState) => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
[name]: updated_value
|
[name]: updated_value
|
||||||
}));
|
}));
|
||||||
@@ -38,9 +37,9 @@ export const updateValueDirty =
|
|||||||
const arr: string[] = dirtyFlags;
|
const arr: string[] = dirtyFlags;
|
||||||
|
|
||||||
// TODO remove comments
|
// TODO remove comments
|
||||||
// console.log('updating ' + name + ' to ' + updated_value); // TODO remove
|
// console.log('updating ' + name + ' to ' + updated_value);
|
||||||
// console.log('dirtyFlags:', dirtyFlags); // TODO remove
|
// console.log('dirtyFlags:', dirtyFlags);
|
||||||
// console.log('binding.ts origData:', origData); // TODO remove
|
// console.log('binding.ts origData:', origData);
|
||||||
|
|
||||||
if (origData[name] !== updated_value) {
|
if (origData[name] !== updated_value) {
|
||||||
if (!arr.includes(name)) {
|
if (!arr.includes(name)) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// TODO can be removed!
|
// TODO extractErrorMessage function can be removed!
|
||||||
export const extractErrorMessage = (error: any, defaultMessage: string) => {
|
export const extractErrorMessage = (error: any, defaultMessage: string) => {
|
||||||
if (error.request) {
|
if (error.request) {
|
||||||
return defaultMessage + ' (' + error.request.status + ': ' + error.request.statusText + ')';
|
return defaultMessage + ' (' + error.request.status + ': ' + error.request.statusText + ')';
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ export * from './route';
|
|||||||
export * from './submit';
|
export * from './submit';
|
||||||
export * from './time';
|
export * from './time';
|
||||||
export * from './useRest';
|
export * from './useRest';
|
||||||
// TODO remove
|
// TODO remove useRest2
|
||||||
export * from './useRest2';
|
export * from './useRest2';
|
||||||
export * from './props';
|
export * from './props';
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ export const useRest = <D>({ read, update }: RestRequestOptions<D>) => {
|
|||||||
const response = await update(toSave);
|
const response = await update(toSave);
|
||||||
setOrigData(response.data);
|
setOrigData(response.data);
|
||||||
setData(response.data);
|
setData(response.data);
|
||||||
if (response.status === 202) {
|
if (response.status === 205) {
|
||||||
setRestartNeeded(true);
|
setRestartNeeded(true); // reboot required
|
||||||
} else {
|
} else {
|
||||||
toast.success(LL.UPDATED_OF(LL.SETTINGS()));
|
toast.success(LL.UPDATED_OF(LL.SETTINGS()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,15 @@ import type { AlovaXHRRequestConfig, AlovaXHRResponse, AlovaXHRResponseHeaders }
|
|||||||
|
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
|
||||||
export interface RestRequestOptions<D> {
|
export interface RestRequestOptions2<D> {
|
||||||
read: () => Method<any, any, any, any, any, AlovaXHRResponse<any>, AlovaXHRResponseHeaders>;
|
read: () => Method<any, any, any, any, any, AlovaXHRResponse<any>, AlovaXHRResponseHeaders>;
|
||||||
update: (
|
update: (
|
||||||
value: D
|
value: D
|
||||||
) => Method<any, unknown, unknown, unknown, AlovaXHRRequestConfig, AlovaXHRResponse<any>, AlovaXHRResponseHeaders>;
|
) => Method<any, unknown, unknown, unknown, AlovaXHRRequestConfig, AlovaXHRResponse<any>, AlovaXHRResponseHeaders>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useRest2 = <D>({ read, update }: RestRequestOptions<D>) => {
|
// TODO rename back to useRest
|
||||||
|
export const useRest2 = <D>({ read, update }: RestRequestOptions2<D>) => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
|
|
||||||
const [errorMessage, setErrorMessage] = useState<string>();
|
const [errorMessage, setErrorMessage] = useState<string>();
|
||||||
@@ -32,12 +33,8 @@ export const useRest2 = <D>({ read, update }: RestRequestOptions<D>) => {
|
|||||||
onSuccess: onWriteSuccess
|
onSuccess: onWriteSuccess
|
||||||
} = useRequest((newData: D) => update(newData), { immediate: false });
|
} = useRequest((newData: D) => update(newData), { immediate: false });
|
||||||
|
|
||||||
const setData = (new_data: D) => {
|
const updateDataValue = (new_data: D) => {
|
||||||
console.log('SET DATA'); // TODO remove console
|
updateData({ data: new_data });
|
||||||
console.log('new_data:', new_data); // TODO remove console
|
|
||||||
updateData({
|
|
||||||
data: new_data
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onWriteSuccess(() => {
|
onWriteSuccess(() => {
|
||||||
@@ -46,7 +43,7 @@ export const useRest2 = <D>({ read, update }: RestRequestOptions<D>) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onReadComplete((event) => {
|
onReadComplete((event) => {
|
||||||
setOrigData(event.data); // make a copy
|
setOrigData(event.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
@@ -62,7 +59,6 @@ export const useRest2 = <D>({ read, update }: RestRequestOptions<D>) => {
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('SAVE DATA'); // TODO remove console
|
|
||||||
setRestartNeeded(false);
|
setRestartNeeded(false);
|
||||||
setErrorMessage(undefined);
|
setErrorMessage(undefined);
|
||||||
await writeData(data).catch((error) => {
|
await writeData(data).catch((error) => {
|
||||||
@@ -79,7 +75,7 @@ export const useRest2 = <D>({ read, update }: RestRequestOptions<D>) => {
|
|||||||
loadData,
|
loadData,
|
||||||
saveData,
|
saveData,
|
||||||
saving,
|
saving,
|
||||||
setData,
|
updateDataValue,
|
||||||
data,
|
data,
|
||||||
origData,
|
origData,
|
||||||
dirtyFlags,
|
dirtyFlags,
|
||||||
|
|||||||
@@ -767,14 +767,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@mui/material@npm:^5.13.4":
|
"@mui/material@npm:^5.13.5":
|
||||||
version: 5.13.4
|
version: 5.13.5
|
||||||
resolution: "@mui/material@npm:5.13.4"
|
resolution: "@mui/material@npm:5.13.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime": ^7.21.0
|
"@babel/runtime": ^7.21.0
|
||||||
"@mui/base": 5.0.0-beta.4
|
"@mui/base": 5.0.0-beta.4
|
||||||
"@mui/core-downloads-tracker": ^5.13.4
|
"@mui/core-downloads-tracker": ^5.13.4
|
||||||
"@mui/system": ^5.13.2
|
"@mui/system": ^5.13.5
|
||||||
"@mui/types": ^7.2.4
|
"@mui/types": ^7.2.4
|
||||||
"@mui/utils": ^5.13.1
|
"@mui/utils": ^5.13.1
|
||||||
"@types/react-transition-group": ^4.4.6
|
"@types/react-transition-group": ^4.4.6
|
||||||
@@ -796,7 +796,7 @@ __metadata:
|
|||||||
optional: true
|
optional: true
|
||||||
"@types/react":
|
"@types/react":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 1f0b26c74e06fb6849af7398b8bc1d211d0af146822c998a9c55c31552ffcf426834eac56dc909c15bae8a3b957df91f32d9c1b6cb1300e063d184bfb530512f
|
checksum: 325a99809efa041aa615b144bfde634ad7def22102b6267769e140aee0cdeaa3f611b79d4e3dc85a832b1f120da19b3e57933fb17487c7d5f67d7c2bbe7f3254
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -838,9 +838,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@mui/system@npm:^5.13.2":
|
"@mui/system@npm:^5.13.5":
|
||||||
version: 5.13.2
|
version: 5.13.5
|
||||||
resolution: "@mui/system@npm:5.13.2"
|
resolution: "@mui/system@npm:5.13.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime": ^7.21.0
|
"@babel/runtime": ^7.21.0
|
||||||
"@mui/private-theming": ^5.13.1
|
"@mui/private-theming": ^5.13.1
|
||||||
@@ -862,7 +862,7 @@ __metadata:
|
|||||||
optional: true
|
optional: true
|
||||||
"@types/react":
|
"@types/react":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 34ebb580e5dd83123cc397c3fd54c3430f66ab715eb1538cf2510821d88249814294f79ea046081b61249643383fd9c23552d9791322855fa2099bf8f1c4e51b
|
checksum: 0bef4c575d9c54e7d93ad14009aecf4a0f18440398a14a6523f3fcea665913ceb344dc496d02b56a3ef53e4dac828f8e7ca5a55fb60448a76363622159d18379
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1288,10 +1288,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/node@npm:^20.3.0":
|
"@types/node@npm:^20.3.1":
|
||||||
version: 20.3.0
|
version: 20.3.1
|
||||||
resolution: "@types/node@npm:20.3.0"
|
resolution: "@types/node@npm:20.3.1"
|
||||||
checksum: f717d92c29c4877db394b604771b3734216f013312f93252f72c2018aabe8083be905fbcf0644c859938c8183b6e0245faaeaab94c9e78268b87a449bc6ef4aa
|
checksum: 7e8a6f5d6fc1ad3778f038f5f8df570741459984280fd2e9539af32620d93438c955fd1b90d00f9cc438cd132ec04d7669ada9e32502336e78713a3ad9b51d10
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1309,12 +1309,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/react-dom@npm:^18.2.4":
|
"@types/react-dom@npm:^18.2.5":
|
||||||
version: 18.2.4
|
version: 18.2.5
|
||||||
resolution: "@types/react-dom@npm:18.2.4"
|
resolution: "@types/react-dom@npm:18.2.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
checksum: dfeaabb4268d39bdd5addc6c0b7099d5c57a364e70f1087b7c3ee189374312dc65201abfd3d87fee0de11d27c225678ce39c22d14b3035cde5792678704c27b5
|
checksum: 7f438f695c91735ff16e6465573a4378fabad6709d99dd08bee4932967ca7e4ccc26dc248f4b88569529885bbca9b1aca0075bee7b833bfa932a558c49d2a066
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1368,14 +1368,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/react@npm:^18.2.11":
|
"@types/react@npm:^18.2.12":
|
||||||
version: 18.2.11
|
version: 18.2.12
|
||||||
resolution: "@types/react@npm:18.2.11"
|
resolution: "@types/react@npm:18.2.12"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/prop-types": "*"
|
"@types/prop-types": "*"
|
||||||
"@types/scheduler": "*"
|
"@types/scheduler": "*"
|
||||||
csstype: ^3.0.2
|
csstype: ^3.0.2
|
||||||
checksum: 9360d7be13195050eb16598796056123ee9d30470e7073a914300fed9282585d0dd0638bb5ff65843e308c3ac213d25b3388e8186f3134490c758f18f11f3bd8
|
checksum: dbaefc7732f77cd0c2bdf6e704ab4ee0f611540777c0b9506d972f165144b6fd6883a29dad61f6965c974c040264852aa8def1e3866b5775b3965a4e67bf92f9
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1393,14 +1393,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@npm:^5.59.9":
|
"@typescript-eslint/eslint-plugin@npm:^5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/eslint-plugin@npm:5.59.9"
|
resolution: "@typescript-eslint/eslint-plugin@npm:5.59.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/regexpp": ^4.4.0
|
"@eslint-community/regexpp": ^4.4.0
|
||||||
"@typescript-eslint/scope-manager": 5.59.9
|
"@typescript-eslint/scope-manager": 5.59.11
|
||||||
"@typescript-eslint/type-utils": 5.59.9
|
"@typescript-eslint/type-utils": 5.59.11
|
||||||
"@typescript-eslint/utils": 5.59.9
|
"@typescript-eslint/utils": 5.59.11
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
grapheme-splitter: ^1.0.4
|
grapheme-splitter: ^1.0.4
|
||||||
ignore: ^5.2.0
|
ignore: ^5.2.0
|
||||||
@@ -1413,43 +1413,43 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 4bb9981bcc009c044ffd6b64288309480df2b6c9cdf6b345987e4b565d0973d1d98b7209f6b46b92880735d788f564e17553641087aa59f67990c84526622a27
|
checksum: 77f29b8bde5d11a5f222b21e5a3546e86f79a07efd8352b3ebcde67fd2c568ba7c6946fa992dbb9d7d80b6f2455017266fdede1ed134bd181b03f98d81fe71c3
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/parser@npm:^5.59.9":
|
"@typescript-eslint/parser@npm:^5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/parser@npm:5.59.9"
|
resolution: "@typescript-eslint/parser@npm:5.59.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager": 5.59.9
|
"@typescript-eslint/scope-manager": 5.59.11
|
||||||
"@typescript-eslint/types": 5.59.9
|
"@typescript-eslint/types": 5.59.11
|
||||||
"@typescript-eslint/typescript-estree": 5.59.9
|
"@typescript-eslint/typescript-estree": 5.59.11
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: af0e041e8a541734ff237ec0eac47e355c2f78dd2b0db4eb4ab0c10ba1b6d5d70f84ddc16f856bc72c4cacd53ef04b5f4948baffb5c8cb2d9a0ffd83a8fbc547
|
checksum: 3deea3a9b694ea97e315881ba37d0a90d7f37f0acbb5990270f44c79db9fc3d5675df856f8d1fb7d92c8d38dc63226a42402d57633513981ee526c06e6e8f3c3
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager@npm:5.59.9":
|
"@typescript-eslint/scope-manager@npm:5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/scope-manager@npm:5.59.9"
|
resolution: "@typescript-eslint/scope-manager@npm:5.59.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": 5.59.9
|
"@typescript-eslint/types": 5.59.11
|
||||||
"@typescript-eslint/visitor-keys": 5.59.9
|
"@typescript-eslint/visitor-keys": 5.59.11
|
||||||
checksum: 41622fd270e5b8574347ed5dd020bbb9752d85e6f40df180e944c1110d9bd2227a949067feb23dd4117dd2be0623c05a47bc363abe605c96deb295753f6dd080
|
checksum: e0173e9beb44408ba3e9a1eb173dd83f5c0281af09f936d03f635b7fac41abe1f829a88d0cba134f250dfa4ce527d8cfa32c96e7ada5de876a7aa8bcc933db3b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/type-utils@npm:5.59.9":
|
"@typescript-eslint/type-utils@npm:5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/type-utils@npm:5.59.9"
|
resolution: "@typescript-eslint/type-utils@npm:5.59.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/typescript-estree": 5.59.9
|
"@typescript-eslint/typescript-estree": 5.59.11
|
||||||
"@typescript-eslint/utils": 5.59.9
|
"@typescript-eslint/utils": 5.59.11
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
tsutils: ^3.21.0
|
tsutils: ^3.21.0
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1457,23 +1457,23 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: c3a9773d2b81350923025933623e1572538f79bf119b40bed17389eda11632f6d364a49b385aa6d915d85f7c3d45376085cc55263d865dbc2b753598bba6473b
|
checksum: 9675cf17970bbf01814d8c8a94aa076fb7c5f5ab8c405800f972a68a72748db07070a526aa2c94d30b2e5ba43bdbef3929a588182bffc3387288b24223574f52
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/types@npm:5.59.9":
|
"@typescript-eslint/types@npm:5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/types@npm:5.59.9"
|
resolution: "@typescript-eslint/types@npm:5.59.11"
|
||||||
checksum: 951046891bcc9fa27d72a5489b496291e44cedcff204d3ce6c10c8916fc5e255332738efd4d7555200a55b49ff4ba1204e186960d216d51fea89fe92a982180e
|
checksum: 8d007c6c66323582d526429d059c477dcb522b904938a6aaf29804027e6f427533fabe9eb3c987491df74d4288dab238c8c948886f03244a1d908f2985631368
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@npm:5.59.9":
|
"@typescript-eslint/typescript-estree@npm:5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/typescript-estree@npm:5.59.9"
|
resolution: "@typescript-eslint/typescript-estree@npm:5.59.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": 5.59.9
|
"@typescript-eslint/types": 5.59.11
|
||||||
"@typescript-eslint/visitor-keys": 5.59.9
|
"@typescript-eslint/visitor-keys": 5.59.11
|
||||||
debug: ^4.3.4
|
debug: ^4.3.4
|
||||||
globby: ^11.1.0
|
globby: ^11.1.0
|
||||||
is-glob: ^4.0.3
|
is-glob: ^4.0.3
|
||||||
@@ -1482,35 +1482,35 @@ __metadata:
|
|||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 2f3d8df6d454fbc52d305abfe8447bff8e8d63294ce47e4679c920f647643f5d15a1f693caf74f4fabece12d5ba27ebdb156d507b16fbd2751fc01ba6c4df3c8
|
checksum: 4306317ad65668a05d9ec7b280eab94dd7e0d15394db633864bad5d9633fbb9dc516e6cd9f8a0fc2f7a4fc0d53658e5dac61cbee3e070b0b7ac99bdbb0bb45ef
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/utils@npm:5.59.9":
|
"@typescript-eslint/utils@npm:5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/utils@npm:5.59.9"
|
resolution: "@typescript-eslint/utils@npm:5.59.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@eslint-community/eslint-utils": ^4.2.0
|
"@eslint-community/eslint-utils": ^4.2.0
|
||||||
"@types/json-schema": ^7.0.9
|
"@types/json-schema": ^7.0.9
|
||||||
"@types/semver": ^7.3.12
|
"@types/semver": ^7.3.12
|
||||||
"@typescript-eslint/scope-manager": 5.59.9
|
"@typescript-eslint/scope-manager": 5.59.11
|
||||||
"@typescript-eslint/types": 5.59.9
|
"@typescript-eslint/types": 5.59.11
|
||||||
"@typescript-eslint/typescript-estree": 5.59.9
|
"@typescript-eslint/typescript-estree": 5.59.11
|
||||||
eslint-scope: ^5.1.1
|
eslint-scope: ^5.1.1
|
||||||
semver: ^7.3.7
|
semver: ^7.3.7
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
|
||||||
checksum: b8a04a83c121faa3e36abb2b6113f2e0ec5cf86884d0cb8619bfc50f7442341ee17e4495d69f8abeb6edad9e0347de8382ea1708a5fd6da1e4c80b7b8215c6ab
|
checksum: c1927950d97afcf3cfc4c3901bc1932caa32bfc533f950f7dab420c478097d3d8daf030c27489e0d49ecdc1f87c52c782833cc505b245ab2a3094c707b0d776e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@npm:5.59.9":
|
"@typescript-eslint/visitor-keys@npm:5.59.11":
|
||||||
version: 5.59.9
|
version: 5.59.11
|
||||||
resolution: "@typescript-eslint/visitor-keys@npm:5.59.9"
|
resolution: "@typescript-eslint/visitor-keys@npm:5.59.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types": 5.59.9
|
"@typescript-eslint/types": 5.59.11
|
||||||
eslint-visitor-keys: ^3.3.0
|
eslint-visitor-keys: ^3.3.0
|
||||||
checksum: 882fd03830cbe0eca8f9a547aecc6519ddbec10e55f5f3de66e605a3f3d42a6237abd3c09b34d9cc3343c8e11386e999876aec384efe523e1478cb22752d326d
|
checksum: 1644c5bcb87e26717bc587f1ed1d87c96e89dae7d5bdafc1eed35a7c49e3157f8c37936b3897571892f412b7dd8439ba9cf8903128bb847831696f6517bb2d7a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1533,17 +1533,17 @@ __metadata:
|
|||||||
"@emotion/react": ^11.11.1
|
"@emotion/react": ^11.11.1
|
||||||
"@emotion/styled": ^11.11.0
|
"@emotion/styled": ^11.11.0
|
||||||
"@mui/icons-material": ^5.11.16
|
"@mui/icons-material": ^5.11.16
|
||||||
"@mui/material": ^5.13.4
|
"@mui/material": ^5.13.5
|
||||||
"@table-library/react-table-library": 4.1.4
|
"@table-library/react-table-library": 4.1.4
|
||||||
"@types/lodash-es": ^4.17.7
|
"@types/lodash-es": ^4.17.7
|
||||||
"@types/node": ^20.3.0
|
"@types/node": ^20.3.1
|
||||||
"@types/react": ^18.2.11
|
"@types/react": ^18.2.12
|
||||||
"@types/react-dom": ^18.2.4
|
"@types/react-dom": ^18.2.5
|
||||||
"@types/react-router-dom": ^5.3.3
|
"@types/react-router-dom": ^5.3.3
|
||||||
"@typescript-eslint/eslint-plugin": ^5.59.9
|
"@typescript-eslint/eslint-plugin": ^5.59.11
|
||||||
"@typescript-eslint/parser": ^5.59.9
|
"@typescript-eslint/parser": ^5.59.11
|
||||||
"@vitejs/plugin-react-swc": ^3.3.2
|
"@vitejs/plugin-react-swc": ^3.3.2
|
||||||
alova: ^2.6.0
|
alova: ^2.6.1
|
||||||
async-validator: ^4.2.5
|
async-validator: ^4.2.5
|
||||||
axios: ^1.4.0
|
axios: ^1.4.0
|
||||||
eslint: ^8.42.0
|
eslint: ^8.42.0
|
||||||
@@ -1571,7 +1571,7 @@ __metadata:
|
|||||||
react-toastify: ^9.1.3
|
react-toastify: ^9.1.3
|
||||||
rollup-plugin-visualizer: ^5.9.2
|
rollup-plugin-visualizer: ^5.9.2
|
||||||
sockette: ^2.0.6
|
sockette: ^2.0.6
|
||||||
terser: ^5.17.7
|
terser: ^5.18.0
|
||||||
typesafe-i18n: ^5.24.3
|
typesafe-i18n: ^5.24.3
|
||||||
typescript: ^5.1.3
|
typescript: ^5.1.3
|
||||||
vite: ^4.3.9
|
vite: ^4.3.9
|
||||||
@@ -1647,10 +1647,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"alova@npm:^2.6.0":
|
"alova@npm:^2.6.1":
|
||||||
version: 2.6.0
|
version: 2.6.1
|
||||||
resolution: "alova@npm:2.6.0"
|
resolution: "alova@npm:2.6.1"
|
||||||
checksum: a99dd001f094cccbc6166c5cc56ed8d417434f9edf05aa5176992a3a3735600a3b626b41b50dd867b8a86b3edf44cfbd576568349af937626a7023f9b839226b
|
checksum: 55504d1cfab8efff3679d5734e7f78891b3b9c581c6669e6a6df6cc854d05c5d275f6645e1347c633f4418a41d418105857c7d96e0f69dc24abeccc06f0a8c18
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -5536,9 +5536,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"terser@npm:^5.17.7":
|
"terser@npm:^5.18.0":
|
||||||
version: 5.17.7
|
version: 5.18.0
|
||||||
resolution: "terser@npm:5.17.7"
|
resolution: "terser@npm:5.18.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jridgewell/source-map": ^0.3.3
|
"@jridgewell/source-map": ^0.3.3
|
||||||
acorn: ^8.8.2
|
acorn: ^8.8.2
|
||||||
@@ -5546,7 +5546,7 @@ __metadata:
|
|||||||
source-map-support: ~0.5.20
|
source-map-support: ~0.5.20
|
||||||
bin:
|
bin:
|
||||||
terser: bin/terser
|
terser: bin/terser
|
||||||
checksum: 864154a1750daf516012e5add4f0749bfc71e8f4f918973ec3d504db6a148be976adf46ae490e795173eeff59ec579d7d464bb6354c1bb71f8e14ff398409aed
|
checksum: 37f562843537c57e119b2ed6d96c2113344d9182a83613abd8e933534b89a3c622ee7ee47d4023249c1d34a2dd1b41a0e56fd6d2e2251f48b79fb7671f269b01
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,7 @@
|
|||||||
#include "cbuf.h"
|
#include "cbuf.h"
|
||||||
|
|
||||||
// Since ESP8266 does not link memchr by default, here's its implementation.
|
// Since ESP8266 does not link memchr by default, here's its implementation.
|
||||||
void* memchr(void* ptr, int ch, size_t count)
|
void * memchr(void * ptr, int ch, size_t count) {
|
||||||
{
|
|
||||||
unsigned char * p = static_cast<unsigned char *>(ptr);
|
unsigned char * p = static_cast<unsigned char *>(ptr);
|
||||||
while (count--)
|
while (count--)
|
||||||
if (*p++ == static_cast<unsigned char>(ch))
|
if (*p++ == static_cast<unsigned char>(ch))
|
||||||
@@ -38,48 +37,90 @@ void* memchr(void* ptr, int ch, size_t count)
|
|||||||
* */
|
* */
|
||||||
const char * AsyncWebServerResponse::_responseCodeToString(int code) {
|
const char * AsyncWebServerResponse::_responseCodeToString(int code) {
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case 100: return ("Continue");
|
case 100:
|
||||||
case 101: return ("Switching Protocols");
|
return ("Continue");
|
||||||
case 200: return ("OK");
|
case 101:
|
||||||
case 201: return ("Created");
|
return ("Switching Protocols");
|
||||||
case 202: return ("Accepted");
|
case 200:
|
||||||
case 203: return ("Non-Authoritative Information");
|
return ("OK");
|
||||||
case 204: return ("No Content");
|
case 201:
|
||||||
case 205: return ("Reset Content");
|
return ("Created");
|
||||||
case 206: return ("Partial Content");
|
case 202:
|
||||||
case 300: return ("Multiple Choices");
|
return ("Accepted"); // proddy: used in wifi
|
||||||
case 301: return ("Moved Permanently");
|
case 203:
|
||||||
case 302: return ("Found");
|
return ("Non-Authoritative Information");
|
||||||
case 303: return ("See Other");
|
case 204:
|
||||||
case 304: return ("Not Modified");
|
return ("No Content");
|
||||||
case 305: return ("Use Proxy");
|
case 205:
|
||||||
case 307: return ("Temporary Redirect");
|
return ("Reset Content"); // proddy: reboot required
|
||||||
case 400: return ("Bad Request");
|
case 206:
|
||||||
case 401: return ("Unauthorized");
|
return ("Partial Content");
|
||||||
case 402: return ("Payment Required");
|
case 300:
|
||||||
case 403: return ("Forbidden");
|
return ("Multiple Choices");
|
||||||
case 404: return ("Not Found");
|
case 301:
|
||||||
case 405: return ("Method Not Allowed");
|
return ("Moved Permanently");
|
||||||
case 406: return ("Not Acceptable");
|
case 302:
|
||||||
case 407: return ("Proxy Authentication Required");
|
return ("Found");
|
||||||
case 408: return ("Request Time-out");
|
case 303:
|
||||||
case 409: return ("Conflict");
|
return ("See Other");
|
||||||
case 410: return ("Gone");
|
case 304:
|
||||||
case 411: return ("Length Required");
|
return ("Not Modified");
|
||||||
case 412: return ("Precondition Failed");
|
case 305:
|
||||||
case 413: return ("Request Entity Too Large");
|
return ("Use Proxy");
|
||||||
case 414: return ("Request-URI Too Large");
|
case 307:
|
||||||
case 415: return ("Unsupported Media Type");
|
return ("Temporary Redirect");
|
||||||
case 416: return ("Requested range not satisfiable");
|
case 400:
|
||||||
case 417: return ("Expectation Failed");
|
return ("Bad Request");
|
||||||
case 500: return ("Internal Server Error");
|
case 401:
|
||||||
case 501: return ("Not Implemented");
|
return ("Unauthorized");
|
||||||
case 502: return ("Bad Gateway");
|
case 402:
|
||||||
case 503: return ("Service Unavailable");
|
return ("Payment Required");
|
||||||
case 504: return ("Gateway Time-out");
|
case 403:
|
||||||
case 505: return ("HTTP Version not supported");
|
return ("Forbidden");
|
||||||
case 507: return ("Insufficient Storage");
|
case 404:
|
||||||
default: return ("");
|
return ("Not Found");
|
||||||
|
case 405:
|
||||||
|
return ("Method Not Allowed");
|
||||||
|
case 406:
|
||||||
|
return ("Not Acceptable");
|
||||||
|
case 407:
|
||||||
|
return ("Proxy Authentication Required");
|
||||||
|
case 408:
|
||||||
|
return ("Request Time-out");
|
||||||
|
case 409:
|
||||||
|
return ("Conflict");
|
||||||
|
case 410:
|
||||||
|
return ("Gone");
|
||||||
|
case 411:
|
||||||
|
return ("Length Required");
|
||||||
|
case 412:
|
||||||
|
return ("Precondition Failed");
|
||||||
|
case 413:
|
||||||
|
return ("Request Entity Too Large");
|
||||||
|
case 414:
|
||||||
|
return ("Request-URI Too Large");
|
||||||
|
case 415:
|
||||||
|
return ("Unsupported Media Type");
|
||||||
|
case 416:
|
||||||
|
return ("Requested range not satisfiable");
|
||||||
|
case 417:
|
||||||
|
return ("Expectation Failed");
|
||||||
|
case 500:
|
||||||
|
return ("Internal Server Error");
|
||||||
|
case 501:
|
||||||
|
return ("Not Implemented");
|
||||||
|
case 502:
|
||||||
|
return ("Bad Gateway");
|
||||||
|
case 503:
|
||||||
|
return ("Service Unavailable");
|
||||||
|
case 504:
|
||||||
|
return ("Gateway Time-out");
|
||||||
|
case 505:
|
||||||
|
return ("HTTP Version not supported");
|
||||||
|
case 507:
|
||||||
|
return ("Insufficient Storage");
|
||||||
|
default:
|
||||||
|
return ("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,8 +139,7 @@ AsyncWebServerResponse::AsyncWebServerResponse()
|
|||||||
, _sentLength(0)
|
, _sentLength(0)
|
||||||
, _ackedLength(0)
|
, _ackedLength(0)
|
||||||
, _writtenLength(0)
|
, _writtenLength(0)
|
||||||
, _state(RESPONSE_SETUP)
|
, _state(RESPONSE_SETUP) {
|
||||||
{
|
|
||||||
for (auto header : DefaultHeaders::Instance()) {
|
for (auto header : DefaultHeaders::Instance()) {
|
||||||
_headers.add(new AsyncWebHeader(header->name(), header->value()));
|
_headers.add(new AsyncWebHeader(header->name(), header->value()));
|
||||||
}
|
}
|
||||||
@@ -161,12 +201,28 @@ String AsyncWebServerResponse::_assembleHead(uint8_t version){
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsyncWebServerResponse::_started() const { return _state > RESPONSE_SETUP; }
|
bool AsyncWebServerResponse::_started() const {
|
||||||
bool AsyncWebServerResponse::_finished() const { return _state > RESPONSE_WAIT_ACK; }
|
return _state > RESPONSE_SETUP;
|
||||||
bool AsyncWebServerResponse::_failed() const { return _state == RESPONSE_FAILED; }
|
}
|
||||||
bool AsyncWebServerResponse::_sourceValid() const { return false; }
|
bool AsyncWebServerResponse::_finished() const {
|
||||||
void AsyncWebServerResponse::_respond(AsyncWebServerRequest *request){ _state = RESPONSE_END; request->client()->close(); }
|
return _state > RESPONSE_WAIT_ACK;
|
||||||
size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest *request, size_t len, uint32_t time){ (void)request; (void)len; (void)time; return 0; }
|
}
|
||||||
|
bool AsyncWebServerResponse::_failed() const {
|
||||||
|
return _state == RESPONSE_FAILED;
|
||||||
|
}
|
||||||
|
bool AsyncWebServerResponse::_sourceValid() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
void AsyncWebServerResponse::_respond(AsyncWebServerRequest * request) {
|
||||||
|
_state = RESPONSE_END;
|
||||||
|
request->client()->close();
|
||||||
|
}
|
||||||
|
size_t AsyncWebServerResponse::_ack(AsyncWebServerRequest * request, size_t len, uint32_t time) {
|
||||||
|
(void)request;
|
||||||
|
(void)len;
|
||||||
|
(void)time;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* String/Code Response
|
* String/Code Response
|
||||||
@@ -249,8 +305,8 @@ size_t AsyncBasicResponse::_ack(AsyncWebServerRequest *request, size_t len, uint
|
|||||||
* Abstract Response
|
* Abstract Response
|
||||||
* */
|
* */
|
||||||
|
|
||||||
AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback): _callback(callback)
|
AsyncAbstractResponse::AsyncAbstractResponse(AwsTemplateProcessor callback)
|
||||||
{
|
: _callback(callback) {
|
||||||
// In case of template processing, we're unable to determine real response size
|
// In case of template processing, we're unable to determine real response size
|
||||||
if (callback) {
|
if (callback) {
|
||||||
_contentLength = 0;
|
_contentLength = 0;
|
||||||
@@ -323,7 +379,8 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
outLen = snprintf_P((char *)buf + headLen, sizeof(buf) - headLen - 2, PSTR("%x"), readLen) + headLen;
|
outLen = snprintf_P((char *)buf + headLen, sizeof(buf) - headLen - 2, PSTR("%x"), readLen) + headLen;
|
||||||
while(outLen < headLen + 4) buf[outLen++] = ' ';
|
while (outLen < headLen + 4)
|
||||||
|
buf[outLen++] = ' ';
|
||||||
buf[outLen++] = '\r';
|
buf[outLen++] = '\r';
|
||||||
buf[outLen++] = '\n';
|
buf[outLen++] = '\n';
|
||||||
outLen += readLen;
|
outLen += readLen;
|
||||||
@@ -369,8 +426,7 @@ size_t AsyncAbstractResponse::_ack(AsyncWebServerRequest *request, size_t len, u
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AsyncAbstractResponse::_readDataFromCacheOrContent(uint8_t* data, const size_t len)
|
size_t AsyncAbstractResponse::_readDataFromCacheOrContent(uint8_t * data, const size_t len) {
|
||||||
{
|
|
||||||
// If we have something in cache, copy it to buffer
|
// If we have something in cache, copy it to buffer
|
||||||
const size_t readFromCache = std::min(len, _cache.size());
|
const size_t readFromCache = std::min(len, _cache.size());
|
||||||
if (readFromCache) {
|
if (readFromCache) {
|
||||||
@@ -383,8 +439,7 @@ size_t AsyncAbstractResponse::_readDataFromCacheOrContent(uint8_t* data, const s
|
|||||||
return readFromCache + readFromContent;
|
return readFromCache + readFromContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size_t len)
|
size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t * data, size_t len) {
|
||||||
{
|
|
||||||
if (!_callback)
|
if (!_callback)
|
||||||
return _fillBuffer(data, len);
|
return _fillBuffer(data, len);
|
||||||
|
|
||||||
@@ -393,8 +448,10 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size
|
|||||||
// Now we've read 'len' bytes, either from cache or from file
|
// Now we've read 'len' bytes, either from cache or from file
|
||||||
// Search for template placeholders
|
// Search for template placeholders
|
||||||
uint8_t * pTemplateStart = data;
|
uint8_t * pTemplateStart = data;
|
||||||
while((pTemplateStart < &data[len]) && (pTemplateStart = (uint8_t*)memchr(pTemplateStart, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart + 1))) { // data[0] ... data[len - 1]
|
while ((pTemplateStart < &data[len])
|
||||||
uint8_t* pTemplateEnd = (pTemplateStart < &data[len - 1]) ? (uint8_t*)memchr(pTemplateStart + 1, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart) : nullptr;
|
&& (pTemplateStart = (uint8_t *)memchr(pTemplateStart, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart + 1))) { // data[0] ... data[len - 1]
|
||||||
|
uint8_t * pTemplateEnd =
|
||||||
|
(pTemplateStart < &data[len - 1]) ? (uint8_t *)memchr(pTemplateStart + 1, TEMPLATE_PLACEHOLDER, &data[len - 1] - pTemplateStart) : nullptr;
|
||||||
// temporary buffer to hold parameter name
|
// temporary buffer to hold parameter name
|
||||||
uint8_t buf[TEMPLATE_PARAM_NAME_LENGTH + 1];
|
uint8_t buf[TEMPLATE_PARAM_NAME_LENGTH + 1];
|
||||||
String paramName;
|
String paramName;
|
||||||
@@ -414,7 +471,8 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size
|
|||||||
}
|
}
|
||||||
} else if (&data[len - 1] - pTemplateStart + 1 < TEMPLATE_PARAM_NAME_LENGTH + 2) { // closing placeholder not found, check if it's in the remaining file data
|
} else if (&data[len - 1] - pTemplateStart + 1 < TEMPLATE_PARAM_NAME_LENGTH + 2) { // closing placeholder not found, check if it's in the remaining file data
|
||||||
memcpy(buf, pTemplateStart + 1, &data[len - 1] - pTemplateStart);
|
memcpy(buf, pTemplateStart + 1, &data[len - 1] - pTemplateStart);
|
||||||
const size_t readFromCacheOrContent = _readDataFromCacheOrContent(buf + (&data[len - 1] - pTemplateStart), TEMPLATE_PARAM_NAME_LENGTH + 2 - (&data[len - 1] - pTemplateStart + 1));
|
const size_t readFromCacheOrContent =
|
||||||
|
_readDataFromCacheOrContent(buf + (&data[len - 1] - pTemplateStart), TEMPLATE_PARAM_NAME_LENGTH + 2 - (&data[len - 1] - pTemplateStart + 1));
|
||||||
if (readFromCacheOrContent) {
|
if (readFromCacheOrContent) {
|
||||||
pTemplateEnd = (uint8_t *)memchr(buf + (&data[len - 1] - pTemplateStart), TEMPLATE_PLACEHOLDER, readFromCacheOrContent);
|
pTemplateEnd = (uint8_t *)memchr(buf + (&data[len - 1] - pTemplateStart), TEMPLATE_PLACEHOLDER, readFromCacheOrContent);
|
||||||
if (pTemplateEnd) {
|
if (pTemplateEnd) {
|
||||||
@@ -424,18 +482,15 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size
|
|||||||
// Copy remaining read-ahead data into cache
|
// Copy remaining read-ahead data into cache
|
||||||
_cache.insert(_cache.begin(), pTemplateEnd + 1, buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
_cache.insert(_cache.begin(), pTemplateEnd + 1, buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
||||||
pTemplateEnd = &data[len - 1];
|
pTemplateEnd = &data[len - 1];
|
||||||
}
|
} else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position
|
||||||
else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position
|
|
||||||
{
|
{
|
||||||
// but first, store read file data in cache
|
// but first, store read file data in cache
|
||||||
_cache.insert(_cache.begin(), buf + (&data[len - 1] - pTemplateStart), buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
_cache.insert(_cache.begin(), buf + (&data[len - 1] - pTemplateStart), buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent);
|
||||||
++pTemplateStart;
|
++pTemplateStart;
|
||||||
}
|
}
|
||||||
}
|
} else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position
|
||||||
else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position
|
|
||||||
++pTemplateStart;
|
++pTemplateStart;
|
||||||
}
|
} else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position
|
||||||
else // closing placeholder not found in content data, store found percent symbol as is and advance to the next position
|
|
||||||
++pTemplateStart;
|
++pTemplateStart;
|
||||||
if (paramName.length()) {
|
if (paramName.length()) {
|
||||||
// call callback and replace with result.
|
// call callback and replace with result.
|
||||||
@@ -492,29 +547,49 @@ void AsyncFileResponse::_setContentType(const String& path){
|
|||||||
extern const __FlashStringHelper * getContentType(const String & path);
|
extern const __FlashStringHelper * getContentType(const String & path);
|
||||||
_contentType = getContentType(path);
|
_contentType = getContentType(path);
|
||||||
#else
|
#else
|
||||||
if (path.endsWith(F(".html"))) _contentType = F("text/html");
|
if (path.endsWith(F(".html")))
|
||||||
else if (path.endsWith(F(".htm"))) _contentType = F("text/html");
|
_contentType = F("text/html");
|
||||||
else if (path.endsWith(F(".css"))) _contentType = F("text/css");
|
else if (path.endsWith(F(".htm")))
|
||||||
else if (path.endsWith(F(".json"))) _contentType = F("application/json");
|
_contentType = F("text/html");
|
||||||
else if (path.endsWith(F(".js"))) _contentType = F("application/javascript");
|
else if (path.endsWith(F(".css")))
|
||||||
else if (path.endsWith(F(".png"))) _contentType = F("image/png");
|
_contentType = F("text/css");
|
||||||
else if (path.endsWith(F(".gif"))) _contentType = F("image/gif");
|
else if (path.endsWith(F(".json")))
|
||||||
else if (path.endsWith(F(".jpg"))) _contentType = F("image/jpeg");
|
_contentType = F("application/json");
|
||||||
else if (path.endsWith(F(".ico"))) _contentType = F("image/x-icon");
|
else if (path.endsWith(F(".js")))
|
||||||
else if (path.endsWith(F(".svg"))) _contentType = F("image/svg+xml");
|
_contentType = F("application/javascript");
|
||||||
else if (path.endsWith(F(".eot"))) _contentType = F("font/eot");
|
else if (path.endsWith(F(".png")))
|
||||||
else if (path.endsWith(F(".woff"))) _contentType = F("font/woff");
|
_contentType = F("image/png");
|
||||||
else if (path.endsWith(F(".woff2"))) _contentType = F("font/woff2");
|
else if (path.endsWith(F(".gif")))
|
||||||
else if (path.endsWith(F(".ttf"))) _contentType = F("font/ttf");
|
_contentType = F("image/gif");
|
||||||
else if (path.endsWith(F(".xml"))) _contentType = F("text/xml");
|
else if (path.endsWith(F(".jpg")))
|
||||||
else if (path.endsWith(F(".pdf"))) _contentType = F("application/pdf");
|
_contentType = F("image/jpeg");
|
||||||
else if (path.endsWith(F(".zip"))) _contentType = F("application/zip");
|
else if (path.endsWith(F(".ico")))
|
||||||
else if(path.endsWith(F(".gz"))) _contentType = F("application/x-gzip");
|
_contentType = F("image/x-icon");
|
||||||
else _contentType = F("text/plain");
|
else if (path.endsWith(F(".svg")))
|
||||||
|
_contentType = F("image/svg+xml");
|
||||||
|
else if (path.endsWith(F(".eot")))
|
||||||
|
_contentType = F("font/eot");
|
||||||
|
else if (path.endsWith(F(".woff")))
|
||||||
|
_contentType = F("font/woff");
|
||||||
|
else if (path.endsWith(F(".woff2")))
|
||||||
|
_contentType = F("font/woff2");
|
||||||
|
else if (path.endsWith(F(".ttf")))
|
||||||
|
_contentType = F("font/ttf");
|
||||||
|
else if (path.endsWith(F(".xml")))
|
||||||
|
_contentType = F("text/xml");
|
||||||
|
else if (path.endsWith(F(".pdf")))
|
||||||
|
_contentType = F("application/pdf");
|
||||||
|
else if (path.endsWith(F(".zip")))
|
||||||
|
_contentType = F("application/zip");
|
||||||
|
else if (path.endsWith(F(".gz")))
|
||||||
|
_contentType = F("application/x-gzip");
|
||||||
|
else
|
||||||
|
_contentType = F("text/plain");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFileResponse::AsyncFileResponse(FS &fs, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback): AsyncAbstractResponse(callback){
|
AsyncFileResponse::AsyncFileResponse(FS & fs, const String & path, const String & contentType, bool download, AwsTemplateProcessor callback)
|
||||||
|
: AsyncAbstractResponse(callback) {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_path = path;
|
_path = path;
|
||||||
|
|
||||||
@@ -548,7 +623,8 @@ AsyncFileResponse::AsyncFileResponse(FS &fs, const String& path, const String& c
|
|||||||
addHeader(F("Content-Disposition"), buf);
|
addHeader(F("Content-Disposition"), buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncFileResponse::AsyncFileResponse(File content, const String& path, const String& contentType, bool download, AwsTemplateProcessor callback): AsyncAbstractResponse(callback){
|
AsyncFileResponse::AsyncFileResponse(File content, const String & path, const String & contentType, bool download, AwsTemplateProcessor callback)
|
||||||
|
: AsyncAbstractResponse(callback) {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_path = path;
|
_path = path;
|
||||||
|
|
||||||
@@ -587,7 +663,8 @@ size_t AsyncFileResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||||||
* Stream Response
|
* Stream Response
|
||||||
* */
|
* */
|
||||||
|
|
||||||
AsyncStreamResponse::AsyncStreamResponse(Stream &stream, const String& contentType, size_t len, AwsTemplateProcessor callback): AsyncAbstractResponse(callback) {
|
AsyncStreamResponse::AsyncStreamResponse(Stream & stream, const String & contentType, size_t len, AwsTemplateProcessor callback)
|
||||||
|
: AsyncAbstractResponse(callback) {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_content = &stream;
|
_content = &stream;
|
||||||
_contentLength = len;
|
_contentLength = len;
|
||||||
@@ -607,7 +684,8 @@ size_t AsyncStreamResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||||||
* Callback Response
|
* Callback Response
|
||||||
* */
|
* */
|
||||||
|
|
||||||
AsyncCallbackResponse::AsyncCallbackResponse(const String& contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback): AsyncAbstractResponse(templateCallback) {
|
AsyncCallbackResponse::AsyncCallbackResponse(const String & contentType, size_t len, AwsResponseFiller callback, AwsTemplateProcessor templateCallback)
|
||||||
|
: AsyncAbstractResponse(templateCallback) {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_content = callback;
|
_content = callback;
|
||||||
_contentLength = len;
|
_contentLength = len;
|
||||||
@@ -629,7 +707,8 @@ size_t AsyncCallbackResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||||||
* Chunked Response
|
* Chunked Response
|
||||||
* */
|
* */
|
||||||
|
|
||||||
AsyncChunkedResponse::AsyncChunkedResponse(const String& contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback): AsyncAbstractResponse(processorCallback) {
|
AsyncChunkedResponse::AsyncChunkedResponse(const String & contentType, AwsResponseFiller callback, AwsTemplateProcessor processorCallback)
|
||||||
|
: AsyncAbstractResponse(processorCallback) {
|
||||||
_code = 200;
|
_code = 200;
|
||||||
_content = callback;
|
_content = callback;
|
||||||
_contentLength = 0;
|
_contentLength = 0;
|
||||||
@@ -651,7 +730,8 @@ size_t AsyncChunkedResponse::_fillBuffer(uint8_t *data, size_t len){
|
|||||||
* Progmem Response
|
* Progmem Response
|
||||||
* */
|
* */
|
||||||
|
|
||||||
AsyncProgmemResponse::AsyncProgmemResponse(int code, const String& contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback): AsyncAbstractResponse(callback) {
|
AsyncProgmemResponse::AsyncProgmemResponse(int code, const String & contentType, const uint8_t * content, size_t len, AwsTemplateProcessor callback)
|
||||||
|
: AsyncAbstractResponse(callback) {
|
||||||
_code = code;
|
_code = code;
|
||||||
_content = content;
|
_content = content;
|
||||||
_contentType = contentType;
|
_contentType = contentType;
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ class HttpPostEndpoint {
|
|||||||
response->setLength();
|
response->setLength();
|
||||||
|
|
||||||
if (outcome == StateUpdateResult::CHANGED_RESTART) {
|
if (outcome == StateUpdateResult::CHANGED_RESTART) {
|
||||||
response->setCode(202); // added by proddy
|
response->setCode(205); // added by proddy, reboot required
|
||||||
}
|
}
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ void WiFiScanner::scanNetworks(AsyncWebServerRequest * request) {
|
|||||||
WiFi.scanDelete();
|
WiFi.scanDelete();
|
||||||
WiFi.scanNetworks(true);
|
WiFi.scanNetworks(true);
|
||||||
}
|
}
|
||||||
request->send(202);
|
request->send(202); // special code to indicate scan in progress
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
|
void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
|
||||||
@@ -36,7 +36,7 @@ void WiFiScanner::listNetworks(AsyncWebServerRequest * request) {
|
|||||||
response->setLength();
|
response->setLength();
|
||||||
request->send(response);
|
request->send(response);
|
||||||
} else if (numNetworks == -1) {
|
} else if (numNetworks == -1) {
|
||||||
request->send(202);
|
request->send(202); // special code to indicate scan in progress
|
||||||
} else {
|
} else {
|
||||||
scanNetworks(request);
|
scanNetworks(request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -480,7 +480,7 @@ const emsesp_sensordata = {
|
|||||||
{ id: '28-233D-9497-0C03', n: 'Dallas 1', t: 25.7, o: 1.2, u: 1 },
|
{ id: '28-233D-9497-0C03', n: 'Dallas 1', t: 25.7, o: 1.2, u: 1 },
|
||||||
{ id: '28-243D-7437-1E3A', n: 'Dallas 2 outside', t: 26.1, o: 0, u: 1 },
|
{ id: '28-243D-7437-1E3A', n: 'Dallas 2 outside', t: 26.1, o: 0, u: 1 },
|
||||||
{ id: '28-243E-7437-1E3B', n: 'Zolder', t: 27.1, o: 0, u: 16 },
|
{ id: '28-243E-7437-1E3B', n: 'Zolder', t: 27.1, o: 0, u: 16 },
|
||||||
{ id: '28-183D-1892-0C33', n: 'Roof', o: 2, u: 1 }
|
{ id: '28-183D-1892-0C33', n: 'Roof', o: 2, u: 1 } // no temperature
|
||||||
],
|
],
|
||||||
// as: [],
|
// as: [],
|
||||||
as: [
|
as: [
|
||||||
@@ -512,95 +512,15 @@ const status = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Dashboard data
|
// Dashboard data
|
||||||
// 7 - Nefit Trendline boiler
|
|
||||||
// 1 - RC35 thermo
|
// 1 - RC35 thermo
|
||||||
// 2 - RC20 thermo
|
// 2 - RC20 thermo
|
||||||
// 3 - Buderus GB125 boiler
|
// 3 - Buderus GB125 boiler
|
||||||
// 4 - RC100 themo
|
// 4 - RC100 themo
|
||||||
// 5 - Mixer MM10
|
// 5 - Mixer MM10
|
||||||
// 6 - Solar SM10
|
// 6 - Solar SM10
|
||||||
|
// 7 - Nefit Trendline boiler
|
||||||
// 99 - Custom
|
// 99 - Custom
|
||||||
|
|
||||||
const emsesp_devicedata_7 = {
|
|
||||||
data: [
|
|
||||||
{ v: '', u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
|
|
||||||
{ v: 'off', u: 0, id: '08heating active' },
|
|
||||||
{ v: 'off', u: 0, id: '04tapwater active' },
|
|
||||||
{ v: 5, u: 1, id: '04selected flow temperature', c: 'selflowtemp' },
|
|
||||||
{ v: 0, u: 3, id: '0Eburner selected max power', c: 'selburnpow' },
|
|
||||||
{ v: 0, u: 3, id: '00heating pump modulation' },
|
|
||||||
{ v: 53.4, u: 1, id: '00current flow temperature' },
|
|
||||||
{ v: 52.7, u: 1, id: '00return temperature' },
|
|
||||||
{ v: 1.3, u: 10, id: '00system pressure' },
|
|
||||||
{ v: 54.9, u: 1, id: '00actual boiler temperature' },
|
|
||||||
{ v: 'off', u: 0, id: '00gas' },
|
|
||||||
{ v: 'off', u: 0, id: '00gas stage 2' },
|
|
||||||
{ v: 0, u: 9, id: '00flame current' },
|
|
||||||
{ v: 'off', u: 0, id: '00heating pump' },
|
|
||||||
{ v: 'off', u: 0, id: '00fan' },
|
|
||||||
{ v: 'off', u: 0, id: '00ignition' },
|
|
||||||
{ v: 'off', u: 0, id: '00oil preheating' },
|
|
||||||
{ v: 'on', u: 0, id: '00heating activated', c: 'heatingactivated', l: ['off', 'on'] },
|
|
||||||
{ v: 80, u: 1, id: '00heating temperature', c: 'heatingtemp' },
|
|
||||||
{ v: 70, u: 3, id: '00burner pump max power', c: 'pumpmodmax' },
|
|
||||||
{ v: 30, u: 3, id: '00burner pump min power', c: 'pumpmodmin' },
|
|
||||||
{ v: 1, u: 8, id: '00pump delay', c: 'pumpdelay' },
|
|
||||||
{ v: 10, u: 8, id: '00burner min period', c: 'burnminperiod' },
|
|
||||||
{ v: 0, u: 3, id: '00burner min power', c: 'burnminpower' },
|
|
||||||
{ v: 50, u: 3, id: '00burner max power', c: 'burnmaxpower' },
|
|
||||||
{ v: -6, u: 2, id: '00hysteresis on temperature', c: 'boilhyston' },
|
|
||||||
{ v: 6, u: 2, id: '00hysteresis off temperature', c: 'boilhystoff' },
|
|
||||||
{ v: 0, u: 1, id: '00set flow temperature' },
|
|
||||||
{ v: 0, u: 3, id: '00burner set power' },
|
|
||||||
{ v: 0, u: 3, id: '00burner current power' },
|
|
||||||
{ v: 326323, u: 0, id: '00burner starts' },
|
|
||||||
{ v: 553437, u: 8, id: '00total burner operating time' },
|
|
||||||
{ v: 451286, u: 8, id: '00total heat operating time' },
|
|
||||||
{ v: 4672173, u: 8, id: '00total UBA operating time' },
|
|
||||||
{ v: '1C(210) 06.06.2020 12:07 (0 min)', u: 0, id: '00last error code' },
|
|
||||||
{ v: '0H', u: 0, id: '00service code' },
|
|
||||||
{ v: 203, u: 0, id: '00service code number' },
|
|
||||||
{ v: 'H00', u: 0, id: '00maintenance message' },
|
|
||||||
{ v: 'manual', u: 0, id: '00maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] },
|
|
||||||
{ v: 6000, u: 7, id: '00time to next maintenance', c: 'maintenancetime' },
|
|
||||||
{ v: '01.01.2012', u: 0, id: '00next maintenance date', c: 'maintenancedate', o: 'Format: < dd.mm.yyyy >' },
|
|
||||||
{ v: 'on', u: 0, id: '00dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] },
|
|
||||||
{ v: 62, u: 1, id: '00dhw set temperature' },
|
|
||||||
{ v: 60, u: 1, id: '00dhw selected temperature', c: 'wwseltemp' },
|
|
||||||
{ v: 'flow', u: 0, id: '00dhw type' },
|
|
||||||
{ v: 'hot', u: 0, id: '00dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] },
|
|
||||||
{ v: 40, u: 2, id: '00dhw flow temperature offset', c: 'wwflowtempoffset' },
|
|
||||||
{ v: 100, u: 3, id: '00dhw max power', c: 'wwmaxpower' },
|
|
||||||
{ v: 'off', u: 0, id: '00dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] },
|
|
||||||
{ v: '3-way valve', u: 0, id: '00dhw charging type' },
|
|
||||||
{ v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'wwhyston' },
|
|
||||||
{ v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'wwhystoff' },
|
|
||||||
{ v: 70, u: 1, id: '00dhw disinfection temperature', c: 'wwdisinfectiontemp' },
|
|
||||||
{
|
|
||||||
v: 'off',
|
|
||||||
u: 0,
|
|
||||||
id: '00dhw circulation pump mode',
|
|
||||||
c: 'wwcircmode',
|
|
||||||
l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous']
|
|
||||||
},
|
|
||||||
{ v: 'off', u: 0, id: '00dhw circulation active', c: 'wwcirc', l: ['off', 'on'] },
|
|
||||||
{ v: 47.3, u: 1, id: '00dhw current intern temperature' },
|
|
||||||
{ v: 0, u: 4, id: '00dhw current tap water flow' },
|
|
||||||
{ v: 47.3, u: 1, id: '00dhw storage intern temperature' },
|
|
||||||
{ v: 'on', u: 0, id: '00dhw activated', c: 'wwactivated', l: ['off', 'on'] },
|
|
||||||
{ v: 'off', u: 0, id: '00dhw one time charging', c: 'wwonetime', l: ['off', 'on'] },
|
|
||||||
{ v: 'off', u: 0, id: '00dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] },
|
|
||||||
{ v: 'off', u: 0, id: '00dhw charging' },
|
|
||||||
{ v: 'off', u: 0, id: '00dhw recharging' },
|
|
||||||
{ v: 'on', u: 0, id: '00dhw temperature ok' },
|
|
||||||
{ v: 'off', u: 0, id: '00dhw active' },
|
|
||||||
{ v: 'on', u: 0, id: '00dhw 3way valve active' },
|
|
||||||
{ v: 0, u: 3, id: '00dhw set pump power' },
|
|
||||||
{ v: 288768, u: 0, id: '00dhw starts' },
|
|
||||||
{ v: 102151, u: 8, id: '00dhw active time' }
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const emsesp_devicedata_1 = {
|
const emsesp_devicedata_1 = {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
@@ -1768,6 +1688,86 @@ const emsesp_devicedata_6 = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const emsesp_devicedata_7 = {
|
||||||
|
data: [
|
||||||
|
{ v: '', u: 0, id: '08reset', c: 'reset', l: ['-', 'maintenance', 'error'] },
|
||||||
|
{ v: 'off', u: 0, id: '08heating active' },
|
||||||
|
{ v: 'off', u: 0, id: '04tapwater active' },
|
||||||
|
{ v: 5, u: 1, id: '04selected flow temperature', c: 'selflowtemp' },
|
||||||
|
{ v: 0, u: 3, id: '0Eburner selected max power', c: 'selburnpow' },
|
||||||
|
{ v: 0, u: 3, id: '00heating pump modulation' },
|
||||||
|
{ v: 53.4, u: 1, id: '00current flow temperature' },
|
||||||
|
{ v: 52.7, u: 1, id: '00return temperature' },
|
||||||
|
{ v: 1.3, u: 10, id: '00system pressure' },
|
||||||
|
{ v: 54.9, u: 1, id: '00actual boiler temperature' },
|
||||||
|
{ v: 'off', u: 0, id: '00gas' },
|
||||||
|
{ v: 'off', u: 0, id: '00gas stage 2' },
|
||||||
|
{ v: 0, u: 9, id: '00flame current' },
|
||||||
|
{ v: 'off', u: 0, id: '00heating pump' },
|
||||||
|
{ v: 'off', u: 0, id: '00fan' },
|
||||||
|
{ v: 'off', u: 0, id: '00ignition' },
|
||||||
|
{ v: 'off', u: 0, id: '00oil preheating' },
|
||||||
|
{ v: 'on', u: 0, id: '00heating activated', c: 'heatingactivated', l: ['off', 'on'] },
|
||||||
|
{ v: 80, u: 1, id: '00heating temperature', c: 'heatingtemp' },
|
||||||
|
{ v: 70, u: 3, id: '00burner pump max power', c: 'pumpmodmax' },
|
||||||
|
{ v: 30, u: 3, id: '00burner pump min power', c: 'pumpmodmin' },
|
||||||
|
{ v: 1, u: 8, id: '00pump delay', c: 'pumpdelay' },
|
||||||
|
{ v: 10, u: 8, id: '00burner min period', c: 'burnminperiod' },
|
||||||
|
{ v: 0, u: 3, id: '00burner min power', c: 'burnminpower' },
|
||||||
|
{ v: 50, u: 3, id: '00burner max power', c: 'burnmaxpower' },
|
||||||
|
{ v: -6, u: 2, id: '00hysteresis on temperature', c: 'boilhyston' },
|
||||||
|
{ v: 6, u: 2, id: '00hysteresis off temperature', c: 'boilhystoff' },
|
||||||
|
{ v: 0, u: 1, id: '00set flow temperature' },
|
||||||
|
{ v: 0, u: 3, id: '00burner set power' },
|
||||||
|
{ v: 0, u: 3, id: '00burner current power' },
|
||||||
|
{ v: 326323, u: 0, id: '00burner starts' },
|
||||||
|
{ v: 553437, u: 8, id: '00total burner operating time' },
|
||||||
|
{ v: 451286, u: 8, id: '00total heat operating time' },
|
||||||
|
{ v: 4672173, u: 8, id: '00total UBA operating time' },
|
||||||
|
{ v: '1C(210) 06.06.2020 12:07 (0 min)', u: 0, id: '00last error code' },
|
||||||
|
{ v: '0H', u: 0, id: '00service code' },
|
||||||
|
{ v: 203, u: 0, id: '00service code number' },
|
||||||
|
{ v: 'H00', u: 0, id: '00maintenance message' },
|
||||||
|
{ v: 'manual', u: 0, id: '00maintenance scheduled', c: 'maintenance', l: ['off', 'time', 'date', 'manual'] },
|
||||||
|
{ v: 6000, u: 7, id: '00time to next maintenance', c: 'maintenancetime' },
|
||||||
|
{ v: '01.01.2012', u: 0, id: '00next maintenance date', c: 'maintenancedate', o: 'Format: < dd.mm.yyyy >' },
|
||||||
|
{ v: 'on', u: 0, id: '00dhw turn on/off', c: 'wwtapactivated', l: ['off', 'on'] },
|
||||||
|
{ v: 62, u: 1, id: '00dhw set temperature' },
|
||||||
|
{ v: 60, u: 1, id: '00dhw selected temperature', c: 'wwseltemp' },
|
||||||
|
{ v: 'flow', u: 0, id: '00dhw type' },
|
||||||
|
{ v: 'hot', u: 0, id: '00dhw comfort', c: 'wwcomfort', l: ['hot', 'eco', 'intelligent'] },
|
||||||
|
{ v: 40, u: 2, id: '00dhw flow temperature offset', c: 'wwflowtempoffset' },
|
||||||
|
{ v: 100, u: 3, id: '00dhw max power', c: 'wwmaxpower' },
|
||||||
|
{ v: 'off', u: 0, id: '00dhw circulation pump available', c: 'wwcircpump', l: ['off', 'on'] },
|
||||||
|
{ v: '3-way valve', u: 0, id: '00dhw charging type' },
|
||||||
|
{ v: -5, u: 2, id: '00dhw hysteresis on temperature', c: 'wwhyston' },
|
||||||
|
{ v: 0, u: 2, id: '00dhw hysteresis off temperature', c: 'wwhystoff' },
|
||||||
|
{ v: 70, u: 1, id: '00dhw disinfection temperature', c: 'wwdisinfectiontemp' },
|
||||||
|
{
|
||||||
|
v: 'off',
|
||||||
|
u: 0,
|
||||||
|
id: '00dhw circulation pump mode',
|
||||||
|
c: 'wwcircmode',
|
||||||
|
l: ['off', '1x3min', '2x3min', '3x3min', '4x3min', '5x3min', '6x3min', 'continuous']
|
||||||
|
},
|
||||||
|
{ v: 'off', u: 0, id: '00dhw circulation active', c: 'wwcirc', l: ['off', 'on'] },
|
||||||
|
{ v: 47.3, u: 1, id: '00dhw current intern temperature' },
|
||||||
|
{ v: 0, u: 4, id: '00dhw current tap water flow' },
|
||||||
|
{ v: 47.3, u: 1, id: '00dhw storage intern temperature' },
|
||||||
|
{ v: 'on', u: 0, id: '00dhw activated', c: 'wwactivated', l: ['off', 'on'] },
|
||||||
|
{ v: 'off', u: 0, id: '00dhw one time charging', c: 'wwonetime', l: ['off', 'on'] },
|
||||||
|
{ v: 'off', u: 0, id: '00dhw disinfecting', c: 'wwdisinfecting', l: ['off', 'on'] },
|
||||||
|
{ v: 'off', u: 0, id: '00dhw charging' },
|
||||||
|
{ v: 'off', u: 0, id: '00dhw recharging' },
|
||||||
|
{ v: 'on', u: 0, id: '00dhw temperature ok' },
|
||||||
|
{ v: 'off', u: 0, id: '00dhw active' },
|
||||||
|
{ v: 'on', u: 0, id: '00dhw 3way valve active' },
|
||||||
|
{ v: 0, u: 3, id: '00dhw set pump power' },
|
||||||
|
{ v: 288768, u: 0, id: '00dhw starts' },
|
||||||
|
{ v: 102151, u: 8, id: '00dhw active time' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
const emsesp_devicedata_99 = {
|
const emsesp_devicedata_99 = {
|
||||||
data: [
|
data: [
|
||||||
{
|
{
|
||||||
@@ -2026,7 +2026,7 @@ rest_server.get(LIST_NETWORKS_ENDPOINT, (req, res) => {
|
|||||||
res.json(list_networks);
|
res.json(list_networks);
|
||||||
});
|
});
|
||||||
rest_server.get(SCAN_NETWORKS_ENDPOINT, (req, res) => {
|
rest_server.get(SCAN_NETWORKS_ENDPOINT, (req, res) => {
|
||||||
res.sendStatus(202);
|
res.sendStatus(202); // reboot required
|
||||||
});
|
});
|
||||||
|
|
||||||
// AP
|
// AP
|
||||||
@@ -2100,6 +2100,7 @@ rest_server.get(VERIFY_AUTHORIZATION_ENDPOINT, (req, res) => {
|
|||||||
res.json(verify_authentication);
|
res.json(verify_authentication);
|
||||||
});
|
});
|
||||||
rest_server.post(RESTART_ENDPOINT, (req, res) => {
|
rest_server.post(RESTART_ENDPOINT, (req, res) => {
|
||||||
|
console.log('command: restart');
|
||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
});
|
});
|
||||||
rest_server.post(FACTORY_RESET_ENDPOINT, (req, res) => {
|
rest_server.post(FACTORY_RESET_ENDPOINT, (req, res) => {
|
||||||
@@ -2128,7 +2129,7 @@ rest_server.get(EMSESP_SETTINGS_ENDPOINT, (req, res) => {
|
|||||||
rest_server.post(EMSESP_SETTINGS_ENDPOINT, (req, res) => {
|
rest_server.post(EMSESP_SETTINGS_ENDPOINT, (req, res) => {
|
||||||
settings = req.body;
|
settings = req.body;
|
||||||
console.log('Write settings: ' + JSON.stringify(settings));
|
console.log('Write settings: ' + JSON.stringify(settings));
|
||||||
// res.status(202).json(settings); // restart needed
|
// res.status(205).json(settings); // restart needed
|
||||||
res.status(200).json(settings); // no restart needed
|
res.status(200).json(settings); // no restart needed
|
||||||
});
|
});
|
||||||
rest_server.get(EMSESP_CORE_DATA_ENDPOINT, (req, res) => {
|
rest_server.get(EMSESP_CORE_DATA_ENDPOINT, (req, res) => {
|
||||||
@@ -2184,8 +2185,9 @@ rest_server.get(EMSESP_DEVICEDATA_ENDPOINT, (req, res) => {
|
|||||||
res.end(null, 'binary');
|
res.end(null, 'binary');
|
||||||
});
|
});
|
||||||
|
|
||||||
rest_server.post(EMSESP_DEVICEENTITIES_ENDPOINT, (req, res) => {
|
rest_server.get(EMSESP_DEVICEENTITIES_ENDPOINT, (req, res) => {
|
||||||
const id = req.body.id;
|
const id = Number(req.query.id);
|
||||||
|
console.log('deviceentities for device ' + id + ' received');
|
||||||
let data = null;
|
let data = null;
|
||||||
|
|
||||||
if (id === 1) {
|
if (id === 1) {
|
||||||
@@ -2233,6 +2235,7 @@ function updateMask(entity, de, dd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// find in dd, either looking for fullname or custom name
|
// find in dd, either looking for fullname or custom name
|
||||||
|
// console.log('looking for ' + fullname + ' in ' + dd.data);
|
||||||
dd_objIndex = dd.data.findIndex((obj) => obj.id.slice(2) === fullname);
|
dd_objIndex = dd.data.findIndex((obj) => obj.id.slice(2) === fullname);
|
||||||
if (dd_objIndex !== -1) {
|
if (dd_objIndex !== -1) {
|
||||||
let changed = new Boolean(false);
|
let changed = new Boolean(false);
|
||||||
@@ -2432,10 +2435,12 @@ rest_server.post(EMSESP_WRITE_ANALOG_ENDPOINT, (req, res) => {
|
|||||||
res.sendStatus(200);
|
res.sendStatus(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
rest_server.post(EMSESP_BOARDPROFILE_ENDPOINT, (req, res) => {
|
rest_server.get(EMSESP_BOARDPROFILE_ENDPOINT, (req, res) => {
|
||||||
const board_profile = req.body.board_profile;
|
const board_profile = req.query.boardProfile;
|
||||||
|
|
||||||
|
// default values
|
||||||
const data = {
|
const data = {
|
||||||
|
board_profile: board_profile,
|
||||||
led_gpio: settings.led_gpio,
|
led_gpio: settings.led_gpio,
|
||||||
dallas_gpio: settings.dallas_gpio,
|
dallas_gpio: settings.dallas_gpio,
|
||||||
rx_gpio: settings.rx_gpio,
|
rx_gpio: settings.rx_gpio,
|
||||||
@@ -2559,9 +2564,10 @@ rest_server.post(EMSESP_BOARDPROFILE_ENDPOINT, (req, res) => {
|
|||||||
data.eth_clock_mode = 0;
|
data.eth_clock_mode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('boardProfile POST. Sending back, profile: ' + board_profile + ', ' + 'data: ' + JSON.stringify(data));
|
console.log('boardProfile GET. Sending back, profile: ' + board_profile + ', ' + 'data: ' + JSON.stringify(data));
|
||||||
|
|
||||||
res.send(data);
|
// res.sendStatus(400); // send back an error, for testing
|
||||||
|
res.json(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
// EMS-ESP API specific
|
// EMS-ESP API specific
|
||||||
|
|||||||
@@ -33,10 +33,12 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
|
|||||||
, _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE)
|
, _fsPersistence(WebCustomization::read, WebCustomization::update, this, fs, EMSESP_CUSTOMIZATION_FILE)
|
||||||
, _masked_entities_handler(CUSTOM_ENTITIES_PATH,
|
, _masked_entities_handler(CUSTOM_ENTITIES_PATH,
|
||||||
securityManager->wrapCallback(std::bind(&WebCustomizationService::custom_entities, this, _1, _2),
|
securityManager->wrapCallback(std::bind(&WebCustomizationService::custom_entities, this, _1, _2),
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED))
|
|
||||||
, _device_entities_handler(DEVICE_ENTITIES_PATH,
|
|
||||||
securityManager->wrapCallback(std::bind(&WebCustomizationService::device_entities, this, _1, _2),
|
|
||||||
AuthenticationPredicates::IS_AUTHENTICATED)) {
|
AuthenticationPredicates::IS_AUTHENTICATED)) {
|
||||||
|
server->on(DEVICE_ENTITIES_PATH,
|
||||||
|
HTTP_GET,
|
||||||
|
securityManager->wrapRequest(std::bind(&WebCustomizationService::device_entities, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
|
|
||||||
|
|
||||||
server->on(DEVICES_SERVICE_PATH,
|
server->on(DEVICES_SERVICE_PATH,
|
||||||
HTTP_GET,
|
HTTP_GET,
|
||||||
securityManager->wrapRequest(std::bind(&WebCustomizationService::devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
securityManager->wrapRequest(std::bind(&WebCustomizationService::devices, this, _1), AuthenticationPredicates::IS_AUTHENTICATED));
|
||||||
@@ -49,10 +51,6 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
|
|||||||
_masked_entities_handler.setMaxContentLength(2048);
|
_masked_entities_handler.setMaxContentLength(2048);
|
||||||
_masked_entities_handler.setMaxJsonBufferSize(2048);
|
_masked_entities_handler.setMaxJsonBufferSize(2048);
|
||||||
server->addHandler(&_masked_entities_handler);
|
server->addHandler(&_masked_entities_handler);
|
||||||
|
|
||||||
_device_entities_handler.setMethod(HTTP_POST);
|
|
||||||
_device_entities_handler.setMaxContentLength(256);
|
|
||||||
server->addHandler(&_device_entities_handler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this creates the customization file, saving it to the FS
|
// this creates the customization file, saving it to the FS
|
||||||
@@ -165,7 +163,7 @@ StateUpdateResult WebCustomization::update(JsonObject & root, WebCustomization &
|
|||||||
void WebCustomizationService::reset_customization(AsyncWebServerRequest * request) {
|
void WebCustomizationService::reset_customization(AsyncWebServerRequest * request) {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
if (LittleFS.remove(EMSESP_CUSTOMIZATION_FILE)) {
|
if (LittleFS.remove(EMSESP_CUSTOMIZATION_FILE)) {
|
||||||
AsyncWebServerResponse * response = request->beginResponse(200); // OK
|
AsyncWebServerResponse * response = request->beginResponse(205); // restart needed
|
||||||
request->send(response);
|
request->send(response);
|
||||||
EMSESP::system_.restart_requested(true);
|
EMSESP::system_.restart_requested(true);
|
||||||
return;
|
return;
|
||||||
@@ -199,17 +197,21 @@ void WebCustomizationService::devices(AsyncWebServerRequest * request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send back list of device entities
|
// send back list of device entities
|
||||||
void WebCustomizationService::device_entities(AsyncWebServerRequest * request, JsonVariant & json) {
|
void WebCustomizationService::device_entities(AsyncWebServerRequest * request) {
|
||||||
if (json.is<JsonObject>()) {
|
uint8_t id;
|
||||||
|
if (request->hasParam(F_(id))) {
|
||||||
|
id = Helpers::atoint(request->getParam(F_(id))->value().c_str()); // get id from url
|
||||||
|
|
||||||
size_t buffer = EMSESP_JSON_SIZE_XXXXLARGE;
|
size_t buffer = EMSESP_JSON_SIZE_XXXXLARGE;
|
||||||
auto * response = new MsgpackAsyncJsonResponse(true, buffer);
|
auto * response = new MsgpackAsyncJsonResponse(true, buffer);
|
||||||
|
|
||||||
while (!response->getSize()) {
|
while (!response->getSize()) {
|
||||||
delete response;
|
delete response;
|
||||||
buffer -= 1024;
|
buffer -= 1024;
|
||||||
response = new MsgpackAsyncJsonResponse(true, buffer);
|
response = new MsgpackAsyncJsonResponse(true, buffer);
|
||||||
}
|
}
|
||||||
for (const auto & emsdevice : EMSESP::emsdevices) {
|
for (const auto & emsdevice : EMSESP::emsdevices) {
|
||||||
if (emsdevice->unique_id() == json["id"]) {
|
if (emsdevice->unique_id() == id) {
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
JsonArray output = response->getRoot();
|
JsonArray output = response->getRoot();
|
||||||
emsdevice->generate_values_web_customization(output);
|
emsdevice->generate_values_web_customization(output);
|
||||||
@@ -319,7 +321,7 @@ void WebCustomizationService::custom_entities(AsyncWebServerRequest * request, J
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AsyncWebServerResponse * response = request->beginResponse(need_reboot ? 201 : 200); // OK
|
AsyncWebServerResponse * response = request->beginResponse(need_reboot ? 205 : 200); // reboot or just OK
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,9 @@
|
|||||||
// GET
|
// GET
|
||||||
#define DEVICES_SERVICE_PATH "/rest/devices"
|
#define DEVICES_SERVICE_PATH "/rest/devices"
|
||||||
#define EMSESP_CUSTOMIZATION_SERVICE_PATH "/rest/customization"
|
#define EMSESP_CUSTOMIZATION_SERVICE_PATH "/rest/customization"
|
||||||
|
#define DEVICE_ENTITIES_PATH "/rest/deviceEntities"
|
||||||
|
|
||||||
// POST
|
// POST
|
||||||
#define DEVICE_ENTITIES_PATH "/rest/deviceEntities"
|
|
||||||
#define CUSTOM_ENTITIES_PATH "/rest/customEntities"
|
#define CUSTOM_ENTITIES_PATH "/rest/customEntities"
|
||||||
#define RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations"
|
#define RESET_CUSTOMIZATION_SERVICE_PATH "/rest/resetCustomizations"
|
||||||
|
|
||||||
@@ -91,13 +91,13 @@ class WebCustomizationService : public StatefulService<WebCustomization> {
|
|||||||
|
|
||||||
// GET
|
// GET
|
||||||
void devices(AsyncWebServerRequest * request);
|
void devices(AsyncWebServerRequest * request);
|
||||||
|
void device_entities(AsyncWebServerRequest * request);
|
||||||
|
|
||||||
// POST
|
// POST
|
||||||
void custom_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
void custom_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
||||||
void device_entities(AsyncWebServerRequest * request, JsonVariant & json);
|
void reset_customization(AsyncWebServerRequest * request); // command
|
||||||
void reset_customization(AsyncWebServerRequest * request);
|
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler _masked_entities_handler, _device_entities_handler;
|
AsyncCallbackJsonWebHandler _masked_entities_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -327,6 +327,7 @@ void WebDataService::write_temperature_sensor(AsyncWebServerRequest * request, J
|
|||||||
if (EMSESP::system_.fahrenheit()) {
|
if (EMSESP::system_.fahrenheit()) {
|
||||||
offset10 = offset / 0.18;
|
offset10 = offset / 0.18;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = EMSESP::temperaturesensor_.update(id, name, offset10);
|
ok = EMSESP::temperaturesensor_.update(id, name, offset10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,11 @@ using namespace std::placeholders; // for `_1` etc
|
|||||||
|
|
||||||
WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
|
||||||
: _httpEndpoint(WebSettings::read, WebSettings::update, this, server, EMSESP_SETTINGS_SERVICE_PATH, securityManager)
|
: _httpEndpoint(WebSettings::read, WebSettings::update, this, server, EMSESP_SETTINGS_SERVICE_PATH, securityManager)
|
||||||
, _fsPersistence(WebSettings::read, WebSettings::update, this, fs, EMSESP_SETTINGS_FILE)
|
, _fsPersistence(WebSettings::read, WebSettings::update, this, fs, EMSESP_SETTINGS_FILE) {
|
||||||
, _boardProfileHandler(EMSESP_BOARD_PROFILE_SERVICE_PATH,
|
// GET
|
||||||
securityManager->wrapCallback(std::bind(&WebSettingsService::board_profile, this, _1, _2), AuthenticationPredicates::IS_ADMIN)) {
|
server->on(EMSESP_BOARD_PROFILE_SERVICE_PATH,
|
||||||
_boardProfileHandler.setMethod(HTTP_POST);
|
HTTP_GET,
|
||||||
_boardProfileHandler.setMaxContentLength(256);
|
securityManager->wrapRequest(std::bind(&WebSettingsService::board_profile, this, _1), AuthenticationPredicates::IS_ADMIN));
|
||||||
server->addHandler(&_boardProfileHandler);
|
|
||||||
|
|
||||||
addUpdateHandler([&](const String & originId) { onUpdate(); }, false);
|
addUpdateHandler([&](const String & originId) { onUpdate(); }, false);
|
||||||
}
|
}
|
||||||
@@ -342,15 +341,16 @@ void WebSettingsService::save() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// build the json profile to send back
|
// build the json profile to send back
|
||||||
void WebSettingsService::board_profile(AsyncWebServerRequest * request, JsonVariant & json) {
|
void WebSettingsService::board_profile(AsyncWebServerRequest * request) {
|
||||||
if (json.is<JsonObject>()) {
|
if (request->hasParam("boardProfile")) {
|
||||||
|
std::string board_profile = request->getParam("boardProfile")->value().c_str();
|
||||||
|
|
||||||
auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_MEDIUM);
|
auto * response = new AsyncJsonResponse(false, EMSESP_JSON_SIZE_MEDIUM);
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
if (json.containsKey("board_profile")) {
|
|
||||||
String board_profile = json["board_profile"];
|
|
||||||
std::vector<int8_t> data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
|
std::vector<int8_t> data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
|
||||||
(void)System::load_board_profile(data, board_profile.c_str());
|
(void)System::load_board_profile(data, board_profile);
|
||||||
|
root["board_profile"] = board_profile;
|
||||||
root["led_gpio"] = data[0];
|
root["led_gpio"] = data[0];
|
||||||
root["dallas_gpio"] = data[1];
|
root["dallas_gpio"] = data[1];
|
||||||
root["rx_gpio"] = data[2];
|
root["rx_gpio"] = data[2];
|
||||||
@@ -365,7 +365,6 @@ void WebSettingsService::board_profile(AsyncWebServerRequest * request, JsonVari
|
|||||||
request->send(response);
|
request->send(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AsyncWebServerResponse * response = request->beginResponse(200);
|
AsyncWebServerResponse * response = request->beginResponse(200);
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
|||||||
@@ -124,9 +124,8 @@ class WebSettingsService : public StatefulService<WebSettings> {
|
|||||||
private:
|
private:
|
||||||
HttpEndpoint<WebSettings> _httpEndpoint;
|
HttpEndpoint<WebSettings> _httpEndpoint;
|
||||||
FSPersistence<WebSettings> _fsPersistence;
|
FSPersistence<WebSettings> _fsPersistence;
|
||||||
AsyncCallbackJsonWebHandler _boardProfileHandler;
|
|
||||||
|
|
||||||
void board_profile(AsyncWebServerRequest * request, JsonVariant & json);
|
void board_profile(AsyncWebServerRequest * request);
|
||||||
|
|
||||||
void onUpdate();
|
void onUpdate();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user