From 3df2d36453a9d56d2381b8934090b8b59fb0f429 Mon Sep 17 00:00:00 2001 From: proddy Date: Tue, 28 Jan 2025 22:33:23 +0100 Subject: [PATCH] https://github.com/emsesp/EMS-ESP32/discussions/2377 --- interface/package.json | 6 +- interface/src/api/app.ts | 4 +- interface/src/app/main/Dashboard.tsx | 224 ++++++++++++++------------- interface/src/app/main/types.ts | 5 + interface/src/i18n/cz/index.ts | 2 +- interface/src/i18n/en/index.ts | 2 +- interface/src/i18n/fr/index.ts | 2 +- interface/src/i18n/it/index.ts | 2 +- interface/src/i18n/nl/index.ts | 2 +- interface/src/i18n/no/index.ts | 2 +- interface/src/i18n/pl/index.ts | 2 +- interface/src/i18n/sv/index.ts | 2 +- interface/src/i18n/tr/index.ts | 2 +- interface/yarn.lock | 153 +++++++++--------- mock-api/rest_server.ts | 25 +-- src/version.h | 2 +- src/web/WebDataService.cpp | 26 ++-- 17 files changed, 245 insertions(+), 218 deletions(-) diff --git a/interface/package.json b/interface/package.json index 00152873d..47bcaf633 100644 --- a/interface/package.json +++ b/interface/package.json @@ -45,9 +45,9 @@ "@eslint/js": "^9.19.0", "@preact/compat": "^18.3.1", "@preact/preset-vite": "^2.10.0", - "@trivago/prettier-plugin-sort-imports": "^5.2.1", + "@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/formidable": "^3", - "@types/node": "^22.10.10", + "@types/node": "^22.12.0", "@types/react": "^19.0.8", "@types/react-dom": "^19.0.3", "concurrently": "^9.1.2", @@ -57,7 +57,7 @@ "prettier": "^3.4.2", "rollup-plugin-visualizer": "^5.14.0", "terser": "^5.37.0", - "typescript-eslint": "8.21.0", + "typescript-eslint": "8.22.0", "vite": "^6.0.11", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^5.1.4" diff --git a/interface/src/api/app.ts b/interface/src/api/app.ts index dae9038f1..a56f4db53 100644 --- a/interface/src/api/app.ts +++ b/interface/src/api/app.ts @@ -5,7 +5,7 @@ import type { Action, Activity, CoreData, - DashboardItem, + DashboardData, DeviceData, DeviceEntity, Entities, @@ -22,7 +22,7 @@ import type { // Dashboard export const readDashboard = () => - alovaInstance.Get('/rest/dashboardData', { + alovaInstance.Get('/rest/dashboardData', { responseType: 'arraybuffer' // uses msgpack }); diff --git a/interface/src/app/main/Dashboard.tsx b/interface/src/app/main/Dashboard.tsx index 2ae103ab6..60dedf6f3 100644 --- a/interface/src/app/main/Dashboard.tsx +++ b/interface/src/app/main/Dashboard.tsx @@ -6,11 +6,11 @@ import { toast } from 'react-toastify'; import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import EditIcon from '@mui/icons-material/Edit'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import HelpOutlineIcon from '@mui/icons-material/HelpOutline'; import UnfoldLessIcon from '@mui/icons-material/UnfoldLess'; import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore'; import { Box, - Grid2 as Grid, IconButton, ToggleButton, ToggleButtonGroup, @@ -58,10 +58,10 @@ const Dashboard = () => { error, loading } = useRequest(readDashboard, { - initialData: [] + initialData: { connected: false, nodes: [] } }).onSuccess((event) => { - if (event.data.length !== parentNodes) { - setParentNodes(event.data.length); // count number of parents/devices + if (event.data.nodes.length !== parentNodes) { + setParentNodes(event.data.nodes.length); // count number of parents/devices } }); @@ -121,7 +121,7 @@ const Dashboard = () => { }); const tree = useTree( - { nodes: data }, + { nodes: data.nodes }, { onChange: undefined // not used but needed }, @@ -154,7 +154,7 @@ const Dashboard = () => { useEffect(() => { showAll - ? tree.fns.onAddAll(data.map((item: DashboardItem) => item.id)) // expand tree + ? tree.fns.onAddAll(data.nodes.map((item: DashboardItem) => item.id)) // expand tree : tree.fns.onRemoveAll(); // collapse tree }, [parentNodes]); @@ -224,47 +224,22 @@ const Dashboard = () => { return ; } - const hasFavEntities = data.filter( + if (loading) { + return; + } + + const hasFavEntities = data.nodes.filter( (item: DashboardItem) => item.id <= 90 ).length; return ( <> - - - - - {LL.DASHBOARD_1()} - - - - - - - - - - - - - - - + {!data.connected && ( + + )} - {!loading && !hasFavEntities && ( - + {data.connected && !hasFavEntities && ( + {LL.NO_DATA_1()}  @@ -280,80 +255,107 @@ const Dashboard = () => { )} - {data.length > 0 && ( - - 0 && ( + <> + + + + + + + + + + + + + + + + + - - {(tableList: DashboardItem[]) => ( - - {tableList.map((di: DashboardItem) => ( - editDashboardValue(di)} - > - {di.id > 99 ? ( - <> - {showName(di)} - - - {formatValue(LL, di.dv?.v, di.dv?.u)} - - +
+ {(tableList: DashboardItem[]) => ( + + {tableList.map((di: DashboardItem) => ( + editDashboardValue(di)} + > + {di.id > 99 ? ( + <> + {showName(di)} + + + {formatValue(LL, di.dv?.v, di.dv?.u)} + + - - {me.admin && - di.dv?.c && - !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && ( - editDashboardValue(di)} - > - - - )} - - - ) : ( - <> - {showName(di)} - - - - )} - - ))} - - )} -
-
-
+ + {me.admin && + di.dv?.c && + !hasMask( + di.dv.id, + DeviceEntityMask.DV_READONLY + ) && ( + editDashboardValue(di)} + > + + + )} + + + ) : ( + <> + {showName(di)} + + + + )} + + ))} + + )} + + + + )} ); diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index b2fc93525..b1ec9ffb3 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -124,6 +124,11 @@ export interface DashboardItem { nodes?: DashboardItem[]; // children nodes, optional } +export interface DashboardData { + connected: boolean; // true if connected to EMS bus + nodes: DashboardItem[]; +} + export interface DeviceValue { id: string; // index, contains mask+name v?: unknown; // value, Number, String or Boolean - can be undefined diff --git a/interface/src/i18n/cz/index.ts b/interface/src/i18n/cz/index.ts index 5d2ee6918..5c2e2f1c7 100644 --- a/interface/src/i18n/cz/index.ts +++ b/interface/src/i18n/cz/index.ts @@ -344,7 +344,7 @@ const cz: Translation = { DUPLICATE: 'Duplikát', UPGRADE: 'Upgrade', DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index 397d065bb..933419022 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -344,7 +344,7 @@ const en: Translation = { DEVELOPER_MODE: 'Developer Mode', DUPLICATE: 'Duplicate', UPGRADE: 'Upgrade', - NO_DATA_1: 'No favourite EMS entities found! Use the', + NO_DATA_1: 'No favourite EMS entities found yet. Use the', NO_DATA_2: 'module to mark them.', NO_DATA_3: 'To see all available entities go to' }; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index edc5a9c1b..df2fdbb16 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -344,7 +344,7 @@ const fr: Translation = { DUPLICATE: 'Duplicate', // TODO translate UPGRADE: 'Upgrade', // TODO translate DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 3125e432a..9f07d48b9 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -344,7 +344,7 @@ const it: Translation = { DUPLICATE: 'Duplicate', // TODO translate UPGRADE: 'Upgrade', // TODO translate DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index d46b5a806..0662bf841 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -344,7 +344,7 @@ const nl: Translation = { DUPLICATE: 'Duplicaat', UPGRADE: 'Upgraden', DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index fa120c1b7..457b18808 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -344,7 +344,7 @@ const no: Translation = { DUPLICATE: 'Duplicate', // TODO translate UPGRADE: 'Upgrade', // TODO translate DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index 16aa6843f..e6d016dfc 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -344,7 +344,7 @@ const pl: BaseTranslation = { DUPLICATE: 'Duplicate', // TODO translate UPGRADE: 'Upgrade', // TODO translate DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index e0ac16763..a8920b86c 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -344,7 +344,7 @@ const sv: Translation = { DUPLICATE: 'Dublett', UPGRADE: 'Uppgradera', DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 2948fb4b4..c0ac55959 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -344,7 +344,7 @@ const tr: Translation = { DUPLICATE: 'Duplicate', // TODO translate UPGRADE: 'Upgrade', // TODO translate DASHBOARD_1: 'All EMS entities that are active and marked as Favorite, plus all Custom Entities, Schedules and external Sensors data are displayed below.', // TODO translate - NO_DATA_1: 'No favourite EMS entities found. Use the', // TODO translate + NO_DATA_1: 'No favourite EMS entities found yet. Use the', // TODO translate NO_DATA_2: 'module to mark them.', // TODO translate NO_DATA_3: 'To see all available entities go to' // TODO translate }; diff --git a/interface/yarn.lock b/interface/yarn.lock index 5bad39894..50bc08217 100644 --- a/interface/yarn.lock +++ b/interface/yarn.lock @@ -74,7 +74,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.26.2, @babel/generator@npm:^7.26.5": +"@babel/generator@npm:^7.26.5": version: 7.26.5 resolution: "@babel/generator@npm:7.26.5" dependencies: @@ -170,7 +170,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.2, @babel/parser@npm:^7.26.5, @babel/parser@npm:^7.26.7": +"@babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.5, @babel/parser@npm:^7.26.7": version: 7.26.7 resolution: "@babel/parser@npm:7.26.7" dependencies: @@ -253,7 +253,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0, @babel/types@npm:^7.26.5, @babel/types@npm:^7.26.7": +"@babel/types@npm:^7.25.9, @babel/types@npm:^7.26.5, @babel/types@npm:^7.26.7": version: 7.26.7 resolution: "@babel/types@npm:7.26.7" dependencies: @@ -1237,14 +1237,14 @@ __metadata: languageName: node linkType: hard -"@trivago/prettier-plugin-sort-imports@npm:^5.2.1": - version: 5.2.1 - resolution: "@trivago/prettier-plugin-sort-imports@npm:5.2.1" +"@trivago/prettier-plugin-sort-imports@npm:^5.2.2": + version: 5.2.2 + resolution: "@trivago/prettier-plugin-sort-imports@npm:5.2.2" dependencies: - "@babel/generator": "npm:^7.26.2" - "@babel/parser": "npm:^7.26.2" - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.26.0" + "@babel/generator": "npm:^7.26.5" + "@babel/parser": "npm:^7.26.7" + "@babel/traverse": "npm:^7.26.7" + "@babel/types": "npm:^7.26.7" javascript-natural-sort: "npm:^0.7.1" lodash: "npm:^4.17.21" peerDependencies: @@ -1259,7 +1259,7 @@ __metadata: optional: true svelte: optional: true - checksum: 10c0/fd782f84d44c61159dce099775a86ebb5082b5e5eea205ec71d6fede3cf079aafb8f9a9979d5742ff0126598a37098cf679d5bad268320907513f2984df3d501 + checksum: 10c0/2a4f0464f1f5a294bcd34558fb053f8263f0c62c4a7fcdd3ce40c9822a68ac8b4d951700ab6d01eb3919efe0ed44e4191997edd494d59679b22db1c0db00474e languageName: node linkType: hard @@ -1399,7 +1399,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^22.10.10": +"@types/node@npm:*": version: 22.10.10 resolution: "@types/node@npm:22.10.10" dependencies: @@ -1408,6 +1408,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^22.12.0": + version: 22.12.0 + resolution: "@types/node@npm:22.12.0" + dependencies: + undici-types: "npm:~6.20.0" + checksum: 10c0/be220706732d95db2ed1c441c1e64cab90bf9a47519ce6f4c79cc5a9ec9d5c517131a149a9ac30afac1a30103e67e3a00d453ba7c1b0141608a3a7ba6397c303 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -1467,15 +1476,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/eslint-plugin@npm:8.21.0" +"@typescript-eslint/eslint-plugin@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.22.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:8.21.0" - "@typescript-eslint/type-utils": "npm:8.21.0" - "@typescript-eslint/utils": "npm:8.21.0" - "@typescript-eslint/visitor-keys": "npm:8.21.0" + "@typescript-eslint/scope-manager": "npm:8.22.0" + "@typescript-eslint/type-utils": "npm:8.22.0" + "@typescript-eslint/utils": "npm:8.22.0" + "@typescript-eslint/visitor-keys": "npm:8.22.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" @@ -1484,64 +1493,64 @@ __metadata: "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/4601d21ec35b9fa5cfc1ad0330733ab40d6c6822c7fc15c3584a16f678c9a72e077a1725a950823fe0f499a15f3981795b1ea5d1e7a1be5c7b8296ea9ae6327c + checksum: 10c0/eecc23e05287cc99a43855d64c0f0898f690ee14b8c31b60ba92ce9732443f6b0c9695514b276fb2ecd27e64c15d4c38cd28b570779115525b4dfdbba60e81ca languageName: node linkType: hard -"@typescript-eslint/parser@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/parser@npm:8.21.0" +"@typescript-eslint/parser@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/parser@npm:8.22.0" dependencies: - "@typescript-eslint/scope-manager": "npm:8.21.0" - "@typescript-eslint/types": "npm:8.21.0" - "@typescript-eslint/typescript-estree": "npm:8.21.0" - "@typescript-eslint/visitor-keys": "npm:8.21.0" + "@typescript-eslint/scope-manager": "npm:8.22.0" + "@typescript-eslint/types": "npm:8.22.0" + "@typescript-eslint/typescript-estree": "npm:8.22.0" + "@typescript-eslint/visitor-keys": "npm:8.22.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/aadebd50ca7aa2d61ad85d890c0d7010f2c293ec4d50a7833ef9674f232f0bc7118faa93a898771fbea50f02d542d687cf3569421b23f72fe6fed6895d5506fc + checksum: 10c0/6575684d4724aa908b0d6a29db5d5054b9277804844ee4179c77371f8b8b84534b9b7e4df0e282c5f39729ae6f0019208a6b83f0ca5d0f06f9da5a06d8ddb4fd languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/scope-manager@npm:8.21.0" +"@typescript-eslint/scope-manager@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/scope-manager@npm:8.22.0" dependencies: - "@typescript-eslint/types": "npm:8.21.0" - "@typescript-eslint/visitor-keys": "npm:8.21.0" - checksum: 10c0/ea405e79dc884ea1c76465604db52f9b0941d6cbb0bde6bce1af689ef212f782e214de69d46503c7c47bfc180d763369b7433f1965e3be3c442b417e8c9f8f75 + "@typescript-eslint/types": "npm:8.22.0" + "@typescript-eslint/visitor-keys": "npm:8.22.0" + checksum: 10c0/f393ab32086f4b095fcd77169abb5200ad94f282860944d164cec8c9b70090c36235f49b066ba24dfd953201b7730e48200a254e5950a9a3565acdacbbc0fd64 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/type-utils@npm:8.21.0" +"@typescript-eslint/type-utils@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/type-utils@npm:8.22.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:8.21.0" - "@typescript-eslint/utils": "npm:8.21.0" + "@typescript-eslint/typescript-estree": "npm:8.22.0" + "@typescript-eslint/utils": "npm:8.22.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^2.0.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/617f5dfe83fd9a7c722b27fa4e7f0c84f29baa94f75a4e8e5ccfd5b0a373437f65724e21b9642870fb0960f204b1a7f516a038200a12f8118f21b1bf86315bf3 + checksum: 10c0/dc457d9184dc2156eda225c63de03b1052d75464d6393edaf0f1728eecf64170f73e19bc9b9d4a4a029870ce25015b59bd6705e1e18b731ca4fcecac4398bfb7 languageName: node linkType: hard -"@typescript-eslint/types@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/types@npm:8.21.0" - checksum: 10c0/67dfd300cc614d7b02e94d0dacfb228a7f4c3fd4eede29c43adb9e9fcc16365ae3df8d6165018da3c123dce65545bef03e3e8183f35e9b3a911ffc727e3274c2 +"@typescript-eslint/types@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/types@npm:8.22.0" + checksum: 10c0/6357d0937e2b84ddb00763d05053fe50f2270fa428aa11f1ad6a1293827cf54da7e6d4d20b00b9d4f633b6982a2eb0e494f05285daa1279d8a3493f0d8abae18 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.21.0" +"@typescript-eslint/typescript-estree@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.22.0" dependencies: - "@typescript-eslint/types": "npm:8.21.0" - "@typescript-eslint/visitor-keys": "npm:8.21.0" + "@typescript-eslint/types": "npm:8.22.0" + "@typescript-eslint/visitor-keys": "npm:8.22.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" @@ -1550,32 +1559,32 @@ __metadata: ts-api-utils: "npm:^2.0.0" peerDependencies: typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/0cf5b0382524f4af54fb5ec71ca7e939ec922711f2d77b383740b28dd4b21407b0ab5dded62df6819d01c12c0b354e95667e3c7025a5d27d05b805161ab94855 + checksum: 10c0/0a9d77fbadfb1e54c06abde424e461103576595c70e50ae8a15a3d7c07f125f253f505208e1ea5cc483b9073d95fc10ce0c4ddfe0fe08ec2aceda6314c341e0d languageName: node linkType: hard -"@typescript-eslint/utils@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/utils@npm:8.21.0" +"@typescript-eslint/utils@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/utils@npm:8.22.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.21.0" - "@typescript-eslint/types": "npm:8.21.0" - "@typescript-eslint/typescript-estree": "npm:8.21.0" + "@typescript-eslint/scope-manager": "npm:8.22.0" + "@typescript-eslint/types": "npm:8.22.0" + "@typescript-eslint/typescript-estree": "npm:8.22.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/d8347dbe9176417220aa62902cfc1b2007a9246bb7a8cccdf8590120903eb50ca14cb668efaab4646d086277f2367559985b62230e43ebd8b0723d237eeaa2f2 + checksum: 10c0/6f1e3f9c0fb865c8cef4fdca04679cea7357ed011338b54d80550e9ad5369a3f24cbe4b0985d293192fe351fa133e5f4ea401f47af90bb46c21903bfe087b398 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.21.0": - version: 8.21.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.21.0" +"@typescript-eslint/visitor-keys@npm:8.22.0": + version: 8.22.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.22.0" dependencies: - "@typescript-eslint/types": "npm:8.21.0" + "@typescript-eslint/types": "npm:8.22.0" eslint-visitor-keys: "npm:^4.2.0" - checksum: 10c0/b3f1412f550e35c0d7ae0410db616951116b365167539f9b85710d8bc2b36b322c5e637caee84cc1ae5df8f1d961880250d52ffdef352b31e5bdbef74ba6fea9 + checksum: 10c0/fd83d2feadaf79950427fbbc3d23ca01cf4646ce7e0dd515a9c881d31ec1cc768e7b8898d3af065e31df39452501a3345092581cbfccac89e89d293519540557 languageName: node linkType: hard @@ -1593,9 +1602,9 @@ __metadata: "@preact/compat": "npm:^18.3.1" "@preact/preset-vite": "npm:^2.10.0" "@table-library/react-table-library": "npm:4.1.7" - "@trivago/prettier-plugin-sort-imports": "npm:^5.2.1" + "@trivago/prettier-plugin-sort-imports": "npm:^5.2.2" "@types/formidable": "npm:^3" - "@types/node": "npm:^22.10.10" + "@types/node": "npm:^22.12.0" "@types/react": "npm:^19.0.8" "@types/react-dom": "npm:^19.0.3" alova: "npm:3.2.8" @@ -1617,7 +1626,7 @@ __metadata: terser: "npm:^5.37.0" typesafe-i18n: "npm:^5.26.2" typescript: "npm:^5.7.3" - typescript-eslint: "npm:8.21.0" + typescript-eslint: "npm:8.22.0" vite: "npm:^6.0.11" vite-plugin-imagemin: "npm:^0.6.1" vite-tsconfig-paths: "npm:^5.1.4" @@ -6646,17 +6655,17 @@ __metadata: languageName: node linkType: hard -"typescript-eslint@npm:8.21.0": - version: 8.21.0 - resolution: "typescript-eslint@npm:8.21.0" +"typescript-eslint@npm:8.22.0": + version: 8.22.0 + resolution: "typescript-eslint@npm:8.22.0" dependencies: - "@typescript-eslint/eslint-plugin": "npm:8.21.0" - "@typescript-eslint/parser": "npm:8.21.0" - "@typescript-eslint/utils": "npm:8.21.0" + "@typescript-eslint/eslint-plugin": "npm:8.22.0" + "@typescript-eslint/parser": "npm:8.22.0" + "@typescript-eslint/utils": "npm:8.22.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: ">=4.8.4 <5.8.0" - checksum: 10c0/44e5c341ad7f0b41dce3b4ca7a4c0a399ebe51a5323d930750db1e308367b4813a620f4c2332a5774a1dccd0047ebbaf993a8b7effd67389e9069b29b5701520 + checksum: 10c0/d7a5ec4a08d0eb0a7cc0bf81919f0305a9fbb091b187cef6d3fa220c1673414dcb46e6cd5c9325050d3df2bbb283756399c1b2720eb4eadaab0bdc3cc8302405 languageName: node linkType: hard diff --git a/mock-api/rest_server.ts b/mock-api/rest_server.ts index d7221e81e..0a0250c81 100644 --- a/mock-api/rest_server.ts +++ b/mock-api/rest_server.ts @@ -4500,14 +4500,14 @@ router params.id ? deviceEntities(Number(params.id)) : status(404) ) .get(EMSESP_DASHBOARD_DATA_ENDPOINT, () => { - let dashboard_data: { id?: number; n?: string; t?: number; nodes?: any[] }[] = + let dashboard_nodes: { id?: number; n?: string; t?: number; nodes?: any[] }[] = []; let dashboard_object: { id?: number; n?: string; t?: number; nodes?: any[] } = {}; let fake = false; - fake = true; // for testing, shows a subset of data + // fake = true; // for testing, shows a subset of data if (!fake) { // pick EMS devices from coredata @@ -4522,7 +4522,7 @@ router }; // only add to dashboard if we have values if ((dashboard_object.nodes ?? []).length > 0) { - dashboard_data.push(dashboard_object); + dashboard_nodes.push(dashboard_object); } } @@ -4534,7 +4534,7 @@ router }; // only add to dashboard if we have values if ((dashboard_object.nodes ?? []).length > 0) { - dashboard_data.push(dashboard_object); + dashboard_nodes.push(dashboard_object); } // add temperature sensor data. no command c @@ -4554,7 +4554,7 @@ router }; // only add to dashboard if we have values if ((dashboard_object.nodes ?? []).length > 0) { - dashboard_data.push(dashboard_object); + dashboard_nodes.push(dashboard_object); } // add analog sensor data. no command c @@ -4575,7 +4575,7 @@ router }; // only add to dashboard if we have values if ((dashboard_object.nodes ?? []).length > 0) { - dashboard_data.push(dashboard_object); + dashboard_nodes.push(dashboard_object); } // add the scheduler data @@ -4597,7 +4597,7 @@ router }; // only add to dashboard if we have values if ((dashboard_object.nodes ?? []).length > 0) { - dashboard_data.push(dashboard_object); + dashboard_nodes.push(dashboard_object); } } else { // for testing only @@ -4609,7 +4609,7 @@ router nodes: getDashboardEntityData(DeviceTypeUniqueID.CUSTOM_UID) }; if ((dashboard_object.nodes ?? []).length > 0) { - dashboard_data.push(dashboard_object); + dashboard_nodes.push(dashboard_object); } // add the scheduler data @@ -4633,10 +4633,15 @@ router // } } - // console.log('dashboard_data: ', dashboard_data); + const dashboardData = { + // connect: false, + connected: true, + nodes: dashboard_nodes + }; + // console.log('dashboardData: ', dashboardData); // return dashboard_data; // if not using msgpack - return new Response(encoder.encode(dashboard_data), { headers }); // msgpack it + return new Response(encoder.encode(dashboardData), { headers }); // msgpack it }) // Customizations diff --git a/src/version.h b/src/version.h index 38c97aac0..40cdeb6f9 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.2-dev.16" +#define EMSESP_APP_VERSION "3.7.2-dev.17" diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 0abd8b1ef..031c246a5 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -352,19 +352,25 @@ void WebDataService::write_analog_sensor(AsyncWebServerRequest * request, JsonVa // this is used in the dashboard and contains all ems device information // /dashboardData endpoint void WebDataService::dashboard_data(AsyncWebServerRequest * request) { - auto * response = new AsyncMessagePackResponse(true); + auto * response = new AsyncMessagePackResponse(); #if defined(EMSESP_STANDALONE) JsonDocument doc; - JsonArray root = doc.to(); + JsonObject root = doc.to(); #else - JsonArray root = response->getRoot(); + JsonObject root = response->getRoot(); #endif - // first do all the recognized devices + // add state of EMS bus + root["connected"] = EMSESP::bus_status() != 2; + + // add all the data + JsonArray nodes = root["nodes"].to(); + + // first fetch all the recognized devices for (const auto & emsdevice : EMSESP::emsdevices) { if (emsdevice->count_entities_fav()) { - JsonObject obj = root.add(); + JsonObject obj = nodes.add(); obj["id"] = emsdevice->unique_id(); // it's unique id obj["n"] = emsdevice->name(); // custom name obj["t"] = emsdevice->device_type(); // device type number @@ -374,15 +380,15 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { // add custom entities, if we have any if (EMSESP::webCustomEntityService.count_entities()) { - JsonObject obj = root.add(); + JsonObject obj = nodes.add(); obj["id"] = EMSdevice::DeviceTypeUniqueID::CUSTOM_UID; // it's unique id obj["t"] = EMSdevice::DeviceType::CUSTOM; // device type number EMSESP::webCustomEntityService.generate_value_web(obj, true); } - // add temperature sensors + // add temperature sensors, if we have any if (EMSESP::temperaturesensor_.have_sensors()) { - JsonObject obj = root.add(); + JsonObject obj = nodes.add(); obj["id"] = EMSdevice::DeviceTypeUniqueID::TEMPERATURESENSOR_UID; // it's unique id obj["t"] = EMSdevice::DeviceType::TEMPERATURESENSOR; // device type number JsonArray nodes = obj["nodes"].to(); @@ -409,7 +415,7 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { // add analog sensors, count excludes disabled entries if (EMSESP::analog_enabled() && EMSESP::analogsensor_.count_entities(false)) { - JsonObject obj = root.add(); + JsonObject obj = nodes.add(); obj["id"] = EMSdevice::DeviceTypeUniqueID::ANALOGSENSOR_UID; // it's unique id obj["t"] = EMSdevice::DeviceType::ANALOGSENSOR; // device type number JsonArray nodes = obj["nodes"].to(); @@ -449,7 +455,7 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { // show scheduler, with name, on/off if (EMSESP::webSchedulerService.count_entities(true)) { - JsonObject obj = root.add(); + JsonObject obj = nodes.add(); obj["id"] = EMSdevice::DeviceTypeUniqueID::SCHEDULER_UID; // it's unique id obj["t"] = EMSdevice::DeviceType::SCHEDULER; // device type number JsonArray nodes = obj["nodes"].to();