mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-08-29 07:08:56 +00:00
Compare commits
54
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b5a670ba2 | ||
|
|
58feb78362 | ||
|
|
c6e13ccb45 | ||
|
|
ac8c45f67f | ||
|
|
a8364ad67b | ||
|
|
e2b49113c7 | ||
|
|
7b9407d020 | ||
|
|
873ad6082c | ||
|
|
8beaf488f7 | ||
|
|
7a1c2d52f0 | ||
|
|
5a79c338d4 | ||
|
|
16fd422c4a | ||
|
|
e5f70d5ba8 | ||
|
|
0618aca73a | ||
|
|
cfc7ab8dd8 | ||
|
|
56aab4e59c | ||
|
|
7075b78a46 | ||
|
|
b31e8c286e | ||
|
|
2c5b536134 | ||
|
|
52201c96bf | ||
|
|
bf964cc6d9 | ||
|
|
1e114dee70 | ||
|
|
897aa8fb7c | ||
|
|
bbcbed12d5 | ||
|
|
36c4db7f8f | ||
|
|
5458e5084d | ||
|
|
744e4a6d5c | ||
|
|
6ea21c383b | ||
|
|
1a1c09449c | ||
|
|
9426c3ea11 | ||
|
|
4d9e9504ef | ||
|
|
32499d14d5 | ||
|
|
c4fd415cbe | ||
|
|
502030c016 | ||
|
|
7a05464f03 | ||
|
|
15fd9b371e | ||
|
|
04a43652d6 | ||
|
|
7b37e97e00 | ||
|
|
94751abaac | ||
|
|
cc8456617a | ||
|
|
8727abdefc | ||
|
|
24e90273c9 | ||
|
|
845bdb7dba | ||
|
|
55f12ff520 | ||
|
|
19eb05a0e0 | ||
|
|
9f7ea9b7c7 | ||
|
|
0d7b8f189c | ||
|
|
4639243cf9 | ||
|
|
df26459b46 | ||
|
|
c58162344f | ||
|
|
5974286445 | ||
|
|
4e527bbce8 | ||
|
|
b3983b35de | ||
|
|
429c5aea58 |
@@ -31,7 +31,7 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
if: ((github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push') == false
|
||||
|
||||
- uses: pnpm/action-setup@v5
|
||||
- uses: pnpm/action-setup@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
@@ -222,7 +222,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: pnpm/action-setup@v5
|
||||
- uses: pnpm/action-setup@v6
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
|
||||
@@ -12,4 +12,4 @@ jobs:
|
||||
- name: 'Checkout repository'
|
||||
uses: actions/checkout@v6
|
||||
- name: 'Dependency review'
|
||||
uses: actions/dependency-review-action@v4
|
||||
uses: actions/dependency-review-action@v5
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
release_created: ${{ steps.release.outputs.release_created }}
|
||||
version: '${{steps.release.outputs.major}}.${{steps.release.outputs.minor}}.${{steps.release.outputs.patch}}'
|
||||
steps:
|
||||
- uses: pnpm/action-setup@v5
|
||||
- uses: pnpm/action-setup@v6
|
||||
with:
|
||||
version: 9
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
- uses: googleapis/release-please-action@v4
|
||||
- uses: googleapis/release-please-action@v5
|
||||
id: release
|
||||
with:
|
||||
target-branch: dev
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
with:
|
||||
ref: dev
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
- uses: pnpm/action-setup@v5
|
||||
- uses: pnpm/action-setup@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
".": "2.9.2"
|
||||
".": "2.11.0"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,95 @@
|
||||
# Changelog
|
||||
|
||||
## [2.11.0](https://github.com/Koenkk/zigbee2mqtt/compare/2.10.1...2.11.0) (2026-06-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow to disable external JS extensions ([#31826](https://github.com/Koenkk/zigbee2mqtt/issues/31826)) ([15fd9b3](https://github.com/Koenkk/zigbee2mqtt/commit/15fd9b371e30ed352cf2de2d241a0d0f7fafa9d1))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps-dev:** bump tmp from 0.2.5 to 0.2.6 ([#32122](https://github.com/Koenkk/zigbee2mqtt/issues/32122)) ([7b9407d](https://github.com/Koenkk/zigbee2mqtt/commit/7b9407d020b9db1093b360f5f6e217bbab7afb63))
|
||||
* **deps:** bump actions/dependency-review-action from 4 to 5 ([#31980](https://github.com/Koenkk/zigbee2mqtt/issues/31980)) ([4d9e950](https://github.com/Koenkk/zigbee2mqtt/commit/4d9e9504ef9c857a1985c79d3a6799552abc3aea))
|
||||
* **deps:** bump brace-expansion from 2.0.2 to 5.0.6 ([#32038](https://github.com/Koenkk/zigbee2mqtt/issues/32038)) ([897aa8f](https://github.com/Koenkk/zigbee2mqtt/commit/897aa8fb7c82dbc9c906f986477c4c1673bb3199))
|
||||
* **deps:** bump pnpm/action-setup from 5 to 6 ([#31698](https://github.com/Koenkk/zigbee2mqtt/issues/31698)) ([1a1c094](https://github.com/Koenkk/zigbee2mqtt/commit/1a1c09449c9d077ea06048d7e2ecea90ff850c9b))
|
||||
* **deps:** bump ws from 8.20.0 to 8.20.1 ([#32041](https://github.com/Koenkk/zigbee2mqtt/issues/32041)) ([bf964cc](https://github.com/Koenkk/zigbee2mqtt/commit/bf964cc6d976d70e687844e5a09c4577763dc0d3))
|
||||
* Fix default value of "optimistic" group setting ([#32054](https://github.com/Koenkk/zigbee2mqtt/issues/32054)) ([b31e8c2](https://github.com/Koenkk/zigbee2mqtt/commit/b31e8c286e7a77517a88e3e7eb2247e9a0fd2cc1))
|
||||
* **ignore:** bump the minor-patch group with 2 updates ([#32137](https://github.com/Koenkk/zigbee2mqtt/issues/32137)) ([ac8c45f](https://github.com/Koenkk/zigbee2mqtt/commit/ac8c45f67f0a4aae2688e55b98dabdc23f73a259))
|
||||
* **ignore:** bump the minor-patch group with 3 updates ([#31982](https://github.com/Koenkk/zigbee2mqtt/issues/31982)) ([9426c3e](https://github.com/Koenkk/zigbee2mqtt/commit/9426c3ea118de9e60326e8dc257a0c2474380f8c))
|
||||
* **ignore:** bump the minor-patch group with 3 updates ([#32106](https://github.com/Koenkk/zigbee2mqtt/issues/32106)) ([e5f70d5](https://github.com/Koenkk/zigbee2mqtt/commit/e5f70d5ba82923f9f37fbda79bed08d581706129))
|
||||
* **ignore:** update zigbee-herdsman to 10.0.8 ([#31945](https://github.com/Koenkk/zigbee2mqtt/issues/31945)) ([04a4365](https://github.com/Koenkk/zigbee2mqtt/commit/04a43652d6e131694e29e06ca646eeac37ed3c7d))
|
||||
* **ignore:** update zigbee-herdsman to 10.1.0 ([#32027](https://github.com/Koenkk/zigbee2mqtt/issues/32027)) ([36c4db7](https://github.com/Koenkk/zigbee2mqtt/commit/36c4db7f8f4e3438f6ebb82cd6ecadf6c54e231e))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.47.0 ([#31946](https://github.com/Koenkk/zigbee2mqtt/issues/31946)) ([7a05464](https://github.com/Koenkk/zigbee2mqtt/commit/7a05464f0355380ee855415bc270632263e3f5d3))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.48.0 ([#31959](https://github.com/Koenkk/zigbee2mqtt/issues/31959)) ([502030c](https://github.com/Koenkk/zigbee2mqtt/commit/502030c0168c8ba6eaf7495a9014489f2f7a7c50))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.49.0 ([#31976](https://github.com/Koenkk/zigbee2mqtt/issues/31976)) ([32499d1](https://github.com/Koenkk/zigbee2mqtt/commit/32499d14d5f0c9eada160d596d6be92da6c4af95))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.50.0 ([#31988](https://github.com/Koenkk/zigbee2mqtt/issues/31988)) ([6ea21c3](https://github.com/Koenkk/zigbee2mqtt/commit/6ea21c383b4801f28e30b022194e71375db94b17))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.51.0 ([#31999](https://github.com/Koenkk/zigbee2mqtt/issues/31999)) ([744e4a6](https://github.com/Koenkk/zigbee2mqtt/commit/744e4a6d5c4dd179e7c3d1a2b4fbcdc820195547))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.51.1 ([#32016](https://github.com/Koenkk/zigbee2mqtt/issues/32016)) ([5458e50](https://github.com/Koenkk/zigbee2mqtt/commit/5458e5084def411aaad9af08e415acb6bc16d181))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.52.0 ([#32040](https://github.com/Koenkk/zigbee2mqtt/issues/32040)) ([1e114de](https://github.com/Koenkk/zigbee2mqtt/commit/1e114dee70b8079eda31d4d0cc52fa073a772798))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.53.0 ([#32051](https://github.com/Koenkk/zigbee2mqtt/issues/32051)) ([52201c9](https://github.com/Koenkk/zigbee2mqtt/commit/52201c96bf897af9bcad30435575923a0452b6dd))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.54.0 ([#32065](https://github.com/Koenkk/zigbee2mqtt/issues/32065)) ([2c5b536](https://github.com/Koenkk/zigbee2mqtt/commit/2c5b53613448ae4c6548f874a36acc1226d53ec3))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.55.0 ([#32068](https://github.com/Koenkk/zigbee2mqtt/issues/32068)) ([7075b78](https://github.com/Koenkk/zigbee2mqtt/commit/7075b78a462a0d1f76cf91cc78601d90edfd8b4e))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.56.0 ([#32087](https://github.com/Koenkk/zigbee2mqtt/issues/32087)) ([56aab4e](https://github.com/Koenkk/zigbee2mqtt/commit/56aab4e59c4ea7bdbd93a1ed6632171994d8ed56))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.57.0 ([#32113](https://github.com/Koenkk/zigbee2mqtt/issues/32113)) ([7a1c2d5](https://github.com/Koenkk/zigbee2mqtt/commit/7a1c2d52f0b0699854f3c8c9375761cb0b22ac55))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.58.0 ([#32126](https://github.com/Koenkk/zigbee2mqtt/issues/32126)) ([e2b4911](https://github.com/Koenkk/zigbee2mqtt/commit/e2b49113c7932c4cd8ef7b23a27e3cd5d4e7150d))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.59.1 ([#32136](https://github.com/Koenkk/zigbee2mqtt/issues/32136)) ([a8364ad](https://github.com/Koenkk/zigbee2mqtt/commit/a8364ad67b0dcbde93b1d6445c269a821321e9b3))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.60.0 ([#32150](https://github.com/Koenkk/zigbee2mqtt/issues/32150)) ([c6e13cc](https://github.com/Koenkk/zigbee2mqtt/commit/c6e13ccb45666f9604e8c9c9655bbe7ea682712d))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.61.1 ([#32156](https://github.com/Koenkk/zigbee2mqtt/issues/32156)) ([58feb78](https://github.com/Koenkk/zigbee2mqtt/commit/58feb783626fd2429bea0f8a0db37bdc107c431b))
|
||||
* Prevent invalid external JS file name on save ([#32037](https://github.com/Koenkk/zigbee2mqtt/issues/32037)) ([bbcbed1](https://github.com/Koenkk/zigbee2mqtt/commit/bbcbed12d53408eaa8ceec110c7071fff8e158e4))
|
||||
* Use Jinja-safe property access in HA discovery templates ([#31930](https://github.com/Koenkk/zigbee2mqtt/issues/31930)) ([c4fd415](https://github.com/Koenkk/zigbee2mqtt/commit/c4fd415cbe7b01719679b1a96d2b6e07b0793125))
|
||||
|
||||
## [2.10.1](https://github.com/Koenkk/zigbee2mqtt/compare/2.10.0...2.10.1) (2026-05-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ignore:** bump @biomejs/biome from 2.4.13 to 2.4.14 in the minor-patch group across 1 directory ([#31881](https://github.com/Koenkk/zigbee2mqtt/issues/31881)) ([55f12ff](https://github.com/Koenkk/zigbee2mqtt/commit/55f12ff52063d576be0fe82891678c52181f3b8e))
|
||||
* **ignore:** bump express-static-gzip from 3.0.0 to 3.0.1 in the minor-patch group ([#31924](https://github.com/Koenkk/zigbee2mqtt/issues/31924)) ([24e9027](https://github.com/Koenkk/zigbee2mqtt/commit/24e90273c9e712e122887e74ccf8208a8b42e762))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.43.0 ([#31878](https://github.com/Koenkk/zigbee2mqtt/issues/31878)) ([19eb05a](https://github.com/Koenkk/zigbee2mqtt/commit/19eb05a0e023c7e2e8639c1dcda18399e96ae74d))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.44.0 ([#31900](https://github.com/Koenkk/zigbee2mqtt/issues/31900)) ([845bdb7](https://github.com/Koenkk/zigbee2mqtt/commit/845bdb7dba5fe0f5e67e1b92c68872da0f3abf6a))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.45.0 ([#31925](https://github.com/Koenkk/zigbee2mqtt/issues/31925)) ([8727abd](https://github.com/Koenkk/zigbee2mqtt/commit/8727abdefc9114a5e2e1036d764271c90065e0a1))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.46.0 ([#31937](https://github.com/Koenkk/zigbee2mqtt/issues/31937)) ([cc84566](https://github.com/Koenkk/zigbee2mqtt/commit/cc8456617a4a389e7297e380901bfd6bb0223b32))
|
||||
* Replace deprecated `url.parse` ([#31845](https://github.com/Koenkk/zigbee2mqtt/issues/31845)) ([9f7ea9b](https://github.com/Koenkk/zigbee2mqtt/commit/9f7ea9b7c79db7a781b431fbe43568e15647f8e5))
|
||||
|
||||
## [2.10.0](https://github.com/Koenkk/zigbee2mqtt/compare/2.9.2...2.10.0) (2026-05-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Home Assistant: add group entities in discovery config ([#31663](https://github.com/Koenkk/zigbee2mqtt/issues/31663)) ([0419726](https://github.com/Koenkk/zigbee2mqtt/commit/041972669a6a8108e8fee1a0fffb555292371285))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Clarify units of pause_on_backoff_gt ([#31668](https://github.com/Koenkk/zigbee2mqtt/issues/31668)) ([4a63e65](https://github.com/Koenkk/zigbee2mqtt/commit/4a63e65981b6bbd746a730e7ca2291aba7a6c975))
|
||||
* **deps:** bump googleapis/release-please-action from 4 to 5 ([#31805](https://github.com/Koenkk/zigbee2mqtt/issues/31805)) ([4e527bb](https://github.com/Koenkk/zigbee2mqtt/commit/4e527bbce8612c85fd636a1c493059af9793991f))
|
||||
* **ignore:** bump @biomejs/biome from 2.4.10 to 2.4.11 in the minor-patch group ([#31699](https://github.com/Koenkk/zigbee2mqtt/issues/31699)) ([cdd7357](https://github.com/Koenkk/zigbee2mqtt/commit/cdd73575227527ae7eca5732d96687a30cea8538))
|
||||
* **ignore:** bump @types/node from 24.12.0 to 24.12.2 in the minor-patch group across 1 directory ([#31628](https://github.com/Koenkk/zigbee2mqtt/issues/31628)) ([e6dd5c7](https://github.com/Koenkk/zigbee2mqtt/commit/e6dd5c73bc2d76b32c45ef19633626dbcdde8379))
|
||||
* **ignore:** bump the minor-patch group with 2 updates ([#31758](https://github.com/Koenkk/zigbee2mqtt/issues/31758)) ([7ba232e](https://github.com/Koenkk/zigbee2mqtt/commit/7ba232e27d973119530119ca136aaab3e8e22ab6))
|
||||
* **ignore:** bump the minor-patch group with 3 updates ([#31806](https://github.com/Koenkk/zigbee2mqtt/issues/31806)) ([b3983b3](https://github.com/Koenkk/zigbee2mqtt/commit/b3983b35de0b6242d8e4d01f0d1d1e535e2d0b60))
|
||||
* **ignore:** bump typescript from 5.9.3 to 6.0.2 ([#31560](https://github.com/Koenkk/zigbee2mqtt/issues/31560)) ([9e27181](https://github.com/Koenkk/zigbee2mqtt/commit/9e27181b64b771250db283b5a4b1da7835470ee6))
|
||||
* **ignore:** update zigbee-herdsman to 10.0.6 ([#31636](https://github.com/Koenkk/zigbee2mqtt/issues/31636)) ([aef3242](https://github.com/Koenkk/zigbee2mqtt/commit/aef32423195914aa9ef08875d4fe6de36df71f11))
|
||||
* **ignore:** update zigbee-herdsman to 10.0.7 ([#31673](https://github.com/Koenkk/zigbee2mqtt/issues/31673)) ([a0204ad](https://github.com/Koenkk/zigbee2mqtt/commit/a0204ad3f00ed366e4c41455ae4189bd31870a95))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.28.0 ([#31574](https://github.com/Koenkk/zigbee2mqtt/issues/31574)) ([08e4e9e](https://github.com/Koenkk/zigbee2mqtt/commit/08e4e9edeb048a07f89d6283e5bea04274a3fb47))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.29.0 ([#31586](https://github.com/Koenkk/zigbee2mqtt/issues/31586)) ([23f9847](https://github.com/Koenkk/zigbee2mqtt/commit/23f9847994da94fa8b38ba823a8e55418b006e7c))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.30.0 ([#31608](https://github.com/Koenkk/zigbee2mqtt/issues/31608)) ([6b567c1](https://github.com/Koenkk/zigbee2mqtt/commit/6b567c1286201aa9fef4744f7378798bc852c9ff))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.31.0 ([#31637](https://github.com/Koenkk/zigbee2mqtt/issues/31637)) ([a50065c](https://github.com/Koenkk/zigbee2mqtt/commit/a50065cbb40bb149a87046bb83a7602a5587b3b0))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.32.0 ([#31653](https://github.com/Koenkk/zigbee2mqtt/issues/31653)) ([4818cc4](https://github.com/Koenkk/zigbee2mqtt/commit/4818cc4163d578990339daf6c5e725bb40a08216))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.33.1 ([#31674](https://github.com/Koenkk/zigbee2mqtt/issues/31674)) ([0c9ec72](https://github.com/Koenkk/zigbee2mqtt/commit/0c9ec722db3f53c57870de7f09de9971d69cbda8))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.34.0 ([#31702](https://github.com/Koenkk/zigbee2mqtt/issues/31702)) ([55d8d1f](https://github.com/Koenkk/zigbee2mqtt/commit/55d8d1f4d0a5895ce146dbec98630d82adcd4e22))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.35.0 ([#31713](https://github.com/Koenkk/zigbee2mqtt/issues/31713)) ([0a7dfce](https://github.com/Koenkk/zigbee2mqtt/commit/0a7dfcef596c3201f9f0cd81960c0e4ad8add0c4))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.36.0 ([#31737](https://github.com/Koenkk/zigbee2mqtt/issues/31737)) ([a54775d](https://github.com/Koenkk/zigbee2mqtt/commit/a54775dea10a14b6d2f25ebb3c79a8a9d979e970))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.37.0 ([#31749](https://github.com/Koenkk/zigbee2mqtt/issues/31749)) ([78f440b](https://github.com/Koenkk/zigbee2mqtt/commit/78f440bada9a14abb1d84af12fc77b1af7d250ea))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.38.0 ([#31768](https://github.com/Koenkk/zigbee2mqtt/issues/31768)) ([305b7bc](https://github.com/Koenkk/zigbee2mqtt/commit/305b7bcafab59250173eddb9c08cb2fed0d966a0))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.38.1 ([#31777](https://github.com/Koenkk/zigbee2mqtt/issues/31777)) ([3bb3d56](https://github.com/Koenkk/zigbee2mqtt/commit/3bb3d56c05b92e349d2b117973df6cf9414b8450))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.39.1 ([#31783](https://github.com/Koenkk/zigbee2mqtt/issues/31783)) ([e715078](https://github.com/Koenkk/zigbee2mqtt/commit/e71507835b2c0673ec0df488e9d1db39a7b64a05))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.40.0 ([#31800](https://github.com/Koenkk/zigbee2mqtt/issues/31800)) ([429c5ae](https://github.com/Koenkk/zigbee2mqtt/commit/429c5aea585da1525347adc13712bc556b4ea2ae))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.41.0 ([#31820](https://github.com/Koenkk/zigbee2mqtt/issues/31820)) ([c581623](https://github.com/Koenkk/zigbee2mqtt/commit/c58162344fddc1cdb49027f6dcc9f1f35030bc61))
|
||||
* **ignore:** update zigbee-herdsman-converters to 26.42.0 ([#31830](https://github.com/Koenkk/zigbee2mqtt/issues/31830)) ([df26459](https://github.com/Koenkk/zigbee2mqtt/commit/df26459b46e67f4f3b1079eb6fa6a439bf1979af))
|
||||
* Improve transmit power description ([#31735](https://github.com/Koenkk/zigbee2mqtt/issues/31735)) ([5974286](https://github.com/Koenkk/zigbee2mqtt/commit/59742864457a9e29783363ebde8ede0e0aca5ea2))
|
||||
|
||||
## [2.9.2](https://github.com/Koenkk/zigbee2mqtt/compare/2.9.1...2.9.2) (2026-03-31)
|
||||
|
||||
|
||||
|
||||
+10
-4
@@ -1,8 +1,14 @@
|
||||
# Contributing to Zigbee2MQTT
|
||||
|
||||
Everybody is invited and welcome to contribute to Zigbee2MQTT. Zigbee2MQTT is written in JavaScript and is based upon [zigbee-herdsman](https://github.com/koenkk/zigbee-herdsman) and [zigbee-herdsman-converters](https://github.com/koenkk/zigbee-herdsman-converters). Zigbee-herdsman-converters contains all device definitions, zigbee-herdsman is responsible for handling all communication with the adapter.
|
||||
> [!WARNING]
|
||||
> Any AI-driven pull request with more than 500 lines of code will not be considered. If wanting to submit something that requires more, split the work into easily review-able pull requests that can be introduced in increments (e.g. pre-refactor, base feature, additional features).
|
||||
|
||||
Everybody is invited and welcomed to contribute to Zigbee2MQTT.
|
||||
Zigbee2MQTT is written in TypeScript.
|
||||
It uses [zigbee-herdsman](https://github.com/koenkk/zigbee-herdsman) for communication with the adapter/coordinator and [zigbee-herdsman-converters](https://github.com/koenkk/zigbee-herdsman-converters) to provide device-specific definitions.
|
||||
|
||||
- Pull requests are always created against the [**dev**](https://github.com/Koenkk/zigbee2mqtt/tree/dev) branch.
|
||||
- Easiest way to start developing Zigbee2MQTT is by setting up a development environment (aka bare-metal installation). You can follow this [guide](https://www.zigbee2mqtt.io/guide/installation/01_linux.html) to do this.
|
||||
- You can run the tests locally by executing `pnpm test`. Zigbee2MQTT enforces 100% code coverage, in case you add new code check if your code is covered by running `pnpm run test:coverage`. The coverage report can be found under `coverage/lcov-report/index.html`. Linting is also enforced and can be run with `pnpm run eslint`.
|
||||
- When you want to add support for a new device no changes to Zigbee2MQTT have to be made, only to zigbee-herdsman-converters. You can find a guide for it [here](https://www.zigbee2mqtt.io/advanced/support-new-devices/01_support_new_devices.html).
|
||||
- Easiest way to start developing Zigbee2MQTT is by setting up a development environment (a.k.a. bare-metal installation). You can follow this [guide](https://www.zigbee2mqtt.io/guide/installation/01_linux.html) to do this.
|
||||
- You can run the tests locally by executing `pnpm test`. Zigbee2MQTT enforces 100% code coverage, in case you add new code check if your code is covered by running `pnpm run test:coverage`. The coverage report can be found under `coverage/lcov-report/index.html`.
|
||||
- Linting & formatting is also enforced and can be run with `pnpm run check` (can use `pnpm run check:w` to fix small issues automatically).
|
||||
- If you want to add support for a new device no change to Zigbee2MQTT has to be made, only to zigbee-herdsman-converters. You can find a guide for it [here](https://www.zigbee2mqtt.io/advanced/support-new-devices/01_support_new_devices.html).
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.10/schema.json",
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.16/schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
|
||||
+25
-17
@@ -50,7 +50,6 @@ export class Controller {
|
||||
this.state = new State(this.eventBus, this.zigbee);
|
||||
this.restartCallback = restartCallback;
|
||||
this.exitCallback = exitCallback;
|
||||
|
||||
// Initialize extensions.
|
||||
this.extensionArgs = [
|
||||
this.zigbee,
|
||||
@@ -62,22 +61,29 @@ export class Controller {
|
||||
this.restartCallback,
|
||||
this.addExtension,
|
||||
];
|
||||
this.extensions = new Set();
|
||||
|
||||
this.extensions = new Set([
|
||||
new ExtensionExternalConverters(...this.extensionArgs),
|
||||
new ExtensionOnEvent(...this.extensionArgs),
|
||||
new ExtensionBridge(...this.extensionArgs),
|
||||
new ExtensionPublish(...this.extensionArgs),
|
||||
new ExtensionReceive(...this.extensionArgs),
|
||||
new ExtensionConfigure(...this.extensionArgs),
|
||||
new ExtensionNetworkMap(...this.extensionArgs),
|
||||
new ExtensionGroups(...this.extensionArgs),
|
||||
new ExtensionBind(...this.extensionArgs),
|
||||
new ExtensionOTAUpdate(...this.extensionArgs),
|
||||
new ExtensionExternalExtensions(...this.extensionArgs),
|
||||
new ExtensionAvailability(...this.extensionArgs),
|
||||
new ExtensionHealth(...this.extensionArgs),
|
||||
]);
|
||||
if (settings.get().advanced.enable_external_js) {
|
||||
this.extensions.add(new ExtensionExternalConverters(...this.extensionArgs));
|
||||
} else {
|
||||
logger.info("External JS (converters/extensions) is disabled");
|
||||
}
|
||||
|
||||
this.extensions.add(new ExtensionOnEvent(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionBridge(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionPublish(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionReceive(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionConfigure(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionNetworkMap(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionGroups(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionBind(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionOTAUpdate(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionAvailability(...this.extensionArgs));
|
||||
this.extensions.add(new ExtensionHealth(...this.extensionArgs));
|
||||
|
||||
if (settings.get().advanced.enable_external_js) {
|
||||
this.extensions.add(new ExtensionExternalExtensions(...this.extensionArgs));
|
||||
}
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
@@ -247,10 +253,12 @@ export class Controller {
|
||||
}
|
||||
|
||||
const existingExtension = this.getExtension(name);
|
||||
|
||||
if (existingExtension) {
|
||||
await this.removeExtension(existingExtension);
|
||||
}
|
||||
await this.extensions.add(extension);
|
||||
|
||||
this.extensions.add(extension);
|
||||
} else {
|
||||
switch (name) {
|
||||
case "Frontend": {
|
||||
|
||||
@@ -176,7 +176,13 @@ export default abstract class ExternalJSExtension<M> extends Extension {
|
||||
}
|
||||
|
||||
const {name, code} = message;
|
||||
|
||||
if (!name.endsWith(".mjs") && !name.endsWith(".js") && !name.endsWith(".cjs")) {
|
||||
return utils.getResponse(message, {}, "JavaScript file must have '.mjs', '.js' or '.cjs' extension");
|
||||
}
|
||||
|
||||
const filePath = this.getFilePath(name, true);
|
||||
|
||||
try {
|
||||
fs.writeFileSync(filePath, code, "utf8");
|
||||
this.symlinkNodeModulesIfNecessary();
|
||||
|
||||
@@ -5,7 +5,6 @@ import {createServer} from "node:http";
|
||||
import {createServer as createSecureServer} from "node:https";
|
||||
import type {Socket} from "node:net";
|
||||
import {posix} from "node:path";
|
||||
import {parse} from "node:url";
|
||||
import bind from "bind-decorator";
|
||||
import expressStaticGzip from "express-static-gzip";
|
||||
import finalhandler from "finalhandler";
|
||||
@@ -157,10 +156,10 @@ export class Frontend extends Extension {
|
||||
@bind private onUpgrade(request: IncomingMessage, socket: Socket, head: Buffer): void {
|
||||
this.wss.handleUpgrade(request, socket, head, (ws) => {
|
||||
// biome-ignore lint/style/noNonNullAssertion: `Only valid for request obtained from Server`
|
||||
const {query} = parse(request.url!, true);
|
||||
const {searchParams} = new URL(request.url!, "http://localhost"); // dummy base, may not be absolute
|
||||
const authToken = settings.get().frontend.auth_token;
|
||||
|
||||
if (!authToken || authToken === query.token) {
|
||||
if (!authToken || authToken === searchParams.get("token")) {
|
||||
this.wss.emit("connection", ws, request);
|
||||
} else {
|
||||
ws.close(4401, "Unauthorized");
|
||||
|
||||
@@ -590,7 +590,7 @@ export class HomeAssistant extends Extension {
|
||||
name: endpointName ? utils.capitalize(endpointName) : null,
|
||||
payload_off: state.value_off,
|
||||
payload_on: state.value_on,
|
||||
value_template: `{{ value_json.${property} }}`,
|
||||
value_template: `{{ value_json["${property}"] }}`,
|
||||
command_topic: true,
|
||||
command_topic_prefix: endpointName,
|
||||
},
|
||||
@@ -636,7 +636,7 @@ export class HomeAssistant extends Extension {
|
||||
max_temp: setpoint.value_max.toString(),
|
||||
// Temperature
|
||||
current_temperature_topic: true,
|
||||
current_temperature_template: `{{ value_json.${temperature.property} }}`,
|
||||
current_temperature_template: `{{ value_json["${temperature.property}"] }}`,
|
||||
command_topic_prefix: endpointName,
|
||||
},
|
||||
};
|
||||
@@ -650,7 +650,7 @@ export class HomeAssistant extends Extension {
|
||||
mode.values.splice(mode.values.indexOf("sleep"), 1);
|
||||
}
|
||||
discoveryEntry.discovery_payload.mode_state_topic = true;
|
||||
discoveryEntry.discovery_payload.mode_state_template = `{{ value_json.${mode.property} }}`;
|
||||
discoveryEntry.discovery_payload.mode_state_template = `{{ value_json["${mode.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.modes = mode.values;
|
||||
discoveryEntry.discovery_payload.mode_command_topic = true;
|
||||
}
|
||||
@@ -659,20 +659,20 @@ export class HomeAssistant extends Extension {
|
||||
if (state) {
|
||||
discoveryEntry.mockProperties.push({property: state.property, value: null});
|
||||
discoveryEntry.discovery_payload.action_topic = true;
|
||||
discoveryEntry.discovery_payload.action_template = `{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json.${state.property}] }}`;
|
||||
discoveryEntry.discovery_payload.action_template = `{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json["${state.property}"]] }}`;
|
||||
}
|
||||
|
||||
const coolingSetpoint = (firstExpose as zhc.Climate).features.find((f) => f.name === "occupied_cooling_setpoint");
|
||||
if (coolingSetpoint) {
|
||||
discoveryEntry.discovery_payload.temperature_low_command_topic = setpoint.name;
|
||||
discoveryEntry.discovery_payload.temperature_low_state_template = `{{ value_json.${setpoint.property} }}`;
|
||||
discoveryEntry.discovery_payload.temperature_low_state_template = `{{ value_json["${setpoint.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.temperature_low_state_topic = true;
|
||||
discoveryEntry.discovery_payload.temperature_high_command_topic = coolingSetpoint.name;
|
||||
discoveryEntry.discovery_payload.temperature_high_state_template = `{{ value_json.${coolingSetpoint.property} }}`;
|
||||
discoveryEntry.discovery_payload.temperature_high_state_template = `{{ value_json["${coolingSetpoint.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.temperature_high_state_topic = true;
|
||||
} else {
|
||||
discoveryEntry.discovery_payload.temperature_command_topic = setpoint.name;
|
||||
discoveryEntry.discovery_payload.temperature_state_template = `{{ value_json.${setpoint.property} }}`;
|
||||
discoveryEntry.discovery_payload.temperature_state_template = `{{ value_json["${setpoint.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.temperature_state_topic = true;
|
||||
}
|
||||
|
||||
@@ -680,7 +680,7 @@ export class HomeAssistant extends Extension {
|
||||
if (fanMode) {
|
||||
discoveryEntry.discovery_payload.fan_modes = fanMode.values;
|
||||
discoveryEntry.discovery_payload.fan_mode_command_topic = true;
|
||||
discoveryEntry.discovery_payload.fan_mode_state_template = `{{ value_json.${fanMode.property} }}`;
|
||||
discoveryEntry.discovery_payload.fan_mode_state_template = `{{ value_json["${fanMode.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.fan_mode_state_topic = true;
|
||||
}
|
||||
|
||||
@@ -688,7 +688,7 @@ export class HomeAssistant extends Extension {
|
||||
if (swingMode) {
|
||||
discoveryEntry.discovery_payload.swing_modes = swingMode.values;
|
||||
discoveryEntry.discovery_payload.swing_mode_command_topic = true;
|
||||
discoveryEntry.discovery_payload.swing_mode_state_template = `{{ value_json.${swingMode.property} }}`;
|
||||
discoveryEntry.discovery_payload.swing_mode_state_template = `{{ value_json["${swingMode.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.swing_mode_state_topic = true;
|
||||
}
|
||||
|
||||
@@ -696,7 +696,7 @@ export class HomeAssistant extends Extension {
|
||||
if (preset) {
|
||||
discoveryEntry.discovery_payload.preset_modes = preset.values;
|
||||
discoveryEntry.discovery_payload.preset_mode_command_topic = "preset";
|
||||
discoveryEntry.discovery_payload.preset_mode_value_template = `{{ value_json.${preset.property} }}`;
|
||||
discoveryEntry.discovery_payload.preset_mode_value_template = `{{ value_json["${preset.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.preset_mode_state_topic = true;
|
||||
}
|
||||
|
||||
@@ -710,7 +710,7 @@ export class HomeAssistant extends Extension {
|
||||
mockProperties: [{property: tempCalibration.property, value: null}],
|
||||
discovery_payload: {
|
||||
name: endpointName ? `${tempCalibration.label} ${endpointName}` : tempCalibration.label,
|
||||
value_template: `{{ value_json.${tempCalibration.property} }}`,
|
||||
value_template: `{{ value_json["${tempCalibration.property}"] }}`,
|
||||
command_topic: true,
|
||||
command_topic_prefix: endpointName,
|
||||
command_topic_postfix: tempCalibration.property,
|
||||
@@ -735,7 +735,7 @@ export class HomeAssistant extends Extension {
|
||||
mockProperties: [{property: piHeatingDemand.property, value: null}],
|
||||
discovery_payload: {
|
||||
name: endpointName ? `${piHeatingDemand.label} ${endpointName}` : piHeatingDemand.label,
|
||||
value_template: `{{ value_json.${piHeatingDemand.property} }}`,
|
||||
value_template: `{{ value_json["${piHeatingDemand.property}"] }}`,
|
||||
...(piHeatingDemand.unit && {unit_of_measurement: piHeatingDemand.unit}),
|
||||
icon: "mdi:radiator",
|
||||
},
|
||||
@@ -766,7 +766,7 @@ export class HomeAssistant extends Extension {
|
||||
mockProperties: [{property: piCoolingDemand.property, value: null}],
|
||||
discovery_payload: {
|
||||
name: endpointName ? /* v8 ignore next */ `${piCoolingDemand.label} ${endpointName}` : piCoolingDemand.label,
|
||||
value_template: `{{ value_json.${piCoolingDemand.property} }}`,
|
||||
value_template: `{{ value_json["${piCoolingDemand.property}"] }}`,
|
||||
...(piCoolingDemand.unit && {unit_of_measurement: piCoolingDemand.unit}),
|
||||
entity_category: "diagnostic",
|
||||
icon: "mdi:air-conditioner",
|
||||
@@ -788,7 +788,7 @@ export class HomeAssistant extends Extension {
|
||||
mockProperties: [{property: localTemperature.property, value: null}],
|
||||
discovery_payload: {
|
||||
name: endpointName ? `${localTemperature.label} ${endpointName}` : localTemperature.label,
|
||||
value_template: `{{ value_json.${localTemperature.property} }}`,
|
||||
value_template: `{{ value_json["${localTemperature.property}"] }}`,
|
||||
...(localTemperature.unit && {unit_of_measurement: localTemperature.unit}),
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
@@ -800,7 +800,7 @@ export class HomeAssistant extends Extension {
|
||||
|
||||
const currentHumidity = allExposes?.filter(isNumericExpose).find((e) => e.name === "humidity" && e.access & ACCESS_STATE);
|
||||
if (currentHumidity) {
|
||||
discoveryEntry.discovery_payload.current_humidity_template = `{{ value_json.${currentHumidity.property} }}`;
|
||||
discoveryEntry.discovery_payload.current_humidity_template = `{{ value_json["${currentHumidity.property}"] }}`;
|
||||
discoveryEntry.discovery_payload.current_humidity_topic = true;
|
||||
}
|
||||
|
||||
@@ -820,7 +820,7 @@ export class HomeAssistant extends Extension {
|
||||
name: endpointName ? utils.capitalize(endpointName) : null,
|
||||
command_topic_prefix: endpointName,
|
||||
command_topic: true,
|
||||
value_template: `{{ value_json.${state.property} }}`,
|
||||
value_template: `{{ value_json["${state.property}"] }}`,
|
||||
state_locked: state.value_on,
|
||||
state_unlocked: state.value_off,
|
||||
/* v8 ignore next */
|
||||
@@ -863,7 +863,7 @@ export class HomeAssistant extends Extension {
|
||||
// The movement direction is calculated (assumed) in this case.
|
||||
if (running) {
|
||||
assert(position, `Cover must have 'position' when it has 'running'`);
|
||||
discoveryEntry.discovery_payload.value_template = `{% if "${featurePropertyWithoutEndpoint(running)}" in value_json and value_json.${featurePropertyWithoutEndpoint(running)} %} {% if value_json.${featurePropertyWithoutEndpoint(position)} > 0 %} closing {% else %} opening {% endif %} {% else %} stopped {% endif %}`;
|
||||
discoveryEntry.discovery_payload.value_template = `{% if "${featurePropertyWithoutEndpoint(running)}" in value_json and value_json["${featurePropertyWithoutEndpoint(running)}"] %} {% if value_json["${featurePropertyWithoutEndpoint(position)}"] > 0 %} closing {% else %} opening {% endif %} {% else %} stopped {% endif %}`;
|
||||
}
|
||||
|
||||
// If curtains have `motor_state` or `moving` property, lookup for possible
|
||||
@@ -877,13 +877,13 @@ export class HomeAssistant extends Extension {
|
||||
discoveryEntry.discovery_payload.state_opening = openingState;
|
||||
discoveryEntry.discovery_payload.state_closing = closingState;
|
||||
discoveryEntry.discovery_payload.state_stopped = stoppedState;
|
||||
discoveryEntry.discovery_payload.value_template = `{% if "${featurePropertyWithoutEndpoint(motorState)}" in value_json and value_json.${featurePropertyWithoutEndpoint(motorState)} %} {{ value_json.${featurePropertyWithoutEndpoint(motorState)} }} {% else %} ${stoppedState} {% endif %}`;
|
||||
discoveryEntry.discovery_payload.value_template = `{% if "${featurePropertyWithoutEndpoint(motorState)}" in value_json and value_json["${featurePropertyWithoutEndpoint(motorState)}"] %} {{ value_json["${featurePropertyWithoutEndpoint(motorState)}"] }} {% else %} ${stoppedState} {% endif %}`;
|
||||
}
|
||||
}
|
||||
|
||||
// If curtains do not have `running`, `motor_state` or `moving` properties.
|
||||
if (!discoveryEntry.discovery_payload.value_template) {
|
||||
discoveryEntry.discovery_payload.value_template = `{{ value_json.${featurePropertyWithoutEndpoint(state)} }}`;
|
||||
discoveryEntry.discovery_payload.value_template = `{{ value_json["${featurePropertyWithoutEndpoint(state)}"] }}`;
|
||||
discoveryEntry.discovery_payload.state_open = "OPEN";
|
||||
discoveryEntry.discovery_payload.state_closed = "CLOSE";
|
||||
discoveryEntry.discovery_payload.state_stopped = "STOP";
|
||||
@@ -898,7 +898,7 @@ export class HomeAssistant extends Extension {
|
||||
if (position) {
|
||||
discoveryEntry.discovery_payload = {
|
||||
...discoveryEntry.discovery_payload,
|
||||
position_template: `{{ value_json.${featurePropertyWithoutEndpoint(position)} }}`,
|
||||
position_template: `{{ value_json["${featurePropertyWithoutEndpoint(position)}"] }}`,
|
||||
set_position_template: `{ "${getProperty(position)}": {{ position }} }`,
|
||||
set_position_topic: true,
|
||||
position_topic: true,
|
||||
@@ -910,7 +910,7 @@ export class HomeAssistant extends Extension {
|
||||
...discoveryEntry.discovery_payload,
|
||||
tilt_command_topic: true,
|
||||
tilt_status_topic: true,
|
||||
tilt_status_template: `{{ value_json.${featurePropertyWithoutEndpoint(tilt)} }}`,
|
||||
tilt_status_template: `{{ value_json["${featurePropertyWithoutEndpoint(tilt)}"] }}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -975,14 +975,14 @@ export class HomeAssistant extends Extension {
|
||||
|
||||
discoveryEntry.discovery_payload.percentage_state_topic = true;
|
||||
discoveryEntry.discovery_payload.percentage_command_topic = "fan_mode";
|
||||
discoveryEntry.discovery_payload.percentage_value_template = `{{ {${percentValues}}[value_json.${modeEmulatedSpeed.property}] | default('None') }}`;
|
||||
discoveryEntry.discovery_payload.percentage_value_template = `{{ {${percentValues}}[value_json["${modeEmulatedSpeed.property}"]] | default('None') }}`;
|
||||
discoveryEntry.discovery_payload.percentage_command_template = `{{ {${percentCommands}}[value] | default('') }}`;
|
||||
discoveryEntry.discovery_payload.speed_range_min = 1;
|
||||
discoveryEntry.discovery_payload.speed_range_max = speeds.length - 1;
|
||||
assert(presets.length !== 0);
|
||||
discoveryEntry.discovery_payload.preset_mode_state_topic = true;
|
||||
discoveryEntry.discovery_payload.preset_mode_command_topic = "fan_mode";
|
||||
discoveryEntry.discovery_payload.preset_mode_value_template = `{{ value_json.${modeEmulatedSpeed.property} if value_json.${modeEmulatedSpeed.property} in [${presetList}] else 'None' | default('None') }}`;
|
||||
discoveryEntry.discovery_payload.preset_mode_value_template = `{{ value_json["${modeEmulatedSpeed.property}"] if value_json["${modeEmulatedSpeed.property}"] in [${presetList}] else 'None' | default('None') }}`;
|
||||
discoveryEntry.discovery_payload.preset_modes = presets;
|
||||
|
||||
// Emulate state based on mode
|
||||
@@ -991,7 +991,7 @@ export class HomeAssistant extends Extension {
|
||||
} else if (nativeSpeed) {
|
||||
discoveryEntry.discovery_payload.percentage_state_topic = true;
|
||||
discoveryEntry.discovery_payload.percentage_command_topic = "speed";
|
||||
discoveryEntry.discovery_payload.percentage_value_template = `{{ value_json.${nativeSpeed.property} | default('None') }}`;
|
||||
discoveryEntry.discovery_payload.percentage_value_template = `{{ value_json["${nativeSpeed.property}"] | default('None') }}`;
|
||||
discoveryEntry.discovery_payload.percentage_command_template = `{{ value | default('') }}`;
|
||||
discoveryEntry.discovery_payload.speed_range_min = nativeSpeed.value_min;
|
||||
discoveryEntry.discovery_payload.speed_range_max = nativeSpeed.value_max;
|
||||
@@ -1021,8 +1021,8 @@ export class HomeAssistant extends Extension {
|
||||
name: endpointName ? /* v8 ignore next */ `${firstExpose.label} ${endpointName}` : firstExpose.label,
|
||||
value_template:
|
||||
typeof firstExpose.value_on === "boolean"
|
||||
? `{% if value_json.${firstExpose.property} %}true{% else %}false{% endif %}`
|
||||
: `{{ value_json.${firstExpose.property} }}`,
|
||||
? `{% if value_json["${firstExpose.property}"] %}true{% else %}false{% endif %}`
|
||||
: `{{ value_json["${firstExpose.property}"] }}`,
|
||||
payload_on: firstExpose.value_on.toString(),
|
||||
payload_off: firstExpose.value_off.toString(),
|
||||
command_topic: true,
|
||||
@@ -1040,7 +1040,7 @@ export class HomeAssistant extends Extension {
|
||||
mockProperties: [{property: firstExpose.property, value: null}],
|
||||
discovery_payload: {
|
||||
name: endpointName ? /* v8 ignore next */ `${firstExpose.label} ${endpointName}` : firstExpose.label,
|
||||
value_template: `{{ value_json.${firstExpose.property} }}`,
|
||||
value_template: `{{ value_json["${firstExpose.property}"] }}`,
|
||||
payload_on: firstExpose.value_on,
|
||||
payload_off: firstExpose.value_off,
|
||||
...(BINARY_DISCOVERY_LOOKUP[firstExpose.name] || {}),
|
||||
@@ -1065,7 +1065,7 @@ export class HomeAssistant extends Extension {
|
||||
mockProperties: [{property: firstExpose.property, value: null}],
|
||||
discovery_payload: {
|
||||
name: endpointName ? `${firstExpose.label} ${endpointName}` : firstExpose.label,
|
||||
value_template: `{{ value_json.${firstExpose.property} }}`,
|
||||
value_template: `{{ value_json["${firstExpose.property}"] }}`,
|
||||
command_topic: true,
|
||||
command_topic_prefix: endpointName,
|
||||
command_topic_postfix: firstExpose.property,
|
||||
@@ -1116,7 +1116,7 @@ export class HomeAssistant extends Extension {
|
||||
mockProperties: [{property: firstExpose.property, value: null}],
|
||||
discovery_payload: {
|
||||
name: endpointName ? `${firstExpose.label} ${endpointName}` : firstExpose.label,
|
||||
value_template: `{{ value_json.${firstExpose.property} }}`,
|
||||
value_template: `{{ value_json["${firstExpose.property}"] }}`,
|
||||
enabled_by_default: !allowsSet,
|
||||
...(firstExpose.unit && {unit_of_measurement: firstExpose.unit}),
|
||||
...NUMERIC_DISCOVERY_LOOKUP[key],
|
||||
@@ -1170,7 +1170,7 @@ export class HomeAssistant extends Extension {
|
||||
}
|
||||
}
|
||||
|
||||
const valueTemplate = firstExpose.access & ACCESS_STATE ? `{{ value_json.${firstExpose.property} }}` : undefined;
|
||||
const valueTemplate = firstExpose.access & ACCESS_STATE ? `{{ value_json["${firstExpose.property}"] }}` : undefined;
|
||||
|
||||
/**
|
||||
* If enum has only one item and has SET access then expose as BUTTON entity.
|
||||
@@ -1299,7 +1299,7 @@ export class HomeAssistant extends Extension {
|
||||
discovery_payload: {
|
||||
name: endpointName ? `${firstExposeTyped.label} ${endpointName}` : firstExposeTyped.label,
|
||||
state_topic: firstExposeTyped.access & ACCESS_STATE,
|
||||
value_template: `{{ value_json.${firstExposeTyped.property} }}`,
|
||||
value_template: `{{ value_json["${firstExposeTyped.property}"] }}`,
|
||||
command_topic_prefix: endpointName,
|
||||
command_topic: true,
|
||||
command_topic_postfix: firstExposeTyped.property,
|
||||
@@ -1317,7 +1317,7 @@ export class HomeAssistant extends Extension {
|
||||
name: endpointName ? `${firstExposeTyped.label} ${endpointName}` : firstExposeTyped.label,
|
||||
// Truncate text if it's too long
|
||||
// https://github.com/Koenkk/zigbee2mqtt/issues/23199
|
||||
value_template: `{{ value_json.${firstExposeTyped.property} | default('',True) | string | truncate(254, True, '', 0) }}`,
|
||||
value_template: `{{ value_json["${firstExposeTyped.property}"] | default('',True) | string | truncate(254, True, '', 0) }}`,
|
||||
...LIST_DISCOVERY_LOOKUP[firstExposeTyped.name],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -215,6 +215,8 @@ export interface Zigbee2MQTTSettings {
|
||||
timestamp_format: string;
|
||||
output: "json" | "attribute" | "attribute_and_json";
|
||||
transmit_power?: number;
|
||||
/** 3.0: default to false (JSON schema & settings `defaults`) */
|
||||
enable_external_js: boolean;
|
||||
};
|
||||
health: {
|
||||
/** in minutes */
|
||||
|
||||
@@ -800,7 +800,7 @@
|
||||
"requiresRestart": true,
|
||||
"minimum": -128,
|
||||
"maximum": 127,
|
||||
"description": "Transmit power of adapter, only available for Z-Stack (CC253*/CC2652/CC1352) adapters, CC2652 = 5dbm, CC1352 max is = 20dbm (5dbm default)"
|
||||
"description": "Transmit power of adapter, in dBm (max is often 20, refer to chip specifications)"
|
||||
},
|
||||
"output": {
|
||||
"type": "string",
|
||||
@@ -808,6 +808,13 @@
|
||||
"title": "MQTT output type",
|
||||
"description": "Examples when 'state' of a device is published json: topic: 'zigbee2mqtt/my_bulb' payload '{\"state\": \"ON\"}' attribute: topic 'zigbee2mqtt/my_bulb/state' payload 'ON' attribute_and_json: both json and attribute (see above)",
|
||||
"default": "json"
|
||||
},
|
||||
"enable_external_js": {
|
||||
"type": "boolean",
|
||||
"title": "Enable external JS",
|
||||
"description": "Enable external JavaScript (extensions and converters) that can execute arbitrary user-provided code. WARNING: If unused, it is advised to disable this.",
|
||||
"default": true,
|
||||
"requiresRestart": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -848,7 +855,8 @@
|
||||
"retain": {
|
||||
"type": "boolean",
|
||||
"title": "Retain",
|
||||
"description": "Retain MQTT messages of this device"
|
||||
"description": "Retain MQTT messages of this device",
|
||||
"default": false
|
||||
},
|
||||
"disabled": {
|
||||
"type": "boolean",
|
||||
@@ -953,10 +961,16 @@
|
||||
"type": "string"
|
||||
},
|
||||
"retain": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"title": "Retain",
|
||||
"description": "Retain MQTT messages of this group",
|
||||
"default": false
|
||||
},
|
||||
"optimistic": {
|
||||
"type": "boolean"
|
||||
"type": "boolean",
|
||||
"title": "Optimistic",
|
||||
"description": "Publish the expected state of group members after set",
|
||||
"default": true
|
||||
},
|
||||
"qos": {
|
||||
"type": ["number"],
|
||||
|
||||
@@ -113,6 +113,7 @@ export const defaults = {
|
||||
network_key: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
|
||||
timestamp_format: "YYYY-MM-DD HH:mm:ss",
|
||||
output: "json",
|
||||
enable_external_js: true,
|
||||
},
|
||||
health: {
|
||||
interval: 10,
|
||||
@@ -167,6 +168,7 @@ export function writeMinimalDefaults(): void {
|
||||
network_key: "GENERATE",
|
||||
pan_id: "GENERATE",
|
||||
ext_pan_id: "GENERATE",
|
||||
enable_external_js: false,
|
||||
},
|
||||
frontend: {
|
||||
enabled: defaults.frontend.enabled,
|
||||
|
||||
+11
-11
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "zigbee2mqtt",
|
||||
"version": "2.9.2-dev",
|
||||
"version": "2.11.0",
|
||||
"description": "Zigbee to MQTT bridge using Zigbee-herdsman",
|
||||
"main": "index.js",
|
||||
"types": "dist/types/api.d.ts",
|
||||
@@ -42,10 +42,10 @@
|
||||
},
|
||||
"homepage": "https://koenkk.github.io/zigbee2mqtt",
|
||||
"dependencies": {
|
||||
"ajv": "^8.18.0",
|
||||
"ajv": "^8.20.0",
|
||||
"bind-decorator": "^1.0.11",
|
||||
"debounce": "^3.0.0",
|
||||
"express-static-gzip": "^3.0.0",
|
||||
"express-static-gzip": "^3.0.1",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"finalhandler": "^2.1.1",
|
||||
"humanize-duration": "^3.33.2",
|
||||
@@ -55,30 +55,30 @@
|
||||
"mqtt": "^5.15.1",
|
||||
"object-assign-deep": "^0.4.0",
|
||||
"rimraf": "^6.1.3",
|
||||
"semver": "^7.7.4",
|
||||
"semver": "^7.8.1",
|
||||
"source-map-support": "^0.5.21",
|
||||
"throttleit": "^2.1.0",
|
||||
"winston": "^3.19.0",
|
||||
"winston-syslog": "^2.7.1",
|
||||
"winston-transport": "^4.9.0",
|
||||
"ws": "^8.20.0",
|
||||
"zigbee-herdsman": "10.0.7",
|
||||
"zigbee-herdsman-converters": "26.39.1",
|
||||
"ws": "^8.21.0",
|
||||
"zigbee-herdsman": "10.1.0",
|
||||
"zigbee-herdsman-converters": "26.61.1",
|
||||
"zigbee2mqtt-frontend": "0.9.21",
|
||||
"zigbee2mqtt-windfront": "2.11.1"
|
||||
"zigbee2mqtt-windfront": "2.11.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.12",
|
||||
"@biomejs/biome": "^2.4.16",
|
||||
"@types/finalhandler": "^1.2.3",
|
||||
"@types/humanize-duration": "^3.27.4",
|
||||
"@types/js-yaml": "^4.0.9",
|
||||
"@types/node": "^24.12.2",
|
||||
"@types/node": "^24.12.4",
|
||||
"@types/object-assign-deep": "^0.4.3",
|
||||
"@types/readable-stream": "4.0.23",
|
||||
"@types/serve-static": "^2.2.0",
|
||||
"@types/ws": "8.18.1",
|
||||
"@vitest/coverage-v8": "^3.1.1",
|
||||
"tmp": "^0.2.5",
|
||||
"tmp": "^0.2.7",
|
||||
"typescript": "^6.0.3",
|
||||
"vitest": "^3.1.1"
|
||||
},
|
||||
|
||||
Generated
+137
-156
@@ -5,15 +5,15 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
overrides:
|
||||
zigbee-herdsman: 10.0.7
|
||||
zigbee-herdsman: 10.1.0
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
ajv:
|
||||
specifier: ^8.18.0
|
||||
version: 8.18.0
|
||||
specifier: ^8.20.0
|
||||
version: 8.20.0
|
||||
bind-decorator:
|
||||
specifier: ^1.0.11
|
||||
version: 1.0.11
|
||||
@@ -21,8 +21,8 @@ importers:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
express-static-gzip:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.1
|
||||
fast-deep-equal:
|
||||
specifier: ^3.1.3
|
||||
version: 3.1.3
|
||||
@@ -51,8 +51,8 @@ importers:
|
||||
specifier: ^6.1.3
|
||||
version: 6.1.3
|
||||
semver:
|
||||
specifier: ^7.7.4
|
||||
version: 7.7.4
|
||||
specifier: ^7.8.1
|
||||
version: 7.8.1
|
||||
source-map-support:
|
||||
specifier: ^0.5.21
|
||||
version: 0.5.21
|
||||
@@ -69,24 +69,24 @@ importers:
|
||||
specifier: ^4.9.0
|
||||
version: 4.9.0
|
||||
ws:
|
||||
specifier: ^8.20.0
|
||||
version: 8.20.0
|
||||
specifier: ^8.21.0
|
||||
version: 8.21.0
|
||||
zigbee-herdsman:
|
||||
specifier: 10.0.7
|
||||
version: 10.0.7
|
||||
specifier: 10.1.0
|
||||
version: 10.1.0
|
||||
zigbee-herdsman-converters:
|
||||
specifier: 26.39.1
|
||||
version: 26.39.1
|
||||
specifier: 26.61.1
|
||||
version: 26.61.1
|
||||
zigbee2mqtt-frontend:
|
||||
specifier: 0.9.21
|
||||
version: 0.9.21
|
||||
zigbee2mqtt-windfront:
|
||||
specifier: 2.11.1
|
||||
version: 2.11.1
|
||||
specifier: 2.11.3
|
||||
version: 2.11.3
|
||||
devDependencies:
|
||||
'@biomejs/biome':
|
||||
specifier: ^2.4.12
|
||||
version: 2.4.12
|
||||
specifier: ^2.4.16
|
||||
version: 2.4.16
|
||||
'@types/finalhandler':
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.4
|
||||
@@ -97,8 +97,8 @@ importers:
|
||||
specifier: ^4.0.9
|
||||
version: 4.0.9
|
||||
'@types/node':
|
||||
specifier: ^24.12.2
|
||||
version: 24.12.2
|
||||
specifier: ^24.12.4
|
||||
version: 24.12.4
|
||||
'@types/object-assign-deep':
|
||||
specifier: ^0.4.3
|
||||
version: 0.4.3
|
||||
@@ -113,16 +113,16 @@ importers:
|
||||
version: 8.18.1
|
||||
'@vitest/coverage-v8':
|
||||
specifier: ^3.1.1
|
||||
version: 3.2.4(vitest@3.2.4(@types/node@24.12.2))
|
||||
version: 3.2.4(vitest@3.2.4(@types/node@24.12.4))
|
||||
tmp:
|
||||
specifier: ^0.2.5
|
||||
version: 0.2.5
|
||||
specifier: ^0.2.7
|
||||
version: 0.2.7
|
||||
typescript:
|
||||
specifier: ^6.0.3
|
||||
version: 6.0.3
|
||||
vitest:
|
||||
specifier: ^3.1.1
|
||||
version: 3.2.4(@types/node@24.12.2)
|
||||
version: 3.2.4(@types/node@24.12.4)
|
||||
optionalDependencies:
|
||||
unix-dgram:
|
||||
specifier: ^2.0.7
|
||||
@@ -159,55 +159,55 @@ packages:
|
||||
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
'@biomejs/biome@2.4.12':
|
||||
resolution: {integrity: sha512-Rro7adQl3NLq/zJCIL98eElXKI8eEiBtoeu5TbXF/U3qbjuSc7Jb5rjUbeHHcquDWeSf3HnGP7XI5qGrlRk/pA==}
|
||||
'@biomejs/biome@2.4.16':
|
||||
resolution: {integrity: sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
hasBin: true
|
||||
|
||||
'@biomejs/cli-darwin-arm64@2.4.12':
|
||||
resolution: {integrity: sha512-BnMU4Pc3ciEVteVpZ0BK33MLr7X57F5w1dwDLDn+/iy/yTrA4Q/N2yftidFtsA4vrDh0FMXDpacNV/Tl3fbmng==}
|
||||
'@biomejs/cli-darwin-arm64@2.4.16':
|
||||
resolution: {integrity: sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@biomejs/cli-darwin-x64@2.4.12':
|
||||
resolution: {integrity: sha512-x9uJ0bI1rJsWICp3VH8w/5PnAVD3A7SqzDpbrfoUQX1QyWrK5jSU4fRLo/wSgGeplCivbxBRKmt5Xq4/nWvq8A==}
|
||||
'@biomejs/cli-darwin-x64@2.4.16':
|
||||
resolution: {integrity: sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@biomejs/cli-linux-arm64-musl@2.4.12':
|
||||
resolution: {integrity: sha512-FhfpkAAlKL6kwvcVap0Hgp4AhZmtd3YImg0kK1jd7C/aSoh4SfsB2f++yG1rU0lr8Y5MCFJrcSkmssiL9Xnnig==}
|
||||
'@biomejs/cli-linux-arm64-musl@2.4.16':
|
||||
resolution: {integrity: sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@biomejs/cli-linux-arm64@2.4.12':
|
||||
resolution: {integrity: sha512-tOwuCuZZtKi1jVzbk/5nXmIsziOB6yqN8c9r9QM0EJYPU6DpQWf11uBOSCfFKKM4H3d9ZoarvlgMfbcuD051Pw==}
|
||||
'@biomejs/cli-linux-arm64@2.4.16':
|
||||
resolution: {integrity: sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@biomejs/cli-linux-x64-musl@2.4.12':
|
||||
resolution: {integrity: sha512-dwTIgZrGutzhkQCuvHynCkyW6hJxUuyZqKKO0YNfaS2GUoRO+tOvxXZqZB6SkWAOdfZTzwaw8IEdUnIkHKHoew==}
|
||||
'@biomejs/cli-linux-x64-musl@2.4.16':
|
||||
resolution: {integrity: sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@biomejs/cli-linux-x64@2.4.12':
|
||||
resolution: {integrity: sha512-8pFeAnLU9QdW9jCIslB/v82bI0lhBmz2ZAKc8pVMFPO0t0wAHsoEkrUQUbMkIorTRIjbqyNZHA3lEXavsPWYSw==}
|
||||
'@biomejs/cli-linux-x64@2.4.16':
|
||||
resolution: {integrity: sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@biomejs/cli-win32-arm64@2.4.12':
|
||||
resolution: {integrity: sha512-B0DLnx0vA9ya/3v7XyCaP+/lCpnbWbMOfUFFve+xb5OxyYvdHaS55YsSddr228Y+JAFk58agCuZTsqNiw2a6ig==}
|
||||
'@biomejs/cli-win32-arm64@2.4.16':
|
||||
resolution: {integrity: sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@biomejs/cli-win32-x64@2.4.12':
|
||||
resolution: {integrity: sha512-yMckRzTyZ83hkk8iDFWswqSdU8tvZxspJKnYNh7JZr/zhZNOlzH13k4ecboU6MurKExCe2HUkH75pGI/O2JwGA==}
|
||||
'@biomejs/cli-win32-x64@2.4.16':
|
||||
resolution: {integrity: sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -553,8 +553,8 @@ packages:
|
||||
'@types/js-yaml@4.0.9':
|
||||
resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==}
|
||||
|
||||
'@types/node@24.12.2':
|
||||
resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==}
|
||||
'@types/node@24.12.4':
|
||||
resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==}
|
||||
|
||||
'@types/object-assign-deep@0.4.3':
|
||||
resolution: {integrity: sha512-d9Gxaj5j1hzrxJ61EFEg13B4g4FgrT/DYtcDWFXPehR8DF2SUZbVMFtZIs8exkVRiqrqBpdTc/lUUZjncsPpMw==}
|
||||
@@ -613,8 +613,8 @@ packages:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
|
||||
ajv@8.18.0:
|
||||
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
|
||||
ajv@8.20.0:
|
||||
resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
|
||||
|
||||
ansi-regex@5.0.1:
|
||||
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
|
||||
@@ -667,12 +667,12 @@ packages:
|
||||
bonjour-service@1.3.0:
|
||||
resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==}
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
|
||||
brace-expansion@2.1.0:
|
||||
resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==}
|
||||
|
||||
brace-expansion@5.0.2:
|
||||
resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==}
|
||||
engines: {node: 20 || >=22}
|
||||
brace-expansion@5.0.6:
|
||||
resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
|
||||
engines: {node: 18 || 20 || >=22}
|
||||
|
||||
broker-factory@3.1.14:
|
||||
resolution: {integrity: sha512-L45k5HMbPIrMid0nTOZ/UPXG/c0aRuQKVrSDFIb1zOkvfiyHgYmIjc3cSiN1KwQIvRDOtKE0tfb3I9EZ3CmpQQ==}
|
||||
@@ -745,15 +745,6 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.4.1:
|
||||
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -824,8 +815,8 @@ packages:
|
||||
resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
express-static-gzip@3.0.0:
|
||||
resolution: {integrity: sha512-36O10S0asHl3QojOBQQ0ZjXNtElmhgPS6erSUCCZymXkB/CK1mnGqOj4BTJN+FYRDIzVFnzo3wLFCZJvAk6rQQ==}
|
||||
express-static-gzip@3.0.1:
|
||||
resolution: {integrity: sha512-LMeU/3YjFlFUa4vrPX+RoMMRW5mIpF4Iysgs6gX7A59WCY4BzyF3O28mBr4eMlWuW4DU9wVAVuVcfx29ln1N6g==}
|
||||
|
||||
fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
@@ -894,8 +885,8 @@ packages:
|
||||
html-escaper@2.0.2:
|
||||
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
|
||||
|
||||
http-errors@2.0.0:
|
||||
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
|
||||
http-errors@2.0.1:
|
||||
resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
humanize-duration@3.33.2:
|
||||
@@ -1008,9 +999,9 @@ packages:
|
||||
resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@3.0.1:
|
||||
resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
mime-types@3.0.2:
|
||||
resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
minimatch@10.2.0:
|
||||
resolution: {integrity: sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==}
|
||||
@@ -1164,17 +1155,17 @@ packages:
|
||||
safer-buffer@2.1.2:
|
||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||
|
||||
semver@7.7.4:
|
||||
resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==}
|
||||
semver@7.8.1:
|
||||
resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
send@1.2.0:
|
||||
resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==}
|
||||
send@1.2.1:
|
||||
resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
serve-static@2.2.0:
|
||||
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
|
||||
serve-static@2.2.1:
|
||||
resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
setimmediate@1.0.5:
|
||||
@@ -1230,10 +1221,6 @@ packages:
|
||||
stackback@0.0.2:
|
||||
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||
|
||||
statuses@2.0.1:
|
||||
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
statuses@2.0.2:
|
||||
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@@ -1306,8 +1293,8 @@ packages:
|
||||
resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
tmp@0.2.5:
|
||||
resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==}
|
||||
tmp@0.2.7:
|
||||
resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==}
|
||||
engines: {node: '>=14.14'}
|
||||
|
||||
toidentifier@1.0.1:
|
||||
@@ -1460,8 +1447,8 @@ packages:
|
||||
resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
ws@8.20.0:
|
||||
resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==}
|
||||
ws@8.21.0:
|
||||
resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
@@ -1472,12 +1459,12 @@ packages:
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
zigbee-herdsman-converters@26.39.1:
|
||||
resolution: {integrity: sha512-CopzHV9NNwNKypQv5TozRubgpUU+OVDCrzRgGwGRtmsqHmAysxF6QBWjguigRqzs5r/P5dDcigRUlDoDZC/+gA==}
|
||||
zigbee-herdsman-converters@26.61.1:
|
||||
resolution: {integrity: sha512-cCt42o58p0KpdzeUb5zLkldnLI9nIOcOdydkV+XyI7VH95LTjCbW89ax71XV3uRV1rnLHZLeEVXsFzf2U7w8aA==}
|
||||
engines: {node: '>=20.15.0'}
|
||||
|
||||
zigbee-herdsman@10.0.7:
|
||||
resolution: {integrity: sha512-QqKJaJryWf7IUuVNV6Dc1/qNPrs2dJANPJhRTG74nZBAsyIDn/vSyCP7g19fuEM7Cphr/0ZgCJZkHP2wKvNPMw==}
|
||||
zigbee-herdsman@10.1.0:
|
||||
resolution: {integrity: sha512-qFl/QsHgnYXn3LhqqsP3ZgmdQtHxiZ5JRwUpy1KaGnmR33In99f0ZNsoekxfuXFHmvxvQkqoCPFEqV1iukS+lg==}
|
||||
|
||||
zigbee-on-host@0.2.4:
|
||||
resolution: {integrity: sha512-NIG6CWp+Yfn7PjqEIRvenHqpwT1U7rSkyimnFOUIFpnmxQOJKrmcwWDfn6WjbU/YIYYWSQPlj+g13icu1xwlyg==}
|
||||
@@ -1487,8 +1474,8 @@ packages:
|
||||
resolution: {integrity: sha512-ClHYlG7g0v/tnIsD6kycNCi1ZEKIbQuU7lGJR3WqYcDmuqEMVcHDGbRiRwYRQcZGMxkqCf7guxNsXiKnC10+kg==}
|
||||
engines: {node: '>=20.11'}
|
||||
|
||||
zigbee2mqtt-windfront@2.11.1:
|
||||
resolution: {integrity: sha512-2xM01JnuCWZlb1xYkIBVFAGJ6mkuAq/DRi8kfmB8KlA77LzHuX+f85pdgDotF9WGWb4+TqxmnpifYri1Nc3K2A==}
|
||||
zigbee2mqtt-windfront@2.11.3:
|
||||
resolution: {integrity: sha512-CANPCKiJMsVD6NEbtJprDGvatQ62txBWPV1sCcdR5cvR7rXuGsHlJjj1N/YJGbsQ0N+eN8+CyBXzNLj1YWcRdQ==}
|
||||
engines: {node: '>=22.12.0'}
|
||||
|
||||
snapshots:
|
||||
@@ -1515,39 +1502,39 @@ snapshots:
|
||||
|
||||
'@bcoe/v8-coverage@1.0.2': {}
|
||||
|
||||
'@biomejs/biome@2.4.12':
|
||||
'@biomejs/biome@2.4.16':
|
||||
optionalDependencies:
|
||||
'@biomejs/cli-darwin-arm64': 2.4.12
|
||||
'@biomejs/cli-darwin-x64': 2.4.12
|
||||
'@biomejs/cli-linux-arm64': 2.4.12
|
||||
'@biomejs/cli-linux-arm64-musl': 2.4.12
|
||||
'@biomejs/cli-linux-x64': 2.4.12
|
||||
'@biomejs/cli-linux-x64-musl': 2.4.12
|
||||
'@biomejs/cli-win32-arm64': 2.4.12
|
||||
'@biomejs/cli-win32-x64': 2.4.12
|
||||
'@biomejs/cli-darwin-arm64': 2.4.16
|
||||
'@biomejs/cli-darwin-x64': 2.4.16
|
||||
'@biomejs/cli-linux-arm64': 2.4.16
|
||||
'@biomejs/cli-linux-arm64-musl': 2.4.16
|
||||
'@biomejs/cli-linux-x64': 2.4.16
|
||||
'@biomejs/cli-linux-x64-musl': 2.4.16
|
||||
'@biomejs/cli-win32-arm64': 2.4.16
|
||||
'@biomejs/cli-win32-x64': 2.4.16
|
||||
|
||||
'@biomejs/cli-darwin-arm64@2.4.12':
|
||||
'@biomejs/cli-darwin-arm64@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-darwin-x64@2.4.12':
|
||||
'@biomejs/cli-darwin-x64@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-arm64-musl@2.4.12':
|
||||
'@biomejs/cli-linux-arm64-musl@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-arm64@2.4.12':
|
||||
'@biomejs/cli-linux-arm64@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-x64-musl@2.4.12':
|
||||
'@biomejs/cli-linux-x64-musl@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-x64@2.4.12':
|
||||
'@biomejs/cli-linux-x64@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-win32-arm64@2.4.12':
|
||||
'@biomejs/cli-win32-arm64@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-win32-x64@2.4.12':
|
||||
'@biomejs/cli-win32-x64@2.4.16':
|
||||
optional: true
|
||||
|
||||
'@colors/colors@1.6.0': {}
|
||||
@@ -1770,7 +1757,7 @@ snapshots:
|
||||
|
||||
'@types/finalhandler@1.2.4':
|
||||
dependencies:
|
||||
'@types/node': 24.12.2
|
||||
'@types/node': 24.12.4
|
||||
|
||||
'@types/http-errors@2.0.5': {}
|
||||
|
||||
@@ -1778,7 +1765,7 @@ snapshots:
|
||||
|
||||
'@types/js-yaml@4.0.9': {}
|
||||
|
||||
'@types/node@24.12.2':
|
||||
'@types/node@24.12.4':
|
||||
dependencies:
|
||||
undici-types: 7.16.0
|
||||
|
||||
@@ -1786,25 +1773,25 @@ snapshots:
|
||||
|
||||
'@types/readable-stream@4.0.23':
|
||||
dependencies:
|
||||
'@types/node': 24.12.2
|
||||
'@types/node': 24.12.4
|
||||
|
||||
'@types/serve-static@2.2.0':
|
||||
dependencies:
|
||||
'@types/http-errors': 2.0.5
|
||||
'@types/node': 24.12.2
|
||||
'@types/node': 24.12.4
|
||||
|
||||
'@types/triple-beam@1.3.5': {}
|
||||
|
||||
'@types/ws@8.18.1':
|
||||
dependencies:
|
||||
'@types/node': 24.12.2
|
||||
'@types/node': 24.12.4
|
||||
|
||||
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.12.2))':
|
||||
'@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@24.12.4))':
|
||||
dependencies:
|
||||
'@ampproject/remapping': 2.3.0
|
||||
'@bcoe/v8-coverage': 1.0.2
|
||||
ast-v8-to-istanbul: 0.3.3
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
istanbul-lib-coverage: 3.2.2
|
||||
istanbul-lib-report: 3.0.1
|
||||
istanbul-lib-source-maps: 5.0.6
|
||||
@@ -1814,7 +1801,7 @@ snapshots:
|
||||
std-env: 3.9.0
|
||||
test-exclude: 7.0.1
|
||||
tinyrainbow: 2.0.0
|
||||
vitest: 3.2.4(@types/node@24.12.2)
|
||||
vitest: 3.2.4(@types/node@24.12.4)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -1826,13 +1813,13 @@ snapshots:
|
||||
chai: 5.2.0
|
||||
tinyrainbow: 2.0.0
|
||||
|
||||
'@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.12.2))':
|
||||
'@vitest/mocker@3.2.4(vite@6.3.5(@types/node@24.12.4))':
|
||||
dependencies:
|
||||
'@vitest/spy': 3.2.4
|
||||
estree-walker: 3.0.3
|
||||
magic-string: 0.30.17
|
||||
optionalDependencies:
|
||||
vite: 6.3.5(@types/node@24.12.2)
|
||||
vite: 6.3.5(@types/node@24.12.4)
|
||||
|
||||
'@vitest/pretty-format@3.2.4':
|
||||
dependencies:
|
||||
@@ -1864,7 +1851,7 @@ snapshots:
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
|
||||
ajv@8.18.0:
|
||||
ajv@8.20.0:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-uri: 3.1.0
|
||||
@@ -1920,11 +1907,11 @@ snapshots:
|
||||
fast-deep-equal: 3.1.3
|
||||
multicast-dns: 7.2.5
|
||||
|
||||
brace-expansion@2.0.2:
|
||||
brace-expansion@2.1.0:
|
||||
dependencies:
|
||||
balanced-match: 1.0.2
|
||||
|
||||
brace-expansion@5.0.2:
|
||||
brace-expansion@5.0.6:
|
||||
dependencies:
|
||||
balanced-match: 4.0.2
|
||||
|
||||
@@ -1998,10 +1985,6 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.1:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.3:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
@@ -2070,11 +2053,11 @@ snapshots:
|
||||
|
||||
expect-type@1.2.1: {}
|
||||
|
||||
express-static-gzip@3.0.0:
|
||||
express-static-gzip@3.0.1:
|
||||
dependencies:
|
||||
mime-types: 3.0.1
|
||||
mime-types: 3.0.2
|
||||
parseurl: 1.3.3
|
||||
serve-static: 2.2.0
|
||||
serve-static: 2.2.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -2142,12 +2125,12 @@ snapshots:
|
||||
|
||||
html-escaper@2.0.2: {}
|
||||
|
||||
http-errors@2.0.0:
|
||||
http-errors@2.0.1:
|
||||
dependencies:
|
||||
depd: 2.0.0
|
||||
inherits: 2.0.4
|
||||
setprototypeof: 1.2.0
|
||||
statuses: 2.0.1
|
||||
statuses: 2.0.2
|
||||
toidentifier: 1.0.1
|
||||
|
||||
humanize-duration@3.33.2: {}
|
||||
@@ -2183,7 +2166,7 @@ snapshots:
|
||||
istanbul-lib-source-maps@5.0.6:
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
istanbul-lib-coverage: 3.2.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -2255,21 +2238,21 @@ snapshots:
|
||||
|
||||
make-dir@4.0.0:
|
||||
dependencies:
|
||||
semver: 7.7.4
|
||||
semver: 7.8.1
|
||||
|
||||
mime-db@1.54.0: {}
|
||||
|
||||
mime-types@3.0.1:
|
||||
mime-types@3.0.2:
|
||||
dependencies:
|
||||
mime-db: 1.54.0
|
||||
|
||||
minimatch@10.2.0:
|
||||
dependencies:
|
||||
brace-expansion: 5.0.2
|
||||
brace-expansion: 5.0.6
|
||||
|
||||
minimatch@9.0.5:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
brace-expansion: 2.1.0
|
||||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
@@ -2300,7 +2283,7 @@ snapshots:
|
||||
socks: 2.8.7
|
||||
split2: 4.2.0
|
||||
worker-timers: 8.0.31
|
||||
ws: 8.20.0
|
||||
ws: 8.21.0
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- supports-color
|
||||
@@ -2444,17 +2427,17 @@ snapshots:
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
|
||||
semver@7.7.4: {}
|
||||
semver@7.8.1: {}
|
||||
|
||||
send@1.2.0:
|
||||
send@1.2.1:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
encodeurl: 2.0.0
|
||||
escape-html: 1.0.3
|
||||
etag: 1.8.1
|
||||
fresh: 2.0.0
|
||||
http-errors: 2.0.0
|
||||
mime-types: 3.0.1
|
||||
http-errors: 2.0.1
|
||||
mime-types: 3.0.2
|
||||
ms: 2.1.3
|
||||
on-finished: 2.4.1
|
||||
range-parser: 1.2.1
|
||||
@@ -2462,12 +2445,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
serve-static@2.2.0:
|
||||
serve-static@2.2.1:
|
||||
dependencies:
|
||||
encodeurl: 2.0.0
|
||||
escape-html: 1.0.3
|
||||
parseurl: 1.3.3
|
||||
send: 1.2.0
|
||||
send: 1.2.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -2509,8 +2492,6 @@ snapshots:
|
||||
|
||||
stackback@0.0.2: {}
|
||||
|
||||
statuses@2.0.1: {}
|
||||
|
||||
statuses@2.0.2: {}
|
||||
|
||||
std-env@3.9.0: {}
|
||||
@@ -2578,7 +2559,7 @@ snapshots:
|
||||
|
||||
tinyspy@4.0.3: {}
|
||||
|
||||
tmp@0.2.5: {}
|
||||
tmp@0.2.7: {}
|
||||
|
||||
toidentifier@1.0.1: {}
|
||||
|
||||
@@ -2606,13 +2587,13 @@ snapshots:
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
vite-node@3.2.4(@types/node@24.12.2):
|
||||
vite-node@3.2.4(@types/node@24.12.4):
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
debug: 4.4.3
|
||||
es-module-lexer: 1.7.0
|
||||
pathe: 2.0.3
|
||||
vite: 6.3.5(@types/node@24.12.2)
|
||||
vite: 6.3.5(@types/node@24.12.4)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- jiti
|
||||
@@ -2627,7 +2608,7 @@ snapshots:
|
||||
- tsx
|
||||
- yaml
|
||||
|
||||
vite@6.3.5(@types/node@24.12.2):
|
||||
vite@6.3.5(@types/node@24.12.4):
|
||||
dependencies:
|
||||
esbuild: 0.25.5
|
||||
fdir: 6.4.6(picomatch@4.0.2)
|
||||
@@ -2636,21 +2617,21 @@ snapshots:
|
||||
rollup: 4.44.0
|
||||
tinyglobby: 0.2.14
|
||||
optionalDependencies:
|
||||
'@types/node': 24.12.2
|
||||
'@types/node': 24.12.4
|
||||
fsevents: 2.3.3
|
||||
|
||||
vitest@3.2.4(@types/node@24.12.2):
|
||||
vitest@3.2.4(@types/node@24.12.4):
|
||||
dependencies:
|
||||
'@types/chai': 5.2.2
|
||||
'@vitest/expect': 3.2.4
|
||||
'@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.12.2))
|
||||
'@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@24.12.4))
|
||||
'@vitest/pretty-format': 3.2.4
|
||||
'@vitest/runner': 3.2.4
|
||||
'@vitest/snapshot': 3.2.4
|
||||
'@vitest/spy': 3.2.4
|
||||
'@vitest/utils': 3.2.4
|
||||
chai: 5.2.0
|
||||
debug: 4.4.1
|
||||
debug: 4.4.3
|
||||
expect-type: 1.2.1
|
||||
magic-string: 0.30.17
|
||||
pathe: 2.0.3
|
||||
@@ -2661,11 +2642,11 @@ snapshots:
|
||||
tinyglobby: 0.2.14
|
||||
tinypool: 1.1.1
|
||||
tinyrainbow: 2.0.0
|
||||
vite: 6.3.5(@types/node@24.12.2)
|
||||
vite-node: 3.2.4(@types/node@24.12.2)
|
||||
vite: 6.3.5(@types/node@24.12.4)
|
||||
vite-node: 3.2.4(@types/node@24.12.4)
|
||||
why-is-node-running: 2.3.0
|
||||
optionalDependencies:
|
||||
'@types/node': 24.12.2
|
||||
'@types/node': 24.12.4
|
||||
transitivePeerDependencies:
|
||||
- jiti
|
||||
- less
|
||||
@@ -2757,17 +2738,17 @@ snapshots:
|
||||
string-width: 5.1.2
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
ws@8.20.0: {}
|
||||
ws@8.21.0: {}
|
||||
|
||||
zigbee-herdsman-converters@26.39.1:
|
||||
zigbee-herdsman-converters@26.61.1:
|
||||
dependencies:
|
||||
iconv-lite: 0.7.2
|
||||
semver: 7.7.4
|
||||
zigbee-herdsman: 10.0.7
|
||||
semver: 7.8.1
|
||||
zigbee-herdsman: 10.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
zigbee-herdsman@10.0.7:
|
||||
zigbee-herdsman@10.1.0:
|
||||
dependencies:
|
||||
'@date-fns/tz': 1.4.1
|
||||
'@serialport/bindings-cpp': 13.0.1
|
||||
@@ -2785,4 +2766,4 @@ snapshots:
|
||||
|
||||
zigbee2mqtt-frontend@0.9.21: {}
|
||||
|
||||
zigbee2mqtt-windfront@2.11.1: {}
|
||||
zigbee2mqtt-windfront@2.11.3: {}
|
||||
|
||||
+13
-23
@@ -1,4 +1,12 @@
|
||||
import {execSync} from "node:child_process";
|
||||
import {execFileSync} from "node:child_process";
|
||||
|
||||
function grepTypeScriptFiles(needle, dir) {
|
||||
try {
|
||||
return execFileSync("grep", ["-r", "-F", "--include=*.ts", "--", needle, dir], {encoding: "utf8"});
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async function checkDuplicateIssue(github, context, name) {
|
||||
// Search for existing issues with the same `name`
|
||||
@@ -63,13 +71,7 @@ export async function newDeviceSupport(github, _core, context, zhcDir) {
|
||||
if (tuyaManufacturerNames.length > 0) {
|
||||
for (const [fullName, partialName] of tuyaManufacturerNames) {
|
||||
if (await checkDuplicateIssue(github, context, fullName)) return;
|
||||
const fullMatch = (() => {
|
||||
try {
|
||||
return execSync(`grep -r --include="*.ts" "${fullName}" "${zhcDir}"`, {encoding: "utf8"});
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
})();
|
||||
const fullMatch = grepTypeScriptFiles(fullName, zhcDir);
|
||||
|
||||
console.log(`Checking full match for '${fullName}', result: '${fullMatch}'`);
|
||||
if (fullMatch) {
|
||||
@@ -94,13 +96,7 @@ If you need help with the process, feel free to ask here and we'll be happy to a
|
||||
return;
|
||||
}
|
||||
|
||||
const partialMatch = (() => {
|
||||
try {
|
||||
return execSync(`grep -r --include="*.ts" "${partialName}" "${zhcDir}"`, {encoding: "utf8"});
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
})();
|
||||
const partialMatch = grepTypeScriptFiles(partialName, zhcDir);
|
||||
|
||||
console.log(`Checking partial match for '${partialName}', result: '${partialMatch}'`);
|
||||
if (partialMatch) {
|
||||
@@ -129,14 +125,8 @@ Let us know if it works so we can support this device out-of-the-box!`,
|
||||
|
||||
if (zigbeeModels.length > 0) {
|
||||
for (const zigbeeModel of zigbeeModels) {
|
||||
if (await checkDuplicateIssue(github, context, fullName)) return;
|
||||
const fullMatch = (() => {
|
||||
try {
|
||||
return execSync(`grep -r --include="*.ts" '"${zigbeeModel}"' "${zhcDir}"`, {encoding: "utf8"});
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
})();
|
||||
if (await checkDuplicateIssue(github, context, zigbeeModel)) return;
|
||||
const fullMatch = grepTypeScriptFiles(`"${zigbeeModel}"`, zhcDir);
|
||||
|
||||
if (fullMatch) {
|
||||
await github.rest.issues.createComment({
|
||||
|
||||
@@ -144,6 +144,7 @@ describe("Extension: Bridge", () => {
|
||||
output: "json",
|
||||
pan_id: 6754,
|
||||
timestamp_format: "YYYY-MM-DD HH:mm:ss",
|
||||
enable_external_js: true,
|
||||
},
|
||||
blocklist: [],
|
||||
device_options: {},
|
||||
@@ -735,7 +736,7 @@ describe("Extension: Bridge", () => {
|
||||
values: ["off", "on", "toggle", "previous"],
|
||||
},
|
||||
{
|
||||
access: 2,
|
||||
access: 3,
|
||||
label: "Effect",
|
||||
name: "effect",
|
||||
property: "effect",
|
||||
@@ -748,11 +749,41 @@ describe("Extension: Bridge", () => {
|
||||
"candle",
|
||||
"fireplace",
|
||||
"colorloop",
|
||||
"sunset",
|
||||
"sunrise",
|
||||
"sparkle",
|
||||
"opal",
|
||||
"glisten",
|
||||
"underwater",
|
||||
"cosmos",
|
||||
"sunbeam",
|
||||
"enchant",
|
||||
"none",
|
||||
"finish_effect",
|
||||
"stop_effect",
|
||||
"stop_hue_effect",
|
||||
],
|
||||
},
|
||||
{
|
||||
access: 3,
|
||||
description: "Animation speed for the active effect (0=slowest, 1=fastest)",
|
||||
label: "Effect speed",
|
||||
name: "effect_speed",
|
||||
property: "effect_speed",
|
||||
type: "numeric",
|
||||
value_max: 1,
|
||||
value_min: 0,
|
||||
value_step: 0.01,
|
||||
},
|
||||
{
|
||||
access: 2,
|
||||
description:
|
||||
'Set the base color of the active effect without stopping it (hex e.g. #FF4400, or JSON {"x":0.6,"y":0.3})',
|
||||
label: "Effect color",
|
||||
name: "effect_color",
|
||||
property: "effect_color",
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
access: 1,
|
||||
category: "diagnostic",
|
||||
@@ -768,6 +799,27 @@ describe("Extension: Bridge", () => {
|
||||
],
|
||||
model: "7146060PH",
|
||||
options: [
|
||||
{
|
||||
access: 2,
|
||||
description:
|
||||
"Control this light using a Philips-specific protocol instead of standard Zigbee commands. When enabled, on/off, brightness, color, and color temperature are combined into single atomic commands. This is required to use the Effect color update mode. When disabled (default), standard Zigbee commands are used, which preserves the usual behavior, including simulating on/off transitions.",
|
||||
label: "Hue native control",
|
||||
name: "hue_native_control",
|
||||
property: "hue_native_control",
|
||||
type: "binary",
|
||||
value_off: false,
|
||||
value_on: true,
|
||||
},
|
||||
{
|
||||
access: 2,
|
||||
description:
|
||||
"Controls what happens when color is changed while an effect is active (requires Hue native control). 'stop' (default): color change stops the effect (Hue app behavior). 'update': color change re-sends the effect with the new color.",
|
||||
label: "Effect color mode",
|
||||
name: "effect_color_mode",
|
||||
property: "effect_color_mode",
|
||||
type: "enum",
|
||||
values: ["stop", "update"],
|
||||
},
|
||||
{
|
||||
access: 2,
|
||||
description:
|
||||
@@ -781,21 +833,21 @@ describe("Extension: Bridge", () => {
|
||||
},
|
||||
{
|
||||
access: 2,
|
||||
description:
|
||||
"When enabled colors will be synced, e.g. if the light supports both color x/y and color temperature a conversion from color x/y to color temperature will be done when setting the x/y color (default true).",
|
||||
label: "Color sync",
|
||||
name: "color_sync",
|
||||
property: "color_sync",
|
||||
description: "State actions will also be published as 'action' when true (default false).",
|
||||
label: "State action",
|
||||
name: "state_action",
|
||||
property: "state_action",
|
||||
type: "binary",
|
||||
value_off: false,
|
||||
value_on: true,
|
||||
},
|
||||
{
|
||||
access: 2,
|
||||
description: "State actions will also be published as 'action' when true (default false).",
|
||||
label: "State action",
|
||||
name: "state_action",
|
||||
property: "state_action",
|
||||
description:
|
||||
"When enabled colors will be synced, e.g. if the light supports both color x/y and color temperature a conversion from color x/y to color temperature will be done when setting the x/y color (default true).",
|
||||
label: "Color sync",
|
||||
name: "color_sync",
|
||||
property: "color_sync",
|
||||
type: "binary",
|
||||
value_off: false,
|
||||
value_on: true,
|
||||
|
||||
@@ -488,6 +488,25 @@ describe("Extension: ExternalConverters", () => {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("zigbee2mqtt/bridge/converters", stringify([]), {retain: true});
|
||||
});
|
||||
|
||||
it("returns error on invalid name", async () => {
|
||||
const converterName = "foo1";
|
||||
|
||||
await resetExtension();
|
||||
for (const mock of mocksClear) mock.mockClear();
|
||||
|
||||
await (controller.getExtension("ExternalConverters")! as ExternalConverters).onMQTTMessage({
|
||||
topic: "zigbee2mqtt/bridge/request/converter/save",
|
||||
message: {name: converterName, code: "a"},
|
||||
});
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
|
||||
"zigbee2mqtt/bridge/response/converter/save",
|
||||
expect.stringContaining(`JavaScript file must have '.mjs', '.js' or '.cjs' extension`),
|
||||
{},
|
||||
);
|
||||
expect(writeFileSyncSpy).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it("returns error on invalid code", async () => {
|
||||
const converterName = "foo1.js";
|
||||
const converterCode = "definetly not a correct javascript code";
|
||||
@@ -609,4 +628,15 @@ describe("Extension: ExternalConverters", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't add extension when external JS disabled", async () => {
|
||||
settings.set(["advanced", "enable_external_js"], false);
|
||||
|
||||
controller = new Controller(vi.fn(), vi.fn());
|
||||
|
||||
await controller.start();
|
||||
await flushPromises();
|
||||
|
||||
expect(controller.getExtension("ExternalConverters")).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -299,6 +299,25 @@ describe("Extension: ExternalExtensions", () => {
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("zigbee2mqtt/bridge/extensions", stringify([]), {retain: true});
|
||||
});
|
||||
|
||||
it("returns error on invalid name", async () => {
|
||||
const extensionName = "foo1";
|
||||
|
||||
await resetExtension();
|
||||
for (const mock of mocksClear) mock.mockClear();
|
||||
|
||||
await (controller.getExtension("ExternalExtensions")! as ExternalExtensions).onMQTTMessage({
|
||||
topic: "zigbee2mqtt/bridge/request/extension/save",
|
||||
message: {name: extensionName, code: "a"},
|
||||
});
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
|
||||
"zigbee2mqtt/bridge/response/extension/save",
|
||||
expect.stringContaining(`JavaScript file must have '.mjs', '.js' or '.cjs' extension`),
|
||||
{},
|
||||
);
|
||||
expect(writeFileSyncSpy).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
it("returns error on invalid code", async () => {
|
||||
const extensionName = "foo1.js";
|
||||
const extensionCode = "definetly not a correct javascript code";
|
||||
@@ -365,4 +384,15 @@ describe("Extension: ExternalExtensions", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't add extension when external JS disabled", async () => {
|
||||
settings.set(["advanced", "enable_external_js"], false);
|
||||
|
||||
controller = new Controller(vi.fn(), vi.fn());
|
||||
|
||||
await controller.start();
|
||||
await flushPromises();
|
||||
|
||||
expect(controller.getExtension("ExternalExtensions")).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -245,6 +245,8 @@ describe("Extension: Frontend", () => {
|
||||
stringify({
|
||||
state: "ON",
|
||||
effect: null,
|
||||
effect_color: null,
|
||||
effect_speed: null,
|
||||
power_on_behavior: null,
|
||||
linkquality: 20,
|
||||
update: {state: null, installed_version: -1, latest_version: -1},
|
||||
@@ -269,6 +271,8 @@ describe("Extension: Frontend", () => {
|
||||
state: "ON",
|
||||
power_on_behavior: null,
|
||||
effect: null,
|
||||
effect_color: null,
|
||||
effect_speed: null,
|
||||
linkquality: 20,
|
||||
update: {state: null, installed_version: -1, latest_version: -1},
|
||||
},
|
||||
@@ -296,6 +300,8 @@ describe("Extension: Frontend", () => {
|
||||
brightness: 90,
|
||||
power_on_behavior: null,
|
||||
effect: null,
|
||||
effect_color: null,
|
||||
effect_speed: null,
|
||||
linkquality: 20,
|
||||
update: {state: null, installed_version: -1, latest_version: -1},
|
||||
},
|
||||
|
||||
@@ -164,6 +164,16 @@ describe("Extension: HomeAssistant", () => {
|
||||
"candle",
|
||||
"fireplace",
|
||||
"colorloop",
|
||||
"sunset",
|
||||
"sunrise",
|
||||
"sparkle",
|
||||
"opal",
|
||||
"glisten",
|
||||
"underwater",
|
||||
"cosmos",
|
||||
"sunbeam",
|
||||
"enchant",
|
||||
"none",
|
||||
"finish_effect",
|
||||
"stop_effect",
|
||||
"stop_hue_effect",
|
||||
@@ -229,7 +239,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unique_id: "9_switch_zigbee2mqtt",
|
||||
group: ["0x0017880104e45542_switch_right_zigbee2mqtt"],
|
||||
origin: origin,
|
||||
value_template: "{{ value_json.state }}",
|
||||
value_template: '{{ value_json["state"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith(
|
||||
@@ -242,7 +252,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "°C",
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_temperature",
|
||||
@@ -269,7 +279,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "%",
|
||||
device_class: "humidity",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.humidity }}",
|
||||
value_template: '{{ value_json["humidity"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_humidity",
|
||||
default_entity_id: "sensor.weather_sensor_humidity",
|
||||
@@ -296,7 +306,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "hPa",
|
||||
device_class: "atmospheric_pressure",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.pressure }}",
|
||||
value_template: '{{ value_json["pressure"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_pressure",
|
||||
default_entity_id: "sensor.weather_sensor_pressure",
|
||||
@@ -323,7 +333,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "%",
|
||||
device_class: "battery",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.battery }}",
|
||||
value_template: '{{ value_json["battery"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_battery",
|
||||
default_entity_id: "sensor.weather_sensor_battery",
|
||||
@@ -353,7 +363,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
entity_category: "diagnostic",
|
||||
unit_of_measurement: "lqi",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.linkquality }}",
|
||||
value_template: '{{ value_json["linkquality"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
name: "Linkquality",
|
||||
object_id: "weather_sensor_linkquality",
|
||||
@@ -395,7 +405,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
default_entity_id: "switch.wall_switch_double_left",
|
||||
unique_id: "0x0017880104e45542_switch_left_zigbee2mqtt",
|
||||
origin: origin,
|
||||
value_template: "{{ value_json.state_left }}",
|
||||
value_template: '{{ value_json["state_left"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/switch/0x0017880104e45542/switch_left/config", stringify(payload), {
|
||||
@@ -422,7 +432,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
default_entity_id: "switch.wall_switch_double_right",
|
||||
unique_id: "0x0017880104e45542_switch_right_zigbee2mqtt",
|
||||
origin: origin,
|
||||
value_template: "{{ value_json.state_right }}",
|
||||
value_template: '{{ value_json["state_right"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/switch/0x0017880104e45542/switch_right/config", stringify(payload), {
|
||||
@@ -525,7 +535,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "%",
|
||||
device_class: "humidity",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.humidity }}",
|
||||
value_template: '{{ value_json["humidity"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_humidity",
|
||||
default_entity_id: "sensor.weather_sensor_humidity",
|
||||
@@ -597,7 +607,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
enabled_by_default: true,
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_temperature",
|
||||
@@ -623,7 +633,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "%",
|
||||
device_class: "humidity",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.humidity }}",
|
||||
value_template: '{{ value_json["humidity"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_humidity",
|
||||
default_entity_id: "sensor.weather_sensor_humidity",
|
||||
@@ -650,7 +660,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "hPa",
|
||||
device_class: "atmospheric_pressure",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.pressure }}",
|
||||
value_template: '{{ value_json["pressure"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
enabled_by_default: true,
|
||||
object_id: "weather_sensor_pressure",
|
||||
@@ -708,7 +718,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "°C",
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
enabled_by_default: true,
|
||||
object_id: "weather_sensor_temperature",
|
||||
@@ -738,7 +748,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "%",
|
||||
device_class: "humidity",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.humidity }}",
|
||||
value_template: '{{ value_json["humidity"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
enabled_by_default: true,
|
||||
device: {
|
||||
@@ -781,7 +791,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "°C",
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_temperature",
|
||||
@@ -808,7 +818,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "%",
|
||||
device_class: "humidity",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.humidity }}",
|
||||
value_template: '{{ value_json["humidity"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_humidity",
|
||||
default_entity_id: "sensor.weather_sensor_humidity",
|
||||
@@ -871,7 +881,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
default_entity_id: "light.my_switch",
|
||||
unique_id: "0x0017880104e45541_light_zigbee2mqtt",
|
||||
origin: origin,
|
||||
value_template: "{{ value_json.state }}",
|
||||
value_template: '{{ value_json["state"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/light/0x0017880104e45541/light/config", stringify(payload), {
|
||||
@@ -917,11 +927,11 @@ describe("Extension: HomeAssistant", () => {
|
||||
command_topic: "zigbee2mqtt/fan/set/fan_state",
|
||||
percentage_state_topic: "zigbee2mqtt/fan",
|
||||
percentage_command_topic: "zigbee2mqtt/fan/set/fan_mode",
|
||||
percentage_value_template: "{{ {'off':0, 'low':1, 'medium':2, 'high':3, 'on':4}[value_json.fan_mode] | default('None') }}",
|
||||
percentage_value_template: "{{ {'off':0, 'low':1, 'medium':2, 'high':3, 'on':4}[value_json[\"fan_mode\"]] | default('None') }}",
|
||||
percentage_command_template: "{{ {0:'off', 1:'low', 2:'medium', 3:'high', 4:'on'}[value] | default('') }}",
|
||||
preset_mode_state_topic: "zigbee2mqtt/fan",
|
||||
preset_mode_command_topic: "zigbee2mqtt/fan/set/fan_mode",
|
||||
preset_mode_value_template: "{{ value_json.fan_mode if value_json.fan_mode in ['smart'] else 'None' | default('None') }}",
|
||||
preset_mode_value_template: "{{ value_json[\"fan_mode\"] if value_json[\"fan_mode\"] in ['smart'] else 'None' | default('None') }}",
|
||||
preset_modes: ["smart"],
|
||||
speed_range_min: 1,
|
||||
speed_range_max: 4,
|
||||
@@ -993,7 +1003,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
command_topic: "zigbee2mqtt/fanbee/set/state",
|
||||
percentage_state_topic: "zigbee2mqtt/fanbee",
|
||||
percentage_command_topic: "zigbee2mqtt/fanbee/set/speed",
|
||||
percentage_value_template: "{{ value_json.speed | default('None') }}",
|
||||
percentage_value_template: "{{ value_json[\"speed\"] | default('None') }}",
|
||||
percentage_command_template: "{{ value | default('') }}",
|
||||
speed_range_min: 1,
|
||||
speed_range_max: 254,
|
||||
@@ -1026,7 +1036,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
it("Should discover thermostat devices", () => {
|
||||
const payload = {
|
||||
action_template:
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json.running_state] }}",
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json[\"running_state\"]] }}",
|
||||
action_topic: "zigbee2mqtt/TS0601_thermostat",
|
||||
availability: [
|
||||
{
|
||||
@@ -1034,7 +1044,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
value_template: "{{ value_json.state }}",
|
||||
},
|
||||
],
|
||||
current_temperature_template: "{{ value_json.local_temperature }}",
|
||||
current_temperature_template: '{{ value_json["local_temperature"] }}',
|
||||
current_temperature_topic: "zigbee2mqtt/TS0601_thermostat",
|
||||
device: {
|
||||
identifiers: ["zigbee2mqtt_0x0017882104a44559"],
|
||||
@@ -1046,18 +1056,18 @@ describe("Extension: HomeAssistant", () => {
|
||||
},
|
||||
preset_mode_command_topic: "zigbee2mqtt/TS0601_thermostat/set/preset",
|
||||
preset_modes: ["schedule", "manual", "boost", "complex", "comfort", "eco", "away"],
|
||||
preset_mode_value_template: "{{ value_json.preset }}",
|
||||
preset_mode_value_template: '{{ value_json["preset"] }}',
|
||||
preset_mode_state_topic: "zigbee2mqtt/TS0601_thermostat",
|
||||
max_temp: "35",
|
||||
min_temp: "5",
|
||||
mode_command_topic: "zigbee2mqtt/TS0601_thermostat/set/system_mode",
|
||||
mode_state_template: "{{ value_json.system_mode }}",
|
||||
mode_state_template: '{{ value_json["system_mode"] }}',
|
||||
mode_state_topic: "zigbee2mqtt/TS0601_thermostat",
|
||||
modes: ["heat", "auto", "off"],
|
||||
name: null,
|
||||
temp_step: 0.5,
|
||||
temperature_command_topic: "zigbee2mqtt/TS0601_thermostat/set/current_heating_setpoint",
|
||||
temperature_state_template: "{{ value_json.current_heating_setpoint }}",
|
||||
temperature_state_template: '{{ value_json["current_heating_setpoint"] }}',
|
||||
temperature_state_topic: "zigbee2mqtt/TS0601_thermostat",
|
||||
temperature_unit: "C",
|
||||
object_id: "ts0601_thermostat",
|
||||
@@ -1097,7 +1107,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
state_topic: "zigbee2mqtt/thermostat",
|
||||
unique_id: "0x0017880104e45550_pi_heating_demand_zigbee2mqtt",
|
||||
unit_of_measurement: "%",
|
||||
value_template: "{{ value_json.pi_heating_demand }}",
|
||||
value_template: '{{ value_json["pi_heating_demand"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/sensor/0x0017880104e45550/pi_heating_demand/config", stringify(payload), {
|
||||
@@ -1134,7 +1144,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
state_topic: "zigbee2mqtt/bosch_radiator",
|
||||
unique_id: "0x18fc2600000d7ae2_pi_heating_demand_zigbee2mqtt",
|
||||
unit_of_measurement: "%",
|
||||
value_template: "{{ value_json.pi_heating_demand }}",
|
||||
value_template: '{{ value_json["pi_heating_demand"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/number/0x18fc2600000d7ae2/pi_heating_demand/config", stringify(payload), {
|
||||
@@ -1146,10 +1156,10 @@ describe("Extension: HomeAssistant", () => {
|
||||
it("Should discover Bosch BTH-RA with a compatibility mapping", () => {
|
||||
const payload = {
|
||||
action_template:
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json.running_state] }}",
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json[\"running_state\"]] }}",
|
||||
action_topic: "zigbee2mqtt/bosch_radiator",
|
||||
availability: [{topic: "zigbee2mqtt/bridge/state", value_template: "{{ value_json.state }}"}],
|
||||
current_temperature_template: "{{ value_json.local_temperature }}",
|
||||
current_temperature_template: '{{ value_json["local_temperature"] }}',
|
||||
current_temperature_topic: "zigbee2mqtt/bosch_radiator",
|
||||
device: {
|
||||
identifiers: ["zigbee2mqtt_0x18fc2600000d7ae2"],
|
||||
@@ -1174,7 +1184,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
origin: origin,
|
||||
temp_step: 0.5,
|
||||
temperature_command_topic: "zigbee2mqtt/bosch_radiator/set/occupied_heating_setpoint",
|
||||
temperature_state_template: "{{ value_json.occupied_heating_setpoint }}",
|
||||
temperature_state_template: '{{ value_json["occupied_heating_setpoint"] }}',
|
||||
temperature_state_topic: "zigbee2mqtt/bosch_radiator",
|
||||
temperature_unit: "C",
|
||||
unique_id: "0x18fc2600000d7ae2_climate_zigbee2mqtt",
|
||||
@@ -1201,10 +1211,10 @@ describe("Extension: HomeAssistant", () => {
|
||||
|
||||
const payload = {
|
||||
action_template:
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json.running_state] }}",
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json[\"running_state\"]] }}",
|
||||
action_topic: "zigbee2mqtt/bosch_radiator",
|
||||
availability: [{topic: "zigbee2mqtt/bridge/state", value_template: "{{ value_json.state }}"}],
|
||||
current_temperature_template: "{{ value_json.local_temperature }}",
|
||||
current_temperature_template: '{{ value_json["local_temperature"] }}',
|
||||
current_temperature_topic: "zigbee2mqtt/bosch_radiator",
|
||||
device: {
|
||||
identifiers: ["zigbee2mqtt_0x18fc2600000d7ae2"],
|
||||
@@ -1218,7 +1228,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
max_temp: "30",
|
||||
min_temp: "5",
|
||||
mode_command_topic: "zigbee2mqtt/bosch_radiator/set/system_mode",
|
||||
mode_state_template: "{{ value_json.system_mode }}",
|
||||
mode_state_template: '{{ value_json["system_mode"] }}',
|
||||
mode_state_topic: "zigbee2mqtt/bosch_radiator",
|
||||
modes: ["heat"],
|
||||
name: null,
|
||||
@@ -1227,7 +1237,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
origin: origin,
|
||||
temp_step: 0.5,
|
||||
temperature_command_topic: "zigbee2mqtt/bosch_radiator/set/occupied_heating_setpoint",
|
||||
temperature_state_template: "{{ value_json.occupied_heating_setpoint }}",
|
||||
temperature_state_template: '{{ value_json["occupied_heating_setpoint"] }}',
|
||||
temperature_state_topic: "zigbee2mqtt/bosch_radiator",
|
||||
temperature_unit: "C",
|
||||
unique_id: "0x18fc2600000d7ae2_climate_zigbee2mqtt",
|
||||
@@ -1245,12 +1255,12 @@ describe("Extension: HomeAssistant", () => {
|
||||
it("Should discover Bosch BTH-RM230Z with a current_humidity attribute", () => {
|
||||
const payload = {
|
||||
action_template:
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json.running_state] }}",
|
||||
"{% set values = {None:None,'idle':'idle','heat':'heating','cool':'cooling','fan_only':'fan'} %}{{ values[value_json[\"running_state\"]] }}",
|
||||
action_topic: "zigbee2mqtt/bosch_rm230z",
|
||||
availability: [{topic: "zigbee2mqtt/bridge/state", value_template: "{{ value_json.state }}"}],
|
||||
current_humidity_template: "{{ value_json.humidity }}",
|
||||
current_humidity_template: '{{ value_json["humidity"] }}',
|
||||
current_humidity_topic: "zigbee2mqtt/bosch_rm230z",
|
||||
current_temperature_template: "{{ value_json.local_temperature }}",
|
||||
current_temperature_template: '{{ value_json["local_temperature"] }}',
|
||||
current_temperature_topic: "zigbee2mqtt/bosch_rm230z",
|
||||
default_entity_id: "climate.bosch_rm230z",
|
||||
device: {
|
||||
@@ -1275,10 +1285,10 @@ describe("Extension: HomeAssistant", () => {
|
||||
origin,
|
||||
temp_step: 0.5,
|
||||
temperature_high_command_topic: "zigbee2mqtt/bosch_rm230z/set/occupied_cooling_setpoint",
|
||||
temperature_high_state_template: "{{ value_json.occupied_cooling_setpoint }}",
|
||||
temperature_high_state_template: '{{ value_json["occupied_cooling_setpoint"] }}',
|
||||
temperature_high_state_topic: "zigbee2mqtt/bosch_rm230z",
|
||||
temperature_low_command_topic: "zigbee2mqtt/bosch_rm230z/set/occupied_heating_setpoint",
|
||||
temperature_low_state_template: "{{ value_json.occupied_heating_setpoint }}",
|
||||
temperature_low_state_template: '{{ value_json["occupied_heating_setpoint"] }}',
|
||||
temperature_low_state_topic: "zigbee2mqtt/bosch_rm230z",
|
||||
temperature_unit: "C",
|
||||
unique_id: "0x18fc2600000d7ae3_climate_zigbee2mqtt",
|
||||
@@ -1309,7 +1319,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
state_topic: "zigbee2mqtt/bosch_rm230z",
|
||||
unique_id: "0x18fc2600000d7ae3_local_temperature_zigbee2mqtt",
|
||||
unit_of_measurement: "°C",
|
||||
value_template: "{{ value_json.local_temperature }}",
|
||||
value_template: '{{ value_json["local_temperature"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/sensor/0x18fc2600000d7ae3/local_temperature/config", stringify(payload), {
|
||||
@@ -1326,9 +1336,9 @@ describe("Extension: HomeAssistant", () => {
|
||||
position_topic: "zigbee2mqtt/smart vent",
|
||||
set_position_topic: "zigbee2mqtt/smart vent/set",
|
||||
set_position_template: '{ "position": {{ position }} }',
|
||||
position_template: "{{ value_json.position }}",
|
||||
position_template: '{{ value_json["position"] }}',
|
||||
state_topic: "zigbee2mqtt/smart vent",
|
||||
value_template: "{{ value_json.state }}",
|
||||
value_template: '{{ value_json["state"] }}',
|
||||
state_open: "OPEN",
|
||||
state_closed: "CLOSE",
|
||||
state_stopped: "STOP",
|
||||
@@ -1365,7 +1375,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
via_device: "zigbee2mqtt_bridge_0x00124b00120144ae",
|
||||
},
|
||||
name: "L6",
|
||||
position_template: "{{ value_json.position }}",
|
||||
position_template: '{{ value_json["position"] }}',
|
||||
position_topic: "zigbee2mqtt/zigfred_plus/l6",
|
||||
set_position_template: '{ "position_l6": {{ position }} }',
|
||||
set_position_topic: "zigbee2mqtt/zigfred_plus/l6/set",
|
||||
@@ -1374,13 +1384,13 @@ describe("Extension: HomeAssistant", () => {
|
||||
state_open: "OPEN",
|
||||
state_topic: "zigbee2mqtt/zigfred_plus/l6",
|
||||
tilt_command_topic: "zigbee2mqtt/zigfred_plus/l6/set/tilt",
|
||||
tilt_status_template: "{{ value_json.tilt }}",
|
||||
tilt_status_template: '{{ value_json["tilt"] }}',
|
||||
tilt_status_topic: "zigbee2mqtt/zigfred_plus/l6",
|
||||
object_id: "zigfred_plus_l6",
|
||||
default_entity_id: "cover.zigfred_plus_l6",
|
||||
unique_id: "0xf4ce368a38be56a1_cover_l6_zigbee2mqtt",
|
||||
origin: origin,
|
||||
value_template: "{{ value_json.state }}",
|
||||
value_template: '{{ value_json["state"] }}',
|
||||
};
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/cover/0xf4ce368a38be56a1/cover_l6/config", stringify(payload), {
|
||||
@@ -1410,7 +1420,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
object_id: "0xa4c138018cf95021_left",
|
||||
default_entity_id: "cover.0xa4c138018cf95021_left",
|
||||
origin: origin,
|
||||
position_template: "{{ value_json.position }}",
|
||||
position_template: '{{ value_json["position"] }}',
|
||||
position_topic: "zigbee2mqtt/0xa4c138018cf95021/left",
|
||||
set_position_template: '{ "position_left": {{ position }} }',
|
||||
set_position_topic: "zigbee2mqtt/0xa4c138018cf95021/left/set",
|
||||
@@ -1419,7 +1429,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
state_stopped: "STOP",
|
||||
state_topic: "zigbee2mqtt/0xa4c138018cf95021/left",
|
||||
unique_id: "0xa4c138018cf95021_cover_left_zigbee2mqtt",
|
||||
value_template: '{% if "moving" in value_json and value_json.moving %} {{ value_json.moving }} {% else %} STOP {% endif %}',
|
||||
value_template: '{% if "moving" in value_json and value_json["moving"] %} {{ value_json["moving"] }} {% else %} STOP {% endif %}',
|
||||
};
|
||||
const payload_right = {
|
||||
availability: [
|
||||
@@ -1441,7 +1451,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
object_id: "0xa4c138018cf95021_right",
|
||||
default_entity_id: "cover.0xa4c138018cf95021_right",
|
||||
origin: origin,
|
||||
position_template: "{{ value_json.position }}",
|
||||
position_template: '{{ value_json["position"] }}',
|
||||
position_topic: "zigbee2mqtt/0xa4c138018cf95021/right",
|
||||
set_position_template: '{ "position_right": {{ position }} }',
|
||||
set_position_topic: "zigbee2mqtt/0xa4c138018cf95021/right/set",
|
||||
@@ -1450,11 +1460,9 @@ describe("Extension: HomeAssistant", () => {
|
||||
state_stopped: "STOP",
|
||||
state_topic: "zigbee2mqtt/0xa4c138018cf95021/right",
|
||||
unique_id: "0xa4c138018cf95021_cover_right_zigbee2mqtt",
|
||||
value_template: '{% if "moving" in value_json and value_json.moving %} {{ value_json.moving }} {% else %} STOP {% endif %}',
|
||||
value_template: '{% if "moving" in value_json and value_json["moving"] %} {{ value_json["moving"] }} {% else %} STOP {% endif %}',
|
||||
};
|
||||
|
||||
console.log(mockMQTTPublishAsync.mock.calls.find((c) => c[0] === "homeassistant/cover/0xa4c138018cf95021/cover_left/config"));
|
||||
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/cover/0xa4c138018cf95021/cover_left/config", stringify(payload_left), {
|
||||
retain: true,
|
||||
qos: 1,
|
||||
@@ -1473,7 +1481,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
unit_of_measurement: "°C",
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
enabled_by_default: true,
|
||||
object_id: "weather_sensor_temperature",
|
||||
@@ -1561,6 +1569,8 @@ describe("Extension: HomeAssistant", () => {
|
||||
color: {hue: 0, saturation: 100, h: 0, s: 100},
|
||||
color_mode: "hs",
|
||||
effect: null,
|
||||
effect_color: null,
|
||||
effect_speed: null,
|
||||
linkquality: null,
|
||||
state: null,
|
||||
power_on_behavior: null,
|
||||
@@ -1584,6 +1594,8 @@ describe("Extension: HomeAssistant", () => {
|
||||
color: {x: 0.4576, y: 0.41},
|
||||
color_mode: "xy",
|
||||
effect: null,
|
||||
effect_color: null,
|
||||
effect_speed: null,
|
||||
linkquality: null,
|
||||
state: null,
|
||||
power_on_behavior: null,
|
||||
@@ -1606,6 +1618,8 @@ describe("Extension: HomeAssistant", () => {
|
||||
stringify({
|
||||
linkquality: null,
|
||||
effect: null,
|
||||
effect_color: null,
|
||||
effect_speed: null,
|
||||
state: "ON",
|
||||
power_on_behavior: null,
|
||||
update: {state: null, installed_version: -1, latest_version: -1},
|
||||
@@ -1653,7 +1667,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
device_class: "temperature",
|
||||
enabled_by_default: true,
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_temperature",
|
||||
@@ -1814,7 +1828,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
device_class: "temperature",
|
||||
enabled_by_default: true,
|
||||
state_class: "measurement",
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_temperature",
|
||||
@@ -1884,7 +1898,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
enabled_by_default: true,
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor_renamed",
|
||||
object_id: "weather_sensor_renamed_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_renamed_temperature",
|
||||
@@ -1968,6 +1982,16 @@ describe("Extension: HomeAssistant", () => {
|
||||
"candle",
|
||||
"fireplace",
|
||||
"colorloop",
|
||||
"sunset",
|
||||
"sunrise",
|
||||
"sparkle",
|
||||
"opal",
|
||||
"glisten",
|
||||
"underwater",
|
||||
"cosmos",
|
||||
"sunbeam",
|
||||
"enchant",
|
||||
"none",
|
||||
"finish_effect",
|
||||
"stop_effect",
|
||||
"stop_hue_effect",
|
||||
@@ -2008,7 +2032,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
enabled_by_default: true,
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor_renamed",
|
||||
object_id: "weather_sensor_renamed_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_renamed_temperature",
|
||||
@@ -2438,6 +2462,16 @@ describe("Extension: HomeAssistant", () => {
|
||||
"candle",
|
||||
"fireplace",
|
||||
"colorloop",
|
||||
"sunset",
|
||||
"sunrise",
|
||||
"sparkle",
|
||||
"opal",
|
||||
"glisten",
|
||||
"underwater",
|
||||
"cosmos",
|
||||
"sunbeam",
|
||||
"enchant",
|
||||
"none",
|
||||
"finish_effect",
|
||||
"stop_effect",
|
||||
"stop_hue_effect",
|
||||
@@ -2484,6 +2518,16 @@ describe("Extension: HomeAssistant", () => {
|
||||
"candle",
|
||||
"fireplace",
|
||||
"colorloop",
|
||||
"sunset",
|
||||
"sunrise",
|
||||
"sparkle",
|
||||
"opal",
|
||||
"glisten",
|
||||
"underwater",
|
||||
"cosmos",
|
||||
"sunbeam",
|
||||
"enchant",
|
||||
"none",
|
||||
"finish_effect",
|
||||
"stop_effect",
|
||||
"stop_hue_effect",
|
||||
@@ -2598,7 +2642,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
device_class: "temperature",
|
||||
state_class: "measurement",
|
||||
enabled_by_default: true,
|
||||
value_template: "{{ value_json.temperature }}",
|
||||
value_template: '{{ value_json["temperature"] }}',
|
||||
state_topic: "zigbee2mqtt/weather_sensor",
|
||||
object_id: "weather_sensor_temperature",
|
||||
default_entity_id: "sensor.weather_sensor_temperature",
|
||||
@@ -2965,7 +3009,7 @@ describe("Extension: HomeAssistant", () => {
|
||||
origin: origin,
|
||||
state_topic: "zigbee2mqtt/0x18fc26000000cafe",
|
||||
unique_id: "0x18fc26000000cafe_device_mode_zigbee2mqtt",
|
||||
value_template: "{{ value_json.device_mode }}",
|
||||
value_template: '{{ value_json["device_mode"] }}',
|
||||
};
|
||||
expect(mockMQTTPublishAsync).toHaveBeenCalledWith("homeassistant/select/0x18fc26000000cafe/device_mode/config", stringify(payload), {
|
||||
retain: true,
|
||||
|
||||
@@ -286,7 +286,7 @@ describe("Extension: NetworkMap", () => {
|
||||
description: "Hue Go",
|
||||
model: "7146060PH",
|
||||
supports:
|
||||
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality",
|
||||
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, effect_speed, effect_color, linkquality",
|
||||
vendor: "Philips",
|
||||
},
|
||||
failed: [],
|
||||
@@ -616,7 +616,7 @@ describe("Extension: NetworkMap", () => {
|
||||
description: "Hue Go",
|
||||
model: "7146060PH",
|
||||
supports:
|
||||
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality",
|
||||
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, effect_speed, effect_color, linkquality",
|
||||
vendor: "Philips",
|
||||
},
|
||||
failed: [],
|
||||
@@ -785,7 +785,7 @@ describe("Extension: NetworkMap", () => {
|
||||
description: "Hue Go",
|
||||
model: "7146060PH",
|
||||
supports:
|
||||
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality",
|
||||
"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, effect_speed, effect_color, linkquality",
|
||||
vendor: "Philips",
|
||||
},
|
||||
failed: [],
|
||||
|
||||
@@ -90,6 +90,7 @@ const SETTINGS_MINIMAL_DEFAULTS = {
|
||||
network_key: "GENERATE",
|
||||
pan_id: "GENERATE",
|
||||
ext_pan_id: "GENERATE",
|
||||
enable_external_js: false,
|
||||
},
|
||||
frontend: {
|
||||
enabled: settings.defaults.frontend!.enabled,
|
||||
@@ -147,6 +148,7 @@ const SAMPLE_SETTINGS_SAVE = {
|
||||
network_key: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
|
||||
pan_id: 12345,
|
||||
ext_pan_id: [8, 7, 6, 5, 4, 3, 2, 1],
|
||||
enable_external_js: false,
|
||||
},
|
||||
frontend: {
|
||||
enabled: true,
|
||||
@@ -963,6 +965,7 @@ describe("Onboarding", () => {
|
||||
network_key: "GENERATE",
|
||||
pan_id: "GENERATE",
|
||||
ext_pan_id: "GENERATE",
|
||||
enable_external_js: false,
|
||||
},
|
||||
serial: {
|
||||
port: SAMPLE_SETTINGS_SAVE.serial.port,
|
||||
|
||||
Reference in New Issue
Block a user