optimize endpoints, so re-use where possible

This commit is contained in:
proddy
2024-09-13 10:03:11 +02:00
parent 63a3152b91
commit 191edffe3c
23 changed files with 192 additions and 428 deletions

View File

@@ -6,7 +6,6 @@ import type {
CoreData, CoreData,
DeviceData, DeviceData,
DeviceEntity, DeviceEntity,
Devices,
Entities, Entities,
EntityItem, EntityItem,
ModuleItem, ModuleItem,
@@ -53,11 +52,9 @@ export const readActivity = () => alovaInstance.Get<Activity>('/rest/activity');
// API // API
export const API = (apiCall: APIcall) => alovaInstance.Post('/api', apiCall); export const API = (apiCall: APIcall) => alovaInstance.Post('/api', apiCall);
// UploadFileForm // DownloadUpload
export const getSettings = () => alovaInstance.Get('/rest/getSettings'); export const exportData = (type: string) =>
export const getCustomizations = () => alovaInstance.Get('/rest/getCustomizations'); alovaInstance.Get('/rest/exportData', { params: { type } });
export const getEntities = () => alovaInstance.Get<Entities>('/rest/getEntities');
export const getSchedule = () => alovaInstance.Get('/rest/getSchedule');
// SettingsCustomization // SettingsCustomization
export const readDeviceEntities = (id: number) => export const readDeviceEntities = (id: number) =>
@@ -75,7 +72,6 @@ export const readDeviceEntities = (id: number) =>
})); }));
} }
}); });
export const readDevices = () => alovaInstance.Get<Devices>('/rest/devices');
export const resetCustomizations = () => export const resetCustomizations = () =>
alovaInstance.Post('/rest/resetCustomizations'); alovaInstance.Post('/rest/resetCustomizations');
export const writeCustomizationEntities = (data: { export const writeCustomizationEntities = (data: {

View File

@@ -1,12 +1,8 @@
import type { HardwareStatus, LogSettings, SystemStatus } from 'types'; import type { LogSettings, SystemStatus } from 'types';
import { alovaInstance, alovaInstanceGH } from './endpoints'; import { alovaInstance, alovaInstanceGH } from './endpoints';
// hardwareStatus - also used to ping in Restart monitor for pinging // systemStatus - also used to ping in Restart monitor for pinging
export const readHardwareStatus = () =>
alovaInstance.Get<HardwareStatus>('/rest/hardwareStatus');
// SystemStatus
export const readSystemStatus = () => export const readSystemStatus = () =>
alovaInstance.Get<SystemStatus>('/rest/systemStatus'); alovaInstance.Get<SystemStatus>('/rest/systemStatus');

View File

@@ -50,8 +50,8 @@ import { useI18nContext } from 'i18n/i18n-react';
import { import {
API, API,
readCoreData,
readDeviceEntities, readDeviceEntities,
readDevices,
resetCustomizations, resetCustomizations,
writeCustomizationEntities, writeCustomizationEntities,
writeDeviceName writeDeviceName
@@ -60,7 +60,7 @@ import SettingsCustomizationsDialog from './CustomizationsDialog';
import EntityMaskToggle from './EntityMaskToggle'; import EntityMaskToggle from './EntityMaskToggle';
import OptionIcon from './OptionIcon'; import OptionIcon from './OptionIcon';
import { DeviceEntityMask } from './types'; import { DeviceEntityMask } from './types';
import type { APIcall, DeviceEntity, DeviceShort } from './types'; import type { APIcall, Device, DeviceEntity } from './types';
export const APIURL = window.location.origin + '/api/'; export const APIURL = window.location.origin + '/api/';
@@ -81,8 +81,8 @@ const Customizations = () => {
useLayoutTitle(LL.CUSTOMIZATIONS()); useLayoutTitle(LL.CUSTOMIZATIONS());
// fetch devices first // fetch devices first from coreData
const { data: devices, send: fetchDevices } = useRequest(readDevices); const { data: devices, send: fetchCoreData } = useRequest(readCoreData);
const { send: sendAPI } = useRequest((data: APIcall) => API(data), { const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false immediate: false
@@ -242,13 +242,13 @@ const Customizations = () => {
useEffect(() => { useEffect(() => {
if (devices && selectedDevice !== -1) { if (devices && selectedDevice !== -1) {
void sendDeviceEntities(selectedDevice); void sendDeviceEntities(selectedDevice);
const id = devices.devices.findIndex((d) => d.i === selectedDevice); const index = devices.devices.findIndex((d) => d.id === selectedDevice);
if (id === -1) { if (index === -1) {
setSelectedDevice(-1); setSelectedDevice(-1);
setSelectedDeviceTypeNameURL(''); setSelectedDeviceTypeNameURL('');
} else { } else {
setSelectedDeviceTypeNameURL(devices.devices[id].url || ''); setSelectedDeviceTypeNameURL(devices.devices[index].url || '');
setSelectedDeviceName(devices.devices[id].s); setSelectedDeviceName(devices.devices[index].n);
setNumChanges(0); setNumChanges(0);
setRestartNeeded(false); setRestartNeeded(false);
} }
@@ -414,7 +414,7 @@ const Customizations = () => {
}) })
.finally(async () => { .finally(async () => {
setRename(false); setRename(false);
await fetchDevices(); await fetchCoreData();
}); });
}; };
@@ -449,9 +449,9 @@ const Customizations = () => {
<MenuItem disabled key={-1} value={-1}> <MenuItem disabled key={-1} value={-1}>
{LL.SELECT_DEVICE()}... {LL.SELECT_DEVICE()}...
</MenuItem> </MenuItem>
{devices.devices.map((device: DeviceShort) => ( {devices.devices.map((device: Device) => (
<MenuItem key={device.i} value={device.i}> <MenuItem key={device.id} value={device.id}>
{device.s}&nbsp;({device.tn}) {device.n}&nbsp;({device.tn})
</MenuItem> </MenuItem>
))} ))}
</TextField> </TextField>

View File

@@ -71,6 +71,7 @@ export interface Device {
p: number; // productid p: number; // productid
v: string; // version v: string; // version
e: number; // entities e: number; // entities
url?: string; // lowercase type name used in API URL
} }
export interface TemperatureSensor { export interface TemperatureSensor {
@@ -113,20 +114,6 @@ export interface CoreData {
devices: Device[]; devices: Device[];
} }
export interface DeviceShort {
i: number; // id
d?: number; // deviceid
p?: number; // productid
s: string; // shortname
t?: number; // device type id
tn?: string; // device type internal name (translated)
url?: string; // lowercase type name used in API URL
}
export interface Devices {
devices: DeviceShort[];
}
export interface DeviceValue { export interface DeviceValue {
id: string; // index, contains mask+name id: string; // index, contains mask+name
v: unknown; // value, Number or String v: unknown; // value, Number or String

View File

@@ -16,7 +16,7 @@ import {
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid2'; import Grid from '@mui/material/Grid2';
import { readHardwareStatus } from 'api/system'; import { readSystemStatus } from 'api/system';
import { useRequest } from 'alova/client'; import { useRequest } from 'alova/client';
import RestartMonitor from 'app/status/RestartMonitor'; import RestartMonitor from 'app/status/RestartMonitor';
@@ -49,7 +49,7 @@ export function boardProfileSelectItems() {
} }
const ApplicationSettings = () => { const ApplicationSettings = () => {
const { data: hardwareData } = useRequest(readHardwareStatus); const { data: hardwareData } = useRequest(readSystemStatus);
const { const {
loadData, loadData,

View File

@@ -18,13 +18,7 @@ import {
import Grid from '@mui/material/Grid2'; import Grid from '@mui/material/Grid2';
import * as SystemApi from 'api/system'; import * as SystemApi from 'api/system';
import { import { API, exportData } from 'api/app';
API,
getCustomizations,
getEntities,
getSchedule,
getSettings
} from 'api/app';
import { import {
checkUpgrade, checkUpgrade,
getDevVersion, getDevVersion,
@@ -52,48 +46,26 @@ const DownloadUpload = () => {
const [useDev, setUseDev] = useState<boolean>(false); const [useDev, setUseDev] = useState<boolean>(false);
const [upgradeAvailable, setUpgradeAvailable] = useState<boolean>(false); const [upgradeAvailable, setUpgradeAvailable] = useState<boolean>(false);
const { send: sendSettings } = useRequest(getSettings(), { const { send: sendExportData } = useRequest((type: string) => exportData(type), {
immediate: false immediate: false
}).onSuccess((event) => { })
saveFile(event.data, 'settings.json'); .onSuccess((event) => {
}); saveFile(event.data, event.args[0]);
toast.info(LL.DOWNLOAD_SUCCESSFUL());
const { send: sendCustomizations } = useRequest(getCustomizations(), { })
immediate: false .onError((error) => {
}).onSuccess((event) => { toast.error(error.message);
saveFile(event.data, 'customizations.json'); });
});
const { send: sendEntities } = useRequest(getEntities(), {
immediate: false
}).onSuccess((event) => {
saveFile(event.data, 'custom_entities.json');
});
const { send: sendSchedule } = useRequest(getSchedule(), {
immediate: false
}).onSuccess((event) => {
saveFile(event.data, 'schedule.json');
});
const { send: sendAPI } = useRequest((data: APIcall) => API(data), { const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
immediate: false immediate: false
}); });
const { send: sendAPIandSave } = useRequest((data: APIcall) => API(data), {
immediate: false
}).onSuccess((event) => {
saveFile(
event.data,
String(event.args[0].device) + '_' + String(event.args[0].cmd) + '.txt'
);
});
const { const {
data: data, data: data,
send: loadData, send: loadData,
error error
} = useRequest(SystemApi.readHardwareStatus); } = useRequest(SystemApi.readSystemStatus);
const { send: sendUploadURL } = useRequest( const { send: sendUploadURL } = useRequest(
(data: { url: string }) => uploadURL(data), (data: { url: string }) => uploadURL(data),
@@ -123,6 +95,8 @@ const DownloadUpload = () => {
// immediate: false, // immediate: false,
// initialData: '3.6.5' // initialData: '3.6.5'
}); });
// called immediately to get the latest version, on page load, then check for upgrade
const { data: latestDevVersion } = useRequest(getDevVersion, { const { data: latestDevVersion } = useRequest(getDevVersion, {
// uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/latest/EMS-ESP-3_7_0-dev_31-ESP32-16MB+.bin // uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/latest/EMS-ESP-3_7_0-dev_31-ESP32-16MB+.bin
// immediate: false, // immediate: false,
@@ -175,40 +149,9 @@ const DownloadUpload = () => {
type: 'text/plain' type: 'text/plain'
}) })
); );
anchor.download = 'emsesp_' + filename; anchor.download = 'emsesp_' + filename + '.json';
anchor.click(); anchor.click();
URL.revokeObjectURL(anchor.href); URL.revokeObjectURL(anchor.href);
toast.info(LL.DOWNLOAD_SUCCESSFUL());
};
const downloadSettings = async () => {
await sendSettings().catch((error: Error) => {
toast.error(error.message);
});
};
const downloadCustomizations = async () => {
await sendCustomizations().catch((error: Error) => {
toast.error(error.message);
});
};
const downloadEntities = async () => {
await sendEntities().catch((error: Error) => {
toast.error(error.message);
});
};
const downloadSchedule = async () => {
await sendSchedule().catch((error: Error) => {
toast.error(error.message);
});
};
const callAPIandSave = async (device: string, cmd: string) => {
await sendAPIandSave({ device, cmd, id: 0 }).catch((error: Error) => {
toast.error(error.message);
});
}; };
useLayoutTitle(LL.DOWNLOAD_UPLOAD()); useLayoutTitle(LL.DOWNLOAD_UPLOAD());
@@ -301,7 +244,7 @@ const DownloadUpload = () => {
startIcon={<DownloadIcon />} startIcon={<DownloadIcon />}
variant="outlined" variant="outlined"
color="primary" color="primary"
onClick={downloadSettings} onClick={() => sendExportData('settings')}
> >
{LL.DOWNLOAD(1)}&nbsp;{LL.SETTINGS_OF(LL.APPLICATION())} {LL.DOWNLOAD(1)}&nbsp;{LL.SETTINGS_OF(LL.APPLICATION())}
</Button> </Button>
@@ -311,7 +254,7 @@ const DownloadUpload = () => {
startIcon={<DownloadIcon />} startIcon={<DownloadIcon />}
variant="outlined" variant="outlined"
color="primary" color="primary"
onClick={downloadCustomizations} onClick={() => sendExportData('customizations')}
> >
{LL.DOWNLOAD(1)}&nbsp;{LL.CUSTOMIZATIONS()} {LL.DOWNLOAD(1)}&nbsp;{LL.CUSTOMIZATIONS()}
</Button> </Button>
@@ -320,7 +263,7 @@ const DownloadUpload = () => {
startIcon={<DownloadIcon />} startIcon={<DownloadIcon />}
variant="outlined" variant="outlined"
color="primary" color="primary"
onClick={downloadEntities} onClick={() => sendExportData('entities')}
> >
{LL.DOWNLOAD(1)}&nbsp;{LL.CUSTOM_ENTITIES(0)} {LL.DOWNLOAD(1)}&nbsp;{LL.CUSTOM_ENTITIES(0)}
</Button> </Button>
@@ -329,7 +272,7 @@ const DownloadUpload = () => {
startIcon={<DownloadIcon />} startIcon={<DownloadIcon />}
variant="outlined" variant="outlined"
color="primary" color="primary"
onClick={downloadSchedule} onClick={() => sendExportData('schedule')}
> >
{LL.DOWNLOAD(1)}&nbsp;{LL.SCHEDULE(0)} {LL.DOWNLOAD(1)}&nbsp;{LL.SCHEDULE(0)}
</Button> </Button>

View File

@@ -36,7 +36,7 @@ const HardwareStatus = () => {
data: data, data: data,
send: loadData, send: loadData,
error error
} = useAutoRequest(SystemApi.readHardwareStatus, { pollingTime: 2000 }); } = useAutoRequest(SystemApi.readSystemStatus, { pollingTime: 2000 });
const content = () => { const content = () => {
if (!data) { if (!data) {

View File

@@ -8,7 +8,7 @@ import {
Typography Typography
} from '@mui/material'; } from '@mui/material';
import { readHardwareStatus } from 'api/system'; import { readSystemStatus } from 'api/system';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useAutoRequest } from 'alova/client'; import { useAutoRequest } from 'alova/client';
@@ -22,7 +22,7 @@ const RestartMonitor = () => {
let count = 0; let count = 0;
const { data } = useAutoRequest(readHardwareStatus, { const { data } = useAutoRequest(readSystemStatus, {
pollingTime: 1000, pollingTime: 1000,
force: true, force: true,
initialData: { status: 'Getting ready...' }, initialData: { status: 'Getting ready...' },
@@ -38,7 +38,7 @@ const RestartMonitor = () => {
document.location.href = '/'; document.location.href = '/';
} }
}) })
.onError((error, _method) => { .onError((error) => {
setErrorMessage(error.message); setErrorMessage(error.message);
}); });

View File

@@ -29,8 +29,8 @@ import {
useTheme useTheme
} from '@mui/material'; } from '@mui/material';
import * as SystemApi from 'api/system';
import { API } from 'api/app'; import { API } from 'api/app';
import { readSystemStatus } from 'api/system';
import { dialogStyle } from 'CustomTheme'; import { dialogStyle } from 'CustomTheme';
import { useAutoRequest, useRequest } from 'alova/client'; import { useAutoRequest, useRequest } from 'alova/client';
@@ -63,7 +63,7 @@ const SystemStatus = () => {
data: data, data: data,
send: loadData, send: loadData,
error error
} = useAutoRequest(SystemApi.readSystemStatus, { } = useAutoRequest(readSystemStatus, {
initialData: [], initialData: [],
pollingTime: 5000, pollingTime: 5000,
async middleware(_, next) { async middleware(_, next) {
@@ -101,7 +101,7 @@ const SystemStatus = () => {
const busStatus = () => { const busStatus = () => {
if (data) { if (data) {
switch (data.status) { switch (data.bus_status) {
case busConnectionStatus.BUS_STATUS_CONNECTED: case busConnectionStatus.BUS_STATUS_CONNECTED:
return ( return (
'EMS ' + 'EMS ' +
@@ -120,7 +120,7 @@ const SystemStatus = () => {
}; };
const busStatusHighlight = () => { const busStatusHighlight = () => {
switch (data.status) { switch (data.bus_status) {
case busConnectionStatus.BUS_STATUS_TX_ERRORS: case busConnectionStatus.BUS_STATUS_TX_ERRORS:
return theme.palette.warning.main; return theme.palette.warning.main;
case busConnectionStatus.BUS_STATUS_CONNECTED: case busConnectionStatus.BUS_STATUS_CONNECTED:

View File

@@ -2,8 +2,19 @@ import type { busConnectionStatus } from 'app/main/types';
import type { NetworkConnectionStatus } from './network'; import type { NetworkConnectionStatus } from './network';
export interface HardwareStatus { export interface SystemStatus {
emsesp_version: string; emsesp_version: string;
bus_status: busConnectionStatus;
uptime: number;
bus_uptime: number;
num_devices: number;
num_sensors: number;
num_analogs: number;
ntp_status: number;
mqtt_status: boolean;
ap_status: boolean;
network_status: NetworkConnectionStatus;
wifi_rssi: number;
build_flags: string; build_flags: string;
esp_platform: string; esp_platform: string;
max_alloc_heap: number; max_alloc_heap: number;
@@ -32,22 +43,6 @@ export interface HardwareStatus {
status: string; status: string;
} }
export interface SystemStatus {
emsesp_version: string;
status: busConnectionStatus;
uptime: number;
bus_uptime: number;
num_devices: number;
num_sensors: number;
num_analogs: number;
free_heap: number;
ntp_status: number;
mqtt_status: boolean;
ap_status: boolean;
network_status: NetworkConnectionStatus;
wifi_rssi: number;
}
export enum LogLevel { export enum LogLevel {
ERROR = 3, ERROR = 3,
WARNING = 4, WARNING = 4,

View File

@@ -307,11 +307,10 @@ const mqtt_status = {
}; };
// STATUS // STATUS
const SYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'systemStatus';
const ACTIVITY_ENDPOINT = REST_ENDPOINT_ROOT + 'activity'; const ACTIVITY_ENDPOINT = REST_ENDPOINT_ROOT + 'activity';
// SETTINGS // SETTINGS
const HARDWARE_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'hardwareStatus'; const SYSTEM_STATUS_ENDPOINT = REST_ENDPOINT_ROOT + 'systemStatus';
const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings'; const SECURITY_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'securitySettings';
// SYSTEM SIGNIN // SYSTEM SIGNIN
@@ -322,8 +321,23 @@ const GENERATE_TOKEN_ENDPOINT = REST_ENDPOINT_ROOT + 'generateToken';
const VERSION = '3.7.0-dev.0'; const VERSION = '3.7.0-dev.0';
// const VERSION = '3.6.4'; // const VERSION = '3.6.4';
let hardware_status = { let system_status = {
emsesp_version: VERSION, emsesp_version: VERSION,
bus_status: 0,
// status: 2,
uptime: 77186,
bus_uptime: 77121,
num_devices: 2,
num_sensors: 1,
num_analogs: 1,
free_heap: 143,
ntp_status: 2,
mqtt_status: true,
ap_status: false,
network_status: 3, // wifi connected
// network_status: 10, // ethernet connected
// network_status: 6, // wifi disconnected
wifi_rssi: -41,
esp_platform: 'ESP32S3', esp_platform: 'ESP32S3',
build_flags: 'DEMO', build_flags: 'DEMO',
cpu_type: 'ESP32-S3', cpu_type: 'ESP32-S3',
@@ -331,7 +345,6 @@ let hardware_status = {
cpu_cores: 2, cpu_cores: 2,
cpu_freq_mhz: 240, cpu_freq_mhz: 240,
max_alloc_heap: 191, max_alloc_heap: 191,
free_heap: 211,
arduino_version: 'ESP32 Arduino v2.0.17', arduino_version: 'ESP32 Arduino v2.0.17',
sdk_version: 'v4.4.7-dirty', sdk_version: 'v4.4.7-dirty',
partition: 'app0', partition: 'app0',
@@ -347,30 +360,11 @@ let hardware_status = {
psram_size: 8189, psram_size: 8189,
free_psram: 8166, free_psram: 8166,
has_loader: true, has_loader: true,
// model: '' model: '',
model: 'BBQKees Electronics EMS Gateway E32 V2 (E32 V2.0 P3/2024011)', // model: 'BBQKees Electronics EMS Gateway E32 V2 (E32 V2.0 P3/2024011)',
status: 'downloading' status: 'downloading'
}; };
const system_status = {
emsesp_version: VERSION,
status: 0,
// status: 2,
uptime: 77186,
bus_uptime: 77121,
num_devices: 2,
num_sensors: 1,
num_analogs: 1,
free_heap: 143,
ntp_status: 2,
mqtt_status: true,
ap_status: false,
network_status: 3, // wifi connected
// network_status: 10, // ethernet connected
// network_status: 6, // wifi disconnected
wifi_rssi: -41
};
let security_settings = { let security_settings = {
jwt_secret: 'naughty!', jwt_secret: 'naughty!',
users: [ users: [
@@ -402,7 +396,6 @@ const generate_token = { token: '1234' };
const EMSESP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'settings'; const EMSESP_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'settings';
const EMSESP_CORE_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'coreData'; const EMSESP_CORE_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'coreData';
const EMSESP_SENSOR_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'sensorData'; const EMSESP_SENSOR_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'sensorData';
const EMSESP_DEVICES_ENDPOINT = REST_ENDPOINT_ROOT + 'devices';
const EMSESP_DEVICEDATA_ENDPOINT1 = REST_ENDPOINT_ROOT + 'deviceData'; const EMSESP_DEVICEDATA_ENDPOINT1 = REST_ENDPOINT_ROOT + 'deviceData';
const EMSESP_DEVICEDATA_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceData/:id?'; const EMSESP_DEVICEDATA_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceData/:id?';
@@ -423,13 +416,9 @@ const EMSESP_RESET_CUSTOMIZATIONS_ENDPOINT =
const EMSESP_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule'; const EMSESP_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'schedule';
const EMSESP_CUSTOMENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customEntities'; const EMSESP_CUSTOMENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'customEntities';
const EMSESP_MODULES_ENDPOINT = REST_ENDPOINT_ROOT + 'modules'; const EMSESP_MODULES_ENDPOINT = REST_ENDPOINT_ROOT + 'modules';
const EMSESP_EXPORT_DATA_ENDPOINT = REST_ENDPOINT_ROOT + 'exportData';
// these are used in the API calls only // these are used in the API calls only
const EMSESP_GET_SETTINGS_ENDPOINT = REST_ENDPOINT_ROOT + 'getSettings';
const EMSESP_GET_CUSTOMIZATIONS_ENDPOINT = REST_ENDPOINT_ROOT + 'getCustomizations';
const EMSESP_GET_ENTITIES_ENDPOINT = REST_ENDPOINT_ROOT + 'getEntities';
const EMSESP_GET_SCHEDULE_ENDPOINT = REST_ENDPOINT_ROOT + 'getSchedule';
const EMSESP_SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info'; const EMSESP_SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info';
const emsesp_info = { const emsesp_info = {
@@ -634,74 +623,6 @@ let settings = {
modbus_timeout: 10000 modbus_timeout: 10000
}; };
const emsesp_devices = {
devices: [
{
i: 2,
s: 'RC20',
t: 5,
tn: 'Thermostat',
url: 'thermostat'
},
{
i: 3,
s: 'Buderus GB125',
t: 5,
tn: 'Boiler',
url: 'boiler'
},
{
i: 4,
s: 'Moduline 1000',
t: 5,
tn: 'Thermostat',
url: 'thermostat'
},
{
i: 5,
s: 'MM10',
t: 7,
tn: 'Mixer Module',
url: 'mixer'
},
{
i: 6,
s: 'SM10',
t: 8,
tn: 'Solar Module',
url: 'solar'
},
{
i: 7,
s: 'Trendline HRC30/Generic Heatronic 3',
t: 4,
tn: 'Boiler',
url: 'boiler'
},
{
i: 8,
s: 'Bosch Compress 7000i AW Heat Pump',
t: 5,
tn: 'Boiler/HP',
url: 'boiler'
},
{
i: 9,
s: 'RC100H',
t: 6,
tn: 'Thermostat',
url: 'thermostat'
},
{
i: 10,
s: 'RC310',
t: 6,
tn: 'Thermostat',
url: 'thermostat'
}
]
};
const emsesp_coredata = { const emsesp_coredata = {
connected: true, connected: true,
// connected: false, // connected: false,
@@ -716,7 +637,8 @@ const emsesp_coredata = {
d: 8, d: 8,
p: 123, p: 123,
v: '06.01', v: '06.01',
e: 69 e: 69,
url: 'boiler'
}, },
{ {
id: 3, id: 3,
@@ -727,7 +649,8 @@ const emsesp_coredata = {
d: 8, d: 8,
p: 123, p: 123,
v: '06.01', v: '06.01',
e: 73 e: 73,
url: 'boiler'
}, },
{ {
id: 1, id: 1,
@@ -738,7 +661,8 @@ const emsesp_coredata = {
d: 24, d: 24,
p: 86, p: 86,
v: '04.01', v: '04.01',
e: 57 e: 57,
url: 'thermostat'
}, },
{ {
id: 2, id: 2,
@@ -749,7 +673,8 @@ const emsesp_coredata = {
d: 23, d: 23,
p: 77, p: 77,
v: '03.03', v: '03.03',
e: 6 e: 6,
url: 'thermostat'
}, },
{ {
id: 4, id: 4,
@@ -760,7 +685,8 @@ const emsesp_coredata = {
d: 16, d: 16,
p: 165, p: 165,
v: '04.01', v: '04.01',
e: 3 e: 3,
url: 'thermostat'
}, },
{ {
id: 5, id: 5,
@@ -782,7 +708,8 @@ const emsesp_coredata = {
d: 48, d: 48,
p: 73, p: 73,
v: '01.02', v: '01.02',
e: 22 e: 22,
url: 'solar'
}, },
{ {
id: 8, id: 8,
@@ -793,7 +720,8 @@ const emsesp_coredata = {
d: 8, d: 8,
p: 172, p: 172,
v: '01.20', v: '01.20',
e: 152 e: 152,
url: 'boiler'
}, },
{ {
id: 9, id: 9,
@@ -804,7 +732,8 @@ const emsesp_coredata = {
d: 56, d: 56,
p: 200, p: 200,
v: '40.07', v: '40.07',
e: 4 e: 4,
url: 'thermostat'
}, },
{ {
id: 10, id: 10,
@@ -815,7 +744,8 @@ const emsesp_coredata = {
d: 16, d: 16,
p: 158, p: 158,
v: '73.03', v: '73.03',
e: 63 e: 63,
url: 'thermostat'
} }
] ]
}; };
@@ -3871,10 +3801,26 @@ let emsesp_modules = {
}; };
// CUSTOMIZATION // CUSTOMIZATION
const emsesp_deviceentities_1 = [ const dummy_deviceentities = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false } {
v: 'unknown',
n: 'no entities for this device',
id: 'unknown',
m: 0,
w: false
}
]; ];
// no data for these
const emsesp_deviceentities_1 = dummy_deviceentities;
const emsesp_deviceentities_3 = dummy_deviceentities;
const emsesp_deviceentities_5 = dummy_deviceentities;
const emsesp_deviceentities_6 = dummy_deviceentities;
const emsesp_deviceentities_8 = dummy_deviceentities;
const emsesp_deviceentities_9 = dummy_deviceentities;
const emsesp_deviceentities_10 = dummy_deviceentities;
const emsesp_deviceentities_none = dummy_deviceentities;
const emsesp_deviceentities_2 = [ const emsesp_deviceentities_2 = [
{ {
v: '(0)', v: '(0)',
@@ -3916,10 +3862,6 @@ const emsesp_deviceentities_2 = [
} }
]; ];
const emsesp_deviceentities_3 = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }
];
const emsesp_deviceentities_4 = [ const emsesp_deviceentities_4 = [
{ {
v: 16, v: 16,
@@ -3943,13 +3885,6 @@ const emsesp_deviceentities_4 = [
w: true w: true
} }
]; ];
const emsesp_deviceentities_5 = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }
];
const emsesp_deviceentities_6 = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }
];
const emsesp_deviceentities_7 = [ const emsesp_deviceentities_7 = [
{ u: 0, n: '!reset', id: 'reset', m: 8, w: false }, { u: 0, n: '!reset', id: 'reset', m: 8, w: false },
@@ -4076,22 +4011,6 @@ const emsesp_deviceentities_7 = [
{ v: 102151, n: 'dhw active time', id: 'dhw/workm', m: 0, w: false } { v: 102151, n: 'dhw active time', id: 'dhw/workm', m: 0, w: false }
]; ];
const emsesp_deviceentities_8 = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }
];
const emsesp_deviceentities_9 = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }
];
const emsesp_deviceentities_10 = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }
];
const emsesp_deviceentities_none = [
{ v: 'dummy value', n: 'dummy name', id: 'dummy', m: 0, w: false }
];
// END DATA // END DATA
// LOG // LOG
@@ -4160,22 +4079,21 @@ router
// SYSTEM and SETTINGS // SYSTEM and SETTINGS
router router
.get(SYSTEM_STATUS_ENDPOINT, () => system_status)
.get(ACTIVITY_ENDPOINT, () => activity) .get(ACTIVITY_ENDPOINT, () => activity)
.get(HARDWARE_STATUS_ENDPOINT, () => { .get(SYSTEM_STATUS_ENDPOINT, () => {
if (countHardwarePoll === 0) { if (countHardwarePoll === 0) {
console.log('Resetting hardware count...'); console.log('Resetting hardware count...');
} }
if (countHardwarePoll >= 2) { if (countHardwarePoll >= 2) {
countHardwarePoll = 0; countHardwarePoll = 0;
hardware_status.status = 'ready'; system_status.status = 'ready';
} }
console.log('Hardware count ' + countHardwarePoll + ' of 2'); console.log('Hardware count ' + countHardwarePoll + ' of 2');
countHardwarePoll++; countHardwarePoll++;
return hardware_status; return system_status;
}) })
.get(SECURITY_SETTINGS_ENDPOINT, () => security_settings) .get(SECURITY_SETTINGS_ENDPOINT, () => security_settings)
.post(SECURITY_SETTINGS_ENDPOINT, async (request: any) => { .post(SECURITY_SETTINGS_ENDPOINT, async (request: any) => {
@@ -4289,11 +4207,6 @@ router
emsesp_sensordata.ts[2].t = Math.floor(Math.random() * 100); emsesp_sensordata.ts[2].t = Math.floor(Math.random() * 100);
return emsesp_sensordata; return emsesp_sensordata;
}) })
.get(EMSESP_DEVICES_ENDPOINT, () => {
// sort by type
const sorted_devices = emsesp_devices.devices.sort((a, b) => a.t - b.t);
return { devices: sorted_devices };
})
.get(EMSESP_DEVICEDATA_ENDPOINT1, (request) => .get(EMSESP_DEVICEDATA_ENDPOINT1, (request) =>
request.query.id ? deviceData(Number(request.query.id)) : status(404) request.query.id ? deviceData(Number(request.query.id)) : status(404)
) )
@@ -4501,11 +4414,11 @@ router
}) })
// Settings - board profile // Settings - board profile
.post(EMSESP_BOARDPROFILE_ENDPOINT, async (request: any) => { .get(EMSESP_BOARDPROFILE_ENDPOINT, (request) => {
const content = await request.json(); const board_profile = request.query.boardProfile;
const board_profile = content.code;
const data = { const data = {
board_profile: settings.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,
@@ -4629,15 +4542,32 @@ router
data.eth_clock_mode = 0; data.eth_clock_mode = 0;
} }
console.log('board profile saved', data); data.board_profile =
typeof board_profile === 'string' ? board_profile : settings.board_profile;
console.log('board profile for ' + board_profile + ' fetched: ', data);
return data; return data;
}) })
// Download Settings // Download Settings
.get(EMSESP_GET_SETTINGS_ENDPOINT, () => emsesp_info) .get(EMSESP_EXPORT_DATA_ENDPOINT, (request) => {
.get(EMSESP_GET_CUSTOMIZATIONS_ENDPOINT, () => emsesp_deviceentities_1) const type = request.query.type;
.get(EMSESP_GET_ENTITIES_ENDPOINT, () => emsesp_customentities) console.log('exporting ' + type + ' data');
.get(EMSESP_GET_SCHEDULE_ENDPOINT, () => emsesp_schedule) switch (type) {
case 'settings':
return emsesp_info;
case 'customizations':
return emsesp_deviceentities_2; // fixed for one device
case 'entities':
return emsesp_customentities;
case 'schedule':
return emsesp_schedule;
case 'modules':
return emsesp_modules;
default:
return status(404);
}
})
// upload URL // upload URL
.post('/rest/uploadURL', () => { .post('/rest/uploadURL', () => {
@@ -4673,7 +4603,7 @@ router
} }
if (cmd === 'restart') { if (cmd === 'restart') {
console.log('restarting...'); console.log('restarting...');
hardware_status.status = 'restarting'; system_status.status = 'restarting';
countHardwarePoll = 0; countHardwarePoll = 0;
return status(200); return status(200);
} }

View File

@@ -1128,8 +1128,6 @@ bool System::check_restore() {
bool reboot_required = false; bool reboot_required = false;
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
// see if we have a temp file, if so try and read it
// TODO find a nicer way to see if a file exists without reporting an error, like using lfs_stat. exists() uses open so same problem.
File new_file = LittleFS.open(TEMP_FILENAME_PATH); File new_file = LittleFS.open(TEMP_FILENAME_PATH);
if (new_file) { if (new_file) {
JsonDocument jsonDocument; JsonDocument jsonDocument;

View File

@@ -29,9 +29,6 @@ WebCustomEntityService::WebCustomEntityService(AsyncWebServer * server, FS * fs,
securityManager, securityManager,
AuthenticationPredicates::IS_AUTHENTICATED) AuthenticationPredicates::IS_AUTHENTICATED)
, _fsPersistence(WebCustomEntity::read, WebCustomEntity::update, this, fs, EMSESP_CUSTOMENTITY_FILE) { , _fsPersistence(WebCustomEntity::read, WebCustomEntity::update, this, fs, EMSESP_CUSTOMENTITY_FILE) {
server->on(EMSESP_GET_ENTITIES_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getEntities(request); }, AuthenticationPredicates::IS_ADMIN));
} }
// load the settings when the service starts // load the settings when the service starts
@@ -711,17 +708,4 @@ void WebCustomEntityService::test() {
} }
#endif #endif
// return entities as a json object
void WebCustomEntityService::getEntities(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["type"] = "entities";
System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root);
response->setLength();
request->send(response);
}
} // namespace emsesp } // namespace emsesp

View File

@@ -22,7 +22,6 @@
#define EMSESP_CUSTOMENTITY_FILE "/config/emsespEntity.json" #define EMSESP_CUSTOMENTITY_FILE "/config/emsespEntity.json"
#define EMSESP_CUSTOMENTITY_SERVICE_PATH "/rest/customEntities" // GET and POST #define EMSESP_CUSTOMENTITY_SERVICE_PATH "/rest/customEntities" // GET and POST
#define EMSESP_GET_ENTITIES_PATH "/rest/getEntities"
namespace emsesp { namespace emsesp {

View File

@@ -28,13 +28,6 @@ WebCustomizationService::WebCustomizationService(AsyncWebServer * server, FS * f
server->on(EMSESP_DEVICE_ENTITIES_PATH, server->on(EMSESP_DEVICE_ENTITIES_PATH,
HTTP_GET, HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_entities(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); securityManager->wrapRequest([this](AsyncWebServerRequest * request) { device_entities(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
server->on(EMSESP_DEVICES_SERVICE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { devices(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
server->on(EMSESP_GET_CUSTOMIZATIONS_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getCustomizations(request); }, AuthenticationPredicates::IS_ADMIN));
// POST // POST
server->on(EMSESP_RESET_CUSTOMIZATION_SERVICE_PATH, server->on(EMSESP_RESET_CUSTOMIZATION_SERVICE_PATH,
@@ -166,29 +159,6 @@ void WebCustomizationService::reset_customization(AsyncWebServerRequest * reques
#endif #endif
} }
// send back a list of devices used in the customization web page
void WebCustomizationService::devices(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
// list is already sorted by device type
// controller is ignored since it doesn't have any associated entities
JsonArray devices = root["devices"].to<JsonArray>();
for (const auto & emsdevice : EMSESP::emsdevices) {
if (emsdevice->has_entities()) {
JsonObject obj = devices.add<JsonObject>();
obj["i"] = emsdevice->unique_id(); // its unique id
obj["s"] = emsdevice->name(); // custom name
obj["t"] = emsdevice->device_type(); // internal device type ID
obj["tn"] = std::string(emsdevice->device_type_2_device_name_translated()); // translated device type name
obj["url"] = emsdevice->device_type_name(); // non-translated, lower-case, used for API URL
}
}
response->setLength();
request->send(response);
}
// send back list of device entities // send back list of device entities
void WebCustomizationService::device_entities(AsyncWebServerRequest * request) { void WebCustomizationService::device_entities(AsyncWebServerRequest * request) {
uint8_t id; uint8_t id;
@@ -425,17 +395,4 @@ void WebCustomizationService::test() {
} }
#endif #endif
// return all customizations in a json object
void WebCustomizationService::getCustomizations(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["type"] = "customizations";
System::extractSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", root);
response->setLength();
request->send(response);
}
} // namespace emsesp } // namespace emsesp

View File

@@ -22,9 +22,7 @@
#define EMSESP_CUSTOMIZATION_FILE "/config/emsespCustomization.json" #define EMSESP_CUSTOMIZATION_FILE "/config/emsespCustomization.json"
// GET // GET
#define EMSESP_DEVICES_SERVICE_PATH "/rest/devices"
#define EMSESP_DEVICE_ENTITIES_PATH "/rest/deviceEntities" #define EMSESP_DEVICE_ENTITIES_PATH "/rest/deviceEntities"
#define EMSESP_GET_CUSTOMIZATIONS_PATH "/rest/getCustomizations"
// POST // POST
#define EMSESP_CUSTOMIZATION_ENTITIES_PATH "/rest/customizationEntities" #define EMSESP_CUSTOMIZATION_ENTITIES_PATH "/rest/customizationEntities"
@@ -98,9 +96,7 @@ class WebCustomizationService : public StatefulService<WebCustomization> {
FSPersistence<WebCustomization> _fsPersistence; FSPersistence<WebCustomization> _fsPersistence;
// GET // GET
void devices(AsyncWebServerRequest * request);
void device_entities(AsyncWebServerRequest * request); void device_entities(AsyncWebServerRequest * request);
void getCustomizations(AsyncWebServerRequest * request);
// POST // POST
void customization_entities(AsyncWebServerRequest * request, JsonVariant json); void customization_entities(AsyncWebServerRequest * request, JsonVariant json);

View File

@@ -66,6 +66,7 @@ void WebDataService::core_data(AsyncWebServerRequest * request) {
obj["p"] = emsdevice->product_id(); // productid obj["p"] = emsdevice->product_id(); // productid
obj["v"] = emsdevice->version(); // version obj["v"] = emsdevice->version(); // version
obj["e"] = emsdevice->count_entities(); // number of entities obj["e"] = emsdevice->count_entities(); // number of entities
obj["url"] = emsdevice->device_type_name(); // non-translated, lower-case, used for API URL in customization page
} }
} }

View File

@@ -25,9 +25,6 @@ namespace emsesp {
WebSchedulerService::WebSchedulerService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager) WebSchedulerService::WebSchedulerService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager)
: _httpEndpoint(WebScheduler::read, WebScheduler::update, this, server, EMSESP_SCHEDULER_SERVICE_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED) : _httpEndpoint(WebScheduler::read, WebScheduler::update, this, server, EMSESP_SCHEDULER_SERVICE_PATH, securityManager, AuthenticationPredicates::IS_AUTHENTICATED)
, _fsPersistence(WebScheduler::read, WebScheduler::update, this, fs, EMSESP_SCHEDULER_FILE) { , _fsPersistence(WebScheduler::read, WebScheduler::update, this, fs, EMSESP_SCHEDULER_FILE) {
server->on(EMSESP_GET_SCHEDULE_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSchedule(request); }, AuthenticationPredicates::IS_ADMIN));
} }
// load the settings when the service starts // load the settings when the service starts
@@ -613,17 +610,4 @@ void WebSchedulerService::test() {
} }
#endif #endif
// return schedule entries in a json object
void WebSchedulerService::getSchedule(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["type"] = "schedule";
System::extractSettings(EMSESP_SCHEDULER_FILE, "Schedule", root);
response->setLength();
request->send(response);
}
} // namespace emsesp } // namespace emsesp

View File

@@ -21,7 +21,6 @@
#define EMSESP_SCHEDULER_FILE "/config/emsespScheduler.json" #define EMSESP_SCHEDULER_FILE "/config/emsespScheduler.json"
#define EMSESP_SCHEDULER_SERVICE_PATH "/rest/schedule" // GET and POST #define EMSESP_SCHEDULER_SERVICE_PATH "/rest/schedule" // GET and POST
#define EMSESP_GET_SCHEDULE_PATH "/rest/getSchedule"
// bit flags for the schedule items. Matches those in interface/src/app/main/SchedulerDialog.tsx // bit flags for the schedule items. Matches those in interface/src/app/main/SchedulerDialog.tsx
// 0-127 (0->0x7F) is day schedule // 0-127 (0->0x7F) is day schedule
@@ -91,8 +90,6 @@ class WebSchedulerService : public StatefulService<WebScheduler> {
HttpEndpoint<WebScheduler> _httpEndpoint; HttpEndpoint<WebScheduler> _httpEndpoint;
FSPersistence<WebScheduler> _fsPersistence; FSPersistence<WebScheduler> _fsPersistence;
void getSchedule(AsyncWebServerRequest * request);
std::list<ScheduleItem> * scheduleItems_; // pointer to the list of schedule events std::list<ScheduleItem> * scheduleItems_; // pointer to the list of schedule events
bool ha_registered_ = false; bool ha_registered_ = false;
std::deque<ScheduleItem *> cmd_changed_; std::deque<ScheduleItem *> cmd_changed_;

View File

@@ -28,9 +28,6 @@ WebSettingsService::WebSettingsService(AsyncWebServer * server, FS * fs, Securit
server->on(EMSESP_BOARD_PROFILE_SERVICE_PATH, server->on(EMSESP_BOARD_PROFILE_SERVICE_PATH,
HTTP_GET, HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { board_profile(request); }, AuthenticationPredicates::IS_AUTHENTICATED)); securityManager->wrapRequest([this](AsyncWebServerRequest * request) { board_profile(request); }, AuthenticationPredicates::IS_AUTHENTICATED));
server->on(EMSESP_GET_SETTINGS_PATH,
HTTP_GET,
securityManager->wrapRequest([this](AsyncWebServerRequest * request) { getSettings(request); }, AuthenticationPredicates::IS_ADMIN));
addUpdateHandler([this] { onUpdate(); }, false); addUpdateHandler([this] { onUpdate(); }, false);
} }
@@ -463,25 +460,4 @@ void WebSettingsService::board_profile(AsyncWebServerRequest * request) {
request->send(response); request->send(response);
} }
// returns json with all system settings
void WebSettingsService::getSettings(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["type"] = "settings";
JsonObject node = root["System"].to<JsonObject>();
node["version"] = EMSESP_APP_VERSION;
System::extractSettings(NETWORK_SETTINGS_FILE, "Network", root);
System::extractSettings(AP_SETTINGS_FILE, "AP", root);
System::extractSettings(MQTT_SETTINGS_FILE, "MQTT", root);
System::extractSettings(NTP_SETTINGS_FILE, "NTP", root);
System::extractSettings(SECURITY_SETTINGS_FILE, "Security", root);
System::extractSettings(EMSESP_SETTINGS_FILE, "Settings", root);
response->setLength();
request->send(response);
}
} // namespace emsesp } // namespace emsesp

View File

@@ -25,7 +25,6 @@
#define EMSESP_SETTINGS_SERVICE_PATH "/rest/settings" #define EMSESP_SETTINGS_SERVICE_PATH "/rest/settings"
#define EMSESP_BOARD_PROFILE_SERVICE_PATH "/rest/boardProfile" #define EMSESP_BOARD_PROFILE_SERVICE_PATH "/rest/boardProfile"
#define EMSESP_GET_SETTINGS_PATH "/rest/getSettings"
namespace emsesp { namespace emsesp {
@@ -136,7 +135,6 @@ class WebSettingsService : public StatefulService<WebSettings> {
FSPersistence<WebSettings> _fsPersistence; FSPersistence<WebSettings> _fsPersistence;
void board_profile(AsyncWebServerRequest * request); void board_profile(AsyncWebServerRequest * request);
void getSettings(AsyncWebServerRequest * request);
void onUpdate(); void onUpdate();
}; };

View File

@@ -26,13 +26,16 @@ namespace emsesp {
WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) { WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) {
// GET // GET
server->on(EMSESP_HARDWARE_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { hardwareStatus(request); });
server->on(EMSESP_SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { systemStatus(request); }); server->on(EMSESP_SYSTEM_STATUS_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { systemStatus(request); });
server->on(EMSESP_EXPORT_DATA_SERVICE_PATH, HTTP_GET, [this](AsyncWebServerRequest * request) { exportData(request); });
// POST // POST
server->on(EMSESP_CHECK_UPGRADE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { checkUpgrade(request, json); }); server->on(EMSESP_CHECK_UPGRADE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { checkUpgrade(request, json); });
} }
// /rest/systemStatus // /rest/systemStatus
// This contains both system & hardware Status to avoid having multiple costly endpoints
// This is also used for polling during the RestartMonitor to see if EMS-ESP is alive
void WebStatusService::systemStatus(AsyncWebServerRequest * request) { void WebStatusService::systemStatus(AsyncWebServerRequest * request) {
EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap
@@ -40,7 +43,12 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) {
JsonObject root = response->getRoot(); JsonObject root = response->getRoot();
root["emsesp_version"] = EMSESP_APP_VERSION; root["emsesp_version"] = EMSESP_APP_VERSION;
root["status"] = EMSESP::bus_status(); // 0, 1 or 2
//
// System Status
//
root["emsesp_version"] = EMSESP_APP_VERSION;
root["bus_status"] = EMSESP::bus_status(); // 0, 1 or 2
root["bus_uptime"] = EMSbus::bus_uptime(); root["bus_uptime"] = EMSbus::bus_uptime();
root["num_devices"] = EMSESP::count_devices(); root["num_devices"] = EMSESP::count_devices();
root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors(); root["num_sensors"] = EMSESP::temperaturesensor_.no_sensors();
@@ -74,20 +82,6 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) {
#endif #endif
} }
response->setLength();
request->send(response);
}
// /rest/hardwareStatus
// This is also used for polling during the RestartMonitor to see if EMS-ESP is alive
void WebStatusService::hardwareStatus(AsyncWebServerRequest * request) {
EMSESP::system_.refreshHeapMem(); // refresh free heap and max alloc heap
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
root["emsesp_version"] = EMSESP_APP_VERSION;
#ifdef EMSESP_DEBUG #ifdef EMSESP_DEBUG
#ifdef EMSESP_TEST #ifdef EMSESP_TEST
root["build_flags"] = "DEBUG,TEST"; root["build_flags"] = "DEBUG,TEST";
@@ -98,15 +92,16 @@ void WebStatusService::hardwareStatus(AsyncWebServerRequest * request) {
root["build_flags"] = "TEST"; root["build_flags"] = "TEST";
#endif #endif
//
// Hardware Status
//
root["esp_platform"] = EMSESP_PLATFORM; root["esp_platform"] = EMSESP_PLATFORM;
#ifndef EMSESP_STANDALONE #ifndef EMSESP_STANDALONE
root["cpu_type"] = ESP.getChipModel(); root["cpu_type"] = ESP.getChipModel();
root["cpu_rev"] = ESP.getChipRevision(); root["cpu_rev"] = ESP.getChipRevision();
root["cpu_cores"] = ESP.getChipCores(); root["cpu_cores"] = ESP.getChipCores();
root["cpu_freq_mhz"] = ESP.getCpuFreqMHz(); root["cpu_freq_mhz"] = ESP.getCpuFreqMHz();
root["max_alloc_heap"] = EMSESP::system_.getMaxAllocMem(); root["max_alloc_heap"] = EMSESP::system_.getMaxAllocMem();
root["free_heap"] = EMSESP::system_.getHeapMem();
root["arduino_version"] = ARDUINO_VERSION; root["arduino_version"] = ARDUINO_VERSION;
root["sdk_version"] = ESP.getSdkVersion(); root["sdk_version"] = ESP.getSdkVersion();
root["partition"] = esp_ota_get_running_partition()->label; // active partition root["partition"] = esp_ota_get_running_partition()->label; // active partition
@@ -170,4 +165,36 @@ void WebStatusService::checkUpgrade(AsyncWebServerRequest * request, JsonVariant
request->send(response); request->send(response);
} }
// returns data for a specific feature/settings as a json object
void WebStatusService::exportData(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse();
JsonObject root = response->getRoot();
String type = request->getParam("type")->value();
if (type == "settings") {
JsonObject node = root["System"].to<JsonObject>();
node["version"] = EMSESP_APP_VERSION;
System::extractSettings(NETWORK_SETTINGS_FILE, "Network", root);
System::extractSettings(AP_SETTINGS_FILE, "AP", root);
System::extractSettings(MQTT_SETTINGS_FILE, "MQTT", root);
System::extractSettings(NTP_SETTINGS_FILE, "NTP", root);
System::extractSettings(SECURITY_SETTINGS_FILE, "Security", root);
System::extractSettings(EMSESP_SETTINGS_FILE, "Settings", root);
} else if (type == "schedule") {
System::extractSettings(EMSESP_SCHEDULER_FILE, "Schedule", root);
} else if (type == "customizations") {
System::extractSettings(EMSESP_CUSTOMIZATION_FILE, "Customizations", root);
} else if (type == "entities") {
System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root);
} else {
request->send(400);
return;
}
root["type"] = type;
response->setLength();
request->send(response);
}
} // namespace emsesp } // namespace emsesp

View File

@@ -1,11 +1,11 @@
#ifndef WebStatusService_h #ifndef WebStatusService_h
#define WebStatusService_h #define WebStatusService_h
#define EMSESP_HARDWARE_STATUS_SERVICE_PATH "/rest/hardwareStatus"
#define EMSESP_SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus" #define EMSESP_SYSTEM_STATUS_SERVICE_PATH "/rest/systemStatus"
#define EMSESP_CHECK_UPGRADE_PATH "/rest/checkUpgrade" #define EMSESP_CHECK_UPGRADE_PATH "/rest/checkUpgrade"
#define EMSESP_EXPORT_DATA_SERVICE_PATH "/rest/exportData"
#include <semver200.h> #include <semver200.h> // for version checking
namespace emsesp { namespace emsesp {
@@ -15,8 +15,8 @@ class WebStatusService {
private: private:
void systemStatus(AsyncWebServerRequest * request); void systemStatus(AsyncWebServerRequest * request);
void hardwareStatus(AsyncWebServerRequest * request);
void checkUpgrade(AsyncWebServerRequest * request, JsonVariant json); void checkUpgrade(AsyncWebServerRequest * request, JsonVariant json);
void exportData(AsyncWebServerRequest * request);
}; };
} // namespace emsesp } // namespace emsesp