Compare commits

...
76 Commits
Author SHA1 Message Date
Koen Kanters 06b3395cff chore(dev): release 1.35.2 (#20636) 2024-02-01 17:20:18 +01:00
Koen KantersandKoenkk 0b59a51c3c fix(ignore): update zigbee-herdsman-converters to 18.25.1 (#21129)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-31 19:36:04 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 1cee011ca0 chore: Bump peter-evans/create-pull-request from 5 to 6 (#21122)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 5 to 6.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v5...v6)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-31 19:59:19 +01:00
Koen Kanters 630b4ec560 chore: merge master to dev 2024-01-30 21:03:09 +01:00
koenkk 4b6f50daf3 chore: fix update dep auto merge 2024-01-30 21:02:50 +01:00
Koen KantersandKoenkk 0361b13b66 Update zigbee-herdsman-converters to 18.25.0 (#21114)
* fix(ignore): update zigbee-herdsman-converters to 18.25.0

* fix

---------

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-30 20:58:29 +01:00
Koen KantersandKoenkk 49dea233b6 fix(ignore): update zigbee-herdsman to 0.33.5 (#21113)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-30 20:24:23 +01:00
koenkk c16abdd832 fix: Use Alpine 3.18.4 as base https://github.com/Koenkk/zigbee2mqtt/issues/20868 2024-01-30 20:13:08 +01:00
koenkk c37f3e834e chore: remove onlythis 2024-01-30 20:12:52 +01:00
Koen KantersandKoenkk f3e79df4b4 fix(ignore): update zigbee-herdsman-converters to 18.24.0 (#21106)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-29 20:13:02 +00:00
Koen KantersandKoenkk 03ba745e46 fix(ignore): update zigbee-herdsman to 0.33.4 (#21104)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-29 19:02:40 +00:00
Koen KantersandKoenkk 7e7d3c6328 fix(ignore): update zigbee-herdsman-converters to 18.23.1 (#21093)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-28 20:03:43 +00:00
Koen KantersandKoenkk 59001babca fix(ignore): update zigbee-herdsman to 0.33.3 (#21094)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-28 19:52:46 +00:00
Koen KantersandKoenkk 0d716288bf Update zigbee-herdsman-converters to 18.22.0 (#21040)
* fix(ignore): update zigbee-herdsman-converters to 18.22.0

* Update homeassistant.test.js

---------

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-27 08:55:15 +00:00
Koen KantersandKoenkk a879382cbd fix(ignore): update zigbee-herdsman-converters to 18.21.0 (#21012)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-25 19:23:45 +00:00
Koen Kantersandnurikk a858798054 fix(ignore): update zigbee2mqtt-frontend to 0.6.152 (#21003)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2024-01-25 11:15:44 +00:00
Koen KantersandKoenkk 416e561b32 fix(ignore): update zigbee-herdsman-converters to 18.20.0 (#20996)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-24 21:07:36 +00:00
Koen KantersandKoenkk a240487bb4 fix(ignore): update zigbee-herdsman to 0.33.2 (#20994)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-24 22:04:17 +01:00
Koen KantersandKoenkk 518972882c fix(ignore): update zigbee-herdsman-converters to 18.19.0 (#20966)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-23 19:23:56 +00:00
Koen KantersandKoenkk ed639ec9d7 fix(ignore): update zigbee-herdsman to 0.33.1 (#20965)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-23 18:56:19 +00:00
Der Mundschenk & Compagnie 6372d84259 fix: Republish correctly on scene changes to Home Assistant (#20952) 2024-01-23 19:25:18 +01:00
Koen KantersandKoenkk 45579dcf10 Update zigbee-herdsman-converters to 18.18.0 (#20933)
* fix(ignore): update zigbee-herdsman-converters to 18.18.0

* Update bridge.test.js

---------

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-22 20:02:57 +00:00
chrthiandKoen Kanters 97eac16aaf fix: Notify systemd for start, stop, watchdog (#20482)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2024-01-21 21:49:17 +01:00
Koen KantersandKoenkk 032557b1db fix(ignore): update zigbee-herdsman to 0.33.0 (#20932)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-21 20:35:49 +00:00
Koen KantersandKoenkk de7bc7cf60 fix(ignore): update zigbee-herdsman-converters to 18.17.0 (#20907)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-20 08:56:11 +00:00
Sergei Salimov 92588fefe3 fix: Home Assistant: additional icons for Aqara TRV entities and various others (#20903)
* Add schedule and schedule_settings icons

* Add various missing entities
2024-01-20 08:36:18 +01:00
Koen KantersandKoenkk 8de20e2cf1 fix(ignore): update zigbee-herdsman-converters to 18.16.0 (#20901)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-19 19:49:09 +00:00
Koen KantersandKoenkk a1360d8e90 fix(ignore): update zigbee-herdsman to 0.32.7 (#20900)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-19 19:26:05 +00:00
Koen KantersandKoenkk 9f3b10235c fix(ignore): update zigbee-herdsman-converters to 18.15.1 (#20876)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-18 21:15:15 +00:00
dependabot[bot] 1d6d386a47 chore: Bump actions/dependency-review-action from 3 to 4 (#20869) 2024-01-18 18:34:20 +01:00
dependabot[bot] 76ea57b732 chore: Bump actions/cache from 3 to 4 (#20870) 2024-01-18 18:34:04 +01:00
slugzero e76f568f0f fix: Remove deprecated sendWhen (#20861) 2024-01-18 18:28:52 +01:00
Koen KantersandKoenkk 080f3b6b50 fix(ignore): update zigbee-herdsman-converters to 18.15.0 (#20860)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-17 20:04:51 +00:00
koenkk a741b2f598 fix: Revert "Enable incremental TSC builds (#19293)" https://github.com/Koenkk/zigbee2mqtt/discussions/20805 2024-01-17 19:55:55 +01:00
mrskycriper ac74fac1db fix: Added icon and device_class for some Aqara device entities (#20746)
* Update homeassistant.ts

* Update homeassistant.ts

* Update homeassistant.ts

* Update homeassistant.ts

* Remove entity_category and add some icons and device classes

* Remove device_class for calibrated because of inverted state mapping
2024-01-17 19:44:52 +01:00
Koen KantersandKoenkk ab9124a517 fix(ignore): update zigbee-herdsman-converters to 18.14.0 (#20847)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-16 21:37:36 +00:00
Koen KantersandKoenkk 4e997c7b83 fix(ignore): update zigbee-herdsman to 0.32.6 (#20846)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-16 20:12:52 +00:00
slugzero 0007db42b0 fix(ignore): Ability to trigger events from converters on incoming Zigbee messages (#20776)
* emit event on converter triggers

* use meta.deviceExposesChanged() instead

* add ExposesChanged event for homeassistant discovery

* add tests for receive.ts and homeassistant.ts
2024-01-15 21:08:08 +01:00
Koen KantersandKoenkk 6ccbb11fc2 fix(ignore): update zigbee-herdsman-converters to 18.13.0 (#20828)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-15 21:07:35 +01:00
Koen KantersandKoenkk 4fe4e2ec2f fix(ignore): update zigbee-herdsman to 0.32.5 (#20826)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-15 19:09:15 +00:00
Koen KantersandKoenkk 2bd7df84eb Update zigbee-herdsman-converters to 18.12.0 (#20775)
* fix(ignore): update zigbee-herdsman-converters to 18.12.0

* Update configure.test.js

---------

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-13 20:06:27 +00:00
Koen KantersandKoenkk ec3e37350d fix(ignore): update zigbee-herdsman to 0.32.4 (#20772)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-13 19:34:18 +00:00
Koen KantersandKoenkk 769bc14163 fix(ignore): update zigbee-herdsman to 0.32.3 (#20744)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-11 19:45:05 +00:00
Koen KantersandKoenkk a38b88455f fix(ignore): update zigbee-herdsman-converters to 18.11.0 (#20742)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-11 19:39:54 +00:00
Koen KantersandKoenkk 9a9bcd503e fix(ignore): update zigbee-herdsman to 0.32.2 (#20726)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-10 20:34:35 +00:00
Koen Kanters f58ee7ad58 chore: merge master to dev 2024-01-10 08:18:53 +01:00
Nerivec 3c9620428e chore: Add 'setup' field to problem report template (#20708)
Allow to discern patterns of behaviors emerging from specific setups (virtualization, low resource devices, etc).
2024-01-10 08:18:34 +01:00
Koen KantersandKoenkk 2bf244c2de fix(ignore): update zigbee-herdsman to 0.32.1 (#20706)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-09 20:26:46 +00:00
Koen KantersandKoenkk 5c8f95ae01 fix(ignore): update zigbee-herdsman-converters to 18.10.1 (#20705)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-09 20:23:01 +00:00
slugzero 363792aee8 fix: Set Home Assistant entity categories config and diagnostic according to expose categories (#20663)
* Add exposes starting with 'config' or 'diagnostic' to respective Home Assistant categories

* alt proposal: default category based on new Expose property

* Use single category 'system' instead of 'config' and 'diagnostic'

* Revert "Use single category 'system' instead of 'config' and 'diagnostic'"

This reverts commit 416dd9c568.

* lint
2024-01-09 19:54:49 +01:00
Koen KantersandKoenkk ce7d022fda Update zigbee-herdsman-converters to 18.10.0 (#20682)
* fix(ignore): update zigbee-herdsman-converters to 18.10.0

* Update bridge.test.js

* Update bridge.test.js

---------

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-08 20:14:03 +00:00
Koen KantersandKoenkk 52f25eb101 fix(ignore): update zigbee-herdsman to 0.32.0 (#20681)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-08 19:27:08 +00:00
Koen KantersandKoenkk ef84ff86fe fix(ignore): update zigbee-herdsman to 0.31.0 (#20639)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-07 13:19:05 +00:00
koenkk dfbe93ef9d chore: fix release ci 2024-01-07 14:14:14 +01:00
koenkk 6bbe8d1844 chore: promote to dev 2024-01-07 14:08:07 +01:00
Koen Kanters 9eaaa0f9d1 chore(dev): release 1.35.1 (#20580) 2024-01-07 13:50:18 +01:00
koenkk 0807049b6c chore: fix changelog generator 2024-01-07 13:47:56 +01:00
Koen KantersandKoenkk 759c235923 fix(ignore): update zigbee-herdsman-converters to 18.9.0 (#20635)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-07 12:36:55 +00:00
Koen KantersandKoenkk 14ac9a8f68 fix(ignore): update zigbee-herdsman-converters to 18.8.0 (#20613)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-06 12:33:39 +00:00
Koen KantersandKoenkk d942db9a92 Update zigbee-herdsman-converters to 18.7.0 (#20607)
* fix(ignore): update zigbee-herdsman-converters to 18.7.0

* Update bridge.test.js

* Update frontend.test.js

---------

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-06 10:32:21 +00:00
koenkk 212c70913c fix: Prevent extension errors from crashing Zigbee2MQTT https://github.com/Koenkk/zigbee2mqtt/issues/20477 2024-01-06 10:19:56 +01:00
Koen KantersandKoenkk b17c22bb50 fix(ignore): update zigbee-herdsman-converters to 18.6.0 (#20585)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-05 10:01:40 +00:00
koenkk c8c5ea2de3 chore: fix release-please 2024-01-04 22:34:33 +01:00
koenkk 00230baedf chore: fix release-please 2024-01-04 22:32:02 +01:00
koenkk 540969be21 chore: fix release-please 2024-01-04 22:30:28 +01:00
Koen KantersandKoenkk 804182e30c Update zigbee-herdsman-converters to 18.5.0 (#20573)
* fix(ignore): update zigbee-herdsman-converters to 18.5.0

* Update receive.ts

---------

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-04 16:35:17 +01:00
Der Mundschenk & Compagnie 99a57bfd08 fix: Prevent warnings for bridge entities with legacy_entity_attributes enabled (#20548) 2024-01-04 14:54:39 +01:00
Der Mundschenk & Compagnie b8edf273c6 fix: Support legacy_availability_payload for Home Assistant connection_state (#20547) 2024-01-04 14:38:29 +01:00
koenkk e9aee4c6dc fix: Fix configure on startup crashing coordinator https://github.com/Koenkk/zigbee2mqtt/issues/20526 2024-01-03 10:51:05 +01:00
koenkk e6bcf91e17 fix: Fix crash due to unhandled Promise exception https://github.com/Koenkk/zigbee2mqtt/issues/20473 2024-01-03 09:09:18 +01:00
Koen KantersandKoenkk 7e37365a5f fix(ignore): update zigbee-herdsman-converters to 18.4.0 (#20523)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2024-01-02 22:00:24 +00:00
koenkk 32b1d5b073 fix: Fix Home Assistant program not truncated when too large https://github.com/Koenkk/zigbee2mqtt/issues/19788 2024-01-02 21:42:49 +01:00
Koen Kantersandnurikk cb7b773e0d fix(ignore): update zigbee2mqtt-frontend to 0.6.151 (#20509)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2024-01-02 14:36:20 +00:00
Koen Kanters 84387b27a4 chore: merge master to dev 2024-01-01 13:22:32 +01:00
koenkk 3d8f0fc3a8 chore: fix release-please 2024-01-01 13:22:03 +01:00
koenkk 02a587f745 chore: promote to dev 2024-01-01 12:33:54 +01:00
33 changed files with 482 additions and 246 deletions
@@ -57,6 +57,14 @@ body:
placeholder: Electrolama zig-a-zig-ah! (zzh!), Slaesh's CC2652RB stick, ...
validations:
required: true
- type: input
id: setup
attributes:
label: Setup
description: How do you run Z2M (plain, add-on...) and on what machine (Pi, x86-64, containerized...)?
placeholder: Add-on on Home Assistant OS on Intel NUC, Plain on Docker container, ...
validations:
required: true
- type: textarea
id: log
attributes:
+34 -4
View File
@@ -41,7 +41,7 @@ jobs:
uses: docker/setup-buildx-action@v3
with:
version: latest
- name: Docker build dev
- name: "dev: Docker build"
if: github.ref == 'refs/heads/dev' && github.event_name == 'push'
run: |
docker buildx build \
@@ -52,7 +52,7 @@ jobs:
--push \
-t koenkk/zigbee2mqtt:latest-dev -t ghcr.io/koenkk/zigbee2mqtt:latest-dev \
.
- name: Docker build release
- name: "release: Docker build"
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
run: |
TAG="$(git describe --tags)"
@@ -64,12 +64,12 @@ jobs:
--push \
-t koenkk/zigbee2mqtt:latest -t "koenkk/zigbee2mqtt:$TAG" -t ghcr.io/koenkk/zigbee2mqtt:latest -t "ghcr.io/koenkk/zigbee2mqtt:$TAG" \
.
- name: Publish to npm
- name: "release: Publish to npm"
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN }}
- name: Trigger zigbee2mqtt/hassio-zigbee2mqtt build
- name: "dev: Trigger zigbee2mqtt/hassio-zigbee2mqtt build"
if: github.ref == 'refs/heads/dev' && github.event_name == 'push'
run: |
curl \
@@ -78,6 +78,36 @@ jobs:
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/zigbee2mqtt/hassio-zigbee2mqtt/actions/workflows/ci.yml/dispatches \
-d '{"ref":"master","inputs":{}}'
- name: "release: Trigger zigbee2mqtt/hassio-zigbee2mqtt build"
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
run: |
TAG=${GITHUB_REF#refs/*/}
echo "Triggering with tag '$TAG'"
curl \
-X POST \
-H "Authorization: token ${{ secrets.GH_TOKEN }}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" \
https://api.github.com/repos/zigbee2mqtt/hassio-zigbee2mqtt/dispatches \
--data "{\"event_type\": \"release\", \"client_payload\": { \"version\": \"$TAG-1\"}}"
- name: "release: merge dev -> master and promote dev"
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
run: |
TAG=${GITHUB_REF#refs/*/}
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git fetch origin
git checkout master
git merge -m 'chore: merge dev to master' origin/dev
git push origin master
git checkout dev
jq ".version = \"$TAG-dev\"" package.json > package.json.tmp
jq ".version = \"$TAG-dev\"" package-lock.json > package-lock.json.tmp
mv package.json.tmp package.json
mv package-lock.json.tmp package-lock.json
git add -A
git commit -m "chore: promote to dev"
git push origin dev
tests:
strategy:
+1 -1
View File
@@ -11,4 +11,4 @@ jobs:
- name: 'Checkout repository'
uses: actions/checkout@v4
- name: 'Dependency review'
uses: actions/dependency-review-action@v3
uses: actions/dependency-review-action@v4
+4 -52
View File
@@ -23,7 +23,6 @@ jobs:
- uses: google-github-actions/release-please-action@v4
id: release
with:
release-type: node
target-branch: dev
token: ${{secrets.GH_TOKEN}}
@@ -39,7 +38,7 @@ jobs:
ref: master
- name: Restore cache commit-user-lookup.json
uses: actions/cache/restore@v3
uses: actions/cache/restore@v4
with:
path: z2m/scripts/commit-user-lookup.json
key: commit-user-lookup-dummy
@@ -51,67 +50,20 @@ jobs:
MASTER_ZHC_VERSION=$(cat z2m-master/package.json | jq -r '.dependencies."zigbee-herdsman-converters"')
MASTER_ZH_VERSION=$(cat z2m-master/package.json | jq -r '.dependencies."zigbee-herdsman"')
MASTER_FRONTEND_VERSION=$(cat z2m-master/package.json | jq -r '.dependencies."zigbee2mqtt-frontend"')
wget -q -O - https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/release-please--branches--dev--components--release-please-action/CHANGELOG.md > z2m/CHANGELOG.md || true
wget -q -O - https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/release-please--branches--dev--components--zigbee2mqtt/CHANGELOG.md > z2m/CHANGELOG.md
cd z2m
npm ci
node scripts/generateChangelog.js $MASTER_Z2M_VERSION $MASTER_ZHC_VERSION $MASTER_ZH_VERSION $MASTER_FRONTEND_VERSION >> ../changelog.md
env:
GH_TOKEN: ${{secrets.GH_TOKEN}}
- name: Update changelog in release PR
- name: Update changelog gist
run: |
gh gist edit bfd4c3d1725a2cccacc11d6ba51008ba -a changelog.md
env:
GH_TOKEN: ${{secrets.GH_TOKEN}}
- name: Upload changelog
uses: actions/upload-artifact@v4
with:
name: changelog
path: changelog.md
- name: Save cache commit-user-lookup.json
uses: actions/cache/save@v3
uses: actions/cache/save@v4
if: always()
with:
path: z2m/scripts/commit-user-lookup.json
key: commit-user-lookup-${{ hashFiles('z2m/scripts/commit-user-lookup.json') }}
create_release:
runs-on: ubuntu-latest
needs: [release-please]
if: ${{ needs.release-please.outputs.release_created }}
steps:
- uses: actions/checkout@v4
with:
ref: dev
token: ${{secrets.GH_TOKEN}}
- name: Merge dev -> master
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git checkout master
git merge -m 'chore: merge dev to master'
git push origin master
- name: Promote to dev
run: |
jq '.version = "${{ needs.release-please.outputs.version }}-dev"' package.json > package.json.tmp
jq '.version = "${{ needs.release-please.outputs.version }}-dev"' package-lock.json > package-lock.json.tmp
mv package.json.tmp package.json
mv package-lock.json.tmp package-lock.json
- uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: promote to dev"
- name: Download changelog
uses: actions/download-artifact@v4
with:
name: changelog
path: ../changelog
- name: update release
id: update_release
uses: tubone24/update_release@v1.0
env:
GITHUB_TOKEN: ${{ github.token }}
TAG_NAME: ${{ needs.release-please.outputs.version }}
with:
body_path: ../changelog/changelog.md
- name: Trigger HA addon update
run: |
curl -XPOST -H "Authorization: token ${{ secrets.GH_TOKEN }}" -H "Accept: application/vnd.github.everest-preview+json" -H "Content-Type: application/json" https://api.github.com/repos/zigbee2mqtt/hassio-zigbee2mqtt/dispatches --data "{\"event_type\": \"release\", \"client_payload\": { \"version\": \"${{ needs.release-please.outputs.version }}-1\"}}"
+4 -6
View File
@@ -22,7 +22,7 @@ jobs:
node-version: 20
cache: npm
- run: npm install ${{ github.event.client_payload.package }}@${{ github.event.client_payload.version }} --save-exact
- uses: peter-evans/create-pull-request@v5
- uses: peter-evans/create-pull-request@v6
id: cpr
with:
commit-message: "fix(ignore): update ${{ github.event.client_payload.package }} to ${{ github.event.client_payload.version }}"
@@ -30,9 +30,7 @@ jobs:
title: Update ${{ github.event.client_payload.package }} to ${{ github.event.client_payload.version }}
token: ${{ secrets.GH_TOKEN }}
- run: sleep 5 # Otherwise pull request may not exist yet causing automerge to fail
- uses: peter-evans/enable-pull-request-automerge@v3
- run: gh pr merge --squash --auto "${{ steps.cpr.outputs.pull-request-number }}"
if: steps.cpr.outputs.pull-request-operation == 'created'
with:
token: ${{ secrets.GH_TOKEN }}
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
merge-method: squash
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
- run: npx npm-check-updates -u -x connect-gzip-static
- run: rm -f package-lock.json
- run: npm install
- uses: peter-evans/create-pull-request@v5
- uses: peter-evans/create-pull-request@v6
with:
commit-message: "fix(ignore): update dependencies"
branch: "deps/all"
+1 -3
View File
@@ -1,5 +1,3 @@
{
".": "1.35.0",
"bootstrap-sha": "7ee207fc0e05f32c9636c0298b48eea1b91ed9e1",
"include-v-in-tag": false
".": "1.35.2"
}
+62
View File
@@ -1,5 +1,67 @@
# Changelog
## [1.35.2](https://github.com/Koenkk/zigbee2mqtt/compare/1.35.1...1.35.2) (2024-01-31)
### Bug Fixes
* Added icon and device_class for some Aqara device entities ([#20746](https://github.com/Koenkk/zigbee2mqtt/issues/20746)) ([ac74fac](https://github.com/Koenkk/zigbee2mqtt/commit/ac74fac1db9b1ee6d473c5045989003548e451f6))
* Home Assistant: additional icons for Aqara TRV entities and various others ([#20903](https://github.com/Koenkk/zigbee2mqtt/issues/20903)) ([92588fe](https://github.com/Koenkk/zigbee2mqtt/commit/92588fefe3f10783c93c145b9b937c39bd6a5773))
* **ignore:** Ability to trigger events from converters on incoming Zigbee messages ([#20776](https://github.com/Koenkk/zigbee2mqtt/issues/20776)) ([0007db4](https://github.com/Koenkk/zigbee2mqtt/commit/0007db42b0365c0b14510f2b03f60277a2a22303))
* **ignore:** update zigbee-herdsman to 0.31.0 ([#20639](https://github.com/Koenkk/zigbee2mqtt/issues/20639)) ([ef84ff8](https://github.com/Koenkk/zigbee2mqtt/commit/ef84ff86fed89d0957961580f92541b20546b951))
* **ignore:** update zigbee-herdsman to 0.32.0 ([#20681](https://github.com/Koenkk/zigbee2mqtt/issues/20681)) ([52f25eb](https://github.com/Koenkk/zigbee2mqtt/commit/52f25eb101ba6102a2c9fcb20d0bb9c56d1bd627))
* **ignore:** update zigbee-herdsman to 0.32.1 ([#20706](https://github.com/Koenkk/zigbee2mqtt/issues/20706)) ([2bf244c](https://github.com/Koenkk/zigbee2mqtt/commit/2bf244c2dea1b6c9db6f8273dcb03e4a40fbe18a))
* **ignore:** update zigbee-herdsman to 0.32.2 ([#20726](https://github.com/Koenkk/zigbee2mqtt/issues/20726)) ([9a9bcd5](https://github.com/Koenkk/zigbee2mqtt/commit/9a9bcd503eb736d3227dcf4fd3853739cfee293a))
* **ignore:** update zigbee-herdsman to 0.32.3 ([#20744](https://github.com/Koenkk/zigbee2mqtt/issues/20744)) ([769bc14](https://github.com/Koenkk/zigbee2mqtt/commit/769bc14163666df402d52abba4c14a7eef99667a))
* **ignore:** update zigbee-herdsman to 0.32.4 ([#20772](https://github.com/Koenkk/zigbee2mqtt/issues/20772)) ([ec3e373](https://github.com/Koenkk/zigbee2mqtt/commit/ec3e37350dde666512d7a966dd28db54d3da7e7c))
* **ignore:** update zigbee-herdsman to 0.32.5 ([#20826](https://github.com/Koenkk/zigbee2mqtt/issues/20826)) ([4fe4e2e](https://github.com/Koenkk/zigbee2mqtt/commit/4fe4e2ec2f9d0d1a6173c7cca2641204c702e933))
* **ignore:** update zigbee-herdsman to 0.32.6 ([#20846](https://github.com/Koenkk/zigbee2mqtt/issues/20846)) ([4e997c7](https://github.com/Koenkk/zigbee2mqtt/commit/4e997c7b83772dfbd73272f7ebd3acbda1a1c55e))
* **ignore:** update zigbee-herdsman to 0.32.7 ([#20900](https://github.com/Koenkk/zigbee2mqtt/issues/20900)) ([a1360d8](https://github.com/Koenkk/zigbee2mqtt/commit/a1360d8e901ae0c5b3e3987215794e48f56ec65d))
* **ignore:** update zigbee-herdsman to 0.33.0 ([#20932](https://github.com/Koenkk/zigbee2mqtt/issues/20932)) ([032557b](https://github.com/Koenkk/zigbee2mqtt/commit/032557b1dbf810872cef61c3a65e2f6df93441e7))
* **ignore:** update zigbee-herdsman to 0.33.1 ([#20965](https://github.com/Koenkk/zigbee2mqtt/issues/20965)) ([ed639ec](https://github.com/Koenkk/zigbee2mqtt/commit/ed639ec9d7867785aeb776c63c927929b365993d))
* **ignore:** update zigbee-herdsman to 0.33.2 ([#20994](https://github.com/Koenkk/zigbee2mqtt/issues/20994)) ([a240487](https://github.com/Koenkk/zigbee2mqtt/commit/a240487bb4711a1403fd1f069a8f32dc454e5b55))
* **ignore:** update zigbee-herdsman to 0.33.3 ([#21094](https://github.com/Koenkk/zigbee2mqtt/issues/21094)) ([59001ba](https://github.com/Koenkk/zigbee2mqtt/commit/59001babca79f04938127e1592f553106b2b0b9f))
* **ignore:** update zigbee-herdsman to 0.33.4 ([#21104](https://github.com/Koenkk/zigbee2mqtt/issues/21104)) ([03ba745](https://github.com/Koenkk/zigbee2mqtt/commit/03ba745e46b849cf7a62bdf598b8bf1d128281d2))
* **ignore:** update zigbee-herdsman to 0.33.5 ([#21113](https://github.com/Koenkk/zigbee2mqtt/issues/21113)) ([49dea23](https://github.com/Koenkk/zigbee2mqtt/commit/49dea233b6248d699a2d0f641ce0a84c9b91e92c))
* **ignore:** update zigbee-herdsman-converters to 18.10.1 ([#20705](https://github.com/Koenkk/zigbee2mqtt/issues/20705)) ([5c8f95a](https://github.com/Koenkk/zigbee2mqtt/commit/5c8f95ae0146aff91c305643c9fa41c8dc690fa7))
* **ignore:** update zigbee-herdsman-converters to 18.11.0 ([#20742](https://github.com/Koenkk/zigbee2mqtt/issues/20742)) ([a38b884](https://github.com/Koenkk/zigbee2mqtt/commit/a38b88455f8a77fe5e9997f05374d3454b100b41))
* **ignore:** update zigbee-herdsman-converters to 18.13.0 ([#20828](https://github.com/Koenkk/zigbee2mqtt/issues/20828)) ([6ccbb11](https://github.com/Koenkk/zigbee2mqtt/commit/6ccbb11fc20d63f86eea03ffc26c9bd790b2ee5e))
* **ignore:** update zigbee-herdsman-converters to 18.14.0 ([#20847](https://github.com/Koenkk/zigbee2mqtt/issues/20847)) ([ab9124a](https://github.com/Koenkk/zigbee2mqtt/commit/ab9124a5179bd87d496944d7bab5794eab6505e3))
* **ignore:** update zigbee-herdsman-converters to 18.15.0 ([#20860](https://github.com/Koenkk/zigbee2mqtt/issues/20860)) ([080f3b6](https://github.com/Koenkk/zigbee2mqtt/commit/080f3b6b50c58636aa217d143a0f3d18fbb55c7f))
* **ignore:** update zigbee-herdsman-converters to 18.15.1 ([#20876](https://github.com/Koenkk/zigbee2mqtt/issues/20876)) ([9f3b102](https://github.com/Koenkk/zigbee2mqtt/commit/9f3b10235cf0f5db38098c4a73bd64d4d53ba6c2))
* **ignore:** update zigbee-herdsman-converters to 18.16.0 ([#20901](https://github.com/Koenkk/zigbee2mqtt/issues/20901)) ([8de20e2](https://github.com/Koenkk/zigbee2mqtt/commit/8de20e2cf1107366dd958c7e781a2011f7dd8f2d))
* **ignore:** update zigbee-herdsman-converters to 18.17.0 ([#20907](https://github.com/Koenkk/zigbee2mqtt/issues/20907)) ([de7bc7c](https://github.com/Koenkk/zigbee2mqtt/commit/de7bc7cf60752874262f684ac7f3923057aab3c2))
* **ignore:** update zigbee-herdsman-converters to 18.19.0 ([#20966](https://github.com/Koenkk/zigbee2mqtt/issues/20966)) ([5189728](https://github.com/Koenkk/zigbee2mqtt/commit/518972882c7a02bfc076aa5093853f23947d769d))
* **ignore:** update zigbee-herdsman-converters to 18.20.0 ([#20996](https://github.com/Koenkk/zigbee2mqtt/issues/20996)) ([416e561](https://github.com/Koenkk/zigbee2mqtt/commit/416e561b329b65fa50af23e08c3d82cbc52387da))
* **ignore:** update zigbee-herdsman-converters to 18.21.0 ([#21012](https://github.com/Koenkk/zigbee2mqtt/issues/21012)) ([a879382](https://github.com/Koenkk/zigbee2mqtt/commit/a879382cbd32bd0935d91b62e6cbbf2a0c9987a4))
* **ignore:** update zigbee-herdsman-converters to 18.23.1 ([#21093](https://github.com/Koenkk/zigbee2mqtt/issues/21093)) ([7e7d3c6](https://github.com/Koenkk/zigbee2mqtt/commit/7e7d3c6328c0cbd89264d6313367dbd1295b0b42))
* **ignore:** update zigbee-herdsman-converters to 18.24.0 ([#21106](https://github.com/Koenkk/zigbee2mqtt/issues/21106)) ([f3e79df](https://github.com/Koenkk/zigbee2mqtt/commit/f3e79df4b4c7a5c68a70375e25507e58c6378b1a))
* **ignore:** update zigbee-herdsman-converters to 18.25.1 ([#21129](https://github.com/Koenkk/zigbee2mqtt/issues/21129)) ([0b59a51](https://github.com/Koenkk/zigbee2mqtt/commit/0b59a51c3c740da5c5d7b86514651c21a5c7387b))
* **ignore:** update zigbee2mqtt-frontend to 0.6.152 ([#21003](https://github.com/Koenkk/zigbee2mqtt/issues/21003)) ([a858798](https://github.com/Koenkk/zigbee2mqtt/commit/a85879805489761d429d1dec4d98c1ae2ebd9400))
* Notify systemd for start, stop, watchdog ([#20482](https://github.com/Koenkk/zigbee2mqtt/issues/20482)) ([97eac16](https://github.com/Koenkk/zigbee2mqtt/commit/97eac16aaf10d9bec4a5353b07ae3ebef92868e5))
* Remove deprecated sendWhen ([#20861](https://github.com/Koenkk/zigbee2mqtt/issues/20861)) ([e76f568](https://github.com/Koenkk/zigbee2mqtt/commit/e76f568f0fe0a36e5324b20b8ca3173f618cd8e6))
* Republish correctly on scene changes to Home Assistant ([#20952](https://github.com/Koenkk/zigbee2mqtt/issues/20952)) ([6372d84](https://github.com/Koenkk/zigbee2mqtt/commit/6372d842596240685ead4a5a10f9a739ec208504))
* Revert "Enable incremental TSC builds ([#19293](https://github.com/Koenkk/zigbee2mqtt/issues/19293))" https://github.com/Koenkk/zigbee2mqtt/discussions/20805 ([a741b2f](https://github.com/Koenkk/zigbee2mqtt/commit/a741b2f598159e1fbd6799619d0e575ad11c0256))
* Set Home Assistant entity categories `config` and `diagnostic` according to expose categories ([#20663](https://github.com/Koenkk/zigbee2mqtt/issues/20663)) ([363792a](https://github.com/Koenkk/zigbee2mqtt/commit/363792aee8f9535163e7c0aa3e5b9961165fc088))
* Use Alpine 3.18.4 as base https://github.com/Koenkk/zigbee2mqtt/issues/20868 ([c16abdd](https://github.com/Koenkk/zigbee2mqtt/commit/c16abdd83233c51fa5f7d6b56db6b19bea9b81f6))
## [1.35.1](https://github.com/Koenkk/zigbee2mqtt/compare/1.35.0...1.35.1) (2024-01-07)
### Bug Fixes
* Fix configure on startup crashing coordinator https://github.com/Koenkk/zigbee2mqtt/issues/20526 ([e9aee4c](https://github.com/Koenkk/zigbee2mqtt/commit/e9aee4c6dc1b7dcfedfa821723b029e1a0423d15))
* Fix crash due to unhandled Promise exception https://github.com/Koenkk/zigbee2mqtt/issues/20473 ([e6bcf91](https://github.com/Koenkk/zigbee2mqtt/commit/e6bcf91e17747eff38ce7774107d697aeff4be15))
* Fix Home Assistant `program` not truncated when too large https://github.com/Koenkk/zigbee2mqtt/issues/19788 ([32b1d5b](https://github.com/Koenkk/zigbee2mqtt/commit/32b1d5b0732544a2026f8582f8bb12a3e5691b2b))
* **ignore:** update zigbee-herdsman-converters to 18.4.0 ([#20523](https://github.com/Koenkk/zigbee2mqtt/issues/20523)) ([7e37365](https://github.com/Koenkk/zigbee2mqtt/commit/7e37365a5faec6d8d33db406ed18d5492fa2fc19))
* **ignore:** update zigbee-herdsman-converters to 18.6.0 ([#20585](https://github.com/Koenkk/zigbee2mqtt/issues/20585)) ([b17c22b](https://github.com/Koenkk/zigbee2mqtt/commit/b17c22bb501599fcc68685ff0fc65642d1dea9ca))
* **ignore:** update zigbee-herdsman-converters to 18.8.0 ([#20613](https://github.com/Koenkk/zigbee2mqtt/issues/20613)) ([14ac9a8](https://github.com/Koenkk/zigbee2mqtt/commit/14ac9a8f68480c433450cb1f33f8feda00359268))
* **ignore:** update zigbee-herdsman-converters to 18.9.0 ([#20635](https://github.com/Koenkk/zigbee2mqtt/issues/20635)) ([759c235](https://github.com/Koenkk/zigbee2mqtt/commit/759c2359234a5f83b9a7f2a5b97e75aef9d0d567))
* **ignore:** update zigbee2mqtt-frontend to 0.6.151 ([#20509](https://github.com/Koenkk/zigbee2mqtt/issues/20509)) ([cb7b773](https://github.com/Koenkk/zigbee2mqtt/commit/cb7b773e0defb1e28dc17af42e3807e7628338df))
* Prevent extension errors from crashing Zigbee2MQTT https://github.com/Koenkk/zigbee2mqtt/issues/20477 ([212c709](https://github.com/Koenkk/zigbee2mqtt/commit/212c70913c06a97dea8dac7d532a7d601c69a3d1))
* Prevent warnings for bridge entities with legacy_entity_attributes enabled ([#20548](https://github.com/Koenkk/zigbee2mqtt/issues/20548)) ([99a57bf](https://github.com/Koenkk/zigbee2mqtt/commit/99a57bfd080fcf311f7cc45e7d0d04cdc0a6138a))
* Support legacy_availability_payload for Home Assistant connection_state ([#20547](https://github.com/Koenkk/zigbee2mqtt/issues/20547)) ([b8edf27](https://github.com/Koenkk/zigbee2mqtt/commit/b8edf273c6de799e30c95c607f315f02b0dcacdd))
## [1.35.0](https://github.com/Koenkk/zigbee2mqtt/compare/1.34.0...v1.35.0) (2024-01-01)
+1 -1
View File
@@ -1,4 +1,4 @@
FROM alpine:3.18.5 as base
FROM alpine:3.18.4 as base
WORKDIR /app
RUN apk add --no-cache tzdata eudev tini nodejs
+19 -4
View File
@@ -39,6 +39,14 @@ const AllExtensions = [
type ExtensionArgs = [Zigbee, MQTT, State, PublishEntityState, EventBus,
(enable: boolean, name: string) => Promise<void>, () => void, (extension: Extension) => Promise<void>];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let sdNotify: any = null;
try {
sdNotify = process.env.NOTIFY_SOCKET ? require('sd-notify') : null;
} catch {
// sd-notify is optional
}
export class Controller {
private eventBus: EventBus;
private zigbee: Zigbee;
@@ -51,10 +59,7 @@ export class Controller {
constructor(restartCallback: () => void, exitCallback: (code: number, restart: boolean) => void) {
logger.init();
this.eventBus = new EventBus( /* istanbul ignore next */ (error) => {
logger.error(`Error: ${error.message}`);
logger.debug(error.stack);
});
this.eventBus = new EventBus();
this.zigbee = new Zigbee(this.eventBus);
this.mqtt = new MQTT(this.eventBus);
this.state = new State(this.eventBus, this.zigbee);
@@ -165,6 +170,12 @@ export class Controller {
(data) => utils.publishLastSeen(data, settings.get(), false, this.publishEntityState));
logger.info(`Zigbee2MQTT started!`);
const watchdogInterval = sdNotify?.watchdogInterval() || 0;
if (watchdogInterval > 0) {
sdNotify.startWatchdogMode(Math.floor(watchdogInterval / 2));
}
sdNotify?.ready();
}
@bind async enableDisableExtension(enable: boolean, name: string): Promise<void> {
@@ -189,6 +200,8 @@ export class Controller {
}
async stop(restart = false): Promise<void> {
sdNotify?.stopping();
// Call extensions
await this.callExtensions('stop', this.extensions);
this.eventBus.removeListeners(this);
@@ -205,6 +218,8 @@ export class Controller {
logger.error('Failed to stop Zigbee2MQTT');
await this.exit(1, restart);
}
sdNotify?.stopWatchdogMode();
}
async exit(code: number, restart = false): Promise<void> {
+23 -9
View File
@@ -1,5 +1,5 @@
import events from 'events';
events.captureRejections = true;
import logger from './util/logger';
// eslint-disable-next-line
type ListenerKey = object;
@@ -8,9 +8,8 @@ export default class EventBus {
private callbacksByExtension: { [s: string]: { event: string, callback: (...args: unknown[]) => void }[] } = {};
private emitter = new events.EventEmitter();
constructor(onError: (error: Error) => void) {
constructor() {
this.emitter.setMaxListeners(100);
this.emitter.on('error', onError);
}
public emitAdapterDisconnected(): void {
@@ -91,6 +90,13 @@ export default class EventBus {
this.on('entityOptionsChanged', callback, key);
}
public emitExposesChanged(data: eventdata.ExposesChanged): void {
this.emitter.emit('exposesChanged', data);
}
public onExposesChanged(key: ListenerKey, callback: (data: eventdata.ExposesChanged) => void): void {
this.on('exposesChanged', callback, key);
}
public emitDeviceLeave(data: eventdata.DeviceLeave): void {
this.emitter.emit('deviceLeave', data);
}
@@ -140,10 +146,10 @@ export default class EventBus {
this.on('devicesChanged', callback, key);
}
public emitScenesChanged(): void {
this.emitter.emit('scenesChanged');
public emitScenesChanged(data: eventdata.ScenesChanged): void {
this.emitter.emit('scenesChanged', data);
}
public onScenesChanged(key: ListenerKey, callback: () => void): void {
public onScenesChanged(key: ListenerKey, callback: (data: eventdata.ScenesChanged) => void): void {
this.on('scenesChanged', callback, key);
}
@@ -161,10 +167,18 @@ export default class EventBus {
this.on('stateChange', callback, key);
}
private on(event: string, callback: (...args: unknown[]) => void, key: ListenerKey): void {
private on(event: string, callback: (...args: unknown[]) => (Promise<void> | void), key: ListenerKey): void {
if (!this.callbacksByExtension[key.constructor.name]) this.callbacksByExtension[key.constructor.name] = [];
this.callbacksByExtension[key.constructor.name].push({event, callback});
this.emitter.on(event, callback);
const wrappedCallback = async (...args: unknown[]): Promise<void> => {
try {
await callback(...args);
} catch (error) {
logger.error(`EventBus error '${key.constructor.name}/${event}': ${error.message}`);
logger.debug(error.stack);
}
};
this.callbacksByExtension[key.constructor.name].push({event, callback: wrappedCallback});
this.emitter.on(event, wrappedCallback);
}
public removeListeners(key: ListenerKey): void {
+3
View File
@@ -66,6 +66,9 @@ export default class Configure extends Extension {
override async start(): Promise<void> {
setImmediate(async () => {
for (const device of this.zigbee.devices(false)) {
// Sleep 10 seconds between configuring on startup to not DDoS the coordinator
// when many devices have to be configured.
await utils.sleep(10);
await this.configure(device, 'started');
}
});
+40 -19
View File
@@ -146,6 +146,7 @@ export default class HomeAssistant extends Extension {
this.eventBus.onDeviceMessage(this, this.onZigbeeEvent);
this.eventBus.onScenesChanged(this, this.onScenesChanged);
this.eventBus.onEntityOptionsChanged(this, (data) => this.discover(data.entity, true));
this.eventBus.onExposesChanged(this, (data) => this.discover(data.device, true));
this.mqtt.subscribe(this.statusTopic);
this.mqtt.subscribe(defaultStatusTopic);
@@ -599,6 +600,7 @@ export default class HomeAssistant extends Extension {
discoveryEntries.push(discoveryEntry);
} else if (isBinaryExposeFeature(firstExpose)) {
const lookup: {[s: string]: KeyValue}= {
auto_off: {icon: 'mdi:flash-auto'},
battery_low: {entity_category: 'diagnostic', device_class: 'battery'},
button_lock: {entity_category: 'config', icon: 'mdi:lock'},
calibration: {entity_category: 'config', icon: 'mdi:progress-wrench'},
@@ -630,8 +632,10 @@ export default class HomeAssistant extends Extension {
occupancy: {device_class: 'motion'},
power_outage_memory: {entity_category: 'config', icon: 'mdi:memory'},
presence: {device_class: 'presence'},
setup: {device_class: 'running'},
smoke: {device_class: 'smoke'},
sos: {device_class: 'safety'},
schedule: {icon: 'mdi:calendar'},
status_capacitive_load: {entity_category: 'diagnostic', icon: 'mdi:tune'},
status_forward_phase_control: {entity_category: 'diagnostic', icon: 'mdi:tune'},
status_inductive_load: {entity_category: 'diagnostic', icon: 'mdi:tune'},
@@ -640,10 +644,15 @@ export default class HomeAssistant extends Extension {
tamper: {device_class: 'tamper'},
temperature_scale: {entity_category: 'config', icon: 'mdi:temperature-celsius'},
test: {entity_category: 'diagnostic', icon: 'mdi:test-tube'},
trigger_indicator: {icon: 'mdi:led-on'},
valve_alarm: {device_class: 'problem'},
valve_detection: {icon: 'mdi:pipe-valve'},
valve_state: {device_class: 'opening'},
vibration: {device_class: 'vibration'},
water_leak: {device_class: 'moisture'},
window: {device_class: 'window'},
window_detection: {icon: 'mdi:window-open-variant'},
window_open: {device_class: 'window'},
};
/**
@@ -700,6 +709,7 @@ export default class HomeAssistant extends Extension {
const lookup: {[s: string]: KeyValue} = {
ac_frequency: {device_class: 'frequency', enabled_by_default: false, entity_category: 'diagnostic',
state_class: 'measurement'},
action_duration: {icon: 'mdi:timer', device_class: 'duration'},
alarm_humidity_max: {device_class: 'humidity', entity_category: 'config', icon: 'mdi:water-plus'},
alarm_humidity_min: {device_class: 'humidity', entity_category: 'config', icon: 'mdi:water-minus'},
alarm_temperature_max: {device_class: 'temperature', entity_category: 'config',
@@ -750,6 +760,7 @@ export default class HomeAssistant extends Extension {
state_class: 'measurement',
},
deadzone_temperature: {entity_category: 'config', icon: 'mdi:thermometer'},
detection_interval: {icon: 'mdi:timer'},
device_temperature: {
device_class: 'temperature', entity_category: 'diagnostic', state_class: 'measurement',
},
@@ -757,6 +768,7 @@ export default class HomeAssistant extends Extension {
eco2: {device_class: 'carbon_dioxide', state_class: 'measurement'},
eco_temperature: {entity_category: 'config', icon: 'mdi:thermometer'},
energy: {device_class: 'energy', state_class: 'total_increasing'},
external_temperature_input: {icon: 'mdi:thermometer'},
formaldehyd: {state_class: 'measurement'},
gas_density: {icon: 'mdi:google-circles-communities', state_class: 'measurement'},
hcho: {icon: 'mdi:air-filter', state_class: 'measurement'},
@@ -781,6 +793,7 @@ export default class HomeAssistant extends Extension {
minimum_on_level: {entity_category: 'config'},
measurement_poll_interval: {entity_category: 'config', icon: 'mdi:clock-out'},
occupancy_timeout: {entity_category: 'config', icon: 'mdi:timer'},
overload_protection: {icon: 'mdi:flash'},
pm10: {device_class: 'pm10', state_class: 'measurement'},
pm25: {device_class: 'pm25', state_class: 'measurement'},
people: {state_class: 'measurement', icon: 'mdi:account-multiple'},
@@ -788,6 +801,7 @@ export default class HomeAssistant extends Extension {
power: {device_class: 'power', entity_category: 'diagnostic', state_class: 'measurement'},
power_factor: {device_class: 'power_factor', enabled_by_default: false,
entity_category: 'diagnostic', state_class: 'measurement'},
power_outage_count: {icon: 'mdi:counter'},
precision: {entity_category: 'config', icon: 'mdi:decimal-comma-increase'},
pressure: {device_class: 'atmospheric_pressure', state_class: 'measurement'},
presence_timeout: {entity_category: 'config', icon: 'mdi:timer'},
@@ -925,6 +939,7 @@ export default class HomeAssistant extends Extension {
alarm_temperature: {entity_category: 'config', icon: 'mdi:thermometer-alert'},
backlight_auto_dim: {entity_category: 'config', icon: 'mdi:brightness-auto'},
backlight_mode: {entity_category: 'config', icon: 'mdi:lightbulb'},
calibrate: {icon: 'mdi:tune'},
color_power_on_behavior: {entity_category: 'config', icon: 'mdi:palette'},
control_mode: {entity_category: 'config', icon: 'mdi:tune'},
device_mode: {entity_category: 'config', icon: 'mdi:tune'},
@@ -938,6 +953,7 @@ export default class HomeAssistant extends Extension {
melody: {entity_category: 'config', icon: 'mdi:music-note'},
mode_phase_control: {entity_category: 'config', icon: 'mdi:tune'},
mode: {entity_category: 'config', icon: 'mdi:tune'},
mode_switch: {icon: 'mdi:tune'},
motion_sensitivity: {entity_category: 'config', icon: 'mdi:tune'},
operation_mode: {entity_category: 'config', icon: 'mdi:tune'},
power_on_behavior: {entity_category: 'config', icon: 'mdi:power-settings'},
@@ -945,6 +961,7 @@ export default class HomeAssistant extends Extension {
power_supply_mode: {entity_category: 'config', icon: 'mdi:power-settings'},
power_type: {entity_category: 'config', icon: 'mdi:lightning-bolt-circle'},
sensitivity: {entity_category: 'config', icon: 'mdi:tune'},
sensor: {icon: 'mdi:tune'},
sensors_type: {entity_category: 'config', icon: 'mdi:tune'},
sound_volume: {entity_category: 'config', icon: 'mdi:volume-high'},
status: {icon: 'mdi:state-machine'},
@@ -1000,10 +1017,12 @@ export default class HomeAssistant extends Extension {
const settableText = firstExpose.type === 'text' && firstExpose.access & ACCESS_SET;
const lookup: {[s: string]: KeyValue} = {
action: {icon: 'mdi:gesture-double-tap'},
color_options: {icon: 'mdi:palette'},
level_config: {entity_category: 'diagnostic'},
programming_mode: {icon: 'mdi:calendar-clock'},
program: {value_template: `{{ value_json.${firstExpose.property}|default('',true) ` +
program: {value_template: `{{ value_json.${firstExpose.property}|default('',True) ` +
`| truncate(254, True, '', 0) }}`},
schedule_settings: {icon: 'mdi:calendar-clock'},
};
if (firstExpose.access & ACCESS_STATE) {
const discoveryEntry: DiscoveryEntry = {
@@ -1039,6 +1058,14 @@ export default class HomeAssistant extends Extension {
throw new Error(`Unsupported exposes type: '${firstExpose.type}'`);
}
// Exposes with category 'config' or 'diagnostic' are always added to the respective category.
// This takes precedence over definitions in this file.
if (firstExpose.category === 'config') {
discoveryEntries.forEach((d) => d.discovery_payload.entity_category = 'config');
} else if (firstExpose.category === 'diagnostic') {
discoveryEntries.forEach((d) => d.discovery_payload.entity_category = 'diagnostic');
}
discoveryEntries.forEach((d) => {
// If a sensor has entity category `config`, then change
// it to `diagnostic`. Sensors have no input, so can't be configured.
@@ -1378,7 +1405,7 @@ export default class HomeAssistant extends Extension {
payload.tilt_status_topic = stateTopic;
}
if (this.entityAttributes) {
if (this.entityAttributes && (isDevice || isGroup) ) {
payload.json_attributes_topic = stateTopic;
}
@@ -1640,20 +1667,15 @@ export default class HomeAssistant extends Extension {
this.discover(data.device);
}
@bind async onScenesChanged(): Promise<void> {
// Re-trigger MQTT discovery of all devices and groups, similar to bridge.ts
const entities = [...this.zigbee.devices(), ...this.zigbee.groups()];
const clearedEntities = new Set<Device|Group>();
@bind async onScenesChanged(data: eventdata.ScenesChanged): Promise<void> {
// Re-trigger MQTT discovery of changed devices and groups, similar to bridge.ts
// First, clear existing scene discovery topics
entities.forEach((entity) => {
logger.debug(`Clearing Home Assistant scene discovery topics for '${entity.name}'`);
this.discovered[this.getDiscoverKey(entity)]?.topics.forEach((topic) => {
if (topic.startsWith('scene')) {
this.mqtt.publish(topic, null, {retain: true, qos: 1}, this.discoveryTopic, false, false);
clearedEntities.add(entity);
}
});
logger.debug(`Clearing Home Assistant scene discovery topics for '${data.entity.name}'`);
this.discovered[this.getDiscoverKey(data.entity)]?.topics.forEach((topic) => {
if (topic.startsWith('scene')) {
this.mqtt.publish(topic, null, {retain: true, qos: 1}, this.discoveryTopic, false, false);
}
});
// Make sure Home Assistant deletes the old entity first otherwise another one (_2) is created
@@ -1661,11 +1683,9 @@ export default class HomeAssistant extends Extension {
logger.debug(`Finished clearing scene discovery topics, waiting for Home Assistant.`);
await utils.sleep(2);
// Re-discover all entities (including their new scenes).
// Re-discover entity (including any new scenes).
logger.debug(`Re-discovering entities with their scenes.`);
clearedEntities.forEach((entity) => {
this.discover(entity, true);
});
this.discover(data.entity, true);
}
private getDevicePayload(entity: Device | Group | Bridge): KeyValue {
@@ -1796,6 +1816,7 @@ export default class HomeAssistant extends Extension {
const discovery: DiscoveryEntry[] = [];
const bridge = new Bridge(coordinatorIeeeAddress, coordinatorVersion, discovery);
const baseTopic = `${settings.get().mqtt.base_topic}/${bridge.name}`;
const legacyAvailability = settings.get().advanced.legacy_availability_payload;
discovery.push(
// Binary sensors.
@@ -1809,7 +1830,7 @@ export default class HomeAssistant extends Extension {
entity_category: 'diagnostic',
state_topic: true,
state_topic_postfix: 'state',
value_template: '{{ value_json.state }}',
value_template: !legacyAvailability ? '{{ value_json.state }}' : '{{ value }}',
payload_on: 'online',
payload_off: 'offline',
availability: false,
+3 -3
View File
@@ -125,11 +125,11 @@ export default class OTAUpdate extends Extension {
logger.debug(`Responded to OTA request of '${data.device.name}' with 'NO_IMAGE_AVAILABLE'`);
}
private async readSoftwareBuildIDAndDateCode(device: Device, sendWhen: 'active' | 'immediate'):
private async readSoftwareBuildIDAndDateCode(device: Device, sendPolicy?: 'immediate'):
Promise<{softwareBuildID: string, dateCode: string}> {
try {
const endpoint = device.zh.endpoints.find((e) => e.supportsInputCluster('genBasic'));
const result = await endpoint.read('genBasic', ['dateCode', 'swBuildId'], {sendWhen});
const result = await endpoint.read('genBasic', ['dateCode', 'swBuildId'], {sendPolicy});
return {softwareBuildID: result.swBuildId, dateCode: result.dateCode};
} catch (e) {
return null;
@@ -273,7 +273,7 @@ export default class OTAUpdate extends Extension {
const payload = this.getEntityPublishPayload(device,
{available: false, currentFileVersion: fileVersion, otaFileVersion: fileVersion});
this.publishEntityState(device, payload);
const to = await this.readSoftwareBuildIDAndDateCode(device, 'active');
const to = await this.readSoftwareBuildIDAndDateCode(device);
const [fromS, toS] = [stringify(from_), stringify(to)];
logger.info(`Device '${device.name}' was updated from '${fromS}' to '${toS}'`);
responseData.from = from_ ? utils.toSnakeCase(from_) : null;
+1 -1
View File
@@ -298,7 +298,7 @@ export default class Publish extends Extension {
const scenesChanged = Object.values(usedConverters)
.some((cl) => cl.some((c) => c.key.some((k) => sceneConverterKeys.includes(k))));
if (scenesChanged) {
this.eventBus.emitScenesChanged();
this.eventBus.emitScenesChanged({entity: re});
}
}
}
+8 -2
View File
@@ -118,7 +118,7 @@ export default class Receive extends Extension {
// for e.g. click switches where we need to count number of clicks and detect long presses.
const publish = (payload: KeyValue): void => {
const options: KeyValue = data.device.options;
zhc.postProcessConvertedFromZigbeeMessage(data.device.definition, payload, options);
zhc.postProcessConvertedFromZigbeeMessage(data.device.definition, payload, options, logger);
if (settings.get().advanced.elapsed) {
const now = Date.now();
@@ -138,7 +138,13 @@ export default class Receive extends Extension {
}
};
const meta = {device: data.device.zh, logger, state: this.state.get(data.device)};
const deviceExposesChanged = (): void => {
this.eventBus.emitDevicesChanged();
this.eventBus.emitExposesChanged({device: data.device});
};
const meta = {device: data.device.zh, logger, state: this.state.get(data.device),
deviceExposesChanged: deviceExposesChanged};
let payload: KeyValue = {};
for (const converter of converters) {
try {
+2
View File
@@ -90,6 +90,7 @@ declare global {
type DeviceInterview = { device: Device, status: 'started' | 'successful' | 'failed' };
type DeviceJoined = { device: Device };
type EntityOptionsChanged = { entity: Device | Group, from: KeyValue, to: KeyValue };
type ExposesChanged = { device: Device };
type Reconfigure = { device: Device };
type DeviceLeave = { ieeeAddr: string, name: string };
type GroupMembersChanged = {group: Group, action: 'remove' | 'add' | 'remove_all',
@@ -106,6 +107,7 @@ declare global {
data: KeyValue | Array<string | number>;
meta: {zclTransactionSequenceNumber?: number; manufacturerCode?: number; frameControl?: ZHFrameControl;};
};
type ScenesChanged = { entity: Device | Group };
}
// Settings
+67 -40
View File
@@ -1,12 +1,12 @@
{
"name": "zigbee2mqtt",
"version": "1.35.0",
"version": "1.35.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "zigbee2mqtt",
"version": "1.35.0",
"version": "1.35.2",
"license": "GPL-3.0",
"dependencies": {
"ajv": "^8.12.0",
@@ -33,9 +33,9 @@
"winston-syslog": "^2.7.0",
"winston-transport": "^4.6.0",
"ws": "^8.16.0",
"zigbee-herdsman": "0.30.0",
"zigbee-herdsman-converters": "18.3.0",
"zigbee2mqtt-frontend": "0.6.150"
"zigbee-herdsman": "0.33.5",
"zigbee-herdsman-converters": "18.25.1",
"zigbee2mqtt-frontend": "0.6.152"
},
"bin": {
"zigbee2mqtt": "cli.js"
@@ -67,6 +67,9 @@
},
"engines": {
"node": "^18 || ^20 || ^21"
},
"optionalDependencies": {
"sd-notify": "^2.8.0"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -3597,11 +3600,6 @@
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
},
"node_modules/array-flatten": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
"integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ=="
},
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -3622,11 +3620,11 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz",
"integrity": "sha512-fWyNdeawGam70jXSVlKl+SUNVcL6j6W79CuSIPfi6HnDUmSCH6gyUys/HrqHeA/wU0Az41rRgean494d0Jb+ww==",
"version": "1.6.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz",
"integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==",
"dependencies": {
"follow-redirects": "^1.15.0",
"follow-redirects": "^1.15.4",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
@@ -3936,12 +3934,10 @@
}
},
"node_modules/bonjour-service": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.1.1.tgz",
"integrity": "sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz",
"integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==",
"dependencies": {
"array-flatten": "^2.1.2",
"dns-equal": "^1.0.0",
"fast-deep-equal": "^3.1.3",
"multicast-dns": "^7.2.5"
}
@@ -4502,11 +4498,6 @@
"node": ">=8"
}
},
"node_modules/dns-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
"integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg=="
},
"node_modules/dns-packet": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
@@ -5715,6 +5706,17 @@
"resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.31.0.tgz",
"integrity": "sha512-fRrehgBG26NNZysRlTq1S+HPtDpp3u+Jzdc/d5A4cEzOD86YLAkDaJyJg8krSdCi7CJ+s7ht3fwRj8Dl+Btd0w=="
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -8764,6 +8766,29 @@
"node": ">=10"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/sd-notify": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/sd-notify/-/sd-notify-2.8.0.tgz",
"integrity": "sha512-e+D1v0Y6UzmqXcPlaTkHk1QMdqk36mF/jIYv5gwry/N2Tb8/UNnpfG6ktGLpeBOR6TCC5hPKgqA+0hTl9sm2tA==",
"hasInstallScript": true,
"optional": true,
"os": [
"linux",
"darwin",
"win32"
],
"dependencies": {
"bindings": "1.5.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@@ -9120,9 +9145,9 @@
}
},
"node_modules/tar-stream": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
"integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz",
"integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==",
"dependencies": {
"b4a": "^1.6.4",
"fast-fifo": "^1.2.0",
@@ -9782,14 +9807,14 @@
}
},
"node_modules/zigbee-herdsman": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/zigbee-herdsman/-/zigbee-herdsman-0.30.0.tgz",
"integrity": "sha512-EHnO34Ra0911cuUbhu6xWnQA9Weaerosd69oxpPbtNgnx6amRsA94SfbXxYM7hHZP4h1wJ0xfysyRbIat8v8vQ==",
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/zigbee-herdsman/-/zigbee-herdsman-0.33.5.tgz",
"integrity": "sha512-oA02QU4jM44OjSPdJ3GM90HAIU1Emk2csiTXAZas0Is6FAY3S1Gv6SoO+lhqxBzMugPFp+AZI/kgPg9W3B0Umw==",
"dependencies": {
"@serialport/bindings-cpp": "^12.0.1",
"@serialport/parser-delimiter": "^12.0.0",
"@serialport/stream": "^12.0.0",
"bonjour-service": "^1.1.1",
"bonjour-service": "^1.2.1",
"debounce": "^2.0.0",
"debug": "^4.3.4",
"fast-deep-equal": "^3.1.3",
@@ -9799,21 +9824,23 @@
}
},
"node_modules/zigbee-herdsman-converters": {
"version": "18.3.0",
"resolved": "https://registry.npmjs.org/zigbee-herdsman-converters/-/zigbee-herdsman-converters-18.3.0.tgz",
"integrity": "sha512-JYyHtU3iB9KYHdmSEG1sF+Xf3RqAGEXol8udK9e0aNiP8TObUwQmqfRS8SPhBVW/A3IgOUyS0opT/lE+/51M5A==",
"version": "18.25.1",
"resolved": "https://registry.npmjs.org/zigbee-herdsman-converters/-/zigbee-herdsman-converters-18.25.1.tgz",
"integrity": "sha512-7Y2aTI+BhyI56mmSf0rhnOcVV+PxJAtKd+HH/shs4/cyxuyR/rdq0EuJNXva/NeTRRpglV6kflVsJ4n+gcS7XQ==",
"dependencies": {
"axios": "^1.6.3",
"axios": "^1.6.5",
"buffer-crc32": "^0.2.13",
"https-proxy-agent": "^7.0.2",
"tar-stream": "^3.1.6",
"zigbee-herdsman": "^0.30.0"
"iconv-lite": "^0.6.3",
"semver": "^7.5.4",
"tar-stream": "^3.1.7",
"zigbee-herdsman": "^0.33.5"
}
},
"node_modules/zigbee2mqtt-frontend": {
"version": "0.6.150",
"resolved": "https://registry.npmjs.org/zigbee2mqtt-frontend/-/zigbee2mqtt-frontend-0.6.150.tgz",
"integrity": "sha512-+BGvDQcKC0XUtVLChwFc2kBJwQkC+SA/VAsAH8tzMwx5riVrflKOH0ewnUYamT/vAqQM0cxZB9Jfnip8mXds3Q==",
"version": "0.6.152",
"resolved": "https://registry.npmjs.org/zigbee2mqtt-frontend/-/zigbee2mqtt-frontend-0.6.152.tgz",
"integrity": "sha512-Nl8E6e1DLlI+DpIlIKRsygs3cdEmTPSIvA/oH/JK3JJ4jGZcNnOGe3hBPL95jv1Z/ZPS2huSn0PX7fnxu8zT4g==",
"engines": {
"node": ">=18"
}
+8 -7
View File
@@ -1,6 +1,6 @@
{
"name": "zigbee2mqtt",
"version": "1.35.0",
"version": "1.35.2",
"description": "Zigbee to MQTT bridge using Zigbee-herdsman",
"main": "index.js",
"repository": {
@@ -26,9 +26,7 @@
"start": "node index.js",
"test-with-coverage": "jest test --coverage",
"test": "jest test",
"test-watch": "jest test --watch",
"clean": "rimraf coverage dist tsconfig.tsbuildinfo",
"prepack": "npm run clean && npm run build"
"test-watch": "jest test --watch"
},
"author": "Koen Kanters",
"license": "GPL-3.0",
@@ -61,9 +59,9 @@
"winston-syslog": "^2.7.0",
"winston-transport": "^4.6.0",
"ws": "^8.16.0",
"zigbee-herdsman": "0.30.0",
"zigbee-herdsman-converters": "18.3.0",
"zigbee2mqtt-frontend": "0.6.150"
"zigbee-herdsman": "0.33.5",
"zigbee-herdsman-converters": "18.25.1",
"zigbee2mqtt-frontend": "0.6.152"
},
"devDependencies": {
"@babel/core": "^7.23.7",
@@ -111,5 +109,8 @@
},
"bin": {
"zigbee2mqtt": "cli.js"
},
"optionalDependencies": {
"sd-notify": "^2.8.0"
}
}
+2 -6
View File
@@ -1,14 +1,10 @@
{
"packages": {
".": {
"changelog-path": "CHANGELOG.md",
"release-type": "node",
"bump-minor-pre-major": false,
"bump-patch-for-minor-pre-major": false,
"draft": false,
"include-component-in-tag": false,
"include-v-in-tag": false,
"prerelease": true,
"skip-github-release": false
"draft": true
}
},
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
+3 -1
View File
@@ -36,10 +36,12 @@ Description=zigbee2mqtt
After=network.target
[Service]
ExecStart=/usr/bin/npm start
Type=notify
ExecStart=/usr/bin/node index.js
WorkingDirectory=/opt/zigbee2mqtt
StandardOutput=inherit
StandardError=inherit
WatchdogSec=10s
Restart=always
User=pi
+6 -5
View File
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -176,11 +176,11 @@ describe('Configure', () => {
});
it('Fail to configure via MQTT when device has no configure', async () => {
await MQTT.events.message('zigbee2mqtt/bridge/request/device/configure', stringify({id: "0x90fd9ffffe4b64ax", transaction: 20}));
await MQTT.events.message('zigbee2mqtt/bridge/request/device/configure', stringify({id: "0x0017880104e45521", transaction: 20}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bridge/response/device/configure',
stringify({"data":{"id": "0x90fd9ffffe4b64ax"},"status":"error","error": "Device 'ZNLDP12LM' cannot be configured","transaction":20}),
stringify({"data":{"id": "0x0017880104e45521"},"status":"error","error": "Device 'button_double_key' cannot be configured","transaction":20}),
{retain: false, qos: 0}, expect.any(Function)
);
});
@@ -200,9 +200,9 @@ describe('Configure', () => {
});
it('Legacy api: Should skip reconfigure when device does not require this', async () => {
await MQTT.events.message('zigbee2mqtt/bridge/configure', '0x90fd9ffffe4b64ax');
await MQTT.events.message('zigbee2mqtt/bridge/configure', '0x0017880104e45521');
await flushPromises();
expect(logger.warn).toHaveBeenCalledWith(`Skipping configure of 'ZNLDP12LM', device does not require this.`)
expect(logger.warn).toHaveBeenCalledWith(`Skipping configure of 'button_double_key', device does not require this.`)
});
it('Should not configure when interview not completed', async () => {
+21
View File
@@ -1,3 +1,4 @@
process.env.NOTIFY_SOCKET = "mocked";
const data = require('./stub/data');
const logger = require('./stub/logger');
const zigbeeHerdsman = require('./stub/zigbeeHerdsman');
@@ -16,6 +17,16 @@ const mocksClear = [
const fs = require('fs');
jest.mock('sd-notify', () => {
return {
watchdogInterval: () => {return 3000;},
startWatchdogMode: (interval) => {},
stopWatchdogMode: () => {},
ready: () => {},
stopping: () => {},
};
}, {virtual: true});
describe('Controller', () => {
let controller;
let mockExit;
@@ -730,4 +741,14 @@ describe('Controller', () => {
await controller.stop();
expect(controller.state.state[device.ieeeAddr]).toStrictEqual(undefined);
});
it('EventBus should handle errors', async () => {
const eventbus = controller.eventBus;
const callback = jest.fn().mockImplementation(async () => {throw new Error('Whoops!')});
eventbus.onStateChange('test', callback);
eventbus.emitStateChange({});
await flushPromises();
expect(callback).toHaveBeenCalledTimes(1);
expect(logger.error).toHaveBeenCalledWith(`EventBus error 'String/stateChange': Whoops!`);
});
});
+1
View File
@@ -67,6 +67,7 @@ jest.mock('https', () => ({
mockHTTPS.variables.onRequest = onRequest;
return mockHTTPS.implementation;
}),
Agent: jest.fn(),
}));
jest.mock("connect-gzip-static", () =>
+117 -66
View File
@@ -5,9 +5,8 @@ const logger = require('./stub/logger');
const zigbeeHerdsman = require('./stub/zigbeeHerdsman');
const flushPromises = require('./lib/flushPromises');
const MQTT = require('./stub/mqtt');
const sleep = require('./stub/sleep');
const Controller = require('../lib/controller');
const fs = require('fs');
const path = require('path');
describe('HomeAssistant extension', () => {
let version;
@@ -42,12 +41,14 @@ describe('HomeAssistant extension', () => {
settings.reRead();
data.writeEmptyState();
MQTT.publish.mockClear();
sleep.mock();
controller = new Controller(false);
await controller.start();
});
afterAll(async () => {
jest.useRealTimers();
sleep.restore();
});
it('Should not have duplicate type/object_ids in a mapping', () => {
@@ -170,8 +171,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -200,8 +201,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -229,8 +230,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -259,8 +260,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -290,8 +291,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -311,8 +312,8 @@ describe('HomeAssistant extension', () => {
"identifiers":[
"zigbee2mqtt_0x0017880104e45542"
],
"manufacturer":"Xiaomi",
"model":"Aqara double key wired wall switch without neutral wire. Doesn't work as a router and doesn't support power meter (QBKG03LM)",
"manufacturer":"Aqara",
"model":"Smart wall switch (no neutral, double rocker) (QBKG03LM)",
"name":"wall_switch_double",
"sw_version": null,
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
@@ -342,8 +343,8 @@ describe('HomeAssistant extension', () => {
"identifiers":[
"zigbee2mqtt_0x0017880104e45542"
],
"manufacturer":"Xiaomi",
"model":"Aqara double key wired wall switch without neutral wire. Doesn't work as a router and doesn't support power meter (QBKG03LM)",
"manufacturer":"Aqara",
"model":"Smart wall switch (no neutral, double rocker) (QBKG03LM)",
"name":"wall_switch_double",
"sw_version": null,
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
@@ -440,8 +441,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -469,8 +470,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -498,8 +499,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -521,7 +522,7 @@ describe('HomeAssistant extension', () => {
temperature: {
expire_after: 90,
device: {
manufacturer: 'From Xiaomi',
manufacturer: 'From Aqara',
sw_version: 'test'
}
},
@@ -529,7 +530,7 @@ describe('HomeAssistant extension', () => {
unique_id: null,
},
device: {
manufacturer: 'Not from Xiaomi',
manufacturer: 'Not from Aqara',
model: 'custom model',
},
},
@@ -558,7 +559,7 @@ describe('HomeAssistant extension', () => {
'name': 'weather_sensor',
'sw_version': 'test',
'model': 'custom model',
'manufacturer': 'From Xiaomi',
'manufacturer': 'From Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -586,7 +587,7 @@ describe('HomeAssistant extension', () => {
'name': 'weather_sensor',
'sw_version': null,
'model': 'custom model',
'manufacturer': 'Not from Xiaomi',
'manufacturer': 'Not from Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'origin': origin,
@@ -632,8 +633,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'Weather Sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -662,8 +663,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'Weather Sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -704,8 +705,8 @@ describe('HomeAssistant extension', () => {
"identifiers": [
"zigbee2mqtt_0x0017880104e45541"
],
"manufacturer": "Xiaomi",
"model": "Aqara single key wired wall switch without neutral wire. Doesn't work as a router and doesn't support power meter (QBKG04LM)",
"manufacturer": "Aqara",
"model": "Smart wall switch (no neutral, single rocker) (QBKG04LM)",
"name": "my_switch",
"sw_version": null,
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
@@ -967,8 +968,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -1096,8 +1097,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -1234,8 +1235,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability_mode': 'all',
@@ -1311,8 +1312,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor_renamed',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -1347,8 +1348,8 @@ describe('HomeAssistant extension', () => {
],
"name":"weather_sensor_renamed",
"sw_version": null,
"model":"Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)",
"manufacturer":"Xiaomi",
"model":"Temperature and humidity sensor (WSDCGQ11LM)",
"manufacturer":"Aqara",
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
}
}),
@@ -1448,8 +1449,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor_renamed',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -1524,8 +1525,8 @@ describe('HomeAssistant extension', () => {
],
"name":"button",
"sw_version": null,
"model":"Aqara wireless switch (WXKG11LM)",
"manufacturer":"Xiaomi",
"model":"Wireless mini switch (WXKG11LM)",
"manufacturer":"Aqara",
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
}
};
@@ -1550,8 +1551,8 @@ describe('HomeAssistant extension', () => {
],
"name":"button",
"sw_version": null,
"model":"Aqara wireless switch (WXKG11LM)",
"manufacturer":"Xiaomi",
"model":"Wireless mini switch (WXKG11LM)",
"manufacturer":"Aqara",
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
}
};
@@ -1716,8 +1717,8 @@ describe('HomeAssistant extension', () => {
],
"name":"button",
"sw_version": null,
"model":"Aqara wireless switch (WXKG11LM)",
"manufacturer":"Xiaomi",
"model":"Wireless mini switch (WXKG11LM)",
"manufacturer":"Aqara",
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
}
};
@@ -1751,7 +1752,7 @@ describe('HomeAssistant extension', () => {
await MQTT.events.message('zigbee2mqtt/U202DST600ZB/l2/set', stringify({state: 'ON', brightness: 20}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/U202DST600ZB', stringify({state_l2:"ON", brightness_l2:20, linkquality: null, state_l1: null}), {"qos": 0, "retain": false}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/U202DST600ZB', stringify({state_l2:"ON", brightness_l2:20, linkquality: null, state_l1: null, power_on_behavior: null}), {"qos": 0, "retain": false}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/U202DST600ZB/l2', stringify({state:"ON", brightness:20}), {"qos": 0, "retain": false}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/U202DST600ZB/l1', stringify({state: null}), {"qos": 0, "retain": false}, expect.any(Function));
});
@@ -1891,8 +1892,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae'
},
'availability': [{topic: 'zigbee2mqtt/bridge/state'}],
@@ -2136,8 +2137,8 @@ describe('HomeAssistant extension', () => {
'identifiers': ['zigbee2mqtt_0x0017880104e45522'],
'name': 'weather_sensor',
'sw_version': null,
'model': 'Aqara temperature, humidity and pressure sensor (WSDCGQ11LM)',
'manufacturer': 'Xiaomi',
'model': 'Temperature and humidity sensor (WSDCGQ11LM)',
'manufacturer': 'Aqara',
'configuration_url': 'http://zigbee.mqtt/#/device/0x0017880104e45522/info',
'via_device': 'zigbee2mqtt_bridge_0x00124b00120144ae',
},
@@ -2153,8 +2154,12 @@ describe('HomeAssistant extension', () => {
});
it('Should rediscover scenes when a scene is changed', async () => {
// Device/endpoint scenes.
const device = controller.zigbee.resolveEntity(zigbeeHerdsman.devices.bulb_color_2);
MQTT.publish.mockClear();
controller.eventBus.emitScenesChanged();
controller.eventBus.emitScenesChanged({entity: device});
await flushPromises();
// Discovery messages for scenes have been purged.
@@ -2164,12 +2169,6 @@ describe('HomeAssistant extension', () => {
{retain: true, qos: 1},
expect.any(Function),
);
expect(MQTT.publish).toHaveBeenCalledWith(
`homeassistant/scene/1221051039810110150109113116116_9/scene_4/config`,
null,
{retain: true, qos: 1},
expect.any(Function),
);
jest.runOnlyPendingTimers();
await flushPromises();
@@ -2197,6 +2196,24 @@ describe('HomeAssistant extension', () => {
{retain: true, qos: 1},
expect.any(Function),
);
expect(MQTT.publish).toHaveBeenCalledTimes( 12 );
// Group scenes.
const group = controller.zigbee.resolveEntity('ha_discovery_group');
MQTT.publish.mockClear();
controller.eventBus.emitScenesChanged({entity: group});
await flushPromises();
// Discovery messages for scenes have been purged.
expect(MQTT.publish).toHaveBeenCalledWith(
`homeassistant/scene/1221051039810110150109113116116_9/scene_4/config`,
null,
{retain: true, qos: 1},
expect.any(Function),
);
jest.runOnlyPendingTimers();
await flushPromises();
payload = {
'name': 'Scene 4',
@@ -2222,9 +2239,7 @@ describe('HomeAssistant extension', () => {
{retain: true, qos: 1},
expect.any(Function),
);
// Only discovery entries for entities with scenes need to be republished.
expect(MQTT.publish).toHaveBeenCalledTimes( 16 );
expect(MQTT.publish).toHaveBeenCalledTimes( 6 );
});
it('Should not clear bridge entities unnecessarily', async () => {
@@ -2287,7 +2302,7 @@ describe('HomeAssistant extension', () => {
'device_class': 'connectivity',
'unique_id': 'bridge_0x00124b00120144ae_connection_state_zigbee2mqtt',
'state_topic': 'zigbee2mqtt/bridge/state',
'value_template': '{{ value_json.state }}',
'value_template': '{{ value }}',
'payload_on': 'online',
'payload_off': 'offline',
'origin': origin,
@@ -2488,4 +2503,40 @@ describe('HomeAssistant extension', () => {
expect.any(Function),
);
});
it('Should publish discovery message when a converter announces changed exposes', async () => {
MQTT.publish.mockClear();
const device = zigbeeHerdsman.devices['BMCT-SLZ'];
const data = {deviceMode: 0}
const msg = {data, cluster: 'manuSpecificBosch10', device, endpoint: device.getEndpoint(1), type: 'attributeReport', linkquality: 10};
await zigbeeHerdsman.events.message(msg);
const payload = {
'availability':[{'topic':'zigbee2mqtt/bridge/state'}],
'command_topic':'zigbee2mqtt/0x18fc26000000cafe/set/device_mode',
'device':{
'identifiers':['zigbee2mqtt_0x18fc26000000cafe'],
'manufacturer':'Bosch',
'model':'Light/shutter control unit II (BMCT-SLZ)',
'name':'0x18fc26000000cafe',
'sw_version':null,
'via_device':'zigbee2mqtt_bridge_0x00124b00120144ae'
},
'entity_category':'config',
'icon':'mdi:tune',
'json_attributes_topic':'zigbee2mqtt/0x18fc26000000cafe',
'name':'Device mode',
'object_id':'0x18fc26000000cafe_device_mode',
'options':['light','shutter','disabled'],
'origin': origin,
'state_topic':'zigbee2mqtt/0x18fc26000000cafe',
'unique_id':'0x18fc26000000cafe_device_mode_zigbee2mqtt',
'value_template':'{{ value_json.device_mode }}'
}
expect(MQTT.publish).toHaveBeenCalledWith(
"homeassistant/select/0x18fc26000000cafe/device_mode/config",
stringify(payload),
{ retain: true, qos: 1 },
expect.any(Function),
);
});
});
+6 -6
View File
@@ -20,7 +20,7 @@ const flushPromises = require('./lib/flushPromises');
const mocksClear = [MQTT.publish, logger.warn, logger.debug];
const setTimeoutNative = setTimeout;
describe('Networkmap', () => {
describe('onlythisNetworkmap', () => {
let controller;
beforeAll(async () => {
@@ -102,7 +102,7 @@ describe('Networkmap', () => {
let call = MQTT.publish.mock.calls[0];
expect(call[0]).toStrictEqual('zigbee2mqtt/bridge/networkmap/raw');
const expected = {"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, color_options, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Aqara double key wireless wall switch (2016 model)","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Xiaomi"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":{"description":"Automatically generated definition","model":"notSupportedModelID","supports":"linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]};
const expected = {"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, color_options, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Wireless remote switch (double rocker), 2016 model","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Aqara"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":{"description":"Automatically generated definition","model":"notSupportedModelID","supports":"linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]};
expect(JSON.parse(call[1])).toStrictEqual(expected);
/**
@@ -148,7 +148,7 @@ describe('Networkmap', () => {
"0x000b57fffec6a5b3" [style="rounded, filled", fillcolor="#4ea3e0", fontcolor="#ffffff", label="{bulb_color|0x000b57fffec6a5b3 (0x9dcf)|Philips Hue Go (7146060PH)|unknown}"];
"0x000b57fffec6a5b3" -> "0x00124b00120144ae" [penwidth=0.5, weight=0, color="#994444", label="120"]
"0x000b57fffec6a5b3" -> "0x000b57fffec6a5b2" [penwidth=0.5, weight=0, color="#994444", label="110"]
"0x0017880104e45521" [style="rounded, dashed, filled", fillcolor="#fff8ce", fontcolor="#000000", label="{button_double_key|0x0017880104e45521 (0x198a)|Xiaomi Aqara double key wireless wall switch (2016 model) (WXKG02LM_rev1)|9 seconds ago}"];
"0x0017880104e45521" [style="rounded, dashed, filled", fillcolor="#fff8ce", fontcolor="#000000", label="{button_double_key|0x0017880104e45521 (0x198a)|Aqara Wireless remote switch (double rocker), 2016 model (WXKG02LM_rev1)|9 seconds ago}"];
"0x0017880104e45521" -> "0x0017880104e45559" [penwidth=1, weight=0, color="#994444", label="130"]
"0x0017880104e45525" [style="rounded, filled", fillcolor="#4ea3e0", fontcolor="#ffffff", label="{0x0017880104e45525|0x0017880104e45525 (0x1988)failed: lqi,routingTable|Boef Automatically generated definition (notSupportedModelID)|9 seconds ago}"];
"0x0017880104e45559" [style="rounded, filled", fillcolor="#4ea3e0", fontcolor="#ffffff", label="{cc2530_router|0x0017880104e45559 (0x198c)|Custom devices (DiY) [CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/) (CC2530.ROUTER)|9 seconds ago}"];
@@ -227,7 +227,7 @@ describe('Networkmap', () => {
---
0x0017880104e45521 (0x198a)
---
Xiaomi Aqara double key wireless wall switch (2016 model) (WXKG02LM_rev1)
Aqara Wireless remote switch (double rocker), 2016 model (WXKG02LM_rev1)
---
9 seconds ago
]
@@ -276,7 +276,7 @@ describe('Networkmap', () => {
let call = MQTT.publish.mock.calls[0];
expect(call[0]).toStrictEqual('zigbee2mqtt/bridge/response/networkmap');
const expected = {"data":{"routes":true,"type":"raw","value":{"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, color_options, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Aqara double key wireless wall switch (2016 model)","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Xiaomi"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":{"description":"Automatically generated definition","model":"notSupportedModelID","supports":"linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]}},"status":"ok"};
const expected = {"data":{"routes":true,"type":"raw","value":{"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, color_options, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Wireless remote switch (double rocker), 2016 model","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Aqara"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":{"description":"Automatically generated definition","model":"notSupportedModelID","supports":"linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]}},"status":"ok"};
const actual = JSON.parse(call[1]);
expect(actual).toStrictEqual(expected);
});
@@ -303,7 +303,7 @@ describe('Networkmap', () => {
let call = MQTT.publish.mock.calls[0];
expect(call[0]).toStrictEqual('zigbee2mqtt/bridge/response/networkmap');
const expected = {"data":{"routes":true,"type":"raw","value":{"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Aqara double key wireless wall switch (2016 model)","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Xiaomi"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":{"description":"Automatically generated definition","model":"notSupportedModelID","supports":"linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]}},"status":"ok"}
const expected = {"data":{"routes":true,"type":"raw","value":{"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), power_on_behavior, effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Wireless remote switch (double rocker), 2016 model","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Aqara"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":{"description":"Automatically generated definition","model":"notSupportedModelID","supports":"linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]}},"status":"ok"}
const actual = JSON.parse(call[1]);
expect(actual).toStrictEqual(expected);
});
+6 -3
View File
@@ -2,6 +2,7 @@ const path = require('path');
const data = require('./stub/data');
const logger = require('./stub/logger');
const sleep = require('./stub/sleep');
const zigbeeHerdsman = require('./stub/zigbeeHerdsman');
const MQTT = require('./stub/mqtt');
const settings = require('../lib/util/settings');
@@ -35,6 +36,7 @@ describe('OTA update', () => {
settings.reRead();
jest.useFakeTimers();
controller = new Controller(jest.fn(), jest.fn());
sleep.mock();
await controller.start();
await jest.runOnlyPendingTimers();
await flushPromises();
@@ -47,6 +49,7 @@ describe('OTA update', () => {
afterAll(async () => {
jest.useRealTimers();
sleep.restore();
});
beforeEach(async () => {
@@ -86,8 +89,8 @@ describe('OTA update', () => {
expect(logger.info).toHaveBeenCalledWith(`Finished update of 'bulb'`);
expect(logger.info).toHaveBeenCalledWith(`Device 'bulb' was updated from '{"dateCode":"20190101","softwareBuildID":1}' to '{"dateCode":"20190103","softwareBuildID":3}'`);
expect(device.save).toHaveBeenCalledTimes(2);
expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendWhen': 'immediate'});
expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendWhen': 'active'});
expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendPolicy': 'immediate'});
expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {});
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb',
stringify({"update_available":false,"update":{"state":"updating","progress":0}}),
@@ -389,7 +392,7 @@ describe('OTA update', () => {
expect(logger.info).toHaveBeenCalledWith(`Device 'bulb' was updated from '{"dateCode":"20190101","softwareBuildID":1}' to '{"dateCode":"20190103","softwareBuildID":3}'`);
expect(logger.error).toHaveBeenCalledTimes(0);
expect(device.save).toHaveBeenCalledTimes(2);
expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendWhen': 'immediate'});
expect(endpoint.read).toHaveBeenCalledWith('genBasic', ['dateCode', 'swBuildId'], {'sendPolicy': 'immediate'});
});
it('Legacy api: Should handle when OTA update fails', async () => {
+3
View File
@@ -1,4 +1,5 @@
const data = require('./stub/data');
const sleep = require('./stub/sleep');
const logger = require('./stub/logger');
const zigbeeHerdsman = require('./stub/zigbeeHerdsman');
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
@@ -30,6 +31,7 @@ describe('Publish', () => {
jest.useFakeTimers();
data.writeEmptyState();
controller = new Controller(jest.fn(), jest.fn());
sleep.mock();
await controller.start();
await flushPromises();
});
@@ -56,6 +58,7 @@ describe('Publish', () => {
afterAll(async () => {
jest.runOnlyPendingTimers();
jest.useRealTimers();
sleep.restore();
});
it('Should publish messages to zigbee devices', async () => {
+10
View File
@@ -1,4 +1,5 @@
const data = require('./stub/data');
const sleep = require('./stub/sleep');
const logger = require('./stub/logger');
const stringify = require('json-stable-stringify-without-jsonify');
const zigbeeHerdsman = require('./stub/zigbeeHerdsman');
@@ -15,6 +16,7 @@ describe('Receive', () => {
beforeAll(async () => {
jest.useFakeTimers();
controller = new Controller(jest.fn(), jest.fn());
sleep.mock();
await controller.start();
await jest.runOnlyPendingTimers();
await flushPromises();
@@ -30,6 +32,7 @@ describe('Receive', () => {
afterAll(async () => {
jest.useRealTimers();
sleep.restore();
});
it('Should handle a zigbee message', async () => {
@@ -464,4 +467,11 @@ describe('Receive', () => {
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/SP600_OLD');
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({energy: 6.65, power: 496});
});
it('Should emit DevicesChanged event when a converter announces changed exposes', async () => {
const device = zigbeeHerdsman.devices['BMCT-SLZ'];
const data = {deviceMode: 0}
const payload = {data, cluster: 'manuSpecificBosch10', device, endpoint: device.getEndpoint(1), type: 'attributeReport', linkquality: 10};
await zigbeeHerdsman.events.message(payload);
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual("zigbee2mqtt/bridge/devices");
});
});
+10
View File
@@ -0,0 +1,10 @@
const utils = require('../../lib/util/utils');
const spy = jest.spyOn(utils.default, 'sleep');
export function mock() {
spy.mockImplementation(() => {});
}
export function restore() {
spy.mockRestore();
}
+2
View File
@@ -204,6 +204,8 @@ const devices = {
'heating_actuator': new Device('Router', '0x0017880104e45562', 6545,4151, [new Endpoint(1, [0,3,4,513], [1026])], true, "Mains (single phase)", "heating.actuator"),
'bj_scene_switch': new Device('EndDevice', '0xd85def11a1002caa', 50117, 4398, [new Endpoint(10, [0,4096], [3,4,5,6,8,25,768,4096], '0xd85def11a1002caa', [{target: bulb_color_2.endpoints[0], cluster: {ID: 8, name: 'genLevelCtrl'}}, {target: bulb_color_2.endpoints[0], cluster: {ID: 6, name: 'genOnOff'}}, {target: bulb_color_2.endpoints[0], cluster: {ID: 768, name: 'lightingColorCtrl'}},]), new Endpoint(11, [0,4096], [3,4,5,6,8,25,768,4096], '0xd85def11a1002caa')], true, 'Battery', 'RB01', false, 'Busch-Jaeger', '20161222', '1.2.0'),
'GW003-AS-IN-TE-FC': new Device('Router', '0x0017548104a44669', 6545,4699, [new Endpoint(1, [3], [0,3,513,514], '0x0017548104a44669')], true, "Mains (single phase)", 'Adapter Zigbee FUJITSU'),
'BMCT-SLZ': new Device('Router', '0x18fc26000000cafe', 6546,4617, [new Endpoint(1, [0,3,4,5,258,1794,2820,2821,64672], [10,25], '0x18fc26000000cafe')], true, "Mains (single phase)", 'RBSH-MMS-ZB-EU'),
}
const mock = {
+1 -2
View File
@@ -16,8 +16,7 @@
"rootDir": "lib",
"inlineSourceMap": true,
"resolveJsonModule": true,
"experimentalDecorators": true,
"incremental": true
"experimentalDecorators": true
},
"include": [
"lib/**/*",