Merge pull request #1868 from proddy/dev

minor changes
This commit is contained in:
Proddy
2024-07-18 11:26:52 +02:00
committed by GitHub
17 changed files with 218 additions and 249 deletions

View File

@@ -26,11 +26,11 @@
"@alova/scene-react": "^1.6.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5.16.1",
"@mui/material": "^5.16.1",
"@mui/icons-material": "^5.16.4",
"@mui/material": "^5.16.4",
"@table-library/react-table-library": "4.1.7",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.14.10",
"@types/node": "^20.14.11",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@types/react-router-dom": "^5.3.3",
@@ -44,7 +44,7 @@
"react-dom": "latest",
"react-dropzone": "^14.2.3",
"react-icons": "^5.2.1",
"react-router-dom": "^6.24.1",
"react-router-dom": "^6.25.1",
"react-toastify": "^10.0.5",
"typesafe-i18n": "^5.26.2",
"typescript": "^5.5.3"
@@ -62,9 +62,9 @@
"preact": "^10.22.1",
"prettier": "^3.3.3",
"rollup-plugin-visualizer": "^5.12.0",
"terser": "^5.31.2",
"terser": "^5.31.3",
"typescript-eslint": "8.0.0-alpha.10",
"vite": "^5.3.3",
"vite": "^5.3.4",
"vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^4.3.2"
},

View File

@@ -26,6 +26,8 @@ import { useRequest } from 'alova';
import { ButtonRow, FormLoader, SectionContent, useLayoutTitle } from 'components';
import { useI18nContext } from 'i18n/i18n-react';
import BBQKeesIcon from '../../project/bbqkees.svg';
function formatNumber(num: number) {
return new Intl.NumberFormat().format(num);
}
@@ -51,8 +53,15 @@ const ESPSystemStatus: FC = () => {
<List>
<ListItem>
<ListItemAvatar>
<Avatar sx={{ bgcolor: '#68374d', color: 'white' }}>
<TapAndPlayIcon />
<Avatar sx={{ bgcolor: '#003289', color: 'white' }}>
{data.model ? (
<img
src={BBQKeesIcon}
style={{ width: 16, verticalAlign: 'middle' }}
/>
) : (
<TapAndPlayIcon />
)}
</Avatar>
</ListItemAvatar>
<ListItemText
@@ -108,7 +117,7 @@ const ESPSystemStatus: FC = () => {
formatNumber(data.free_heap) +
' KB (' +
formatNumber(data.max_alloc_heap) +
' KB alloc)'
' KB max alloc)'
}
/>
</ListItem>

View File

@@ -0,0 +1,26 @@
<svg width="20mm" height="30.146mm" version="1.1" viewBox="0 0 20 30.146" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(-86.195 -104.7)">
<g transform="matrix(.53414 0 0 .53414 70.913 49.568)">
<g fill="#fff">
<path d="m66.034 122.7h-37.398a18.722 18.722 0 0 0-0.02643 0.52631 18.722 18.722 0 0 0 18.722 18.722 18.722 18.722 0 0 0 18.722-18.722 18.722 18.722 0 0 0-0.01882-0.52631z" color="#000000" stroke-width=".15037" style="-inkscape-stroke:none"/>
<path d="m30.943 141.6v2h32.174v-2z" color="#000000" style="-inkscape-stroke:none"/>
<path d="m40.738 142-6.9004 11.951 1.7305 1 6.9023-11.951z" color="#000000" style="-inkscape-stroke:none"/>
<g fill="#fff" fill-rule="evenodd">
<path d="m32.395 158.45-0.0041-7.9929 6.9282 4z" color="#000000" stroke-width=".8pt" style="-inkscape-stroke:none"/>
<path d="m31.857 149.54 0.0039 9.8398 0.80078-0.46094 7.7246-4.4551zm1.0664 1.8457 5.3281 3.0762-5.3242 3.0723z" color="#000000" style="-inkscape-stroke:none"/>
</g>
<path d="m56.547 103.22-1.5645 1.2461s0.33514 0.43498 0.48828 1.0391c0.15315 0.60408 0.18926 1.209-0.57617 1.9688-1.1965 1.1876-1.5061 2.5227-1.4004 3.4902 0.10574 0.96749 0.5918 1.6426 0.5918 1.6426l1.6211-1.1699s-0.17552-0.2403-0.22461-0.68946c-0.04909-0.44915-0.0062-1.0331 0.82031-1.8535 1.2576-1.2483 1.3774-2.8142 1.1074-3.8789s-0.86328-1.7949-0.86328-1.7949z" color="#000000" style="-inkscape-stroke:none"/>
<path d="m48.918 103.22-1.5645 1.2461s0.33513 0.43498 0.48828 1.0391 0.18926 1.209-0.57617 1.9688c-1.1965 1.1876-1.5042 2.5227-1.3984 3.4902 0.10574 0.96749 0.58984 1.6426 0.58984 1.6426l1.623-1.1699s-0.17552-0.2403-0.22461-0.68946c-0.04909-0.44915-0.0062-1.0331 0.82031-1.8535 1.2576-1.2483 1.3754-2.8142 1.1055-3.8789s-0.86328-1.7949-0.86328-1.7949z" color="#000000" style="-inkscape-stroke:none"/>
<path d="m41.291 103.22-1.5664 1.2461s0.33709 0.43498 0.49024 1.0391 0.18926 1.209-0.57617 1.9688c-1.1965 1.1876-1.5061 2.5227-1.4004 3.4902s0.5918 1.6426 0.5918 1.6426l1.6211-1.1699s-0.17552-0.2403-0.22461-0.68946c-0.04909-0.44916-0.0062-1.0331 0.82031-1.8535 1.2576-1.2483 1.3754-2.8142 1.1055-3.8789-0.26993-1.0647-0.86133-1.7949-0.86133-1.7949z" color="#000000" style="-inkscape-stroke:none"/>
<path d="m54.896 113.47c-1.4548 0-2.706 0.87699-3.5293 2.0957-0.82334 1.2187-1.291 2.8147-1.291 4.5586v8e-3c5.87e-4 0.0787 0.0036 0.15349 0.0059 0.22656l1.998-0.0605c-0.0019-0.0604-0.0034-0.11856-0.0039-0.17383v-2e-3c-1.6e-5 -2e-3 1.4e-5 -4e-3 0-6e-3 0.0015-1.3755 0.38921-2.6056 0.94726-3.4316 0.55917-0.82768 1.2182-1.2148 1.873-1.2148 0.65485 0 1.3139 0.38716 1.873 1.2148s0.94727 2.0607 0.94727 3.4394h2c0-1.7439-0.46768-3.3399-1.291-4.5586-0.82334-1.2187-2.0745-2.0957-3.5293-2.0957z" color="#000000" style="-inkscape-stroke:none;paint-order:stroke fill markers"/>
<path d="m47.27 113.47c-1.4548 0-2.706 0.87699-3.5293 2.0957-0.82334 1.2187-1.291 2.8147-1.291 4.5586h2c0-1.3788 0.38809-2.6118 0.94726-3.4394 0.55917-0.82768 1.2182-1.2148 1.873-1.2148 0.65484-1e-5 1.3119 0.38716 1.8711 1.2148 0.55802 0.82598 0.94567 2.0563 0.94727 3.4316-0.0018 0.0584-0.0035 0.11387-0.0059 0.16406l1.998 0.0957c0.0037-0.0788 0.0057-0.15249 0.0078-0.22071l2e-3 -0.0156v-0.0156c0-1.7439-0.46767-3.3399-1.291-4.5586-0.82334-1.2187-2.0745-2.0957-3.5293-2.0957z" color="#000000" style="-inkscape-stroke:none"/>
<path d="m39.641 113.47c-1.4548 0-2.706 0.87699-3.5293 2.0957-0.82334 1.2187-1.291 2.8147-1.291 4.5586v0.012c8.96e-4 0.0721 0.0037 0.15312 0.0078 0.24024l1.9961-0.0957c-0.0021-0.0456-0.0031-0.0976-0.0039-0.15625v-2e-3c3.87e-4 -1.378 0.38837-2.6102 0.94727-3.4375 0.55917-0.82768 1.2182-1.2148 1.873-1.2148 0.65484 0 1.3139 0.38716 1.873 1.2148s0.94726 2.0607 0.94726 3.4394h2c0-1.7439-0.46768-3.3399-1.291-4.5586s-2.0745-2.0957-3.5293-2.0957z" color="#000000" style="-inkscape-stroke:none"/>
<path d="m57.557 119.33v2h5.8418v-2z" color="#000000" style="-inkscape-stroke:none"/>
<path d="m31.137 119.33v2h5.8418v-2z" color="#000000" style="-inkscape-stroke:none"/>
</g>
<path d="m35.826 119.95v0.77149h22.883v-0.77149z" color="#000000" fill-opacity="0" style="-inkscape-stroke:none"/>
<path d="m59.064 150.73c-2.4534 0-4.4629 2.0115-4.4629 4.4648s2.0095 4.4629 4.4629 4.4629 4.4629-2.0095 4.4629-4.4629-2.0095-4.4648-4.4629-4.4648zm0 2c1.3725 0 2.4629 1.0924 2.4629 2.4648s-1.0904 2.4629-2.4629 2.4629-2.4629-1.0904-2.4629-2.4629 1.0904-2.4648 2.4629-2.4648z" color="#000000" fill="#fff" style="-inkscape-stroke:none;paint-order:stroke fill markers"/>
<path d="m54.932 142.14-1.8359 0.79687 3.752 8.6582 1.8359-0.79493z" color="#000000" fill="#fff" style="-inkscape-stroke:none"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -1046,44 +1046,6 @@ __metadata:
languageName: node
linkType: hard
"@floating-ui/core@npm:^1.0.0":
version: 1.6.1
resolution: "@floating-ui/core@npm:1.6.1"
dependencies:
"@floating-ui/utils": "npm:^0.2.0"
checksum: 10c0/7d78b3788d438807d3c1a52477ee1693a29b8a4416dd6e13761427925d9fba1d45c849527752d8fd9776842182d919fddf7ecbc34f3bf2de3bafa1717619a56f
languageName: node
linkType: hard
"@floating-ui/dom@npm:^1.0.0":
version: 1.6.5
resolution: "@floating-ui/dom@npm:1.6.5"
dependencies:
"@floating-ui/core": "npm:^1.0.0"
"@floating-ui/utils": "npm:^0.2.0"
checksum: 10c0/ebdc14806f786e60df8e7cc2c30bf9cd4d75fe734f06d755588bbdef2f60d0a0f21dffb14abdc58dea96e5577e2e366feca6d66ba962018efd1bc91a3ece4526
languageName: node
linkType: hard
"@floating-ui/react-dom@npm:^2.0.8":
version: 2.0.9
resolution: "@floating-ui/react-dom@npm:2.0.9"
dependencies:
"@floating-ui/dom": "npm:^1.0.0"
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 10c0/d8cd1fb2b8a5012ca692d6f677a0af923ef81131f69accea8ce8b5413202ab4c3c79e6eda1446f4dad06a2dfd596ece748c562ba28c289678a856755db4f528f
languageName: node
linkType: hard
"@floating-ui/utils@npm:^0.2.0":
version: 0.2.2
resolution: "@floating-ui/utils@npm:0.2.2"
checksum: 10c0/b2becdcafdf395af1641348da0031ff1eaad2bc60c22e14bd3abad4acfe2c8401e03097173d89a2f646a99b75819a78ef21ebb2572cab0042a56dd654b0065cd
languageName: node
linkType: hard
"@humanwhocodes/module-importer@npm:^1.0.1":
version: 1.0.1
resolution: "@humanwhocodes/module-importer@npm:1.0.1"
@@ -1164,38 +1126,16 @@ __metadata:
languageName: node
linkType: hard
"@mui/base@npm:5.0.0-beta.40":
version: 5.0.0-beta.40
resolution: "@mui/base@npm:5.0.0-beta.40"
dependencies:
"@babel/runtime": "npm:^7.23.9"
"@floating-ui/react-dom": "npm:^2.0.8"
"@mui/types": "npm:^7.2.14"
"@mui/utils": "npm:^5.15.14"
"@popperjs/core": "npm:^2.11.8"
clsx: "npm:^2.1.0"
prop-types: "npm:^15.8.1"
peerDependencies:
"@types/react": ^17.0.0 || ^18.0.0
react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/631b4ee389e23d82c16c5845c2849af43000f52f1def639b9bb5bf39fd09f4eab93787d32950b715a7de7b689faab53bb7c9a78f6fd12b663876cf8128d45de1
"@mui/core-downloads-tracker@npm:^5.16.4":
version: 5.16.4
resolution: "@mui/core-downloads-tracker@npm:5.16.4"
checksum: 10c0/639099e14132a66a472a92432d2b0fca7c2ebb718afcc22b4a1ebd537fe34f96fed57d95e84525461d1ab2a41672a14a746da7de8060ed3a60fafc0beadb3ebb
languageName: node
linkType: hard
"@mui/core-downloads-tracker@npm:^5.16.1":
version: 5.16.1
resolution: "@mui/core-downloads-tracker@npm:5.16.1"
checksum: 10c0/2bdad71c53d65e59eba4889e6d3270b964200dddae448ae7d095de7130a4ec82e7fccdf8668488996e22993b653b91544195c10eeb996dc1c3a6c7a34c88c9c4
languageName: node
linkType: hard
"@mui/icons-material@npm:^5.16.1":
version: 5.16.1
resolution: "@mui/icons-material@npm:5.16.1"
"@mui/icons-material@npm:^5.16.4":
version: 5.16.4
resolution: "@mui/icons-material@npm:5.16.4"
dependencies:
"@babel/runtime": "npm:^7.23.9"
peerDependencies:
@@ -1205,20 +1145,20 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/90c235ee065a18e07e2c3059dcfe15ef880c5f936cde538c41ba3dfab83bbb963093a28603852647e0ef05e0a233e50ea4cd932d9ae58dcf803dadc16dd603af
checksum: 10c0/e6cd3b64dd02d21182f0a0509d412a084fdea8752e4a202907cd1cf92a5476ec87e6074a409ebcb9a35e29c91d20729e9eddd9530c1d3755a93b0f56cf3be519
languageName: node
linkType: hard
"@mui/material@npm:^5.16.1":
version: 5.16.1
resolution: "@mui/material@npm:5.16.1"
"@mui/material@npm:^5.16.4":
version: 5.16.4
resolution: "@mui/material@npm:5.16.4"
dependencies:
"@babel/runtime": "npm:^7.23.9"
"@mui/base": "npm:5.0.0-beta.40"
"@mui/core-downloads-tracker": "npm:^5.16.1"
"@mui/system": "npm:^5.16.1"
"@mui/core-downloads-tracker": "npm:^5.16.4"
"@mui/system": "npm:^5.16.4"
"@mui/types": "npm:^7.2.15"
"@mui/utils": "npm:^5.16.1"
"@mui/utils": "npm:^5.16.4"
"@popperjs/core": "npm:^2.11.8"
"@types/react-transition-group": "npm:^4.4.10"
clsx: "npm:^2.1.0"
csstype: "npm:^3.1.3"
@@ -1238,16 +1178,16 @@ __metadata:
optional: true
"@types/react":
optional: true
checksum: 10c0/13baf645c276a97fade56ccce83ceaea95ee71cff56fea407cce576ff96b81115dacc5dd3d30a250047fc104e5ce63c28bdc095351e567407f9944af9d9daa83
checksum: 10c0/ab12f3219d3a6b5dd3564e7b3826e283167c64b947774e3e35301419d35cd9875d45d8625e8c145d59fe38c7a7ef110251b11a47b94e5468fa96afbb179d2e1f
languageName: node
linkType: hard
"@mui/private-theming@npm:^5.16.1":
version: 5.16.1
resolution: "@mui/private-theming@npm:5.16.1"
"@mui/private-theming@npm:^5.16.4":
version: 5.16.4
resolution: "@mui/private-theming@npm:5.16.4"
dependencies:
"@babel/runtime": "npm:^7.23.9"
"@mui/utils": "npm:^5.16.1"
"@mui/utils": "npm:^5.16.4"
prop-types: "npm:^15.8.1"
peerDependencies:
"@types/react": ^17.0.0 || ^18.0.0
@@ -1255,13 +1195,13 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/8a95c7d59be1fd3ba8e49addb76870d5efe675a8f61ecb1558306053f0c71abad22f08d551e55fc48d5c012b0d1f1aefe924e0d3395485451ad1fe92a47adab2
checksum: 10c0/3c191afe4025cac9bbdecae1ea6232155e71c45c2929acce1ce31dd4c913800d6e9eaa38897e91dd7bff74529de3247768d26120c54c33ef69e40136c9ec6b04
languageName: node
linkType: hard
"@mui/styled-engine@npm:^5.16.1":
version: 5.16.1
resolution: "@mui/styled-engine@npm:5.16.1"
"@mui/styled-engine@npm:^5.16.4":
version: 5.16.4
resolution: "@mui/styled-engine@npm:5.16.4"
dependencies:
"@babel/runtime": "npm:^7.23.9"
"@emotion/cache": "npm:^11.11.0"
@@ -1276,19 +1216,19 @@ __metadata:
optional: true
"@emotion/styled":
optional: true
checksum: 10c0/fc011390c64ff970ad095e0a9e18f5ad777491fd49974233137b673fa9698d178c6b5f6346a28c1d8a1718dd453879ded4198bbc73e73dfcc8d5a90ea17760f6
checksum: 10c0/5dbd656aedfbf308dbbbb651a589c12b85ba1af2b6b351a657ee5af1210eab9629cee0781b2dc33b14b0a9482f7a6fa6e8b695d94f7cc5f1f7df7efe88034372
languageName: node
linkType: hard
"@mui/system@npm:^5.16.1":
version: 5.16.1
resolution: "@mui/system@npm:5.16.1"
"@mui/system@npm:^5.16.4":
version: 5.16.4
resolution: "@mui/system@npm:5.16.4"
dependencies:
"@babel/runtime": "npm:^7.23.9"
"@mui/private-theming": "npm:^5.16.1"
"@mui/styled-engine": "npm:^5.16.1"
"@mui/private-theming": "npm:^5.16.4"
"@mui/styled-engine": "npm:^5.16.4"
"@mui/types": "npm:^7.2.15"
"@mui/utils": "npm:^5.16.1"
"@mui/utils": "npm:^5.16.4"
clsx: "npm:^2.1.0"
csstype: "npm:^3.1.3"
prop-types: "npm:^15.8.1"
@@ -1304,19 +1244,7 @@ __metadata:
optional: true
"@types/react":
optional: true
checksum: 10c0/17b76d32d4ee1800910993d7309c36a8ea1982890ee952d1a301e5125a8ebe7bcdf3d8930fb385dd79712c4e3ea9e9e9547fac23b79dc874b60b33b0dbdffa8a
languageName: node
linkType: hard
"@mui/types@npm:^7.2.14":
version: 7.2.14
resolution: "@mui/types@npm:7.2.14"
peerDependencies:
"@types/react": ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/d4e0a9fce4bddfb5e0b7b6be1b15b591df33bb90ef0087e4bd5fe85f00f62776c7ed0e4698e7fb43213e1f04064aac1695b53ca52aaeaee7dbba248a792bdd1e
checksum: 10c0/1665e2f9b6b30f2177b49b19bc778980e3f076167a1436f8b8bf513075674192e33684ab3a9262144f6008d3f9521ac4c073f5e15abfb4c989efc78cd09f8ecc
languageName: node
linkType: hard
@@ -1332,30 +1260,13 @@ __metadata:
languageName: node
linkType: hard
"@mui/utils@npm:^5.15.14":
version: 5.15.14
resolution: "@mui/utils@npm:5.15.14"
dependencies:
"@babel/runtime": "npm:^7.23.9"
"@types/prop-types": "npm:^15.7.11"
prop-types: "npm:^15.8.1"
react-is: "npm:^18.2.0"
peerDependencies:
"@types/react": ^17.0.0 || ^18.0.0
react: ^17.0.0 || ^18.0.0
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/36265988477637a011361456b40929de928e215466b72e6c48673a2088610d83e09960a3e0608100448910683079fc80a5e11dbf49b9ce7109dd8e49403ae3b3
languageName: node
linkType: hard
"@mui/utils@npm:^5.16.1":
version: 5.16.1
resolution: "@mui/utils@npm:5.16.1"
"@mui/utils@npm:^5.16.4":
version: 5.16.4
resolution: "@mui/utils@npm:5.16.4"
dependencies:
"@babel/runtime": "npm:^7.23.9"
"@types/prop-types": "npm:^15.7.12"
clsx: "npm:^2.1.1"
prop-types: "npm:^15.8.1"
react-is: "npm:^18.3.1"
peerDependencies:
@@ -1364,7 +1275,7 @@ __metadata:
peerDependenciesMeta:
"@types/react":
optional: true
checksum: 10c0/9a64bbfcd84474c9d18a79f3e236c4145d43983c3b1810cbcb6cf9d37d36f1bfeeb5a4f9ebf907050364b0a991caba28c481d2e6b2818e4e1c22729eeed24505
checksum: 10c0/f3d6c22a61440b76c3396c437669668e5733db7fcbb82de571a98b9d8259d690b6817081269e961cb20a67a28bedcfa85f234342ee560daf6a981fcce85ab088
languageName: node
linkType: hard
@@ -1503,10 +1414,10 @@ __metadata:
languageName: node
linkType: hard
"@remix-run/router@npm:1.17.1":
version: 1.17.1
resolution: "@remix-run/router@npm:1.17.1"
checksum: 10c0/bee1631feb03975b64e1c7b574da432a05095dda2ff0f164c737e4952841a58d7b9861de87bd13a977fd970c74dcf8c558fc2d26c6ec01a9ae9041b1b4430869
"@remix-run/router@npm:1.18.0":
version: 1.18.0
resolution: "@remix-run/router@npm:1.18.0"
checksum: 10c0/3ec7e441a0e54932a3d3bf932432094420f2c117715d80a5454bc7e55d13b91250749942aab032cd07aee191f1c1de33fede8682025bfd3a453dd207c016e140
languageName: node
linkType: hard
@@ -1867,12 +1778,12 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:^20.14.10":
version: 20.14.10
resolution: "@types/node@npm:20.14.10"
"@types/node@npm:^20.14.11":
version: 20.14.11
resolution: "@types/node@npm:20.14.11"
dependencies:
undici-types: "npm:~5.26.4"
checksum: 10c0/0b06cff14365c2d0085dc16cc8cbea5c40ec09cfc1fea966be9eeecf35562760bfde8f88e86de6edfaf394501236e229d9c1084fad04fb4dec472ae245d8ae69
checksum: 10c0/5306becc0ff41d81b1e31524bd376e958d0741d1ce892dffd586b9ae0cb6553c62b0d62abd16da8bea6b9a2c17572d360450535d7c073794b0cef9cb4e39691e
languageName: node
linkType: hard
@@ -1883,7 +1794,7 @@ __metadata:
languageName: node
linkType: hard
"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.11, @types/prop-types@npm:^15.7.12":
"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.12":
version: 15.7.12
resolution: "@types/prop-types@npm:15.7.12"
checksum: 10c0/1babcc7db6a1177779f8fde0ccc78d64d459906e6ef69a4ed4dd6339c920c2e05b074ee5a92120fe4e9d9f1a01c952f843ebd550bee2332fc2ef81d1706878f8
@@ -2105,15 +2016,15 @@ __metadata:
"@emotion/react": "npm:^11.11.4"
"@emotion/styled": "npm:^11.11.5"
"@eslint/js": "npm:^9.7.0"
"@mui/icons-material": "npm:^5.16.1"
"@mui/material": "npm:^5.16.1"
"@mui/icons-material": "npm:^5.16.4"
"@mui/material": "npm:^5.16.4"
"@preact/compat": "npm:^17.1.2"
"@preact/preset-vite": "npm:^2.9.0"
"@table-library/react-table-library": "npm:4.1.7"
"@trivago/prettier-plugin-sort-imports": "npm:^4.3.0"
"@types/babel__core": "npm:^7"
"@types/lodash-es": "npm:^4.17.12"
"@types/node": "npm:^20.14.10"
"@types/node": "npm:^20.14.11"
"@types/react": "npm:^18.3.3"
"@types/react-dom": "npm:^18.3.0"
"@types/react-router-dom": "npm:^5.3.3"
@@ -2132,14 +2043,14 @@ __metadata:
react-dom: "npm:latest"
react-dropzone: "npm:^14.2.3"
react-icons: "npm:^5.2.1"
react-router-dom: "npm:^6.24.1"
react-router-dom: "npm:^6.25.1"
react-toastify: "npm:^10.0.5"
rollup-plugin-visualizer: "npm:^5.12.0"
terser: "npm:^5.31.2"
terser: "npm:^5.31.3"
typesafe-i18n: "npm:^5.26.2"
typescript: "npm:^5.5.3"
typescript-eslint: "npm:8.0.0-alpha.10"
vite: "npm:^5.3.3"
vite: "npm:^5.3.4"
vite-plugin-imagemin: "npm:^0.6.1"
vite-tsconfig-paths: "npm:^4.3.2"
languageName: unknown
@@ -2694,7 +2605,7 @@ __metadata:
languageName: node
linkType: hard
"clsx@npm:^2.1.0":
"clsx@npm:^2.1.0, clsx@npm:^2.1.1":
version: 2.1.1
resolution: "clsx@npm:2.1.1"
checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839
@@ -6267,34 +6178,34 @@ __metadata:
languageName: node
linkType: hard
"react-is@npm:^18.2.0, react-is@npm:^18.3.1":
"react-is@npm:^18.3.1":
version: 18.3.1
resolution: "react-is@npm:18.3.1"
checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072
languageName: node
linkType: hard
"react-router-dom@npm:^6.24.1":
version: 6.24.1
resolution: "react-router-dom@npm:6.24.1"
"react-router-dom@npm:^6.25.1":
version: 6.25.1
resolution: "react-router-dom@npm:6.25.1"
dependencies:
"@remix-run/router": "npm:1.17.1"
react-router: "npm:6.24.1"
"@remix-run/router": "npm:1.18.0"
react-router: "npm:6.25.1"
peerDependencies:
react: ">=16.8"
react-dom: ">=16.8"
checksum: 10c0/458c6c539304984c47b0ad8d5d5b1f8859cc0845e47591d530cb4fcb13498f70a89b42bc4daeea55d57cfa08408b453bcf601cabb2c987f554cdcac13805caa8
checksum: 10c0/15e2b5bf89a26db9a108d19a4e0e2054180bfb1f5f62662dd93ad697ee1bdc91a8041efd762d552c95e65fc06ca0cb0c1e88acdeeaf03aba37f7a29e470c7cc4
languageName: node
linkType: hard
"react-router@npm:6.24.1":
version: 6.24.1
resolution: "react-router@npm:6.24.1"
"react-router@npm:6.25.1":
version: 6.25.1
resolution: "react-router@npm:6.25.1"
dependencies:
"@remix-run/router": "npm:1.17.1"
"@remix-run/router": "npm:1.18.0"
peerDependencies:
react: ">=16.8"
checksum: 10c0/f50c78ca52c5154ab933c17708125e8bf71ccf2072993a80302526a0a23db9ceac6e36d5c891d62ccd16f13e60cd1b6533a2036523d1b09e0148ac49e34b2e83
checksum: 10c0/a7e824c1f6d9641beabc23111865ddd2525b3794403e07b297fc2bdd4cddec93e166aacdb9d2602768864d70f3bf490f59eeab8474a04ae1f13a832f305eeec3
languageName: node
linkType: hard
@@ -7162,9 +7073,9 @@ __metadata:
languageName: node
linkType: hard
"terser@npm:^5.31.2":
version: 5.31.2
resolution: "terser@npm:5.31.2"
"terser@npm:^5.31.3":
version: 5.31.3
resolution: "terser@npm:5.31.3"
dependencies:
"@jridgewell/source-map": "npm:^0.3.3"
acorn: "npm:^8.8.2"
@@ -7172,7 +7083,7 @@ __metadata:
source-map-support: "npm:~0.5.20"
bin:
terser: bin/terser
checksum: 10c0/5b72f58421f69267f67cb60cf4398282afcdec697e9b6f1909035cdf52d9960226fc1df5968e27ba96736b7a7ba76609d0b7b060ee5da7769553940726059b63
checksum: 10c0/eb2b525dada9febd3db74e94bd295f9cd7abd809e4f9c6bbc795a3048ad50fd327c15eab99db383fa820239680eef6d2dbd7dc05361769c204ddee5cf684d41e
languageName: node
linkType: hard
@@ -7524,9 +7435,9 @@ __metadata:
languageName: node
linkType: hard
"vite@npm:^5.3.3":
version: 5.3.3
resolution: "vite@npm:5.3.3"
"vite@npm:^5.3.4":
version: 5.3.4
resolution: "vite@npm:5.3.4"
dependencies:
esbuild: "npm:^0.21.3"
fsevents: "npm:~2.3.3"
@@ -7560,7 +7471,7 @@ __metadata:
optional: true
bin:
vite: bin/vite.js
checksum: 10c0/a796872e1d11875d994615cd00da185c80eeb7753034d35c096050bf3c269c02004070cf623c5fe2a4a90ea2f12488e6f9d13933ec810f117f1b931e1b5e3385
checksum: 10c0/604a1c8698bcf09d6889533c552f20137c80cb5027e9e7ddf6215d51e3df763414f8712168c22b3c8c16383aff9447094c05f21d7cca3c115874ff9d12e1538e
languageName: node
linkType: hard

View File

@@ -369,6 +369,7 @@ const ESPsystem_status = {
psram_size: 0,
free_psram: 0,
has_loader: true,
// model: ''
model: 'BBQKees Electronics EMS Gateway E32 V2 (E32 V2.0 P3/2024011)'
};

View File

@@ -334,10 +334,10 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
// first see if there is a command registered and it's valid
auto cf = find_command(device_type, device_id, cmd, flag);
if (!cf) {
LOG_WARNING("Command failed: invalid command '%s'", cmd ? cmd : "");
LOG_WARNING("Command failed: unknown command '%s'", cmd ? cmd : "");
// if we don't alread have a message set, set it to invalid command
if (!output["message"]) {
output["message"] = "invalid command";
output["message"] = "unknown command";
}
return CommandRet::ERROR;
}
@@ -360,39 +360,45 @@ uint8_t Command::call(const uint8_t device_type, const char * cmd, const char *
snprintf(info_s, sizeof(info_s), "'%s/%s'", dname, cmd);
}
if (single_command) {
LOG_DEBUG(("%sCalling command %s"), ro.c_str(), info_s);
} else {
if (id > 0) {
LOG_INFO(("%sCalling command %s with value %s and id %d on device 0x%02X"), ro.c_str(), info_s, value, id, device_id);
} else {
LOG_INFO(("%sCalling command %s with value %s"), ro.c_str(), info_s, value);
}
}
// call the function based on type, either with a json package or no parameters
// call the function based on command function type
// commands return true or false only (bool)
uint8_t return_code = CommandRet::OK;
if (cf->cmdfunction_json_) {
// JSON
// handle commands that report back a JSON body
return_code = ((cf->cmdfunction_json_)(value, id, output)) ? CommandRet::OK : CommandRet::ERROR;
} else if (cf->cmdfunction_) {
// Normal command
// if it's a read only command and we're trying to set a value, return an error
if (!single_command && EMSESP::cmd_is_readonly(device_type, device_id, cmd, id)) {
return_code = CommandRet::INVALID; // error on readonly or invalid hc
} else {
// call it...
return_code = ((cf->cmdfunction_)(value, id)) ? CommandRet::OK : CommandRet::ERROR;
}
}
// report back. If not OK show output from error, other return the HTTP code
// report back. If not OK show output from error, otherwise return the HTTP code
if (return_code != CommandRet::OK) {
char error[100];
if (single_command) {
LOG_ERROR("Command '%s' failed with error '%s'", cmd, FL_(cmdRet)[return_code]);
snprintf(error, sizeof(error), "Command '%s' failed (%s)", cmd, FL_(cmdRet)[return_code]);
} else {
LOG_ERROR("Command '%s: %s' failed with error '%s'", cmd, value, FL_(cmdRet)[return_code]);
snprintf(error, sizeof(error), "Command '%s: %s' failed (%s)", cmd, value, FL_(cmdRet)[return_code]);
}
output.clear();
output["message"] = error;
LOG_WARNING(error);
} else {
if (single_command) {
LOG_DEBUG(("%sCalling command %s"), ro.c_str(), info_s);
} else {
if (id > 0) {
LOG_INFO(("%sCalling command %s with value %s and id %d on device 0x%02X"), ro.c_str(), info_s, value, id, device_id);
} else {
LOG_INFO(("%sCalling command %s with value %s"), ro.c_str(), info_s, value);
}
}
return message(return_code, "callback function failed", output);
}
return return_code;
}

View File

@@ -252,7 +252,7 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(const in
// if its a new one, the heating circuit object will be created and also the fetch flags set
std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::shared_ptr<const Telegram> telegram) {
// look through the Monitor and Set arrays to see if there is a match
uint8_t hc_num = 0;
uint8_t hc_num = 0; // 0 means we haven't found it yet
bool toggle_ = false;
// search device-id types for remote thermostats first, they have only a single typeid for all hcs
@@ -271,6 +271,7 @@ std::shared_ptr<Thermostat::HeatingCircuit> Thermostat::heating_circuit(std::sha
}
}
}
// not found, search status message/set types
if (hc_num == 0) {
for (uint8_t i = 0; i < set_typeids.size(); i++) {

View File

@@ -109,6 +109,7 @@ class Thermostat : public EMSdevice {
return hc_num_;
}
// returns heating circuit number 0..9
uint8_t hc() const {
return hc_num_ - 1;
}

View File

@@ -332,7 +332,7 @@ void EMSdevice::fetch_values() {
// toggle on/off automatic fetch for a telegramID
void EMSdevice::toggle_fetch(uint16_t telegram_id, bool toggle) {
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("Toggling fetch for deviceID 0x%02X, telegramID 0x%02X to %d", device_id(), telegram_id, toggle);
EMSESP::logger().debug("Setting fetch to %d for deviceID 0x%02X, telegramID 0x%02X", toggle, device_id(), telegram_id);
#endif
for (auto & tf : telegram_functions_) {

View File

@@ -746,15 +746,22 @@ void EMSESP::publish_response(std::shared_ptr<const Telegram> telegram) {
// for other types like sensors, scheduler, custom entities it will process single commands like 'info', 'values', 'commands'...
bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8_t id, const uint8_t devicetype) {
// check first for EMS devices
bool found_device = false;
for (const auto & emsdevice : emsdevices) {
if (emsdevice->device_type() == devicetype) {
found_device = true;
if (emsdevice->get_value_info(root, cmd, id)) {
return true;
}
}
}
// if the EMS device was valid, but the cmd not found show an error
if (found_device) {
root["message"] = std::string("unknown command ") + cmd;
return false;
}
// check for other devices...
// check for other non EMS devices...
// temperature sensor
if (devicetype == DeviceType::TEMPERATURESENSOR) {
@@ -788,7 +795,7 @@ bool EMSESP::get_device_value_info(JsonObject root, const char * cmd, const int8
bool EMSESP::return_not_found(JsonObject output, const char * msg, const char * cmd) {
output.clear();
char error[100];
snprintf(error, sizeof(error), "cannot find %s in '%s'", msg, cmd);
snprintf(error, sizeof(error), "cannot find %s in %s", msg, cmd);
output["message"] = error;
return false;
}

View File

@@ -59,9 +59,9 @@ MAKE_WORD_TRANSLATION(water_device, "Water Module", "Wassermodul", "", "", "Modu
MAKE_WORD_TRANSLATION(pool_device, "Pool Module", "Poolmodul", "", "", "Moduł basenu", "", "", "", "", "") // TODO translate
// commands
MAKE_WORD_TRANSLATION(info_cmd, "lists all values", "Liste aller Werte", "lijst van alle waardes", "", "wyświetl wszystkie wartości", "Viser alle verdier", "", "Tüm değerleri listele", "elenca tutti i valori", "zobraziť všetky hodnoty") // TODO translate
MAKE_WORD_TRANSLATION(commands_cmd, "lists all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi", "zobraziť všetky príkazy") // TODO translate
MAKE_WORD_TRANSLATION(entities_cmd, "lists all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità", "zobraziť všetky entity") // TODO translate
MAKE_WORD_TRANSLATION(info_cmd, "list all values", "Liste aller Werte", "lijst van alle waardes", "", "wyświetl wszystkie wartości", "Viser alle verdier", "", "Tüm değerleri listele", "elenca tutti i valori", "zobraziť všetky hodnoty") // TODO translate
MAKE_WORD_TRANSLATION(commands_cmd, "list all commands", "Liste aller Kommandos", "lijst van alle commando's", "", "wyświetl wszystkie komendy", "Viser alle kommandoer", "", "Tüm komutları listele", "elencaa tutti i comandi", "zobraziť všetky príkazy") // TODO translate
MAKE_WORD_TRANSLATION(entities_cmd, "list all entities", "Liste aller Entitäten", "lijst van alle entiteiten", "", "wyświetl wszsytkie encje", "Viser alle enheter", "", "Tüm varlıkları listele", "elenca tutte le entità", "zobraziť všetky entity") // TODO translate
MAKE_WORD_TRANSLATION(send_cmd, "send a telegram", "Sende EMS-Telegramm", "stuur een telegram", "", "wyślij telegram", "send et telegram", "", "Bir telegram gönder", "invia un telegramma", "poslať telegram") // TODO translate
MAKE_WORD_TRANSLATION(setiovalue_cmd, "set io value", "Setze Wertevorgabe", "instellen standaardwaarde", "", "ustaw wartość", "sett en io verdi", "", "Giriş/Çıkış değerlerini ayarla", "imposta valore io", "nastaviť hodnotu io") // TODO translate
MAKE_WORD_TRANSLATION(changeloglevel_cmd, "change log level", "Ändere Sysloglevel", "aanpassen log niveau", "", "zmień poziom log-u", "endre loggnivå", "", "Kayıt seviyesini değiştir", "cambia livello registrazione", "") // TODO translate

View File

@@ -579,7 +579,7 @@ void Mqtt::ha_status() {
}
#endif
// TODO camelCase
// These come from the heartbeat MQTT topic
publish_system_ha_sensor_config(DeviceValueType::STRING, "EMS Bus", "bus_status", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::STRING, "Uptime", "uptime", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Uptime (sec)", "uptime_sec", DeviceValueUOM::SECONDS);
@@ -592,6 +592,9 @@ void Mqtt::ha_status() {
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx reads", "txreads", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx writes", "txwrites", DeviceValueUOM::NONE);
publish_system_ha_sensor_config(DeviceValueType::INT8, "Tx fails", "txfails", DeviceValueUOM::NONE);
// This comes from the info MQTT topic
publish_system_ha_sensor_config(DeviceValueType::STRING, "Version", "version", DeviceValueUOM::NONE);
}
// add sub or pub task to the queue.
@@ -980,7 +983,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
readonly_sensors = false;
break;
default:
// plain old sensor, and make read-only
// plain old sensor, and make it read-only
break;
}
}
@@ -1083,12 +1086,18 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
free(F_name); // very important!
doc["name"] = ha_name;
// not needed for commands
if (type != DeviceValueType::CMD) {
// state topic, except for commands
char stat_t[MQTT_TOPIC_MAX_SIZE];
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), tag_to_topic(device_type, tag).c_str());
// This is where we determine which MQTT topic to pull the data from
// There is one exception for DeviceType::SYSTEM, which uses the heartbeat topic, and when fetching the version we want to take this from the info topic instead
if ((device_type == EMSdevice::DeviceType::SYSTEM) && (strncmp(entity, "version", 7) == 0)) {
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), F_(info));
} else {
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), tag_to_topic(device_type, tag).c_str());
}
doc["stat_t"] = stat_t;
// value template

View File

@@ -668,7 +668,6 @@ void System::send_info_mqtt() {
}
// create the json for heartbeat
// TODO camelCase
void System::heartbeat_json(JsonObject output) {
switch (EMSESP::bus_status()) {
case EMSESP::BUS_STATUS_OFFLINE:
@@ -1414,7 +1413,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output
#endif
EMSESP::esp8266React.getNetworkSettingsService()->read([&](NetworkSettings & settings) {
if (WiFi.status() == WL_CONNECTED && !settings.bssid.isEmpty()) {
node["BSSID"] = "set"; // TODO why is this not the actual value?
node["BSSID"] = "set"; // TODO why is this not the actual value??
}
node["TxPower setting"] = settings.tx_power;
node["static ip config"] = settings.staticIPConfig;

View File

@@ -119,8 +119,8 @@ bool Test::test(const std::string & cmd, int8_t id1, int8_t id2) {
// RC300WWmode2(0x31D), data: 00 00 09 07
uart_telegram({0x10, 00, 0xFF, 00, 02, 0x1D, 00, 00, 0x09, 0x07});
// 2nd thermostat
// Thermostat RCPLUSStatusMessage_HC2(0x01A6)
// 2nd thermostat on HC2
// Thermostat RC300Monitor(0x02A6)
uart_telegram({0x98, 0x00, 0xFF, 0x00, 0x01, 0xA6, 0x00, 0xCF, 0x21, 0x2E, 0x00, 0x00, 0x2E, 0x24,
0x03, 0x25, 0x03, 0x03, 0x01, 0x03, 0x25, 0x00, 0xC8, 0x00, 0x00, 0x11, 0x01, 0x03});
@@ -599,8 +599,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
if (command == "2thermostats") {
shell.printfln("Testing multiple thermostats...");
test("2thermostats");
shell.invoke_command("show values");
shell.invoke_command("show devices");
// shell.invoke_command("show values");
// shell.invoke_command("show devices");
ok = true;
}
@@ -963,17 +963,27 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const
// load devices
test("boiler");
// test("thermostat");
test("2thermostats");
if (single) {
// run dedicated tests only
EMSESP::webCustomEntityService.test(); // custom entities
EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
EMSESP::temperaturesensor_.test(); // add temperature sensors
EMSESP::webSchedulerService.test(); // run scheduler tests, and conditions
// EMSESP::webCustomEntityService.test(); // custom entities
// EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS
// EMSESP::temperaturesensor_.test(); // add temperature sensors
// EMSESP::webSchedulerService.test(); // run scheduler tests, and conditions
// request.url("/api/analogsensor/test_analog10/bad");
// request.url("/api/thermostat/commands");
// EMSESP::webAPIService.webAPIService(&request);
request.url("/api/thermostat/hc1/mode2");
EMSESP::webAPIService.webAPIService(&request);
request.url("/api/thermostat/hc2/mode");
EMSESP::webAPIService.webAPIService(&request);
request.url("/api/thermostat/hc1/mode");
EMSESP::webAPIService.webAPIService(&request);
} else {
EMSESP::webCustomEntityService.test(); // custom entities
EMSESP::webCustomizationService.test(); // set customizations - this will overwrite any settings in the FS

View File

@@ -124,15 +124,7 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
// call command
uint8_t return_code = Command::process(request->url().c_str(), is_admin, input, output);
if (return_code != CommandRet::OK) {
char error[100];
if (output.size()) {
snprintf(error, sizeof(error), "API call failed. %s (%s)", (const char *)output["message"], Command::return_code_string(return_code).c_str());
} else {
snprintf(error, sizeof(error), "API call failed (%s)", Command::return_code_string(return_code).c_str());
}
emsesp::EMSESP::logger().err(error);
api_fails_++;
}
@@ -142,10 +134,10 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
if (api_data) {
request->send(200, "text/plain; charset=utf-8", api_data);
#if defined(EMSESP_STANDALONE)
Serial.println();
Serial.printf("%sweb output: %s[%s] %s(200)%s ", COLOR_WHITE, COLOR_BRIGHT_CYAN, request->url().c_str(), COLOR_BRIGHT_GREEN, COLOR_MAGENTA);
serializeJson(output, Serial);
Serial.println(COLOR_RESET);
Serial.println();
#endif
api_count_++;
delete response;
@@ -166,11 +158,11 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
api_count_++;
#if defined(EMSESP_STANDALONE)
Serial.println();
Serial.printf("%sweb output: %s[%s]", COLOR_WHITE, COLOR_BRIGHT_CYAN, request->url().c_str());
Serial.printf(" %s(%d)%s ", ret_codes[return_code] == 200 ? COLOR_BRIGHT_GREEN : COLOR_BRIGHT_RED, ret_codes[return_code], COLOR_YELLOW);
serializeJson(output, Serial);
Serial.println(COLOR_RESET);
Serial.println();
#endif
}

View File

@@ -329,7 +329,7 @@ bool WebSchedulerService::has_commands() {
}
// execute scheduled command
bool WebSchedulerService::command(const char * cmd, const char * data) {
bool WebSchedulerService::command(const char * name, const char * cmd, const char * data) {
JsonDocument doc_input;
JsonObject input = doc_input.to<JsonObject>();
if (strlen(data)) { // empty data queries a value
@@ -347,7 +347,7 @@ bool WebSchedulerService::command(const char * cmd, const char * data) {
if (return_code == CommandRet::OK) {
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("Scheduled command '%s' with data '%s' was successful", cmd, data);
EMSESP::logger().debug("Schedule command '%s' with data '%s' was successful", cmd, data);
#endif
if (strlen(data) == 0 && output.size()) {
Mqtt::queue_publish("response", output);
@@ -357,14 +357,10 @@ bool WebSchedulerService::command(const char * cmd, const char * data) {
char error[100];
if (output.size()) {
snprintf(error,
sizeof(error),
"Scheduled command %s failed with error: %s (%s)",
cmd,
(const char *)output["message"],
Command::return_code_string(return_code).c_str());
// check for empty name
snprintf(error, sizeof(error), "Schedule %s: %s", name ? name : "", (const char *)output["message"]); // use error message if we have it
} else {
snprintf(error, sizeof(error), "Scheduled command %s failed with error %s", cmd, Command::return_code_string(return_code).c_str());
snprintf(error, sizeof(error), "Schedule %s: command %s failed with error %s", name, cmd, Command::return_code_string(return_code).c_str());
}
emsesp::EMSESP::logger().warning(error);
@@ -381,7 +377,7 @@ bool WebSchedulerService::onChange(const char * cmd) {
#ifdef EMESESP_DEBUG
// emsesp::EMSESP::logger().debug(scheduleItem.cmd.c_str());
#endif
cmd_ok |= command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
cmd_ok |= command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
}
}
return cmd_ok;
@@ -396,7 +392,7 @@ void WebSchedulerService::condition() {
#endif
if (!match.empty() && match[0] == '1') {
if (scheduleItem.retry_cnt == 0xFF) { // default unswitched
scheduleItem.retry_cnt = command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 1 : 0xFF;
scheduleItem.retry_cnt = command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 1 : 0xFF;
}
} else if (scheduleItem.retry_cnt == 1) {
scheduleItem.retry_cnt = 0xFF;
@@ -429,7 +425,7 @@ void WebSchedulerService::loop() {
if (last_tm_min == -2) {
for (ScheduleItem & scheduleItem : *scheduleItems_) {
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_TIMER && scheduleItem.elapsed_min == 0) {
scheduleItem.retry_cnt = command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 0xFF : 0;
scheduleItem.retry_cnt = command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str()) ? 0xFF : 0;
}
}
last_tm_min = -1; // startup done, now use for RTC
@@ -442,12 +438,13 @@ void WebSchedulerService::loop() {
// retry startup commands not yet executed
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_TIMER && scheduleItem.elapsed_min == 0
&& scheduleItem.retry_cnt < MAX_STARTUP_RETRIES) {
scheduleItem.retry_cnt = command(scheduleItem.cmd.c_str(), scheduleItem.value.c_str()) ? 0xFF : scheduleItem.retry_cnt + 1;
scheduleItem.retry_cnt =
command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), scheduleItem.value.c_str()) ? 0xFF : scheduleItem.retry_cnt + 1;
}
// scheduled timer commands
if (scheduleItem.active && scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_TIMER && scheduleItem.elapsed_min > 0
&& (uptime_min % scheduleItem.elapsed_min == 0)) {
command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
}
}
last_uptime_min = uptime_min;
@@ -464,7 +461,7 @@ void WebSchedulerService::loop() {
for (const ScheduleItem & scheduleItem : *scheduleItems_) {
uint8_t dow = scheduleItem.flags & SCHEDULEFLAG_SCHEDULE_TIMER ? 0 : scheduleItem.flags;
if (scheduleItem.active && (real_dow & dow) && real_min == scheduleItem.elapsed_min) {
command(scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
command(scheduleItem.name.c_str(), scheduleItem.cmd.c_str(), compute(scheduleItem.value).c_str());
}
}
last_tm_min = tm->tm_min;
@@ -502,41 +499,41 @@ void WebSchedulerService::test() {
// should output 'locale is en'
test_value = "\"locale is \"system/settings/locale";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
// test with negative value
// should output 'rssi is -23'
test_value = "\"rssi is \"0+system/network/rssi";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
// should output 'rssi is -23 dbm'
test_value = "\"rssi is \"(system/network/rssi)\" dBm\"";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
test_value = "(custom/seltemp/value)";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
test_value = "\"seltemp=\"(custom/seltemp/value)";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
test_value = "(custom/seltemp)";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
test_value = "(boiler/outdoortemp)";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
test_value = "boiler/flowtempoffset";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
test_value = "(boiler/flowtempoffset/value)";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
test_value = "(boiler/storagetemp1/value)";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
// (14 - 40) * 2.8 + 5 = -67.8
test_value = "(custom/seltemp - boiler/flowtempoffset) * 2.8 + 5";
command(test_cmd.c_str(), compute(test_value).c_str());
command("test", test_cmd.c_str(), compute(test_value).c_str());
}
#endif

View File

@@ -73,7 +73,7 @@ class WebSchedulerService : public StatefulService<WebScheduler> {
#ifndef EMSESP_STANDALONE
private:
#endif
bool command(const char * cmd, const char * data);
bool command(const char * name, const char * cmd, const char * data);
void condition();
HttpEndpoint<WebScheduler> _httpEndpoint;