mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 15:59:52 +03:00
URL updates
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
"@mui/icons-material": "^6.1.1",
|
"@mui/icons-material": "^6.1.1",
|
||||||
"@mui/material": "^6.1.1",
|
"@mui/material": "^6.1.1",
|
||||||
"@table-library/react-table-library": "4.1.7",
|
"@table-library/react-table-library": "4.1.7",
|
||||||
"alova": "3.0.16",
|
"alova": "3.0.17",
|
||||||
"async-validator": "^4.2.5",
|
"async-validator": "^4.2.5",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
@@ -47,8 +47,8 @@
|
|||||||
"@preact/preset-vite": "^2.9.1",
|
"@preact/preset-vite": "^2.9.1",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
||||||
"@types/formidable": "^3",
|
"@types/formidable": "^3",
|
||||||
"@types/node": "^22.7.3",
|
"@types/node": "^22.7.4",
|
||||||
"@types/react": "^18.3.9",
|
"@types/react": "^18.3.10",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"concurrently": "^9.0.1",
|
"concurrently": "^9.0.1",
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"formidable": "^3.5.1",
|
"formidable": "^3.5.1",
|
||||||
"prettier": "^3.3.3",
|
"prettier": "^3.3.3",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"terser": "^5.34.0",
|
"terser": "^5.34.1",
|
||||||
"typescript-eslint": "8.7.0",
|
"typescript-eslint": "8.7.0",
|
||||||
"vite": "^5.4.8",
|
"vite": "^5.4.8",
|
||||||
"vite-plugin-imagemin": "^0.6.1",
|
"vite-plugin-imagemin": "^0.6.1",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { alovaInstance } from 'api/endpoints';
|
|||||||
|
|
||||||
import type {
|
import type {
|
||||||
APIcall,
|
APIcall,
|
||||||
|
Action,
|
||||||
Activity,
|
Activity,
|
||||||
CoreData,
|
CoreData,
|
||||||
DeviceData,
|
DeviceData,
|
||||||
@@ -52,9 +53,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);
|
||||||
|
|
||||||
// DownloadUpload
|
// Generic action
|
||||||
export const exportData = (type: string) =>
|
export const callAction = (action: Action) =>
|
||||||
alovaInstance.Get('/rest/exportData', { params: { type } });
|
alovaInstance.Post('/rest/action', action);
|
||||||
|
|
||||||
// SettingsCustomization
|
// SettingsCustomization
|
||||||
export const readDeviceEntities = (id: number) =>
|
export const readDeviceEntities = (id: number) =>
|
||||||
@@ -118,7 +119,7 @@ export const writeModules = (data: {
|
|||||||
license: string;
|
license: string;
|
||||||
}) => alovaInstance.Post('/rest/modules', data);
|
}) => alovaInstance.Post('/rest/modules', data);
|
||||||
|
|
||||||
// SettingsEntities
|
// CustomEntities
|
||||||
export const readCustomEntities = () =>
|
export const readCustomEntities = () =>
|
||||||
alovaInstance.Get<EntityItem[]>('/rest/customEntities', {
|
alovaInstance.Get<EntityItem[]>('/rest/customEntities', {
|
||||||
transform(data) {
|
transform(data) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import CommentIcon from '@mui/icons-material/CommentTwoTone';
|
import CommentIcon from '@mui/icons-material/CommentTwoTone';
|
||||||
@@ -16,18 +16,17 @@ import {
|
|||||||
ListItemAvatar,
|
ListItemAvatar,
|
||||||
ListItemButton,
|
ListItemButton,
|
||||||
ListItemText,
|
ListItemText,
|
||||||
Paper,
|
|
||||||
Stack,
|
Stack,
|
||||||
Typography,
|
Typography
|
||||||
styled
|
|
||||||
} from '@mui/material';
|
} from '@mui/material';
|
||||||
|
|
||||||
import { useRequest } from 'alova/client';
|
import { useRequest } from 'alova/client';
|
||||||
import { SectionContent, useLayoutTitle } from 'components';
|
import { SectionContent, useLayoutTitle } 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 { saveFile } from 'utils/file';
|
||||||
|
|
||||||
import { API } from '../../api/app';
|
import { API, callAction } from '../../api/app';
|
||||||
import type { APIcall } from './types';
|
import type { APIcall } from './types';
|
||||||
|
|
||||||
const Help = () => {
|
const Help = () => {
|
||||||
@@ -36,33 +35,79 @@ const Help = () => {
|
|||||||
|
|
||||||
const { me } = useContext(AuthenticatedContext);
|
const { me } = useContext(AuthenticatedContext);
|
||||||
|
|
||||||
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
|
const [customSupportIMG, setCustomSupportIMG] = useState<string | null>(null);
|
||||||
immediate: false
|
const [customSupportHTML, setCustomSupportHTML] = useState<string | null>(null);
|
||||||
}).onSuccess((event) => {
|
|
||||||
const anchor = document.createElement('a');
|
useRequest(() => callAction({ action: 'customSupport' })).onSuccess(
|
||||||
anchor.href = URL.createObjectURL(
|
(event: { data: { img_url: string; html: string[] } }) => {
|
||||||
new Blob([JSON.stringify(event.data, null, 2)], {
|
if (event.data) {
|
||||||
type: 'text/plain'
|
setCustomSupportIMG(event.data.img_url);
|
||||||
})
|
setCustomSupportHTML(event.data.html.join('<br/>'));
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
anchor.download =
|
const { send: sendExportAllValues } = useRequest(
|
||||||
'emsesp_' + event.args[0].device + '_' + event.args[0].entity + '.txt';
|
() => callAction({ action: 'export', param: 'allvalues' }),
|
||||||
anchor.click();
|
{
|
||||||
URL.revokeObjectURL(anchor.href);
|
immediate: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.onSuccess((event) => {
|
||||||
|
saveFile(event.data, 'allvalues', '.txt');
|
||||||
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
||||||
});
|
})
|
||||||
|
.onError((error) => {
|
||||||
const callAPI = async (device: string, cmd: string) => {
|
toast.error(error.message);
|
||||||
await sendAPI({ device, cmd, id: 0 }).catch((error: Error) => {
|
});
|
||||||
|
|
||||||
|
const { send: sendAPI } = useRequest((data: APIcall) => API(data), {
|
||||||
|
immediate: false
|
||||||
|
})
|
||||||
|
.onSuccess((event) => {
|
||||||
|
saveFile(event.data, 'system_info', '.json');
|
||||||
|
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
||||||
|
})
|
||||||
|
.onError((error) => {
|
||||||
toast.error(error.message);
|
toast.error(error.message);
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SectionContent>
|
<SectionContent>
|
||||||
{me.admin ? (
|
<Stack
|
||||||
|
padding={1}
|
||||||
|
mb={2}
|
||||||
|
direction="row"
|
||||||
|
divider={<Divider orientation="vertical" flexItem />}
|
||||||
|
sx={{
|
||||||
|
borderRadius: 3,
|
||||||
|
border: '2px solid grey',
|
||||||
|
justifyContent: 'space-evenly',
|
||||||
|
alignItems: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="subtitle1">
|
||||||
|
{customSupportHTML ? (
|
||||||
|
<div dangerouslySetInnerHTML={{ __html: customSupportHTML }} />
|
||||||
|
) : (
|
||||||
|
LL.HELP_INFORMATION_5()
|
||||||
|
)}
|
||||||
|
</Typography>
|
||||||
|
<Box
|
||||||
|
component="img"
|
||||||
|
sx={{
|
||||||
|
maxHeight: 250
|
||||||
|
}}
|
||||||
|
src={
|
||||||
|
customSupportIMG
|
||||||
|
? customSupportIMG
|
||||||
|
: 'https://emsesp.org/_media/images/installer.jpeg'
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
{me.admin && (
|
||||||
<List sx={{ borderRadius: 3, border: '2px solid grey' }}>
|
<List sx={{ borderRadius: 3, border: '2px solid grey' }}>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemButton component="a" href="https://emsesp.org">
|
<ListItemButton component="a" href="https://emsesp.org">
|
||||||
@@ -100,31 +145,6 @@ const Help = () => {
|
|||||||
</ListItemButton>
|
</ListItemButton>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
</List>
|
</List>
|
||||||
) : (
|
|
||||||
<Stack
|
|
||||||
spacing={1}
|
|
||||||
padding={1}
|
|
||||||
direction="row"
|
|
||||||
divider={<Divider orientation="vertical" flexItem />}
|
|
||||||
sx={{
|
|
||||||
borderRadius: 3,
|
|
||||||
border: '2px solid grey',
|
|
||||||
justifyContent: 'space-around',
|
|
||||||
alignItems: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Typography border="red" variant="subtitle1">
|
|
||||||
{LL.HELP_INFORMATION_5()}
|
|
||||||
</Typography>
|
|
||||||
<Box
|
|
||||||
padding={1}
|
|
||||||
component="img"
|
|
||||||
sx={{
|
|
||||||
maxHeight: { xs: 100, md: 250 }
|
|
||||||
}}
|
|
||||||
src="https://emsesp.org/_media/images/installer.jpeg"
|
|
||||||
/>
|
|
||||||
</Stack>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box p={2} color="warning.main">
|
<Box p={2} color="warning.main">
|
||||||
@@ -135,7 +155,7 @@ const Help = () => {
|
|||||||
startIcon={<DownloadIcon />}
|
startIcon={<DownloadIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => callAPI('system', 'info')}
|
onClick={() => sendAPI({ device: 'system', cmd: 'info', id: 0 })}
|
||||||
>
|
>
|
||||||
{LL.DOWNLOAD(1)} {LL.SUPPORT_INFORMATION(0)}
|
{LL.DOWNLOAD(1)} {LL.SUPPORT_INFORMATION(0)}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -146,7 +166,7 @@ const Help = () => {
|
|||||||
startIcon={<DownloadIcon />}
|
startIcon={<DownloadIcon />}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={() => callAPI('system', 'allvalues')}
|
onClick={() => sendExportAllValues()}
|
||||||
>
|
>
|
||||||
{LL.DOWNLOAD(1)} {LL.ALLVALUES()}
|
{LL.DOWNLOAD(1)} {LL.ALLVALUES()}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -265,6 +265,12 @@ export interface APIcall {
|
|||||||
cmd: string;
|
cmd: string;
|
||||||
id: number;
|
id: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Action {
|
||||||
|
action: string;
|
||||||
|
param?: string; // optional
|
||||||
|
}
|
||||||
|
|
||||||
export interface WriteAnalogSensor {
|
export interface WriteAnalogSensor {
|
||||||
id: number;
|
id: number;
|
||||||
gpio: number;
|
gpio: number;
|
||||||
|
|||||||
@@ -18,7 +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 { API, exportData } from 'api/app';
|
import { API, callAction } from 'api/app';
|
||||||
import {
|
import {
|
||||||
checkUpgrade,
|
checkUpgrade,
|
||||||
getDevVersion,
|
getDevVersion,
|
||||||
@@ -37,6 +37,7 @@ import {
|
|||||||
useLayoutTitle
|
useLayoutTitle
|
||||||
} from 'components';
|
} from 'components';
|
||||||
import { useI18nContext } from 'i18n/i18n-react';
|
import { useI18nContext } from 'i18n/i18n-react';
|
||||||
|
import { saveFile } from 'utils/file';
|
||||||
|
|
||||||
const DownloadUpload = () => {
|
const DownloadUpload = () => {
|
||||||
const { LL } = useI18nContext();
|
const { LL } = useI18nContext();
|
||||||
@@ -46,11 +47,23 @@ 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: sendExportData } = useRequest((type: string) => exportData(type), {
|
const { send: sendCheckUpgrade } = useRequest(
|
||||||
|
(version: string) => callAction({ action: 'checkUpgrade', param: version }),
|
||||||
|
{
|
||||||
immediate: false
|
immediate: false
|
||||||
})
|
}
|
||||||
|
).onSuccess((event) => {
|
||||||
|
setUpgradeAvailable((event.data as { upgradeable: boolean }).upgradeable);
|
||||||
|
});
|
||||||
|
|
||||||
|
const { send: sendExportData } = useRequest(
|
||||||
|
(type: string) => callAction({ action: 'export', param: type }),
|
||||||
|
{
|
||||||
|
immediate: false
|
||||||
|
}
|
||||||
|
)
|
||||||
.onSuccess((event) => {
|
.onSuccess((event) => {
|
||||||
saveFile(event.data, event.args[0]);
|
saveFile(event.data, event.args[0], '.json');
|
||||||
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
toast.info(LL.DOWNLOAD_SUCCESSFUL());
|
||||||
})
|
})
|
||||||
.onError((error) => {
|
.onError((error) => {
|
||||||
@@ -83,12 +96,6 @@ const DownloadUpload = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { send: sendCheckUpgrade } = useRequest(checkUpgrade, {
|
|
||||||
immediate: false
|
|
||||||
}).onSuccess((event) => {
|
|
||||||
setUpgradeAvailable(event.data.upgradeable);
|
|
||||||
});
|
|
||||||
|
|
||||||
// called immediately to get the latest version, on page load
|
// called immediately to get the latest version, on page load
|
||||||
const { data: latestVersion } = useRequest(getStableVersion, {
|
const { data: latestVersion } = useRequest(getStableVersion, {
|
||||||
// uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/v3.6.5/EMS-ESP-3_6_5-ESP32-16MB+.bin
|
// uncomment next 2 lines for testing, uses https://github.com/emsesp/EMS-ESP32/releases/download/v3.6.5/EMS-ESP-3_6_5-ESP32-16MB+.bin
|
||||||
@@ -102,7 +109,7 @@ const DownloadUpload = () => {
|
|||||||
// immediate: false,
|
// immediate: false,
|
||||||
// initialData: '3.7.0-dev.32'
|
// initialData: '3.7.0-dev.32'
|
||||||
}).onSuccess((event) => {
|
}).onSuccess((event) => {
|
||||||
void sendCheckUpgrade({ version: event.data });
|
void sendCheckUpgrade(event.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/';
|
const STABLE_URL = 'https://github.com/emsesp/EMS-ESP32/releases/download/';
|
||||||
@@ -142,18 +149,6 @@ const DownloadUpload = () => {
|
|||||||
setRestarting(true);
|
setRestarting(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveFile = (json: unknown, filename: string) => {
|
|
||||||
const anchor = document.createElement('a');
|
|
||||||
anchor.href = URL.createObjectURL(
|
|
||||||
new Blob([JSON.stringify(json, null, 2)], {
|
|
||||||
type: 'text/plain'
|
|
||||||
})
|
|
||||||
);
|
|
||||||
anchor.download = 'emsesp_' + filename + '.json';
|
|
||||||
anchor.click();
|
|
||||||
URL.revokeObjectURL(anchor.href);
|
|
||||||
};
|
|
||||||
|
|
||||||
useLayoutTitle(LL.DOWNLOAD_UPLOAD());
|
useLayoutTitle(LL.DOWNLOAD_UPLOAD());
|
||||||
|
|
||||||
const internet_live =
|
const internet_live =
|
||||||
|
|||||||
11
interface/src/utils/file.ts
Normal file
11
interface/src/utils/file.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export const saveFile = (json: unknown, filename: string, extension: string) => {
|
||||||
|
const anchor = document.createElement('a');
|
||||||
|
anchor.href = URL.createObjectURL(
|
||||||
|
new Blob([JSON.stringify(json, null, 2)], {
|
||||||
|
type: 'text/plain'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
anchor.download = 'emsesp_' + filename + extension;
|
||||||
|
anchor.click();
|
||||||
|
URL.revokeObjectURL(anchor.href);
|
||||||
|
};
|
||||||
@@ -1446,12 +1446,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/node@npm:^22.7.3":
|
"@types/node@npm:^22.7.4":
|
||||||
version: 22.7.3
|
version: 22.7.4
|
||||||
resolution: "@types/node@npm:22.7.3"
|
resolution: "@types/node@npm:22.7.4"
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: "npm:~6.19.2"
|
undici-types: "npm:~6.19.2"
|
||||||
checksum: 10c0/0e579813528b0370454337a952f43b792cd12731e10fdca0fdb627158e980c1219bba99e9048c134b6a19325d817016059afe016ccd372326c838a1b85a51574
|
checksum: 10c0/c22bf54515c78ff3170142c1e718b90e2a0003419dc2d55f79c9c9362edd590a6ab1450deb09ff6e1b32d1b4698da407930b16285e8be3a009ea6cd2695cac01
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1518,13 +1518,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/react@npm:^18.3.9":
|
"@types/react@npm:^18.3.10":
|
||||||
version: 18.3.9
|
version: 18.3.10
|
||||||
resolution: "@types/react@npm:18.3.9"
|
resolution: "@types/react@npm:18.3.10"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/prop-types": "npm:*"
|
"@types/prop-types": "npm:*"
|
||||||
csstype: "npm:^3.0.2"
|
csstype: "npm:^3.0.2"
|
||||||
checksum: 10c0/a92b8e061d0c833e096254782c56a802316593f4a907fb834b557cabe848a0829b9eb6056404ea239eb4d5ec5ac7b7724309761516c0a7a277916fa04dd4f805
|
checksum: 10c0/f5be1de1b0331c1fdb33d577f4cf7f1b949d4bded5347b2351a537f03c51dade5be115e21b161dcf1b37061954d320f6a0bdf8d7b70e24eda51071fdd614383d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -1678,11 +1678,11 @@ __metadata:
|
|||||||
"@table-library/react-table-library": "npm:4.1.7"
|
"@table-library/react-table-library": "npm:4.1.7"
|
||||||
"@trivago/prettier-plugin-sort-imports": "npm:^4.3.0"
|
"@trivago/prettier-plugin-sort-imports": "npm:^4.3.0"
|
||||||
"@types/formidable": "npm:^3"
|
"@types/formidable": "npm:^3"
|
||||||
"@types/node": "npm:^22.7.3"
|
"@types/node": "npm:^22.7.4"
|
||||||
"@types/react": "npm:^18.3.9"
|
"@types/react": "npm:^18.3.10"
|
||||||
"@types/react-dom": "npm:^18.3.0"
|
"@types/react-dom": "npm:^18.3.0"
|
||||||
"@types/react-router-dom": "npm:^5.3.3"
|
"@types/react-router-dom": "npm:^5.3.3"
|
||||||
alova: "npm:3.0.16"
|
alova: "npm:3.0.17"
|
||||||
async-validator: "npm:^4.2.5"
|
async-validator: "npm:^4.2.5"
|
||||||
concurrently: "npm:^9.0.1"
|
concurrently: "npm:^9.0.1"
|
||||||
eslint: "npm:^9.11.1"
|
eslint: "npm:^9.11.1"
|
||||||
@@ -1698,7 +1698,7 @@ __metadata:
|
|||||||
react-router-dom: "npm:^6.26.2"
|
react-router-dom: "npm:^6.26.2"
|
||||||
react-toastify: "npm:^10.0.5"
|
react-toastify: "npm:^10.0.5"
|
||||||
rollup-plugin-visualizer: "npm:^5.12.0"
|
rollup-plugin-visualizer: "npm:^5.12.0"
|
||||||
terser: "npm:^5.34.0"
|
terser: "npm:^5.34.1"
|
||||||
typesafe-i18n: "npm:^5.26.2"
|
typesafe-i18n: "npm:^5.26.2"
|
||||||
typescript: "npm:^5.6.2"
|
typescript: "npm:^5.6.2"
|
||||||
typescript-eslint: "npm:8.7.0"
|
typescript-eslint: "npm:8.7.0"
|
||||||
@@ -1764,13 +1764,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"alova@npm:3.0.16":
|
"alova@npm:3.0.17":
|
||||||
version: 3.0.16
|
version: 3.0.17
|
||||||
resolution: "alova@npm:3.0.16"
|
resolution: "alova@npm:3.0.17"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@alova/shared": "npm:^1.0.5"
|
"@alova/shared": "npm:^1.0.5"
|
||||||
rate-limiter-flexible: "npm:^5.0.3"
|
rate-limiter-flexible: "npm:^5.0.3"
|
||||||
checksum: 10c0/66cb597f4f00feda04b7619dd852fde92bc920cc97b018be70791240c8e8c64677a998a02a684f3aace5997322236a677264f25afe6bcaf4ec856ae42be859a8
|
checksum: 10c0/e8a2ae885a3ff44dafec230d9388dc22b6445bb0cf8511fc9855b5a98ad9961941b0d33a7da874df23db4af0dba75872a470e3edebbdcc5ead8aecbc7fcc3d6b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -6654,9 +6654,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"terser@npm:^5.34.0":
|
"terser@npm:^5.34.1":
|
||||||
version: 5.34.0
|
version: 5.34.1
|
||||||
resolution: "terser@npm:5.34.0"
|
resolution: "terser@npm:5.34.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@jridgewell/source-map": "npm:^0.3.3"
|
"@jridgewell/source-map": "npm:^0.3.3"
|
||||||
acorn: "npm:^8.8.2"
|
acorn: "npm:^8.8.2"
|
||||||
@@ -6664,7 +6664,7 @@ __metadata:
|
|||||||
source-map-support: "npm:~0.5.20"
|
source-map-support: "npm:~0.5.20"
|
||||||
bin:
|
bin:
|
||||||
terser: bin/terser
|
terser: bin/terser
|
||||||
checksum: 10c0/74e8ef4e565e5600415cd9377a90eed419b8076465d453c0c76aef4053c45371512d2de76c34d01e004cdd49ea5a749d77eeb343f7e665b2d172158ca08ba23e
|
checksum: 10c0/51c7d704c5c4ae88bf937124112c9972aed4e1fd29d805cc2d86e0f54cd631ecd4e69db5bb3c1e3b450c741c86e2313328bea0fde925329e8a31a07a7941723c
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
@@ -117,6 +117,55 @@ function updateMask(entity: any, de: any, dd: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// called by Action endpoint
|
||||||
|
function export_data(type: string) {
|
||||||
|
console.log('exporting ' + type + '...');
|
||||||
|
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;
|
||||||
|
case 'allvalues':
|
||||||
|
return emsesp_allvalues;
|
||||||
|
default:
|
||||||
|
return status(404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// called by Action endpoint
|
||||||
|
function custom_support() {
|
||||||
|
return {
|
||||||
|
html: [
|
||||||
|
'This product is installed and managed by:',
|
||||||
|
'',
|
||||||
|
'<b>Bosch Installer Example</b>',
|
||||||
|
'Nefit Road 12',
|
||||||
|
'1234 AB Amsterdam',
|
||||||
|
'Phone: +31 123 456 789',
|
||||||
|
'email: support@boschinstaller.nl',
|
||||||
|
'',
|
||||||
|
"For help and questions please <a target='_blank' href='https://emsesp.org'>contact</a> your installer."
|
||||||
|
],
|
||||||
|
img_url: 'https://emsesp.org/_media/images/designer.png'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// called by Action endpoint
|
||||||
|
function check_upgrade(version: string) {
|
||||||
|
console.log('check upgrade from version', version);
|
||||||
|
const data = {
|
||||||
|
upgradeable: true
|
||||||
|
// upgradeable: false
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
// START DATA
|
// START DATA
|
||||||
|
|
||||||
// LOG
|
// LOG
|
||||||
@@ -402,7 +451,6 @@ const EMSESP_DEVICEDATA_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceData/:id?';
|
|||||||
const EMSESP_DEVICEENTITIES_ENDPOINT1 = REST_ENDPOINT_ROOT + 'deviceEntities';
|
const EMSESP_DEVICEENTITIES_ENDPOINT1 = REST_ENDPOINT_ROOT + 'deviceEntities';
|
||||||
const EMSESP_DEVICEENTITIES_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceEntities/:id?';
|
const EMSESP_DEVICEENTITIES_ENDPOINT2 = REST_ENDPOINT_ROOT + 'deviceEntities/:id?';
|
||||||
|
|
||||||
const EMSESP_CHECK_UPGRADE_ENDPOINT = REST_ENDPOINT_ROOT + 'checkUpgrade';
|
|
||||||
const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile';
|
const EMSESP_BOARDPROFILE_ENDPOINT = REST_ENDPOINT_ROOT + 'boardProfile';
|
||||||
const EMSESP_WRITE_DEVICEVALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue';
|
const EMSESP_WRITE_DEVICEVALUE_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceValue';
|
||||||
const EMSESP_WRITE_DEVICENAME_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceName';
|
const EMSESP_WRITE_DEVICENAME_ENDPOINT = REST_ENDPOINT_ROOT + 'writeDeviceName';
|
||||||
@@ -416,7 +464,8 @@ 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';
|
|
||||||
|
const EMSESP_ACTION_ENDPOINT = REST_ENDPOINT_ROOT + 'action';
|
||||||
|
|
||||||
// these are used in the API calls only
|
// these are used in the API calls only
|
||||||
const EMSESP_SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info';
|
const EMSESP_SYSTEM_INFO_ENDPOINT = API_ENDPOINT_ROOT + 'system/info';
|
||||||
@@ -4081,16 +4130,10 @@ router
|
|||||||
router
|
router
|
||||||
.get(ACTIVITY_ENDPOINT, () => activity)
|
.get(ACTIVITY_ENDPOINT, () => activity)
|
||||||
.get(SYSTEM_STATUS_ENDPOINT, () => {
|
.get(SYSTEM_STATUS_ENDPOINT, () => {
|
||||||
if (countHardwarePoll === 0) {
|
|
||||||
console.log('Resetting hardware count...');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (countHardwarePoll >= 2) {
|
if (countHardwarePoll >= 2) {
|
||||||
countHardwarePoll = 0;
|
countHardwarePoll = 0;
|
||||||
system_status.status = 'ready';
|
system_status.status = 'ready';
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Hardware count ' + countHardwarePoll + ' of 2');
|
|
||||||
countHardwarePoll++;
|
countHardwarePoll++;
|
||||||
|
|
||||||
return system_status;
|
return system_status;
|
||||||
@@ -4402,17 +4445,6 @@ router
|
|||||||
return status(200);
|
return status(200);
|
||||||
})
|
})
|
||||||
|
|
||||||
// check upgrade
|
|
||||||
.post(EMSESP_CHECK_UPGRADE_ENDPOINT, async (request: any) => {
|
|
||||||
const content = await request.json();
|
|
||||||
console.log('check upgrade from ', content.version);
|
|
||||||
const data = {
|
|
||||||
upgradeable: true
|
|
||||||
// upgradeable: false
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
})
|
|
||||||
|
|
||||||
// Settings - board profile
|
// Settings - board profile
|
||||||
.get(EMSESP_BOARDPROFILE_ENDPOINT, (request) => {
|
.get(EMSESP_BOARDPROFILE_ENDPOINT, (request) => {
|
||||||
const board_profile = request.query.boardProfile;
|
const board_profile = request.query.boardProfile;
|
||||||
@@ -4549,32 +4581,32 @@ router
|
|||||||
return data;
|
return data;
|
||||||
})
|
})
|
||||||
|
|
||||||
// Download Settings
|
|
||||||
.get(EMSESP_EXPORT_DATA_ENDPOINT, (request) => {
|
|
||||||
const type = request.query.type;
|
|
||||||
console.log('exporting ' + type + ' data');
|
|
||||||
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', () => {
|
||||||
console.log('upload File from URL');
|
console.log('upload File from URL');
|
||||||
return status(200);
|
return status(200);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// generic action for all /rest/... endpoints
|
||||||
|
// takes an action and param in JSON
|
||||||
|
.post(EMSESP_ACTION_ENDPOINT, async (request: any) => {
|
||||||
|
const content = await request.json();
|
||||||
|
if (content.hasOwnProperty('action')) {
|
||||||
|
const action = content.action;
|
||||||
|
if (action === 'export') {
|
||||||
|
// export data
|
||||||
|
return export_data(content.param);
|
||||||
|
} else if (action === 'customSupport') {
|
||||||
|
// send custom support
|
||||||
|
return custom_support();
|
||||||
|
} else if (action === 'checkUpgrade') {
|
||||||
|
// check upgrade
|
||||||
|
return check_upgrade(content.param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status(404); // cmd not found
|
||||||
|
})
|
||||||
|
|
||||||
// API which are usually POST for security
|
// API which are usually POST for security
|
||||||
.post(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info)
|
.post(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info)
|
||||||
.get(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info)
|
.get(EMSESP_SYSTEM_INFO_ENDPOINT, () => emsesp_info)
|
||||||
@@ -4594,9 +4626,6 @@ router
|
|||||||
if (cmd === 'info') {
|
if (cmd === 'info') {
|
||||||
return emsesp_info;
|
return emsesp_info;
|
||||||
}
|
}
|
||||||
if (cmd === 'allvalues') {
|
|
||||||
return emsesp_allvalues;
|
|
||||||
}
|
|
||||||
if (cmd === 'format') {
|
if (cmd === 'format') {
|
||||||
console.log('formatting...');
|
console.log('formatting...');
|
||||||
return status(200);
|
return status(200);
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ unbuild_flags =
|
|||||||
${common.core_unbuild_flags}
|
${common.core_unbuild_flags}
|
||||||
|
|
||||||
[espressif32_base]
|
[espressif32_base]
|
||||||
platform = espressif32@6.8.1
|
platform = espressif32@6.9.0
|
||||||
framework = arduino
|
framework = arduino
|
||||||
board_build.filesystem = littlefs
|
board_build.filesystem = littlefs
|
||||||
build_flags =
|
build_flags =
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ MAKE_WORD_TRANSLATION(schedule_cmd, "enable schedule item", "Aktiviere Zeitplane
|
|||||||
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS", "nastaviť vlastnú hodnotu na ems") // TODO translate
|
MAKE_WORD_TRANSLATION(entity_cmd, "set custom value on ems", "Sende eigene Entitäten zu EMS", "verstuur custom waarde naar EMS", "", "wyślij własną wartość na EMS", "", "", "emp üzerinde özel değer ayarla", "imposta valori personalizzati su EMS", "nastaviť vlastnú hodnotu na ems") // TODO translate
|
||||||
MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoek om antwoord", "", "uzyskaj odpowiedź", "", "", "gelen cevap", "", "získať odpoveď") // TODO translate
|
MAKE_WORD_TRANSLATION(commands_response, "get response", "Hole Antwort", "Verzoek om antwoord", "", "uzyskaj odpowiedź", "", "", "gelen cevap", "", "získať odpoveď") // TODO translate
|
||||||
MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "Zugabe einer Menge kalten Wassers", "", "", "uruchom tryśnięcie zimnej wody", "", "", "soğuk su gönder", "", "pošlite studenú dávku vody") // TODO translate
|
MAKE_WORD_TRANSLATION(coldshot_cmd, "send a cold shot of water", "Zugabe einer Menge kalten Wassers", "", "", "uruchom tryśnięcie zimnej wody", "", "", "soğuk su gönder", "", "pošlite studenú dávku vody") // TODO translate
|
||||||
MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values in system", "Alle Werte im System ausgeben", "", "", "wyświetl wszystkie wartości", "", "", "", "", "vypísať všetky hodnoty") // TODO translate
|
MAKE_WORD_TRANSLATION(allvalues_cmd, "output all values in system", "Alle Werte im System ausgeben", "", "", "wyświetl wszystkie wartości", "", "", "", "", "vypísať všetky hodnoty") // TODO remove
|
||||||
MAKE_WORD_TRANSLATION(message_cmd, "send a message", "Eine Nachricht senden", "", "", "", "", "", "", "", "poslať správu") // TODO translate
|
MAKE_WORD_TRANSLATION(message_cmd, "send a message", "Eine Nachricht senden", "", "", "", "", "", "", "", "poslať správu") // TODO translate
|
||||||
MAKE_WORD_TRANSLATION(values_cmd, "list all values", "Liste alle Werte auf", "", "", "", "", "", "", "", "vypísať všetky hodnoty") // TODO translate
|
MAKE_WORD_TRANSLATION(values_cmd, "list all values", "Liste alle Werte auf", "", "", "", "", "", "", "", "vypísať všetky hodnoty") // TODO translate
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ bool System::command_response(const char * value, const int8_t id, JsonObject ou
|
|||||||
|
|
||||||
// output all the devices and the values
|
// output all the devices and the values
|
||||||
// not system info
|
// not system info
|
||||||
|
// TODO remove?
|
||||||
bool System::command_allvalues(const char * value, const int8_t id, JsonObject output) {
|
bool System::command_allvalues(const char * value, const int8_t id, JsonObject output) {
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
JsonObject device_output;
|
JsonObject device_output;
|
||||||
@@ -874,7 +875,7 @@ void System::commands_init() {
|
|||||||
|
|
||||||
// these commands will return data in JSON format
|
// these commands will return data in JSON format
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F("response"), System::command_response, FL_(commands_response));
|
Command::add(EMSdevice::DeviceType::SYSTEM, F("response"), System::command_response, FL_(commands_response));
|
||||||
Command::add(EMSdevice::DeviceType::SYSTEM, F("allvalues"), System::command_allvalues, FL_(allvalues_cmd));
|
Command::add(EMSdevice::DeviceType::SYSTEM, F("allvalues"), System::command_allvalues, FL_(allvalues_cmd)); // TODO remove
|
||||||
|
|
||||||
// MQTT subscribe "ems-esp/system/#"
|
// MQTT subscribe "ems-esp/system/#"
|
||||||
Mqtt::subscribe(EMSdevice::DeviceType::SYSTEM, "system/#", nullptr); // use empty function callback
|
Mqtt::subscribe(EMSdevice::DeviceType::SYSTEM, "system/#", nullptr); // use empty function callback
|
||||||
@@ -1139,7 +1140,7 @@ void System::show_system(uuid::console::Shell & shell) {
|
|||||||
|
|
||||||
// see if there is a restore of an older settings file that needs to be applied
|
// see if there is a restore of an older settings file that needs to be applied
|
||||||
bool System::check_restore() {
|
bool System::check_restore() {
|
||||||
bool reboot_required = false;
|
bool reboot_required = false; // true if we need to reboot
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
#ifndef EMSESP_STANDALONE
|
||||||
File new_file = LittleFS.open(TEMP_FILENAME_PATH);
|
File new_file = LittleFS.open(TEMP_FILENAME_PATH);
|
||||||
@@ -1167,11 +1168,20 @@ bool System::check_restore() {
|
|||||||
} else if (settings_type == "entities") {
|
} else if (settings_type == "entities") {
|
||||||
// it's a entity file, just replace it and there's no need to reboot
|
// it's a entity file, just replace it and there's no need to reboot
|
||||||
saveSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", input);
|
saveSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", input);
|
||||||
|
} else if (settings_type == "custom_support") {
|
||||||
|
// it's a custom support file - save it to /config
|
||||||
|
new_file.close();
|
||||||
|
if (LittleFS.rename(TEMP_FILENAME_PATH, EMSESP_CUSTOMSUPPORT_FILE)) {
|
||||||
|
LOG_INFO("Custom support information loaded");
|
||||||
|
return false; // no need to reboot
|
||||||
|
} else {
|
||||||
|
LOG_ERROR("Failed to save custom support file");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Unrecognized file uploaded");
|
LOG_ERROR("Unrecognized file uploaded");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Unrecognized file uploaded, not json. Will be removed.");
|
LOG_ERROR("Unrecognized file uploaded, not json.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// close (just in case) and remove the temp file
|
// close (just in case) and remove the temp file
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ using uuid::console::Shell;
|
|||||||
|
|
||||||
#define EMSESP_FS_CONFIG_DIRECTORY "/config"
|
#define EMSESP_FS_CONFIG_DIRECTORY "/config"
|
||||||
|
|
||||||
|
#define EMSESP_CUSTOMSUPPORT_FILE "/config/customSupport.json"
|
||||||
|
|
||||||
namespace emsesp {
|
namespace emsesp {
|
||||||
|
|
||||||
enum PHY_type : uint8_t { PHY_TYPE_NONE = 0, PHY_TYPE_LAN8720, PHY_TYPE_TLK110 };
|
enum PHY_type : uint8_t { PHY_TYPE_NONE = 0, PHY_TYPE_LAN8720, PHY_TYPE_TLK110 };
|
||||||
@@ -63,7 +65,7 @@ class System {
|
|||||||
static bool command_message(const char * value, const int8_t id);
|
static bool command_message(const char * value, const int8_t id);
|
||||||
static bool command_info(const char * value, const int8_t id, JsonObject output);
|
static bool command_info(const char * value, const int8_t id, JsonObject output);
|
||||||
static bool command_response(const char * value, const int8_t id, JsonObject output);
|
static bool command_response(const char * value, const int8_t id, JsonObject output);
|
||||||
static bool command_allvalues(const char * value, const int8_t id, JsonObject output);
|
static bool command_allvalues(const char * value, const int8_t id, JsonObject output); // TODO fix
|
||||||
|
|
||||||
static bool get_value_info(JsonObject root, const char * cmd);
|
static bool get_value_info(JsonObject root, const char * cmd);
|
||||||
static void get_value_json(JsonObject output, const std::string & circuit, const std::string & name, JsonVariant val);
|
static void get_value_json(JsonObject output, const std::string & circuit, const std::string & name, JsonVariant val);
|
||||||
|
|||||||
@@ -327,7 +327,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
|
|
||||||
// shell.invoke_command("show devices");
|
// shell.invoke_command("show devices");
|
||||||
// shell.invoke_command("show values");
|
// shell.invoke_command("show values");
|
||||||
// shell.invoke_command("call system allvalues");
|
|
||||||
// shell.invoke_command("call system publish");
|
// shell.invoke_command("call system publish");
|
||||||
// shell.invoke_command("show mqtt");
|
// shell.invoke_command("show mqtt");
|
||||||
ok = true;
|
ok = true;
|
||||||
@@ -792,7 +791,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
|
|
||||||
shell.invoke_command("call temperaturesensor");
|
shell.invoke_command("call temperaturesensor");
|
||||||
shell.invoke_command("show values");
|
shell.invoke_command("show values");
|
||||||
shell.invoke_command("call system allvalues");
|
|
||||||
shell.invoke_command("call temperaturesensor info");
|
shell.invoke_command("call temperaturesensor info");
|
||||||
shell.invoke_command("call temperaturesensor values");
|
shell.invoke_command("call temperaturesensor values");
|
||||||
|
|
||||||
@@ -842,7 +840,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
|
|||||||
|
|
||||||
shell.invoke_command("call analogsensor");
|
shell.invoke_command("call analogsensor");
|
||||||
shell.invoke_command("show values");
|
shell.invoke_command("show values");
|
||||||
shell.invoke_command("call system allvalues");
|
|
||||||
shell.invoke_command("call analogsensor info");
|
shell.invoke_command("call analogsensor info");
|
||||||
shell.invoke_command("call analogsensor values");
|
shell.invoke_command("call analogsensor values");
|
||||||
|
|
||||||
|
|||||||
@@ -463,7 +463,6 @@ uint8_t WebCustomEntityService::count_entities() {
|
|||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
for (const CustomEntityItem & entity : *customEntityItems_) {
|
for (const CustomEntityItem & entity : *customEntityItems_) {
|
||||||
render_value(output, entity);
|
render_value(output, entity);
|
||||||
// TODO check JsonVariant
|
|
||||||
if (output[entity.name].is<JsonVariantConst>() || entity.writeable) {
|
if (output[entity.name].is<JsonVariantConst>() || entity.writeable) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,9 @@ namespace emsesp {
|
|||||||
WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) {
|
WebStatusService::WebStatusService(AsyncWebServer * server, SecurityManager * securityManager) {
|
||||||
// GET
|
// GET
|
||||||
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
|
// generic action - POST
|
||||||
server->on(EMSESP_CHECK_UPGRADE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { checkUpgrade(request, json); });
|
server->on(EMSESP_ACTION_SERVICE_PATH, [this](AsyncWebServerRequest * request, JsonVariant json) { action(request, json); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// /rest/systemStatus
|
// /rest/systemStatus
|
||||||
@@ -146,13 +145,42 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) {
|
|||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns trues if there is an upgrade available
|
// generic action handler - as a POST
|
||||||
void WebStatusService::checkUpgrade(AsyncWebServerRequest * request, JsonVariant json) {
|
void WebStatusService::action(AsyncWebServerRequest * request, JsonVariant json) {
|
||||||
auto * response = new AsyncJsonResponse();
|
auto * response = new AsyncJsonResponse();
|
||||||
JsonObject root = response->getRoot();
|
JsonObject root = response->getRoot();
|
||||||
|
|
||||||
|
// get action and optional param
|
||||||
|
std::string action = json["action"];
|
||||||
|
std::string param = json["param"]; // is optional
|
||||||
|
|
||||||
|
// TODO remove
|
||||||
|
Serial.printf("Action: %s\n", action.c_str());
|
||||||
|
Serial.printf("Param: %s\n", param.c_str());
|
||||||
|
|
||||||
|
bool ok = true;
|
||||||
|
if (action == "checkUpgrade") {
|
||||||
|
ok = checkUpgrade(root, param);
|
||||||
|
} else if (action == "export") {
|
||||||
|
ok = exportData(root, param);
|
||||||
|
} else if (action == "customSupport") {
|
||||||
|
ok = customSupport(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
// send response
|
||||||
|
if (!ok) {
|
||||||
|
request->send(400);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
response->setLength();
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// returns true if there is an upgrade available
|
||||||
|
bool WebStatusService::checkUpgrade(JsonObject root, std::string & latest_version) {
|
||||||
version::Semver200_version settings_version(EMSESP_APP_VERSION);
|
version::Semver200_version settings_version(EMSESP_APP_VERSION);
|
||||||
const std::string latest_version = json["version"] | EMSESP_APP_VERSION;
|
|
||||||
version::Semver200_version this_version(latest_version);
|
version::Semver200_version this_version(latest_version);
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
@@ -161,16 +189,11 @@ void WebStatusService::checkUpgrade(AsyncWebServerRequest * request, JsonVariant
|
|||||||
|
|
||||||
root["upgradeable"] = (this_version > settings_version);
|
root["upgradeable"] = (this_version > settings_version);
|
||||||
|
|
||||||
response->setLength();
|
return true;
|
||||||
request->send(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns data for a specific feature/settings as a json object
|
// returns data for a specific feature/settings as a json object
|
||||||
void WebStatusService::exportData(AsyncWebServerRequest * request) {
|
bool WebStatusService::exportData(JsonObject root, std::string & type) {
|
||||||
auto * response = new AsyncJsonResponse();
|
|
||||||
JsonObject root = response->getRoot();
|
|
||||||
|
|
||||||
String type = request->getParam("type")->value();
|
|
||||||
root["type"] = type;
|
root["type"] = type;
|
||||||
|
|
||||||
if (type == "settings") {
|
if (type == "settings") {
|
||||||
@@ -189,12 +212,15 @@ void WebStatusService::exportData(AsyncWebServerRequest * request) {
|
|||||||
} else if (type == "entities") {
|
} else if (type == "entities") {
|
||||||
System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root);
|
System::extractSettings(EMSESP_CUSTOMENTITY_FILE, "Entities", root);
|
||||||
} else {
|
} else {
|
||||||
request->send(400);
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
response->setLength();
|
// custom support
|
||||||
request->send(response);
|
bool WebStatusService::customSupport(JsonObject root) {
|
||||||
|
root["custom_support"] = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#define WebStatusService_h
|
#define WebStatusService_h
|
||||||
|
|
||||||
#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_EXPORT_DATA_SERVICE_PATH "/rest/exportData"
|
#define EMSESP_ACTION_SERVICE_PATH "/rest/action"
|
||||||
|
|
||||||
#include <semver200.h> // for version checking
|
#include <semver200.h> // for version checking
|
||||||
|
|
||||||
@@ -13,10 +13,14 @@ class WebStatusService {
|
|||||||
public:
|
public:
|
||||||
WebStatusService(AsyncWebServer * server, SecurityManager * securityManager);
|
WebStatusService(AsyncWebServer * server, SecurityManager * securityManager);
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void systemStatus(AsyncWebServerRequest * request);
|
void systemStatus(AsyncWebServerRequest * request);
|
||||||
void checkUpgrade(AsyncWebServerRequest * request, JsonVariant json);
|
void action(AsyncWebServerRequest * request, JsonVariant json);
|
||||||
void exportData(AsyncWebServerRequest * request);
|
|
||||||
|
private:
|
||||||
|
bool checkUpgrade(JsonObject root, std::string & latest_version);
|
||||||
|
bool exportData(JsonObject root, std::string & type);
|
||||||
|
bool customSupport(JsonObject root);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace emsesp
|
} // namespace emsesp
|
||||||
|
|||||||
Reference in New Issue
Block a user