mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
@@ -33,6 +33,9 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/).
|
||||
- pumpmode enum for HT3 boilers, add commands for manual defrost, chimneysweeper [#2727](https://github.com/emsesp/EMS-ESP32/issues/2727)
|
||||
- pid settings [#2735](https://github.com/emsesp/EMS-ESP32/issues/2735)
|
||||
- refresh MQTT button added to MQTT Settings page
|
||||
- added LWT (Last Will and Testament) to MQTT entities in Home Assistant
|
||||
- added api/metrics endpoint for prometheus integration by @gr3enk
|
||||
[#2774](https://github.com/emsesp/EMS-ESP32/pull/2774)
|
||||
|
||||
## Fixed
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
"standalone-devcontainer": "concurrently -c \"auto\" \"typesafe-i18n\" \"pnpm:mock-rest\" \"vite --host\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@alova/adapter-xhr": "2.2.1",
|
||||
"@alova/adapter-xhr": "2.3.0",
|
||||
"@emotion/react": "^11.14.0",
|
||||
"@emotion/styled": "^11.14.1",
|
||||
"@mui/icons-material": "^7.3.5",
|
||||
"@mui/material": "^7.3.5",
|
||||
"@preact/compat": "^18.3.1",
|
||||
"@table-library/react-table-library": "4.1.15",
|
||||
"alova": "3.3.4",
|
||||
"alova": "3.4.0",
|
||||
"async-validator": "^4.2.5",
|
||||
"etag": "^1.8.1",
|
||||
"formidable": "^3.5.4",
|
||||
@@ -59,7 +59,7 @@
|
||||
"concurrently": "^9.2.1",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier": "^3.7.3",
|
||||
"rollup-plugin-visualizer": "^6.0.5",
|
||||
"terser": "^5.44.1",
|
||||
"typescript-eslint": "^8.48.0",
|
||||
@@ -67,5 +67,5 @@
|
||||
"vite-plugin-imagemin": "^0.6.1",
|
||||
"vite-tsconfig-paths": "^5.1.4"
|
||||
},
|
||||
"packageManager": "pnpm@10.23.0+sha512.21c4e5698002ade97e4efe8b8b4a89a8de3c85a37919f957e7a0f30f38fbc5bbdd05980ffe29179b2fb6e6e691242e098d945d1601772cad0fef5fb6411e2a4b"
|
||||
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a"
|
||||
}
|
||||
|
||||
70
interface/pnpm-lock.yaml
generated
70
interface/pnpm-lock.yaml
generated
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@alova/adapter-xhr':
|
||||
specifier: 2.2.1
|
||||
version: 2.2.1(alova@3.3.4)
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0(alova@3.4.0)
|
||||
'@emotion/react':
|
||||
specifier: ^11.14.0
|
||||
version: 11.14.0(@types/react@19.2.7)(react@19.2.0)
|
||||
@@ -30,8 +30,8 @@ importers:
|
||||
specifier: 4.1.15
|
||||
version: 4.1.15(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
alova:
|
||||
specifier: 3.3.4
|
||||
version: 3.3.4
|
||||
specifier: 3.4.0
|
||||
version: 3.4.0
|
||||
async-validator:
|
||||
specifier: ^4.2.5
|
||||
version: 4.2.5
|
||||
@@ -86,7 +86,7 @@ importers:
|
||||
version: 2.10.2(@babel/core@7.28.5)(preact@10.27.2)(vite@7.2.4(@types/node@24.10.1)(terser@5.44.1))
|
||||
'@trivago/prettier-plugin-sort-imports':
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0(prettier@3.6.2)
|
||||
version: 6.0.0(prettier@3.7.3)
|
||||
'@types/node':
|
||||
specifier: ^24.10.1
|
||||
version: 24.10.1
|
||||
@@ -109,8 +109,8 @@ importers:
|
||||
specifier: ^10.1.8
|
||||
version: 10.1.8(eslint@9.39.1)
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
specifier: ^3.7.3
|
||||
version: 3.7.3
|
||||
rollup-plugin-visualizer:
|
||||
specifier: ^6.0.5
|
||||
version: 6.0.5(rollup@4.53.3)
|
||||
@@ -132,8 +132,8 @@ importers:
|
||||
|
||||
packages:
|
||||
|
||||
'@alova/adapter-xhr@2.2.1':
|
||||
resolution: {integrity: sha512-0aPVdFmmMn4Z4KvG+DOyWhzQKaBGCe8yPQ4mJz1hQNPzbrIfqq+0flVF6ArFL4EtPbOJVnKropJNE691sjtq5A==}
|
||||
'@alova/adapter-xhr@2.3.0':
|
||||
resolution: {integrity: sha512-IegkchjfXFxXgn6JUZuVEHFQn+jojzrnNdzrGhX5ecEOIC8M/CQvLQzXjLeT6PbGiwnXwvZWL2ya4eqQz51+uQ==}
|
||||
peerDependencies:
|
||||
alova: ^3.0.20
|
||||
|
||||
@@ -475,8 +475,8 @@ packages:
|
||||
resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/eslintrc@3.3.1':
|
||||
resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==}
|
||||
'@eslint/eslintrc@3.3.3':
|
||||
resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
|
||||
'@eslint/js@9.39.1':
|
||||
@@ -960,8 +960,8 @@ packages:
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
alova@3.3.4:
|
||||
resolution: {integrity: sha512-UKKqXdvf8aQ4C7m3brO77YWe5CDz8N59PdAUz7M8gowKUUXTutbk0Vk5DRBrCe0hMUyyNMUhdCZ38llGxCViyQ==}
|
||||
alova@3.4.0:
|
||||
resolution: {integrity: sha512-/vSvVbA45CHg34Y5erx+wVxy1B/n4UoGX7dKqSpLVz9cDSDSOhqCnRD/dV+AErjMmQeVpJrjmDT7SCkhQbnUeQ==}
|
||||
engines: {node: '>= 18.0.0'}
|
||||
|
||||
ansi-regex@2.1.1:
|
||||
@@ -1027,8 +1027,8 @@ packages:
|
||||
base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
||||
baseline-browser-mapping@2.8.31:
|
||||
resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==}
|
||||
baseline-browser-mapping@2.8.32:
|
||||
resolution: {integrity: sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==}
|
||||
hasBin: true
|
||||
|
||||
bin-build@3.0.0:
|
||||
@@ -1185,8 +1185,8 @@ packages:
|
||||
convert-source-map@2.0.0:
|
||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
|
||||
cookie@1.1.0:
|
||||
resolution: {integrity: sha512-vXiThu1/rlos7EGu8TuNZQEg2e9TvhH9dmS4T4ZVzB7Ao1agEZ6EG3sn5n+hZRYUgduISd1HpngFzAZiDGm5vQ==}
|
||||
cookie@1.1.1:
|
||||
resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
core-util-is@1.0.3:
|
||||
@@ -1337,8 +1337,8 @@ packages:
|
||||
duplexer3@0.1.5:
|
||||
resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
|
||||
|
||||
electron-to-chromium@1.5.260:
|
||||
resolution: {integrity: sha512-ov8rBoOBhVawpzdre+Cmz4FB+y66Eqrk6Gwqd8NGxuhv99GQ8XqMAr351KEkOt7gukXWDg6gJWEMKgL2RLMPtA==}
|
||||
electron-to-chromium@1.5.262:
|
||||
resolution: {integrity: sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==}
|
||||
|
||||
emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
@@ -2478,8 +2478,8 @@ packages:
|
||||
resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
prettier@3.6.2:
|
||||
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
||||
prettier@3.7.3:
|
||||
resolution: {integrity: sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
@@ -3098,10 +3098,10 @@ packages:
|
||||
|
||||
snapshots:
|
||||
|
||||
'@alova/adapter-xhr@2.2.1(alova@3.3.4)':
|
||||
'@alova/adapter-xhr@2.3.0(alova@3.4.0)':
|
||||
dependencies:
|
||||
'@alova/shared': 1.3.1
|
||||
alova: 3.3.4
|
||||
alova: 3.4.0
|
||||
|
||||
'@alova/shared@1.3.1': {}
|
||||
|
||||
@@ -3423,7 +3423,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
|
||||
'@eslint/eslintrc@3.3.1':
|
||||
'@eslint/eslintrc@3.3.3':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.4.3
|
||||
@@ -3716,7 +3716,7 @@ snapshots:
|
||||
react-virtualized-auto-sizer: 1.0.26(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
react-window: 1.8.11(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||
|
||||
'@trivago/prettier-plugin-sort-imports@6.0.0(prettier@3.6.2)':
|
||||
'@trivago/prettier-plugin-sort-imports@6.0.0(prettier@3.7.3)':
|
||||
dependencies:
|
||||
'@babel/generator': 7.28.5
|
||||
'@babel/parser': 7.28.5
|
||||
@@ -3726,7 +3726,7 @@ snapshots:
|
||||
lodash-es: 4.17.21
|
||||
minimatch: 9.0.5
|
||||
parse-imports-exports: 0.2.4
|
||||
prettier: 3.6.2
|
||||
prettier: 3.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -3911,7 +3911,7 @@ snapshots:
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
|
||||
alova@3.3.4:
|
||||
alova@3.4.0:
|
||||
dependencies:
|
||||
'@alova/shared': 1.3.1
|
||||
rate-limiter-flexible: 5.0.5
|
||||
@@ -3962,7 +3962,7 @@ snapshots:
|
||||
|
||||
base64-js@1.5.1: {}
|
||||
|
||||
baseline-browser-mapping@2.8.31: {}
|
||||
baseline-browser-mapping@2.8.32: {}
|
||||
|
||||
bin-build@3.0.0:
|
||||
dependencies:
|
||||
@@ -4019,9 +4019,9 @@ snapshots:
|
||||
|
||||
browserslist@4.28.0:
|
||||
dependencies:
|
||||
baseline-browser-mapping: 2.8.31
|
||||
baseline-browser-mapping: 2.8.32
|
||||
caniuse-lite: 1.0.30001757
|
||||
electron-to-chromium: 1.5.260
|
||||
electron-to-chromium: 1.5.262
|
||||
node-releases: 2.0.27
|
||||
update-browserslist-db: 1.1.4(browserslist@4.28.0)
|
||||
|
||||
@@ -4151,7 +4151,7 @@ snapshots:
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
|
||||
cookie@1.1.0: {}
|
||||
cookie@1.1.1: {}
|
||||
|
||||
core-util-is@1.0.3: {}
|
||||
|
||||
@@ -4366,7 +4366,7 @@ snapshots:
|
||||
|
||||
duplexer3@0.1.5: {}
|
||||
|
||||
electron-to-chromium@1.5.260: {}
|
||||
electron-to-chromium@1.5.262: {}
|
||||
|
||||
emoji-regex@8.0.0: {}
|
||||
|
||||
@@ -4529,7 +4529,7 @@ snapshots:
|
||||
'@eslint/config-array': 0.21.1
|
||||
'@eslint/config-helpers': 0.4.2
|
||||
'@eslint/core': 0.17.0
|
||||
'@eslint/eslintrc': 3.3.1
|
||||
'@eslint/eslintrc': 3.3.3
|
||||
'@eslint/js': 9.39.1
|
||||
'@eslint/plugin-kit': 0.4.1
|
||||
'@humanfs/node': 0.16.7
|
||||
@@ -5487,7 +5487,7 @@ snapshots:
|
||||
|
||||
prepend-http@2.0.0: {}
|
||||
|
||||
prettier@3.6.2: {}
|
||||
prettier@3.7.3: {}
|
||||
|
||||
process-nextick-args@2.0.1: {}
|
||||
|
||||
@@ -5533,7 +5533,7 @@ snapshots:
|
||||
|
||||
react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
|
||||
dependencies:
|
||||
cookie: 1.1.0
|
||||
cookie: 1.1.1
|
||||
react: 19.2.0
|
||||
set-cookie-parser: 2.7.2
|
||||
optionalDependencies:
|
||||
|
||||
@@ -266,6 +266,7 @@ const MqttSettings = () => {
|
||||
label={LL.CERT()}
|
||||
variant="outlined"
|
||||
value={data.rootCA}
|
||||
sx={{ width: '50ch' }}
|
||||
onChange={updateFormValue}
|
||||
margin="normal"
|
||||
/>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"@trivago/prettier-plugin-sort-imports": "^6.0.0",
|
||||
"formidable": "^3.5.4",
|
||||
"itty-router": "^5.0.22",
|
||||
"prettier": "^3.6.2"
|
||||
"prettier": "^3.7.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.23.0+sha512.21c4e5698002ade97e4efe8b8b4a89a8de3c85a37919f957e7a0f30f38fbc5bbdd05980ffe29179b2fb6e6e691242e098d945d1601772cad0fef5fb6411e2a4b"
|
||||
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a"
|
||||
}
|
||||
|
||||
16
mock-api/pnpm-lock.yaml
generated
16
mock-api/pnpm-lock.yaml
generated
@@ -13,7 +13,7 @@ importers:
|
||||
version: 3.1.2
|
||||
'@trivago/prettier-plugin-sort-imports':
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0(prettier@3.6.2)
|
||||
version: 6.0.0(prettier@3.7.3)
|
||||
formidable:
|
||||
specifier: ^3.5.4
|
||||
version: 3.5.4
|
||||
@@ -21,8 +21,8 @@ importers:
|
||||
specifier: ^5.0.22
|
||||
version: 5.0.22
|
||||
prettier:
|
||||
specifier: ^3.6.2
|
||||
version: 3.6.2
|
||||
specifier: ^3.7.3
|
||||
version: 3.7.3
|
||||
|
||||
packages:
|
||||
|
||||
@@ -167,8 +167,8 @@ packages:
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
prettier@3.6.2:
|
||||
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
||||
prettier@3.7.3:
|
||||
resolution: {integrity: sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
|
||||
@@ -246,7 +246,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@noble/hashes': 1.8.0
|
||||
|
||||
'@trivago/prettier-plugin-sort-imports@6.0.0(prettier@3.6.2)':
|
||||
'@trivago/prettier-plugin-sort-imports@6.0.0(prettier@3.7.3)':
|
||||
dependencies:
|
||||
'@babel/generator': 7.28.5
|
||||
'@babel/parser': 7.28.5
|
||||
@@ -256,7 +256,7 @@ snapshots:
|
||||
lodash-es: 4.17.21
|
||||
minimatch: 9.0.5
|
||||
parse-imports-exports: 0.2.4
|
||||
prettier: 3.6.2
|
||||
prettier: 3.7.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -311,6 +311,6 @@ snapshots:
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
prettier@3.6.2: {}
|
||||
prettier@3.7.3: {}
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
@@ -569,14 +569,15 @@ let mqtt_settings = {
|
||||
publish_time_heartbeat: 60,
|
||||
publish_time_water: 60,
|
||||
mqtt_qos: 0,
|
||||
rootCA: '',
|
||||
mqtt_retain: false,
|
||||
ha_enabled: true,
|
||||
nested_format: 1,
|
||||
discovery_type: 0,
|
||||
discovery_prefix: 'homeassistant',
|
||||
send_response: true,
|
||||
publish_single: false
|
||||
publish_single: false,
|
||||
enableTLS: true,
|
||||
rootCA: ''
|
||||
};
|
||||
const mqtt_status = {
|
||||
enabled: true,
|
||||
|
||||
@@ -106,7 +106,7 @@ board_build.filesystem = littlefs
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson @ 7.4.2
|
||||
ESP32Async/AsyncTCP @ 3.4.9
|
||||
ESP32Async/ESPAsyncWebServer @ 3.9.0
|
||||
ESP32Async/ESPAsyncWebServer @ 3.9.2
|
||||
https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8
|
||||
|
||||
|
||||
@@ -214,23 +214,20 @@ lib_ldf_mode = off
|
||||
lib_deps =
|
||||
|
||||
; unit tests
|
||||
; The code is in ./test/test_api.*
|
||||
; The test code is in ./test/test_api.cpp and the test_api.h file is created by the native-test-create environment.
|
||||
; to run use `platformio run -e native-test -t exec`. All tests should PASS.
|
||||
; to update the test results, compile with -DEMSESP_UNITY_CREATE by uncommenting the line below
|
||||
; then re-run and capture the output between "START - CUT HERE" and "END - CUT HERE" into the test_api.h file
|
||||
; tip: use https://jsondiff.com/ to compare the expected and actual responses.
|
||||
[env:native-test]
|
||||
platform = native
|
||||
test_build_src = true
|
||||
build_flags =
|
||||
; -DEMSESP_UNITY_CREATE
|
||||
-DARDUINOJSON_ENABLE_ARDUINO_STRING=1
|
||||
-DEMSESP_STANDALONE -DEMSESP_TEST
|
||||
-DEMSESP_UNITY
|
||||
-DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.3-dev.0\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
||||
-std=gnu++17 -Og -ggdb
|
||||
build_type = debug
|
||||
build_src_flags =
|
||||
-DEMSESP_STANDALONE -DEMSESP_TEST
|
||||
-DEMSESP_UNITY
|
||||
-DARDUINOJSON_ENABLE_ARDUINO_STRING=1
|
||||
-DEMSESP_DEFAULT_LOCALE=\"en\" -DEMSESP_DEFAULT_TX_MODE=8 -DEMSESP_DEFAULT_VERSION=\"3.7.3-dev.0\" -DEMSESP_DEFAULT_BOARD_PROFILE=\"S32\"
|
||||
-std=gnu++17 -Og -ggdb
|
||||
-Wall -Wextra
|
||||
-Wno-unused-parameter -Wno-sign-compare -Wno-missing-braces
|
||||
-Wno-vla-cxx-extension -Wno-tautological-constant-out-of-range-compare
|
||||
@@ -260,6 +257,12 @@ lib_deps = Unity
|
||||
test_testing_command =
|
||||
${platformio.build_dir}/${this.__env__}/program
|
||||
|
||||
; builds the test cases and creates the test_api.h file
|
||||
; run with `pio run -e native-test-create -t exec` and capture the output between "START - CUT HERE" and "END - CUT HERE" and paste it into the test_api.h file
|
||||
[env:native-test-create]
|
||||
extends = env:native-test
|
||||
build_flags =
|
||||
-DEMSESP_UNITY_CREATE
|
||||
;
|
||||
; Building and testing locally on OS, which we call "standalone" without an ESP32.
|
||||
; See https://docs.platformio.org/en/latest/platforms/native.html
|
||||
|
||||
@@ -173,7 +173,7 @@ bool MqttSettingsService::configureMqtt() {
|
||||
|
||||
// only connect if WiFi is connected and MQTT is enabled
|
||||
if (_state.enabled && emsesp::EMSESP::system_.network_connected() && !_state.host.isEmpty()) {
|
||||
// create last will topic with the base prefixed. It has to be static because the client destroys the reference
|
||||
// create the Last Will Testament topic (LWT) with the base prefixed. It has to be static because the client destroys the reference
|
||||
static char will_topic[FACTORY_MQTT_MAX_TOPIC_LENGTH];
|
||||
if (_state.base.isEmpty()) {
|
||||
snprintf(will_topic, sizeof(will_topic), "status");
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef FACTORY_MQTT_KEEP_ALIVE
|
||||
#define FACTORY_MQTT_KEEP_ALIVE 16
|
||||
#define FACTORY_MQTT_KEEP_ALIVE 60
|
||||
#endif
|
||||
|
||||
#ifndef FACTORY_MQTT_CLEAN_SESSION
|
||||
|
||||
@@ -87,8 +87,8 @@ static void setup_commands(std::shared_ptr<Commands> const & commands) {
|
||||
Command::show_all(shell);
|
||||
} else if (command == F_(system)) {
|
||||
EMSESP::system_.show_system(shell);
|
||||
} else if (command == F_(users) && (shell.has_flags(CommandFlags::ADMIN))) {
|
||||
EMSESP::system_.show_users(shell); // admin only
|
||||
} else if (command == F_(users)) {
|
||||
EMSESP::system_.show_users(shell);
|
||||
} else if (command == F_(devices)) {
|
||||
EMSESP::show_devices(shell);
|
||||
} else if (command == F_(log)) {
|
||||
|
||||
@@ -1715,9 +1715,8 @@ std::string EMSdevice::get_metrics_prometheus(const int8_t tag) {
|
||||
}
|
||||
|
||||
// only process number and boolean types for now
|
||||
if (dv.type != DeviceValueType::BOOL && dv.type != DeviceValueType::UINT8 && dv.type != DeviceValueType::INT8
|
||||
&& dv.type != DeviceValueType::UINT16 && dv.type != DeviceValueType::INT16 && dv.type != DeviceValueType::UINT24
|
||||
&& dv.type != DeviceValueType::UINT32 && dv.type != DeviceValueType::TIME) {
|
||||
if (dv.type != DeviceValueType::BOOL && dv.type != DeviceValueType::UINT8 && dv.type != DeviceValueType::INT8 && dv.type != DeviceValueType::UINT16
|
||||
&& dv.type != DeviceValueType::INT16 && dv.type != DeviceValueType::UINT24 && dv.type != DeviceValueType::UINT32 && dv.type != DeviceValueType::TIME) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -509,14 +509,14 @@ void Mqtt::on_connect() {
|
||||
queue_subscribe_message(discovery_prefix_ + "/+/" + Mqtt::basename() + "/#");
|
||||
}
|
||||
|
||||
// send initial MQTT messages for some of our services
|
||||
EMSESP::system_.send_heartbeat(); // send heartbeat
|
||||
|
||||
// re-subscribe to all custom registered MQTT topics
|
||||
resubscribe();
|
||||
|
||||
// publish to the last will topic (see Mqtt::start() function) to say we're alive
|
||||
queue_publish_retain("status", "online"); // retain: https://github.com/emsesp/EMS-ESP32/discussions/2086
|
||||
|
||||
// send initial MQTT messages for some of our services
|
||||
EMSESP::system_.send_heartbeat(); // send heartbeat
|
||||
}
|
||||
|
||||
// Home Assistant Discovery - the main master Device called EMS-ESP
|
||||
@@ -532,9 +532,10 @@ void Mqtt::ha_status() {
|
||||
strcpy(uniq, "system_status");
|
||||
}
|
||||
|
||||
doc["~"] = Mqtt::base();
|
||||
doc["uniq_id"] = uniq;
|
||||
doc["def_ent_id"] = (std::string) "binary_sensor." + uniq;
|
||||
doc["stat_t"] = Mqtt::base() + "/status";
|
||||
doc["stat_t"] = "~/status";
|
||||
doc["name"] = "System status";
|
||||
doc["pl_on"] = "online";
|
||||
doc["pl_off"] = "offline";
|
||||
@@ -981,8 +982,9 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
return queue_remove_topic(topic);
|
||||
}
|
||||
|
||||
// build the full payload
|
||||
// build the full topic's payload
|
||||
JsonDocument doc;
|
||||
doc["~"] = Mqtt::base();
|
||||
doc["uniq_id"] = uniq_id;
|
||||
|
||||
// set the entity_id. This is breaking change in HA 2025.10.0 - see https://github.com/home-assistant/core/pull/151775
|
||||
@@ -1000,9 +1002,9 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
char command_topic[MQTT_TOPIC_MAX_SIZE];
|
||||
// add command topic
|
||||
if (tag >= DeviceValueTAG::TAG_HC1) {
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s/%s", Mqtt::base().c_str(), device_name, EMSdevice::tag_to_mqtt(tag), entity);
|
||||
snprintf(command_topic, sizeof(command_topic), "~/%s/%s/%s", device_name, EMSdevice::tag_to_mqtt(tag), entity);
|
||||
} else {
|
||||
snprintf(command_topic, sizeof(command_topic), "%s/%s/%s", Mqtt::base().c_str(), device_name, entity);
|
||||
snprintf(command_topic, sizeof(command_topic), "~/%s/%s", device_name, entity);
|
||||
}
|
||||
doc["cmd_t"] = command_topic;
|
||||
|
||||
@@ -1063,9 +1065,9 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev
|
||||
// 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));
|
||||
snprintf(stat_t, sizeof(stat_t), "~/%s", F_(info));
|
||||
} else {
|
||||
snprintf(stat_t, sizeof(stat_t), "%s/%s", Mqtt::base().c_str(), tag_to_topic(device_type, tag).c_str());
|
||||
snprintf(stat_t, sizeof(stat_t), "~/%s", tag_to_topic(device_type, tag).c_str());
|
||||
}
|
||||
doc["stat_t"] = stat_t;
|
||||
|
||||
@@ -1484,6 +1486,11 @@ void Mqtt::add_ha_avail_section(JsonObject doc, const char * state_t, const bool
|
||||
avty.add(avty_json); // returns 0 if no mem
|
||||
}
|
||||
|
||||
// add LWT (Last Will and Testament)
|
||||
avty_json.clear();
|
||||
avty_json["t"] = "~/status"; // as a topic
|
||||
avty.add(avty_json);
|
||||
|
||||
doc["avty_mode"] = "all";
|
||||
}
|
||||
|
||||
|
||||
@@ -731,11 +731,6 @@ void System::heartbeat_json(JsonObject output) {
|
||||
|
||||
// send periodic MQTT message with system information
|
||||
void System::send_heartbeat() {
|
||||
// don't send heartbeat if WiFi or MQTT is not connected
|
||||
if (!Mqtt::connected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
refreshHeapMem(); // refresh free heap and max alloc heap
|
||||
|
||||
JsonDocument doc;
|
||||
@@ -997,6 +992,11 @@ int8_t System::wifi_quality(int8_t dBm) {
|
||||
|
||||
// print users to console
|
||||
void System::show_users(uuid::console::Shell & shell) {
|
||||
if (!shell.has_flags(CommandFlags::ADMIN)) {
|
||||
shell.printfln("Unauthorized. You need to be an admin to view users.");
|
||||
return;
|
||||
}
|
||||
|
||||
shell.printfln("Users:");
|
||||
|
||||
#ifndef EMSESP_STANDALONE
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define EMSESP_APP_VERSION "3.7.3-dev.32"
|
||||
#define EMSESP_APP_VERSION "3.7.3-dev.33"
|
||||
|
||||
@@ -144,6 +144,8 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
|
||||
return;
|
||||
}
|
||||
|
||||
api_count_++;
|
||||
|
||||
// send the json that came back from the command call
|
||||
// sequence matches CommandRet in command.h (FAIL, OK, NOT_FOUND, ERROR, NOT_ALLOWED, INVALID, NO_VALUE)
|
||||
// 400 (bad request)
|
||||
@@ -153,16 +155,23 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
|
||||
// 400 (invalid)
|
||||
int ret_codes[7] = {400, 200, 404, 400, 401, 400, 404};
|
||||
|
||||
response->setCode(ret_codes[return_code]);
|
||||
response->setLength();
|
||||
response->setContentType("application/json; charset=utf-8");
|
||||
request->send(response);
|
||||
|
||||
// serialize JSON to string to ensure correct content-length and avoid HTTP parsing errors (issue #2752)
|
||||
std::string output_str;
|
||||
serializeJson(output, output_str);
|
||||
request->send(ret_codes[return_code], "application/json; charset=utf-8", output_str.c_str());
|
||||
// std::string output_str;
|
||||
// serializeJson(output, output_str);
|
||||
// request->send(ret_codes[return_code], "application/json; charset=utf-8", output_str.c_str());
|
||||
|
||||
#if defined(EMSESP_UNITY)
|
||||
// store the result so we can test with Unity later
|
||||
storeResponse(output);
|
||||
#endif
|
||||
#if defined(EMSESP_STANDALONE) && !defined(EMSESP_UNITY)
|
||||
std::string output_str;
|
||||
serializeJson(output, output_str);
|
||||
Serial.printf("%sweb output: %s[%s] %s(%d)%s %s%s",
|
||||
COLOR_WHITE,
|
||||
COLOR_BRIGHT_CYAN,
|
||||
@@ -175,9 +184,6 @@ void WebAPIService::parse(AsyncWebServerRequest * request, JsonObject input) {
|
||||
Serial.println();
|
||||
EMSESP::logger().debug("web output: %s %s", request->url().c_str(), output_str.c_str());
|
||||
#endif
|
||||
|
||||
api_count_++;
|
||||
delete response;
|
||||
}
|
||||
|
||||
#if defined(EMSESP_UNITY)
|
||||
|
||||
@@ -422,7 +422,7 @@ void WebSettings::set_board_profile(WebSettings & settings) {
|
||||
|
||||
// load the board profile into the data vector
|
||||
// 0=led, 1=dallas, 2=rx, 3=tx, 4=button, 5=phy_type, 6=eth_power, 7=eth_phy_addr, 8=eth_clock_mode, 9=led_type
|
||||
std::vector<int8_t> data(99, 0); // initialize with 99 for all values, just as a safe guard to catch bad gpios
|
||||
std::vector<int8_t> data(10, 99); // initialize with 99 for all values, just as a safe guard to catch bad gpios
|
||||
if (settings.board_profile != "default") {
|
||||
if (!System::load_board_profile(data, settings.board_profile.c_str())) {
|
||||
#if defined(EMSESP_DEBUG)
|
||||
|
||||
@@ -29,7 +29,7 @@ async function testAPI(ip = "ems-esp.local", apiPath = "system") {
|
||||
}
|
||||
|
||||
// Run the test
|
||||
testAPI("192.168.1.223", "system")
|
||||
testAPI("192.168.1.65", "system")
|
||||
.then(() => {
|
||||
console.log('Test completed successfully');
|
||||
process.exit(0);
|
||||
|
||||
@@ -299,9 +299,8 @@ void manual_test8() {
|
||||
TEST_ASSERT_TRUE(strstr(response, "emsesp_") != nullptr);
|
||||
TEST_ASSERT_TRUE(strstr(response, " gauge") != nullptr);
|
||||
|
||||
TEST_ASSERT_TRUE(strstr(response, "emsesp_tapwateractive") != nullptr ||
|
||||
strstr(response, "emsesp_selflowtemp") != nullptr ||
|
||||
strstr(response, "emsesp_curflowtemp") != nullptr);
|
||||
TEST_ASSERT_TRUE(strstr(response, "emsesp_tapwateractive") != nullptr || strstr(response, "emsesp_selflowtemp") != nullptr
|
||||
|| strstr(response, "emsesp_curflowtemp") != nullptr);
|
||||
}
|
||||
|
||||
void manual_test9() {
|
||||
|
||||
Reference in New Issue
Block a user