Compare commits

...
198 Commits
Author SHA1 Message Date
Koen Kantersandgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ea39d86e6b chore: release 1.37.1 (#22569)
* chore: release dev

* chore(release): update helm-chart docs

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-05-09 22:23:15 +02:00
Koen KantersandKoenkk 06fd8a4eb1 fix(ignore): update zigbee-herdsman-converters to 19.37.2 (#22570)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-09 20:14:10 +00:00
Nerivec d26ccaed65 fix: Fix logger crashing on restart (#22565) 2024-05-09 21:42:28 +02:00
Koen KantersandKoenkk 989f667c81 fix(ignore): update zigbee-herdsman to 0.46.6 (#22558)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-09 06:17:53 +00:00
Koen Kanters cce41c20fb chore: set release-please pull-request-title-pattern 2024-05-08 23:43:55 +02:00
Koen Kanters 350c682e8f chore: make tests faster 2024-05-08 23:32:46 +02:00
Koen KantersandKoenkk 6bcb4b66b1 fix(ignore): update zigbee-herdsman to 0.46.5 (#22552)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-08 21:16:13 +00:00
Koen Kanters 58d37b0f92 chore: improve test speed 2024-05-08 23:09:23 +02:00
Koen Kanters aecdfe638b chore: another attempt to fix release_please 2024-05-08 22:55:46 +02:00
Koen KantersandKoenkk cc9a95c74e fix(ignore): update zigbee-herdsman-converters to 19.37.1 (#22549)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-08 20:49:51 +00:00
Koen Kanters 834626d2e9 chore: fix release_please.yml 2024-05-08 22:44:30 +02:00
Koen KantersandKoenkk 6b886f6268 fix(ignore): update zigbee-herdsman-converters to 19.37.0 (#22531)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-07 20:49:28 +00:00
Koen Kanters a0c9a1769f fix: Fix MQTT ECONNREFUSED error https://github.com/zigbee2mqtt/hassio-zigbee2mqtt/issues/605 2024-05-07 21:25:01 +02:00
Koen KantersandKoenkk 3544d5172e fix(ignore): update zigbee-herdsman-converters to 19.36.1 (#22503)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-06 20:00:06 +00:00
Koen KantersandKoenkk e44608a46d fix(ignore): update zigbee-herdsman to 0.46.4 (#22501)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-06 19:55:04 +00:00
Jose Luis Pedrosaandjose 6a69c16170 chore: Release please no longer overwrites .release-please-manifest.json (#22499)
Co-authored-by: jose <jose.pedrosa@reddit.com>
2024-05-06 21:43:55 +02:00
Jose Luis Pedrosaandjose b2e8b3e00c fix: Add Helm chart (#21852)
* Initial draft for helm chart

* Add CI using helm releaser

Add helm chart docummentation

Add configuration.yaml values

* Set maintainer

set right defaults on values.yaml

* Add ci to update values on chart

* Add chart version on CI

* Remove manual update of the chart

* Trigger update of Chart.yaml with release_please

* Add chart to release-please

* Add version to release-please manifest for chart

* remove the second release-please

* Update appVersion in chart.yaml too

* Add make target to generate helm-docs

* Generate docs and manage versions in release-please

* Add persistent static volumes

* Small fixes, ensure no volume works

* Fixes for static provisioned volume

* Delete yq dependency in CI

* Delete Makefile, update release-please to run doc generation directly

---------

Co-authored-by: jose <jose.pedrosa@reddit.com>
2024-05-06 20:30:09 +02:00
Koen KantersandKoenkk 358e2eee45 fix(ignore): update zigbee-herdsman-converters to 19.36.0 (#22472)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-05 20:45:29 +00:00
Koen KantersandKoenkk 316654b5d3 fix(ignore): update zigbee-herdsman to 0.46.3 (#22471)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-05 20:32:55 +00:00
Nerivec eb49f523bf fix: Add settings for finer control over debug log level (#22426)
* Add settings for finer control over debug log level.

* Updates from feedback.
2024-05-05 21:52:26 +02:00
Koen KantersandKoenkk b754b9d463 fix(ignore): update dependencies (#22456)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-05 21:44:20 +02:00
Koen KantersandKoenkk e4c9bac348 fix(ignore): update zigbee-herdsman to 0.46.2 (#22470)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-05 19:05:33 +00:00
Koen KantersandKoenkk beedfaefac fix(ignore): update zigbee-herdsman-converters to 19.35.0 (#22442)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-04 08:34:32 +00:00
Koen KantersandKoenkk 329d832337 fix(ignore): update zigbee-herdsman to 0.46.1 (#22439)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-04 07:00:44 +00:00
Koen Kantersandnurikk 23e97d0001 fix(ignore): update zigbee2mqtt-frontend to 0.6.167 (#22419)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-05-03 08:44:34 +00:00
Koen KantersandKoenkk 3a61f0acfa Update zigbee-herdsman-converters to 19.34.0 (#22411)
* fix(ignore): update zigbee-herdsman-converters to 19.34.0

* fix tests

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-02 20:20:06 +00:00
Koen Kantersandnurikk 5899436d74 fix(ignore): update zigbee2mqtt-frontend to 0.6.166 (#22410)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-05-02 20:00:06 +00:00
Koen Kanters 97d5c5c97a chore: merge master to dev 2024-05-02 21:18:48 +02:00
rbswift ee5cf5a901 chore: Improve update.sh (#22395)
Pulling without specifying how to reconcile divergent branches is discouraged and produces an ugly "hint" that can be a little disconcerting when running update.sh
2024-05-02 21:18:25 +02:00
Koen KantersandKoenkk 907591c467 fix(ignore): update zigbee-herdsman-converters to 19.33.0 (#22381)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-01 20:28:30 +00:00
Koen KantersandKoenkk 55b5f91a96 fix(ignore): update zigbee-herdsman to 0.46.0 (#22380)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-01 20:20:29 +00:00
github-actions[bot] ce915a6797 chore: promote to dev 2024-05-01 19:45:20 +00:00
Koen Kanters 46f34c8cc7 chore(dev): release 1.37.0 (#22022) 2024-05-01 21:23:10 +02:00
Koen KantersandKoenkk e03013c581 fix(ignore): update zigbee-herdsman-converters to 19.32.0 (#22377)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-05-01 19:17:13 +00:00
Koen Kantersandnurikk 8a288a9119 fix(ignore): update zigbee2mqtt-frontend to 0.6.165 (#22366)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-04-30 19:47:10 +00:00
Koen KantersandKoenkk 8e27ec24f6 fix(ignore): update zigbee-herdsman to 0.45.0 (#22365)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-30 19:38:26 +00:00
Koen KantersandKoenkk 4b291bf012 Update zigbee-herdsman-converters to 19.31.1 (#22341)
* fix(ignore): update zigbee-herdsman-converters to 19.31.1

* fix tests

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-29 20:01:56 +00:00
Koen Kantersandnurikk 10e6ad0e67 fix(ignore): update zigbee2mqtt-frontend to 0.6.164 (#22340)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-04-28 18:23:36 +00:00
Koen KantersandKoenkk 1b089ef6ae fix(ignore): update zigbee-herdsman to 0.44.0 (#22339)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-28 18:11:30 +00:00
Koen KantersandKoenkk d7e2d98a5a fix(ignore): update dependencies (#22331)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-28 08:56:01 +02:00
Koen Kanters eb69319674 chore: merge master to dev 2024-04-28 08:53:39 +02:00
Koen Kanters 8c8a6a3ecf chore: don't autoupdate eslint 2024-04-28 08:53:17 +02:00
Koen Kanters baa1d703d4 chore: don't autoupdate eslint 2024-04-28 08:50:56 +02:00
Koen KantersandKoenkk 37551265a2 fix(ignore): update zigbee-herdsman-converters to 19.29.0 (#22325)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-27 07:19:33 +00:00
Koen KantersandKoenkk 245afb1126 fix(ignore): update zigbee-herdsman-converters to 19.28.0 (#22318)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-25 20:31:11 +00:00
Koen KantersandKoenkk 389779d4e3 fix(ignore): update zigbee-herdsman to 0.43.1 (#22317)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-25 19:50:10 +00:00
Koen KantersandKoenkk df23240683 fix(ignore): update zigbee-herdsman-converters to 19.27.0 (#22301)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-23 20:46:01 +00:00
Koen KantersandKoenkk 75f9743528 fix(ignore): update zigbee-herdsman to 0.43.0 (#22300)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-23 20:25:41 +00:00
Koen Kantersandnurikk e5d632bc91 fix(ignore): update zigbee2mqtt-frontend to 0.6.163 (#22288)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-04-22 11:31:56 +00:00
Koen KantersandKoenkk 4f97a7ad2c fix(ignore): update zigbee-herdsman to 0.42.5 (#22285)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-21 20:47:08 +00:00
Koen KantersandKoenkk 4bf2ffa7dd fix(ignore): update zigbee-herdsman-converters to 19.26.0 (#22284)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-21 19:09:52 +00:00
Koen KantersandKoenkk a8f6bec673 fix(ignore): update zigbee-herdsman to 0.42.4 (#22283)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-21 19:01:53 +00:00
Koen KantersandKoenkk 80504b943d fix(ignore): update zigbee-herdsman-converters to 19.25.0 (#22266)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-20 10:04:27 +00:00
Koen KantersandKoenkk d9628df17b fix(ignore): update zigbee-herdsman-converters to 19.24.0 (#22254)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-18 20:29:12 +00:00
Koen KantersandKoenkk f7abbd5f5a fix(ignore): update zigbee-herdsman to 0.42.3 (#22253)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-18 20:15:59 +00:00
Koen KantersandKoenkk 1544317fce fix(ignore): update zigbee-herdsman-converters to 19.23.0 (#22232)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-16 19:49:38 +00:00
Koen KantersandKoenkk 172aa7461a fix(ignore): update zigbee-herdsman-converters to 19.22.0 (#22221)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-15 20:13:35 +00:00
Koen KantersandKoenkk 76f5425452 fix(ignore): update zigbee-herdsman to 0.42.2 (#22220)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-15 19:55:40 +00:00
Koen KantersandKoenkk 87aa18d14c fix(ignore): update zigbee-herdsman-converters to 19.21.0 (#22199)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-13 08:07:00 +00:00
Koen KantersandKoenkk e10ab5ccb2 fix(ignore): update zigbee-herdsman-converters to 19.20.0 (#22187)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-11 19:46:11 +00:00
f774753213 fix(ignore): update zigbee-herdsman-converters to 19.19.1 (#22171)
* fix(ignore): update zigbee-herdsman-converters to 19.19.1

* fix(configure): pass definition to function call (#22154)

* Pass definition to configure

* fix test

---------

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
Co-authored-by: Sergei Salimov <32013287+mrskycriper@users.noreply.github.com>
2024-04-10 22:02:12 +02:00
Koen KantersandKoenkk a210c238f1 fix(ignore): update zigbee-herdsman to 0.42.1 (#22143)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-10 19:56:41 +00:00
Koen KantersandKoenkk cdbbe0d49f fix(ignore): update zigbee-herdsman-converters to 19.19.0 (#22153)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-09 19:21:28 +00:00
Koen Kanters c98e5a74de fix: Remove deprecated Home Assistant color_mode (#22142) 2024-04-08 21:19:17 +02:00
Koen KantersandKoenkk 8b8d660b06 fix(ignore): update zigbee-herdsman-converters to 19.18.0 (#22141)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-08 19:14:41 +00:00
Nerivec 3c1a4afcb7 fix: Convert logger into a class (#22129) 2024-04-07 20:52:55 +02:00
Koen KantersandKoenkk cabc9f5e2f fix(ignore): update zigbee-herdsman-converters to 19.17.0 (#22122)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-07 08:46:33 +00:00
Koen KantersandKoenkk 28b8aff1ae fix(ignore): update zigbee-herdsman to 0.42.0 (#22121)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-07 10:42:45 +02:00
Koen KantersandKoenkk e7487189cf fix(ignore): update dependencies (#22007)
* fix(ignore): update dependencies

* fix

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-06 13:02:02 +02:00
Koen Kanters 92f53235f3 fix: Fix crash when stopping in case MQTT client did not connect yet (#22110) 2024-04-06 10:49:22 +00:00
Koen Kanters 002050f35b fix: Reduce MQTT publishing by excluding debug logging from bridge/logging (#22066)
* fix: Reduce MQTT publishing by excluding debug logging from `bridge/logging`

* fix tests

* fix
2024-04-06 12:44:43 +02:00
Koen KantersandKoenkk 394a3fbd8a fix(ignore): update zigbee-herdsman-converters to 19.16.0 (#22107)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-06 09:46:26 +00:00
Koen Kanters af3a0332f9 chore: Update stale.yml 2024-04-06 08:33:30 +02:00
Koen Kantersandnurikk 0c80129466 fix(ignore): update zigbee2mqtt-frontend to 0.6.162 (#22094)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-04-05 11:51:31 +00:00
Koen KantersandKoenkk ae35aaed5e fix(ignore): update zigbee-herdsman-converters to 19.15.0 (#22089)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-04 20:06:53 +00:00
Koen Kanters 9d251dbad5 fix: Disable automatic reconfigure when configureKey changes (#22088) 2024-04-04 21:47:44 +02:00
Koen KantersandKoenkk a020138f6b fix(ignore): update zigbee-herdsman to 0.41.2 (#22087)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-04 19:36:33 +00:00
Koen KantersandKoenkk 701cdda38c Update zigbee-herdsman-converters to 19.14.0 (#22065)
* fix(ignore): update zigbee-herdsman-converters to 19.14.0

* fix tests

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-04 19:33:39 +00:00
Nerivec 919c4eee73 fix: Cleanup old logger leftovers (#22069) 2024-04-04 20:24:39 +02:00
Koen KantersandKoenkk 3e913495b1 fix(ignore): update zigbee-herdsman to 0.41.1 (#22064)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-03 18:26:22 +00:00
Koen Kanters bbb6f9e042 fix: Change MQTT publish log to debug (#22063) 2024-04-03 18:13:46 +00:00
Koen Kanters cdd6fb0864 fix(ignore): fix 73566df 2024-04-02 22:39:33 +02:00
Koen Kanters 780c065fa1 fix(ignore): fix 73566dff98 2024-04-02 22:38:02 +02:00
Koen KantersandKoenkk db7d9e1120 fix(ignore): update zigbee-herdsman-converters to 19.13.0 (#22046)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-02 22:37:10 +02:00
NerivecandKoen Kanters 73566dff98 feat: Unified logging across z2m/zh/zhc (#21984)
* Unified logging across z2m/zh/zhc

* Updates

---------

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2024-04-02 22:33:51 +02:00
Koen KantersandKoenkk bd0a41107a fix(ignore): update zigbee-herdsman to 0.41.0 (#22045)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-02 22:33:26 +02:00
Koen KantersandKoenkk 62844ff637 Update zigbee-herdsman-converters to 19.12.1 (#22044)
* fix(ignore): update zigbee-herdsman-converters to 19.12.1

* fix tests

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-02 20:17:43 +00:00
github-actions[bot] 5077b03a02 chore: promote to dev 2024-04-01 18:06:23 +00:00
Koen Kanters ffc2ff1d0e chore(dev): release 1.36.1 (#21638) 2024-04-01 19:52:17 +02:00
Koen KantersandKoenkk 3aadab0925 fix(ignore): update zigbee-herdsman-converters to 19.11.2 (#22021)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-04-01 17:49:24 +00:00
Koen KantersandKoenkk 85c00b8b43 fix(ignore): update zigbee-herdsman-converters to 19.11.1 (#22014)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-31 19:12:44 +00:00
Koen KantersandKoenkk e51792c65a fix(ignore): update zigbee-herdsman-converters to 19.11.0 (#22013)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-31 18:44:03 +00:00
Koen KantersandKoenkk 1e74b2f53f fix(ignore): update zigbee-herdsman to 0.40.3 (#22010)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-31 08:01:06 +00:00
Koen KantersandKoenkk 886b5345d7 fix(ignore): update zigbee-herdsman to 0.40.2 (#22000)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-30 10:14:12 +00:00
Koen KantersandKoenkk 7d8b5374ad fix(ignore): update zigbee-herdsman-converters to 19.10.0 (#21996)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-29 19:48:10 +00:00
Koen KantersandKoenkk 0c7730f4c5 fix(ignore): update zigbee-herdsman to 0.40.1 (#21987)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-28 20:08:42 +00:00
Koen KantersandKoenkk a7aab714ba fix(ignore): update zigbee-herdsman-converters to 19.9.0 (#21970)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-27 19:57:56 +00:00
Koen KantersandKoenkk 032b9a096e fix(ignore): update zigbee-herdsman-converters to 19.8.0 (#21957)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-26 19:47:40 +00:00
Koen KantersandKoenkk 1f3d61dc7f Update zigbee-herdsman-converters to 19.7.0 (#21947)
* fix(ignore): update zigbee-herdsman-converters to 19.7.0

* fix tests

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-25 21:24:00 +00:00
Koen KantersandKoenkk 32b173c653 fix(ignore): update zigbee-herdsman-converters to 19.6.0 (#21927)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-24 13:48:20 +00:00
Koen KantersandKoenkk 8c4cd8c9aa fix(ignore): update dependencies (#21923)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-24 08:06:46 +01:00
Koen KantersandKoenkk 73423ebd60 fix(ignore): update zigbee-herdsman-converters to 19.5.0 (#21902)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-21 19:35:31 +00:00
Koen KantersandKoenkk 334e260b85 fix(ignore): update zigbee-herdsman to 0.40.0 (#21901)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-21 19:32:32 +00:00
Koen Kanters 731957dab9 chore: merge master to dev 2024-03-21 20:10:51 +01:00
wexmanandJens Weiermann 9c505fd75f chore: optimized svg logo (#21874)
* optimized svg image

* preserved original border

---------

Co-authored-by: Jens Weiermann <j.weiermann@wilms.com>
2024-03-21 20:10:33 +01:00
Koen KantersandKoenkk 25cec20f0d fix(ignore): update zigbee-herdsman-converters to 19.4.2 (#21892)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-20 20:40:45 +00:00
Koen KantersandKoenkk f05d501380 fix(ignore): update zigbee-herdsman to 0.39.1 (#21891)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-20 20:27:30 +00:00
Koen KantersandKoenkk b02c34c6e5 fix(ignore): update zigbee-herdsman-converters to 19.4.1 (#21872)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-19 20:57:38 +00:00
Koen KantersandKoenkk 801134b630 fix(ignore): update zigbee-herdsman to 0.39.0 (#21871)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-19 20:50:21 +00:00
Koen KantersandKoenkk 73d43007d4 fix(ignore): update zigbee-herdsman-converters to 19.4.0 (#21870)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-19 20:30:52 +00:00
Koen KantersandKoenkk 1a9e05e6ab fix(ignore): update zigbee-herdsman-converters to 19.3.0 (#21851)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-17 20:21:30 +00:00
Koen KantersandKoenkk 1006725b09 fix(ignore): update dependencies (#21832)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-17 10:18:56 +01:00
Koen KantersandKoenkk a4f9c49ab5 fix(ignore): update zigbee-herdsman-converters to 19.2.1 (#21801)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-14 19:58:50 +00:00
Koen KantersandKoenkk 658622880f fix(ignore): update zigbee-herdsman to 0.38.1 (#21802)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-14 20:55:17 +01:00
Koen KantersandKoenkk 720fc491ce fix(ignore): update zigbee-herdsman-converters to 19.1.1 (#21789)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-13 19:45:48 +00:00
Koen KantersandKoenkk 56feb77f2d fix(ignore): update zigbee-herdsman-converters to 19.1.0 (#21778)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-12 20:42:14 +00:00
Koen KantersandKoenkk 233d263e13 fix(ignore): update zigbee-herdsman to 0.38.0 (#21777)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-12 20:32:24 +00:00
Koen KantersandKoenkk dbd616fbe5 fix(ignore): update zigbee-herdsman-converters to 19.0.0 (#21768)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-11 20:51:22 +00:00
Koen KantersandKoenkk 86c2e90e06 Update zigbee-herdsman-converters to 18.49.0 (#21767)
* fix(ignore): update zigbee-herdsman-converters to 18.49.0

* fix tests

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-11 20:40:55 +00:00
Koen KantersandKoenkk 43610bbff4 fix(ignore): Update dependencies (#21740)
* fix(ignore): update dependencies

* fix

* fix

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-10 19:08:48 +00:00
Koen Kanters 29543bad4b fix(ignore): fix tests 2024-03-10 19:54:35 +01:00
Koen KantersandKoenkk 2a047a469c fix(ignore): update zigbee-herdsman-converters to 18.48.0 (#21753)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-10 19:45:41 +01:00
Koen Kanters 83502f2d30 fix(ignore): Update manufacturer codes (#21729) 2024-03-10 19:45:22 +01:00
Koen KantersandKoenkk b60f679814 fix(ignore): update zigbee-herdsman to 0.37.0 (#21743)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-10 19:41:50 +01:00
Sergei Salimov 14e044093c fix: Home Assistant: remove button name if device_class is present (#21726)
* Remove preset name if button has device class

* fix device_class for consumer_connected

* combine device_class checks
2024-03-08 22:39:15 +01:00
Koen KantersandKoenkk 3188038a7b fix(ignore): update zigbee-herdsman-converters to 18.47.0 (#21728)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-08 21:36:44 +00:00
Koen KantersandKoenkk ebf996acd8 fix(ignore): update zigbee-herdsman to 0.36.2 (#21727)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-08 21:26:15 +00:00
Koen KantersandKoenkk 0e0eccbd13 fix(ignore): update zigbee-herdsman-converters to 18.46.0 (#21714)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-07 21:03:26 +00:00
Koen KantersandKoenkk e834e93deb fix(ignore): update zigbee-herdsman to 0.36.1 (#21713)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-07 20:05:21 +00:00
Koen KantersandKoenkk d37c164993 fix(ignore): update zigbee-herdsman-converters to 18.45.0 (#21699)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-06 19:36:32 +00:00
Koen KantersandKoenkk 6daa7aa61d fix(ignore): update zigbee-herdsman-converters to 18.44.0 (#21690)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-05 21:36:10 +00:00
koenkk 1110d3f8ef fix: Fix incorrect update state when Z2M is restarted during OTA update https://github.com/Koenkk/zigbee2mqtt/issues/12794 2024-03-05 22:33:33 +01:00
Koen KantersandKoenkk 1d73d9d476 fix(ignore): update zigbee-herdsman to 0.36.0 (#21689)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-05 20:51:14 +00:00
Simon RettbergandKoen Kanters 2da80954d6 fix: Fix crash due to race condition during interview (#21680)
Fixes #21118
Mentioned in #21036 and #20688

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2024-03-05 21:28:35 +01:00
koenkk e2fa66a38c chore: fix ci 2024-03-05 21:23:07 +01:00
koenkk 94382ee418 chore: fix ci 2024-03-05 21:19:56 +01:00
Koen KantersandKoenkk 94c92ef021 Update zigbee-herdsman-converters to 18.43.0 (#21678)
* fix(ignore): update zigbee-herdsman-converters to 18.43.0

* Update configure.test.js

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-04 21:44:31 +00:00
Koen KantersandKoenkk 8c86849bb9 fix(ignore): update dependencies (#21657)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-04 22:32:11 +01:00
Koen KantersandKoenkk 30909d57fb fix(ignore): update zigbee-herdsman to 0.35.3 (#21677)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-04 21:23:13 +00:00
Koen Kantersandnurikk aaed8ab95e fix(ignore): update zigbee2mqtt-frontend to 0.6.161 (#21660)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-03-03 09:39:49 +00:00
Koen Kanters f24b20b133 chore: merge master to dev 2024-03-02 22:19:13 +01:00
koenkk 2a53b8e59b chore: fix release ci 2024-03-02 22:18:48 +01:00
Koen KantersandKoenkk ccaa1281a3 fix(ignore): update zigbee-herdsman to 0.35.2 (#21654)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-02 21:16:37 +00:00
Sergei Salimov 01843fe6c4 fix: Add more Home Assistant entity icons (#21652) 2024-03-02 21:46:46 +01:00
Koen Kanters 66fb672492 fix: Fix set endpoint name conversion (#21653)
* fix: Fix `set` endpoint name conversion https://github.com/Koenkk/zigbee2mqtt/issues/21646

* fix
2024-03-02 21:45:19 +01:00
koenkk 38ed953599 chore: promote to dev 2024-03-01 21:17:51 +01:00
Koen Kanters 86ed71cb1f chore(dev): release 1.36.0 (#21266) 2024-03-01 20:58:11 +01:00
Koen KantersandKoenkk ccc31670ec fix(ignore): update zigbee-herdsman-converters to 18.42.0 (#21637)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-01 19:50:46 +00:00
Koen KantersandKoenkk 0d8f5780dd fix(ignore): update zigbee-herdsman to 0.35.1 (#21636)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-03-01 19:45:01 +00:00
Koen Kantersandnurikk a8a262640f fix(ignore): update zigbee2mqtt-frontend to 0.6.159 (#21623)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-02-29 20:45:12 +00:00
Koen KantersandKoenkk 72333f0888 fix(ignore): update zigbee-herdsman-converters to 18.41.0 (#21622)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-29 20:20:07 +00:00
Koen KantersandKoenkk a84083be40 fix(ignore): update zigbee-herdsman to 0.35.0 (#21621)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-29 16:57:19 +00:00
Sergei Salimov 9b8583e778 fix: Add noise and noise_detected to HA lookup (#21610) 2024-02-29 17:42:48 +01:00
Koen KantersandKoenkk aeaa040920 fix(ignore): update zigbee-herdsman-converters to 18.40.0 (#21603)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-27 20:04:02 +00:00
Koen KantersandKoenkk 222b67b1b0 fix(ignore): update zigbee-herdsman to 0.34.9 (#21602)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-27 19:04:44 +00:00
Koen KantersandKoenkk 1ee1710a96 Update zigbee-herdsman-converters to 18.39.1 (#21590)
* fix(ignore): update zigbee-herdsman-converters to 18.39.1

* fix

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-26 21:32:08 +00:00
Koen Kanters a1e2ee7837 chore: merge master to dev 2024-02-26 21:45:09 +01:00
koenkk f04ade6d76 chore: Update problem_report template 2024-02-26 21:44:00 +01:00
Koen KantersandKoenkk fee0811893 fix(ignore): update zigbee-herdsman to 0.34.8 (#21588)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-26 19:21:45 +00:00
Koen Kanters 956003aa0a fix: Fix endpoint matching for TuYa dummy endpoints (#21576) 2024-02-26 20:02:05 +01:00
Koen KantersandKoenkk 8fb28f9e2f Update zigbee-herdsman-converters to 18.38.0 (#21568)
* fix(ignore): update zigbee-herdsman-converters to 18.38.0

* fix tests

---------

Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-25 21:09:35 +00:00
Koen KantersandKoenkk a06a0ea059 fix(ignore): update zigbee-herdsman to 0.34.7 (#21575)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-25 21:04:49 +00:00
Koen KantersandKoenkk 4f71c1e8bf fix(ignore): update zigbee-herdsman to 0.34.6 (#21567)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-25 13:57:37 +00:00
Koen KantersandKoenkk c56470c83f fix(ignore): update dependencies (#21561)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-25 14:12:46 +01:00
Koen KantersandKoenkk cc27032752 fix(ignore): update zigbee-herdsman to 0.34.5 (#21563)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-25 09:03:54 +00:00
Koen KantersandKoenkk 7c97902d4a fix(ignore): update zigbee-herdsman-converters to 18.37.1 (#21549)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-24 08:31:39 +00:00
Koen KantersandKoenkk 23959c5b0e fix(ignore): update zigbee-herdsman to 0.34.4 (#21545)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-23 20:40:51 +00:00
Koen KantersandKoenkk e726d5907e fix(ignore): update zigbee-herdsman to 0.34.3 (#21530)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-22 19:37:33 +00:00
Koen KantersandKoenkk 1337f54e4a fix(ignore): update zigbee-herdsman-converters to 18.37.0 (#21533)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-22 19:32:59 +00:00
Oleksandr Masliuchenko 471902e531 fix: Improve nested group and device name match (#21521) 2024-02-22 19:54:09 +01:00
Koen KantersandKoenkk 22d33360f6 fix(ignore): update zigbee-herdsman-converters to 18.36.0 (#21504)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-20 20:04:54 +00:00
koenkk db1e3b73d1 fix: Only configure routers on startup https://github.com/Koenkk/zigbee2mqtt/issues/21446 2024-02-20 20:24:03 +01:00
Artem Draft fe73db4ff6 fix: trigger_count & power_outage_count adjustments in HA (#21492) 2024-02-20 19:47:45 +01:00
Koen Kanters 9dd6eeee7b chore: merge master to dev 2024-02-20 19:47:25 +01:00
Oleksandr Masliuchenko 3c609658fd fix: Fix parsing entity name that contains slash in the name and endpoint specification (#21493) 2024-02-20 19:47:22 +01:00
Anthony Bourguignon 8b694432aa fix: Check if Zigbee2MQTT is running in update.sh (#21494) 2024-02-20 19:46:44 +01:00
Koen KantersandKoenkk b32bd309ca fix(ignore): update zigbee-herdsman-converters to 18.35.0 (#21487)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-19 21:08:45 +00:00
Koen KantersandKoenkk 78b5e6fd4b fix(ignore): update zigbee-herdsman to 0.34.2 (#21478)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-19 20:46:48 +00:00
Koen Kanters c5c0a8b193 feat: Add experimental Ember adapter @Nerivec https://github.com/Koenkk/zigbee-herdsman/pull/918 (#21459) 2024-02-18 22:11:09 +01:00
Koen KantersandKoenkk b51eef2319 fix(ignore): update zigbee-herdsman to 0.34.1 (#21461)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-18 21:01:03 +00:00
Koen KantersandKoenkk ebed9d31d7 fix(ignore): update zigbee-herdsman-converters to 18.34.0 (#21456)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-18 16:39:07 +00:00
Koen KantersandKoenkk 16b251d3c9 fix(ignore): update dependencies (#21444)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-18 16:23:36 +01:00
Koen KantersandKoenkk 5766bf479b fix(ignore): update zigbee-herdsman-converters to 18.33.2 (#21416)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-15 19:01:26 +00:00
Koen KantersandKoenkk 8a9477f2bb fix(ignore): update zigbee-herdsman-converters to 18.33.1 (#21400)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-14 18:49:57 +00:00
Koen KantersandKoenkk 2aaf878889 fix(ignore): update zigbee-herdsman-converters to 18.33.0 (#21387)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-13 19:28:16 +00:00
Koen KantersandKoenkk dfa499659e fix(ignore): update zigbee-herdsman to 0.33.9 (#21386)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-13 19:05:11 +00:00
Sergei SalimovandKoen Kanters 24b5f9b43a feat: Add support for button entity in Home Assistant (#21372)
* add button entity support

* add enabled_by_default to select

---------

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2024-02-13 19:43:21 +01:00
Koen KantersandKoenkk 0ab7390a64 fix(ignore): update zigbee-herdsman-converters to 18.32.0 (#21373)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-12 20:31:38 +00:00
Koen KantersandKoenkk c7b820c376 fix(ignore): update zigbee-herdsman-converters to 18.31.0 (#21359)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-11 20:46:36 +00:00
Koen KantersandKoenkk ce41f2f8ba fix(ignore): update dependencies (#21347)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-11 21:07:38 +01:00
Koen Kantersandnurikk 8bc3c46c34 fix(ignore): update zigbee2mqtt-frontend to 0.6.158 (#21356)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-02-11 18:17:21 +00:00
Oleksandr Masliuchenko b4473d6e24 fix: Remove predefined endpoint list, remove limits on device friendly name (#21325)
* Get rid of predefined list of endpoints, correct friend name validations

* Fix minor bug while parsing a topic for an unknown device
2024-02-10 16:50:44 +01:00
Koen KantersandKoenkk 910f3a6860 fix(ignore): update zigbee-herdsman-converters to 18.30.0 (#21315)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-08 19:58:46 +00:00
Oleksandr MasliuchenkoandKoen Kanters 81335e5b4b fix: Remove dependency on predefined list of endpoints (parseEntityID() function) (#21264)
* Add function resolveEntityByID() function as an improved alternative for parseEntityID()

* Port deviceGroupMembership.ts from parseEntityID() to resolveEntityByID()

* Migrade groups.ts from parseEntityID() to resolveEntityByID()

* Improve test coverage on groups functionality

* Migrate from parseEntityID() to resolveEntityByID() for bridge functionality

* Migrate from parseEntityID() to resolveEntityByID() for bind functionality

* Finally get rid of parseEntityID() function

* Fix linter issues

* Move resolveEntityAndEndpoint() function to zigbee.ts

---------

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2024-02-08 20:54:05 +01:00
Koen KantersandKoenkk 55653c974e fix(ignore): update zigbee-herdsman-converters to 18.29.1 (#21290)
Co-authored-by: Koenkk <2892853+Koenkk@users.noreply.github.com>
2024-02-07 20:32:47 +00:00
Oleksandr MasliuchenkoandKoen Kanters a5a87a79a8 fix: Match endpoint name in the MQTT topic based on endpoints listed in the definition (#21214)
* Add endpoint matching based on the endpoint names list in the device definition

* Cleanup debug prints

* Correct creating endpoint names list, filter out null elements

* Correct test due to slightly changed behavior

* Fix endpoint name lookup when converter does not provide full name-to-id mapping

* Simplify topic name matching

* Remove obsolete branches, improve code coverage

* Make linter happy

* Make linter happy

* Remove dependency on endpoint names while removing device from all groups

* Get rid of predefined list of endpoints when processing group state update

---------

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2024-02-07 20:12:48 +01:00
Koen Kantersandnurikk a479bf9039 fix(ignore): update zigbee2mqtt-frontend to 0.6.157 (#21269)
Co-authored-by: nurikk <1525421+nurikk@users.noreply.github.com>
2024-02-06 21:32:15 +00:00
koenkk b7e19cc86a chore: promote to dev 2024-02-06 21:06:28 +01:00
63 changed files with 2721 additions and 1491 deletions
@@ -7,6 +7,7 @@ body:
value: |
**IMPORTANT:** Before submitting:
- You read the [FAQ](https://www.zigbee2mqtt.io/guide/faq/)
- Are you using an EZSP adapter (e.g. Dongle-E/SkyConnect)? Try the [new driver](https://github.com/Koenkk/zigbee2mqtt/discussions/21462)
- Zigbee2MQTT fails to start? Read [this](https://www.zigbee2mqtt.io/guide/installation/20_zigbee2mqtt-fails-to-start.html)
- Make sure the bug also occurs in the [dev branch](https://www.zigbee2mqtt.io/advanced/more/switch-to-dev-branch.html)
- Make sure you are using the [latest firmware](https://www.zigbee2mqtt.io/guide/adapters/#recommended) on your adapter
+6
View File
@@ -11,6 +11,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
if: (github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push'
with:
# Required for `release: merge dev -> master and promote dev`
token: ${{secrets.GH_TOKEN}}
- uses: actions/checkout@v4
if: ((github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push') == false
- uses: actions/setup-node@v4
with:
node-version: 20
+31
View File
@@ -0,0 +1,31 @@
name: Release Charts
on:
push:
branches:
- main
paths:
- 'charts/**'
jobs:
release:
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.6.0
with:
skip_existing: true
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
+36 -1
View File
@@ -26,6 +26,41 @@ jobs:
target-branch: dev
token: ${{secrets.GH_TOKEN}}
# we use grep,awk,sed here because the output from release-please despite being JSON, it's not valid (probably shell-escaping) and
# jq fails to parse it. Creates the output pr_branch
- name: Get the branch of the release-please PR
id: get_pr_branch
if: ${{ steps.release.outputs.prs_created == 'true' }}
run: |
BRANCH=$(echo '${{ steps.release.outputs.prs }}' | grep -o -P '\"headBranchName\":\"(.*?)\"' | awk -F':' '{print $2}' | tr -d \")
echo "pr_branch=${BRANCH}" >> $GITHUB_OUTPUT
# Checkout PR branch
- uses: actions/checkout@v4
if: ${{ steps.release.outputs.prs_created == 'true' }}
with:
repository: koenkk/zigbee2mqtt
path: ./z2m-pr
ref: ${{ steps.get_pr_branch.outputs.pr_branch }}
token: ${{secrets.GH_TOKEN}}
- name: Add updated helm chart release versions and documentation to release PR
if: ${{ steps.release.outputs.prs_created == 'true' }}
run: |
pushd ./z2m-pr
Z2M_VERSION="$(jq -r '."."' .release-please-manifest.json)"
yq -i ".appVersion=\"${Z2M_VERSION}\"" charts/zigbee2mqtt/Chart.yaml
yq -i ".image.tag=\"${Z2M_VERSION}\"" charts/zigbee2mqtt/values.yaml
# Keep chart version in step lock with zigbee2mqtt
jq ".\"charts/zigbee2mqtt\"=\"${Z2M_VERSION}\"" .release-please-manifest.json > .release-please-manifest.json.tmp
mv .release-please-manifest.json.tmp .release-please-manifest.json
go run github.com/norwoodj/helm-docs/cmd/helm-docs@latest
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add .
git commit -m "chore(release): update helm-chart docs"
git push
# Checkout repos
- uses: actions/checkout@v4
with:
@@ -50,7 +85,7 @@ 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--zigbee2mqtt/CHANGELOG.md > z2m/CHANGELOG.md
wget -q -O - https://raw.githubusercontent.com/Koenkk/zigbee2mqtt/release-please--branches--dev/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
+2 -2
View File
@@ -12,8 +12,8 @@ jobs:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days'
stale-pr-message: 'This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 7 days'
stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 30 days'
stale-pr-message: 'This pull request is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 30 days'
days-before-stale: 180
days-before-close: 30
exempt-issue-labels: dont-stale
+2 -1
View File
@@ -23,7 +23,8 @@ jobs:
node-version: 20
cache: npm
# connect-gzip-static@4.0.0 requires Node 20 >=
- run: npx npm-check-updates -u -x connect-gzip-static
# eslint: https://github.com/typescript-eslint/typescript-eslint/issues/8211
- run: npx npm-check-updates -u -x connect-gzip-static -x eslint
- run: rm -f package-lock.json
- run: npm install
- uses: peter-evans/create-pull-request@v6
+3 -2
View File
@@ -1,3 +1,4 @@
{
".": "1.35.3"
}
".": "1.37.1",
"charts/zigbee2mqtt": "1.37.1"
}
+192
View File
@@ -1,5 +1,197 @@
# Changelog
## [1.37.1](https://github.com/Koenkk/zigbee2mqtt/compare/1.37.0...1.37.1) (2024-05-09)
### Bug Fixes
* Add Helm chart ([#21852](https://github.com/Koenkk/zigbee2mqtt/issues/21852)) ([b2e8b3e](https://github.com/Koenkk/zigbee2mqtt/commit/b2e8b3e00c152540109e7b9101784f3b03261b40))
* Add settings for finer control over debug log level ([#22426](https://github.com/Koenkk/zigbee2mqtt/issues/22426)) ([eb49f52](https://github.com/Koenkk/zigbee2mqtt/commit/eb49f523bf3a0c085655cfae7aac97d7da749db9))
* Fix logger crashing on restart ([#22565](https://github.com/Koenkk/zigbee2mqtt/issues/22565)) ([d26ccae](https://github.com/Koenkk/zigbee2mqtt/commit/d26ccaed65b922b00f1a7599941289ead4b7fb31))
* Fix MQTT `ECONNREFUSED error` https://github.com/zigbee2mqtt/hassio-zigbee2mqtt/issues/605 ([a0c9a17](https://github.com/Koenkk/zigbee2mqtt/commit/a0c9a1769f7e25673672e3a312b2e4bd3812ff32))
* **ignore:** update dependencies ([#22456](https://github.com/Koenkk/zigbee2mqtt/issues/22456)) ([b754b9d](https://github.com/Koenkk/zigbee2mqtt/commit/b754b9d4635ef3300893acba51eadae4e41039a3))
* **ignore:** update zigbee-herdsman to 0.46.0 ([#22380](https://github.com/Koenkk/zigbee2mqtt/issues/22380)) ([55b5f91](https://github.com/Koenkk/zigbee2mqtt/commit/55b5f91a96f589fd0e3da5f4800dad32dbd57cf7))
* **ignore:** update zigbee-herdsman to 0.46.1 ([#22439](https://github.com/Koenkk/zigbee2mqtt/issues/22439)) ([329d832](https://github.com/Koenkk/zigbee2mqtt/commit/329d832337cda15b324c46a2adf6a24c5d38a8bd))
* **ignore:** update zigbee-herdsman to 0.46.2 ([#22470](https://github.com/Koenkk/zigbee2mqtt/issues/22470)) ([e4c9bac](https://github.com/Koenkk/zigbee2mqtt/commit/e4c9bac348680f5571cef0b79407fb9459757a36))
* **ignore:** update zigbee-herdsman to 0.46.3 ([#22471](https://github.com/Koenkk/zigbee2mqtt/issues/22471)) ([316654b](https://github.com/Koenkk/zigbee2mqtt/commit/316654b5d3acc6452e888d0e48a77908c431e783))
* **ignore:** update zigbee-herdsman to 0.46.4 ([#22501](https://github.com/Koenkk/zigbee2mqtt/issues/22501)) ([e44608a](https://github.com/Koenkk/zigbee2mqtt/commit/e44608a46dfe3baab1f82dd430f66afe0ac09c4f))
* **ignore:** update zigbee-herdsman to 0.46.5 ([#22552](https://github.com/Koenkk/zigbee2mqtt/issues/22552)) ([6bcb4b6](https://github.com/Koenkk/zigbee2mqtt/commit/6bcb4b66b1a69f19b49a3b9a4c9be32e8f1df4e4))
* **ignore:** update zigbee-herdsman to 0.46.6 ([#22558](https://github.com/Koenkk/zigbee2mqtt/issues/22558)) ([989f667](https://github.com/Koenkk/zigbee2mqtt/commit/989f667c81e4f2b61edd379382d2c8f77c556e3b))
* **ignore:** update zigbee-herdsman-converters to 19.33.0 ([#22381](https://github.com/Koenkk/zigbee2mqtt/issues/22381)) ([907591c](https://github.com/Koenkk/zigbee2mqtt/commit/907591c467f926af172427ff641e7b20e5fa309c))
* **ignore:** update zigbee-herdsman-converters to 19.35.0 ([#22442](https://github.com/Koenkk/zigbee2mqtt/issues/22442)) ([beedfae](https://github.com/Koenkk/zigbee2mqtt/commit/beedfaefacdb53d3c379164dbb4dae5de396d40d))
* **ignore:** update zigbee-herdsman-converters to 19.36.0 ([#22472](https://github.com/Koenkk/zigbee2mqtt/issues/22472)) ([358e2ee](https://github.com/Koenkk/zigbee2mqtt/commit/358e2eee4551baee58c4d212d9d65562d2e84bd6))
* **ignore:** update zigbee-herdsman-converters to 19.36.1 ([#22503](https://github.com/Koenkk/zigbee2mqtt/issues/22503)) ([3544d51](https://github.com/Koenkk/zigbee2mqtt/commit/3544d5172e03cdcbd61cde13ebc20c2e5fbeaba5))
* **ignore:** update zigbee-herdsman-converters to 19.37.0 ([#22531](https://github.com/Koenkk/zigbee2mqtt/issues/22531)) ([6b886f6](https://github.com/Koenkk/zigbee2mqtt/commit/6b886f626863cae8acc2895a7fe2482b068138d6))
* **ignore:** update zigbee-herdsman-converters to 19.37.1 ([#22549](https://github.com/Koenkk/zigbee2mqtt/issues/22549)) ([cc9a95c](https://github.com/Koenkk/zigbee2mqtt/commit/cc9a95c74e53261636dc7329be2becddf4772fdc))
* **ignore:** update zigbee-herdsman-converters to 19.37.2 ([#22570](https://github.com/Koenkk/zigbee2mqtt/issues/22570)) ([06fd8a4](https://github.com/Koenkk/zigbee2mqtt/commit/06fd8a4eb120f03dd9f3a1d59ab7b20a32fe15a9))
* **ignore:** update zigbee2mqtt-frontend to 0.6.166 ([#22410](https://github.com/Koenkk/zigbee2mqtt/issues/22410)) ([5899436](https://github.com/Koenkk/zigbee2mqtt/commit/5899436d74cb0c67016758797c2e928f35715d9d))
* **ignore:** update zigbee2mqtt-frontend to 0.6.167 ([#22419](https://github.com/Koenkk/zigbee2mqtt/issues/22419)) ([23e97d0](https://github.com/Koenkk/zigbee2mqtt/commit/23e97d0001048269662c6336a8aef6788615934c))
## [1.37.0](https://github.com/Koenkk/zigbee2mqtt/compare/1.36.1...1.37.0) (2024-05-01)
### Features
* Unified logging across z2m/zh/zhc ([#21984](https://github.com/Koenkk/zigbee2mqtt/issues/21984)) ([73566df](https://github.com/Koenkk/zigbee2mqtt/commit/73566dff98e64038117ec71c7aaa897a4070474d))
### Bug Fixes
* Change `MQTT publish` log to `debug` ([#22063](https://github.com/Koenkk/zigbee2mqtt/issues/22063)) ([bbb6f9e](https://github.com/Koenkk/zigbee2mqtt/commit/bbb6f9e042a5c6cce78591e402d8ab0f7ab4195e))
* Cleanup old logger leftovers ([#22069](https://github.com/Koenkk/zigbee2mqtt/issues/22069)) ([919c4ee](https://github.com/Koenkk/zigbee2mqtt/commit/919c4eee739d9c2dee855cf868e88f7848e6af36))
* Convert logger into a class ([#22129](https://github.com/Koenkk/zigbee2mqtt/issues/22129)) ([3c1a4af](https://github.com/Koenkk/zigbee2mqtt/commit/3c1a4afcb723eecccf6ab9c3e04e1e0eca7b2cbb))
* Disable automatic reconfigure when configureKey changes ([#22088](https://github.com/Koenkk/zigbee2mqtt/issues/22088)) ([9d251db](https://github.com/Koenkk/zigbee2mqtt/commit/9d251dbad5660f7663a79360a584df69d6f10875))
* Fix crash when stopping in case MQTT client did not connect yet ([#22110](https://github.com/Koenkk/zigbee2mqtt/issues/22110)) ([92f5323](https://github.com/Koenkk/zigbee2mqtt/commit/92f53235f3e143ade8883dce01439f87913e2679))
* **ignore:** fix 73566df ([cdd6fb0](https://github.com/Koenkk/zigbee2mqtt/commit/cdd6fb086419892e2725fc545b8015d83dea145d))
* **ignore:** fix 73566dff98e64038117ec71c7aaa897a4070474d ([780c065](https://github.com/Koenkk/zigbee2mqtt/commit/780c065fa106358683bbef6fd72b0257adca5bae))
* **ignore:** update dependencies ([#22007](https://github.com/Koenkk/zigbee2mqtt/issues/22007)) ([e748718](https://github.com/Koenkk/zigbee2mqtt/commit/e7487189cf6b2143a5606ce9bac7d4fa6e240587))
* **ignore:** update dependencies ([#22331](https://github.com/Koenkk/zigbee2mqtt/issues/22331)) ([d7e2d98](https://github.com/Koenkk/zigbee2mqtt/commit/d7e2d98a5a79689cfdc06e1f9bd3b1ed10251132))
* **ignore:** update zigbee-herdsman to 0.41.0 ([#22045](https://github.com/Koenkk/zigbee2mqtt/issues/22045)) ([bd0a411](https://github.com/Koenkk/zigbee2mqtt/commit/bd0a41107a18ab725d0d669af7993f2ad57cd9dd))
* **ignore:** update zigbee-herdsman to 0.41.1 ([#22064](https://github.com/Koenkk/zigbee2mqtt/issues/22064)) ([3e91349](https://github.com/Koenkk/zigbee2mqtt/commit/3e913495b1a843cf0d67e4f2ffba975f56dd5f94))
* **ignore:** update zigbee-herdsman to 0.41.2 ([#22087](https://github.com/Koenkk/zigbee2mqtt/issues/22087)) ([a020138](https://github.com/Koenkk/zigbee2mqtt/commit/a020138f6b4e90377d8bacf475fd33f62abb24e5))
* **ignore:** update zigbee-herdsman to 0.42.0 ([#22121](https://github.com/Koenkk/zigbee2mqtt/issues/22121)) ([28b8aff](https://github.com/Koenkk/zigbee2mqtt/commit/28b8aff1ae8cabce8f61e34c85cd0b72b52a1e83))
* **ignore:** update zigbee-herdsman to 0.42.1 ([#22143](https://github.com/Koenkk/zigbee2mqtt/issues/22143)) ([a210c23](https://github.com/Koenkk/zigbee2mqtt/commit/a210c238f1156bdbb56ba5fc223d0b2159c07273))
* **ignore:** update zigbee-herdsman to 0.42.2 ([#22220](https://github.com/Koenkk/zigbee2mqtt/issues/22220)) ([76f5425](https://github.com/Koenkk/zigbee2mqtt/commit/76f54254529d13bfa0e9a40a0c7455b0c1e61bc8))
* **ignore:** update zigbee-herdsman to 0.42.3 ([#22253](https://github.com/Koenkk/zigbee2mqtt/issues/22253)) ([f7abbd5](https://github.com/Koenkk/zigbee2mqtt/commit/f7abbd5f5ab878bea364cc0cda4222b8941fd487))
* **ignore:** update zigbee-herdsman to 0.42.4 ([#22283](https://github.com/Koenkk/zigbee2mqtt/issues/22283)) ([a8f6bec](https://github.com/Koenkk/zigbee2mqtt/commit/a8f6bec673f43fd76c3495927c2c44e831ade6da))
* **ignore:** update zigbee-herdsman to 0.42.5 ([#22285](https://github.com/Koenkk/zigbee2mqtt/issues/22285)) ([4f97a7a](https://github.com/Koenkk/zigbee2mqtt/commit/4f97a7ad2c12ec70ff459dc233d55bada734e7ab))
* **ignore:** update zigbee-herdsman to 0.43.0 ([#22300](https://github.com/Koenkk/zigbee2mqtt/issues/22300)) ([75f9743](https://github.com/Koenkk/zigbee2mqtt/commit/75f9743528ac3f55b837548f234b29bdf8182a0d))
* **ignore:** update zigbee-herdsman to 0.43.1 ([#22317](https://github.com/Koenkk/zigbee2mqtt/issues/22317)) ([389779d](https://github.com/Koenkk/zigbee2mqtt/commit/389779d4e332db1945ff7b490ec881eec71b4721))
* **ignore:** update zigbee-herdsman to 0.44.0 ([#22339](https://github.com/Koenkk/zigbee2mqtt/issues/22339)) ([1b089ef](https://github.com/Koenkk/zigbee2mqtt/commit/1b089ef6ae364786602c485ea5deafad4e21f023))
* **ignore:** update zigbee-herdsman to 0.45.0 ([#22365](https://github.com/Koenkk/zigbee2mqtt/issues/22365)) ([8e27ec2](https://github.com/Koenkk/zigbee2mqtt/commit/8e27ec24f664ca702eba93f90b42c9f4e74d16df))
* **ignore:** update zigbee-herdsman-converters to 19.13.0 ([#22046](https://github.com/Koenkk/zigbee2mqtt/issues/22046)) ([db7d9e1](https://github.com/Koenkk/zigbee2mqtt/commit/db7d9e1120e01dd6b4e20bd352689eebb9a8912f))
* **ignore:** update zigbee-herdsman-converters to 19.15.0 ([#22089](https://github.com/Koenkk/zigbee2mqtt/issues/22089)) ([ae35aae](https://github.com/Koenkk/zigbee2mqtt/commit/ae35aaed5ef3591f288019d9cb35d90a31aa4798))
* **ignore:** update zigbee-herdsman-converters to 19.16.0 ([#22107](https://github.com/Koenkk/zigbee2mqtt/issues/22107)) ([394a3fb](https://github.com/Koenkk/zigbee2mqtt/commit/394a3fbd8aeb1dd4708326d8f854ac7db4b28dbf))
* **ignore:** update zigbee-herdsman-converters to 19.17.0 ([#22122](https://github.com/Koenkk/zigbee2mqtt/issues/22122)) ([cabc9f5](https://github.com/Koenkk/zigbee2mqtt/commit/cabc9f5e2f6e22fb380e259093d29ec506a3b1f3))
* **ignore:** update zigbee-herdsman-converters to 19.18.0 ([#22141](https://github.com/Koenkk/zigbee2mqtt/issues/22141)) ([8b8d660](https://github.com/Koenkk/zigbee2mqtt/commit/8b8d660b0622072696113c3a66458cbde1918838))
* **ignore:** update zigbee-herdsman-converters to 19.19.0 ([#22153](https://github.com/Koenkk/zigbee2mqtt/issues/22153)) ([cdbbe0d](https://github.com/Koenkk/zigbee2mqtt/commit/cdbbe0d49fff21a3fb5000ecef25bb71b3d64360))
* **ignore:** update zigbee-herdsman-converters to 19.19.1 ([#22171](https://github.com/Koenkk/zigbee2mqtt/issues/22171)) ([f774753](https://github.com/Koenkk/zigbee2mqtt/commit/f77475321300a11ca0d30525fe38afa7d079f42e))
* **ignore:** update zigbee-herdsman-converters to 19.20.0 ([#22187](https://github.com/Koenkk/zigbee2mqtt/issues/22187)) ([e10ab5c](https://github.com/Koenkk/zigbee2mqtt/commit/e10ab5ccb272fdc3b2922fd28c043d84860137e1))
* **ignore:** update zigbee-herdsman-converters to 19.21.0 ([#22199](https://github.com/Koenkk/zigbee2mqtt/issues/22199)) ([87aa18d](https://github.com/Koenkk/zigbee2mqtt/commit/87aa18d14cbf19a89d7d0dced6eb86393f0239af))
* **ignore:** update zigbee-herdsman-converters to 19.22.0 ([#22221](https://github.com/Koenkk/zigbee2mqtt/issues/22221)) ([172aa74](https://github.com/Koenkk/zigbee2mqtt/commit/172aa7461ac507aa55dcd653d40873445c827f28))
* **ignore:** update zigbee-herdsman-converters to 19.23.0 ([#22232](https://github.com/Koenkk/zigbee2mqtt/issues/22232)) ([1544317](https://github.com/Koenkk/zigbee2mqtt/commit/1544317fce5de3be71395af06450a5e997b39dab))
* **ignore:** update zigbee-herdsman-converters to 19.24.0 ([#22254](https://github.com/Koenkk/zigbee2mqtt/issues/22254)) ([d9628df](https://github.com/Koenkk/zigbee2mqtt/commit/d9628df17b228a0908d7b95e35cbb97171c2485c))
* **ignore:** update zigbee-herdsman-converters to 19.25.0 ([#22266](https://github.com/Koenkk/zigbee2mqtt/issues/22266)) ([80504b9](https://github.com/Koenkk/zigbee2mqtt/commit/80504b943d742a20481b458eb0fdc9cdf9452961))
* **ignore:** update zigbee-herdsman-converters to 19.26.0 ([#22284](https://github.com/Koenkk/zigbee2mqtt/issues/22284)) ([4bf2ffa](https://github.com/Koenkk/zigbee2mqtt/commit/4bf2ffa7ddd0de3d70160ccefbaf483fc9a83a22))
* **ignore:** update zigbee-herdsman-converters to 19.27.0 ([#22301](https://github.com/Koenkk/zigbee2mqtt/issues/22301)) ([df23240](https://github.com/Koenkk/zigbee2mqtt/commit/df232406838b991c87ddbaa6c28ebcedd6226fcf))
* **ignore:** update zigbee-herdsman-converters to 19.28.0 ([#22318](https://github.com/Koenkk/zigbee2mqtt/issues/22318)) ([245afb1](https://github.com/Koenkk/zigbee2mqtt/commit/245afb112648c23c74c8e1e9d9b038c84d71ca40))
* **ignore:** update zigbee-herdsman-converters to 19.29.0 ([#22325](https://github.com/Koenkk/zigbee2mqtt/issues/22325)) ([3755126](https://github.com/Koenkk/zigbee2mqtt/commit/37551265a204b6509b2534b5b0fcc9825b5188ac))
* **ignore:** update zigbee-herdsman-converters to 19.32.0 ([#22377](https://github.com/Koenkk/zigbee2mqtt/issues/22377)) ([e03013c](https://github.com/Koenkk/zigbee2mqtt/commit/e03013c58180391d9f3fe6878712ab032896a94f))
* **ignore:** update zigbee2mqtt-frontend to 0.6.162 ([#22094](https://github.com/Koenkk/zigbee2mqtt/issues/22094)) ([0c80129](https://github.com/Koenkk/zigbee2mqtt/commit/0c801294661b0f6e592dd09f681c83bff376414d))
* **ignore:** update zigbee2mqtt-frontend to 0.6.163 ([#22288](https://github.com/Koenkk/zigbee2mqtt/issues/22288)) ([e5d632b](https://github.com/Koenkk/zigbee2mqtt/commit/e5d632bc9177c134d6856f9b5881f26be4ed4140))
* **ignore:** update zigbee2mqtt-frontend to 0.6.164 ([#22340](https://github.com/Koenkk/zigbee2mqtt/issues/22340)) ([10e6ad0](https://github.com/Koenkk/zigbee2mqtt/commit/10e6ad0e67a237693365c5bc8752ba3cbefe757f))
* **ignore:** update zigbee2mqtt-frontend to 0.6.165 ([#22366](https://github.com/Koenkk/zigbee2mqtt/issues/22366)) ([8a288a9](https://github.com/Koenkk/zigbee2mqtt/commit/8a288a91192bfa47aad80435a02cf3313da0b4bc))
* Reduce MQTT publishing by excluding debug logging from `bridge/logging` ([#22066](https://github.com/Koenkk/zigbee2mqtt/issues/22066)) ([002050f](https://github.com/Koenkk/zigbee2mqtt/commit/002050f35bd6228a464482d17a7feee82f9f5d31))
* Remove deprecated Home Assistant `color_mode` ([#22142](https://github.com/Koenkk/zigbee2mqtt/issues/22142)) ([c98e5a7](https://github.com/Koenkk/zigbee2mqtt/commit/c98e5a74de1c322533f9c0defa0bbf0b5627b775))
## [1.36.1](https://github.com/Koenkk/zigbee2mqtt/compare/1.36.0...1.36.1) (2024-04-01)
### Bug Fixes
* Add more Home Assistant entity icons ([#21652](https://github.com/Koenkk/zigbee2mqtt/issues/21652)) ([01843fe](https://github.com/Koenkk/zigbee2mqtt/commit/01843fe6c43210ade1d1dfcd134fdd979d47f194))
* Fix `set` endpoint name conversion ([#21653](https://github.com/Koenkk/zigbee2mqtt/issues/21653)) ([66fb672](https://github.com/Koenkk/zigbee2mqtt/commit/66fb672492c8f049368d5dbda3925500941cd534))
* Fix crash due to race condition during interview ([#21680](https://github.com/Koenkk/zigbee2mqtt/issues/21680)) ([2da8095](https://github.com/Koenkk/zigbee2mqtt/commit/2da80954d69c753bcfbef30c2579584d7a0f8779))
* Fix incorrect update state when Z2M is restarted during OTA update https://github.com/Koenkk/zigbee2mqtt/issues/12794 ([1110d3f](https://github.com/Koenkk/zigbee2mqtt/commit/1110d3f8efff948811a980968f8dc84465500d4f))
* Home Assistant: remove button name if `device_class` is present ([#21726](https://github.com/Koenkk/zigbee2mqtt/issues/21726)) ([14e0440](https://github.com/Koenkk/zigbee2mqtt/commit/14e044093c4f481fc7c4f58c35c68ebddddf621c))
* **ignore:** fix tests ([29543ba](https://github.com/Koenkk/zigbee2mqtt/commit/29543bad4bb8768bb66c15f4f084b0d9ccc6c1bc))
* **ignore:** update dependencies ([#21657](https://github.com/Koenkk/zigbee2mqtt/issues/21657)) ([8c86849](https://github.com/Koenkk/zigbee2mqtt/commit/8c86849bb992e1125e9fed301eef8655aa95466c))
* **ignore:** Update dependencies ([#21740](https://github.com/Koenkk/zigbee2mqtt/issues/21740)) ([43610bb](https://github.com/Koenkk/zigbee2mqtt/commit/43610bbff44572937650ee03ccd239d084d9959f))
* **ignore:** update dependencies ([#21832](https://github.com/Koenkk/zigbee2mqtt/issues/21832)) ([1006725](https://github.com/Koenkk/zigbee2mqtt/commit/1006725b09a6e07e60586409798de3cbc7f3c1f1))
* **ignore:** update dependencies ([#21923](https://github.com/Koenkk/zigbee2mqtt/issues/21923)) ([8c4cd8c](https://github.com/Koenkk/zigbee2mqtt/commit/8c4cd8c9aa8777027d538a114fc9310b1f2fe7a2))
* **ignore:** Update manufacturer codes ([#21729](https://github.com/Koenkk/zigbee2mqtt/issues/21729)) ([83502f2](https://github.com/Koenkk/zigbee2mqtt/commit/83502f2d30cf2d79f3ea8576ab065590da29abd8))
* **ignore:** update zigbee-herdsman to 0.35.2 ([#21654](https://github.com/Koenkk/zigbee2mqtt/issues/21654)) ([ccaa128](https://github.com/Koenkk/zigbee2mqtt/commit/ccaa1281a35249874a065fd2d4975aeab93f05f4))
* **ignore:** update zigbee-herdsman to 0.35.3 ([#21677](https://github.com/Koenkk/zigbee2mqtt/issues/21677)) ([30909d5](https://github.com/Koenkk/zigbee2mqtt/commit/30909d57fba7f7a45caeb14afcbf5f8ac724c876))
* **ignore:** update zigbee-herdsman to 0.36.0 ([#21689](https://github.com/Koenkk/zigbee2mqtt/issues/21689)) ([1d73d9d](https://github.com/Koenkk/zigbee2mqtt/commit/1d73d9d4768d8511ca24066fe199d4096b0301ac))
* **ignore:** update zigbee-herdsman to 0.36.1 ([#21713](https://github.com/Koenkk/zigbee2mqtt/issues/21713)) ([e834e93](https://github.com/Koenkk/zigbee2mqtt/commit/e834e93debbd343236e71e275bbd3726a3b4ae3c))
* **ignore:** update zigbee-herdsman to 0.36.2 ([#21727](https://github.com/Koenkk/zigbee2mqtt/issues/21727)) ([ebf996a](https://github.com/Koenkk/zigbee2mqtt/commit/ebf996acd83f32668be7dfd3994c2976db52bc58))
* **ignore:** update zigbee-herdsman to 0.37.0 ([#21743](https://github.com/Koenkk/zigbee2mqtt/issues/21743)) ([b60f679](https://github.com/Koenkk/zigbee2mqtt/commit/b60f679814294ce454e4e7c08fc3dd11b9a224ff))
* **ignore:** update zigbee-herdsman to 0.38.0 ([#21777](https://github.com/Koenkk/zigbee2mqtt/issues/21777)) ([233d263](https://github.com/Koenkk/zigbee2mqtt/commit/233d263e132e7b046194dedd620ae687a815f1ec))
* **ignore:** update zigbee-herdsman to 0.38.1 ([#21802](https://github.com/Koenkk/zigbee2mqtt/issues/21802)) ([6586228](https://github.com/Koenkk/zigbee2mqtt/commit/658622880ffc7eee1c27ba499ce75da03b25c216))
* **ignore:** update zigbee-herdsman to 0.39.0 ([#21871](https://github.com/Koenkk/zigbee2mqtt/issues/21871)) ([801134b](https://github.com/Koenkk/zigbee2mqtt/commit/801134b6303ecea0d41254ac84a6f0f96393dc3f))
* **ignore:** update zigbee-herdsman to 0.39.1 ([#21891](https://github.com/Koenkk/zigbee2mqtt/issues/21891)) ([f05d501](https://github.com/Koenkk/zigbee2mqtt/commit/f05d501380a5416fb610f6eeeea7c9b7a04394cb))
* **ignore:** update zigbee-herdsman to 0.40.0 ([#21901](https://github.com/Koenkk/zigbee2mqtt/issues/21901)) ([334e260](https://github.com/Koenkk/zigbee2mqtt/commit/334e260b851535379548e52a61cbef5956411f46))
* **ignore:** update zigbee-herdsman to 0.40.1 ([#21987](https://github.com/Koenkk/zigbee2mqtt/issues/21987)) ([0c7730f](https://github.com/Koenkk/zigbee2mqtt/commit/0c7730f4c50fb97313de35533140a8c99f6ad374))
* **ignore:** update zigbee-herdsman to 0.40.2 ([#22000](https://github.com/Koenkk/zigbee2mqtt/issues/22000)) ([886b534](https://github.com/Koenkk/zigbee2mqtt/commit/886b5345d7c134f27aa14e259ce1cfd8423b8636))
* **ignore:** update zigbee-herdsman to 0.40.3 ([#22010](https://github.com/Koenkk/zigbee2mqtt/issues/22010)) ([1e74b2f](https://github.com/Koenkk/zigbee2mqtt/commit/1e74b2f53ff7af8d1067265c966f75aef8a794f1))
* **ignore:** update zigbee-herdsman-converters to 18.44.0 ([#21690](https://github.com/Koenkk/zigbee2mqtt/issues/21690)) ([6daa7aa](https://github.com/Koenkk/zigbee2mqtt/commit/6daa7aa61db7c6ceef707ab27afca14e31a2e79f))
* **ignore:** update zigbee-herdsman-converters to 18.45.0 ([#21699](https://github.com/Koenkk/zigbee2mqtt/issues/21699)) ([d37c164](https://github.com/Koenkk/zigbee2mqtt/commit/d37c164993cd4b3bc2f027be3a3a2b9a5b30d200))
* **ignore:** update zigbee-herdsman-converters to 18.46.0 ([#21714](https://github.com/Koenkk/zigbee2mqtt/issues/21714)) ([0e0eccb](https://github.com/Koenkk/zigbee2mqtt/commit/0e0eccbd139e38df31b0860af26c50032f629fae))
* **ignore:** update zigbee-herdsman-converters to 18.47.0 ([#21728](https://github.com/Koenkk/zigbee2mqtt/issues/21728)) ([3188038](https://github.com/Koenkk/zigbee2mqtt/commit/3188038a7bf673b2053783910229e1e60b6f5921))
* **ignore:** update zigbee-herdsman-converters to 18.48.0 ([#21753](https://github.com/Koenkk/zigbee2mqtt/issues/21753)) ([2a047a4](https://github.com/Koenkk/zigbee2mqtt/commit/2a047a469c70f17a3c12d0a6f6fc2de9744835e7))
* **ignore:** update zigbee-herdsman-converters to 19.0.0 ([#21768](https://github.com/Koenkk/zigbee2mqtt/issues/21768)) ([dbd616f](https://github.com/Koenkk/zigbee2mqtt/commit/dbd616fbe5a62986d2c28bbcc9cea93d293da397))
* **ignore:** update zigbee-herdsman-converters to 19.1.0 ([#21778](https://github.com/Koenkk/zigbee2mqtt/issues/21778)) ([56feb77](https://github.com/Koenkk/zigbee2mqtt/commit/56feb77f2d1c357d59245db3b7cc37520554ed41))
* **ignore:** update zigbee-herdsman-converters to 19.1.1 ([#21789](https://github.com/Koenkk/zigbee2mqtt/issues/21789)) ([720fc49](https://github.com/Koenkk/zigbee2mqtt/commit/720fc491ce70f197778b5abe750ac2d779a9ad4c))
* **ignore:** update zigbee-herdsman-converters to 19.10.0 ([#21996](https://github.com/Koenkk/zigbee2mqtt/issues/21996)) ([7d8b537](https://github.com/Koenkk/zigbee2mqtt/commit/7d8b5374adca3c97976e557f1d44e1b85728d575))
* **ignore:** update zigbee-herdsman-converters to 19.11.0 ([#22013](https://github.com/Koenkk/zigbee2mqtt/issues/22013)) ([e51792c](https://github.com/Koenkk/zigbee2mqtt/commit/e51792c65afa5a2bc863bb619c0057fc7242b191))
* **ignore:** update zigbee-herdsman-converters to 19.11.1 ([#22014](https://github.com/Koenkk/zigbee2mqtt/issues/22014)) ([85c00b8](https://github.com/Koenkk/zigbee2mqtt/commit/85c00b8b43e2716231203599fac8bf01662535d5))
* **ignore:** update zigbee-herdsman-converters to 19.11.2 ([#22021](https://github.com/Koenkk/zigbee2mqtt/issues/22021)) ([3aadab0](https://github.com/Koenkk/zigbee2mqtt/commit/3aadab0925d52839baf6d884ea59d25ff083a015))
* **ignore:** update zigbee-herdsman-converters to 19.2.1 ([#21801](https://github.com/Koenkk/zigbee2mqtt/issues/21801)) ([a4f9c49](https://github.com/Koenkk/zigbee2mqtt/commit/a4f9c49ab5ef647829b8f505df7f91df8fca5036))
* **ignore:** update zigbee-herdsman-converters to 19.3.0 ([#21851](https://github.com/Koenkk/zigbee2mqtt/issues/21851)) ([1a9e05e](https://github.com/Koenkk/zigbee2mqtt/commit/1a9e05e6ab93a1e93024600a58c5b8e62544daf4))
* **ignore:** update zigbee-herdsman-converters to 19.4.0 ([#21870](https://github.com/Koenkk/zigbee2mqtt/issues/21870)) ([73d4300](https://github.com/Koenkk/zigbee2mqtt/commit/73d43007d45ee3cfc2d49ff2f4475fef63560421))
* **ignore:** update zigbee-herdsman-converters to 19.4.1 ([#21872](https://github.com/Koenkk/zigbee2mqtt/issues/21872)) ([b02c34c](https://github.com/Koenkk/zigbee2mqtt/commit/b02c34c6e52cf97364f6affce82b281cd40c1780))
* **ignore:** update zigbee-herdsman-converters to 19.4.2 ([#21892](https://github.com/Koenkk/zigbee2mqtt/issues/21892)) ([25cec20](https://github.com/Koenkk/zigbee2mqtt/commit/25cec20f0d0b6201679b719bf8dec9e7ebb26b62))
* **ignore:** update zigbee-herdsman-converters to 19.5.0 ([#21902](https://github.com/Koenkk/zigbee2mqtt/issues/21902)) ([73423eb](https://github.com/Koenkk/zigbee2mqtt/commit/73423ebd60a04f0caf7ac40743422cea3ef052e9))
* **ignore:** update zigbee-herdsman-converters to 19.6.0 ([#21927](https://github.com/Koenkk/zigbee2mqtt/issues/21927)) ([32b173c](https://github.com/Koenkk/zigbee2mqtt/commit/32b173c6537a4cdc3c303e521c5fa159cfcfb58d))
* **ignore:** update zigbee-herdsman-converters to 19.8.0 ([#21957](https://github.com/Koenkk/zigbee2mqtt/issues/21957)) ([032b9a0](https://github.com/Koenkk/zigbee2mqtt/commit/032b9a096eac7ba01a8eee188c042287db55bfed))
* **ignore:** update zigbee-herdsman-converters to 19.9.0 ([#21970](https://github.com/Koenkk/zigbee2mqtt/issues/21970)) ([a7aab71](https://github.com/Koenkk/zigbee2mqtt/commit/a7aab714ba1861eab15d0df3228e222feb8fa996))
* **ignore:** update zigbee2mqtt-frontend to 0.6.161 ([#21660](https://github.com/Koenkk/zigbee2mqtt/issues/21660)) ([aaed8ab](https://github.com/Koenkk/zigbee2mqtt/commit/aaed8ab95ec031ad5ea1f00933cc5f79b58fce29))
## [1.36.0](https://github.com/Koenkk/zigbee2mqtt/compare/1.35.3...1.36.0) (2024-03-01)
### Features
* Add experimental Ember adapter @Nerivec https://github.com/Koenkk/zigbee-herdsman/pull/918 ([#21459](https://github.com/Koenkk/zigbee2mqtt/issues/21459)) ([c5c0a8b](https://github.com/Koenkk/zigbee2mqtt/commit/c5c0a8b1938ed51887b21ded06d584f200ba32d1))
* Add support for button entity in Home Assistant ([#21372](https://github.com/Koenkk/zigbee2mqtt/issues/21372)) ([24b5f9b](https://github.com/Koenkk/zigbee2mqtt/commit/24b5f9b43af8303f87fd5f29e57cca4a850d7b1d))
### Bug Fixes
* `trigger_count` & `power_outage_count` adjustments in HA ([#21492](https://github.com/Koenkk/zigbee2mqtt/issues/21492)) ([fe73db4](https://github.com/Koenkk/zigbee2mqtt/commit/fe73db4ff686915841fc045750c7c7c98457422d))
* Add noise and noise_detected to HA lookup ([#21610](https://github.com/Koenkk/zigbee2mqtt/issues/21610)) ([9b8583e](https://github.com/Koenkk/zigbee2mqtt/commit/9b8583e778ffbd92ba82315d5a53ed68f51e4fc3))
* Check if Zigbee2MQTT is running in `update.sh` ([#21494](https://github.com/Koenkk/zigbee2mqtt/issues/21494)) ([8b69443](https://github.com/Koenkk/zigbee2mqtt/commit/8b694432aaa229823674eb4933eded3f2ab1517a))
* Fix endpoint matching for TuYa dummy endpoints ([#21576](https://github.com/Koenkk/zigbee2mqtt/issues/21576)) ([956003a](https://github.com/Koenkk/zigbee2mqtt/commit/956003aa0ab104f611cf3d0c61bec1c476ac17d0))
* Fix parsing entity name that contains slash in the name and endpoint specification ([#21493](https://github.com/Koenkk/zigbee2mqtt/issues/21493)) ([3c60965](https://github.com/Koenkk/zigbee2mqtt/commit/3c609658fd788410270af3343f01cc47b6ef0ab1))
* **ignore:** update dependencies ([#21347](https://github.com/Koenkk/zigbee2mqtt/issues/21347)) ([ce41f2f](https://github.com/Koenkk/zigbee2mqtt/commit/ce41f2f8ba89d31926cdce7d2d93ec19ffccf7fc))
* **ignore:** update dependencies ([#21444](https://github.com/Koenkk/zigbee2mqtt/issues/21444)) ([16b251d](https://github.com/Koenkk/zigbee2mqtt/commit/16b251d3c9c0651436899de6b63033d98e7b1353))
* **ignore:** update dependencies ([#21561](https://github.com/Koenkk/zigbee2mqtt/issues/21561)) ([c56470c](https://github.com/Koenkk/zigbee2mqtt/commit/c56470c83fd3b9ea366f67814e09146bcac6d188))
* **ignore:** update zigbee-herdsman to 0.33.9 ([#21386](https://github.com/Koenkk/zigbee2mqtt/issues/21386)) ([dfa4996](https://github.com/Koenkk/zigbee2mqtt/commit/dfa499659ec69db40ccc3d5c1dff874f446587d0))
* **ignore:** update zigbee-herdsman to 0.34.1 ([#21461](https://github.com/Koenkk/zigbee2mqtt/issues/21461)) ([b51eef2](https://github.com/Koenkk/zigbee2mqtt/commit/b51eef2319adf2b26b7b9a4a279adf2b671dd380))
* **ignore:** update zigbee-herdsman to 0.34.2 ([#21478](https://github.com/Koenkk/zigbee2mqtt/issues/21478)) ([78b5e6f](https://github.com/Koenkk/zigbee2mqtt/commit/78b5e6fd4b11ba138f83e848c60ac017fe5b10f2))
* **ignore:** update zigbee-herdsman to 0.34.3 ([#21530](https://github.com/Koenkk/zigbee2mqtt/issues/21530)) ([e726d59](https://github.com/Koenkk/zigbee2mqtt/commit/e726d5907e86ca3fabef4491579994d9e89f0fe0))
* **ignore:** update zigbee-herdsman to 0.34.4 ([#21545](https://github.com/Koenkk/zigbee2mqtt/issues/21545)) ([23959c5](https://github.com/Koenkk/zigbee2mqtt/commit/23959c5b0ec7e36183400920617e3052cd9bf17a))
* **ignore:** update zigbee-herdsman to 0.34.5 ([#21563](https://github.com/Koenkk/zigbee2mqtt/issues/21563)) ([cc27032](https://github.com/Koenkk/zigbee2mqtt/commit/cc2703275272c268b1f04ce75488027d6c70b870))
* **ignore:** update zigbee-herdsman to 0.34.6 ([#21567](https://github.com/Koenkk/zigbee2mqtt/issues/21567)) ([4f71c1e](https://github.com/Koenkk/zigbee2mqtt/commit/4f71c1e8bf3fe430cc03d3054a6e2a75ba6ec7de))
* **ignore:** update zigbee-herdsman to 0.34.7 ([#21575](https://github.com/Koenkk/zigbee2mqtt/issues/21575)) ([a06a0ea](https://github.com/Koenkk/zigbee2mqtt/commit/a06a0ea059354ac43de47c9d4e6d573bd6186288))
* **ignore:** update zigbee-herdsman to 0.34.8 ([#21588](https://github.com/Koenkk/zigbee2mqtt/issues/21588)) ([fee0811](https://github.com/Koenkk/zigbee2mqtt/commit/fee0811893a6bc90b86978e5c80cdb4e1a23ef70))
* **ignore:** update zigbee-herdsman to 0.34.9 ([#21602](https://github.com/Koenkk/zigbee2mqtt/issues/21602)) ([222b67b](https://github.com/Koenkk/zigbee2mqtt/commit/222b67b1b0c9151222c4d9cc2e531bf74a080ba6))
* **ignore:** update zigbee-herdsman to 0.35.0 ([#21621](https://github.com/Koenkk/zigbee2mqtt/issues/21621)) ([a84083b](https://github.com/Koenkk/zigbee2mqtt/commit/a84083be404a54303eb9337cc86c3938a1d5d41e))
* **ignore:** update zigbee-herdsman to 0.35.1 ([#21636](https://github.com/Koenkk/zigbee2mqtt/issues/21636)) ([0d8f578](https://github.com/Koenkk/zigbee2mqtt/commit/0d8f5780ddf05d176b199a152b3a1a212bca6810))
* **ignore:** update zigbee-herdsman-converters to 18.29.1 ([#21290](https://github.com/Koenkk/zigbee2mqtt/issues/21290)) ([55653c9](https://github.com/Koenkk/zigbee2mqtt/commit/55653c974ef72e8b5d8107d1b2e1b67efb70e4e1))
* **ignore:** update zigbee-herdsman-converters to 18.30.0 ([#21315](https://github.com/Koenkk/zigbee2mqtt/issues/21315)) ([910f3a6](https://github.com/Koenkk/zigbee2mqtt/commit/910f3a68603bf4b7f31d7a80370816d02f7126b8))
* **ignore:** update zigbee-herdsman-converters to 18.31.0 ([#21359](https://github.com/Koenkk/zigbee2mqtt/issues/21359)) ([c7b820c](https://github.com/Koenkk/zigbee2mqtt/commit/c7b820c3763e6052cc6755e0e12926c316de7f42))
* **ignore:** update zigbee-herdsman-converters to 18.32.0 ([#21373](https://github.com/Koenkk/zigbee2mqtt/issues/21373)) ([0ab7390](https://github.com/Koenkk/zigbee2mqtt/commit/0ab7390a642a723fc4e1847bbd95ea12487388ab))
* **ignore:** update zigbee-herdsman-converters to 18.33.0 ([#21387](https://github.com/Koenkk/zigbee2mqtt/issues/21387)) ([2aaf878](https://github.com/Koenkk/zigbee2mqtt/commit/2aaf878889b4211b8a470c847721c75b5a91e39e))
* **ignore:** update zigbee-herdsman-converters to 18.33.1 ([#21400](https://github.com/Koenkk/zigbee2mqtt/issues/21400)) ([8a9477f](https://github.com/Koenkk/zigbee2mqtt/commit/8a9477f2bb6afbfeacf64547c8bfe4ae4f18ca7f))
* **ignore:** update zigbee-herdsman-converters to 18.33.2 ([#21416](https://github.com/Koenkk/zigbee2mqtt/issues/21416)) ([5766bf4](https://github.com/Koenkk/zigbee2mqtt/commit/5766bf479ba548d819f87de2046f554b6de15945))
* **ignore:** update zigbee-herdsman-converters to 18.34.0 ([#21456](https://github.com/Koenkk/zigbee2mqtt/issues/21456)) ([ebed9d3](https://github.com/Koenkk/zigbee2mqtt/commit/ebed9d31d710ac6853e3eee6b677cfe6e84fd556))
* **ignore:** update zigbee-herdsman-converters to 18.35.0 ([#21487](https://github.com/Koenkk/zigbee2mqtt/issues/21487)) ([b32bd30](https://github.com/Koenkk/zigbee2mqtt/commit/b32bd309ca7748d4dcb0b3ca5b3428578a86487c))
* **ignore:** update zigbee-herdsman-converters to 18.36.0 ([#21504](https://github.com/Koenkk/zigbee2mqtt/issues/21504)) ([22d3336](https://github.com/Koenkk/zigbee2mqtt/commit/22d33360f6966625afb9f456d5ffe96c42baaa3f))
* **ignore:** update zigbee-herdsman-converters to 18.37.0 ([#21533](https://github.com/Koenkk/zigbee2mqtt/issues/21533)) ([1337f54](https://github.com/Koenkk/zigbee2mqtt/commit/1337f54e4a49ac9e28b9c3eb780829915b59cb57))
* **ignore:** update zigbee-herdsman-converters to 18.37.1 ([#21549](https://github.com/Koenkk/zigbee2mqtt/issues/21549)) ([7c97902](https://github.com/Koenkk/zigbee2mqtt/commit/7c97902d4a088d680010511148b67ac19d05b91a))
* **ignore:** update zigbee-herdsman-converters to 18.40.0 ([#21603](https://github.com/Koenkk/zigbee2mqtt/issues/21603)) ([aeaa040](https://github.com/Koenkk/zigbee2mqtt/commit/aeaa0409203e19d54511601cf7e0124db6a09778))
* **ignore:** update zigbee-herdsman-converters to 18.41.0 ([#21622](https://github.com/Koenkk/zigbee2mqtt/issues/21622)) ([72333f0](https://github.com/Koenkk/zigbee2mqtt/commit/72333f0888b5be3abacb286ed0a227438d593563))
* **ignore:** update zigbee-herdsman-converters to 18.42.0 ([#21637](https://github.com/Koenkk/zigbee2mqtt/issues/21637)) ([ccc3167](https://github.com/Koenkk/zigbee2mqtt/commit/ccc31670ec5b93bddaa8cef3f965fd8cc77e51a4))
* **ignore:** update zigbee2mqtt-frontend to 0.6.157 ([#21269](https://github.com/Koenkk/zigbee2mqtt/issues/21269)) ([a479bf9](https://github.com/Koenkk/zigbee2mqtt/commit/a479bf9039248d0b0ebc7e0f65dfc8ff342090d4))
* **ignore:** update zigbee2mqtt-frontend to 0.6.158 ([#21356](https://github.com/Koenkk/zigbee2mqtt/issues/21356)) ([8bc3c46](https://github.com/Koenkk/zigbee2mqtt/commit/8bc3c46c34e1c13c893b5d52143f6e357ff58546))
* **ignore:** update zigbee2mqtt-frontend to 0.6.159 ([#21623](https://github.com/Koenkk/zigbee2mqtt/issues/21623)) ([a8a2626](https://github.com/Koenkk/zigbee2mqtt/commit/a8a262640ff075e92bfb8d0491f4f9efe8f33ce2))
* Improve nested group and device name match ([#21521](https://github.com/Koenkk/zigbee2mqtt/issues/21521)) ([471902e](https://github.com/Koenkk/zigbee2mqtt/commit/471902e53134dbf2baddb9c37e2c20105b8f0043))
* Match endpoint name in the MQTT topic based on endpoints listed in the definition ([#21214](https://github.com/Koenkk/zigbee2mqtt/issues/21214)) ([a5a87a7](https://github.com/Koenkk/zigbee2mqtt/commit/a5a87a79a80aaa261a34a8fb541f47347c4ca729))
* Only configure routers on startup https://github.com/Koenkk/zigbee2mqtt/issues/21446 ([db1e3b7](https://github.com/Koenkk/zigbee2mqtt/commit/db1e3b73d1d4a2a98879ab10e5b18f84b30bd3bc))
* Remove dependency on predefined list of endpoints (`parseEntityID()` function) ([#21264](https://github.com/Koenkk/zigbee2mqtt/issues/21264)) ([81335e5](https://github.com/Koenkk/zigbee2mqtt/commit/81335e5b4b0ed0e1dacdd764de1711f5a1481f7f))
* Remove predefined endpoint list, remove limits on device friendly name ([#21325](https://github.com/Koenkk/zigbee2mqtt/issues/21325)) ([b4473d6](https://github.com/Koenkk/zigbee2mqtt/commit/b4473d6e24de8dc2db0ae7cb7bbb014788854ae4))
## [1.35.3](https://github.com/Koenkk/zigbee2mqtt/compare/1.35.2...1.35.3) (2024-02-06)
+23
View File
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
+8
View File
@@ -0,0 +1,8 @@
# Changelog
## [1.37.1](https://github.com/Koenkk/zigbee2mqtt/compare/1.37.0...1.37.1) (2024-05-09)
### Bug Fixes
* Add Helm chart ([#21852](https://github.com/Koenkk/zigbee2mqtt/issues/21852)) ([b2e8b3e](https://github.com/Koenkk/zigbee2mqtt/commit/b2e8b3e00c152540109e7b9101784f3b03261b40))
+17
View File
@@ -0,0 +1,17 @@
apiVersion: v2
appVersion: 1.37.1
description: Bridges events and allows you to control your Zigbee devices via MQTT
name: zigbee2mqtt
version: 1.37.1
kubeVersion: ">=1.26.0-0"
keywords:
- zigbee
- mqtt
- home-assistant
home: https://github.com/Koenkk/zigbee2mqtt
icon: https://www.zigbee2mqtt.io/logo.png
sources:
- https://github.com/Koenkk/zigbee2mqtt
maintainers:
- name: Koen Kanters
email: XXXX
+93
View File
@@ -0,0 +1,93 @@
# zigbee2mqtt
![Version: 1.37.1](https://img.shields.io/badge/Version-1.37.1-informational?style=flat-square) ![AppVersion: 1.37.1](https://img.shields.io/badge/AppVersion-1.37.1-informational?style=flat-square)
Bridges events and allows you to control your Zigbee devices via MQTT
**Homepage:** <https://github.com/Koenkk/zigbee2mqtt>
## Maintainers
| Name | Email | Url |
| ---- | ------ | --- |
| Koen Kanters | <XXXX> | |
## Source Code
* <https://github.com/Koenkk/zigbee2mqtt>
## Requirements
Kubernetes: `>=1.26.0-0`
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| customLabels | object | `{}` | |
| fullnameOverride | string | `nil` | override the name of the objects generated |
| image.imagePullSecrets | object | `{}` | Container additional secrets to pull image |
| image.pullPolicy | string | `"IfNotPresent"` | Container pull policy |
| image.repository | string | `"koenkk/zigbee2mqtt"` | Image repository for the `zigbee2mqtt` container. |
| image.tag | string | `"1.37.1"` | Version for the `zigbee2mqtt` container. |
| ingress.annotations | object | `{}` | |
| ingress.enabled | bool | `false` | When enabled a new Ingress will be created |
| ingress.hosts[0] | string | `"yourdomain.com"` | |
| ingress.ingressClassName | string | `"contour"` | |
| ingress.labels | object | `{}` | |
| ingress.path | string | `"/"` | |
| ingress.pathType | string | `"Prefix"` | |
| ingress.tls[0].hosts[0] | string | `"yourdomain.com"` | |
| ingress.tls[0].secretName | string | `"some-tls-secret"` | |
| nameOverride | string | `nil` | override the release name |
| service.annotations | object | `{}` | annotations for the service created |
| service.port | int | `8080` | port in which the service will be listening |
| service.type | string | `"LoadBalancer"` | type of Service to be created |
| statefulset.dnsPolicy | string | `"ClusterFirst"` | pod dns policy |
| statefulset.nodeSelector | object | `{}` | Select specific kube node, this will allow enforcing zigbee2mqtt running only on the node with the USB adapter connected |
| statefulset.resources | object | `{"limits":{"cpu":"200m","memory":"600Mi"},"requests":{"cpu":"200m","memory":"600Mi"}}` | CPU/Memory configuration for the pods |
| statefulset.storage.enabled | bool | `false` | |
| statefulset.storage.existingVolume | string | `""` | |
| statefulset.storage.matchExpressions | object | `{}` | |
| statefulset.storage.matchLabels | object | `{}` | |
| statefulset.storage.size | string | `"1Gi"` | |
| statefulset.storage.storageClassName | string | `"freenas-nfs-csi"` | the name for the storage class to be used in the persistent volume claim |
| statefulset.tolerations | object | `{}` | Node taint tolerations for the pods |
| zigbee2mqtt.advanced.adapter_concurrent | string | `nil` | Optional: configure adapter concurrency (e.g. 2 for CC2531 or 16 for CC26X2R1) (default: null, uses recommended value) |
| zigbee2mqtt.advanced.adapter_delay | int | `0` | Optional: Set the adapter delay, only used for Conbee/Raspbee adapters (default 0). In case you are having issues try `200`. For more information see https://github.com/Koenkk/zigbee2mqtt/issues/4884 |
| zigbee2mqtt.advanced.cache_state | bool | `true` | Has to be true when integrating via Home Assistant (default: true) |
| zigbee2mqtt.advanced.cache_state_persistent | bool | `true` | Optional: persist cached state, only used when cache_state: true (default: true) |
| zigbee2mqtt.advanced.cache_state_send_on_startup | bool | `true` | Optional: send cached state on startup, only used when cache_state_persistent: true (default: true) |
| zigbee2mqtt.advanced.channel | int | `11` | Optional: ZigBee channel, changing requires re-pairing of all devices. (Note: use a ZLL channel: 11, 15, 20, or 25 to avoid Problems) (default: 11) |
| zigbee2mqtt.advanced.elapsed | bool | `false` | Optional: Add an elapsed attribute to MQTT messages, contains milliseconds since the previous msg (default: false) |
| zigbee2mqtt.advanced.last_seen | string | `"disable"` | Optional: Add a last_seen attribute to MQTT messages, contains date/time of last Zigbee message possible values are: disable (default), ISO_8601, ISO_8601_local, epoch (default: disable) |
| zigbee2mqtt.advanced.legacy_api | bool | `false` | Optional: disables the legacy api (default: shown below) |
| zigbee2mqtt.advanced.log_level | string | `"info"` | |
| zigbee2mqtt.advanced.log_output | list | `["console"]` | Optional: network encryption key GENERATE will make Zigbee2MQTT generate a new network key on next startup Note: changing requires repairing of all devices (default: shown below) network_key: null |
| zigbee2mqtt.advanced.report | bool | `true` | Optional: Enables report feature, this feature is DEPRECATED since reporting is now setup by default when binding devices. Docs can still be found here: https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/information/report.md |
| zigbee2mqtt.advanced.timestamp_format | string | `"YYYY-MM-DD HH:mm:ss"` | |
| zigbee2mqtt.advanced.transmit_power | int | `5` | Optional: Transmit power setting in dBm (default: 5). This will set the transmit power for devices that bring an inbuilt amplifier. It can't go over the maximum of the respective hardware and might be limited by firmware (for example to migrate heat, or by using an unsupported firmware). For the CC2652R(B) this is 5 dBm, CC2652P/CC1352P-2 20 dBm. |
| zigbee2mqtt.availability.active.timeout | int | `10` | Time after which an active device will be marked as offline in minutes (default = 10 minutes) |
| zigbee2mqtt.availability.passive.timeout | int | `1500` | Time after which a passive device will be marked as offline in minutes (default = 1500 minutes aka 25 hours) |
| zigbee2mqtt.external_converters | list | `[]` | |
| zigbee2mqtt.frontend.auth_token | string | `nil` | Optional, enables authentication, disabled by default, cleartext (no hashing required) |
| zigbee2mqtt.frontend.host | string | `"0.0.0.0"` | Optional, empty by default to listen on both IPv4 and IPv6. Opens a unix socket when given a path instead of an address (e.g. '/run/zigbee2mqtt/zigbee2mqtt.sock') Don't set this if you use Docker or the Home Assistant add-on unless you're sure the chosen IP is available inside the container |
| zigbee2mqtt.frontend.port | int | `8080` | Mandatory, default 8080 |
| zigbee2mqtt.frontend.url | string | `nil` | Optional, url on which the frontend can be reached, currently only used for the Home Assistant device configuration page |
| zigbee2mqtt.homeassistant.discovery_topic | string | `"homeassistant"` | |
| zigbee2mqtt.homeassistant.enabled | bool | `true` | |
| zigbee2mqtt.homeassistant.legacy_entity_attributes | bool | `true` | |
| zigbee2mqtt.homeassistant.legacy_triggers | bool | `false` | |
| zigbee2mqtt.homeassistant.status_topic | string | `"hass/status"` | |
| zigbee2mqtt.mqtt.server | string | `"mqtt://localhost:1883"` | Required: MQTT server URL (use mqtts:// for SSL/TLS connection) |
| zigbee2mqtt.ota | object | `{"disable_automatic_update_check":false,"ikea_ota_use_test_url":false,"update_check_interval":1440}` | Optional: OTA update settings See https://www.zigbee2mqtt.io/guide/usage/ota_updates.html for more info |
| zigbee2mqtt.ota.disable_automatic_update_check | bool | `false` | Disable automatic update checks |
| zigbee2mqtt.ota.ikea_ota_use_test_url | bool | `false` | Optional: use IKEA TRADFRI OTA test server, see OTA updates documentation (default: false) |
| zigbee2mqtt.ota.update_check_interval | int | `1440` | Minimum time between OTA update checks |
| zigbee2mqtt.permit_join | bool | `false` | Optional: allow new devices to join. |
| zigbee2mqtt.serial.baudrate | int | `115200` | Optional: Baud rate speed for serial port, this can be anything firmware support but default is 115200 for Z-Stack and EZSP, 38400 for Deconz, however note that some EZSP firmware need 57600. |
| zigbee2mqtt.serial.disable_led | bool | `false` | Optional: disable LED of the adapter if supported (default: false) |
| zigbee2mqtt.serial.port | string | `"/dev/ttyACM0"` | Required: location of the adapter (e.g. CC2531). USB adapters - use format "port: /dev/ttyACM0" To autodetect the USB port, set 'port: null'. Ethernet adapters - use format "port: tcp://192.168.1.12:6638" |
| zigbee2mqtt.serial.rtscts | bool | `false` | Optional: RTS / CTS Hardware Flow Control for serial port (default: false) |
| zigbee2mqtt.timezone | string | `"UTC"` | |
+37
View File
@@ -0,0 +1,37 @@
{{/* vim: set filetype=mustache: */}}
{{/* Expand the name of the chart.*/}}
{{- define "zigbee2mqtt.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "zigbee2mqtt.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/* labels for helm resources */}}
{{- define "zigbee2mqtt.labels" -}}
app.kubernetes.io/instance: "{{ .Release.Name }}"
app.kubernetes.io/managed-by: "{{ .Release.Service }}"
app.kubernetes.io/name: "{{ template "zigbee2mqtt.name" . }}"
app.kubernetes.io/version: "{{ .Chart.AppVersion }}"
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}"
{{- if .Values.customLabels }}
{{ toYaml .Values.customLabels | indent 2 -}}
{{- end }}
{{- end }}
@@ -0,0 +1,39 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "zigbee2mqtt.fullname" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "zigbee2mqtt.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
data:
configuration.yaml: |
# Define the files which contains the configs. As k8s config maps
# Are read only by design, we need to extract dynamic config to external files
devices: devices.yaml
groups: groups.yaml
{{- if .Values.zigbee2mqtt.homeassistant }}
homeassistant:
{{- .Values.zigbee2mqtt.homeassistant | toYaml | nindent 6}}
{{- end }}
ota:
{{- .Values.zigbee2mqtt.ota | toYaml | nindent 6}}
permit_join: {{ .Values.zigbee2mqtt.permit_join }}
{{- if .Values.zigbee2mqtt.availability }}
availability:
{{- .Values.zigbee2mqtt.availability | toYaml | nindent 6}}
{{- end }}
{{- if gt (len .Values.zigbee2mqtt.external_converters) 0 }}
external_converters: {{- .Values.zigbee2mqtt.external_converters }}
{{- end }}
mqtt:
{{- .Values.zigbee2mqtt.mqtt | toYaml | nindent 6}}
serial:
{{- .Values.zigbee2mqtt.serial | toYaml | nindent 6}}
frontend:
{{- .Values.zigbee2mqtt.frontend | toYaml | nindent 6}}
advanced:
{{- .Values.zigbee2mqtt.advanced | toYaml | nindent 6}}
+56
View File
@@ -0,0 +1,56 @@
{{- if .Values.ingress.enabled -}}
{{- $servicePort := .Values.service.port -}}
{{- $ingressPath := .Values.ingress.path -}}
{{- $ingressPathType := .Values.ingress.pathType -}}
{{- $fullName := include "zigbee2mqtt.fullname" . }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "zigbee2mqtt.labels" . | nindent 4 }}
{{- with .Values.ingress.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.ingress.annotations }}
annotations:
{{- range $key, $value := . }}
{{ $key }}: {{ tpl $value $ | quote }}
{{- end }}
{{- end }}
spec:
ingressClassName: {{ .Values.ingress.ingressClassName }}
{{- with .Values.ingress.tls }}
tls:
{{- tpl (toYaml .) $ | nindent 4 }}
{{- end }}
rules:
{{- if .Values.ingress.hosts }}
{{- range .Values.ingress.hosts }}
- host: {{ tpl . $ | quote }}
http:
paths:
- path: {{ $ingressPath }}
pathType: {{ $ingressPathType }}
backend:
service:
name: {{ $fullName }}
port:
number: {{ $servicePort }}
{{- end }}
{{- else }}
- http:
paths:
- backend:
service:
name: {{ $fullName }}
port:
number: {{ $servicePort }}
{{- with $ingressPath }}
path: {{ . }}
{{- end }}
pathType: {{ $ingressPathType }}
{{- end -}}
{{- end }}
+20
View File
@@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "zigbee2mqtt.fullname" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "zigbee2mqtt.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
selector:
app: {{ include "zigbee2mqtt.fullname" . }}
ports:
- name: http
port: {{ .Values.service.port }}
targetPort: web
protocol: TCP
@@ -0,0 +1,102 @@
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: {{ include "zigbee2mqtt.fullname" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "zigbee2mqtt.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ include "zigbee2mqtt.fullname" . }}
template:
metadata:
labels:
{{- include "zigbee2mqtt.labels" . | nindent 8 }}
app: {{ include "zigbee2mqtt.fullname" . }}
spec:
{{- if .Values.image.imagePullSecrets }}
imagePullSecrets:
{{ toYaml .Values.image.imagePullSecrets | indent 8 }}
{{- end }}
dnsPolicy: {{ .Values.statefulset.dnsPolicy }}
{{- with .Values.statefulset.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
nodeSelector:
{{- with .Values.statefulset.nodeSelector }}
{{ toYaml . | indent 8 }}
{{- end }}
securityContext:
seccompProfile:
type: RuntimeDefault
{{- with .Values.statefulset.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
containers:
- name: zigbee2mqtt
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
securityContext:
privileged: true
capabilities:
add: ["SYS_ADMIN"]
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: TZ
value: {{ .Values.zigbee2mqtt.timezone }}
ports:
- containerPort: {{ .Values.zigbee2mqtt.frontend.port }}
name: web
protocol: TCP
livenessProbe:
failureThreshold: 5
httpGet:
path: /
port: web
initialDelaySeconds: 60
timeoutSeconds: 10
periodSeconds: 30
volumeMounts:
- mountPath: /app/data/configuration.yaml
name: config-volume
subPath: configuration.yaml
- mountPath: /app/data/
name: data-volume
resources: {{- toYaml .Values.statefulset.resources | nindent 12 }}
volumes:
- name: config-volume
configMap:
name: {{ include "zigbee2mqtt.fullname" . }}
{{- if not .Values.statefulset.storage.enabled }}
- name: data-volume
emptyDir: { }
{{- end }}
{{- if .Values.statefulset.storage.enabled }}
volumeClaimTemplates:
- metadata:
name: data-volume
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: {{ .Values.statefulset.storage.storageClassName }}
{{- if .Values.statefulset.storage.existingVolume }}
volumeName: {{ .Values.statefulset.storage.existingVolume }}
{{- end }}
{{- if or .Values.statefulset.storage.matchLabels (.Values.statefulset.storage.matchExpressions) }}
selector:
{{- if .Values.statefulset.storage.matchLabels }}
matchLabels:
{{ toYaml .Values.statefulset.storage.matchLabels | indent 8 }}
{{- end -}}
{{- if .Values.statefulset.storage.matchExpressions }}
matchExpressions:
{{ toYaml .Values.statefulset.storage.matchExpressions | indent 8 }}
{{- end -}}
{{- end }}
resources:
requests:
storage: {{ .Values.statefulset.storage.size }}
{{- end }}
+201
View File
@@ -0,0 +1,201 @@
# -- override the release name
nameOverride: null
# -- override the name of the objects generated
fullnameOverride: null
customLabels: {}
image:
# -- Image repository for the `zigbee2mqtt` container.
repository: koenkk/zigbee2mqtt
# -- Version for the `zigbee2mqtt` container.
tag: "1.37.1"
# -- Container pull policy
pullPolicy: IfNotPresent
# -- Container additional secrets to pull image
imagePullSecrets: {}
service:
# -- annotations for the service created
annotations: {}
# -- type of Service to be created
type: LoadBalancer
# -- port in which the service will be listening
port: 8080
statefulset:
storage:
enabled: false
size: 1Gi
# -- the name for the storage class to be used in the persistent volume claim
storageClassName: freenas-nfs-csi
existingVolume: ""
## Persistent Volume selectors
## https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector
matchLabels: {}
matchExpressions: {}
# -- pod dns policy
dnsPolicy: ClusterFirst
# -- CPU/Memory configuration for the pods
resources:
requests:
memory: 600Mi
cpu: 200m
limits:
memory: 600Mi
cpu: 200m
# -- Node taint tolerations for the pods
tolerations: {}
# -- Select specific kube node, this will allow enforcing zigbee2mqtt running
# only on the node with the USB adapter connected
nodeSelector: {}
zigbee2mqtt:
homeassistant:
enabled: true
discovery_topic: 'homeassistant'
status_topic: 'hass/status'
legacy_entity_attributes: true
legacy_triggers: false
# -- Optional: allow new devices to join.
permit_join: false
availability:
active:
# -- Time after which an active device will be marked as offline in
# minutes (default = 10 minutes)
timeout: 10
passive:
# -- Time after which a passive device will be marked as offline in
# minutes (default = 1500 minutes aka 25 hours)
timeout: 1500
timezone: UTC
external_converters: []
mqtt:
# -- Required: MQTT server URL (use mqtts:// for SSL/TLS connection)
server: "mqtt://localhost:1883"
# -- Optional: MQTT base topic for Zigbee2MQTT MQTT messages (default: zigbee2mqtt)
# base_topic: zigbee2mqtt
# -- Optional: absolute path to SSL/TLS certificate of CA used to sign server and client certificates (default: nothing)
# ca: '/etc/ssl/mqtt-ca.crt'
# -- Optional: absolute paths to SSL/TLS key and certificate for client-authentication (default: nothing)
# key: '/etc/ssl/mqtt-client.key'
# cert: '/etc/ssl/mqtt-client.crt'
# -- Optional: MQTT server authentication user (default: nothing)
# user: my_user
# -- Optional: MQTT server authentication password (default: nothing)
# password: my_password
# -- Optional: MQTT client ID (default: nothing)
# client_id: 'MY_CLIENT_ID'
# -- Optional: disable self-signed SSL certificates (default: true)
# reject_unauthorized: true
# -- Optional: Include device information to mqtt messages (default: false)
# include_device_information: true
# -- Optional: MQTT keepalive in seconds (default: 60)
# keepalive: 60
# -- Optional: MQTT protocol version (default: 4), set this to 5 if you
# use the 'retention' device specific configuration
# version: 4
# -- Optional: Disable retain for all send messages. ONLY enable if you MQTT broker doesn't
# support retained message (e.g. AWS IoT core, Azure IoT Hub, Google Cloud IoT core, IBM Watson IoT Platform).
# Enabling will break the Home Assistant integration. (default: false)
# force_disable_retain: false
serial:
# -- Required: location of the adapter (e.g. CC2531).
# USB adapters - use format "port: /dev/ttyACM0"
# To autodetect the USB port, set 'port: null'.
# Ethernet adapters - use format "port: tcp://192.168.1.12:6638"
port: "/dev/ttyACM0"
# -- Optional: disable LED of the adapter if supported (default: false)
disable_led: false
# -- Optional: adapter type, not needed unless you are experiencing problems (default: shown below, options: zstack, deconz, ezsp)
# adapter: null
# -- Optional: Baud rate speed for serial port, this can be anything firmware support but default is 115200 for Z-Stack and EZSP, 38400 for Deconz, however note that some EZSP firmware need 57600.
baudrate: 115200
# -- Optional: RTS / CTS Hardware Flow Control for serial port (default: false)
rtscts: false
# -- Optional: OTA update settings
# See https://www.zigbee2mqtt.io/guide/usage/ota_updates.html for more info
ota:
# -- Optional: use IKEA TRADFRI OTA test server, see OTA updates documentation (default: false)
ikea_ota_use_test_url: false
# -- Minimum time between OTA update checks
update_check_interval: 1440
# -- Disable automatic update checks
disable_automatic_update_check: false
frontend:
# -- Mandatory, default 8080
port: 8080
# -- Optional, empty by default to listen on both IPv4 and IPv6. Opens a unix socket when given a path instead of an address (e.g. '/run/zigbee2mqtt/zigbee2mqtt.sock')
# Don't set this if you use Docker or the Home Assistant add-on unless you're sure the chosen IP is available inside the container
host: 0.0.0.0
# -- Optional, enables authentication, disabled by default, cleartext (no hashing required)
auth_token: null
# -- Optional, url on which the frontend can be reached, currently only used for the Home Assistant device configuration page
url: null
advanced:
# -- Optional: ZigBee pan ID (default: shown below)
# Setting pan_id: GENERATE will make Zigbee2MQTT generate a new panID on next startup
# pan_id: null
# Optional: Zigbee extended pan ID, GENERATE will make Zigbee2MQTT generate a new extended panID on next startup (default: shown below)
# ext_pan_id: null
# -- Optional: ZigBee channel, changing requires re-pairing of all devices. (Note: use a ZLL channel: 11, 15, 20, or 25 to avoid Problems)
# (default: 11)
channel: 11
# -- Optional: network encryption key
# GENERATE will make Zigbee2MQTT generate a new network key on next startup
# Note: changing requires repairing of all devices (default: shown below)
# network_key: null
log_output:
- console
log_level: info
timestamp_format: 'YYYY-MM-DD HH:mm:ss'
# -- Optional: state caching, MQTT message payload will contain all attributes, not only changed ones.
# -- Has to be true when integrating via Home Assistant (default: true)
cache_state: true
# -- Optional: persist cached state, only used when cache_state: true (default: true)
cache_state_persistent: true
# -- Optional: send cached state on startup, only used when cache_state_persistent: true (default: true)
cache_state_send_on_startup: true
# -- Optional: Add a last_seen attribute to MQTT messages, contains date/time of last Zigbee message
# possible values are: disable (default), ISO_8601, ISO_8601_local, epoch (default: disable)
last_seen: 'disable'
# -- Optional: Add an elapsed attribute to MQTT messages, contains milliseconds since the previous msg (default: false)
elapsed: false
# -- Optional: Enables report feature, this feature is DEPRECATED since reporting is now setup by default
# when binding devices. Docs can still be found here: https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/information/report.md
report: true
# -- Optional: disables the legacy api (default: shown below)
legacy_api: false
# -- Optional: MQTT output type: json, attribute or attribute_and_json (default: shown below)
# Examples when 'state' of a device is published
# json: topic: 'zigbee2mqtt/my_bulb' payload '{"state": "ON"}'
# attribute: topic 'zigbee2mqtt/my_bulb/state' payload 'ON"
# attribute_and_json:
# -- Optional: configure adapter concurrency (e.g. 2 for CC2531 or 16 for CC26X2R1) (default: null, uses recommended value)
adapter_concurrent: null
# -- Optional: Transmit power setting in dBm (default: 5).
# This will set the transmit power for devices that bring an inbuilt amplifier.
# It can't go over the maximum of the respective hardware and might be limited
# by firmware (for example to migrate heat, or by using an unsupported firmware).
# For the CC2652R(B) this is 5 dBm, CC2652P/CC1352P-2 20 dBm.
transmit_power: 5
# -- Optional: Set the adapter delay, only used for Conbee/Raspbee adapters (default 0).
# In case you are having issues try `200`.
# For more information see https://github.com/Koenkk/zigbee2mqtt/issues/4884
adapter_delay: 0
ingress:
# -- When enabled a new Ingress will be created
enabled: false
# The ingress class name for the ingress
ingressClassName: contour
# Additional labels for the ingres
labels: {}
# URL in which the ingress will be accepting requests for zigbee2mqtt
path: /
# Ingress implementation specific (potentially) for most use cases Prefix should be ok
pathType: Prefix
# Additional annotations for the ingress. ExternalDNS, and CertManager are tipically integrated here
annotations: {}
# configuration for tls service (ig any)
tls:
- secretName: some-tls-secret
hosts:
- yourdomain.com
# list of hosts that should be allowed for the zigbee2mqtt service
hosts:
- yourdomain.com
Executable → Regular
+120 -1
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 25 KiB

+7 -7
View File
@@ -8,7 +8,8 @@ import utils from './util/utils';
import stringify from 'json-stable-stringify-without-jsonify';
import assert from 'assert';
import bind from 'bind-decorator';
import * as zhc from 'zigbee-herdsman-converters';
import {setLogger as zhcSetLogger} from 'zigbee-herdsman-converters';
import {setLogger as zhSetLogger} from 'zigbee-herdsman';
// Extensions
import ExtensionFrontend from './extension/frontend';
@@ -60,6 +61,8 @@ export class Controller {
constructor(restartCallback: () => void, exitCallback: (code: number, restart: boolean) => void) {
logger.init();
zhSetLogger(logger);
zhcSetLogger(logger);
this.eventBus = new EventBus();
this.zigbee = new Zigbee(this.eventBus);
this.mqtt = new MQTT(this.eventBus);
@@ -92,13 +95,10 @@ export class Controller {
/* istanbul ignore next */
settings.get().advanced.soft_reset_timeout !== 0 && new ExtensionSoftReset(...this.extensionArgs),
].filter((n) => n);
zhc.setLogger(logger);
}
async start(): Promise<void> {
this.state.start();
logger.logOutput();
const info = await utils.getZigbee2MQTTVersion();
logger.info(`Starting Zigbee2MQTT version ${info.version} (commit #${info.commitHash})`);
@@ -138,9 +138,9 @@ export class Controller {
// Enable zigbee join
try {
if (settings.get().permit_join) {
logger.warn('`permit_join` set to `true` in configuration.yaml.');
logger.warn('Allowing new devices to join.');
logger.warn('Set `permit_join` to `false` once you joined all devices.');
logger.warning('`permit_join` set to `true` in configuration.yaml.');
logger.warning('Allowing new devices to join.');
logger.warning('Set `permit_join` to `false` once you joined all devices.');
}
await this.zigbee.permitJoin(settings.get().permit_join);
+2 -2
View File
@@ -87,7 +87,7 @@ export default class Availability extends Extension {
logger.debug(`Successfully pinged '${device.name}' (attempt ${i + 1}/${attempts})`);
break;
} catch (error) {
logger.warn(`Failed to ping '${device.name}' (attempt ${i + 1}/${attempts}, ${error.message})`);
logger.warning(`Failed to ping '${device.name}' (attempt ${i + 1}/${attempts}, ${error.message})`);
// Try again in 3 seconds.
const lastAttempt = i - 1 === attempts;
!lastAttempt && await utils.sleep(3);
@@ -215,7 +215,7 @@ export default class Availability extends Extension {
const options: KeyValue = device.options;
const state = this.state.get(device);
const meta: zhc.Tz.Meta = {
message: this.state.get(device), mapped: device.definition, logger, endpoint_name: null,
message: this.state.get(device), mapped: device.definition, endpoint_name: null,
options, state, device: device.zh,
};
await converter?.convertGet?.(device.endpoint(), item.keys[0], meta)
+30 -27
View File
@@ -4,7 +4,7 @@ import utils from '../util/utils';
import Extension from './extension';
import stringify from 'json-stable-stringify-without-jsonify';
import debounce from 'debounce';
import * as zigbeeHerdsman from 'zigbee-herdsman/dist';
import {Zcl} from 'zigbee-herdsman';
import bind from 'bind-decorator';
import Device from '../model/device';
import Group from '../model/group';
@@ -97,12 +97,12 @@ const pollOnMessage: PollOnMessage = [
read: {cluster: 'genLevelCtrl', attributes: ['currentLevel']},
// When the bound devices/members of group have the following manufacturerIDs
manufacturerIDs: [
zigbeeHerdsman.Zcl.ManufacturerCode.Philips,
zigbeeHerdsman.Zcl.ManufacturerCode.ATMEL,
zigbeeHerdsman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHerdsman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
zigbeeHerdsman.Zcl.ManufacturerCode.TELINK,
zigbeeHerdsman.Zcl.ManufacturerCode.BUSCH_JAEGER,
Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
Zcl.ManufacturerCode.ATMEL,
Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
Zcl.ManufacturerCode.TELINK_MICRO,
Zcl.ManufacturerCode.BUSCH_JAEGER_ELEKTRO,
],
manufacturerNames: [
'GLEDOPTO',
@@ -133,12 +133,12 @@ const pollOnMessage: PollOnMessage = [
},
read: {cluster: 'genOnOff', attributes: ['onOff']},
manufacturerIDs: [
zigbeeHerdsman.Zcl.ManufacturerCode.Philips,
zigbeeHerdsman.Zcl.ManufacturerCode.ATMEL,
zigbeeHerdsman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHerdsman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
zigbeeHerdsman.Zcl.ManufacturerCode.TELINK,
zigbeeHerdsman.Zcl.ManufacturerCode.BUSCH_JAEGER,
Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
Zcl.ManufacturerCode.ATMEL,
Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
Zcl.ManufacturerCode.TELINK_MICRO,
Zcl.ManufacturerCode.BUSCH_JAEGER_ELEKTRO,
],
manufacturerNames: [
'GLEDOPTO',
@@ -165,11 +165,11 @@ const pollOnMessage: PollOnMessage = [
},
},
manufacturerIDs: [
zigbeeHerdsman.Zcl.ManufacturerCode.Philips,
zigbeeHerdsman.Zcl.ManufacturerCode.ATMEL,
zigbeeHerdsman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHerdsman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
zigbeeHerdsman.Zcl.ManufacturerCode.TELINK,
Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V,
Zcl.ManufacturerCode.ATMEL,
Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC,
Zcl.ManufacturerCode.TELINK_MICRO,
// Note: ManufacturerCode.BUSCH_JAEGER is left out intentionally here as their devices don't support colors
],
manufacturerNames: [
@@ -222,25 +222,28 @@ export default class Bind extends Extension {
const message = utils.parseJSON(data.message, data.message);
let error = null;
const parsedSource = utils.parseEntityID(sourceKey);
const parsedTarget = utils.parseEntityID(targetKey);
const source = this.zigbee.resolveEntity(parsedSource.ID);
const target = targetKey === 'default_bind_group' ?
defaultBindGroup : this.zigbee.resolveEntity(parsedTarget.ID);
const parsedSource = this.zigbee.resolveEntityAndEndpoint(sourceKey);
const parsedTarget = this.zigbee.resolveEntityAndEndpoint(targetKey);
const source = parsedSource.entity;
const target = targetKey === 'default_bind_group' ? defaultBindGroup : parsedTarget.entity;
const responseData: KeyValue = {from: sourceKey, to: targetKey};
if (!source || !(source instanceof Device)) {
error = `Source device '${sourceKey}' does not exist`;
} else if (parsedSource.endpointID && !parsedSource.endpoint) {
error = `Source device '${parsedSource.ID}' does not have endpoint '${parsedSource.endpointID}'`;
} else if (!target) {
error = `Target device or group '${targetKey}' does not exist`;
} else if (target instanceof Device && parsedTarget.endpointID && !parsedTarget.endpoint) {
error = `Target device '${parsedTarget.ID}' does not have endpoint '${parsedTarget.endpointID}'`;
} else {
const successfulClusters: string[] = [];
const failedClusters = [];
const attemptedClusters = [];
const bindSource: zh.Endpoint = source.endpoint(parsedSource.endpoint);
const bindSource: zh.Endpoint = parsedSource.endpoint;
let bindTarget: number | zh.Group | zh.Endpoint = null;
if (target instanceof Device) bindTarget = target.endpoint(parsedTarget.endpoint);
if (target instanceof Device) bindTarget = parsedTarget.endpoint;
else if (target instanceof Group) bindTarget = target.zh;
else bindTarget = Number(target.ID);
@@ -391,7 +394,7 @@ export default class Bind extends Extension {
await endpoint.configureReporting(bind.cluster.name, items);
logger.info(`Successfully setup reporting for '${entity}' cluster '${bind.cluster.name}'`);
} catch (error) {
logger.warn(`Failed to setup reporting for '${entity}' cluster '${bind.cluster.name}'`);
logger.warning(`Failed to setup reporting for '${entity}' cluster '${bind.cluster.name}'`);
}
}
}
@@ -433,7 +436,7 @@ export default class Bind extends Extension {
await endpoint.configureReporting(cluster, items);
logger.info(`Successfully disabled reporting for '${entity}' cluster '${cluster}'`);
} catch (error) {
logger.warn(`Failed to disable reporting for '${entity}' cluster '${cluster}'`);
logger.warning(`Failed to disable reporting for '${entity}' cluster '${cluster}'`);
}
}
+57 -14
View File
@@ -13,6 +13,7 @@ import data from '../util/data';
import JSZip from 'jszip';
import fs from 'fs';
import * as zhc from 'zigbee-herdsman-converters';
import winston from 'winston';
const requestRegex = new RegExp(`${settings.get().mqtt.base_topic}/bridge/request/(.*)`);
@@ -28,6 +29,8 @@ export default class Bridge extends Extension {
private coordinatorVersion: zh.CoordinatorVersion;
private restartRequired = false;
private lastJoinedDeviceIeeeAddr: string;
private lastBridgeLoggingPayload: string;
private logTransport: winston.transport;
private requestLookup: {[key: string]: (message: KeyValue | string) => Promise<MQTTResponse>};
override async start(): Promise<void> {
@@ -58,16 +61,41 @@ export default class Bridge extends Extension {
'config/log_level': this.configLogLevel,
};
const mqtt = this.mqtt;
class EventTransport extends Transport {
log(info: {message: string, level: string}, callback: () => void): void {
const payload = stringify({message: info.message, level: info.level});
mqtt.publish(`bridge/logging`, payload, {}, settings.get().mqtt.base_topic, true);
callback();
const debugToMQTTFrontend = settings.get().advanced.log_debug_to_mqtt_frontend;
const baseTopic = settings.get().mqtt.base_topic;
const bridgeLogging = (message: string, level: string, namespace: string): void => {
const payload = stringify({message, level, namespace});
if (payload !== this.lastBridgeLoggingPayload) {
this.lastBridgeLoggingPayload = payload;
this.mqtt.publish(`bridge/logging`, payload, {}, baseTopic, true);
}
};
if (debugToMQTTFrontend) {
class DebugEventTransport extends Transport {
log(info: {message: string, level: string, namespace: string}, next: () => void): void {
bridgeLogging(info.message, info.level, info.namespace);
next();
}
}
this.logTransport = new DebugEventTransport();
} else {
class EventTransport extends Transport {
log(info: {message: string, level: string, namespace: string}, next: () => void): void {
if (info.level !== 'debug') {
bridgeLogging(info.message, info.level, info.namespace);
}
next();
}
}
this.logTransport = new EventTransport();
}
logger.addTransport(new EventTransport());
logger.addTransport(this.logTransport);
this.zigbee2mqttVersion = await utils.getZigbee2MQTTVersion();
this.zigbeeHerdsmanVersion = await utils.getDependencyVersion('zigbee-herdsman');
@@ -118,6 +146,11 @@ export default class Bridge extends Extension {
this.eventBus.onMQTTMessage(this, this.onMQTTMessage);
}
override async stop(): Promise<void> {
super.stop();
logger.removeTransport(this.logTransport);
}
@bind async onMQTTMessage(data: eventdata.MQTTMessage): Promise<void> {
const match = data.topic.match(requestRegex);
const key = match?.[1]?.toLowerCase();
@@ -158,18 +191,22 @@ export default class Bridge extends Extension {
if (restartRequired) this.restartRequired = true;
// Apply some settings on-the-fly.
if (newSettings.hasOwnProperty('permit_join')) {
if (newSettings.permit_join != undefined) {
await this.zigbee.permitJoin(newSettings.permit_join);
}
if (newSettings.hasOwnProperty('homeassistant')) {
if (newSettings.homeassistant != undefined) {
await this.enableDisableExtension(newSettings.homeassistant, 'HomeAssistant');
}
if (newSettings.hasOwnProperty('advanced') && newSettings.advanced.hasOwnProperty('log_level')) {
if (newSettings.advanced?.log_level != undefined) {
logger.setLevel(newSettings.advanced.log_level);
}
if (newSettings.advanced?.log_debug_namespace_ignore != undefined) {
logger.setDebugNamespaceIgnore(newSettings.advanced.log_debug_namespace_ignore);
}
logger.info('Successfully changed options');
this.publishInfo();
return utils.getResponse(message, {restart_required: this.restartRequired}, null);
@@ -430,8 +467,13 @@ export default class Bridge extends Extension {
throw new Error(`Invalid payload`);
}
const parsedID = utils.parseEntityID(message.id);
const endpoint = (this.getEntity('device', parsedID.ID) as Device).endpoint(parsedID.endpoint);
const device = this.zigbee.resolveEntityAndEndpoint(message.id);
if (!device.entity) throw new Error(`Device '${message.id}' does not exist`);
const endpoint = device.endpoint;
if (device.endpointID && !endpoint) {
throw new Error(`Device '${device.ID}' does not have endpoint '${device.endpointID}'`);
}
const coordinatorEndpoint = this.zigbee.firstCoordinatorEndpoint();
await endpoint.bind(message.cluster, coordinatorEndpoint);
@@ -457,8 +499,9 @@ export default class Bridge extends Extension {
throw new Error(`Invalid payload`);
}
const parsedID = utils.parseEntityID(message.id);
const device = this.getEntity('device', parsedID.ID) as Device;
const device = this.zigbee.resolveEntityAndEndpoint(message.id).entity as Device;
if (!device) throw new Error(`Device '${message.id}' does not exist`);
const source = await zhc.generateExternalDefinitionSource(device.zh);
return utils.getResponse(message, {id: message.id, source}, null);
+6 -5
View File
@@ -35,7 +35,7 @@ export default class Configure extends Extension {
}
if (!device.definition || !device.definition.configure) {
logger.warn(`Skipping configure of '${device.name}', device does not require this.`);
logger.warning(`Skipping configure of '${device.name}', device does not require this.`);
return;
}
@@ -65,7 +65,9 @@ export default class Configure extends Extension {
override async start(): Promise<void> {
setImmediate(async () => {
for (const device of this.zigbee.devices(false)) {
// Only configure routers on startup, end devices are likely sleeping and
// will reconfigure once they send a message
for (const device of this.zigbee.devices(false).filter((d) => d.zh.type === 'Router')) {
// Sleep 10 seconds between configuring on startup to not DDoS the coordinator
// when many devices have to be configured.
await utils.sleep(10);
@@ -94,8 +96,7 @@ export default class Configure extends Extension {
return;
}
if (device.zh.meta?.hasOwnProperty('configured') &&
device.zh.meta.configured === zhc.getConfigureKey(device.definition)) {
if (device.zh.meta?.hasOwnProperty('configured')) {
return;
}
@@ -117,7 +118,7 @@ export default class Configure extends Extension {
logger.info(`Configuring '${device.name}'`);
try {
await device.definition.configure(device.zh, this.zigbee.firstCoordinatorEndpoint(), logger);
await device.definition.configure(device.zh, this.zigbee.firstCoordinatorEndpoint(), device.definition);
logger.info(`Successfully configured '${device.name}'`);
device.zh.meta.configured = zhc.getConfigureKey(device.definition);
device.zh.save();
+22 -10
View File
@@ -68,10 +68,13 @@ export default class Groups extends Extension {
const groupID = settingGroup.ID;
const zigbeeGroup = zigbeeGroups.find((g) => g.ID === groupID) || this.zigbee.createGroup(groupID);
const settingsEndpoint = settingGroup.devices.map((d) => {
const parsed = utils.parseEntityID(d);
const entity = this.zigbee.resolveEntity(parsed.ID) as Device;
const parsed = this.zigbee.resolveEntityAndEndpoint(d);
const entity = parsed.entity as Device;
if (!entity) logger.error(`Cannot find '${d}' of group '${settingGroup.friendly_name}'`);
return {'endpoint': entity?.endpoint(parsed.endpoint), 'name': entity?.name};
if (parsed.endpointID && !parsed.endpoint) {
logger.error(`Cannot find endpoint '${parsed.endpointID}' of device '${parsed.ID}'`);
}
return {'endpoint': parsed.endpoint, 'name': entity?.name};
}).filter((e) => e.endpoint != null);
// In settings but not in zigbee
@@ -109,8 +112,9 @@ export default class Groups extends Extension {
const payload: KeyValue = {};
let endpointName: string = null;
const endpointNames: string[] = data.entity instanceof Device ? data.entity.getEndpointNames() : [];
for (let [prop, value] of Object.entries(data.update)) {
const endpointNameMatch = utils.endpointNames.find((n) => prop.endsWith(`_${n}`));
const endpointNameMatch = endpointNames.find((n) => prop.endsWith(`_${n}`));
if (endpointNameMatch) {
prop = prop.substring(0, prop.length - endpointNameMatch.length - 1);
endpointName = endpointNameMatch;
@@ -237,8 +241,8 @@ export default class Groups extends Extension {
type = 'remove_all';
}
const parsedEntity = utils.parseEntityID(data.message);
resolvedEntityDevice = this.zigbee.resolveEntity(parsedEntity.ID) as Device;
const parsedEntity = this.zigbee.resolveEntityAndEndpoint(data.message);
resolvedEntityDevice = parsedEntity.entity as Device;
if (!resolvedEntityDevice || !(resolvedEntityDevice instanceof Device)) {
logger.error(`Device '${data.message}' does not exist`);
@@ -255,7 +259,12 @@ export default class Groups extends Extension {
return null;
}
resolvedEntityEndpoint = resolvedEntityDevice.endpoint(parsedEntity.endpoint);
resolvedEntityEndpoint = parsedEntity.endpoint;
if (parsedEntity.endpointID && !resolvedEntityEndpoint) {
logger.error(`Device '${parsedEntity.ID}' does not have endpoint '${parsedEntity.endpointID}'`);
return null;
}
} else if (topicRegexMatch) {
type = topicRegexMatch[1] as 'remove' | 'add' | 'remove_all';
const message = JSON.parse(data.message);
@@ -270,13 +279,16 @@ export default class Groups extends Extension {
}
}
const parsed = utils.parseEntityID(message.device);
resolvedEntityDevice = this.zigbee.resolveEntity(parsed.ID) as Device;
const parsed = this.zigbee.resolveEntityAndEndpoint(message.device);
resolvedEntityDevice = parsed?.entity as Device;
if (!error && (!resolvedEntityDevice || !(resolvedEntityDevice instanceof Device))) {
error = `Device '${message.device}' does not exist`;
}
if (!error) {
resolvedEntityEndpoint = resolvedEntityDevice.endpoint(parsed.endpoint);
resolvedEntityEndpoint = parsed.endpoint;
if (parsed.endpointID && !resolvedEntityEndpoint) {
error = `Device '${parsed.ID}' does not have endpoint '${parsed.endpointID}'`;
}
}
}
+46 -16
View File
@@ -128,7 +128,7 @@ export default class HomeAssistant extends Extension {
override async start(): Promise<void> {
if (!settings.get().advanced.cache_state) {
logger.warn('In order for Home Assistant integration to work properly set `cache_state: true');
logger.warning('In order for Home Assistant integration to work properly set `cache_state: true');
}
this.zigbee2MQTTVersion = (await utils.getZigbee2MQTTVersion(false)).version;
@@ -210,7 +210,6 @@ export default class HomeAssistant extends Extension {
].filter((c) => c);
if (colorModes.length) {
discoveryEntry.discovery_payload.color_mode = true;
discoveryEntry.discovery_payload.supported_color_modes = colorModes;
}
@@ -600,6 +599,7 @@ export default class HomeAssistant extends Extension {
discoveryEntries.push(discoveryEntry);
} else if (isBinaryExposeFeature(firstExpose)) {
const lookup: {[s: string]: KeyValue}= {
activity_led_indicator: {icon: 'mdi:led-on'},
auto_off: {icon: 'mdi:flash-auto'},
battery_low: {entity_category: 'diagnostic', device_class: 'battery'},
button_lock: {entity_category: 'config', icon: 'mdi:lock'},
@@ -613,7 +613,7 @@ export default class HomeAssistant extends Extension {
card: {entity_category: 'config', icon: 'mdi:clipboard-check'},
child_lock: {entity_category: 'config', icon: 'mdi:account-lock'},
color_sync: {entity_category: 'config', icon: 'mdi:sync-circle'},
consumer_connected: {entity_category: 'diagnostic', device_class: 'connectivity'},
consumer_connected: {device_class: 'plug'},
contact: {device_class: 'door'},
garage_door_contact: {device_class: 'garage_door', payload_on: false, payload_off: true},
eco_mode: {entity_category: 'config', icon: 'mdi:leaf'},
@@ -629,6 +629,7 @@ export default class HomeAssistant extends Extension {
motor_reversal: {entity_category: 'config', icon: 'mdi:arrow-left-right'},
moving: {device_class: 'moving'},
no_position_support: {entity_category: 'config', icon: 'mdi:minus-circle-outline'},
noise_detected: {device_class: 'sound'},
occupancy: {device_class: 'motion'},
power_outage_memory: {entity_category: 'config', icon: 'mdi:memory'},
presence: {device_class: 'presence'},
@@ -644,6 +645,7 @@ 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'},
th_heater: {icon: 'mdi:heat-wave'},
trigger_indicator: {icon: 'mdi:led-on'},
valve_alarm: {device_class: 'problem'},
valve_detection: {icon: 'mdi:pipe-valve'},
@@ -682,9 +684,6 @@ export default class HomeAssistant extends Extension {
},
};
// Let Home Assistant generate entity name when device_class is present
if (discoveryEntry.discovery_payload.device_class) delete discoveryEntry.discovery_payload.name;
discoveryEntries.push(discoveryEntry);
} else {
const discoveryEntry: DiscoveryEntry = {
@@ -700,9 +699,6 @@ export default class HomeAssistant extends Extension {
},
};
// Let Home Assistant generate entity name when device_class is present
if (discoveryEntry.discovery_payload.device_class) delete discoveryEntry.discovery_payload.name;
discoveryEntries.push(discoveryEntry);
}
} else if (isNumericExposeFeature(firstExpose)) {
@@ -792,6 +788,11 @@ export default class HomeAssistant extends Extension {
min_temperature: {entity_category: 'config', icon: 'mdi:thermometer-low'},
minimum_on_level: {entity_category: 'config'},
measurement_poll_interval: {entity_category: 'config', icon: 'mdi:clock-out'},
noise: {device_class: 'sound_pressure', state_class: 'measurement'},
noise_detect_level: {icon: 'mdi:volume-equal'},
noise_timeout: {icon: 'mdi:timer'},
occupancy_level: {icon: 'mdi:motion-sensor'},
occupancy_sensitivity: {icon: 'mdi:motion-sensor'},
occupancy_timeout: {entity_category: 'config', icon: 'mdi:timer'},
overload_protection: {icon: 'mdi:flash'},
pm10: {device_class: 'pm10', state_class: 'measurement'},
@@ -801,7 +802,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'},
power_outage_count: {icon: 'mdi:counter', enabled_by_default: false},
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'},
@@ -818,7 +819,9 @@ export default class HomeAssistant extends Extension {
temperature_calibration: {entity_category: 'config', icon: 'mdi:wrench-clock'},
temperature_max: {entity_category: 'config', icon: 'mdi:thermometer-plus'},
temperature_min: {entity_category: 'config', icon: 'mdi:thermometer-minus'},
temperature_offset: {icon: 'mdi:thermometer-lines'},
transition: {entity_category: 'config', icon: 'mdi:transition'},
trigger_count: {icon: 'mdi:counter', enabled_by_default: false},
voc: {device_class: 'volatile_organic_compounds', state_class: 'measurement'},
voc_index: {state_class: 'measurement'},
vibration_timeout: {entity_category: 'config', icon: 'mdi:timer'},
@@ -891,9 +894,6 @@ export default class HomeAssistant extends Extension {
discoveryEntry.discovery_payload.entity_category = 'diagnostic';
}
// Let Home Assistant generate entity name when device_class is present
if (discoveryEntry.discovery_payload.device_class) delete discoveryEntry.discovery_payload.name;
discoveryEntries.push(discoveryEntry);
/**
@@ -924,9 +924,6 @@ export default class HomeAssistant extends Extension {
delete discoveryEntry.discovery_payload.device_class;
}
// Let Home Assistant generate entity name when device_class is present
if (discoveryEntry.discovery_payload.device_class) delete discoveryEntry.discovery_payload.name;
if (firstExpose.value_min != null) discoveryEntry.discovery_payload.min = firstExpose.value_min;
if (firstExpose.value_max != null) discoveryEntry.discovery_payload.max = firstExpose.value_max;
@@ -946,6 +943,7 @@ export default class HomeAssistant extends Extension {
effect: {enabled_by_default: false, icon: 'mdi:palette'},
force: {entity_category: 'config', icon: 'mdi:valve'},
keep_time: {entity_category: 'config', icon: 'mdi:av-timer'},
identify: {device_class: 'identify'},
keypad_lockout: {entity_category: 'config', icon: 'mdi:lock'},
load_detection_mode: {entity_category: 'config', icon: 'mdi:tune'},
load_dimmable: {entity_category: 'config', icon: 'mdi:chart-bell-curve'},
@@ -960,6 +958,7 @@ export default class HomeAssistant extends Extension {
power_outage_memory: {entity_category: 'config', icon: 'mdi:power-settings'},
power_supply_mode: {entity_category: 'config', icon: 'mdi:power-settings'},
power_type: {entity_category: 'config', icon: 'mdi:lightning-bolt-circle'},
restart: {device_class: 'restart'},
sensitivity: {entity_category: 'config', icon: 'mdi:tune'},
sensor: {icon: 'mdi:tune'},
sensors_type: {entity_category: 'config', icon: 'mdi:tune'},
@@ -969,6 +968,7 @@ export default class HomeAssistant extends Extension {
temperature_display_mode: {entity_category: 'config', icon: 'mdi:thermometer'},
temperature_sensor_select: {entity_category: 'config', icon: 'mdi:home-thermometer'},
thermostat_unit: {entity_category: 'config', icon: 'mdi:thermometer'},
update: {device_class: 'update'},
volume: {entity_category: 'config', icon: 'mdi: volume-high'},
week: {entity_category: 'config', icon: 'mdi:calendar-clock'},
};
@@ -1008,6 +1008,29 @@ export default class HomeAssistant extends Extension {
command_topic: true,
command_topic_postfix: firstExpose.property,
options: firstExpose.values.map((v) => v.toString()),
enabled_by_default: firstExpose.values.length !== 1, // hide if button is exposed
...lookup[firstExpose.name],
},
});
}
/**
* If enum has only item and only supports SET then expose as button entity.
* Note: select entity is hidden by default to avoid breaking changes
* for selects already existing in HA (legacy).
*/
if (firstExpose.access & ACCESS_SET && firstExpose.values.length === 1) {
discoveryEntries.push({
type: 'button',
object_id: firstExpose.property,
mockProperties: [],
discovery_payload: {
name: endpoint ? `${firstExpose.label} ${endpoint}` : firstExpose.label,
state_topic: false,
command_topic_prefix: endpoint,
command_topic: true,
command_topic_postfix: firstExpose.property,
payload_press: firstExpose.values[0].toString(),
...lookup[firstExpose.name],
},
});
@@ -1075,6 +1098,13 @@ export default class HomeAssistant extends Extension {
}
});
discoveryEntries.forEach((d) => {
// Let Home Assistant generate entity name when device_class is present
if (d.discovery_payload.device_class) {
delete d.discovery_payload.name;
}
});
return discoveryEntries;
}
+1 -1
View File
@@ -445,7 +445,7 @@ export default class BridgeLegacy extends Extension {
stringify({type: `touchlink`, message: 'reset_success', meta: {status: 'success'}}),
);
} else {
logger.warn('Failed to factory reset device through Touchlink');
logger.warning('Failed to factory reset device through Touchlink');
this.mqtt.publish(
'bridge/log',
stringify({type: `touchlink`, message: 'reset_failed', meta: {status: 'failed'}}),
+10 -5
View File
@@ -1,7 +1,6 @@
/* istanbul ignore file */
import * as settings from '../../util/settings';
import logger from '../../util/logger';
import utils from '../../util/utils';
import Extension from '../extension';
import bind from 'bind-decorator';
import Device from '../../model/device';
@@ -19,19 +18,25 @@ export default class DeviceGroupMembership extends Extension {
return null;
}
const parsed = utils.parseEntityID(match[1]);
const device = this.zigbee.resolveEntity(parsed.ID) as Device;
const parsed = this.zigbee.resolveEntityAndEndpoint(match[1]);
const device = parsed?.entity as Device;
if (!device || !(device instanceof Device)) {
logger.error(`Device '${match[1]}' does not exist`);
return;
}
const endpoint = device.endpoint(parsed.endpoint);
const endpoint = parsed.endpoint;
if (parsed.endpointID && !endpoint) {
logger.error(`Device '${parsed.ID}' does not have endpoint '${parsed.endpointID}'`);
return;
}
const response = await endpoint.command(
`genGroups`, 'getMembership', {groupcount: 0, grouplist: []}, {},
);
if (!response) {
logger.warn(`Couldn't get group membership of ${device.ieeeAddr}`);
logger.warning(`Couldn't get group membership of ${device.ieeeAddr}`);
return;
}
+4 -4
View File
@@ -39,16 +39,16 @@ export default class SoftReset extends Extension {
}
private async handleTimeout(): Promise<void> {
logger.warn('Soft reset timeout triggered');
logger.warning('Soft reset timeout triggered');
try {
await this.zigbee.reset('soft');
logger.warn('Soft reset ZNP due to timeout');
logger.warning('Soft reset ZNP due to timeout');
} catch (error) {
logger.warn('Soft reset failed, trying stop/start');
logger.warning('Soft reset failed, trying stop/start');
await this.zigbee.stop();
logger.warn('Zigbee stopped');
logger.warning('Zigbee stopped');
try {
await this.zigbee.start();
+7 -3
View File
@@ -65,6 +65,10 @@ export default class OTAUpdate extends Extension {
// remove them.
for (const device of this.zigbee.devices(false)) {
this.removeProgressAndRemainingFromState(device);
// Reset update state, e.g. when Z2M restarted during update.
if (this.state.get(device).update?.state === 'updating') {
this.state.get(device).update.state = 'available';
}
}
}
@@ -94,7 +98,7 @@ export default class OTAUpdate extends Extension {
try {
// @ts-expect-error typing guaranteed by data.type
const dataData: zhc.ota.ImageInfo = data.data;
availableResult = await data.device.definition.ota.isUpdateAvailable(data.device.zh, logger, dataData);
availableResult = await data.device.definition.ota.isUpdateAvailable(data.device.zh, dataData);
} catch (e) {
supportsOTA = false;
logger.debug(`Failed to check if update available for '${data.device.name}' (${e.message})`);
@@ -202,7 +206,7 @@ export default class OTAUpdate extends Extension {
}
try {
const availableResult = await device.definition.ota.isUpdateAvailable(device.zh, logger, null);
const availableResult = await device.definition.ota.isUpdateAvailable(device.zh, null);
const msg = `${availableResult.available ? 'Update' : 'No update'} available for '${device.name}'`;
logger.info(msg);
@@ -266,7 +270,7 @@ export default class OTAUpdate extends Extension {
};
const from_ = await this.readSoftwareBuildIDAndDateCode(device, 'immediate');
const fileVersion = await device.definition.ota.updateToLatest(device.zh, logger, onProgress);
const fileVersion = await device.definition.ota.updateToLatest(device.zh, onProgress);
logger.info(`Finished update of '${device.name}'`);
this.eventBus.emitReconfigure({device});
this.removeProgressAndRemainingFromState(device);
+26 -16
View File
@@ -10,8 +10,7 @@ import Group from '../model/group';
import Device from '../model/device';
import bind from 'bind-decorator';
const topicRegex = new RegExp(`^(.+?)(?:/(${utils.endpointNames.join('|')}|\\d+))?/(get|set)(?:/(.+))?`);
const propertyEndpointRegex = new RegExp(`^(.*?)_(${utils.endpointNames.join('|')})$`);
const topicGetSetRegex = new RegExp(`^(.+?)/(get|set)(?:/(.+))?`);
const stateValues = ['on', 'off', 'toggle', 'open', 'close', 'stop', 'lock', 'unlock'];
const sceneConverterKeys = ['scene_store', 'scene_add', 'scene_remove', 'scene_remove_all', 'scene_rename'];
@@ -40,18 +39,30 @@ export default class Publish extends Extension {
}
parseTopic(topic: string): ParsedTopic | null {
const match = topic.match(topicRegex);
if (!match) {
return null;
}
// The function supports the following topic formats (below are for 'set'. 'get' will look the same):
// - <base_topic>/device_name/set (endpoint and attribute is defined in the payload)
// - <base_topic>/device_name/set/attribute (default endpoint used)
// - <base_topic>/device_name/endpoint/set (attribute is defined in the payload)
// - <base_topic>/device_name/endpoint/set/attribute (payload is the value)
const ID = match[1].replace(`${settings.get().mqtt.base_topic}/`, '');
// If we didn't replace base_topic we received something we don't care about
if (ID === match[1] || ID.match(/bridge/)) {
return null;
}
// The first step is to get rid of base topic part
topic = topic.replace(`${settings.get().mqtt.base_topic}/`, '');
return {ID: ID, endpoint: match[2], type: match[3] as 'get' | 'set', attribute: match[4]};
// Also bridge requests are something we don't care about
if (topic.match(/bridge/)) return null;
// Make the rough split on get/set keyword.
// Before the get/set is the device name and optional endpoint name.
// After it there will be an optional attribute name.
const match = topic.match(topicGetSetRegex);
if (!match) return null;
const deviceNameAndEndpoint = match[1];
const attribute = match[3];
// Now parse the device/group name, and endpoint name
const entity = this.zigbee.resolveEntityAndEndpoint(deviceNameAndEndpoint);
return {ID: entity.ID, endpoint: entity.endpointID, type: match[2] as 'get' | 'set', attribute: attribute};
}
parseMessage(parsedTopic: ParsedTopic, data: eventdata.MQTTMessage): KeyValue | null {
@@ -185,6 +196,9 @@ export default class Publish extends Extension {
toPublish[ID] = {...toPublish[ID], ...payload};
};
const endpointNames = re instanceof Device ? re.getEndpointNames() : [];
const propertyEndpointRegex = new RegExp(`^(.*?)_(${endpointNames.join('|')})$`);
for (let [key, value] of entries) {
let endpointName = parsedTopic.endpoint;
let localTarget = target;
@@ -196,10 +210,6 @@ export default class Publish extends Extension {
endpointName = propertyEndpointMatch[2];
key = propertyEndpointMatch[1];
localTarget = re.endpoint(endpointName);
if (localTarget == null) {
logger.error(`Device '${re.name}' has no endpoint '${endpointName}'`);
continue;
}
endpointOrGroupID = localTarget.ID;
}
+1 -1
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, logger);
zhc.postProcessConvertedFromZigbeeMessage(data.device.definition, payload, options);
if (settings.get().advanced.elapsed) {
const now = Date.now();
+12 -3
View File
@@ -65,12 +65,21 @@ export default class Device {
}
endpointName(endpoint: zh.Endpoint): string {
let name = null;
let epName = null;
if (this.definition?.endpoint) {
name = Object.entries(this.definition?.endpoint(this.zh)).find((e) => e[1] == endpoint.ID)[0];
const mapping = this.definition?.endpoint(this.zh);
for (const [name, id] of Object.entries(mapping)) {
if (id == endpoint.ID) {
epName = name;
}
}
}
/* istanbul ignore next */
return name === 'default' ? null : name;
return epName === 'default' ? null : epName;
}
getEndpointNames(): string[] {
return Object.keys(this.definition?.endpoint?.(this.zh) ?? {}).filter((name) => name !== 'default');
}
isIkeaTradfri(): boolean {return this.zh.manufacturerID === 4476;}
+3 -2
View File
@@ -127,7 +127,7 @@ export default class MQTT {
{retain: true, qos: 0});
this.eventBus.removeListeners(this);
logger.info('Disconnecting from MQTT server');
this.client.end();
this.client?.end();
}
subscribe(topic: string): void {
@@ -173,6 +173,7 @@ export default class MQTT {
this.eventBus.emitMQTTMessagePublished({topic, payload, options: {...defaultOptions, ...options}});
if (!this.isConnected()) {
/* istanbul ignore else */
if (!skipLog) {
logger.error(`Not connected to MQTT server!`);
logger.error(`Cannot send message: topic: '${topic}', payload: '${payload}`);
@@ -181,7 +182,7 @@ export default class MQTT {
}
if (!skipLog) {
logger.info(`MQTT publish: topic '${topic}', payload '${payload}'`);
logger.debug(`MQTT publish: topic '${topic}', payload '${payload}'`);
}
const actualOptions: mqtt.IClientPublishOptions = {...defaultOptions, ...options};
+3 -1
View File
@@ -143,7 +143,7 @@ declare global {
serial: {
disable_led: boolean,
port?: string,
adapter?: 'deconz' | 'zstack' | 'ezsp' | 'zigate',
adapter?: 'deconz' | 'zstack' | 'ezsp' | 'zigate' | 'ember',
baudrate?: number,
rtscts?: boolean,
},
@@ -196,6 +196,8 @@ declare global {
log_file: string,
log_level: 'debug' | 'info' | 'error' | 'warn',
log_syslog: KeyValue,
log_debug_to_mqtt_frontend: boolean,
log_debug_namespace_ignore: string,
pan_id: number | 'GENERATE',
ext_pan_id: number[] | 'GENERATE',
channel: number,
+203 -199
View File
@@ -7,219 +7,223 @@ import fx from 'mkdir-recursive';
import {rimrafSync} from 'rimraf';
import assert from 'assert';
const colorizer = winston.format.colorize();
const LOG_LEVELS = ['error', 'warning', 'info', 'debug'] as const;
type LogLevel = typeof LOG_LEVELS[number];
type Z2MLogLevel = 'warn' | 'debug' | 'info' | 'error';
type WinstonLogLevel = 'warning' | 'debug' | 'info' | 'error';
class Logger {
private level: LogLevel;
private output: string[];
private directory: string;
private logger: winston.Logger;
private fileTransport: winston.transports.FileTransportInstance;
private debugNamespaceIgnoreRegex?: RegExp;
const z2mToWinstonLevel = (level: Z2MLogLevel): WinstonLogLevel => level === 'warn' ? 'warning' : level;
const winstonToZ2mLevel = (level: WinstonLogLevel): Z2MLogLevel => level === 'warning' ? 'warn' : level;
public init(): void {
// What transports to enable
this.output = settings.get().advanced.log_output;
// Directory to log to
const timestamp = moment(Date.now()).format('YYYY-MM-DD.HH-mm-ss');
this.directory = settings.get().advanced.log_directory.replace('%TIMESTAMP%', timestamp);
const logFilename = settings.get().advanced.log_file.replace('%TIMESTAMP%', timestamp);
// Determine the log level.
const settingLevel = settings.get().advanced.log_level;
// workaround for syslog<>npm level conflict
this.level = settingLevel === 'warn' ? 'warning' : settingLevel;
const levelWithCompensatedLength: {[s: string]: string} = {
'info': 'info ',
'error': 'error',
'warn': 'warn ',
'debug': 'debug',
};
assert(
LOG_LEVELS.includes(this.level),
`'${this.level}' is not valid log_level, use one of '${LOG_LEVELS.join(', ')}'`,
);
let logger: winston.Logger;
let fileTransport : winston.transport;
let output: string[];
let directory: string;
let logFilename: string;
let transportsToUse: winston.transport[];
const timestampFormat = (): string => moment().format(settings.get().advanced.timestamp_format);
function init(): void {
// What transports to enable
output = settings.get().advanced.log_output;
// Directory to log to
const timestamp = moment(Date.now()).format('YYYY-MM-DD.HH-mm-ss');
directory = settings.get().advanced.log_directory.replace('%TIMESTAMP%', timestamp);
logFilename = settings.get().advanced.log_file.replace('%TIMESTAMP%', timestamp);
// Make sure that log directory exists when not logging to stdout only
if (output.includes('file')) {
fx.mkdirSync(directory);
if (settings.get().advanced.log_symlink_current) {
const current = settings.get().advanced.log_directory.replace('%TIMESTAMP%', 'current');
const actual = './' + timestamp;
/* istanbul ignore next */
if (fs.existsSync(current)) {
fs.unlinkSync(current);
}
fs.symlinkSync(actual, current);
}
}
// Determine the log level.
const z2mLevel = settings.get().advanced.log_level;
const validLevels = ['info', 'error', 'warn', 'debug'];
assert(validLevels.includes(z2mLevel),
`'${z2mLevel}' is not valid log_level, use one of '${validLevels.join(', ')}'`);
const level = z2mToWinstonLevel(z2mLevel);
const timestampFormat = (): string => moment().format(settings.get().advanced.timestamp_format);
// Setup default console logger
transportsToUse = [
new winston.transports.Console({
level,
silent: !output.includes('console'),
this.logger = winston.createLogger({
level: this.level,
format: winston.format.combine(
winston.format.errors({stack: true}),
winston.format.timestamp({format: timestampFormat}),
winston.format.printf(/* istanbul ignore next */(info) => {
const {timestamp, level, message} = info;
const l = winstonToZ2mLevel(level as WinstonLogLevel);
),
levels: winston.config.syslog.levels,
});
const plainPrefix = `Zigbee2MQTT:${levelWithCompensatedLength[l]}`;
let prefix = plainPrefix;
if (process.stdout.isTTY) {
prefix = colorizer.colorize(l, plainPrefix);
}
return `${prefix} ${timestamp.split('.')[0]}: ${message}`;
const consoleSilenced = !this.output.includes('console');
// Print to user what logging is active
let logging = `Logging to console${consoleSilenced ? ' (silenced)' : ''}`;
// Setup default console logger
this.logger.add(new winston.transports.Console({
silent: consoleSilenced,
// winston.config.syslog.levels sets 'warning' as 'red'
format: winston.format.combine(
winston.format.colorize({colors: {debug: 'blue', info: 'green', warning: 'yellow', error: 'red'}}),
winston.format.printf(/* istanbul ignore next */(info) => {
return `[${info.timestamp}] ${info.level}: \t${info.namespace}: ${info.message}`;
}),
),
}),
];
}));
// Add file logger when enabled
// NOTE: the initiation of the logger, even when not added as transport tries to create the logging directory
const transportFileOptions: KeyValue = {
filename: path.join(directory, logFilename),
json: false,
level,
format: winston.format.combine(
winston.format.timestamp({format: timestampFormat}),
winston.format.printf(/* istanbul ignore next */(info) => {
const {timestamp, level, message} = info;
const l = winstonToZ2mLevel(level as WinstonLogLevel);
return `${levelWithCompensatedLength[l]} ${timestamp.split('.')[0]}: ${message}`;
}),
),
};
if (this.output.includes('file')) {
logging += `, file (filename: ${logFilename})`;
if (settings.get().advanced.log_rotation) {
transportFileOptions.tailable = true;
transportFileOptions.maxFiles = 3; // Keep last 3 files
transportFileOptions.maxsize = 10000000; // 10MB
}
// Make sure that log directory exists when not logging to stdout only
fx.mkdirSync(this.directory);
if (output.includes('file')) {
fileTransport = new winston.transports.File(transportFileOptions);
transportsToUse.push(fileTransport);
}
/* istanbul ignore next */
if (output.includes('syslog')) {
// eslint-disable-next-line
require('winston-syslog').Syslog;
const options: KeyValue = {
app_name: 'Zigbee2MQTT',
format: winston.format.printf(/* istanbul ignore next */(info) => {
return `${info.message}`;
}),
...settings.get().advanced.log_syslog,
};
if (options.hasOwnProperty('type')) options.type = options.type.toString();
// @ts-ignore
transportsToUse.push(new winston.transports.Syslog(options));
}
logger = winston.createLogger({transports: transportsToUse, levels: winston.config.syslog.levels});
}
// Cleanup any old log directory.
function cleanup(): void {
if (settings.get().advanced.log_directory.includes('%TIMESTAMP%')) {
const rootDirectory = path.join(directory, '..');
let directories = fs.readdirSync(rootDirectory).map((d) => {
d = path.join(rootDirectory, d);
return {path: d, birth: fs.statSync(d).mtime};
});
directories.sort((a: KeyValue, b: KeyValue) => b.birth - a.birth);
directories = directories.slice(10, directories.length);
directories.forEach((dir) => {
logger.debug(`Removing old log directory '${dir.path}'`);
rimrafSync(dir.path);
});
}
}
// Print to user what logging is enabled
function logOutput(): void {
if (output.includes('file')) {
if (output.includes('console')) {
logger.info(`Logging to console and directory: '${directory}' filename: ${logFilename}`);
} else {
logger.info(`Logging to directory: '${directory}' filename: ${logFilename}`);
}
cleanup();
} else if (output.includes('console')) {
logger.info(`Logging to console only'`);
}
}
function addTransport(transport: winston.transport): void {
transport.level = transportsToUse[0].level;
logger.add(transport);
}
function getLevel(): Z2MLogLevel {
return winstonToZ2mLevel(transportsToUse[0].level as WinstonLogLevel);
}
function setLevel(level: Z2MLogLevel): void {
logger.transports.forEach((transport) => transport.level = z2mToWinstonLevel(level as Z2MLogLevel));
}
function warn(message: string): void {
// winston.config.syslog.levels doesn't have warn, but is required for syslog.
logger.warning(message);
}
function warning(message: string): void {
logger.warning(message);
}
function info(message: string): void {
logger.info(message);
}
function debug(message: string): void {
logger.debug(message);
}
function error(message: string): void {
logger.error(message);
}
// Workaround for https://github.com/winstonjs/winston/issues/1629.
// https://github.com/Koenkk/zigbee2mqtt/pull/10905
/* istanbul ignore next */
async function end(): Promise<void> {
logger.end();
await new Promise<void>((resolve) => {
if (!fileTransport) {
process.nextTick(resolve);
} else {
// @ts-ignore
if (fileTransport._dest) {
// @ts-ignore
fileTransport._dest.on('finish', resolve);
} else {
// @ts-ignore
fileTransport.on('open', () => fileTransport._dest.on('finish', resolve));
if (settings.get().advanced.log_symlink_current) {
const current = settings.get().advanced.log_directory.replace('%TIMESTAMP%', 'current');
const actual = './' + timestamp;
/* istanbul ignore next */
if (fs.existsSync(current)) {
fs.unlinkSync(current);
}
fs.symlinkSync(actual, current);
}
// Add file logger when enabled
// eslint-disable-next-line max-len
// NOTE: the initiation of the logger even when not added as transport tries to create the logging directory
const transportFileOptions: KeyValue = {
filename: path.join(this.directory, logFilename),
json: false,
format: winston.format.printf(/* istanbul ignore next */(info) => {
return `[${info.timestamp}] ${info.level}: \t${info.namespace}: ${info.message}`;
}),
};
if (settings.get().advanced.log_rotation) {
transportFileOptions.tailable = true;
transportFileOptions.maxFiles = 3; // Keep last 3 files
transportFileOptions.maxsize = 10000000; // 10MB
}
this.fileTransport = new winston.transports.File(transportFileOptions);
this.logger.add(this.fileTransport);
}
});
/* istanbul ignore next */
if (this.output.includes('syslog')) {
logging += `, syslog`;
// eslint-disable-next-line
require('winston-syslog').Syslog;
const options: KeyValue = {
app_name: 'Zigbee2MQTT',
format: winston.format.printf(/* istanbul ignore next */(info) => {
return `${info.namespace}: ${info.message}`;
}),
...settings.get().advanced.log_syslog,
};
if (options.hasOwnProperty('type')) {
options.type = options.type.toString();
}
// @ts-expect-error untyped transport
this.logger.add(new winston.transports.Syslog(options));
}
this.setDebugNamespaceIgnore(settings.get().advanced.log_debug_namespace_ignore);
this.info(logging);
}
get winston(): winston.Logger {
return this.logger;
}
public addTransport(transport: winston.transport): void {
transport.level = this.level;
this.logger.add(transport);
}
public removeTransport(transport: winston.transport): void {
this.logger.remove(transport);
}
public getDebugNamespaceIgnore(): string {
return this.debugNamespaceIgnoreRegex?.toString().slice(1, -1)/* remove slashes */ ?? '';
}
public setDebugNamespaceIgnore(value: string): void {
this.debugNamespaceIgnoreRegex = value != '' ? new RegExp(value) : undefined;
}
// TODO refactor Z2M level to 'warning' to simplify logic
public getLevel(): LogLevel | 'warn' {
return this.level === 'warning' ? 'warn' : this.level;
}
public setLevel(level: LogLevel | 'warn'): void {
if (level === 'warn') {
level = 'warning';
}
this.level = level;
this.logger.transports.forEach((transport) => transport.level = this.level);
}
public warning(message: string, namespace: string = 'z2m'): void {
this.logger.warning(message, {namespace});
}
public info(message: string, namespace: string = 'z2m'): void {
this.logger.info(message, {namespace});
}
public debug(message: string, namespace: string = 'z2m'): void {
if (this.level !== 'debug') {
return;
}
if (this.debugNamespaceIgnoreRegex?.test(namespace)) {
return;
}
this.logger.debug(message, {namespace});
}
public error(message: string, namespace: string = 'z2m'): void {
this.logger.error(message, {namespace});
}
// Cleanup any old log directory.
public cleanup(): void {
if (settings.get().advanced.log_directory.includes('%TIMESTAMP%')) {
const rootDirectory = path.join(this.directory, '..');
let directories = fs.readdirSync(rootDirectory).map((d) => {
d = path.join(rootDirectory, d);
return {path: d, birth: fs.statSync(d).mtime};
});
directories.sort((a: KeyValue, b: KeyValue) => b.birth - a.birth);
directories = directories.slice(10, directories.length);
directories.forEach((dir) => {
this.debug(`Removing old log directory '${dir.path}'`);
rimrafSync(dir.path);
});
}
}
// Workaround for https://github.com/winstonjs/winston/issues/1629.
// https://github.com/Koenkk/zigbee2mqtt/pull/10905
/* istanbul ignore next */
public async end(): Promise<void> {
this.logger.end();
await new Promise<void>((resolve) => {
if (!this.fileTransport) {
process.nextTick(resolve);
} else {
// @ts-expect-error workaround
if (this.fileTransport._dest) {
// @ts-expect-error workaround
this.fileTransport._dest.on('finish', resolve);
} else {
// @ts-expect-error workaround
this.fileTransport.on('open', () => this.fileTransport._dest.on('finish', resolve));
}
}
});
}
}
export default {
init, logOutput, warn, warning, error, info, debug, setLevel, getLevel, cleanup, addTransport, end,
winston: (): winston.Logger => logger,
};
export default new Logger();
+18 -1
View File
@@ -227,7 +227,7 @@
},
"adapter": {
"type": ["string"],
"enum": ["deconz", "zstack", "zigate", "ezsp", "auto"],
"enum": ["deconz", "zstack", "zigate", "ezsp", "auto", "ember"],
"title": "Adapter",
"default": "auto",
"requiresRestart": true,
@@ -497,6 +497,23 @@
"description": "Logging level",
"default": "info"
},
"log_debug_to_mqtt_frontend": {
"type": "boolean",
"title": "Log debug to MQTT and frontend",
"description": "Log debug level to MQTT and frontend (may decrease overall performance)",
"requiresRestart": true,
"default": false
},
"log_debug_namespace_ignore": {
"type": "string",
"title": "Log debug namespace ignore",
"description": "Do not log these namespaces (regex-based) for debug level",
"default": "",
"examples": [
"^zhc:legacy:fz:(tuya|moes)",
"^zhc:legacy:fz:(tuya|moes)|^zh:ember:uart:|^zh:controller"
]
},
"log_syslog": {
"type": "object",
"title": "syslog",
+4 -2
View File
@@ -80,9 +80,11 @@ const defaults: RecursivePartial<Settings> = {
log_symlink_current: false,
log_output: ['console', 'file'],
log_directory: path.join(data.getPath(), 'log', '%TIMESTAMP%'),
log_file: 'log.txt',
log_file: 'log.log',
log_level: /* istanbul ignore next */ process.env.DEBUG ? 'debug' : 'info',
log_syslog: {},
log_debug_to_mqtt_frontend: false,
log_debug_namespace_ignore: '',
pan_id: 0x1a62,
ext_pan_id: [0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD],
channel: 11,
@@ -593,7 +595,7 @@ export function removeDevice(IDorName: string): void {
// Remove device from groups
if (settings.groups) {
const regex =
new RegExp(`^(${device.friendly_name}|${device.ID})(/(\\d|${utils.endpointNames.join('|')}))?$`);
new RegExp(`^(${device.friendly_name}|${device.ID})(/[^/]+)?$`);
for (const group of Object.values(settings.groups).filter((g) => g.devices)) {
group.devices = group.devices.filter((device) => !device.match(regex));
}
+2 -30
View File
@@ -30,22 +30,6 @@ function toLocalISOString(date: Date): string {
':' + pad(tzOffset % 60);
}
const endpointNames = [
'left', 'right', 'center', 'bottom_left', 'bottom_right', 'default',
'top_left', 'top_right', 'white', 'rgb', 'cct', 'system', 'top', 'bottom', 'center_left', 'center_right',
'ep1', 'ep2', 'row_1', 'row_2', 'row_3', 'row_4', 'relay', 'usb',
'l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8',
'l9', 'l10', 'l11', 'l12', 'l13', 'l14', 'l15', 'l16',
'l17', 'l18', 'l19', 'l20', 'l21', 'l22', 'l23', 'l24',
'th1', 'th2', 'th3', 'th4', 'th5', 'th6', 'th7', 'th8', 'th9', 'th10',
'button_1', 'button_2', 'button_3', 'button_4', 'button_5',
'button_6', 'button_7', 'button_8', 'button_9', 'button_10',
'button_11', 'button_12', 'button_13', 'button_14', 'button_15',
'button_16', 'button_17', 'button_18', 'button_19', 'button_20',
'button_light', 'button_fan_high', 'button_fan_med', 'button_fan_low',
'heat', 'cool', 'water', 'meter', 'wifi', 'no_occupancy_since',
];
function capitalize(s: string): string {
return s[0].toUpperCase() + s.slice(1);
}
@@ -252,16 +236,10 @@ function getAllFiles(path_: string): string[] {
function validateFriendlyName(name: string, throwFirstError=false): string[] {
const errors = [];
for (const endpointName of endpointNames) {
if (name.toLowerCase().endsWith('/' + endpointName)) {
errors.push(`friendly_name is not allowed to end with: '/${endpointName}'`);
}
}
if (name.length === 0) errors.push(`friendly_name must be at least 1 char long`);
if (name.endsWith('/') || name.startsWith('/')) errors.push(`friendly_name is not allowed to end or start with /`);
if (containsControlCharacter(name)) errors.push(`friendly_name is not allowed to contain control char`);
if (endpointNames.includes(name)) errors.push(`Following friendly_name are not allowed: '${endpointNames}'`);
if (name.match(/.*\/\d*$/)) errors.push(`Friendly name cannot end with a "/DIGIT" ('${name}')`);
if (name.includes('#') || name.includes('+')) {
errors.push(`MQTT wildcard (+ and #) not allowed in friendly_name ('${name}')`);
@@ -309,12 +287,6 @@ function isAvailabilityEnabledForEntity(entity: Device | Group, settings: Settin
return !blocklist.includes(entity.name) && !blocklist.includes(entity.ieeeAddr);
}
const entityIDRegex = new RegExp(`^(.+?)(?:/(${endpointNames.join('|')}|\\d+))?$`);
function parseEntityID(ID: string): {ID: string, endpoint: string} {
const match = ID.match(entityIDRegex);
return match && {ID: match[1], endpoint: match[2]};
}
function isEndpoint(obj: unknown): obj is zh.Endpoint {
return obj.constructor.name.toLowerCase() === 'endpoint';
}
@@ -433,10 +405,10 @@ function getScenes(entity: zh.Endpoint | zh.Group): Scene[] {
}
export default {
endpointNames, capitalize, getZigbee2MQTTVersion, getDependencyVersion, formatDate, objectHasProperties,
capitalize, getZigbee2MQTTVersion, getDependencyVersion, formatDate, objectHasProperties,
equalsPartial, getObjectProperty, getResponse, parseJSON, loadModuleFromText, loadModuleFromFile,
removeNullPropertiesFromObject, toNetworkAddressHex, toSnakeCase,
parseEntityID, isEndpoint, isZHGroup, hours, minutes, seconds, validateFriendlyName, sleep,
isEndpoint, isZHGroup, hours, minutes, seconds, validateFriendlyName, sleep,
sanitizeImageParameter, isAvailabilityEnabledForEntity, publishLastSeen, availabilityPayload,
getAllFiles, filterProperties, flatten, arrayUnique, clone, computeSettingsToChange, getScenes,
};
+41 -7
View File
@@ -11,6 +11,8 @@ import * as ZHEvents from 'zigbee-herdsman/dist/controller/events';
import bind from 'bind-decorator';
import {randomInt} from 'crypto';
const entityIDRegex = new RegExp(`^(.+?)(?:/([^/]+))?$`);
export default class Zigbee {
private herdsman: Controller;
private eventBus: EventBus;
@@ -56,7 +58,7 @@ export default class Zigbee {
let startResult;
try {
this.herdsman = new Controller(herdsmanSettings, logger);
this.herdsman = new Controller(herdsmanSettings);
startResult = await this.herdsman.start();
} catch (error) {
logger.error(`Error while starting zigbee-herdsman`);
@@ -86,22 +88,22 @@ export default class Zigbee {
});
this.herdsman.on('deviceInterview', async (data: ZHEvents.DeviceInterviewPayload) => {
const device = this.resolveDevice(data.device.ieeeAddr);
await device.resolveDefinition();
/* istanbul ignore if */ if (!device) return; // Prevent potential race
await device.resolveDefinition();
const d = {device, status: data.status};
this.logDeviceInterview(d);
this.eventBus.emitDeviceInterview(d);
});
this.herdsman.on('deviceJoined', async (data: ZHEvents.DeviceJoinedPayload) => {
const device = this.resolveDevice(data.device.ieeeAddr);
await device.resolveDefinition();
/* istanbul ignore if */ if (!device) return; // Prevent potential race
await device.resolveDefinition();
logger.info(`Device '${device.name}' joined`);
this.eventBus.emitDeviceJoined({device});
});
this.herdsman.on('deviceLeave', (data: ZHEvents.DeviceLeavePayload) => {
const name = settings.getDevice(data.ieeeAddr)?.friendly_name || data.ieeeAddr;
logger.warn(`Device '${name}' left the network`);
logger.warning(`Device '${name}' left the network`);
this.eventBus.emitDeviceLeave({ieeeAddr: data.ieeeAddr, name});
});
this.herdsman.on('message', async (data: ZHEvents.MessagePayload) => {
@@ -132,11 +134,11 @@ export default class Zigbee {
};
if (passlist.length > 0) {
if (!passlist.includes(device.ieeeAddr)) {
logger.warn(`Device which is not on passlist connected (${device.ieeeAddr}), removing...`);
logger.warning(`Device which is not on passlist connected (${device.ieeeAddr}), removing...`);
await remove(device);
}
} else if (blocklist.includes(device.ieeeAddr)) {
logger.warn(`Device on blocklist is connected (${device.ieeeAddr}), removing...`);
logger.warning(`Device on blocklist is connected (${device.ieeeAddr}), removing...`);
await remove(device);
}
}
@@ -160,7 +162,7 @@ export default class Zigbee {
const {vendor, description, model} = data.device.definition;
logger.info(`Device '${name}' is supported, identified as: ${vendor} ${description} (${model})`);
} else {
logger.warn(`Device '${name}' with Zigbee model '${data.device.zh.modelID}' and manufacturer name ` +
logger.warning(`Device '${name}' with Zigbee model '${data.device.zh.modelID}' and manufacturer name ` +
`'${data.device.zh.manufacturerName}' is NOT supported, ` +
// eslint-disable-next-line max-len
`please follow https://www.zigbee2mqtt.io/advanced/support-new-devices/01_support_new_devices.html`);
@@ -283,6 +285,38 @@ export default class Zigbee {
}
}
resolveEntityAndEndpoint(ID: string)
: {ID: string, entity: Device | Group, endpointID: string, endpoint: zh.Endpoint} {
// This function matches the following entity formats:
// device_name (just device name)
// device_name/ep_name (device name and endpoint numeric ID or name)
// device/name (device name with slashes)
// device/name/ep_name (device name with slashes, and endpoint numeric ID or name)
// The function tries to find an exact match first
let entityName = ID;
let deviceOrGroup = this.resolveEntity(ID);
let endpointNameOrID = undefined;
// If exact match did not happenc, try matching a device_name/endpoint pattern
if (!deviceOrGroup) {
// First split the input token by the latest slash
const match = ID.match(entityIDRegex);
// Get the resulting IDs from the match
entityName = match[1];
deviceOrGroup = this.resolveEntity(match[1]);
endpointNameOrID = match[2];
}
// If the function returns non-null endpoint name, but the endpoint field is null, then
// it means that endpoint was not matched because there is no such endpoint on the device
// (or the entity is a group)
const endpoint = deviceOrGroup?.isDevice() ? deviceOrGroup.endpoint(endpointNameOrID) : null;
return {ID: entityName, entity: deviceOrGroup, endpointID: endpointNameOrID, endpoint: endpoint};
}
firstCoordinatorEndpoint(): zh.Endpoint {
return this.herdsman.getDevicesByType('Coordinator')[0].endpoints[0];
}
+784 -937
View File
File diff suppressed because it is too large Load Diff
+25 -25
View File
@@ -1,6 +1,6 @@
{
"name": "zigbee2mqtt",
"version": "1.35.3",
"version": "1.37.1",
"description": "Zigbee to MQTT bridge using Zigbee-herdsman",
"main": "index.js",
"repository": {
@@ -24,9 +24,9 @@
"build-watch": "tsc --watch",
"eslint": "eslint lib/ --max-warnings=0",
"start": "node index.js",
"test-with-coverage": "jest test --coverage",
"test": "jest test",
"test-watch": "jest test --watch"
"test-with-coverage": "jest test --silent --maxWorkers=50% --coverage",
"test": "jest test --silent --maxWorkers=50%",
"test-watch": "jest test --silent --maxWorkers=25% --watch"
},
"author": "Koen Kanters",
"license": "GPL-3.0",
@@ -35,7 +35,7 @@
},
"homepage": "https://koenkk.github.io/zigbee2mqtt",
"dependencies": {
"ajv": "^8.12.0",
"ajv": "^8.13.0",
"bind-decorator": "^1.0.11",
"connect-gzip-static": "3.0.1",
"debounce": "^2.0.0",
@@ -43,49 +43,49 @@
"fast-deep-equal": "^3.1.3",
"finalhandler": "^1.2.0",
"git-last-commit": "^1.0.1",
"humanize-duration": "^3.31.0",
"humanize-duration": "^3.32.0",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"jszip": "^3.10.1",
"mkdir-recursive": "^0.4.0",
"moment": "^2.30.1",
"mqtt": "^5.3.5",
"mqtt": "^5.5.0",
"object-assign-deep": "^0.4.0",
"rimraf": "^5.0.5",
"semver": "^7.5.4",
"semver": "^7.6.0",
"source-map-support": "^0.5.21",
"uri-js": "^4.4.1",
"winston": "^3.11.0",
"winston": "^3.13.0",
"winston-syslog": "^2.7.0",
"winston-transport": "^4.7.0",
"ws": "^8.16.0",
"zigbee-herdsman": "0.33.8",
"zigbee-herdsman-converters": "18.28.3",
"zigbee2mqtt-frontend": "0.6.156"
"ws": "^8.17.0",
"zigbee-herdsman": "0.46.6",
"zigbee-herdsman-converters": "19.37.2",
"zigbee2mqtt-frontend": "0.6.167"
},
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/plugin-proposal-decorators": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"@babel/preset-typescript": "^7.23.3",
"@babel/core": "^7.24.5",
"@babel/plugin-proposal-decorators": "^7.24.1",
"@babel/preset-env": "^7.24.5",
"@babel/preset-typescript": "^7.24.1",
"@types/debounce": "^1.2.4",
"@types/finalhandler": "^1.2.3",
"@types/humanize-duration": "^3.27.4",
"@types/jest": "^29.5.12",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.11.16",
"@types/node": "^20.12.8",
"@types/object-assign-deep": "^0.4.3",
"@types/readable-stream": "4.0.10",
"@types/readable-stream": "4.0.12",
"@types/ws": "8.5.10",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"babel-jest": "^29.7.0",
"eslint": "^8.56.0",
"eslint": "^8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-jest": "^28.5.0",
"jest": "^29.7.0",
"tmp": "^0.2.1",
"typescript": "^5.3.3"
"tmp": "^0.2.3",
"typescript": "^5.4.5"
},
"overrides": {
"zigbee-herdsman-converters": {
+14
View File
@@ -5,7 +5,21 @@
"include-component-in-tag": false,
"include-v-in-tag": false,
"draft": true
},
"charts/zigbee2mqtt": {
"release-type": "helm",
"include-component-in-tag": false,
"include-v-in-tag": false,
"draft": true,
"extra-files": [
{
"type": "yaml",
"path": "charts/zigbee2mqtt",
"jsonpath": "$.appVersion"
}
]
}
},
"pull-request-title-pattern": "chore${scope}: release ${version}",
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
}
+1 -1
View File
@@ -10,7 +10,7 @@ import Availability from '../lib/extension/availability';
import flushPromises from './lib/flushPromises';
import stringify from 'json-stable-stringify-without-jsonify';
const mocks = [MQTT.publish, logger.warn, logger.debug];
const mocks = [MQTT.publish, logger.warning, logger.debug];
const devices = zigbeeHerdsman.devices;
zigbeeHerdsman.returnDevices.push(
...[devices.bulb_color.ieeeAddr, devices.bulb_color_2.ieeeAddr, devices.coordinator.ieeeAddr, devices.remote.ieeeAddr])
+31 -3
View File
@@ -157,7 +157,7 @@ describe('Bind', () => {
expect(target.configureReporting).toHaveBeenCalledWith("genOnOff",[{"attribute": "onOff", "maximumReportInterval": 0xFFFF, "minimumReportInterval": 0, "reportableChange": 0}]);
expect(target.configureReporting).toHaveBeenCalledWith("genLevelCtrl",[{"attribute": "currentLevel", "maximumReportInterval": 0xFFFF, "minimumReportInterval": 5, "reportableChange": 1}]);
expect(target.configureReporting).toHaveBeenCalledWith("lightingColorCtrl",[{"attribute":"colorTemperature","minimumReportInterval":5,"maximumReportInterval":0xFFFF,"reportableChange":1},{"attribute":"currentX","minimumReportInterval":5,"maximumReportInterval":0xFFFF,"reportableChange":1},{"attribute":"currentY","minimumReportInterval":5,"maximumReportInterval":0xFFFF,"reportableChange":1}]);
expect(zigbeeHerdsman.devices.bulb_color.meta.configured).toBe(1324213189);
expect(zigbeeHerdsman.devices.bulb_color.meta.configured).toBe(332242049);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bridge/response/device/unbind',
stringify({"data":{"from":"remote","to":"bulb_color","clusters":["genScenes","genOnOff","genLevelCtrl"],"failed":[]},"status":"ok"}),
@@ -387,7 +387,7 @@ describe('Bind', () => {
);
});
it('Error bind fails when source not existing', async () => {
it('Error bind fails when source device does not exist', async () => {
const device = zigbeeHerdsman.devices.remote;
const target = zigbeeHerdsman.devices.bulb_color.getEndpoint(1);
const endpoint = device.getEndpoint(1);
@@ -401,7 +401,21 @@ describe('Bind', () => {
);
});
it('Error bind fails when target not existing', async () => {
it("Error bind fails when source device's endpoint does not exist", async () => {
const device = zigbeeHerdsman.devices.remote;
const target = zigbeeHerdsman.devices.bulb_color.getEndpoint(1);
const endpoint = device.getEndpoint(1);
mockClear(device);
MQTT.events.message('zigbee2mqtt/bridge/request/device/bind', stringify({from: 'remote/not_existing_endpoint', to: 'bulb_color'}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bridge/response/device/bind',
stringify({"data":{"from":"remote/not_existing_endpoint","to":"bulb_color"},"status":"error","error":"Source device 'remote' does not have endpoint 'not_existing_endpoint'"}),
{retain: false, qos: 0}, expect.any(Function)
);
});
it('Error bind fails when target device or group does not exist', async () => {
const device = zigbeeHerdsman.devices.remote;
const target = zigbeeHerdsman.devices.bulb_color.getEndpoint(1);
const endpoint = device.getEndpoint(1);
@@ -415,6 +429,20 @@ describe('Bind', () => {
);
});
it("Error bind fails when target device's endpoint does not exist", async () => {
const device = zigbeeHerdsman.devices.remote;
const target = zigbeeHerdsman.devices.bulb_color.getEndpoint(1);
const endpoint = device.getEndpoint(1);
mockClear(device);
MQTT.events.message('zigbee2mqtt/bridge/request/device/bind', stringify({from: 'remote', to: 'bulb_color/not_existing_endpoint'}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bridge/response/device/bind',
stringify({"data":{"from":"remote","to":"bulb_color/not_existing_endpoint"},"status":"error","error":"Target device 'bulb_color' does not have endpoint 'not_existing_endpoint'"}),
{retain: false, qos: 0}, expect.any(Function)
);
});
it('Legacy api: Should bind', async () => {
const device = zigbeeHerdsman.devices.remote;
const target = zigbeeHerdsman.devices.bulb_color.getEndpoint(1);
+103 -12
View File
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -8,7 +8,7 @@ const flushPromises = require('./lib/flushPromises');
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const stringify = require('json-stable-stringify-without-jsonify');
const mocksClear = [MQTT.publish, logger.warn, logger.debug];
const mocksClear = [MQTT.publish, logger.warning, logger.debug];
describe('Configure', () => {
let controller;
@@ -24,7 +24,7 @@ describe('Configure', () => {
const endpoint2 = device.getEndpoint(2);
expect(endpoint2.write).toHaveBeenCalledTimes(1);
expect(endpoint2.write).toHaveBeenCalledWith("genBasic", {"49": {"type": 25, "value": 11}}, {"disableDefaultResponse": true, "manufacturerCode": 4107});
expect(device.meta.configured).toBe(1);
expect(device.meta.configured).toBe(332242049);
}
const expectBulbConfigured = () => {
@@ -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: "0x0017880104e45521", transaction: 20}));
await MQTT.events.message('zigbee2mqtt/bridge/request/device/configure', stringify({id: "0x0017882104a44559", transaction: 20}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bridge/response/device/configure',
stringify({"data":{"id": "0x0017880104e45521"},"status":"error","error": "Device 'button_double_key' cannot be configured","transaction":20}),
stringify({"data":{"id": "0x0017882104a44559"},"status":"error","error": "Device 'TS0601_thermostat' 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', '0x0017880104e45521');
await MQTT.events.message('zigbee2mqtt/bridge/configure', '0x0017882104a44559');
await flushPromises();
expect(logger.warn).toHaveBeenCalledWith(`Skipping configure of 'button_double_key', device does not require this.`)
expect(logger.warning).toHaveBeenCalledWith(`Skipping configure of 'TS0601_thermostat', device does not require this.`)
});
it('Should not configure when interview not completed', async () => {
+4 -4
View File
@@ -53,13 +53,13 @@ describe('Controller', () => {
it('Start controller', async () => {
await controller.start();
expect(zigbeeHerdsman.constructor).toHaveBeenCalledWith({"network":{"panID":6754,"extendedPanID":[221,221,221,221,221,221,221,221],"channelList":[11],"networkKey":[1,3,5,7,9,11,13,15,0,2,4,6,8,10,12,13]},"databasePath":path.join(data.mockDir, "database.db"), "databaseBackupPath":path.join(data.mockDir, "database.db.backup"),"backupPath":path.join(data.mockDir, "coordinator_backup.json"),"acceptJoiningDeviceHandler": expect.any(Function),adapter: {concurrent: null, delay: null, disableLED: false}, "serialPort":{"baudRate":undefined,"rtscts":undefined,"path":"/dev/dummy"}}, logger);
expect(zigbeeHerdsman.constructor).toHaveBeenCalledWith({"network":{"panID":6754,"extendedPanID":[221,221,221,221,221,221,221,221],"channelList":[11],"networkKey":[1,3,5,7,9,11,13,15,0,2,4,6,8,10,12,13]},"databasePath":path.join(data.mockDir, "database.db"), "databaseBackupPath":path.join(data.mockDir, "database.db.backup"),"backupPath":path.join(data.mockDir, "coordinator_backup.json"),"acceptJoiningDeviceHandler": expect.any(Function),adapter: {concurrent: null, delay: null, disableLED: false}, "serialPort":{"baudRate":undefined,"rtscts":undefined,"path":"/dev/dummy"}});
expect(zigbeeHerdsman.start).toHaveBeenCalledTimes(1);
expect(zigbeeHerdsman.setTransmitPower).toHaveBeenCalledTimes(0);
expect(zigbeeHerdsman.permitJoin).toHaveBeenCalledTimes(1);
expect(zigbeeHerdsman.permitJoin).toHaveBeenCalledWith(true, undefined, undefined);
expect(logger.info).toHaveBeenCalledWith(`Currently ${Object.values(zigbeeHerdsman.devices).length - 1} devices are joined:`)
expect(logger.info).toHaveBeenCalledWith('bulb (0x000b57fffec6a5b2): LED1545G12 - IKEA TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (Router)');
expect(logger.info).toHaveBeenCalledWith('bulb (0x000b57fffec6a5b2): LED1545G12 - IKEA TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm (Router)');
expect(logger.info).toHaveBeenCalledWith('remote (0x0017880104e45517): 324131092621 - Philips Hue dimmer switch (EndDevice)');
expect(logger.info).toHaveBeenCalledWith('0x0017880104e45518 (0x0017880104e45518): Not supported (EndDevice)');
expect(MQTT.connect).toHaveBeenCalledTimes(1);
@@ -280,7 +280,7 @@ describe('Controller', () => {
logger.debug.mockClear();
await controller.mqtt.publish('skip-this-topic', '', {});
await MQTT.events.message('zigbee2mqtt/skip-this-topic', 'skipped');
expect(logger.debug).toHaveBeenCalledTimes(0);
expect(logger.debug).toHaveBeenCalledTimes(1);
});
it('On zigbee event message', async () => {
@@ -398,7 +398,7 @@ describe('Controller', () => {
const payload = {device, status: 'successful'};
await zigbeeHerdsman.events.deviceInterview(payload);
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/bridge/log', stringify({"type":"pairing","message":"interview_successful","meta":{"friendly_name":"bulb","model":"LED1545G12","vendor":"IKEA","description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","supported":true}}), { retain: false, qos: 0 }, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/bridge/log', stringify({"type":"pairing","message":"interview_successful","meta":{"friendly_name":"bulb","model":"LED1545G12","vendor":"IKEA","description":"TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm","supported":true}}), { retain: false, qos: 0 }, expect.any(Function));
});
it('On zigbee deviceInterview successful not supported', async () => {
+24 -2
View File
@@ -273,7 +273,7 @@ describe('Groups', () => {
expect(logger.error).toHaveBeenCalledWith("Group 'group_1_not_existing' does not exist");
});
it('Legacy api: Log when adding to non-existing device', async () => {
it('Legacy api: Log when adding a non-existing device', async () => {
await resetExtension();
logger.error.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/group/group_1/add', 'bulb_color_not_existing');
@@ -281,6 +281,14 @@ describe('Groups', () => {
expect(logger.error).toHaveBeenCalledWith("Device 'bulb_color_not_existing' does not exist");
});
it('Legacy api: Log when adding a non-existing endpoint', async () => {
await resetExtension();
logger.error.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/group/group_1/add', 'bulb_color/not_existing_endpoint');
await flushPromises();
expect(logger.error).toHaveBeenCalledWith("Device 'bulb_color' does not have endpoint 'not_existing_endpoint'");
});
it('Should publish group state change when a device in it changes state', async () => {
const device = zigbeeHerdsman.devices.bulb_color;
const endpoint = device.getEndpoint(1);
@@ -869,7 +877,7 @@ describe('Groups', () => {
);
});
it('Error when adding to non-existing device', async () => {
it('Error when adding a non-existing device', async () => {
await resetExtension();
logger.error.mockClear();
MQTT.publish.mockClear();
@@ -883,6 +891,20 @@ describe('Groups', () => {
);
});
it('Error when adding a non-existing endpoint', async () => {
await resetExtension();
logger.error.mockClear();
MQTT.publish.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/request/group/members/add', stringify({group: 'group_1', device: 'bulb_color/not_existing_endpoint'}));
await flushPromises();
expect(MQTT.publish).not.toHaveBeenCalledWith('zigbee2mqtt/bridge/groups', expect.any(String), expect.any(Object), expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bridge/response/group/members/add',
stringify({"data":{"device":"bulb_color/not_existing_endpoint","group":"group_1"},"status":"error","error":"Device 'bulb_color' does not have endpoint 'not_existing_endpoint'"}),
{retain: false, qos: 0}, expect.any(Function)
);
});
it('Should only include relevant properties when publishing member states', async () => {
const bulbColor = zigbeeHerdsman.devices.bulb_color;
const bulbColorTemp = zigbeeHerdsman.devices.bulb;
+8 -13
View File
@@ -83,7 +83,6 @@ describe('HomeAssistant extension', () => {
"availability":[{"topic":"zigbee2mqtt/bridge/state"}],
"brightness":true,
"brightness_scale":254,
"color_mode":true,
"command_topic":"zigbee2mqtt/ha_discovery_group/set",
"device":{
"identifiers":["zigbee2mqtt_1221051039810110150109113116116_9"],
@@ -371,7 +370,6 @@ describe('HomeAssistant extension', () => {
"availability":[{"topic":"zigbee2mqtt/bridge/state"}],
"brightness":true,
"brightness_scale":254,
"color_mode": true,
"supported_color_modes": ["color_temp"],
"min_mireds": 250,
"max_mireds": 454,
@@ -381,7 +379,7 @@ describe('HomeAssistant extension', () => {
"zigbee2mqtt_0x000b57fffec6a5b2"
],
"manufacturer":"IKEA",
"model":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (LED1545G12)",
"model":"TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm (LED1545G12)",
"name":"bulb",
"sw_version": null,
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
@@ -993,9 +991,9 @@ describe('HomeAssistant extension', () => {
it('Should warn when starting with cache_state false', async () => {
settings.set(['advanced', 'cache_state'], false);
logger.warn.mockClear();
logger.warning.mockClear();
await resetExtension();
expect(logger.warn).toHaveBeenCalledWith("In order for Home Assistant integration to work properly set `cache_state: true");
expect(logger.warning).toHaveBeenCalledWith("In order for Home Assistant integration to work properly set `cache_state: true");
});
it('Should set missing values to null', async () => {
@@ -1369,7 +1367,6 @@ describe('HomeAssistant extension', () => {
"availability":[{"topic":"zigbee2mqtt/bridge/state"}],
"brightness":true,
"brightness_scale":254,
"color_mode":true,
"command_topic":"zigbee2mqtt/ha_discovery_group_new/set",
"device":{
"identifiers":["zigbee2mqtt_1221051039810110150109113116116_9"],
@@ -1482,7 +1479,7 @@ describe('HomeAssistant extension', () => {
],
"name":"bulb",
'sw_version': null,
"model":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (LED1545G12)",
"model":"TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm (LED1545G12)",
"manufacturer":"IKEA",
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
},
@@ -1916,7 +1913,6 @@ describe('HomeAssistant extension', () => {
"availability":[{"topic":"zigbee2mqtt/bridge/state"}],
"brightness":true,
"brightness_scale":254,
"color_mode":true,
"command_topic":"zigbee2mqtt/ha_discovery_group/set",
"device":{
"identifiers":["zigbee2mqtt_1221051039810110150109113116116_9"],
@@ -1970,7 +1966,6 @@ describe('HomeAssistant extension', () => {
"availability":[{"topic":"zigbee2mqtt/bridge/state","value_template":'{{ value_json.state }}'}],
"brightness":true,
"brightness_scale":254,
"color_mode":true,
"command_topic":"zigbee2mqtt/ha_discovery_group/set",
"device":{
"identifiers":["zigbee2mqtt_1221051039810110150109113116116_9"],
@@ -2030,14 +2025,13 @@ describe('HomeAssistant extension', () => {
],
"brightness":true,
"brightness_scale":254,
"color_mode":true,
"command_topic":"zigbee2mqtt/bulb/set",
"device":{
"identifiers":[
"zigbee2mqtt_0x000b57fffec6a5b2"
],
"manufacturer":"IKEA",
"model":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (LED1545G12)",
"model":"TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm (LED1545G12)",
"name":"bulb",
"sw_version":null,
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
@@ -2088,7 +2082,7 @@ describe('HomeAssistant extension', () => {
"zigbee2mqtt_0x000b57fffec6a5b2"
],
"manufacturer":"IKEA",
"model":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (LED1545G12)",
"model":"TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm (LED1545G12)",
"name":"bulb",
"sw_version": null,
"via_device": "zigbee2mqtt_bridge_0x00124b00120144ae",
@@ -2530,7 +2524,8 @@ describe('HomeAssistant extension', () => {
'origin': origin,
'state_topic':'zigbee2mqtt/0x18fc26000000cafe',
'unique_id':'0x18fc26000000cafe_device_mode_zigbee2mqtt',
'value_template':'{{ value_json.device_mode }}'
'value_template':'{{ value_json.device_mode }}',
'enabled_by_default': true,
}
expect(MQTT.publish).toHaveBeenCalledWith(
"homeassistant/select/0x18fc26000000cafe/device_mode/config",
+3 -3
View File
@@ -25,7 +25,7 @@ describe('Bridge legacy', () => {
data.writeDefaultConfiguration();
settings.reRead();
logger.info.mockClear();
logger.warn.mockClear();
logger.warning.mockClear();
});
afterAll(async () => {
@@ -183,7 +183,7 @@ describe('Bridge legacy', () => {
const payload = JSON.parse(MQTT.publish.mock.calls[0][1]);
expect(payload.length).toStrictEqual(Object.values(zigbeeHerdsman.devices).length);
expect(payload[1]).toStrictEqual({"ieeeAddr": "0x00124b00120144ae", "type": "Coordinator", "dateCode": "20190425", "friendly_name": "Coordinator", networkAddress: 0, softwareBuildID: "z-Stack", lastSeen: 100});
expect(payload[2]).toStrictEqual({"dateCode": null, "friendly_name": "bulb", "ieeeAddr": "0x000b57fffec6a5b2", "lastSeen": 1000, "manufacturerID": 4476, "model": "LED1545G12", "modelID": "TRADFRI bulb E27 WS opal 980lm", "networkAddress": 40369, "powerSource": "Mains (single phase)", "softwareBuildID": null, "type": "Router", "description": "TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white", "vendor": "IKEA"});
expect(payload[2]).toStrictEqual({"dateCode": null, "friendly_name": "bulb", "ieeeAddr": "0x000b57fffec6a5b2", "lastSeen": 1000, "manufacturerID": 4476, "model": "LED1545G12", "modelID": "TRADFRI bulb E27 WS opal 980lm", "networkAddress": 40369, "powerSource": "Mains (single phase)", "softwareBuildID": null, "type": "Router", "description": "TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm", "vendor": "IKEA"});
Date.now = now;
});
@@ -478,6 +478,6 @@ describe('Bridge legacy', () => {
MQTT.events.message('zigbee2mqtt/bridge/config/touchlink/factory_reset', '');
await flushPromises();
expect(zigbeeHerdsman.touchlinkFactoryResetFirst).toHaveBeenCalledTimes(1);
expect(logger.warn).toHaveBeenCalledWith('Failed to factory reset device through Touchlink');
expect(logger.warning).toHaveBeenCalledWith('Failed to factory reset device through Touchlink');
});
});
+1 -1
View File
@@ -16,7 +16,7 @@ const Controller = require('../../lib/controller');
const flushPromises = require('../lib/flushPromises');
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const mocksClear = [MQTT.publish, logger.warn, logger.debug];
const mocksClear = [MQTT.publish, logger.warning, logger.debug];
describe('Report', () => {
let controller;
+114 -63
View File
@@ -9,6 +9,8 @@ const {rimrafSync} = require('rimraf');
const Transport = require('winston-transport');
describe('Logger', () => {
let logger;
beforeEach(async () => {
data.writeDefaultConfiguration();
jest.resetModules();
@@ -17,6 +19,8 @@ describe('Logger', () => {
settings.reRead();
stdOutWriteOriginal = console._stdout.write;
console._stdout.write = () => {};
logger = require('../lib/util/logger').default;
logger.init();
});
afterEach(async () => {
@@ -24,18 +28,11 @@ describe('Logger', () => {
});
it('Create log directory', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const dirs = fs.readdirSync(dir.name);
expect(dirs.length).toBe(1);
});
it('Should cleanup', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
for (const d of fs.readdirSync(dir.name)) {
rimrafSync(path.join(dir.name, d));
}
@@ -50,54 +47,54 @@ describe('Logger', () => {
})
it('Should not cleanup when there is no timestamp set', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
for (let i = 30; i < 40; i++) {
fs.mkdirSync(path.join(dir.name, `log_${i}`));
}
settings.set(['advanced', 'log_directory'], dir.name + '/bla');
expect(fs.readdirSync(dir.name).length).toBe(20);
expect(fs.readdirSync(dir.name).length).toBe(21);
logger.cleanup();
expect(fs.readdirSync(dir.name).length).toBe(20);
expect(fs.readdirSync(dir.name).length).toBe(21);
})
it('Set and get log level', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
logger.setLevel('debug');
expect(logger.getLevel()).toBe('debug');
logger.setLevel('info');
expect(logger.getLevel()).toBe('info');
logger.setLevel('warning');
expect(logger.getLevel()).toBe('warn');// match old Z2M levels
logger.setLevel('warn');
expect(logger.getLevel()).toBe('warn');// match old Z2M levels
logger.setLevel('error');
expect(logger.getLevel()).toBe('error');
});
it('Add transport', () => {
it('Set warning when log level is warn', () => {
settings.set(['advanced', 'log_level'], 'warn');
settings.reRead();
logger.init();
expect(logger.level).toBe('warning');// getLevel() reports old Z2M level to match display/value
settings.set(['advanced', 'log_level'], 'info');
settings.reRead();
});
it('Add/remove transport', () => {
class DummyTransport extends Transport {
log(info, callback) {
}
}
const logger = require('../lib/util/logger').default;
logger.init();
expect(logger.winston().transports.length).toBe(2);
logger.addTransport(new DummyTransport());
expect(logger.winston().transports.length).toBe(3);
});
it('Set and get log level warn <-> warning', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
logger.setLevel('warn');
expect(logger.winston().transports[0].level).toBe('warning');
expect(logger.getLevel()).toBe('warn');
expect(logger.winston.transports.length).toBe(2);
const transport = new DummyTransport();
logger.addTransport(transport);
expect(logger.winston.transports.length).toBe(3);
logger.removeTransport(transport);
expect(logger.winston.transports.length).toBe(2);
});
it('Logger should be console and file by default', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston()._readableState.pipes;
const pipes = logger.winston._readableState.pipes;
expect(pipes.length).toBe(2);
expect(pipes[0].constructor.name).toBe('Console');
expect(pipes[0].silent).toBe(false);
@@ -107,10 +104,8 @@ describe('Logger', () => {
it('Logger can be file only', () => {
settings.set(['advanced', 'log_output'], ['file']);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston()._readableState.pipes;
const pipes = logger.winston._readableState.pipes;
expect(pipes.length).toBe(2);
expect(pipes[0].constructor.name).toBe('Console');
expect(pipes[0].silent).toBe(true);
@@ -120,30 +115,24 @@ describe('Logger', () => {
it('Logger can be console only', () => {
settings.set(['advanced', 'log_output'], ['console']);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston()._readableState.pipes;
const pipes = logger.winston._readableState.pipes;
expect(pipes.constructor.name).toBe('Console');
expect(pipes.silent).toBe(false);
});
it('Logger can be nothing', () => {
settings.set(['advanced', 'log_output'], []);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston()._readableState.pipes;
const pipes = logger.winston._readableState.pipes;
expect(pipes.constructor.name).toBe('Console');
expect(pipes.silent).toBe(true);
});
it('Should allow to disable log rotation', () => {
settings.set(['advanced', 'log_rotation'], false);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston()._readableState.pipes;
const pipes = logger.winston._readableState.pipes;
expect(pipes[1].constructor.name).toBe('File');
expect(pipes[1].maxFiles).toBeNull();
expect(pipes[1].tailable).toBeFalsy();
@@ -152,9 +141,7 @@ describe('Logger', () => {
it('Should allow to symlink logs to current directory', () => {
settings.set(['advanced', 'log_symlink_current'], true);
let logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
expect(fs.readdirSync(dir.name).includes('current')).toBeTruthy()
jest.resetModules();
@@ -162,26 +149,90 @@ describe('Logger', () => {
});
it('Log', () => {
const logger = require('../lib/util/logger').default;
logger.init();
const warn = jest.spyOn(logger.winston(), 'warning');
logger.warn('warn');
expect(warn).toHaveBeenCalledWith('warn');
logger.setLevel('debug');
const debug = jest.spyOn(logger.winston(), 'debug');
const debug = jest.spyOn(logger.winston, 'debug');
logger.debug('debug');
expect(debug).toHaveBeenCalledWith('debug');
expect(debug).toHaveBeenCalledWith('debug', {namespace: 'z2m'});
expect(debug).toHaveBeenCalledTimes(1);
const warning = jest.spyOn(logger.winston(), 'warning');
logger.warning('warning');
expect(warning).toHaveBeenCalledWith('warning');
const info = jest.spyOn(logger.winston(), 'info');
const info = jest.spyOn(logger.winston, 'info');
logger.info('info');
expect(info).toHaveBeenCalledWith('info');
expect(info).toHaveBeenCalledWith('info', {namespace: 'z2m'});
expect(info).toHaveBeenCalledTimes(1);
const error = jest.spyOn(logger.winston(), 'error');
const warning = jest.spyOn(logger.winston, 'warning');
logger.warning('warning');
expect(warning).toHaveBeenCalledWith('warning', {namespace: 'z2m'});
expect(warning).toHaveBeenCalledTimes(1);
const error = jest.spyOn(logger.winston, 'error');
logger.error('error');
expect(error).toHaveBeenCalledWith('error');
expect(error).toHaveBeenCalledWith('error', {namespace: 'z2m'});
logger.error(new Error('error'));// test for stack=true
expect(error).toHaveBeenCalledWith('error', {namespace: 'z2m'});
expect(error).toHaveBeenCalledTimes(2);
});
it.each([
[
'^zhc:legacy:fz:(tuya|moes)',
new RegExp(/^zhc:legacy:fz:(tuya|moes)/),
[
{ ns: 'zhc:legacy:fz:tuya_device12', match: true },
{ ns: 'zhc:legacy:fz:moes_dimmer', match: true },
{ ns: 'zhc:legacy:fz:not_moes', match: false },
{ ns: 'zhc:legacy:fz', match: false },
{ ns: 'zhc:legacy:fz:', match: false },
{ ns: '1zhc:legacy:fz:tuya_device12', match: false },
]
],
[
'^zhc:legacy:fz:(tuya|moes)|^zh:ember:uart:|^zh:controller',
new RegExp(/^zhc:legacy:fz:(tuya|moes)|^zh:ember:uart:|^zh:controller/),
[
{ ns: 'zh:ember:uart:ash', match: true },
{ ns: 'zh:ember:uart', match: false },
{ ns: 'zh:controller', match: true },
{ ns: 'zh:controller:', match: true },
{ ns: 'azh:controller:', match: false },
]
],
[
'',
undefined,
[
{ ns: 'zhc:legacy:fz:tuya_device12', match: false },
{ ns: 'zhc:legacy:fz:moes_dimmer', match: false },
{ ns: 'zhc:legacy:fz:not_moes', match: false },
{ ns: 'zhc:legacy:fz', match: false },
{ ns: 'zhc:legacy:fz:', match: false },
{ ns: '1zhc:legacy:fz:tuya_device12', match: false },
{ ns: 'zh:ember:uart:ash', match: false },
{ ns: 'zh:ember:uart', match: false },
{ ns: 'zh:controller', match: false },
{ ns: 'zh:controller:', match: false },
{ ns: 'azh:controller:', match: false },
]
],
])('Sets namespace ignore for debug level %s', (ignore, expected, tests) => {
logger.setLevel('debug');
const debugSpy = jest.spyOn(logger.winston, 'debug');
logger.setDebugNamespaceIgnore(ignore);
expect(logger.debugNamespaceIgnoreRegex).toStrictEqual(expected);
expect(logger.getDebugNamespaceIgnore()).toStrictEqual(ignore);
for (const test of tests) {
logger.debug('Test message', test.ns);
if (test.match) {
expect(debugSpy).not.toHaveBeenCalled();
} else {
expect(debugSpy).toHaveBeenCalled();
}
debugSpy.mockClear();
}
})
});
+9 -9
View File
@@ -17,10 +17,10 @@ const MQTT = require('./stub/mqtt');
const settings = require('../lib/util/settings');
const Controller = require('../lib/controller');
const flushPromises = require('./lib/flushPromises');
const mocksClear = [MQTT.publish, logger.warn, logger.debug];
const mocksClear = [MQTT.publish, logger.warning, logger.debug];
const setTimeoutNative = setTimeout;
describe('onlythisNetworkmap', () => {
describe('Networkmap', () => {
let controller;
beforeAll(async () => {
@@ -102,7 +102,7 @@ describe('onlythisNetworkmap', () => {
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":"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"}]};
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 bulb E26/E27, white spectrum, globe, opal, 980 lm","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, color_options, identify, 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, voltage, power_outage_count, action, 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":"action, linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"CC2530 router","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);
/**
@@ -143,7 +143,7 @@ describe('onlythisNetworkmap', () => {
const expected = `digraph G {
node[shape=record];
"0x00124b00120144ae" [style="bold, filled", fillcolor="#e04e5d", fontcolor="#ffffff", label="{Coordinator|0x00124b00120144ae (0x0000)|0 seconds ago}"];
"0x000b57fffec6a5b2" [style="rounded, filled", fillcolor="#4ea3e0", fontcolor="#ffffff", label="{bulb|0x000b57fffec6a5b2 (0x9db1)|IKEA TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (LED1545G12)|9 seconds ago}"];
"0x000b57fffec6a5b2" [style="rounded, filled", fillcolor="#4ea3e0", fontcolor="#ffffff", label="{bulb|0x000b57fffec6a5b2 (0x9db1)|IKEA TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm (LED1545G12)|9 seconds ago}"];
"0x000b57fffec6a5b2" -> "0x00124b00120144ae" [penwidth=2, weight=1, color="#009900", label="92 (routes: 0x198c)"]
"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"]
@@ -151,7 +151,7 @@ describe('onlythisNetworkmap', () => {
"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}"];
"0x0017880104e45559" [style="rounded, filled", fillcolor="#4ea3e0", fontcolor="#ffffff", label="{cc2530_router|0x0017880104e45559 (0x198c)|Custom devices (DiY) CC2530 router (CC2530.ROUTER)|9 seconds ago}"];
"0x0017880104e45559" -> "0x000b57fffec6a5b2" [penwidth=0.5, weight=0, color="#994444", label="100"]
"0x0017880104e45511" [style="rounded, dashed, filled", fillcolor="#fff8ce", fontcolor="#000000", label="{0x0017880104e45511|0x0017880104e45511 (0x045a)|external external (external_converter_device)|9 seconds ago}"];
"0x0017880104e45511" -> "0x00124b00120144ae" [penwidth=1, weight=0, color="#994444", label="92"]
@@ -207,7 +207,7 @@ describe('onlythisNetworkmap', () => {
---
0x000b57fffec6a5b2 (0x9db1)
---
IKEA TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (LED1545G12)
IKEA TRADFRI bulb E26/E27, white spectrum, globe, opal, 980 lm (LED1545G12)
---
9 seconds ago
]
@@ -237,7 +237,7 @@ describe('onlythisNetworkmap', () => {
---
0x0017880104e45559 (0x198c)
---
Custom devices (DiY) [CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/) (CC2530.ROUTER)
Custom devices (DiY) CC2530 router (CC2530.ROUTER)
---
9 seconds ago
]
@@ -276,7 +276,7 @@ describe('onlythisNetworkmap', () => {
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":"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 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 bulb E26/E27, white spectrum, globe, opal, 980 lm","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, color_options, identify, 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, voltage, power_outage_count, action, 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":"action, linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"CC2530 router","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('onlythisNetworkmap', () => {
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":"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 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, voltage, power_outage_count, action, 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":"action, linkquality","vendor":"Boef"},"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"CC2530 router","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);
});
+1 -1
View File
@@ -8,7 +8,7 @@ const settings = require('../lib/util/settings');
const Controller = require('../lib/controller');
const flushPromises = require('./lib/flushPromises');
const mocksClear = [MQTT.publish, logger.warn, logger.debug];
const mocksClear = [MQTT.publish, logger.warning, logger.debug];
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
const mockOnEvent = jest.fn();
+16 -9
View File
@@ -72,7 +72,7 @@ describe('OTA update', () => {
mockClear(mapped);
logger.info.mockClear();
device.save.mockClear();
mapped.ota.updateToLatest.mockImplementationOnce((a, b, onUpdate) => {
mapped.ota.updateToLatest.mockImplementationOnce((a, onUpdate) => {
onUpdate(0, null);
onUpdate(10, 3600.2123);
return 90;
@@ -83,7 +83,7 @@ describe('OTA update', () => {
expect(logger.info).toHaveBeenCalledWith(`Updating 'bulb' to latest firmware`);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(0);
expect(mapped.ota.updateToLatest).toHaveBeenCalledTimes(1);
expect(mapped.ota.updateToLatest).toHaveBeenCalledWith(device, logger, expect.any(Function));
expect(mapped.ota.updateToLatest).toHaveBeenCalledWith(device, expect.any(Function));
expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 0.00%`);
expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 10.00%, ≈ 60 minutes remaining`);
expect(logger.info).toHaveBeenCalledWith(`Finished update of 'bulb'`);
@@ -126,7 +126,7 @@ describe('OTA update', () => {
const mapped = await zigbeeHerdsmanConverters.findByDevice(device)
mockClear(mapped);
device.save.mockClear();
mapped.ota.updateToLatest.mockImplementationOnce((a, b, onUpdate) => {
mapped.ota.updateToLatest.mockImplementationOnce((a, onUpdate) => {
throw new Error('Update failed');
});
@@ -260,7 +260,7 @@ describe('OTA update', () => {
await zigbeeHerdsman.events.message(payload);
await flushPromises();
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(1);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, {"imageType": 12382});
expect(logger.info).toHaveBeenCalledWith(`Update available for 'bulb'`);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98}, undefined, 10);
@@ -294,7 +294,7 @@ describe('OTA update', () => {
await zigbeeHerdsman.events.message(payload);
await flushPromises();
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(1);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, {"imageType": 12382});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98}, undefined, 10);
expect(MQTT.publish).toHaveBeenCalledWith(
@@ -316,7 +316,7 @@ describe('OTA update', () => {
await zigbeeHerdsman.events.message(payload);
await flushPromises();
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(1);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, {"imageType": 12382});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98}, undefined, 10);
expect(MQTT.publish).toHaveBeenCalledWith(
@@ -374,7 +374,7 @@ describe('OTA update', () => {
logger.info.mockClear();
logger.error.mockClear();
device.save.mockClear();
mapped.ota.updateToLatest.mockImplementationOnce((a, b, onUpdate) => {
mapped.ota.updateToLatest.mockImplementationOnce((a, onUpdate) => {
onUpdate(0, null);
onUpdate(10, 3600);
return 91;
@@ -385,7 +385,7 @@ describe('OTA update', () => {
expect(logger.info).toHaveBeenCalledWith(`Updating 'bulb' to latest firmware`);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(0);
expect(mapped.ota.updateToLatest).toHaveBeenCalledTimes(1);
expect(mapped.ota.updateToLatest).toHaveBeenCalledWith(device, logger, expect.any(Function));
expect(mapped.ota.updateToLatest).toHaveBeenCalledWith(device, expect.any(Function));
expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 0.00%`);
expect(logger.info).toHaveBeenCalledWith(`Update of 'bulb' at 10.00%, ≈ 60 minutes remaining`);
expect(logger.info).toHaveBeenCalledWith(`Finished update of 'bulb'`);
@@ -404,7 +404,7 @@ describe('OTA update', () => {
logger.info.mockClear();
logger.error.mockClear();
device.save.mockClear();
mapped.ota.updateToLatest.mockImplementationOnce((a, b, onUpdate) => {
mapped.ota.updateToLatest.mockImplementationOnce((a, onUpdate) => {
throw new Error('Update failed');
});
@@ -485,4 +485,11 @@ describe('OTA update', () => {
expect(spyUseIndexOverride).toHaveBeenCalledWith('http://my.site/index.json');
spyUseIndexOverride.mockClear();
});
it('Clear update state on startup', async () => {
const device = controller.zigbee.resolveEntity(zigbeeHerdsman.devices.bulb_color.ieeeAddr);
controller.state.set(device, {update: {progress: 100, remaining: 10, state: 'updating'}})
await resetExtension();
expect(controller.state.get(device)).toStrictEqual({update: {state: 'available'}});
});
});
+39 -5
View File
@@ -9,7 +9,7 @@ const settings = require('../lib/util/settings');
const Controller = require('../lib/controller');
const flushPromises = require('./lib/flushPromises');
const mocksClear = [MQTT.publish, logger.warn, logger.debug];
const mocksClear = [MQTT.publish, logger.warning, logger.debug];
const expectNothingPublished = () => {
Object.values(zigbeeHerdsman.devices).forEach((d) => {
@@ -223,6 +223,40 @@ describe('Publish', () => {
);
});
it('Should publish messages to TuYa switch with dummy endpoints', async () => {
const device = zigbeeHerdsman.devices.TS0601_switch;
const endpoint = device.getEndpoint(1);
await MQTT.events.message('zigbee2mqtt/TS0601_switch/set', stringify({state_l2: 'ON'}));
await flushPromises();
expect(endpoint.command).toHaveBeenCalledTimes(1);
expect(endpoint.command).toHaveBeenCalledWith("manuSpecificTuya", "dataRequest", {dpValues: [{data: [1], datatype: 1, dp: 2}], seq: expect.any(Number)}, {disableDefaultResponse: true});
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/TS0601_switch',
stringify({state_l2: 'ON'}),
{ retain: false, qos: 0 },
expect.any(Function)
);
});
it('Should publish messages to TuYa cover switch with dummy endpoints', async () => {
const device = zigbeeHerdsman.devices.TS0601_cover_switch;
const endpoint = device.getEndpoint(1);
await MQTT.events.message('zigbee2mqtt/TS0601_cover_switch/set', stringify({state: 'OPEN'}));
await MQTT.events.message('zigbee2mqtt/TS0601_cover_switch/set', stringify({state_l1: 'ON'}));
await MQTT.events.message('zigbee2mqtt/TS0601_cover_switch/l2/set', stringify({state: 'OFF'}));
await flushPromises();
expect(endpoint.command).toHaveBeenCalledTimes(3);
expect(endpoint.command).toHaveBeenCalledWith("manuSpecificTuya", "dataRequest", {dpValues: [{data: [0], datatype: 4, dp: 1}], seq: expect.any(Number)}, {disableDefaultResponse: true});
expect(endpoint.command).toHaveBeenCalledWith("manuSpecificTuya", "dataRequest", {dpValues: [{data: [1], datatype: 1, dp: 102}], seq: expect.any(Number)}, {disableDefaultResponse: true});
expect(endpoint.command).toHaveBeenCalledWith("manuSpecificTuya", "dataRequest", {dpValues: [{data: [0], datatype: 1, dp: 101}], seq: expect.any(Number)}, {disableDefaultResponse: true});
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/TS0601_cover_switch',
stringify({state_l2: 'OFF', state_l1: 'ON', state: 'OPEN'}),
{ retain: false, qos: 0 },
expect.any(Function)
);
});
it('Should publish messages to zigbee devices with color xy', async () => {
const device = zigbeeHerdsman.devices.bulb_color;
const endpoint = device.getEndpoint(1);
@@ -534,7 +568,7 @@ describe('Publish', () => {
logger.error.mockClear();
await MQTT.events.message('zigbee2mqtt/0x0017880104e45542/get', stringify({state_center: '', state_right: ''}));
await flushPromises();
expect(logger.error).toHaveBeenCalledWith(`Device 'wall_switch_double' has no endpoint 'center'`);
expect(logger.error).toHaveBeenCalledWith(`No converter available for 'state_center' ("")`);
expect(endpoint2.read).toHaveBeenCalledTimes(0);
expect(endpoint3.read).toHaveBeenCalledTimes(1);
expect(endpoint3.read).toHaveBeenCalledWith('genOnOff', ['onOff']);
@@ -975,7 +1009,7 @@ describe('Publish', () => {
await MQTT.events.message('zigbee2mqtt/curtain/set', stringify(payload));
await flushPromises();
expect(endpoint.write).toHaveBeenCalledTimes(1);
expect(endpoint.write).toHaveBeenCalledWith("genAnalogOutput", {"85": {"type": 57, "value": 100}});
expect(endpoint.write).toHaveBeenCalledWith("genAnalogOutput", {presentValue: 100});
});
it('ZNCLDJ11LM position', async () => {
@@ -985,7 +1019,7 @@ describe('Publish', () => {
await MQTT.events.message('zigbee2mqtt/curtain/set', stringify(payload));
await flushPromises();
expect(endpoint.write).toHaveBeenCalledTimes(1);
expect(endpoint.write).toHaveBeenCalledWith("genAnalogOutput", {"85": {"type": 57, "value": 10}});
expect(endpoint.write).toHaveBeenCalledWith("genAnalogOutput", {presentValue: 10});
});
it('ZNCLDJ11LM position', async () => {
@@ -995,7 +1029,7 @@ describe('Publish', () => {
await MQTT.events.message('zigbee2mqtt/curtain/set', stringify(payload));
await flushPromises();
expect(endpoint.write).toHaveBeenCalledTimes(1);
expect(endpoint.write).toHaveBeenCalledWith("genAnalogOutput", {"85": {"type": 57, "value": 0}});
expect(endpoint.write).toHaveBeenCalledWith("genAnalogOutput", {presentValue: 0});
});
it('ZNCLDJ11LM position', async () => {
+1 -1
View File
@@ -8,7 +8,7 @@ const settings = require('../lib/util/settings');
const Controller = require('../lib/controller');
const flushPromises = require('./lib/flushPromises');
const mocksClear = [MQTT.publish, logger.warn, logger.debug];
const mocksClear = [MQTT.publish, logger.warning, logger.debug];
describe('Receive', () => {
let controller;
-12
View File
@@ -882,18 +882,6 @@ describe('Settings', () => {
expect(settings.validate()).toEqual(expect.arrayContaining([error]));
});
it('Configuration shouldnt be valid when friendly_name is a postfix', async () => {
write(configurationFile, {
...minimalConfig,
devices: {'0x0017880104e45519': {friendly_name: 'left', retain: false}},
});
settings.reRead();
const error = `Following friendly_name are not allowed: '${utils.endpointNames}'`;
expect(settings.validate()).toEqual(expect.arrayContaining([error]));
});
it('Configuration shouldnt be valid when duplicate friendly_name are used', async () => {
write(configurationFile, {
devices: {
+6
View File
@@ -179,6 +179,12 @@ function writeDefaultConfiguration() {
'0x0017882104a44559': {
friendly_name: 'TS0601_thermostat',
},
'0x0017882104a44560': {
friendly_name: 'TS0601_switch',
},
'0x0017882104a44562': {
friendly_name: 'TS0601_cover_switch',
},
'0x0017882194e45543': {
friendly_name: 'QS-Zigbee-D02-TRIAC-2C-LN',
},
+13 -7
View File
@@ -1,28 +1,34 @@
let level = 'info';
let debugNamespaceIgnore = '';
const transports = [];
let transports = [];
let transportsEnabled = false;
const callTransports = (level, message) => {
const callTransports = (level, message, namespace) => {
if (transportsEnabled) {
for (const transport of transports) {
transport.log({level, message}, () => {});
transport.log({level, message, namespace}, () => {});
}
}
}
const mock = {
init: jest.fn(),
info: jest.fn().mockImplementation((msg) => callTransports('info', msg)),
warn: jest.fn().mockImplementation((msg) => callTransports('warn', msg)),
error: jest.fn().mockImplementation((msg) => callTransports('error', msg)),
debug: jest.fn().mockImplementation((msg) => callTransports('debug', msg)),
info: jest.fn().mockImplementation((msg, namespace = 'z2m') => callTransports('info', msg, namespace)),
warning: jest.fn().mockImplementation((msg, namespace = 'z2m') => callTransports('warning', msg, namespace)),
error: jest.fn().mockImplementation((msg, namespace = 'z2m') => callTransports('error', msg, namespace)),
debug: jest.fn().mockImplementation((msg, namespace = 'z2m') => callTransports('debug', msg, namespace)),
cleanup: jest.fn(),
logOutput: jest.fn(),
add: (transport) => transports.push(transport),
addTransport: (transport) => transports.push(transport),
removeTransport: (transport) => {
transports = transports.filter((t) => t !== transport);
},
setLevel: (newLevel) => {level = newLevel},
getLevel: () => level,
setDebugNamespaceIgnore: (newIgnore) => {debugNamespaceIgnore = newIgnore},
getDebugNamespaceIgnore: () => debugNamespaceIgnore,
setTransportsEnabled: (value) => {transportsEnabled = value},
end: jest.fn(),
};
+7 -1
View File
@@ -118,6 +118,8 @@ class Device {
this.ping = jest.fn();
this.removeFromNetwork = jest.fn();
this.removeFromDatabase = jest.fn();
this.customClusters = {};
this.addCustomCluster = jest.fn();
this.save = jest.fn();
this.manufacturerName = manufacturerName;
this.lastSeen = 1000;
@@ -134,6 +136,8 @@ const bulb_color = new Device('Router', '0x000b57fffec6a5b3', 40399, 4107, [new
const bulb_color_2 = new Device('Router', '0x000b57fffec6a5b4', 401292, 4107, [new Endpoint(1, [0,3,4,5,6,8,768,2821,4096], [5,25,32,4096], '0x000b57fffec6a5b4', [], {lightingColorCtrl: {colorCapabilities: 254}}, [], null, null, {'scenes': {'1_0': {name: 'Chill scene', state: {state: 'ON'}}, '4_9': {state: {state: 'OFF'}}}})], true, "Mains (single phase)", "LLC020", false, 'Philips', '2019.09', '5.127.1.26581');
const bulb_2 = new Device('Router', '0x000b57fffec6a5b7', 40369, 4476, [new Endpoint(1, [0,3,4,5,6,8,768,2821,4096], [5,25,32,4096], '0x000b57fffec6a5b7', [], {lightingColorCtrl: {colorCapabilities: 17}})], true, "Mains (single phase)", "TRADFRI bulb E27 WS opal 980lm");
const TS0601_thermostat = new Device('EndDevice', '0x0017882104a44559', 6544,4151, [new Endpoint(1, [], [], '0x0017882104a44559')], true, "Mains (single phase)", 'kud7u2l');
const TS0601_switch = new Device('EndDevice', '0x0017882104a44560', 6544,4151, [new Endpoint(1, [], [], '0x0017882104a44560')], true, "Mains (single phase)", 'kjintbl');
const TS0601_cover_switch = new Device('EndDevice', '0x0017882104a44562', 6544,4151, [new Endpoint(1, [], [], '0x0017882104a44562')], true, "Mains (single phase)", 'TS0601', false, '_TZE200_5nldle7w');
const ZNCZ02LM = new Device('Router', '0x0017880104e45524', 6540,4151, [new Endpoint(1, [0, 6], [], '0x0017880104e45524')], true, "Mains (single phase)", "lumi.plug");
const GLEDOPTO_2ID = new Device('Router', '0x0017880104e45724', 6540,4151, [new Endpoint(11, [0,3,4,5,6,8,768], [], '0x0017880104e45724', [], {}, [], 49246, 528), new Endpoint(12, [0, 3, 4, 5, 6, 8, 768], [], '0x0017880104e45724', [], {}, [], 260, 258), new Endpoint(13, [4096], [4096], '0x0017880104e45724', [], {}, [], 49246, 57694), new Endpoint(15, [0, 3, 4, 5, 6, 8, 768], [], '0x0017880104e45724', [], {}, [], 49246, 256)], true, "Mains (single phase)", 'GL-C-007', false, 'GLEDOPTO');
const QBKG03LM = new Device('Router', '0x0017880104e45542', 6540,4151, [new Endpoint(1, [0], [], '0x0017880104e45542'), new Endpoint(2, [0, 6], [], '0x0017880104e45542'), new Endpoint(3, [0, 6], [], '0x0017880104e45542')], true, "Mains (single phase)", 'lumi.ctrl_neutral2');
@@ -197,6 +201,8 @@ const devices = {
'3157100': new Device('Router', '0x0017880104e44559', 6542,4151, [new Endpoint(1, [], [], '0x0017880104e44559')], true, "Mains (single phase)", '3157100', false, 'Centralite'),
'J1': new Device('Router', '0x0017880104a44559', 6543,4151, [new Endpoint(1, [], [], '0x0017880104a44559')], true, "Mains (single phase)", 'J1 (5502)'),
'TS0601_thermostat': TS0601_thermostat,
'TS0601_switch': TS0601_switch,
'TS0601_cover_switch': TS0601_cover_switch,
'external_converter_device': new Device('EndDevice', '0x0017880104e45511', 1114, 'external', [new Endpoint(1, [], [], '0x0017880104e45511')], false, null, 'external_converter_device' ),
'QS_Zigbee_D02_TRIAC_2C_LN':new Device('Router', '0x0017882194e45543', 6549,4151, [new Endpoint(1, [0], [], '0x0017882194e45543'), new Endpoint(2, [0, 6], [], '0x0017882194e45543')], true, "Mains (single phase)", 'TS110F', false, '_TYZB01_v8gtiaed'),
'unknown': new Device('Router', '0x0017980134e45545', 6540,4151, [], true, "Mains (single phase)"),
@@ -257,8 +263,8 @@ const mock = {
const mockConstructor = jest.fn().mockImplementation(() => mock);
jest.mock('zigbee-herdsman', () => ({
...jest.requireActual('zigbee-herdsman'),
Controller: mockConstructor,
Zcl: {ManufacturerCode: {Philips: 4107}},
}));
module.exports = {
+17 -13
View File
@@ -1,18 +1,24 @@
#!/bin/bash -e
cd "$(dirname "$0")"
NEED_RESTART=0
if [ -d data-backup ]; then
echo "ERROR: Backup directory exists. May be previous restoring was failed?"
echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later."
echo "2. Manually delete 'data-backup' dir and try again."
exit 1
echo "ERROR: Backup directory exists. May be previous restoring was failed?"
echo "1. Save 'data-backup' and 'data' dirs to safe location to make possibility to restore config later."
echo "2. Manually delete 'data-backup' dir and try again."
exit 1
fi
if which systemctl 2> /dev/null > /dev/null; then
echo "Stopping Zigbee2MQTT..."
sudo systemctl stop zigbee2mqtt
echo "Checking Zigbee2MQTT status..."
if systemctl is-active --quiet zigbee2mqtt; then
echo "Stopping Zigbee2MQTT..."
sudo systemctl stop zigbee2mqtt
NEED_RESTART=1
fi
else
echo "Skipped stopping Zigbee2MQTT, no systemctl found"
echo "Skipped stopping Zigbee2MQTT, no systemctl found"
fi
echo "Creating backup of configuration..."
@@ -22,7 +28,7 @@ echo "Checking out changes to package-lock.json..."
git checkout package-lock.json
echo "Updating..."
git pull
git pull --no-rebase
echo "Installing dependencies..."
npm ci
@@ -34,11 +40,9 @@ echo "Restore configuration..."
cp -R data-backup/* data
rm -rf data-backup
if which systemctl 2> /dev/null > /dev/null; then
echo "Starting Zigbee2MQTT..."
sudo systemctl start zigbee2mqtt
else
echo "Skipped starting Zigbee2MQTT, no systemctl found"
if [ $NEED_RESTART -eq 1 ]; then
echo "Starting Zigbee2MQTT..."
sudo systemctl start zigbee2mqtt
fi
echo "Done!"