20 Commits

Author SHA1 Message Date
Proddy
2821f8e750 Merge pull request #2824 from MichaelDvP/dev
some more fixes
2025-12-18 11:23:37 +01:00
MichaelDvP
1cccd8dc2c Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-12-18 09:18:03 +01:00
Proddy
4d13982594 Merge pull request #2823 from proddy/dev
fix HA sensors not been added to HA device
2025-12-18 08:43:57 +01:00
MichaelDvP
10c63640c0 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2025-12-18 07:20:50 +01:00
proddy
14ad1239db don't need to add name to ids each time for HA 2025-12-18 06:45:48 +01:00
proddy
2a16cb6e64 3.7.3-dev.38 2025-12-18 06:45:25 +01:00
proddy
89fa5947bd fix standalone 2025-12-17 22:10:17 +01:00
proddy
a81e56e3bf package update 2025-12-17 22:10:05 +01:00
proddy
90ad2dde54 minor optimization 2025-12-17 22:09:55 +01:00
proddy
9c243cbe8d sort types 2025-12-17 22:09:32 +01:00
proddy
c1b444541f fix HA 2025-12-17 22:09:17 +01:00
MichaelDvP
8527b16e9d dev 38 2025-12-17 18:14:09 +01:00
MichaelDvP
a728420010 small fix 2025-12-17 18:13:35 +01:00
MichaelDvP
378d9e8634 Merge branch 'dev' of https://github.com/proddy/EMS-ESP32 into dev 2025-12-17 18:11:53 +01:00
MichaelDvP
1973081529 ha_dev_section for custom and scheduler 2025-12-17 18:11:43 +01:00
MichaelDvP
45ae6d802c use (const char *) for PSRAM-stored sensor.name in ArduinoJson 2025-12-17 16:42:38 +01:00
MichaelDvP
c4297e2996 Merge branch 'dev' of https://github.com/emsesp/EMS-ESP32 into dev 2025-12-17 12:34:54 +01:00
proddy
310afe3ab8 fix HA sensor referencing 2025-12-17 11:37:46 +01:00
MichaelDvP
3215f36530 fix typo in analogsensor:remove_ha_topic 2025-12-17 11:36:50 +01:00
proddy
55621e12d9 package update - fixes vite-tsconfig-paths 2025-12-17 11:26:57 +01:00
12 changed files with 166 additions and 171 deletions

View File

@@ -41,7 +41,7 @@
"react": "^19.2.3", "react": "^19.2.3",
"react-dom": "^19.2.3", "react-dom": "^19.2.3",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-router": "^7.10.1", "react-router": "^7.11.0",
"react-toastify": "^11.0.5", "react-toastify": "^11.0.5",
"typesafe-i18n": "^5.26.2", "typesafe-i18n": "^5.26.2",
"typescript": "^5.9.3" "typescript": "^5.9.3"
@@ -65,7 +65,7 @@
"typescript-eslint": "^8.50.0", "typescript-eslint": "^8.50.0",
"vite": "^7.3.0", "vite": "^7.3.0",
"vite-plugin-imagemin": "^0.6.1", "vite-plugin-imagemin": "^0.6.1",
"vite-tsconfig-paths": "^6.0.1" "vite-tsconfig-paths": "^6.0.2"
}, },
"packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402" "packageManager": "pnpm@10.26.0+sha512.3b3f6c725ebe712506c0ab1ad4133cf86b1f4b687effce62a9b38b4d72e3954242e643190fc51fa1642949c735f403debd44f5cb0edd657abe63a8b6a7e1e402"
} }

244
interface/pnpm-lock.yaml generated
View File

@@ -63,8 +63,8 @@ importers:
specifier: ^5.5.0 specifier: ^5.5.0
version: 5.5.0(react@19.2.3) version: 5.5.0(react@19.2.3)
react-router: react-router:
specifier: ^7.10.1 specifier: ^7.11.0
version: 7.10.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3) version: 7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
react-toastify: react-toastify:
specifier: ^11.0.5 specifier: ^11.0.5
version: 11.0.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3) version: 11.0.5(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -127,8 +127,8 @@ importers:
specifier: ^0.6.1 specifier: ^0.6.1
version: 0.6.1(vite@7.3.0(@types/node@25.0.3)(terser@5.44.1)) version: 0.6.1(vite@7.3.0(@types/node@25.0.3)(terser@5.44.1))
vite-tsconfig-paths: vite-tsconfig-paths:
specifier: ^6.0.1 specifier: ^6.0.2
version: 6.0.1(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(terser@5.44.1)) version: 6.0.2(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(terser@5.44.1))
packages: packages:
@@ -291,68 +291,68 @@ packages:
'@emotion/weak-memoize@0.4.0': '@emotion/weak-memoize@0.4.0':
resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==}
'@esbuild/aix-ppc64@0.27.1': '@esbuild/aix-ppc64@0.27.2':
resolution: {integrity: sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==} resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [aix] os: [aix]
'@esbuild/android-arm64@0.27.1': '@esbuild/android-arm64@0.27.2':
resolution: {integrity: sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==} resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [android] os: [android]
'@esbuild/android-arm@0.27.1': '@esbuild/android-arm@0.27.2':
resolution: {integrity: sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==} resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [android] os: [android]
'@esbuild/android-x64@0.27.1': '@esbuild/android-x64@0.27.2':
resolution: {integrity: sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==} resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [android] os: [android]
'@esbuild/darwin-arm64@0.27.1': '@esbuild/darwin-arm64@0.27.2':
resolution: {integrity: sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==} resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@esbuild/darwin-x64@0.27.1': '@esbuild/darwin-x64@0.27.2':
resolution: {integrity: sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==} resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@esbuild/freebsd-arm64@0.27.1': '@esbuild/freebsd-arm64@0.27.2':
resolution: {integrity: sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==} resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [freebsd] os: [freebsd]
'@esbuild/freebsd-x64@0.27.1': '@esbuild/freebsd-x64@0.27.2':
resolution: {integrity: sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==} resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [freebsd] os: [freebsd]
'@esbuild/linux-arm64@0.27.1': '@esbuild/linux-arm64@0.27.2':
resolution: {integrity: sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==} resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@esbuild/linux-arm@0.27.1': '@esbuild/linux-arm@0.27.2':
resolution: {integrity: sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==} resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@esbuild/linux-ia32@0.27.1': '@esbuild/linux-ia32@0.27.2':
resolution: {integrity: sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==} resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [linux] os: [linux]
@@ -363,92 +363,92 @@ packages:
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
'@esbuild/linux-loong64@0.27.1': '@esbuild/linux-loong64@0.27.2':
resolution: {integrity: sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==} resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [loong64] cpu: [loong64]
os: [linux] os: [linux]
'@esbuild/linux-mips64el@0.27.1': '@esbuild/linux-mips64el@0.27.2':
resolution: {integrity: sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==} resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [mips64el] cpu: [mips64el]
os: [linux] os: [linux]
'@esbuild/linux-ppc64@0.27.1': '@esbuild/linux-ppc64@0.27.2':
resolution: {integrity: sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==} resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ppc64] cpu: [ppc64]
os: [linux] os: [linux]
'@esbuild/linux-riscv64@0.27.1': '@esbuild/linux-riscv64@0.27.2':
resolution: {integrity: sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==} resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [riscv64] cpu: [riscv64]
os: [linux] os: [linux]
'@esbuild/linux-s390x@0.27.1': '@esbuild/linux-s390x@0.27.2':
resolution: {integrity: sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==} resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [s390x] cpu: [s390x]
os: [linux] os: [linux]
'@esbuild/linux-x64@0.27.1': '@esbuild/linux-x64@0.27.2':
resolution: {integrity: sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==} resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@esbuild/netbsd-arm64@0.27.1': '@esbuild/netbsd-arm64@0.27.2':
resolution: {integrity: sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==} resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [netbsd] os: [netbsd]
'@esbuild/netbsd-x64@0.27.1': '@esbuild/netbsd-x64@0.27.2':
resolution: {integrity: sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==} resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [netbsd] os: [netbsd]
'@esbuild/openbsd-arm64@0.27.1': '@esbuild/openbsd-arm64@0.27.2':
resolution: {integrity: sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==} resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openbsd] os: [openbsd]
'@esbuild/openbsd-x64@0.27.1': '@esbuild/openbsd-x64@0.27.2':
resolution: {integrity: sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==} resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [openbsd] os: [openbsd]
'@esbuild/openharmony-arm64@0.27.1': '@esbuild/openharmony-arm64@0.27.2':
resolution: {integrity: sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==} resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [openharmony] os: [openharmony]
'@esbuild/sunos-x64@0.27.1': '@esbuild/sunos-x64@0.27.2':
resolution: {integrity: sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==} resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [sunos] os: [sunos]
'@esbuild/win32-arm64@0.27.1': '@esbuild/win32-arm64@0.27.2':
resolution: {integrity: sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==} resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@esbuild/win32-ia32@0.27.1': '@esbuild/win32-ia32@0.27.2':
resolution: {integrity: sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==} resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@esbuild/win32-x64@0.27.1': '@esbuild/win32-x64@0.27.2':
resolution: {integrity: sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==} resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
@@ -1027,8 +1027,8 @@ packages:
base64-js@1.5.1: base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
baseline-browser-mapping@2.9.8: baseline-browser-mapping@2.9.9:
resolution: {integrity: sha512-Y1fOuNDowLfgKOypdc9SPABfoWXuZHBOyCS4cD52IeZBhr4Md6CLLs6atcxVrzRmQ06E7hSlm5bHHApPKR/byA==} resolution: {integrity: sha512-V8fbOCSeOFvlDj7LLChUcqbZrdKD9RU/VR260piF1790vT0mfLSwGc/Qzxv3IqiTukOpNtItePa0HBpMAj7MDg==}
hasBin: true hasBin: true
bin-build@3.0.0: bin-build@3.0.0:
@@ -1493,8 +1493,8 @@ packages:
engines: {node: '>=12'} engines: {node: '>=12'}
hasBin: true hasBin: true
esbuild@0.27.1: esbuild@0.27.2:
resolution: {integrity: sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==} resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
@@ -2525,8 +2525,8 @@ packages:
react-is@19.2.3: react-is@19.2.3:
resolution: {integrity: sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==} resolution: {integrity: sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==}
react-router@7.10.1: react-router@7.11.0:
resolution: {integrity: sha512-gHL89dRa3kwlUYtRQ+m8NmxGI6CgqN+k4XyGjwcFoQwwCWF6xXpOCUlDovkXClS0d0XJN/5q7kc5W3kiFEd0Yw==} resolution: {integrity: sha512-uI4JkMmjbWCZc01WVP2cH7ZfSzH91JAZUDd7/nIprDgWxBV1TkkmLToFh7EbMTcMak8URFRa2YoBL/W8GWnCTQ==}
engines: {node: '>=20.0.0'} engines: {node: '>=20.0.0'}
peerDependencies: peerDependencies:
react: '>=18' react: '>=18'
@@ -2988,8 +2988,8 @@ packages:
peerDependencies: peerDependencies:
vite: 5.x || 6.x || 7.x vite: 5.x || 6.x || 7.x
vite-tsconfig-paths@6.0.1: vite-tsconfig-paths@6.0.2:
resolution: {integrity: sha512-OQuYkfCQhc2T+n//0N7/oogTosgiSyZQ7dydrpUlH5SbnFTtplpekdY4GMi6jDwEpiwWlqeUJMyPfC2ePM1+2A==} resolution: {integrity: sha512-c06LOO8fWB5RuEPpEIHXU9t7Dt4DoiPIljnKws9UygIaQo6PoFKawTftz5/QVcO+6pOs/HHWycnq4UrZkWVYnQ==}
peerDependencies: peerDependencies:
vite: '*' vite: '*'
peerDependenciesMeta: peerDependenciesMeta:
@@ -3316,85 +3316,85 @@ snapshots:
'@emotion/weak-memoize@0.4.0': {} '@emotion/weak-memoize@0.4.0': {}
'@esbuild/aix-ppc64@0.27.1': '@esbuild/aix-ppc64@0.27.2':
optional: true optional: true
'@esbuild/android-arm64@0.27.1': '@esbuild/android-arm64@0.27.2':
optional: true optional: true
'@esbuild/android-arm@0.27.1': '@esbuild/android-arm@0.27.2':
optional: true optional: true
'@esbuild/android-x64@0.27.1': '@esbuild/android-x64@0.27.2':
optional: true optional: true
'@esbuild/darwin-arm64@0.27.1': '@esbuild/darwin-arm64@0.27.2':
optional: true optional: true
'@esbuild/darwin-x64@0.27.1': '@esbuild/darwin-x64@0.27.2':
optional: true optional: true
'@esbuild/freebsd-arm64@0.27.1': '@esbuild/freebsd-arm64@0.27.2':
optional: true optional: true
'@esbuild/freebsd-x64@0.27.1': '@esbuild/freebsd-x64@0.27.2':
optional: true optional: true
'@esbuild/linux-arm64@0.27.1': '@esbuild/linux-arm64@0.27.2':
optional: true optional: true
'@esbuild/linux-arm@0.27.1': '@esbuild/linux-arm@0.27.2':
optional: true optional: true
'@esbuild/linux-ia32@0.27.1': '@esbuild/linux-ia32@0.27.2':
optional: true optional: true
'@esbuild/linux-loong64@0.14.54': '@esbuild/linux-loong64@0.14.54':
optional: true optional: true
'@esbuild/linux-loong64@0.27.1': '@esbuild/linux-loong64@0.27.2':
optional: true optional: true
'@esbuild/linux-mips64el@0.27.1': '@esbuild/linux-mips64el@0.27.2':
optional: true optional: true
'@esbuild/linux-ppc64@0.27.1': '@esbuild/linux-ppc64@0.27.2':
optional: true optional: true
'@esbuild/linux-riscv64@0.27.1': '@esbuild/linux-riscv64@0.27.2':
optional: true optional: true
'@esbuild/linux-s390x@0.27.1': '@esbuild/linux-s390x@0.27.2':
optional: true optional: true
'@esbuild/linux-x64@0.27.1': '@esbuild/linux-x64@0.27.2':
optional: true optional: true
'@esbuild/netbsd-arm64@0.27.1': '@esbuild/netbsd-arm64@0.27.2':
optional: true optional: true
'@esbuild/netbsd-x64@0.27.1': '@esbuild/netbsd-x64@0.27.2':
optional: true optional: true
'@esbuild/openbsd-arm64@0.27.1': '@esbuild/openbsd-arm64@0.27.2':
optional: true optional: true
'@esbuild/openbsd-x64@0.27.1': '@esbuild/openbsd-x64@0.27.2':
optional: true optional: true
'@esbuild/openharmony-arm64@0.27.1': '@esbuild/openharmony-arm64@0.27.2':
optional: true optional: true
'@esbuild/sunos-x64@0.27.1': '@esbuild/sunos-x64@0.27.2':
optional: true optional: true
'@esbuild/win32-arm64@0.27.1': '@esbuild/win32-arm64@0.27.2':
optional: true optional: true
'@esbuild/win32-ia32@0.27.1': '@esbuild/win32-ia32@0.27.2':
optional: true optional: true
'@esbuild/win32-x64@0.27.1': '@esbuild/win32-x64@0.27.2':
optional: true optional: true
'@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)': '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)':
@@ -3958,7 +3958,7 @@ snapshots:
base64-js@1.5.1: {} base64-js@1.5.1: {}
baseline-browser-mapping@2.9.8: {} baseline-browser-mapping@2.9.9: {}
bin-build@3.0.0: bin-build@3.0.0:
dependencies: dependencies:
@@ -4015,7 +4015,7 @@ snapshots:
browserslist@4.28.1: browserslist@4.28.1:
dependencies: dependencies:
baseline-browser-mapping: 2.9.8 baseline-browser-mapping: 2.9.9
caniuse-lite: 1.0.30001760 caniuse-lite: 1.0.30001760
electron-to-chromium: 1.5.267 electron-to-chromium: 1.5.267
node-releases: 2.0.27 node-releases: 2.0.27
@@ -4470,34 +4470,34 @@ snapshots:
esbuild-windows-64: 0.14.54 esbuild-windows-64: 0.14.54
esbuild-windows-arm64: 0.14.54 esbuild-windows-arm64: 0.14.54
esbuild@0.27.1: esbuild@0.27.2:
optionalDependencies: optionalDependencies:
'@esbuild/aix-ppc64': 0.27.1 '@esbuild/aix-ppc64': 0.27.2
'@esbuild/android-arm': 0.27.1 '@esbuild/android-arm': 0.27.2
'@esbuild/android-arm64': 0.27.1 '@esbuild/android-arm64': 0.27.2
'@esbuild/android-x64': 0.27.1 '@esbuild/android-x64': 0.27.2
'@esbuild/darwin-arm64': 0.27.1 '@esbuild/darwin-arm64': 0.27.2
'@esbuild/darwin-x64': 0.27.1 '@esbuild/darwin-x64': 0.27.2
'@esbuild/freebsd-arm64': 0.27.1 '@esbuild/freebsd-arm64': 0.27.2
'@esbuild/freebsd-x64': 0.27.1 '@esbuild/freebsd-x64': 0.27.2
'@esbuild/linux-arm': 0.27.1 '@esbuild/linux-arm': 0.27.2
'@esbuild/linux-arm64': 0.27.1 '@esbuild/linux-arm64': 0.27.2
'@esbuild/linux-ia32': 0.27.1 '@esbuild/linux-ia32': 0.27.2
'@esbuild/linux-loong64': 0.27.1 '@esbuild/linux-loong64': 0.27.2
'@esbuild/linux-mips64el': 0.27.1 '@esbuild/linux-mips64el': 0.27.2
'@esbuild/linux-ppc64': 0.27.1 '@esbuild/linux-ppc64': 0.27.2
'@esbuild/linux-riscv64': 0.27.1 '@esbuild/linux-riscv64': 0.27.2
'@esbuild/linux-s390x': 0.27.1 '@esbuild/linux-s390x': 0.27.2
'@esbuild/linux-x64': 0.27.1 '@esbuild/linux-x64': 0.27.2
'@esbuild/netbsd-arm64': 0.27.1 '@esbuild/netbsd-arm64': 0.27.2
'@esbuild/netbsd-x64': 0.27.1 '@esbuild/netbsd-x64': 0.27.2
'@esbuild/openbsd-arm64': 0.27.1 '@esbuild/openbsd-arm64': 0.27.2
'@esbuild/openbsd-x64': 0.27.1 '@esbuild/openbsd-x64': 0.27.2
'@esbuild/openharmony-arm64': 0.27.1 '@esbuild/openharmony-arm64': 0.27.2
'@esbuild/sunos-x64': 0.27.1 '@esbuild/sunos-x64': 0.27.2
'@esbuild/win32-arm64': 0.27.1 '@esbuild/win32-arm64': 0.27.2
'@esbuild/win32-ia32': 0.27.1 '@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 0.27.1 '@esbuild/win32-x64': 0.27.2
escalade@3.2.0: {} escalade@3.2.0: {}
@@ -5525,7 +5525,7 @@ snapshots:
react-is@19.2.3: {} react-is@19.2.3: {}
react-router@7.10.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3): react-router@7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
dependencies: dependencies:
cookie: 1.1.1 cookie: 1.1.1
react: 19.2.3 react: 19.2.3
@@ -6002,7 +6002,7 @@ snapshots:
stack-trace: 1.0.0-pre2 stack-trace: 1.0.0-pre2
vite: 7.3.0(@types/node@25.0.3)(terser@5.44.1) vite: 7.3.0(@types/node@25.0.3)(terser@5.44.1)
vite-tsconfig-paths@6.0.1(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(terser@5.44.1)): vite-tsconfig-paths@6.0.2(typescript@5.9.3)(vite@7.3.0(@types/node@25.0.3)(terser@5.44.1)):
dependencies: dependencies:
debug: 4.4.3 debug: 4.4.3
globrex: 0.1.2 globrex: 0.1.2
@@ -6015,7 +6015,7 @@ snapshots:
vite@7.3.0(@types/node@25.0.3)(terser@5.44.1): vite@7.3.0(@types/node@25.0.3)(terser@5.44.1):
dependencies: dependencies:
esbuild: 0.27.1 esbuild: 0.27.2
fdir: 6.5.0(picomatch@4.0.3) fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3 picomatch: 4.0.3
postcss: 8.5.6 postcss: 8.5.6

View File

@@ -108,16 +108,18 @@ const SensorsAnalogDialog = ({
// Memoize menu items to avoid recreation on each render // Memoize menu items to avoid recreation on each render
const analogTypeMenuItems = useMemo( const analogTypeMenuItems = useMemo(
() => () =>
AnalogTypeNames.map((val, i) => ( AnalogTypeNames.map((val, i) => ({ name: val, value: i + 1 }))
.sort((a, b) => a.name.localeCompare(b.name))
.map(({ name, value }) => (
<MenuItem <MenuItem
key={val} key={name}
value={i + 1} value={value}
disabled={disabledTypeList.includes(i + 1)} disabled={disabledTypeList?.includes(value)}
> >
{val} {name}
</MenuItem> </MenuItem>
)), )),
[] [disabledTypeList]
); );
const uomMenuItems = useMemo( const uomMenuItems = useMemo(

View File

@@ -262,7 +262,7 @@ export const AnalogTypeNames = [
'PWM 0', // 7 'PWM 0', // 7
'PWM 1', // 8 'PWM 1', // 8
'PWM 2', // 9 'PWM 2', // 9
'NTC Temp.', // 10 'NTC Temp', // 10
'RGB Led', // 11 'RGB Led', // 11
'Pulse', // 12 'Pulse', // 12
'Freq 0', // 13 'Freq 0', // 13
@@ -270,7 +270,7 @@ export const AnalogTypeNames = [
'Freq 2', // 15 'Freq 2', // 15
'Counter 0', // 16 'Counter 0', // 16
'Counter 1', // 17 'Counter 1', // 17
'Counter2' // 18 'Counter 2' // 18
] as const; ] as const;
export const BOARD_PROFILES = { export const BOARD_PROFILES = {

View File

@@ -2,9 +2,7 @@ import { useMemo } from 'react';
import { MenuItem } from '@mui/material'; import { MenuItem } from '@mui/material';
type TimeZones = Record<string, string>; export const TIME_ZONES: Record<string, string> = {
export const TIME_ZONES: Readonly<TimeZones> = {
'Africa/Abidjan': 'GMT0', 'Africa/Abidjan': 'GMT0',
'Africa/Accra': 'GMT0', 'Africa/Accra': 'GMT0',
'Africa/Addis_Ababa': 'EAT-3', 'Africa/Addis_Ababa': 'EAT-3',

View File

@@ -1048,7 +1048,9 @@ const emsesp_sensordata = {
} }
], ],
analog_enabled: true, analog_enabled: true,
available_gpios: [] as number[] available_gpios: [] as number[],
exclude_types: [] as number[],
platform: 'ESP32'
}; };
const activity = { const activity = {

View File

@@ -650,7 +650,7 @@ void AnalogSensor::remove_ha_topic(const int8_t type, const uint8_t gpio) const
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio); snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
} else if (type >= AnalogType::PWM_0 && type <= AnalogType::PWM_2) { } else if (type >= AnalogType::PWM_0 && type <= AnalogType::PWM_2) {
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio); snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
} else if (type >= AnalogType::RGB) { } else if (type == AnalogType::RGB) {
snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio); snprintf(topic, sizeof(topic), "number/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
} else if (type == AnalogType::DIGITAL_IN) { } else if (type == AnalogType::DIGITAL_IN) {
snprintf(topic, sizeof(topic), "binary_sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio); snprintf(topic, sizeof(topic), "binary_sensor/%s/%s_%02d/config", Mqtt::basename().c_str(), F_(analogsensor), gpio);
@@ -676,12 +676,13 @@ void AnalogSensor::publish_values(const bool force) {
JsonDocument doc; JsonDocument doc;
JsonObject obj = doc.to<JsonObject>(); JsonObject obj = doc.to<JsonObject>();
bool ha_dev_created = false;
for (auto & sensor : sensors_) { for (auto & sensor : sensors_) {
if (Mqtt::is_nested()) { if (Mqtt::is_nested()) {
char s[10]; char s[10];
JsonObject dataSensor = obj[Helpers::smallitoa(s, sensor.gpio())].to<JsonObject>(); JsonObject dataSensor = obj[Helpers::smallitoa(s, sensor.gpio())].to<JsonObject>();
dataSensor["name"] = sensor.name(); dataSensor["name"] = (const char *)sensor.name();
#if CONFIG_IDF_TARGET_ESP32 #if CONFIG_IDF_TARGET_ESP32
if (sensor.type() == AnalogType::PULSE || (sensor.type() == AnalogType::DIGITAL_OUT && sensor.gpio() != 25 && sensor.gpio() != 26)) { if (sensor.type() == AnalogType::PULSE || (sensor.type() == AnalogType::DIGITAL_OUT && sensor.gpio() != 25 && sensor.gpio() != 26)) {
#else #else
@@ -738,7 +739,7 @@ void AnalogSensor::publish_values(const bool force) {
config["~"] = Mqtt::base(); config["~"] = Mqtt::base();
config["uniq_id"] = uniq_s; config["uniq_id"] = uniq_s;
config["name"] = sensor.name(); config["name"] = (const char *)sensor.name();
if (sensor.uom() != DeviceValueUOM::NONE && sensor.type() != AnalogType::DIGITAL_OUT) { if (sensor.uom() != DeviceValueUOM::NONE && sensor.type() != AnalogType::DIGITAL_OUT) {
config["unit_of_meas"] = EMSdevice::uom_to_string(sensor.uom()); config["unit_of_meas"] = EMSdevice::uom_to_string(sensor.uom());
@@ -798,18 +799,16 @@ void AnalogSensor::publish_values(const bool force) {
config["stat_cla"] = "measurement"; config["stat_cla"] = "measurement";
} }
// see if we need to create the [devs] discovery section, as this needs only to be done once for all sensors
if (std::none_of(sensors_.begin(), sensors_.end(), [](const auto & sensor) { return sensor.ha_registered; })) {
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Analog Sensors", nullptr, "EMS-ESP", EMSESP_APP_VERSION, true);
}
// add default_entity_id // add default_entity_id
std::string topic_str(topic); std::string topic_str(topic);
config["def_ent_id"] = topic_str.substr(0, topic_str.find("/")) + "." + uniq_s; config["def_ent_id"] = topic_str.substr(0, topic_str.find("/")) + "." + uniq_s;
// dev section with model is only created on the 1st sensor
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Analog Sensors", nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_dev_created);
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond); Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>()); sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
ha_dev_created |= sensor.ha_registered;
} }
} }
@@ -857,8 +856,8 @@ bool AnalogSensor::get_value_info(JsonObject output, const char * cmd, const int
// note we don't add the device and state classes here, as we do in the custom entity service // note we don't add the device and state classes here, as we do in the custom entity service
void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) { void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) {
output["name"] = sensor.name(); output["name"] = (const char *)sensor.name();
output["fullname"] = sensor.name(); output["fullname"] = (const char *)sensor.name();
output["gpio"] = sensor.gpio(); output["gpio"] = sensor.gpio();
output["type"] = F_(number); output["type"] = F_(number);
output["analog"] = FL_(list_sensortype)[sensor.type()]; output["analog"] = FL_(list_sensortype)[sensor.type()];

View File

@@ -1451,7 +1451,7 @@ void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const char * mo
// create dev section // create dev section
JsonObject dev_json = doc["dev"].to<JsonObject>(); JsonObject dev_json = doc["dev"].to<JsonObject>();
// add ids and name - with capitalize first letter // add ids and name - capitalize first letter of the name
JsonArray ids = dev_json["ids"].to<JsonArray>(); // ids, it is an array with a single element JsonArray ids = dev_json["ids"].to<JsonArray>(); // ids, it is an array with a single element
if (name != nullptr) { if (name != nullptr) {
// for ids, replace all spaces with - // for ids, replace all spaces with -
@@ -1464,11 +1464,10 @@ void Mqtt::add_ha_dev_section(JsonObject doc, const char * name, const char * mo
dev_json["name"] = Mqtt::basename() + " " + cap_name; dev_json["name"] = Mqtt::basename() + " " + cap_name;
free(cap_name); free(cap_name);
} else { } else {
ids.add(Mqtt::basename()); ids.add(Mqtt::basename()); // no name, assign it to the main EMS-ESP device in HA
dev_json["name"] = Mqtt::basename();
} }
// this is used to only create it once when entities are dynamically added // create the model, manufacturer and version
if (create_model) { if (create_model) {
dev_json["mf"] = brand != nullptr ? brand : "EMS-ESP"; dev_json["mf"] = brand != nullptr ? brand : "EMS-ESP";
if (model != nullptr) { if (model != nullptr) {

View File

@@ -418,8 +418,8 @@ bool TemperatureSensor::get_value_info(JsonObject output, const char * cmd, cons
// note we don't add the device and state classes here, as we do in the custom entity service // note we don't add the device and state classes here, as we do in the custom entity service
void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor) { void TemperatureSensor::get_value_json(JsonObject output, const Sensor & sensor) {
output["id"] = sensor.id(); output["id"] = sensor.id();
output["name"] = sensor.name(); output["name"] = (const char *)sensor.name();
output["fullname"] = sensor.name(); output["fullname"] = (const char *)sensor.name();
if (Helpers::hasValue(sensor.temperature_c)) { if (Helpers::hasValue(sensor.temperature_c)) {
char val[10]; char val[10];
output["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0)); output["value"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
@@ -480,6 +480,7 @@ void TemperatureSensor::publish_values(const bool force) {
} }
JsonDocument doc; JsonDocument doc;
bool ha_dev_created = false;
for (auto & sensor : sensors_) { for (auto & sensor : sensors_) {
bool has_value = Helpers::hasValue(sensor.temperature_c); bool has_value = Helpers::hasValue(sensor.temperature_c);
@@ -487,7 +488,7 @@ void TemperatureSensor::publish_values(const bool force) {
char val[10]; char val[10];
if (Mqtt::is_nested()) { if (Mqtt::is_nested()) {
JsonObject dataSensor = doc[sensor.id()].to<JsonObject>(); JsonObject dataSensor = doc[sensor.id()].to<JsonObject>();
dataSensor["name"] = sensor.name(); dataSensor["name"] = (const char *)sensor.name();
dataSensor["temp"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0)); dataSensor["temp"] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
} else { } else {
doc[sensor.name()] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0)); doc[sensor.name()] = serialized(Helpers::render_value(val, sensor.temperature_c, 10, EMSESP::system_.fahrenheit() ? 2 : 0));
@@ -541,19 +542,17 @@ void TemperatureSensor::publish_values(const bool force) {
config["uniq_id"] = uniq_s; config["uniq_id"] = uniq_s;
config["def_ent_id"] = (std::string) "sensor." + uniq_s; config["def_ent_id"] = (std::string) "sensor." + uniq_s;
config["name"] = sensor.name(); config["name"] = (const char *)sensor.name();
// see if we need to create the [devs] discovery section, as this needs only to be done once for all sensors
if (std::none_of(sensors_.begin(), sensors_.end(), [](const auto & sensor) { return sensor.ha_registered; })) {
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Temperature Sensors", nullptr, "EMS-ESP", EMSESP_APP_VERSION, true);
}
// dev section with model is only created on the 1st sensor
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Temperature Sensors", nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_dev_created);
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond); Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE];
snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id()); snprintf(topic, sizeof(topic), "sensor/%s/%s_%s/config", Mqtt::basename().c_str(), F_(temperaturesensor), sensor.id());
sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>()); sensor.ha_registered = Mqtt::queue_ha(topic, config.as<JsonObject>());
ha_dev_created |= sensor.ha_registered;
} }
} }
} }

View File

@@ -1 +1 @@
#define EMSESP_APP_VERSION "3.7.3-dev.37" #define EMSESP_APP_VERSION "3.7.3-dev.38"

View File

@@ -465,9 +465,7 @@ void WebCustomEntityService::publish(const bool force) {
Mqtt::add_ha_classes(config.as<JsonObject>(), EMSdevice::DeviceType::SYSTEM, entityItem.value_type, entityItem.uom); Mqtt::add_ha_classes(config.as<JsonObject>(), EMSdevice::DeviceType::SYSTEM, entityItem.value_type, entityItem.uom);
if (!ha_created) { Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Custom Entities", nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_created);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), "Custom Entities", nullptr, "EMS-ESP", EMSESP_APP_VERSION, true);
}
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond); Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>()); ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());

View File

@@ -276,9 +276,7 @@ void WebSchedulerService::publish(const bool force) {
config["cmd_t"] = command_topic; config["cmd_t"] = command_topic;
Mqtt::add_ha_bool(config.as<JsonObject>()); Mqtt::add_ha_bool(config.as<JsonObject>());
if (!ha_created) { Mqtt::add_ha_dev_section(config.as<JsonObject>(), F_(scheduler), nullptr, "EMS-ESP", EMSESP_APP_VERSION, !ha_created);
Mqtt::add_ha_dev_section(config.as<JsonObject>(), F_(scheduler), nullptr, "EMS-ESP", EMSESP_APP_VERSION, true);
}
Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond); Mqtt::add_ha_avty_section(config.as<JsonObject>(), stat_t, val_cond);
ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>()); ha_created |= Mqtt::queue_ha(topic, config.as<JsonObject>());