Compare commits

...
2198 Commits
Author SHA1 Message Date
Koen Kanters 44922120a6 1.21.2 2021-10-01 17:53:20 +02:00
Koen Kanters c7b9c06c89 Undev 2021-10-01 17:53:17 +02:00
github-actions[bot]andKoenkk 258326a88c Update zigbee-herdsman-converters to 14.0.261 (#8939)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-10-01 17:52:34 +02:00
Koen Kanters 4ec828d68e Merge branch 'dev' 2021-10-01 17:43:57 +02:00
github-actions[bot]andKoenkk d9735f5981 Update zigbee-herdsman-converters to 14.0.260 (#8938)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-10-01 17:42:53 +02:00
github-actions[bot]andnurikk fa8011983d Update zigbee2mqtt-frontend to 0.6.12 (#8929)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-10-01 08:55:08 +08:00
github-actions[bot]andnurikk 7f98771e99 Update zigbee2mqtt-frontend to 0.6.11 (#8876)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-09-30 19:17:44 +08:00
github-actions[bot]andKoenkk 7d6d71dcbe Update zigbee-herdsman-converters to 14.0.259 (#8918)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-29 22:16:11 +02:00
Koen Kanters 8d9f14e30b Fix device configuring with endpoint ID not working. https://github.com/nurikk/zigbee2mqtt-frontend/issues/874 2021-09-29 22:00:01 +02:00
github-actions[bot]andKoenkk 06d30d1036 Update zigbee-herdsman-converters to 14.0.258 (#8903)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-28 20:43:12 +02:00
github-actions[bot]andKoenkk f517b85a75 Update zigbee-herdsman-converters to 14.0.257 (#8896)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-27 20:40:14 +02:00
738b241a31 Update zigbee-herdsman to 0.13.149 (#8889)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-09-26 19:08:19 +02:00
github-actions[bot]andKoenkk 2605d48557 Update zigbee-herdsman-converters to 14.0.256 (#8888)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-26 19:05:41 +02:00
github-actions[bot]andKoenkk 918d8e2f88 Update dependencies (#8884)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-26 17:18:04 +02:00
github-actions[bot]andKoenkk 0dfadb3a10 Update zigbee-herdsman-converters to 14.0.255 (#8880)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-25 19:15:34 +02:00
github-actions[bot]andKoenkk 27a7bdb14a Update zigbee-herdsman-converters to 14.0.254 (#8869)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-24 18:41:45 +02:00
github-actions[bot]andKoenkk 5829663b95 Update zigbee-herdsman-converters to 14.0.253 (#8856)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-23 20:30:04 +02:00
Koen Kanters a8eec889f5 Remove debug log. https://github.com/Koenkk/zigbee2mqtt/issues/8836 2021-09-22 20:02:41 +02:00
Koen Kanters 6888394600 Refactor frontend to TypeScript. 2021-09-22 20:01:46 +02:00
github-actions[bot]andKoenkk 57b4d678d5 Update zigbee-herdsman-converters to 14.0.252 (#8847)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-22 19:40:10 +02:00
Koen Kanters 59dd6e6bff Fix error when device does not exists. https://github.com/Koenkk/zigbee2mqtt/issues/8836 2021-09-22 19:06:28 +02:00
Koen Kanters 89dea86b3a Refactor HomeAssistant extension to TypeScript 2021-09-22 18:04:57 +02:00
github-actions[bot]andKoenkk 74ee5581fe Update zigbee-herdsman-converters to 14.0.251 (#8837)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-21 22:18:41 +02:00
Koen Kanters aaad76e323 Add debug logging for https://github.com/Koenkk/zigbee2mqtt/issues/8836 2021-09-21 22:01:31 +02:00
Koen Kanters 7557c10095 More TypeScript refactoring 2021-09-21 16:58:20 +02:00
github-actions[bot]andKoenkk 58957a30e4 Update zigbee-herdsman to 0.13.148 (#8825)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-20 22:06:59 +02:00
github-actions[bot]andKoenkk 32ddcc5e61 Update zigbee-herdsman-converters to 14.0.250 (#8824)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-20 21:55:35 +02:00
Koen Kanters 6369fe1528 Fix Home Assistant discovery for covers only supporting tilt. https://github.com/Koenkk/zigbee-herdsman-converters/pull/2663 2021-09-20 21:52:26 +02:00
github-actions[bot]andKoenkk 187dde436c Update zigbee-herdsman to 0.13.147 (#8823)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-20 21:33:42 +02:00
github-actions[bot]andnurikk 80b35ba728 Update zigbee2mqtt-frontend to 0.6.8 (#8822)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-09-21 00:46:38 +08:00
github-actions[bot]andKoenkk 41b1d53723 Update dependencies (#8812)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-20 12:11:07 +02:00
github-actions[bot]andKoenkk 9f12ef7370 Update zigbee-herdsman to 0.13.146 (#8809)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-19 21:54:46 +02:00
Koen Kanters 7f4a9c2a9b Refactor onEvent extension to TypeScript 2021-09-19 11:37:08 +02:00
Koen Kanters 48de2fa647 Refactor configure extension to TypeScript. 2021-09-19 11:08:16 +02:00
Koen Kanters 27b36b316c Update CI node version to 14 2021-09-18 18:26:17 +02:00
Koen Kanters ca3c6ce32f More TypeScript refactoring (#8797)
* ts

* Updates
2021-09-18 18:23:28 +02:00
github-actions[bot]andKoenkk 0d3998f369 Update zigbee-herdsman-converters to 14.0.249 (#8796)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-18 16:20:06 +02:00
github-actions[bot]andnurikk b929dcbeb8 Update zigbee2mqtt-frontend to 0.6.7 (#8792)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-09-18 12:31:21 +08:00
github-actions[bot]andKoenkk b558bbdc85 Update zigbee-herdsman to 0.13.145 (#8762)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-16 00:38:35 +02:00
github-actions[bot]andKoenkk bb5be4df25 Update zigbee-herdsman-converters to 14.0.248 (#8756)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-15 14:58:56 +02:00
github-actions[bot]andKoenkk eca5492a8e Update zigbee-herdsman-converters to 14.0.247 (#8752)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-15 01:44:01 +02:00
ac44a50d3d Update zigbee-herdsman-converters to 14.0.246 (#8737)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-09-13 02:10:39 +02:00
github-actions[bot]andKoenkk 32b127d280 Update zigbee-herdsman to 0.13.144 (#8736)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-13 02:02:21 +02:00
github-actions[bot]andKoenkk 8c0827afe3 Update zigbee-herdsman-converters to 14.0.245 (#8728)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-12 13:30:54 +02:00
github-actions[bot]andKoenkk 7a97c67f74 Update dependencies (#8724)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-12 13:10:42 +02:00
github-actions[bot]andnurikk bb1cbf3de7 Update zigbee2mqtt-frontend to 0.6.6 (#8727)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-09-12 18:29:08 +08:00
github-actions[bot]andKoenkk 75d2fe393d Update zigbee-herdsman to 0.13.143 (#8723)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-11 19:18:29 -04:00
Koen Kanters fb081316e2 More TypeScript refactoring (#8721)
* Update

* u

* Updates

* Updates

* updates

* Updates

* Update
2021-09-11 14:51:29 +02:00
github-actions[bot]andKoenkk feff729eb6 Update zigbee-herdsman-converters to 14.0.244 (#8720)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-11 14:36:06 +02:00
Koen Kanters 69e3deb7ac Add multi endpoint support for Home Assistant cover. https://github.com/Koenkk/zigbee2mqtt/issues/8712 2021-09-11 13:53:00 +02:00
github-actions[bot]andKoenkk c1eb56aa30 Update zigbee-herdsman-converters to 14.0.243 (#8715)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-11 02:00:02 +02:00
Pavel Sokolov cadcdc3525 Fix zStackEraseAllNvMem.js (#8692)
* Fix zStackEraseAllNvMem.js

* lint fix
2021-09-09 00:46:10 +08:00
github-actions[bot]andKoenkk d140d2b4b2 Update zigbee-herdsman-converters to 14.0.242 (#8679)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-07 19:36:36 +02:00
frooglandKoen Kanters 22bba95a70 ead bulb state, brightness and colour on scene recall command (#8585)
* Poll brightness/state after recalling scene

When a ZigBee Scene Controller is recalling a scene through a direct binding
we need to poll for changed state and brightness.

* Also poll for color changes on scene recalling

* Force copy of settings.schema.json

* Update bind.js

* Update zigbeeHerdsman.js

* Update bind.test.js

* Update bind.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-09-07 19:17:23 +02:00
Koen Kanters 291383fe2f Fix tests failing on Node 16 2021-09-06 18:41:53 +02:00
github-actions[bot]andKoenkk 7e5814aaad Update zigbee-herdsman-converters to 14.0.241 (#8669)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-06 18:20:52 +02:00
github-actions[bot]andKoenkk 22a607da7b Update zigbee-herdsman to 0.13.142 (#8668)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-06 17:40:08 +02:00
Robert AlexaandKoen Kanters d07333c70d Home Assistant discover number selection entities for numeric values supporting set (#8640)
* Add support for numeric that allows SET access as number entities

* Remove redundant comment

* gitignore intellij idea folder

* Expose both entities to avoid breaking changes

* Improve comment

* Update homeassistant.js

* Update homeassistant.test.js

* Update homeassistant.test.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-09-06 17:38:34 +02:00
github-actions[bot]andnurikk 3c87803c79 Update zigbee2mqtt-frontend to 0.6.4 (#8664)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-09-06 20:09:38 +08:00
github-actions[bot]andKoenkk 02a508270f Update zigbee-herdsman to 0.13.141 (#8652)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-05 13:49:44 +02:00
Koen Kanters 4a51e0c0c9 Force copy of settings.schema.json 2021-09-05 13:36:28 +02:00
github-actions[bot]andKoenkk edf14b80d2 Update dependencies (#8646)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-05 13:35:43 +02:00
Koen Kanters 3708b314d1 Force copy of settings.schema.json 2021-09-05 13:32:45 +02:00
github-actions[bot]andnurikk 7da50f9248 Update zigbee2mqtt-frontend to 0.6.2 (#8641)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-09-04 22:46:55 +08:00
github-actions[bot]andnurikk e59f347d68 Update zigbee2mqtt-frontend to 0.6.1 (#8639)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-09-04 17:05:39 +08:00
github-actions[bot]andKoenkk b112184b65 Update zigbee-herdsman-converters to 14.0.240 (#8634)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-03 22:02:21 +02:00
Koen Kanters 1a514b824f Home Assistant remove deprecated last_reset_topic and change state_class to total_increasing for energy. https://github.com/Koenkk/zigbee2mqtt/issues/8604 2021-09-03 21:40:59 +02:00
github-actions[bot]andKoenkk a2653037e9 Update zigbee-herdsman to 0.13.140 (#8633)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-03 21:27:59 +02:00
Koen Kanters cf019195af Fix tests failing 2021-09-03 16:35:58 +02:00
github-actions[bot]andKoenkk b8c245b9f3 Update zigbee-herdsman to 0.13.139 (#8627)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-03 16:31:06 +02:00
Koen Kanters 31327f7e1b Fix "Cannot read property 'version' of undefined". https://github.com/Koenkk/zigbee2mqtt/pull/8567 2021-09-02 20:18:13 +02:00
github-actions[bot]andKoenkk e050a763f7 Update zigbee-herdsman-converters to 14.0.239 (#8613)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-02 17:56:47 +02:00
Koen Kanters 4125ae0888 TypeScript refactoring (#8567)
* Updates

* Updates

* Updates

* Rename

* Updates

* updates

* Updates

* Updates
2021-09-01 20:39:17 +02:00
Koen Kanters c299d9b632 Promote to dev 2021-09-01 18:10:44 +02:00
Koen Kanters eb5750d968 1.21.1 2021-09-01 18:10:02 +02:00
Koen Kanters d8432b502e Undev 2021-09-01 18:05:33 +02:00
github-actions[bot]andKoenkk 15685cacf8 Update zigbee-herdsman-converters to 14.0.238 (#8598)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-09-01 17:15:29 +02:00
github-actions[bot]andKoenkk d92bdf1c57 Update zigbee-herdsman to 0.13.138 (#8590)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-31 20:14:24 +02:00
github-actions[bot]andKoenkk 4f7264e565 Update zigbee-herdsman-converters to 14.0.237 (#8588)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-31 20:09:33 +02:00
github-actions[bot]andKoenkk 05b19117cf Update zigbee-herdsman-converters to 14.0.236 (#8576)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-30 20:03:32 +02:00
github-actions[bot]andnurikk 991b937451 Update zigbee2mqtt-frontend to 0.6.0 (#8572)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-30 20:36:37 +08:00
github-actions[bot]andKoenkk 9d60f9b64f Update zigbee-herdsman-converters to 14.0.235 (#8568)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-29 19:20:33 +02:00
github-actions[bot]andKoenkk 9e3afbf48a Update dependencies (#8555)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-29 18:56:17 +02:00
Koen Kanters 17b2315d89 Enable Home Assistant availability_mode all only when new availability feature is enabled. #6281 2021-08-28 16:20:02 +02:00
github-actions[bot]andKoenkk 7122137639 Update zigbee-herdsman to 0.13.136 (#8548)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-28 15:43:19 +02:00
Koen Kanters a9e4745075 More availability fixes. #6281 2021-08-28 14:42:04 +02:00
Koen Kanters fd7351ff61 Small availability fixes. #6281 2021-08-28 14:06:47 +02:00
Koen Kanters 22430631d2 Honour legacy availability options and retrieve state when device reconnects #6281 (#8545)
* Availability

* Updates
2021-08-28 10:08:09 +02:00
github-actions[bot]andKoenkk 7b8c5944a0 Update zigbee-herdsman-converters to 14.0.234 (#8543)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-27 20:09:38 +02:00
github-actions[bot]andKoenkk 09198d5ad5 Update zigbee-herdsman to 0.13.135 (#8541)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-27 19:49:22 +02:00
github-actions[bot]andKoenkk 352ebceadd Update zigbee-herdsman-converters to 14.0.233 (#8534)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-26 20:17:53 +02:00
Koen Kanters 3774a78134 Migrate utils to typescript. 2021-08-25 20:11:55 +02:00
Koen Kanters 5b6b4c1736 Availability stop pining when device leaves. #6281 2021-08-25 19:14:48 +02:00
github-actions[bot]andKoenkk 8bb296f3f7 Update zigbee-herdsman-converters to 14.0.232 (#8521)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-25 19:02:43 +02:00
github-actions[bot]andKoenkk 6741e43e32 Update zigbee-herdsman to 0.13.134 (#8520)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-25 18:55:07 +02:00
Koen Kanters d78bf2a3d2 Fix devices missing from UI after repair. https://github.com/nurikk/z2m-frontend/issues/746 2021-08-24 20:25:31 +02:00
github-actions[bot]andKoenkk 13e757429d Update zigbee-herdsman-converters to 14.0.231 (#8506)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-24 20:22:08 +02:00
f21516a2f2 Update zigbee-herdsman-converters to 14.0.230 (#8495)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-23 20:59:35 +02:00
github-actions[bot]andKoenkk ccc91b499a Update zigbee-herdsman to 0.13.133 (#8494)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-23 20:55:05 +02:00
Koen Kanters 1234c5a3e0 Don't use node_modules for binaries. https://github.com/Koenkk/zigbee2mqtt/issues/8410 2021-08-23 20:52:25 +02:00
Koen Kanters 9129f95c39 Add availability_mode for Home Assistant and publish availability only when its enabled for that device. #6281 2021-08-23 19:24:10 +02:00
github-actions[bot]andKoenkk b18373b669 Update zigbee-herdsman-converters to 14.0.229 (#8493)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-23 17:15:30 +02:00
Koen Kanters 5e2e8f3eb3 Don't discover entity specific availability topic for groups. #6281 2021-08-23 17:04:43 +02:00
Koen Kanters d7ae59886e Revert "Add availability_mode all for Home Assistant discovery. #6281"
This reverts commit d07f1dab31.
2021-08-23 08:19:51 +02:00
github-actions[bot]andnurikk 8f75dd8652 Update zigbee2mqtt-frontend to 0.5.27 (#8485)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-23 13:29:20 +08:00
Koen Kanters d07f1dab31 Add availability_mode all for Home Assistant discovery. #6281 2021-08-22 22:41:27 +02:00
Koen Kanters 9e8dcb2784 Allow to disable/enable availability for device and allow to configure timeout. #6281 2021-08-22 22:30:32 +02:00
github-actions[bot]andKoenkk 59f6455f13 Update zigbee-herdsman-converters to 14.0.228 (#8482)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-22 21:19:43 +02:00
github-actions[bot]andKoenkk 69d51c95db Update dependencies (#8473)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-22 18:27:27 +02:00
github-actions[bot]andKoenkk dffc58aa6b Update zigbee-herdsman-converters to 14.0.227 (#8466)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-21 14:51:11 +02:00
Jorge Schrauwen c7bf3324dc Don't publish of msg is empty after filtering (#8448) 2021-08-21 14:00:42 +02:00
github-actions[bot]andnurikk cb47efe3fe Update zigbee2mqtt-frontend to 0.5.26 (#8459)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-21 16:04:47 +08:00
Koen Kanters 94cfad445b Debug log when device requests OTA. https://github.com/Koenkk/zigbee2mqtt/issues/4561 2021-08-19 20:36:31 +02:00
github-actions[bot]andKoenkk eebc92f931 Update zigbee-herdsman-converters to 14.0.226 (#8439)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-19 19:56:40 +02:00
Koen Kanters f9451ffe22 Ping 2 times when device is unavailable where second attempt has recovery enabled. #6281 2021-08-18 21:22:06 +02:00
github-actions[bot]andKoenkk 288c0b795c Update zigbee-herdsman to 0.13.132 (#8419)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-18 21:17:01 +02:00
github-actions[bot]andKoenkk c134d4e975 Update zigbee-herdsman-converters to 14.0.225 (#8418)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-18 18:09:52 +02:00
github-actions[bot]andKoenkk fb390544af Update zigbee-herdsman-converters to 14.0.224 (#8407)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-17 19:41:20 +02:00
Franck NijhofandKoen Kanters c93b9300da Add Home Assistant device classes for air quality sensors (#8399)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-17 17:02:38 +02:00
Koen Kanters 486333d342 Fix typo. https://github.com/Koenkk/zigbee2mqtt/commit/773de25657f52b24a33c49c5565f6881ff611f7d 2021-08-17 16:45:20 +02:00
Koen Kanters 773de25657 Attempt 3 pings before marking device as unavailable and 1 when device is already unavailable. #6281 2021-08-16 21:16:52 +02:00
github-actions[bot]andKoenkk 726462caed Update zigbee-herdsman-converters to 14.0.223 (#8395)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-16 17:52:52 +02:00
Koen Kanters fe24391de8 Fix availability sleep duration. #6281 2021-08-15 22:15:38 +02:00
Koen Kanters 05deca6261 Reduce availability verbosity. #6281 2021-08-15 21:42:24 +02:00
Koen Kanters 755e8d3866 Ping twice before marking device as unavailable and wait 2 seconds between pings. #6281 2021-08-15 21:31:28 +02:00
ffc48131de Update zigbee-herdsman-converters to 14.0.222 (#8389)
* Update zigbee-herdsman-converters to 14.0.222

* Update package.json

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-15 21:02:16 +02:00
github-actions[bot]andKoenkk 0d5d5a696a Update zigbee-herdsman to 0.13.131 (#8388)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-15 20:55:07 +02:00
z-x-fandKoen Kanters a8545d08b6 Add usb to endpoint names (#8370)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-15 20:27:43 +02:00
github-actions[bot]andKoenkk e5f20f342d Update dependencies (#8375)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-15 20:11:19 +02:00
Koen Kanters c18a698e6b Availability refactor part 1 (#8243)
* Initial

* Updates

* update

* Updates

* Updates

* Updates
2021-08-14 16:04:03 +02:00
github-actions[bot]andKoenkk f74047d090 Update zigbee-herdsman to 0.13.130 (#8366)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-14 12:48:14 +02:00
Koen Kanters 17dc22fdb0 Move source map install to index.js 2021-08-14 09:59:31 +02:00
github-actions[bot]andKoenkk 5a2f262fe5 Update zigbee-herdsman-converters to 14.0.221 (#8362)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-13 19:27:22 +02:00
github-actions[bot]andKoenkk 61e133b894 Update zigbee-herdsman to 0.13.129 (#8361)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-13 19:16:54 +02:00
github-actions[bot]andnurikk fc2e8304f5 Update zigbee2mqtt-frontend to 0.5.25 (#8347)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-13 15:48:52 +08:00
github-actions[bot]andKoenkk a3f22833cd Update zigbee-herdsman-converters to 14.0.220 (#8346)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-12 17:30:34 +02:00
Koen Kanters a41c00faea Fix Home Assistant discovery for Hive SLR2(b). https://github.com/Koenkk/zigbee2mqtt/issues/7903 2021-08-12 16:55:47 +02:00
github-actions[bot]andKoenkk 632f9f579c Update zigbee-herdsman-converters to 14.0.219 (#8332)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-11 17:15:09 +02:00
github-actions[bot]andKoenkk 6dcae7b83e Update zigbee-herdsman-converters to 14.0.218 (#8324)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-10 22:39:55 +02:00
Koen Kanters 5c8fa5cb48 Log error stack on OTA update exception. https://github.com/Koenkk/zigbee2mqtt/issues/8297 2021-08-10 20:39:56 +02:00
github-actions[bot]andKoenkk 500642d42c Update zigbee-herdsman to 0.13.128 (#8323)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-10 19:21:50 +02:00
bee7474b8f Update dependencies (#8298)
* Update dependencies

* Update frontend.js

* Update frontend.js

* Update frontend.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-10 19:12:13 +02:00
github-actions[bot]andKoenkk 911c3d285e Update zigbee-herdsman-converters to 14.0.217 (#8309)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-09 17:39:52 +02:00
github-actions[bot]andnurikk 86743179a2 Update zigbee2mqtt-frontend to 0.5.23 (#8306)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-09 13:57:13 +08:00
108694276e Update zigbee-herdsman to 0.13.127 (#8305)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-08 21:48:08 +02:00
3d27a63b5a Update zigbee-herdsman-converters to 14.0.216 (#8289)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-08 21:45:09 +02:00
github-actions[bot]andnurikk 950498898c Update zigbee2mqtt-frontend to 0.5.22 (#8299)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-08 11:08:37 +08:00
Koen Kanters fab62e10fe Fix removing device from blocklist in frontend not working. https://github.com/Koenkk/zigbee2mqtt/issues/8266 2021-08-07 13:00:22 +02:00
github-actions[bot]andnurikk 08fa79d6d8 Update zigbee2mqtt-frontend to 0.5.21 (#8286)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-07 15:22:25 +08:00
github-actions[bot]andKoenkk 1b2398f13f Update zigbee-herdsman-converters to 14.0.215 (#8279)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-06 18:20:55 +02:00
github-actions[bot]andKoenkk 0685ade693 Update zigbee-herdsman to 0.13.126 (#8278)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-06 16:56:44 +02:00
github-actions[bot]andKoenkk 10615e29f3 Update zigbee-herdsman-converters to 14.0.214 (#8264)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-05 20:37:43 +02:00
a380df4f21 Update zigbee-herdsman-converters to 14.0.213 (#8247)
* Update zigbee-herdsman-converters to 14.0.213

* Update publish.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-08-03 21:04:52 +02:00
github-actions[bot]andKoenkk 86d92a9591 Update zigbee-herdsman to 0.13.125 (#8246)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-03 20:48:55 +02:00
github-actions[bot]andKoenkk 33ee9f7bd7 Update zigbee-herdsman-converters to 14.0.212 (#8245)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-03 20:26:31 +02:00
github-actions[bot]andnurikk 056e07a411 Update zigbee2mqtt-frontend to 0.5.19 (#8229)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-08-03 10:36:14 +08:00
Koen Kanters 62d763614a Fix build failing when starting from outside Zigbee2MQTT directory. https://github.com/Koenkk/zigbee2mqtt/issues/8222 2021-08-02 18:18:44 +02:00
github-actions[bot]andKoenkk 7db4e1b8d0 Update zigbee-herdsman-converters to 14.0.211 (#8225)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-02 18:15:29 +02:00
Jorge Schrauwen db61a623d5 Allow non systemctl systems to use update.sh (#8206)
With this change update.sh works on systems that do not use systemctl.
I can update z2m on my illumos machine by running `svcadm disable zigbee2mqtt; ./update.sh ; svcadm enable zigbee2mqtt`
2021-08-02 09:38:08 +02:00
github-actions[bot]andKoenkk c813eca843 Update dependencies (#8199)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-01 20:54:44 +02:00
Koen Kanters ceb63071c8 Promote to dev 2021-08-01 20:39:47 +02:00
Koen Kanters 70891eec39 1.21.0 2021-08-01 20:39:11 +02:00
Koen Kanters e637eca3ea Undev 2021-08-01 20:38:00 +02:00
github-actions[bot]andKoenkk 30f80c08d2 Update zigbee-herdsman-converters to 14.0.210 (#8204)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-01 20:29:03 +02:00
github-actions[bot]andKoenkk 745951f38d Update zigbee-herdsman-converters to 14.0.209 (#8202)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-08-01 19:27:13 +02:00
github-actions[bot]andKoenkk 30ff15b7dc Update zigbee-herdsman-converters to 14.0.208 (#8193)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-31 16:56:29 +02:00
Franck Nijhof be2689ee04 Add support for Home Assistant energy statistics (#8187)
* Add support for Home Assistant energy statistics

* Correct timestamp

* darn quotes
2021-07-31 16:30:42 +02:00
github-actions[bot]andnurikk cee9eb1e26 Update zigbee2mqtt-frontend to 0.5.18 (#8182)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-30 23:51:53 +08:00
github-actions[bot]andKoenkk 1e5e3bef97 Update zigbee-herdsman-converters to 14.0.207 (#8181)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-30 16:18:16 +02:00
github-actions[bot]andKoenkk 2457b7ee27 Update zigbee-herdsman-converters to 14.0.206 (#8177)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-29 20:22:46 +02:00
github-actions[bot]andKoenkk 6068cd8541 Update zigbee-herdsman to 0.13.124 (#8176)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-29 20:11:18 +02:00
github-actions[bot]andnurikk ffea1ed97d Update zigbee2mqtt-frontend to 0.5.16 (#8173)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-29 22:27:30 +08:00
github-actions[bot]andKoenkk 05a535cf30 Update zigbee-herdsman to 0.13.123 (#8166)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-28 20:37:14 +02:00
github-actions[bot]andKoenkk b1ee119575 Update zigbee-herdsman to 0.13.122 (#8164)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-28 19:42:51 +02:00
github-actions[bot]andKoenkk cd033c8995 Update zigbee-herdsman-converters to 14.0.205 (#8158)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-27 20:10:04 +02:00
Koen Kanters bf29fa8164 Always write hash on build. https://github.com/Koenkk/zigbee2mqtt/issues/8145 2021-07-27 19:47:39 +02:00
Koen Kanters 26ade49513 Fix ".flat is not a function" error. https://github.com/Koenkk/zigbee2mqtt/issues/8137 2021-07-27 18:39:39 +02:00
github-actions[bot]andKoenkk f9b8217996 Update zigbee-herdsman to 0.13.121 (#8157)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-27 18:28:38 +02:00
github-actions[bot]andKoenkk 35c2ffc0e5 Update zigbee-herdsman-converters to 14.0.204 (#8129)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-25 18:34:07 +02:00
github-actions[bot]andKoenkk 3653edeac3 Update dependencies (#8124)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-25 17:23:10 +02:00
Koen Kanters 6e84c149fe Fix typos 2021-07-24 16:13:11 +02:00
Koen Kanters 236b751bd1 Fix some cacheable not being cached. https://github.com/Koenkk/zigbee-herdsman-converters/pull/2814 2021-07-24 15:12:43 +02:00
github-actions[bot]andKoenkk b09f20e62e Update zigbee-herdsman-converters to 14.0.203 (#8119)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-24 10:36:30 +02:00
github-actions[bot]andKoenkk f74f5fd638 Update zigbee-herdsman to 0.13.120 (#8116)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-23 14:59:39 +02:00
github-actions[bot]andKoenkk 7279bc0e3c Update zigbee-herdsman-converters to 14.0.202 (#8109)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-22 19:26:06 +02:00
github-actions[bot]andnurikk 0e498c6d49 Update zigbee2mqtt-frontend to 0.5.14 (#8071)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-22 21:46:30 +08:00
Koen Kanters f571938efc Migrate settings.js to TypeScript. 2021-07-21 22:14:33 +02:00
Koen Kanters 402a9f6d95 Mark source-map-support as production dependency 2021-07-21 20:19:01 +02:00
github-actions[bot]andKoenkk aae288b3fe Update zigbee-herdsman-converters to 14.0.201 (#8100)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-21 19:36:02 +02:00
Koen Kanters 7b65dc631b Enable TypeScript (#8074)
* Enable Typescript

* Fix tests

* Fix tests again

* Automatically (re)build

* Updates

* Updates

* Update shrinkwrap

* Enable sourcemaps
2021-07-21 19:35:14 +02:00
Koen Kanters 321b34721f Clear outdated Home Assistant discovery when topic does not match. https://github.com/Koenkk/zigbee2mqtt/issues/8079 2021-07-20 18:14:56 +02:00
github-actions[bot]andKoenkk eaaa83dbe5 Update zigbee-herdsman-converters to 14.0.200 (#8089)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-20 18:12:58 +02:00
Franck Nijhof 7675dd1bcb Handle enabled by default for enum types / select|sensor entities (#8087)
* Disable power_on_behavior select entities by default

* Populate a bunch more

* Restore text type action lookup, it is used for DIY devices

* Remove stale comment
2021-07-20 16:53:49 +02:00
github-actions[bot]andKoenkk 46e2a772fe Update zigbee-herdsman-converters to 14.0.199 (#8077)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-19 20:33:07 +02:00
github-actions[bot]andKoenkk 6242da009c Update dependencies (#8064)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-19 10:07:12 +02:00
github-actions[bot]andnurikk bf97e668b0 Update zigbee2mqtt-frontend to 0.4.43 (#8065)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-18 13:38:05 +08:00
github-actions[bot]andKoenkk c6fdb253c6 Update zigbee-herdsman-converters to 14.0.198 (#8063)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-17 20:49:42 +02:00
Koen Kanters 51f4348e41 Fix adding endpoint to groups without endpoint name failing. #8027 2021-07-17 20:26:46 +02:00
github-actions[bot]andKoenkk b172c49bf3 Update zigbee-herdsman-converters to 14.0.197 (#8058)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-16 19:51:52 +02:00
Koen Kanters f8927a94ec Home Assistant groups use color temperature range supported by all bulbs. https://github.com/Koenkk/zigbee2mqtt/issues/8032 2021-07-16 19:09:29 +02:00
github-actions[bot]andKoenkk 07ff52a56f Update zigbee-herdsman-converters to 14.0.196 (#8055)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-15 20:17:12 +02:00
Koen Kanters a1c0bf2a85 Log stack on group add failure. #8027 2021-07-15 19:52:18 +02:00
github-actions[bot]andnurikk 0fd25cddb2 Update zigbee2mqtt-frontend to 0.4.40 (#8052)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-16 00:40:30 +08:00
github-actions[bot]andKoenkk f8742344c9 Update zigbee-herdsman to 0.13.119 (#8046)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-15 10:44:59 +02:00
github-actions[bot]andKoenkk be246fa841 Update zigbee-herdsman-converters to 14.0.195 (#8045)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-14 20:36:25 +02:00
Koen Kanters 515599ad13 Discover color temperature range for Home Assistant groups. https://github.com/Koenkk/zigbee2mqtt/issues/8032 2021-07-14 19:47:02 +02:00
Koen Kanters a2bf9c5d01 Log stack on group add failure. https://github.com/Koenkk/zigbee2mqtt/issues/8027 2021-07-14 19:13:06 +02:00
github-actions[bot]andnurikk 0974cbe08d Update zigbee2mqtt-frontend to 0.4.39 (#8029)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-14 11:57:53 +08:00
github-actions[bot]andKoenkk 465d47c163 Update zigbee-herdsman-converters to 14.0.194 (#8034)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-13 19:46:47 +02:00
Ilya Kirov c4936da726 Expose manufacturer in frontend (#8030) 2021-07-13 19:22:44 +02:00
github-actions[bot]andnurikk 0a2a8dd563 Update zigbee2mqtt-frontend to 0.4.37 (#8028)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-13 13:41:49 +08:00
github-actions[bot]andKoenkk 3e005170b4 Update zigbee-herdsman-converters to 14.0.193 (#8025)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-12 19:33:58 +02:00
github-actions[bot]andnurikk 685c707d90 Update zigbee2mqtt-frontend to 0.4.34 (#8017)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-12 12:00:56 +08:00
github-actions[bot]andKoenkk 589af545af Update dependencies (#8012)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-11 20:49:25 +02:00
Yip Rui FungandKoen Kanters 9edbe5a2a8 Discover enum exposes as select entities in Home Assistant (#7980)
* Read/write exposed enums are now discovered as MQTT Select entities in home assistant 2021.7.

* Read/Write enums are now exposed as a Select in addition to the existing sensor, for compatibility.

Also, the sensor will be disabled by default for new entities, shouldn't effect existing installations.

* Add support for returning multiple config from a single call to exposeToConfig.

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-07-09 19:37:32 +02:00
github-actions[bot]andKoenkk 60a1cf3727 Update zigbee-herdsman-converters to 14.0.192 (#7995)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-09 16:40:05 +02:00
github-actions[bot]andKoenkk 4e9863aa76 Update zigbee-herdsman-converters to 14.0.191 (#7979)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-08 17:02:05 +02:00
Koen Kanters 679d231743 Use unique identifier for Home Assistant group. https://github.com/Koenkk/zigbee2mqtt/issues/7918 2021-07-07 21:07:40 +02:00
Koen Kanters 8c929cf94b Fix Home Assistant discovery clearing all group discoveries. https://github.com/Koenkk/zigbee2mqtt/issues/7918 2021-07-06 20:14:39 +02:00
github-actions[bot]andKoenkk 486ae903a3 Update zigbee-herdsman-converters to 14.0.190 (#7972)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-06 20:12:05 +02:00
github-actions[bot]andKoenkk fbf9a58fff Update zigbee-herdsman-converters to 14.0.189 (#7958)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-05 22:53:18 +02:00
d67649e458 Update dependencies (#7956)
* Update dependencies

* Update dependencies

* updates

* update

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-07-05 22:12:50 +02:00
github-actions[bot]andKoenkk 08c5758aee Update dependencies (#7955)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-05 21:32:22 +02:00
github-actions[bot]andKoenkk c85987459a Update zigbee-herdsman to 0.13.118 (#7954)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-05 21:08:37 +02:00
Koen Kanters 47882ab933 Update update_deps 2021-07-05 21:04:40 +02:00
Koen Kanters a76c13c461 Make tests compatible with Jest 27 2021-07-05 20:46:53 +02:00
Colin McCambridgeandKoen Kanters 67391615d9 Update to new Home Assistant MQTT Fan discovery (#7359)
* Update to new Home Assistant MQTT Fan discovery

- Support 3 generic speeds plus presets.

* Customize Home Assistant discovery for 99432

* Revert "Update homeassistant.js"

This reverts commit 87b0a93c7a43244a58741c72cb8dabc58e1dc87e.

* Fix

* fix

* u

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-07-04 20:30:33 +02:00
Koen Kanters 53ae10e17b Remove console.log 2021-07-04 20:26:29 +02:00
github-actions[bot]andnurikk 223ba7fdee Update zigbee2mqtt-frontend to 0.4.33 (#7940)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-05 00:30:25 +08:00
github-actions[bot]andnurikk 6e1d6b5051 Update zigbee2mqtt-frontend to 0.4.31 (#7910)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-07-04 16:24:03 +08:00
Koen Kanters 96657e1a7d Update last_seen for all received Zigbee messages (not only handled ones). https://github.com/Koenkk/zigbee2mqtt/issues/7423 2021-07-03 17:40:22 +02:00
github-actions[bot]andKoenkk 82767a2a18 Update zigbee-herdsman-converters to 14.0.188 (#7929)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-03 15:39:31 +02:00
github-actions[bot]andKoenkk f8a978d1d8 Update zigbee-herdsman-converters to 14.0.187 (#7924)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-02 21:16:29 +02:00
Koen Kanters fe1aa084fb Only use converters of group members. https://github.com/Koenkk/zigbee2mqtt/issues/7922 2021-07-02 21:01:58 +02:00
Koen Kanters cd1a4573b1 Fix Home Assistant group discovery collision between different Zigbee2MQTT instances. https://github.com/Koenkk/zigbee2mqtt/issues/7918 2021-07-02 20:21:18 +02:00
github-actions[bot]andKoenkk 0df8663c8b Update zigbee-herdsman-converters to 14.0.186 (#7917)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-01 20:20:17 +02:00
Koen Kanters 1985e24517 Postfix all properties with endpoint name. https://github.com/Koenkk/zigbee-herdsman-converters/pull/2735 2021-07-01 19:59:52 +02:00
Koen Kanters 234e39eaea Add -dev 2021-07-01 18:16:42 +02:00
Koen Kanters 41b67fdd07 1.20.0 2021-07-01 18:16:02 +02:00
Koen Kanters 112a731812 Undev 2021-07-01 18:15:53 +02:00
github-actions[bot]andKoenkk be36316355 Update zigbee-herdsman-converters to 14.0.185 (#7916)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-07-01 17:52:41 +02:00
github-actions[bot]andKoenkk 2afd9ab68b Update zigbee-herdsman-converters to 14.0.184 (#7909)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-30 17:42:57 +02:00
github-actions[bot]andKoenkk 4cfa22501c Update zigbee-herdsman-converters to 14.0.183 (#7896)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-29 08:59:36 +02:00
github-actions[bot]andKoenkk 519a6e91f4 Update zigbee-herdsman-converters to 14.0.182 (#7885)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-26 17:50:27 +02:00
Koen Kanters 1587dc7b84 Add additional debug logging for OTA updates. https://github.com/Koenkk/zigbee2mqtt/issues/3997 2021-06-26 17:21:48 +02:00
github-actions[bot]andnurikk 523b315ab1 Update zigbee2mqtt-frontend to 0.4.29 (#7884)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-26 22:43:10 +08:00
github-actions[bot]andnurikk 1c6730ea5f Update zigbee2mqtt-frontend to 0.4.28 (#7877)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-26 00:21:54 +08:00
github-actions[bot]andnurikk a4eb3a7a0b Update zigbee2mqtt-frontend to 0.4.27 (#7876)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-25 20:31:31 +08:00
github-actions[bot]andnurikk 6898f9c54a Update zigbee2mqtt-frontend to 0.4.25 (#7872)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-25 08:36:17 +08:00
github-actions[bot]andnurikk dadda2de96 Update zigbee2mqtt-frontend to 0.4.24 (#7866)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-25 00:30:11 +08:00
Koen Kanters c27c300324 Combine published state of /set command into one message. https://github.com/Koenkk/zigbee2mqtt/issues/7854 2021-06-23 16:33:34 +02:00
06a30f7ae9 Update zigbee-herdsman-converters to 14.0.181 (#7857)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-06-22 23:05:47 +02:00
github-actions[bot]andKoenkk 74c2b1c252 Update zigbee-herdsman to 0.13.117 (#7856)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-22 23:03:30 +02:00
Koen Kanters 7b7f511dc7 Fix non supported color_mode and color properties being published for group members. https://github.com/Koenkk/zigbee2mqtt/issues/7220 https://github.com/Koenkk/zigbee2mqtt/issues/7736 2021-06-22 22:45:12 +02:00
Koen Kanters 0c45812c69 Fix frontend not working when MQTT broker is offline. https://github.com/nurikk/z2m-frontend/issues/589 2021-06-22 17:03:06 +02:00
github-actions[bot]andnurikk ac855963cb Update zigbee2mqtt-frontend to 0.4.22 (#7845)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-21 23:56:30 +08:00
github-actions[bot]andKoenkk 02e4abbff2 Update zigbee-herdsman-converters to 14.0.180 (#7840)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-20 20:54:43 +02:00
github-actions[bot]andnurikk 76a0cd507f Update zigbee2mqtt-frontend to 0.4.21 (#7830)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-20 01:17:32 +08:00
Koen Kanters 91c16812df Home Assistant: enable expose binary as switch for boolean values. https://github.com/Koenkk/zigbee2mqtt/issues/7797 2021-06-18 14:45:56 +02:00
github-actions[bot]andKoenkk 922f5024ff Update zigbee-herdsman-converters to 14.0.179 (#7817)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-18 13:20:31 +02:00
Koen Kanters 8dc7ad8dcc Home Assistant group discovery #2410 (#7672)
* Initial

* done
2021-06-16 22:48:48 +02:00
github-actions[bot]andKoenkk c8fdfc77f2 Update zigbee-herdsman-converters to 14.0.178 (#7808)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-16 21:44:24 +02:00
Koen Kanters ce311c93b1 Home Assistant: disable expose binary as switch for boolean values. https://github.com/Koenkk/zigbee2mqtt/issues/7797 2021-06-16 17:20:11 +02:00
github-actions[bot]andKoenkk 04c4c77d1e Update zigbee-herdsman-converters to 14.0.177 (#7801)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-15 18:18:44 +02:00
github-actions[bot]andKoenkk 1c8fd479d0 Update zigbee-herdsman to 0.13.116 (#7799)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-15 18:12:19 +02:00
github-actions[bot]andKoenkk 497ca1800b Update zigbee-herdsman-converters to 14.0.176 (#7789)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-14 19:15:38 +02:00
Koen Kanters 7f995e964d Fix "Cannot read property 'group' of null" exception on "request/group/members/remove_all". https://github.com/Koenkk/zigbee2mqtt/issues/7785 2021-06-14 19:12:24 +02:00
github-actions[bot]andKoenkk 3b3dae51b5 Update zigbee-herdsman-converters to 14.0.175 (#7767)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-12 19:51:51 +02:00
github-actions[bot]andKoenkk c314e8d267 Update zigbee-herdsman to 0.13.115 (#7766)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-12 19:37:56 +02:00
Robert AlexaandKoen Kanters 8dab33dee9 Home Assistant: expose binary with SET access as switch (#7760)
* Add support for binary attributes with SET access - discover as switch in HA

* Code linting

* Update npm-shrinkwrap.json

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-06-12 19:05:13 +02:00
github-actions[bot]andKoenkk 217ce2212a Update zigbee-herdsman-converters to 14.0.174 (#7758)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-11 19:21:04 +02:00
github-actions[bot]andKoenkk 4ccee02fe3 Update zigbee-herdsman-converters to 14.0.173 (#7748)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-10 19:38:57 +02:00
github-actions[bot]andKoenkk ee7bdf4ae2 Update zigbee-herdsman-converters to 14.0.172 (#7735)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-08 16:23:08 +02:00
Koen Kanters fa8593c898 Log and publish friendly_name on deviceLeave. https://github.com/Koenkk/zigbee2mqtt/issues/7725 2021-06-08 15:58:10 +02:00
Franck Nijhof 000884b080 Deprecate Home Assistant entity attributes (#7683)
* Deprecate Home Assistant entity attributes

* Adjust test to match latest dev

* Set default only for new installations

* Fix tests
2021-06-08 15:33:14 +02:00
github-actions[bot]andKoenkk 9eb1fe61e7 Update zigbee-herdsman-converters to 14.0.171 (#7724)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-07 15:54:32 +02:00
github-actions[bot]andKoenkk 741b936680 Update zigbee-herdsman to 0.13.114 (#7723)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-07 15:49:32 +02:00
github-actions[bot]andKoenkk 61b57aceae Update zigbee-herdsman to 0.13.113 (#7719)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-07 10:09:34 +02:00
Koen Kanters 7b13b2d213 Improve 0401a13d5d 2021-06-07 09:54:33 +02:00
Koen Kanters 0401a13d5d Disable legacy options on new network start. 2021-06-07 09:46:10 +02:00
github-actions[bot]andnurikk 95d39a3ff6 Update zigbee2mqtt-frontend to 0.4.19 (#7711)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-06 17:26:29 +08:00
github-actions[bot]andKoenkk 34e286c261 Update zigbee-herdsman to 0.13.112 (#7705)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-05 19:35:46 +02:00
github-actions[bot]andKoenkk 0b19d01e6d Update zigbee-herdsman-converters to 14.0.170 (#7702)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-04 22:16:48 +02:00
Franck Nijhof 5e7387fa9c Disable less common Home Assistant entities by default (#7684)
* Disable less common Home Assistant entities by default

* Disable illuminance by default

* Please eslint
2021-06-04 21:33:45 +02:00
Franck Nijhof 51fd598e32 Add Home Assistant sensor state_class support (#7677) 2021-06-04 11:41:42 +02:00
Koen Kanters 269dac2bf8 Promote to dev 2021-06-04 11:33:25 +02:00
Koen Kanters 9781c4352f Merge branch 'master' into dev 2021-06-04 11:32:57 +02:00
Koen Kanters 9bd46932c3 1.19.1 2021-06-04 11:29:42 +02:00
Koen Kanters ac5ebae639 Fix Docker container not starting on Raspberry Pi. https://github.com/Koenkk/zigbee2mqtt/issues/7662 2021-06-04 11:29:28 +02:00
github-actions[bot]andnurikk a608c3984b Update zigbee2mqtt-frontend to 0.4.18 (#7689)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-06-03 22:54:47 +08:00
github-actions[bot]andKoenkk c5081559cf Update zigbee-herdsman-converters to 14.0.169 (#7670)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-02 20:36:13 +02:00
Koen Kanters 0ea5f14ab7 Fix Docker container not starting on Raspberry Pi. https://github.com/Koenkk/zigbee2mqtt/issues/7662 2021-06-02 19:42:20 +02:00
Koen Kanters 9f02eb3359 Promote to dev 2021-06-01 17:55:58 +02:00
Koen Kanters 89cb4f9536 1.19.0 2021-06-01 17:55:07 +02:00
Koen Kanters fbf34f51ec Undev 2021-06-01 17:54:54 +02:00
github-actions[bot]andKoenkk 337c1fdef3 Update zigbee-herdsman-converters to 14.0.168 (#7661)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-06-01 15:26:08 +02:00
github-actions[bot]andKoenkk e0b9e3e738 Update zigbee-herdsman-converters to 14.0.167 (#7652)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-31 19:14:03 +02:00
Koen Kanters 34bc82ddd6 Fix tests 2021-05-31 19:01:12 +02:00
Koen Kanters cae4e1ff7c Display network address in router as hex. https://github.com/Koenkk/zigbee2mqtt/discussions/7603 2021-05-31 18:57:27 +02:00
Jorge Schrauwen e1bc0b53a2 Update title/description for filtered_attributes and filtired_optimistic (#7643)
* Update title/description for filtered_attributes and filtired_optimistic

The way the frontend displays it is a bit confusing, this should hopefully clear that up.

* Lint
2021-05-30 17:27:23 +02:00
github-actions[bot]andKoenkk ae4a332946 Update zigbee-herdsman-converters to 14.0.166 (#7640)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-30 14:05:37 +02:00
Jorge Schrauwen 15a7bab5f3 #7571 Add filtered_optimistic device option (#7633)
* Add filtered_optimistic device option

* Add test to cover filtered_optimistic
2021-05-30 13:03:55 +02:00
github-actions[bot]andKoenkk c6e2e875d5 Update zigbee-herdsman-converters to 14.0.165 (#7632)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-29 15:44:00 +02:00
github-actions[bot]andKoenkk 2e739cdc07 Update zigbee-herdsman to 0.13.111 (#7631)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-29 15:20:49 +02:00
Koen Kanters bd64be2b5d Show network address as hex in graphviz and plantuml network map. #7603 2021-05-29 15:19:26 +02:00
Koen Kanters fff76e6013 Republish devices when network address changes. https://github.com/Koenkk/zigbee2mqtt/discussions/7603 2021-05-29 15:06:14 +02:00
github-actions[bot]andnurikk 3d00338bc8 Update zigbee2mqtt-frontend to 0.4.16 (#7629)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-29 13:57:50 +08:00
github-actions[bot]andKoenkk 7d7ef3c7eb Update zigbee-herdsman-converters to 14.0.164 (#7626)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-28 22:03:07 +02:00
Koen Kanters 9941be1d1a Honour optimisitic false for groups (#7615)
* Honour optimisitic false for groups. https://github.com/Koenkk/zigbee2mqtt/issues/7571

* Remove default optimistic true for groups. https://github.com/Koenkk/zigbee2mqtt/issues/7571

* Updates
2021-05-28 20:23:00 +02:00
github-actions[bot]andKoenkk 7185741881 Update zigbee-herdsman-converters to 14.0.163 (#7616)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-27 18:07:18 +02:00
github-actions[bot]andKoenkk a996f5ca34 Update zigbee-herdsman-converters to 14.0.162 (#7610)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-26 18:45:49 +02:00
github-actions[bot]andKoenkk f41789e8ba Update zigbee-herdsman-converters to 14.0.161 (#7600)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-25 19:44:12 +02:00
github-actions[bot]andKoenkk fc22702bc1 Update zigbee-herdsman to 0.13.110 (#7598)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-25 19:28:43 +02:00
github-actions[bot]andKoenkk 2e8a9d9050 Update zigbee-herdsman-converters to 14.0.160 (#7597)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-25 18:53:07 +02:00
github-actions[bot]andKoenkk 6e3822caa2 Update zigbee-herdsman to 0.13.109 (#7594)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-25 18:10:19 +02:00
Koen Kanters 085983d4cd Bump to alpine 3.13 2021-05-24 21:27:49 +02:00
Koen Kanters 4af5314cd5 Merge remote-tracking branch 'origin/master' into dev 2021-05-24 21:25:39 +02:00
github-actions[bot]andKoenkk 3ef1f6a726 Update zigbee-herdsman-converters to 14.0.159 (#7586)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-24 21:23:37 +02:00
github-actions[bot]andKoenkk 85d397b1a5 Update zigbee-herdsman-converters to 14.0.158 (#7585)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-24 20:46:18 +02:00
github-actions[bot]andKoenkk 2faa252f88 Update zigbee-herdsman to 0.13.108 (#7584)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-24 20:32:05 +02:00
github-actions[bot]andKoenkk 5195f5f248 Update zigbee-herdsman-converters to 14.0.157 (#7570)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-23 15:52:57 +02:00
Jorge SchrauwenandKoen Kanters 597a5a4925 Add skip_disable_reporting to unbind group/remove (#7455)
* Allow skipping disable of reporting during unbind

* Allow skipping disable of reporting during remove from group

* Add tests

* Update bind.js

* Update groups.js

* Update bind.test.js

* Update bind.test.js

* Update bind.test.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-23 15:37:34 +02:00
github-actions[bot]andKoenkk ab84000040 Update dependencies (#7568)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-23 15:13:30 +02:00
github-actions[bot]andKoenkk ab466d3073 Update zigbee-herdsman-converters to 14.0.156 (#7563)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-22 19:42:37 +02:00
github-actions[bot]andKoenkk 792883c3db Update zigbee-herdsman-converters to 14.0.155 (#7560)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-22 14:36:26 +02:00
github-actions[bot]andKoenkk 6ca931207d Update zigbee-herdsman to 0.13.107 (#7559)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-22 14:13:37 +02:00
github-actions[bot]andKoenkk 70f5838c85 Update zigbee-herdsman-converters to 14.0.153 (#7551)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-21 20:02:28 +02:00
github-actions[bot]andKoenkk 49942df205 Update zigbee-herdsman to 0.13.106 (#7550)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-21 19:24:36 +02:00
github-actions[bot]andnurikk 888cc7eeee Update zigbee2mqtt-frontend to 0.4.15 (#7544)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-21 15:00:53 +08:00
github-actions[bot]andKoenkk 8344622815 Update zigbee-herdsman-converters to 14.0.152 (#7541)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-20 19:36:54 +02:00
github-actions[bot]andKoenkk dd9caff60f Update zigbee-herdsman to 0.13.105 (#7540)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-20 19:25:11 +02:00
github-actions[bot]andKoenkk 55916d7cd8 Update zigbee-herdsman-converters to 14.0.151 (#7531)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-19 20:16:07 +02:00
github-actions[bot]andKoenkk 7671a983bf Update zigbee-herdsman to 0.13.104 (#7530)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-19 20:10:32 +02:00
github-actions[bot]andKoenkk 891e7029fc Update zigbee-herdsman to 0.13.103 (#7529)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-19 19:59:07 +02:00
github-actions[bot]andKoenkk 7bdf52d824 Update zigbee-herdsman-converters to 14.0.150 (#7518)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-18 20:08:46 +02:00
github-actions[bot]andKoenkk c171e02cc9 Update zigbee-herdsman to 0.13.102 (#7517)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-18 18:30:28 +02:00
github-actions[bot]andKoenkk 45aa352578 Update zigbee-herdsman to 0.13.101 (#7515)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-18 17:14:43 +02:00
github-actions[bot]andnurikk 92cef6726a Update zigbee2mqtt-frontend to 0.4.14 (#7514)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-18 22:38:46 +08:00
github-actions[bot]andKoenkk 0d91b9474c Update zigbee-herdsman-converters to 14.0.149 (#7506)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-17 20:32:24 +02:00
github-actions[bot]andKoenkk c50547e465 Update zigbee-herdsman to 0.13.100 (#7504)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-17 20:16:00 +02:00
github-actions[bot]andnurikk 74bf357757 Update zigbee2mqtt-frontend to 0.4.13 (#7496)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-17 09:15:47 +08:00
Koen Kanters 669489fe97 Delete codeql-analysis.yml 2021-05-16 20:47:38 +02:00
9d0dd59c6c Update zigbee-herdsman-converters to 14.0.148 (#7492)
* Update zigbee-herdsman-converters to 14.0.148

* Update bridge.test.js

* Update group.test.js

* Update homeassistant.test.js

* Update networkMap.test.js

* Update publish.test.js

* Update homeassistant.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-16 20:47:09 +02:00
github-actions[bot]andKoenkk 638233263d Update zigbee-herdsman to 0.13.99 (#7493)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-16 19:33:56 +02:00
russdanandKoen Kanters 5aa1d21ed4 Fix controlling heat endpoint with occupied_heating_setpoint_heat not working (#7481)
* Update publish.js

Fix for issue #7470 .  Tests:

error 2021-05-14 11:37:13: key: occupied_heating_setpoint_heat
error 2021-05-14 11:37:13: endpointNameMatch 'heat' (heat)
error 2021-05-14 11:37:13: Before replace 'occupied_heating_setpoint_heat' (occupied_heating_setpoint_heat)
error 2021-05-14 11:37:13: After replace 'occupied_heating_setpoint' (occupied_heating_setpoint)
error 2021-05-14 11:37:26: key: occupied_heating_setpoint_water
error 2021-05-14 11:37:26: endpointNameMatch 'water' (water)
error 2021-05-14 11:37:26: Before replace 'occupied_heating_setpoint_water' (occupied_heating_setpoint_water)
error 2021-05-14 11:37:26: After replace 'occupied_heating_setpoint' (occupied_heating_setpoint)

* Update publish.js

* Update publish.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-16 16:08:36 +02:00
github-actions[bot]andKoenkk f20429664f Update dependencies (#7490)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-16 16:00:52 +02:00
github-actions[bot]andKoenkk 3557779efc Update zigbee-herdsman-converters to 14.0.146 (#7480)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-15 15:35:13 +02:00
github-actions[bot]andKoenkk fe8d20f86e Update zigbee-herdsman to 0.13.98 (#7479)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-15 15:27:36 +02:00
github-actions[bot]andKoenkk 39b68aa07d Update zigbee-herdsman to 0.13.97 (#7457)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-13 20:17:20 +02:00
Jorge Schrauwen 55ce381d28 homeassistant: copy hue/saturation to h/s (#7453) 2021-05-13 14:57:18 +02:00
github-actions[bot]andKoenkk 05b9252a4b Update zigbee-herdsman-converters to 14.0.145 (#7448)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-12 19:07:21 +02:00
github-actions[bot]andnurikk 766c632c30 Update zigbee2mqtt-frontend to 0.4.10 (#7447)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-12 23:17:19 +08:00
333db4ca77 Update zigbee-herdsman-converters to 14.0.144 (#7436)
* Update zigbee-herdsman-converters to 14.0.144

* Update homeassistant.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-12 08:33:43 +02:00
github-actions[bot]andnurikk f799550095 Update zigbee2mqtt-frontend to 0.4.9 (#7427)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-11 09:39:48 +08:00
John Doe fb7be8684f Fix json schema default values and examples (#7426) 2021-05-11 09:25:55 +08:00
github-actions[bot]andKoenkk 82f69beb38 Update zigbee-herdsman-converters to 14.0.143 (#7425)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-10 21:21:26 +02:00
github-actions[bot]andKoenkk d8dc4e79fe Update dependencies (#7401)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-10 17:52:07 +02:00
github-actions[bot]andnurikk 8f07addade Update zigbee2mqtt-frontend to 0.4.8 (#7420)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-10 22:48:42 +08:00
github-actions[bot]andnurikk 4666ee7261 Update zigbee2mqtt-frontend to 0.4.6 (#7406)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-10 00:04:06 +08:00
github-actions[bot]andnurikk a6736c4cd5 Update zigbee2mqtt-frontend to 0.4.5 (#7402)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-09 12:12:21 +08:00
github-actions[bot]andnurikk 7447b61841 Update zigbee2mqtt-frontend to 0.4.4 (#7398)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-09 01:05:51 +08:00
Koen Kanters 723121d671 Fix tests 2021-05-08 15:52:14 +02:00
github-actions[bot]andKoenkk fe8098c8b2 Update zigbee-herdsman to 0.13.96 (#7394)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-08 15:32:39 +02:00
Koen Kanters e6b317b762 Pass disableLED option to herdsman 2021-05-08 15:30:57 +02:00
github-actions[bot]andKoenkk 56397e2027 Update zigbee-herdsman-converters to 14.0.142 (#7382)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-07 19:20:03 +02:00
Koen Kanters 6bbe738f91 Fix controlling of different endpoint names in one message not working when endpoints have same ID. https://github.com/Koenkk/zigbee-herdsman-converters/pull/2545 2021-05-07 19:03:44 +02:00
github-actions[bot]andKoenkk a893cac951 Update zigbee-herdsman-converters to 14.0.141 (#7369)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-06 21:52:42 +02:00
github-actions[bot]andKoenkk c27249b676 Update zigbee-herdsman to 0.13.95 (#7366)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-06 21:13:21 +02:00
github-actions[bot]andnurikk 1ec33bdd8a Update zigbee2mqtt-frontend to 0.4.3 (#7358)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-06 08:46:26 +08:00
github-actions[bot]andKoenkk d74865b5f1 Update zigbee-herdsman-converters to 14.0.140 (#7356)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-05 20:43:33 +02:00
github-actions[bot]andKoenkk 548589cb70 Update zigbee-herdsman to 0.13.94 (#7355)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-05 20:05:19 +02:00
Koen Kanters febcb2b1c7 Set default for adapter to auto in schema. https://github.com/nurikk/z2m-frontend/issues/449 2021-05-05 19:50:59 +02:00
beacbd3496 Update zigbee-herdsman-converters to 14.0.139 (#7339)
* Update zigbee-herdsman-converters to 14.0.139

* Update configure.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-04 22:43:04 +02:00
Koen Kanters a77e857868 Fix color_mode missing for lights with multiple endpoints. #7220 2021-05-04 22:29:23 +02:00
github-actions[bot]andKoenkk 6c6956f1c1 Update zigbee-herdsman-converters to 14.0.138 (#7338)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-04 21:16:44 +02:00
Koen Kanters 504917bfa6 Fix device not removed from group in configuration.yaml upon device removal. https://github.com/Koenkk/zigbee2mqtt/issues/7326 2021-05-04 21:06:00 +02:00
Koen Kanters 37f773a5ee Add auto adapter type. 2021-05-04 20:04:21 +02:00
github-actions[bot]andKoenkk aace96a96c Update zigbee-herdsman to 0.13.93 (#7336)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-04 20:02:58 +02:00
github-actions[bot]andnurikk b2a64ea066 Update zigbee2mqtt-frontend to 0.4.2 (#7331)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-04 23:38:22 +08:00
github-actions[bot]andKoenkk baeac6fa68 Update zigbee-herdsman-converters to 14.0.137 (#7312)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-03 20:59:11 +02:00
Koen Kanters a35faa9554 Allow null values for serial.adapter. https://github.com/nurikk/z2m-frontend/issues/449 2021-05-03 20:44:33 +02:00
Koen Kanters 700e9c0c3a Improve network scan stability. https://github.com/Koenkk/zigbee2mqtt/issues/7163 2021-05-03 20:04:54 +02:00
svasilievandKoen Kanters 2dc409bf38 Include nodejs version 16 to supported engines (#7297)
Updating Arch, brought nodejs version 16, that made zigbee2mqtt not working. Adding 16 to supported engines, fixes it.

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-03 19:26:13 +02:00
github-actions[bot]andKoenkk 7fa04cf183 Update zigbee-herdsman-converters to 14.0.136 (#7296)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-02 20:21:11 +02:00
b76e63d222 Update zigbee-herdsman-converters to 14.0.135 (#7295)
* Update zigbee-herdsman-converters to 14.0.135

* Update group.test.js

* Update publish.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-02 20:13:34 +02:00
github-actions[bot]andnurikk 3393ac1035 Update zigbee2mqtt-frontend to 0.4.1 (#7291)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-02 23:24:13 +08:00
github-actions[bot]andKoenkk 2886d90dde Update dependencies (#7287)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-02 13:20:41 +02:00
github-actions[bot]andKoenkk e3deb03331 Update zigbee-herdsman-converters to 14.0.134 (#7279)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-01 19:21:49 +02:00
github-actions[bot]andKoenkk e64b7d2e86 Update zigbee-herdsman-converters to 14.0.133 (#7278)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-01 17:39:32 +02:00
Koen Kanters 2fe085d409 Home Assistant: don't publish mocked values anymore replaced by unknown state in #7032 2021-05-01 17:01:59 +02:00
a1983e2a32 Update zigbee-herdsman-converters to 14.0.132 (#7277)
* Update zigbee-herdsman-converters to 14.0.132

* Update configure.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-01 16:16:12 +02:00
Koen Kanters 4f495a0ed7 Promote to dev 2021-05-01 14:52:40 +02:00
Koen Kanters f2e39af12c 1.18.3 2021-05-01 14:52:07 +02:00
Koen Kanters 111d4d70bd Undev 2021-05-01 14:52:01 +02:00
github-actions[bot]andKoenkk fae2e4851c Update zigbee-herdsman-converters to 14.0.131 (#7276)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-05-01 14:15:31 +02:00
43ff2daebe Update zigbee-herdsman-converters to 14.0.129 (#7275)
* Update zigbee-herdsman-converters to 14.0.129

* Update homeassistant.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-05-01 13:56:44 +02:00
github-actions[bot]andnurikk 19373d815f Update zigbee2mqtt-frontend to 0.4.0 (#7271)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-05-01 11:35:36 +08:00
Koen Kanters e9a5ec1a58 Revert "Home Assistant: remove attributes from discovered entities. https://github.com/Koenkk/zigbee2mqtt/discussions/7249"
This reverts commit 54ab0a3f98.
2021-04-30 16:41:18 +02:00
Koen Kanters ec97931ee4 Home Assistant: don't counter action: null payload. 2021-04-30 16:41:00 +02:00
github-actions[bot]andnurikk 20c0712aba Update zigbee2mqtt-frontend to 0.3.121 (#7247)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-04-30 09:15:36 +08:00
github-actions[bot]andKoenkk 2e5e5beb83 Update zigbee-herdsman-converters to 14.0.128 (#7251)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-29 20:03:24 +02:00
Koen Kanters 54ab0a3f98 Home Assistant: remove attributes from discovered entities. https://github.com/Koenkk/zigbee2mqtt/discussions/7249 2021-04-29 19:43:54 +02:00
Koen Kanters d61d6e28f2 Only attempt to configure end device when message is received from it. (#7242) 2021-04-29 18:18:51 +02:00
ssierglandKoen Kanters 1d8b37eee0 Properly handle SIGTERM and other kernel events (#7230)
* Properly handle SIGTERM and other kernel events

see

https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#handling-kernel-signals

* Update Dockerfile

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-04-29 18:13:41 +02:00
github-actions[bot]andKoenkk 2b488ccff4 Update zigbee-herdsman-converters to 14.0.127 (#7241)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-28 20:06:27 +02:00
cedbd1fd4c Update zigbee-herdsman-converters to 14.0.126 (#7240)
* Update zigbee-herdsman-converters to 14.0.126

* Update bind.js

* Update networkMap.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-04-28 19:48:08 +02:00
Koen Kanters f27e5efe0f Fix Home Assistant "KeyError: 'color_mode'" for brightness only lights. https://github.com/Koenkk/zigbee2mqtt/issues/7220 2021-04-28 19:10:39 +02:00
github-actions[bot]andKoenkk 7eeaeafbd0 Update zigbee-herdsman-converters to 14.0.125 (#7221)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-27 16:27:58 +02:00
github-actions[bot]andKoenkk e4d868652a Update zigbee-herdsman-converters to 14.0.124 (#7216)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-26 21:42:48 +02:00
71d77ac27c Update zigbee-herdsman-converters to 14.0.121 (#7213)
* Update zigbee-herdsman-converters to 14.0.121

* Update bridge.test.js

* Update bridge.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-04-26 16:34:08 +02:00
github-actions[bot]andKoenkk 1f80a05477 Update zigbee-herdsman to 0.13.92 (#7211)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-26 11:35:25 +02:00
github-actions[bot]andKoenkk a02c8d242a Update zigbee-herdsman-converters to 14.0.120 (#7205)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-25 19:26:15 +02:00
daxy01andKoen Kanters edc18e3376 Add log_symlink_current option (#7166)
* Update logger.js

Adding a symlink from "log/<timestamp>" to "log/current" to be able to always view the last logfile using "log/current/log.txt".

* Update logger.js

* Update logger.js

Create directory first to prevent startup failure

* Update logger.js

Fixing check on startup

* Update settings.js

* Update logger.js

* Update settings.schema.json

* Update bridge.test.js

* Update logger.test.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-04-25 19:21:38 +02:00
github-actions[bot]andKoenkk 1f797e5e3a Update zigbee-herdsman-converters to 14.0.119 (#7204)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-25 18:55:26 +02:00
Koen Kanters aee4e96619 Attempt to fix https://github.com/Koenkk/zigbee2mqtt/issues/7198 2021-04-25 15:27:40 +02:00
Koen Kanters 7631c191c5 Home Assistant discovery: add color_mode for lights (#7057)
* Home Assistant add color_mode.

* Fix tests

* Fix coverage
2021-04-25 14:56:59 +02:00
github-actions[bot]andKoenkk 8802354ca9 Update dependencies (#7199)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-25 14:30:39 +02:00
github-actions[bot]andKoenkk 627b94e5ab Update zigbee-herdsman-converters to 14.0.118 (#7192)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-24 18:56:42 +02:00
github-actions[bot]andnurikk 8ed842603c Update zigbee2mqtt-frontend to 0.3.120 (#7190)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-04-24 21:58:41 +08:00
github-actions[bot]andKoenkk 6904020f7d Update zigbee-herdsman-converters to 14.0.117 (#7182)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-23 20:44:47 +02:00
d3fd3bcacc Update zigbee-herdsman-converters to 14.0.116 (#7169)
* Fix state of members from group incorrect when toZigbee converter reads a member state. #7038

* Update zigbee-herdsman-converters to 14.0.116

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-22 20:34:13 +02:00
Koen Kanters 366c5fcb4d Fix state of members from group incorrect when toZigbee converter reads a member state. #7038 2021-04-22 20:28:54 +02:00
Koen Kanters 2c44f4ede9 Test case for #7106 2021-04-22 19:20:03 +02:00
Koen Kanters 3f0ef8e08f Improve utils.getObjectProperty() 2021-04-22 19:19:17 +02:00
github-actions[bot]andKoenkk 01af249e95 Update zigbee-herdsman-converters to 14.0.115 (#7162)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-21 19:56:15 +02:00
github-actions[bot]andKoenkk a1e6439a5c Update zigbee-herdsman-converters to 14.0.114 (#7148)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-20 18:42:49 +02:00
github-actions[bot]andKoenkk ba305ad18b Update zigbee-herdsman-converters to 14.0.113 (#7134)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-19 20:17:37 +02:00
pklokke 95dd6c485c Support binding of server clusters towards clients (#7127)
This allows binding of devices such as sleepy temperature sensors to heating actuators
2021-04-19 20:16:31 +02:00
github-actions[bot]andKoenkk dbfdbcba4a Update zigbee-herdsman to 0.13.91 (#7122)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-18 20:43:42 +02:00
github-actions[bot]andKoenkk 14cc33cd44 Update zigbee-herdsman-converters to 14.0.112 (#7121)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-18 20:32:21 +02:00
xyzroeandKoen Kanters 9a53b954f8 Add wifi endpoint name (#7103)
* Update utils.js

added endpointNames wifi, ds, bme
wifi for future devices
ds and bme are using in DIYRuZ_Flower

* Update utils.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-04-18 20:25:18 +02:00
github-actions[bot]andKoenkk 615026984c Update dependencies (#7110)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-18 19:40:27 +02:00
github-actions[bot]andKoenkk bd660dee82 Update zigbee-herdsman-converters to 14.0.111 (#7105)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-17 16:13:09 +02:00
HeddaandKoen Kanters 75dc72550f Add 57600 as another common baud rate speed example (#7094)
* Add 57600 as another common board date example

Add 57600 as another common board date example to avoid confusions like in https://github.com/Koenkk/zigbee-herdsman/issues/319

* Spelling and grammar

Spelling and grammar

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-04-17 14:45:48 +02:00
github-actions[bot]andKoenkk c7443191ff Update zigbee-herdsman-converters to 14.0.110 (#7089)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-15 17:27:08 +02:00
Koen Kanters dff4af94f5 Home Assistant: fix device_automation not published when homeassistant is in device options. https://github.com/Koenkk/zigbee2mqtt/issues/7074 2021-04-14 20:22:26 +02:00
github-actions[bot]andKoenkk a1fc606d99 Update zigbee-herdsman to 0.13.90 (#7076)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-14 16:48:24 +02:00
github-actions[bot]andKoenkk 89ceaac3d1 Update zigbee-herdsman-converters to 14.0.109 (#7072)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-13 21:05:43 +02:00
Koen Kanters 8df8ef629e Fix state of group not changing when state of specific endpoint is changed. https://github.com/Koenkk/zigbee2mqtt/issues/6905 2021-04-13 20:20:44 +02:00
Koen Kanters 07262bd62f Fix device option set to null instead of removed when sending null. https://github.com/nurikk/z2m-frontend/issues/430 2021-04-12 19:49:21 +02:00
Koen Kanters 5963f3b7f4 Home Assistant: set unknown values to null (#7032) 2021-04-12 16:59:41 +02:00
github-actions[bot]andKoenkk 7e861aa3bb Update zigbee-herdsman-converters to 14.0.108 (#7047)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-11 17:54:23 +02:00
github-actions[bot]andKoenkk a4da036266 Update dependencies (#7040)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-11 13:04:15 +02:00
Koen Kanters 487ab0648d Improve logging 2021-04-10 18:51:13 +02:00
github-actions[bot]andKoenkk e91a23b3ed Update zigbee-herdsman-converters to 14.0.107 (#7022)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-09 22:33:05 +02:00
ptvoandptvoinfo d5d16d1616 Update schema with the Icon device property. (#7018)
* Device-specific icon

* Updated tests.

* Updated test

* Updated tests

* Updated tests.

* Updated tests

* Update schema with the Icon device property.

* Fix

Co-authored-by: ptvoinfo <xagga@ya.ru>
2021-04-09 20:52:41 +08:00
ptvoandptvoinfo e81ac11466 Allow to redefine device icon (#7013)
* Device-specific icon

* Updated tests.

* Updated test

* Updated tests

* Updated tests.

* Updated tests

Co-authored-by: ptvoinfo <xagga@ya.ru>
2021-04-09 19:35:44 +08:00
github-actions[bot]andKoenkk 93c0a8a7ba Update zigbee-herdsman-converters to 14.0.106 (#7003)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-08 21:00:02 +02:00
John Doe 42a4596be6 Add device icon from converter definition (#7001) 2021-04-08 22:57:55 +08:00
github-actions[bot]andnurikk 53772e5536 Update zigbee2mqtt-frontend to 0.3.119 (#6998)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-04-08 21:57:42 +08:00
github-actions[bot]andKoenkk 2446e173b6 Update zigbee-herdsman-converters to 14.0.105 (#6990)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-07 19:28:18 +02:00
Koen Kanters 30efb3e824 Fix "Cannot read property 'ID' of undefined". https://github.com/Koenkk/zigbee2mqtt/issues/6981 2021-04-07 18:39:54 +02:00
ab0ae8ce91 Update zigbee-herdsman-converters to 14.0.104 (#6975)
* Update zigbee-herdsman-converters to 14.0.104

* Update bridge.test.js

* Update otaUpdate.test.js

* Update zigbeeHerdsman.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-04-06 22:24:30 +02:00
github-actions[bot]andKoenkk 172689976e Update zigbee-herdsman-converters to 14.0.103 (#6968)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-05 21:06:24 +02:00
Koen Kanters bf47282ea7 Fix optimistic group state property not postfixed with endpoint name when necessary. https://github.com/Koenkk/zigbee2mqtt/issues/6905 2021-04-04 21:00:24 +02:00
github-actions[bot]andnurikk ec8348854b Update zigbee2mqtt-frontend to 0.3.118 (#6952)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-04-04 17:24:22 +08:00
github-actions[bot]andKoenkk 348c562f97 Update zigbee-herdsman to 0.13.89 (#6953)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-04 10:45:20 +02:00
github-actions[bot]andKoenkk 92bd2166e3 Update dependencies (#6948)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-04-04 10:35:29 +02:00
github-actions[bot]andnurikk d6a1d2deb5 Update zigbee2mqtt-frontend to 0.3.115 (#6938)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-04-03 15:54:29 +08:00
Koen Kanters f98d71ba6e Promote to dev 2021-04-01 09:08:03 +02:00
Koen Kanters abd8a09264 1.18.2 2021-04-01 09:07:24 +02:00
Koen Kanters 9bfbd25bd8 Remove -dev 2021-04-01 09:07:21 +02:00
Koen Kanters afc2b2ea95 Merge branch 'dev' 2021-04-01 09:06:39 +02:00
6bf27b9976 Update zigbee-herdsman-converters to 14.0.102 (#6903)
* Update zigbee-herdsman-converters to 14.0.102

* Update publish.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-03-31 18:30:08 +02:00
github-actions[bot]andKoenkk 29c8a179e3 Update zigbee-herdsman-converters to 14.0.101 (#6888)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-30 19:36:23 +02:00
github-actions[bot]andKoenkk be906fec76 Update zigbee-herdsman to 0.13.88 (#6882)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-30 17:52:09 +02:00
github-actions[bot]andnurikk 9aacf32ac7 Update zigbee2mqtt-frontend to 0.3.114 (#6880)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-30 16:36:00 +08:00
github-actions[bot]andKoenkk 010a140835 Update zigbee-herdsman-converters to 14.0.100 (#6875)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-29 21:17:29 +02:00
Koen Kanters 0b72de7056 Log FAQ on failed to start Zigbee 2021-03-29 20:15:47 +02:00
github-actions[bot]andKoenkk ddbfa02d5c Update zigbee-herdsman-converters to 14.0.99 (#6860)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-28 13:45:45 +02:00
github-actions[bot]andKoenkk cd563bffd5 Update dependencies (#6857)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-28 13:13:00 +02:00
github-actions[bot]andKoenkk 306e1b6391 Update zigbee-herdsman-converters to 14.0.98 (#6855)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-27 20:09:50 +01:00
github-actions[bot]andKoenkk f8f79d3d18 Update zigbee-herdsman to 0.13.87 (#6850)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-26 21:56:11 +01:00
github-actions[bot]andKoenkk 58bc53683d Update zigbee-herdsman-converters to 14.0.97 (#6846)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-26 21:21:51 +01:00
github-actions[bot]andKoenkk 41a4dea208 Update zigbee-herdsman to 0.13.86 (#6843)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-26 18:50:42 +01:00
github-actions[bot]andKoenkk e56f6b602e Update zigbee-herdsman-converters to 14.0.96 (#6830)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-25 19:42:32 +01:00
github-actions[bot]andKoenkk fda0270343 Update zigbee-herdsman-converters to 14.0.95 (#6821)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-24 19:23:13 +01:00
0493cf60da Fix no transaction in group and bind responses (#6810)
* Fix no transaction property in /group/members response

* Update groups.js

* Update group.test.js

* Update bind.js

* Update bind.test.js

Co-authored-by: Guillaume COURTOIS <guillaume.courtois@victeon.fr>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-03-24 19:17:49 +01:00
github-actions[bot]andKoenkk 98b98ddf8f Update zigbee-herdsman to 0.13.85 (#6820)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-24 19:16:36 +01:00
github-actions[bot]andnurikk 171e87d6ba Update zigbee2mqtt-frontend to 0.3.113 (#6819)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-24 15:56:21 +00:00
github-actions[bot]andnurikk 6d19579a70 Update zigbee2mqtt-frontend to 0.3.111 (#6795)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-23 22:42:14 +00:00
766ab452cc Update zigbee-herdsman-converters to 14.0.94 (#6806)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-03-23 19:13:16 +01:00
github-actions[bot]andKoenkk add5179fc8 Update zigbee-herdsman to 0.13.84 (#6805)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-23 19:08:29 +01:00
github-actions[bot]andKoenkk e66e2cbc04 Update zigbee-herdsman-converters to 14.0.93 (#6792)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-23 16:25:34 +01:00
github-actions[bot]andKoenkk 9c6ed20d6c Update zigbee-herdsman to 0.13.83 (#6791)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-22 20:30:40 +01:00
Koen Kanters b6085fceae Add buymeacoffee 2021-03-22 20:28:15 +01:00
Koen Kanters 326823ee00 Add permit_join_timeout to bridge/info 2021-03-22 17:03:01 +01:00
github-actions[bot]andKoenkk 4d2eaa882b Update zigbee-herdsman to 0.13.82 (#6787)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-22 17:02:06 +01:00
github-actions[bot]andKoenkk f6e7bec357 Update zigbee-herdsman-converters to 14.0.92 (#6782)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-21 21:23:16 +01:00
github-actions[bot]andKoenkk 9b1772824b Update dependencies (#6773)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-21 13:17:38 +01:00
github-actions[bot]andKoenkk 840e97edd9 Update zigbee-herdsman-converters to 14.0.91 (#6771)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-20 19:21:51 +01:00
github-actions[bot]andnurikk a2f847e370 Update zigbee2mqtt-frontend to 0.3.110 (#6768)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-20 15:13:38 +08:00
github-actions[bot]andnurikk c255625131 Update zigbee2mqtt-frontend to 0.3.109 (#6767)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-20 13:52:12 +08:00
github-actions[bot]andnurikk 5df8d1c4c0 Update zigbee2mqtt-frontend to 0.3.108 (#6766)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-20 11:40:58 +08:00
github-actions[bot]andKoenkk 04ebe253bb Update zigbee-herdsman-converters to 14.0.90 (#6764)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-19 19:36:39 +01:00
Jorge Schrauwen 3541db891d groups: also publish color_mode (#6756) 2021-03-19 17:48:56 +01:00
github-actions[bot]andKoenkk fb4f88295c Update zigbee-herdsman-converters to 14.0.89 (#6754)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-18 18:20:41 +01:00
github-actions[bot]andnurikk 8c6bb7383c Update zigbee2mqtt-frontend to 0.3.107 (#6752)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-18 23:51:39 +08:00
5a37400408 Update zigbee-herdsman-converters to 14.0.88 (#6745)
* Update zigbee-herdsman-converters to 14.0.88

* Update group.test.js

* Update publish.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-03-17 22:19:26 +01:00
Koen Kanters 1acccc002a Only publish changed properties for groups and its members. #6718 2021-03-17 21:44:29 +01:00
github-actions[bot]andKoenkk 144fdb43da Update zigbee-herdsman to 0.13.81 (#6744)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-17 20:14:06 +01:00
Franck Nijhof a17f3b1c5a Fix use of deprecated values in HA Cover platform discovery (#6544) 2021-03-17 16:48:50 +01:00
github-actions[bot]andKoenkk a9b5d5ea58 Update zigbee-herdsman-converters to 14.0.87 (#6735)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-16 20:32:33 +01:00
b85825ba4a Update zigbee-herdsman-converters to 14.0.86 (#6711)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-03-14 17:11:53 +01:00
Koen Kanters 06a14c5b20 Prepare for https://github.com/Koenkk/zigbee2mqtt/pull/6711 2021-03-14 17:09:43 +01:00
github-actions[bot]andKoenkk 1f09b853d2 Update zigbee-herdsman to 0.13.80 (#6710)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-14 16:55:02 +01:00
github-actions[bot]andKoenkk 953e0e7f12 Update dependencies (#6700)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-14 16:33:35 +01:00
github-actions[bot]andnurikk 7b54d188f4 Update zigbee2mqtt-frontend to 0.3.85 (#6703)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-14 16:33:50 +08:00
John Doe 39239d1416 Revert "Add additionalProperties to device schema (#6687)" (#6692)
This reverts commit eb930ac544.
2021-03-13 20:59:44 +08:00
github-actions[bot]andnurikk 036aab2e2e Update zigbee2mqtt-frontend to 0.3.84 (#6688)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-13 18:48:08 +08:00
John Doe eb930ac544 Add additionalProperties to device schema (#6687) 2021-03-13 11:22:23 +01:00
29343f8e9c Update zigbee-herdsman-converters to 14.0.85 (#6680)
* Update zigbee-herdsman-converters to 14.0.85

* Update bridge.test.js

* Update zigbeeHerdsman.js

* Update otaUpdate.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-03-13 10:28:48 +01:00
github-actions[bot]andnurikk 0a2466e55b Update zigbee2mqtt-frontend to 0.3.82 (#6682)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-13 16:40:25 +08:00
github-actions[bot]andnurikk 07c02f94da Update zigbee2mqtt-frontend to 0.3.81 (#6681)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-13 11:38:35 +08:00
github-actions[bot]andKoenkk f70e1b343d Update zigbee-herdsman to 0.13.79 (#6679)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-12 20:16:59 +01:00
Koen Kanters 26d4f3d70b Changes for https://github.com/Koenkk/zigbee2mqtt/pull/6669. 2021-03-11 20:11:34 +01:00
github-actions[bot]andKoenkk 581145eae2 Update zigbee-herdsman-converters to 14.0.84 (#6669)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-11 20:11:17 +01:00
github-actions[bot]andKoenkk 50cbc85da6 Update zigbee-herdsman to 0.13.78 (#6668)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-11 20:00:36 +01:00
df670a872e Update zigbee-herdsman-converters to 14.0.83 (#6659)
* Update zigbee-herdsman-converters to 14.0.83

* Update bridge.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-03-10 23:04:53 +01:00
github-actions[bot]andKoenkk 6163265323 Update zigbee-herdsman to 0.13.77 (#6658)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-10 22:43:47 +01:00
github-actions[bot]andKoenkk 20e60ba812 Update zigbee-herdsman-converters to 14.0.81 (#6639)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-09 20:34:58 +01:00
Koen Kanters 00c2894bb4 Reread settings on restart. https://github.com/Koenkk/zigbee2mqtt/discussions/6628 2021-03-09 19:50:05 +01:00
github-actions[bot]andKoenkk f10b0e3070 Update zigbee-herdsman-converters to 14.0.80 (#6627)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-08 19:30:33 +01:00
github-actions[bot]andnurikk ece9e03fba Update zigbee2mqtt-frontend to 0.3.80 (#6624)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-08 12:34:08 +08:00
github-actions[bot]andKoenkk 87f0408bd5 Update zigbee-herdsman-converters to 14.0.79 (#6619)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-07 17:43:30 +01:00
github-actions[bot]andKoenkk 46848cb5c9 Update dependencies (#6610)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-07 17:25:17 +01:00
John Doe 0ca834cc70 Add timer api to extensions sandbox (#6604) 2021-03-06 17:41:11 +01:00
github-actions[bot]andKoenkk 0d60ae2f58 Update zigbee-herdsman to 0.13.76 (#6605)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-06 17:40:46 +01:00
github-actions[bot]andKoenkk 2712d98871 Update zigbee-herdsman-converters to 14.0.78 (#6603)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-06 17:27:01 +01:00
Koen Kanters 377356b9c1 Fix no attribute property in configured_reportings when attribute is manufacturer specific. #6580 2021-03-06 14:51:07 +01:00
github-actions[bot]andnurikk 6fa5f75510 Update zigbee2mqtt-frontend to 0.3.79 (#6592)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-06 15:34:03 +08:00
github-actions[bot]andKoenkk 199d970947 Update zigbee-herdsman-converters to 14.0.77 (#6566)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-04 17:56:49 +01:00
Koen Kanters 42f2bd496d Merge branch 'master' into dev
# Conflicts:
#	npm-shrinkwrap.json
#	package.json
2021-03-04 17:28:52 +01:00
github-actions[bot]andKoenkk 5508b6cc60 Update zigbee-herdsman-converters to 14.0.76 (#6557)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-04 17:14:22 +01:00
github-actions[bot]andKoenkk 92a374e63c Update zigbee-herdsman to 0.13.75 (#6553)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-03 17:17:53 +01:00
Jorge Schrauwen e5a9c947aa Home Assistant does not support 'sleep' as system_mode (#6549)
But 'sleep' is a valid ZCL system_mode, so far only the Viessmann TRV supports it.
We simply drop the exposed system_mode value to not confuse homeassistent.
2021-03-03 16:59:03 +01:00
github-actions[bot]andnurikk c97fce71f7 Update zigbee2mqtt-frontend to 0.3.78 (#6546)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-03 21:25:38 +08:00
github-actions[bot]andnurikk 1a266637c5 Update zigbee2mqtt-frontend to 0.3.77 (#6545)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-03-03 21:14:55 +08:00
Koen Kanters a43d1f3917 1.18.1 2021-03-02 21:42:12 +01:00
Koen Kanters 8b9dfb3ee3 Fix not starting with CC2652RB. https://github.com/Koenkk/zigbee2mqtt/issues/6517 2021-03-02 21:42:02 +01:00
github-actions[bot]andKoenkk b9c69f96fd Update zigbee-herdsman to 0.13.74 (#6534)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-02 21:03:43 +01:00
Koen Kanters 5ed30eb005 Promote to dev 2021-03-02 20:42:24 +01:00
Koen Kanters 7e52087c73 Merge branch 'master' into dev 2021-03-02 20:41:40 +01:00
Koen Kanters 4100ebb670 Update update_check_interval in settings.schema.json. https://github.com/Koenkk/zigbee2mqtt/commit/fb2ab44e3e28a242ae12bbaf78864f470910dc62 2021-03-02 20:24:27 +01:00
Koen Kanters 52b8022173 Revert "Update update_check_interval in settings.schema.json. https://github.com/Koenkk/zigbee2mqtt/commit/fb2ab44e3e28a242ae12bbaf78864f470910dc62"
This reverts commit e552b76b04.
2021-03-02 20:24:10 +01:00
Ilya Kirov d77231b99f Added "ezsp" adapter to schema (#6532) 2021-03-02 19:41:56 +01:00
github-actions[bot]andKoenkk 1341973f07 Update zigbee-herdsman to 0.13.73 (#6533)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-02 19:41:38 +01:00
Koen Kanters e552b76b04 Update update_check_interval in settings.schema.json. https://github.com/Koenkk/zigbee2mqtt/commit/fb2ab44e3e28a242ae12bbaf78864f470910dc62 2021-03-02 19:31:21 +01:00
John Doe fb2ab44e3e Set default update_check_interval to 1 day (#6523) 2021-03-02 19:22:39 +01:00
github-actions[bot]andKoenkk 827f9cdcdf Update zigbee-herdsman-converters to 14.0.75 (#6510)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-03-01 18:58:49 +01:00
Koen Kanters 3fd66193d7 1.18.0 2021-03-01 17:22:17 +01:00
Koen Kanters 2e80a9422f Undev 2021-03-01 17:22:11 +01:00
Koen Kanters 82ccf0290f Merge remote-tracking branch 'origin/master' into dev 2021-03-01 17:21:26 +01:00
ptvoandptvoinfo 18269d65f8 Added support for 16-channels DIY devices. (#6508)
* Added support for 16-channels DIY devices.

* Fixed a typo

Co-authored-by: ptvoinfo <xagga@ya.ru>
2021-03-01 21:39:45 +08:00
github-actions[bot]andnurikk 57165e3d71 Update zigbee2mqtt-frontend to 0.3.76 (#6498)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-28 22:18:40 +08:00
github-actions[bot]andKoenkk 12c34a8ed7 Update zigbee-herdsman-converters to 14.0.74 (#6496)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-28 11:33:07 +01:00
github-actions[bot]andKoenkk 9d835ff9dc Update zigbee-herdsman to 0.13.72 (#6495)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-28 11:15:03 +01:00
github-actions[bot]andKoenkk 744dd47336 Update dependencies (#6485)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-28 11:03:45 +01:00
github-actions[bot]andnurikk fa5a7b19af Update zigbee2mqtt-frontend to 0.3.75 (#6490)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-28 13:46:51 +08:00
John Doe 4ca3aabf49 Add remove extension API (#6489)
* Add remove extension API

* Fix type
2021-02-28 13:44:54 +08:00
github-actions[bot]andnurikk 1a56874b65 Update zigbee2mqtt-frontend to 0.3.74 (#6488)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-28 11:56:37 +08:00
1ddd2ac30a Update zigbee-herdsman-converters to 14.0.73 (#6483)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-27 21:40:05 +01:00
Koen Kanters b2e28acc79 Fix test for new zhc version 2021-02-27 21:37:58 +01:00
github-actions[bot]andKoenkk 95b99a3ece Update zigbee-herdsman-converters to 14.0.72 (#6478)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-27 17:43:31 +01:00
github-actions[bot]andnurikk a8cd925c6a Update zigbee2mqtt-frontend to 0.3.73 (#6475)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-27 18:12:32 +08:00
github-actions[bot]andnurikk 1f60c1733f Update zigbee2mqtt-frontend to 0.3.72 (#6474)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-27 17:06:54 +08:00
github-actions[bot]andnurikk cd71a9d918 Update zigbee2mqtt-frontend to 0.3.70 (#6471)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-27 16:48:57 +08:00
John Doe 26326f71a6 stateChange event brodcasts complete entity state (#6473) 2021-02-27 09:46:33 +01:00
github-actions[bot]andnurikk cb7ac97f79 Update zigbee2mqtt-frontend to 0.3.66 (#6451)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-27 13:34:20 +08:00
github-actions[bot]andKoenkk efc4428a7c Update zigbee-herdsman-converters to 14.0.71 (#6463)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-26 19:34:58 +01:00
github-actions[bot]andKoenkk 212ed66139 Update zigbee-herdsman-converters to 14.0.70 (#6454)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-25 22:17:11 +01:00
github-actions[bot]andKoenkk 88a105ede9 Update zigbee-herdsman-converters to 14.0.69 (#6440)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-24 21:43:48 +01:00
github-actions[bot]andKoenkk 428c9c581c Update zigbee-herdsman-converters to 14.0.68 (#6436)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-24 18:16:26 +01:00
Jorge Schrauwen 2ed9582d6b Add meter endpoint name (#6427)
Prerequisite for https://github.com/Koenkk/zigbee-herdsman-converters/pull/2273
2021-02-24 17:14:45 +01:00
dae989bbf2 Update zigbee-herdsman-converters to 14.0.66 (#6426)
* Update zigbee-herdsman-converters to 14.0.66

* Update bridge.test.js

* Update networkMap.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-23 20:00:13 +01:00
Koen Kanters 3768504480 Fix user extensions api topic 2021-02-23 19:27:30 +01:00
github-actions[bot]andnurikk 6346e07532 Update zigbee2mqtt-frontend to 0.3.64 (#6421)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-23 21:07:46 +08:00
John Doe 2d0b18c17b Simplify user extensions api (#6420)
* Simplify user extensions api

* Change structure
2021-02-23 21:00:45 +08:00
github-actions[bot]andKoenkk 9badca362a Update zigbee-herdsman-converters to 14.0.65 (#6417)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-22 20:45:50 +01:00
declanshanaghyandKoen Kanters 7f9dc04112 Customize icons for accelerometer axes (#6355)
* Publish Docker images to Github container registry. #6326

* Customize icons for accelerometer axes

* Remove fallback on '-' for unit_of_measurement

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-22 19:37:43 +01:00
github-actions[bot]andnurikk d5b2486772 Update zigbee2mqtt-frontend to 0.3.62 (#6410)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-22 21:45:01 +08:00
John DoeandKoen Kanters 028792e5b4 Implement extension loading api (#6378)
* Implement extension loading api

* Fix frontend tests

* Implement saving and unloading extensions

* Save after loading

* Add tests

* Fix coverage

* Refactor frontent test calls

* Update controller.js

* Review fixes

* Update utils.js

* Rename list topic

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-22 21:29:58 +08:00
github-actions[bot]andKoenkk 0c011e0a97 Update zigbee-herdsman-converters to 14.0.64 (#6401)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-21 21:05:27 +01:00
Koen Kanters 049deaf590 Change +- to ≈ for OTA update message. https://github.com/Koenkk/zigbee2mqtt/issues/6397 2021-02-21 20:47:00 +01:00
github-actions[bot]andKoenkk 20def3ff37 Update zigbee-herdsman-converters to 14.0.63 (#6389)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-21 11:21:34 +01:00
github-actions[bot]andKoenkk 207e84d382 Update dependencies (#6384)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-21 10:47:49 +01:00
github-actions[bot]andKoenkk 51cec634a6 Update zigbee-herdsman-converters to 14.0.62 (#6376)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-19 20:25:28 +01:00
github-actions[bot]andnurikk a16635d475 Update zigbee2mqtt-frontend to 0.3.59 (#6368)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-19 20:15:14 +08:00
github-actions[bot]andnurikk 5953d68916 Update zigbee2mqtt-frontend to 0.3.58 (#6356)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-19 15:40:56 +08:00
github-actions[bot]andKoenkk 32388fb960 Update zigbee-herdsman-converters to 14.0.61 (#6349)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-18 20:52:45 +01:00
github-actions[bot]andnurikk 67bb215894 Update zigbee2mqtt-frontend to 0.3.57 (#6343)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-18 21:19:05 +08:00
Koen Kanters a151d765ca Publish Docker images to Github container registry. #6326 (#6329) 2021-02-17 13:04:58 +01:00
Koen Kanters 6484feecb7 Publish Docker images to Github container registry. #6326 2021-02-17 13:01:59 +01:00
github-actions[bot]andKoenkk 1914673ef7 Update zigbee-herdsman-converters to 14.0.60 (#6323)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-16 20:49:29 +01:00
Timoline f1a473d506 Updated transmit_power description (#6318)
Updated transmit_power description
2021-02-16 19:20:04 +01:00
TimolineandKoen Kanters 6f2210e792 Added syslog settings (#6312)
* Added syslog settings

not perfect yet, should be a dependencie of other setting

* fixed typo

* Update settings.schema.json

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-16 19:09:43 +01:00
github-actions[bot]andnurikk 91173a71b8 Update zigbee2mqtt-frontend to 0.3.55 (#6320)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-16 21:22:06 +08:00
github-actions[bot]andKoenkk 0b459e4075 Update zigbee-herdsman-converters to 14.0.59 (#6307)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-15 20:36:37 +01:00
8eb1a986fd Update zigbee-herdsman-converters to 14.0.58 (#6305)
* Update zigbee-herdsman-converters to 14.0.58

* Update availability.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-15 20:12:51 +01:00
Timoline 0b66e84295 Added examples for MQTT protocol version (#6303) 2021-02-15 19:36:17 +01:00
github-actions[bot]andKoenkk 8d3edf1dd5 Update zigbee-herdsman to 0.13.71 (#6301)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-15 19:30:27 +01:00
Timoline c3ad65688a changed description to minutes (#6280) 2021-02-15 17:59:58 +01:00
Timoline 6ab609cd46 added some examples for channel in schema (#6279) 2021-02-15 17:59:01 +01:00
Timoline e358ec305e Update update_check_interval to type number (#6278) 2021-02-15 17:58:39 +01:00
flatsiedatsieandKoen Kanters 9dd9f33b4a OTA updates: add update_check_interval and disable_automatic_update_check options (#6268)
* OTA privacy enhancement

Adds the option to disallow device-initiated OTA update checks.

Currently these OTA update checks can be quite frequent, and essentially mean the device is indirectly able to ping a cloud server. In the EU it's wise to handle an IP address as personal information, and therefore it might be wise to not enable OTA checking by default. Ideally a user would agree to a privacy policy that clarifies things a bit first.

* Added default settings for OTA update management

* Set update interval in minutes

* OTA update settings

* Adds both settings for OTA updates control

* Update settings.schema.json

* Update settings.js

* Update otaUpdate.js

* Update otaUpdate.test.js

* Update bridge.test.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-14 18:20:32 +01:00
github-actions[bot]andKoenkk 89a9dbba42 Update zigbee-herdsman-converters to 14.0.57 (#6275)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-14 14:30:47 +01:00
github-actions[bot]andKoenkk d1550c7511 Update zigbee-herdsman to 0.13.70 (#6269)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-14 13:54:10 +01:00
github-actions[bot]andKoenkk b34d795b77 Update dependencies (#6263)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-14 11:55:43 +01:00
Andrew OstroumovandKoen Kanters 1df52cc6e8 Prevent devices always being pinged at exactly the same time (#6133)
* Add availability lag of rand 10% from timeout

* Update availability.js

* Update utils.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-14 11:37:31 +01:00
github-actions[bot]andnurikk 1b76cd0ae5 Update zigbee2mqtt-frontend to 0.3.54 (#6265)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-14 16:00:54 +08:00
github-actions[bot]andnurikk 7f60605c09 Update zigbee2mqtt-frontend to 0.3.53 (#6256)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-13 23:51:14 +08:00
github-actions[bot]andnurikk a63b6c3eb4 Update zigbee2mqtt-frontend to 0.3.52 (#6252)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-13 17:03:17 +08:00
github-actions[bot]andnurikk 10fe61d4ff Update zigbee2mqtt-frontend to 0.3.51 (#6248)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-13 11:15:52 +08:00
Koen Kanters 1e37ba1271 Don't log no converter available for genBasic cluster. https://github.com/Koenkk/zigbee-herdsman-converters/issues/2237 2021-02-12 20:46:32 +01:00
Koen Kanters 5986152349 Expose max/min color temp to Home Assistant. https://github.com/Koenkk/zigbee-herdsman-converters/issues/2217 2021-02-12 20:38:06 +01:00
github-actions[bot]andnurikk 545caef6d5 Update zigbee2mqtt-frontend to 0.3.50 (#6246)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-12 23:58:16 +08:00
github-actions[bot]andnurikk e07f065cb5 Update zigbee2mqtt-frontend to 0.3.49 (#6244)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-12 21:47:24 +08:00
github-actions[bot]andnurikk 07f012a577 Update zigbee2mqtt-frontend to 0.3.48 (#6241)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-12 20:22:08 +08:00
github-actions[bot]andKoenkk cf333cacd8 Update zigbee-herdsman-converters to 14.0.56 (#6233)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-11 21:31:49 +01:00
Marius 6cf32b9fb1 Preparing to make org switch for the add-on (#5546) 2021-02-11 18:38:55 +01:00
github-actions[bot]andKoenkk 084d6bad1a Update zigbee-herdsman-converters to 14.0.55 (#6219)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-10 20:30:32 +01:00
github-actions[bot]andKoenkk 2b71b2a19a Update zigbee-herdsman-converters to 14.0.54 (#6216)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-10 18:41:50 +01:00
Koen Kanters b8284370d0 Bind to coordinator when setting-up reporting. https://github.com/Koenkk/zigbee2mqtt/issues/6191 2021-02-10 18:24:37 +01:00
github-actions[bot]andKoenkk c08a8ec230 Update zigbee-herdsman-converters to 14.0.53 (#6200)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-09 20:53:51 +01:00
Koen Kanters 85ed093008 Prep for next zigbee-herdsman-converters 2021-02-09 20:31:48 +01:00
github-actions[bot]andKoenkk 6c5e1cc346 Update zigbee-herdsman to 0.13.68 (#6199)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-09 18:33:00 +01:00
Crowbar ZandKoen Kanters 2515d5f816 Support Tradfri Remote buttons triggering polling (#6192)
* Support Tradfri Remote buttons triggering polling

* Update Tradfri remote test commandStepWithOnOff
Will now poll both LevelCtrl and OnOff in case light turns on

* Update the right test this time

* Updating both tests

* Update debounce test

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-09 17:20:33 +01:00
github-actions[bot]andnurikk 5a5237c39d Update zigbee2mqtt-frontend to 0.3.45 (#6198)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-09 23:36:04 +08:00
github-actions[bot]andnurikk 1d90c32719 Update zigbee2mqtt-frontend to 0.3.44 (#6195)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-09 22:27:10 +08:00
github-actions[bot]andKoenkk d2a62297df Update zigbee-herdsman to 0.13.67 (#6189)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-09 10:50:22 +01:00
github-actions[bot]andnurikk fddada4c1c Update zigbee2mqtt-frontend to 0.3.43 (#6183)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-09 10:04:57 +08:00
github-actions[bot]andKoenkk 1f29f86f49 Update zigbee-herdsman to 0.13.66 (#6173)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-08 17:33:18 +01:00
TimolineandJohn Doe 294bc2aab1 Update settings.schema.json (#6165)
* Update settings.schema.json

Added missing descriptions

* Update settings.schema.json

changed description Adapter delay

Co-authored-by: John Doe <nurikk@users.noreply.github.com>
2021-02-08 13:38:22 +08:00
Timoline 0d1782bfd0 Update settings.schema.json (#6166)
* Update settings.schema.json

Added missing settings legacy_api and homeassistant_legacy_triggers

* Update settings.schema.json

Removed legacy_api, it was already in
2021-02-08 13:34:58 +08:00
github-actions[bot]andKoenkk 1bcc5f1bab Update zigbee-herdsman-converters to 14.0.50 (#6164)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-07 17:59:42 +01:00
github-actions[bot]andKoenkk 036c884452 Update zigbee-herdsman to 0.13.65 (#6163)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-07 17:50:51 +01:00
Timoline 012d7d9d7b Added description for Frontend binding host (#6157)
Added description for Frontend binding host
2021-02-07 17:05:27 +01:00
TimolineandKoen Kanters 5d3d6fc59c Update settings.schema.json (#6159)
* Update settings.schema.json

added setting ikea_ota_use_test_url

* Update settings.schema.json

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-07 17:04:13 +01:00
Koen Kanters f992597392 bridge/request/options: fix exception on null value. 2021-02-07 14:07:27 +01:00
github-actions[bot]andKoenkk e996eb5c7c Update zigbee-herdsman-converters to 14.0.49 (#6155)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-07 13:39:32 +01:00
0e821cc7c8 Fix descriptions for cached state settings (#6152)
Co-authored-by: John Doe <nurikk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-07 12:59:37 +01:00
Timoline 9df40bd9be fixed small typo (#6149) 2021-02-07 12:45:07 +01:00
github-actions[bot]andKoenkk 385531cec7 Update dependencies (#6141)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-07 12:36:32 +01:00
Koen Kanters 687511ec0c Mark as -dev. https://github.com/Koenkk/zigbee2mqtt/pull/6145 2021-02-07 12:34:54 +01:00
github-actions[bot]andnurikk 654e66b280 Update zigbee2mqtt-frontend to 0.3.42 (#6148)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-07 15:08:50 +08:00
Timoline d43b445749 Changed some titles in the settings schema (#6147) 2021-02-07 15:04:18 +08:00
github-actions[bot]andnurikk f673840246 Update zigbee2mqtt-frontend to 0.3.41 (#6146)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-07 11:21:04 +08:00
John Doe 33b6ea86f9 Add frontend config (#6145)
* 1.17.1

* Add frontend config json schema
2021-02-07 11:19:00 +08:00
github-actions[bot]andnurikk f30d9eb276 Update zigbee2mqtt-frontend to 0.3.40 (#6144)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-07 09:53:47 +08:00
github-actions[bot]andnurikk a35ae185ba Update zigbee2mqtt-frontend to 0.3.39 (#6140)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-07 08:24:55 +08:00
69d3843794 Update zigbee-herdsman-converters to 14.0.48 (#6132)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-06 18:32:21 +01:00
Koen Kanters 0b006ae9e7 Fix tests 2021-02-06 18:29:36 +01:00
Koen Kanters b9e0293325 Send offline state to frontend. 2021-02-06 17:50:44 +01:00
github-actions[bot]andnurikk 9114bc91ed Update zigbee2mqtt-frontend to 0.3.38 (#6131)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-07 00:38:44 +08:00
Koen Kanters 5889588a8a Add zigbee2mqtt/bridge/request/options and zigbee2mqtt/bridge/request/restart (#6089)
* Initial

* Update schema

* Log changed options

* Implement zigbee2mqtt/bridge/request/restart

* Implement restart required

* Updates

* Updatos

* Set rtscts: false defaults

* Updates

* Updates
2021-02-06 23:32:20 +08:00
Koen Kanters bf2d793577 Don't log publishes to bridge/info, bridge/devices and bridge/groups to reduce log spam 2021-02-06 15:44:10 +01:00
github-actions[bot]andnurikk 0d7e471fe5 Update zigbee2mqtt-frontend to 0.3.37 (#6127)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-06 22:41:18 +08:00
github-actions[bot]andKoenkk caafca3d6d Update zigbee-herdsman to 0.13.64 (#6110)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-06 13:53:53 +01:00
github-actions[bot]andnurikk 3687863a62 Update zigbee2mqtt-frontend to 0.3.36 (#6116)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-06 13:04:37 +08:00
github-actions[bot]andnurikk e3dde51f8f Update zigbee2mqtt-frontend to 0.3.31 (#6115)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-06 10:00:06 +08:00
github-actions[bot]andnurikk 9add83acdb Update zigbee2mqtt-frontend to 0.3.30 (#6114)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-06 09:20:55 +08:00
github-actions[bot]andKoenkk 11e7aec9c6 Update zigbee-herdsman-converters to 14.0.47 (#6109)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-05 19:45:40 +01:00
github-actions[bot]andKoenkk 27111ef3fd Update zigbee-herdsman to 0.13.63 (#6108)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-05 19:37:55 +01:00
github-actions[bot]andnurikk ade6fabb1f Update zigbee2mqtt-frontend to 0.3.29 (#6103)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-05 23:24:03 +08:00
github-actions[bot]andKoenkk 62e0ef0cff Update zigbee-herdsman to 0.13.62 (#6098)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-05 13:26:29 +01:00
github-actions[bot]andnurikk 7982715502 Update zigbee2mqtt-frontend to 0.3.26 (#6094)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-05 14:38:19 +08:00
github-actions[bot]andnurikk 6c3f4713a1 Update zigbee2mqtt-frontend to 0.3.25 (#6064)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-05 13:38:42 +08:00
github-actions[bot]andKoenkk 341d1853fa Update zigbee-herdsman-converters to 14.0.46 (#6085)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-04 18:19:32 +01:00
Koen Kanters 6c3ac2cd85 Don't allow adding groups with invalid name. #6066 2021-02-04 18:01:44 +01:00
Koen Kanters 836aac46c7 Deprecate retrieve_state option 2021-02-03 20:55:05 +01:00
github-actions[bot]andKoenkk e31de39c52 Update zigbee-herdsman-converters to 14.0.45 (#6072)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-03 18:18:46 +01:00
John Doe 7c1e2c1bbf Log info after changing entity option (#6063) 2021-02-03 12:26:12 +08:00
f042b9df2c Update zigbee-herdsman-converters to 14.0.44 (#6055)
* Update zigbee-herdsman-converters to 14.0.44

* Update availability.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-02-02 22:50:22 +01:00
noned80 ed7f12eb89 Spelling correction of error message (#6056) 2021-02-02 22:44:29 +01:00
github-actions[bot]andKoenkk efd1a2e8ad Update zigbee-herdsman to 0.13.61 (#6053)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-02 20:37:30 +01:00
github-actions[bot]andKoenkk e6c71d79a7 Update zigbee-herdsman-converters to 14.0.43 (#6034)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-01 20:14:55 +01:00
github-actions[bot]andKoenkk ada49fa764 Update zigbee-herdsman to 0.13.60 (#6031)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-01 19:09:05 +01:00
Koen Kanters 50d33a202c Promote to dev 2021-02-01 18:14:39 +01:00
Koen Kanters 99274c72c2 1.17.1 2021-02-01 18:13:58 +01:00
Koen Kanters 8c88f370e6 Undev 2021-02-01 18:13:54 +01:00
Koen Kanters 7cf746aa6a Merge branch 'dev' 2021-02-01 18:13:27 +01:00
github-actions[bot]andKoenkk 504e1141f1 Update zigbee-herdsman-converters to 14.0.42 (#6029)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-02-01 18:12:43 +01:00
github-actions[bot]andnurikk 0f1aad6b98 Update zigbee2mqtt-frontend to 0.3.23 (#6017)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-02-01 11:29:46 +08:00
John Doe f1c29c9bfc Flag "readOnly": true some fields (#6016) 2021-02-01 11:03:28 +08:00
github-actions[bot]andKoenkk 3918b33e2d Update zigbee-herdsman-converters to 14.0.41 (#6006)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-31 19:50:57 +01:00
Lubomir Kaplan 9f5c68e9ec Pass logger to zigbee-herdsman controller (#5988)
* passing logger to zigbee-herdsman controller

* updated controller test for logger passing
2021-01-31 16:14:06 +01:00
github-actions[bot]andnurikk 1ce11b2ad6 Update zigbee2mqtt-frontend to 0.3.22 (#5997)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-31 19:33:26 +08:00
John Doe 236ba3951f Publish wheither device supports OTA or not (#5995) 2021-01-31 19:31:14 +08:00
github-actions[bot]andKoenkk 26450ff930 Update dependencies (#5992)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-31 12:10:12 +01:00
github-actions[bot]andKoenkk 3cfad2ac16 Update zigbee-herdsman-converters to 14.0.40 (#5987)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-30 17:31:09 +01:00
John Doe 0903f4c777 Dummy options (#5981)
* Split groups and devices schema into definition

* Dummy bridge/request/options

* Linter
2021-01-30 15:44:36 +01:00
github-actions[bot]andKoenkk 61b9ddcd60 Update zigbee-herdsman-converters to 14.0.39 (#5972)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-29 20:20:22 +01:00
Koen Kanters e769d17ea5 Improve tests 2021-01-29 20:14:08 +01:00
Koen Kanters 435a64a407 Create codeql-analysis.yml 2021-01-28 20:39:14 +01:00
Koen Kanters 2f107b6b27 Add CONTRIBUTING.md 2021-01-28 20:37:35 +01:00
Koen Kanters 833ab1a1c0 Add CODE_OF_CONDUCT.md 2021-01-28 20:37:05 +01:00
github-actions[bot]andKoenkk 45be18027c Update zigbee-herdsman-converters to 14.0.37 (#5955)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-28 20:12:09 +01:00
Koen Kanters 403de64e5e Copy LICENSE to Docker image 2021-01-28 20:09:36 +01:00
Koen Kanters de51d4c561 Docker: use node 14 2021-01-28 20:07:19 +01:00
github-actions[bot]andKoenkk 5772eb4413 Update zigbee-herdsman-converters to 14.0.36 (#5950)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-28 18:19:37 +01:00
github-actions[bot]andKoenkk 54fc4fa82b Update zigbee-herdsman-converters to 14.0.35 (#5942)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-27 20:55:36 +01:00
Koen Kanters 5cdd8eb7be Preps for new zigbee-herdsman-converters (build will fail for this commit) 2021-01-27 20:51:30 +01:00
github-actions[bot]andKoenkk 435963a8a4 Update zigbee-herdsman-converters to 14.0.34 (#5920)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-27 11:35:59 +01:00
github-actions[bot]andnurikk a038f7e334 Update zigbee2mqtt-frontend to 0.3.19 (#5915)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-26 16:18:43 +08:00
github-actions[bot]andnurikk 665a6c9bf4 Update zigbee2mqtt-frontend to 0.3.17 (#5912)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-26 13:54:32 +08:00
github-actions[bot]andKoenkk 051df6fb14 Update zigbee-herdsman-converters to 14.0.33 (#5905)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-25 20:02:42 +01:00
github-actions[bot]andKoenkk d95bbd9820 Update zigbee-herdsman to 0.13.59 (#5904)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-25 19:48:57 +01:00
github-actions[bot]andKoenkk fa33ac21f5 Update zigbee-herdsman-converters to 14.0.32 (#5903)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-25 18:16:05 +01:00
github-actions[bot]andKoenkk ee18da225b Update zigbee-herdsman-converters to 14.0.31 (#5891)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-24 20:03:03 +01:00
github-actions[bot]andKoenkk 104520b8ce Update dependencies (#5880)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-24 13:28:49 +01:00
fenduru acb0945927 Add test for using device friendly names in group config. (#5865) 2021-01-23 16:40:11 +01:00
github-actions[bot]andKoenkk 9ca483d18d Update zigbee-herdsman-converters to 14.0.30 (#5873)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-23 16:08:08 +01:00
github-actions[bot]andKoenkk 548030aa33 Update zigbee-herdsman-converters to 14.0.29 (#5870)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-23 14:11:50 +01:00
github-actions[bot]andKoenkk 8c5595894f Update zigbee-herdsman-converters to 14.0.28 (#5862)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-22 20:15:11 +01:00
Koen Kanters 6a33670296 Network scan stability improvement 2021-01-22 19:16:35 +01:00
Koen Kanters 1b32a46649 Setup reporting when binding and make report feature deprecated (#5529)
* Initial

* Updates

* Some tests

* tests

* Updates

* Move poll to bind

* Move report to legacy

* Updates

* Remove toPoll key. https://github.com/Koenkk/zigbee2mqtt/pull/5529#pullrequestreview-570285310

* Updates

* Updates

* Update bridge.test.js

* Fix tests
2021-01-22 18:56:44 +01:00
d80a84aca1 Update zigbee-herdsman-converters to 14.0.27 (#5851)
* Update zigbee-herdsman-converters to 14.0.27

* Update bridge.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-21 19:52:02 +01:00
Koen Kanters e65d660236 Remove duplicate E11-N1EA. https://github.com/Koenkk/zigbee2mqtt/issues/775#issuecomment-763999942 2021-01-21 17:39:53 +01:00
github-actions[bot]andKoenkk 4e2e04e3e7 Update zigbee-herdsman to 0.13.58 (#5837)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-20 19:33:00 +01:00
Koen Kanters 51c2a8fdb8 Make E11-N1EA pingable. https://github.com/Koenkk/zigbee2mqtt/issues/775#issuecomment-763755661 2021-01-20 19:31:29 +01:00
8fcad24adb Update zigbee-herdsman-converters to 14.0.25 (#5824)
* Update zigbee-herdsman-converters to 14.0.25

* Update bridge.test.js

* Update bridge.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-19 19:27:12 +01:00
Koen Kanters c67de5eb28 Fix nothing logged in frontend when log_level warn is set. https://github.com/Koenkk/zigbee2mqtt/issues/5812 2021-01-19 18:14:40 +01:00
Jorge Schrauwen 0d59b52479 Add missing devices options to settings.schema.json (#5823)
Looks like a few more were missing that just debounce: https://github.com/Koenkk/zigbee2mqtt.io/blob/05fc32d8e09bf4cc1bccfc4acb8f618ce7ab3a22/docs/information/configuration.md#device-specific-configuration
2021-01-19 17:39:46 +01:00
Koen Kanters d1a1035e43 Fix nothing logged when log_level set to warn. https://github.com/Koenkk/zigbee2mqtt/issues/5812 2021-01-18 18:31:47 +01:00
Koen Kanters 48767a7bcf Allow to generate panID by setting "pan_id: GENERATE". https://github.com/Koenkk/zigbee2mqtt/issues/5745 2021-01-18 18:01:10 +01:00
github-actions[bot]andnurikk 2d870bd7ea Update zigbee2mqtt-frontend to 0.3.16 (#5799)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-18 08:44:28 +08:00
github-actions[bot]andnurikk 2ef2c54702 Update zigbee2mqtt-frontend to 0.3.15 (#5788)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-17 18:57:34 +08:00
github-actions[bot]andnurikk 9a8476dc15 Update zigbee2mqtt-frontend to 0.3.14 (#5787)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-17 17:25:42 +08:00
John Doe dbf84e775e Update schema (#5786)
* Split groups and devices schema into definition

* Update settings schema
2021-01-17 17:20:50 +08:00
John Doe 0e6779db3a Republish info (#5785)
* Split groups and devices schema into definition

* Republish bridge info after device/group props change
2021-01-17 09:51:32 +01:00
github-actions[bot]andKoenkk 4a9bdf16f5 Update dependencies (#5782)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-17 09:29:41 +01:00
github-actions[bot]andKoenkk 6a24c609b6 Update zigbee-herdsman-converters to 14.0.24 (#5781)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-16 21:34:16 +01:00
github-actions[bot]andKoenkk a48a36aaf2 Update zigbee-herdsman to 0.13.57 (#5780)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-16 21:18:51 +01:00
github-actions[bot]andKoenkk e5bf3cdb34 Update zigbee-herdsman-converters to 14.0.23 (#5775)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-16 19:20:43 +01:00
xyzroe bbe4f9cd5f endpoint support for binary and numeric discovery entries (#5771)
* endpoint support for binary and numeric exposes

* endpoint support for binary and numeric exposes
2021-01-16 18:26:55 +01:00
github-actions[bot]andKoenkk 5050ca0dc0 Update zigbee-herdsman-converters to 14.0.22 (#5770)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-16 13:12:19 +01:00
John DoeandKoen Kanters d50d010b82 Publish settings json schema to bridge/info (#5754)
* Publish settings json schema to bridge/info

* Update frontend

* Please linter

* Rename configSchema -> config_schema

* Fix settings schema

* Update titles

* Updated descriptions

* Update frontend

* Update json schema titles and descriptions

* Update schema

* Update frontend

* Update npm-shrinkwrap.json

* Update package.json

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-16 12:32:15 +01:00
github-actions[bot]andKoenkk 4f777cae87 Update zigbee-herdsman to 0.13.55 (#5768)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-16 12:23:12 +01:00
github-actions[bot]andKoenkk 97827d4309 Update zigbee-herdsman-converters to 14.0.21 (#5764)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-15 20:19:46 +01:00
Koen Kanters 16cd176822 Fix group state not changing when members state changes under certain circumstances. https://github.com/Koenkk/zigbee2mqtt/issues/5725 2021-01-15 18:05:51 +01:00
github-actions[bot]andKoenkk a822165c26 Update zigbee-herdsman-converters to 14.0.20 (#5733)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-13 21:55:23 +01:00
github-actions[bot]andKoenkk bdc261ff9e Update zigbee-herdsman-converters to 14.0.19 (#5732)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-13 20:42:14 +01:00
github-actions[bot]andnurikk 9604c836fd Update zigbee2mqtt-frontend to 0.3.4 (#5731)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-14 01:05:23 +08:00
d752f0593d Update zigbee-herdsman-converters to 14.0.18 (#5723)
* Update zigbee-herdsman-converters to 14.0.18

* Update receive.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-12 21:57:05 +01:00
github-actions[bot]andKoenkk 197c80165b Update zigbee-herdsman to 0.13.54 (#5722)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-12 21:53:10 +01:00
github-actions[bot]andKoenkk 34c69c4309 Update zigbee-herdsman to 0.13.53 (#5719)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-12 21:25:48 +01:00
github-actions[bot]andKoenkk e6ec3c6c9b Update zigbee-herdsman to 0.13.52 (#5713)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-12 20:40:06 +01:00
github-actions[bot]andKoenkk f512e36b9e Update zigbee-herdsman-converters to 14.0.17 (#5702)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-11 20:10:16 +01:00
github-actions[bot]andKoenkk ca5cdd4f8b Update zigbee-herdsman to 0.13.51 (#5698)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-11 18:10:28 +01:00
github-actions[bot]andKoenkk 5943863c78 Update zigbee-herdsman-converters to 14.0.16 (#5697)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-11 18:01:58 +01:00
Koen Kanters ed76bbbdc5 Add ExtensionFrontend. https://github.com/Koenkk/zigbee2mqtt/issues/5688 2021-01-11 17:01:20 +01:00
github-actions[bot]andKoenkk 09d436fb9c Update zigbee-herdsman-converters to 14.0.15 (#5677)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-10 17:56:17 +01:00
github-actions[bot]andKoenkk 351cf41884 Update zigbee-herdsman to 0.13.50 (#5673)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-10 16:55:09 +01:00
Koen Kanters 19c54040bc Allow string values for permit_join call. https://github.com/Koenkk/zigbee2mqtt/issues/5644 2021-01-10 16:54:01 +01:00
github-actions[bot]andKoenkk 8026dde26a Update dependencies (#5663)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-10 15:14:59 +01:00
Koen Kanters 7014bb05f0 Fix tests 2021-01-09 15:17:09 +01:00
Koen Kanters 7b0eb87685 Don't allow friendly_name to start with. https://github.com/Koenkk/zigbee2mqtt/commit/d7c74ca3ad65dc8cc0366d321c5494c4f3b7a51b 2021-01-09 15:13:29 +01:00
github-actions[bot]andKoenkk 9189dd1d3d Update zigbee-herdsman-converters to 14.0.14 (#5650)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-09 15:07:23 +01:00
Koen Kanters 77a6ec09fb More friendly name checks. https://github.com/Koenkk/zigbee2mqtt/commit/d7c74ca3ad65dc8cc0366d321c5494c4f3b7a51b 2021-01-09 14:21:01 +01:00
f356be8253 Update zigbee-herdsman-converters to 14.0.13 (#5638)
* Update zigbee-herdsman-converters to 14.0.13

* Update bridge.test.js

* Update networkMap.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-08 22:30:36 +01:00
Koen Kanters 4626d557d3 Fix log level in frontend not updating after setting log level. https://github.com/Koenkk/zigbee2mqtt/issues/5635 2021-01-08 21:47:05 +01:00
github-actions[bot]andKoenkk cab93d0c72 Update zigbee-herdsman to 0.13.49 (#5637)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-08 21:01:09 +01:00
Koen Kanters d7c74ca3ad Fix not allowed friendly_names being allowed. #5618 2021-01-08 20:46:04 +01:00
Koen Kanters b2cd519e0b Allow disabling discovery of device_automation. https://github.com/Koenkk/zigbee2mqtt/issues/5597 2021-01-08 20:23:25 +01:00
github-actions[bot]andnurikk 0a56e5c3d5 Update zigbee2mqtt-frontend to 0.3.2 (#5616)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-08 07:34:49 +08:00
Koen Kanters 4fc10f0cfb Attempt to fix external converters exposes not loaded into HA discovery. https://github.com/Koenkk/zigbee2mqtt/discussions/5605 2021-01-07 19:24:48 +01:00
Koen Kanters 2942ae9f4a Fix some properties not being published when debounce is used (#5509)
* initial

* More logging. https://github.com/Koenkk/zigbee-herdsman-converters/issues/1988

* More logging

* Ignore group_optimistic

* Cleanup

* Add logging again

* We got him?

* go

* linto
2021-01-07 19:17:13 +01:00
David 2524020963 Fix availability not working for Sengled E11-N1EA bulb (#5603)
Added availability support for Sengled E11-N1EA (RGB) bulb.  

https://www.zigbee2mqtt.io/devices/E11-N1EA.html#sengled-e11-n1ea
2021-01-07 19:07:36 +01:00
Koen Kanters 2cf9657bd4 Fix disabling discovery of specific Home Assistant sensor not working. #5597 2021-01-07 18:56:39 +01:00
github-actions[bot]andKoenkk 4c95265d5e Update zigbee-herdsman-converters to 14.0.12 (#5600)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-06 19:34:00 +01:00
github-actions[bot]andKoenkk cd5246865b Update zigbee-herdsman-converters to 14.0.11 (#5583)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-05 20:56:07 +01:00
Koen Kanters 4b8500603d Prepare for next zhc release 2021-01-05 20:36:04 +01:00
Koen Kanters adfb9f0c42 Fix setting last_seen from frontend not working. #5545 2021-01-05 19:15:08 +01:00
Koen Kanters acfd938e48 HA discovery: prefer XY over HS. 2021-01-05 18:40:26 +01:00
90abc2e846 Update zigbee-herdsman-converters to 14.0.8 (#5558)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-04 21:18:37 +01:00
Koen Kanters 1be15c67cf Prepare test for next zigbee-herdsman-converters version. 2021-01-04 21:16:49 +01:00
Igor ListopadandKoen Kanters 660796a1e4 Add specifying auth_token in a different file (#5537)
* Add specifying auth_token in a different file

* Update settings.js

* Update settings.js

* Update settings.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-04 19:32:03 +01:00
github-actions[bot]andKoenkk 5336ed9d9d Update zigbee-herdsman to 0.13.48 (#5550)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-04 18:03:31 +01:00
github-actions[bot]andKoenkk 7b3beafddc Update zigbee-herdsman-converters to 14.0.6 (#5527)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-03 15:25:59 +01:00
github-actions[bot]andKoenkk 1ffbf2ca71 Update zigbee-herdsman to 0.13.47 (#5523)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-03 11:14:59 +01:00
Koen Kanters d53b63d67e Allow joining for a specific amount of time. https://github.com/nurikk/z2m-frontend/issues/202 2021-01-03 11:08:33 +01:00
github-actions[bot]andKoenkk 1298769d4d Update dependencies (#5519)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-03 10:12:27 +01:00
914819799a Update zigbee-herdsman-converters to 14.0.5 (#5505)
* Update zigbee-herdsman-converters to 14.0.5

* Update bridge.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2021-01-02 11:05:43 +01:00
github-actions[bot]andnurikk cf7156707d Update zigbee2mqtt-frontend to 0.3.1 (#5490)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2021-01-02 16:42:42 +08:00
Pedro Lamas 2dc9016f9f More HA device classes in use (#5495) 2021-01-01 22:48:07 +01:00
Koen Kanters 3a9e6ad2c3 Promote to dev 2021-01-01 12:37:57 +01:00
Koen Kanters 07cdc9d549 1.17.0 2021-01-01 12:35:53 +01:00
Koen Kanters 03eaa17800 Undev 2021-01-01 12:30:22 +01:00
github-actions[bot]andKoenkk 3d3f754433 Update zigbee-herdsman-converters to 14.0.3 (#5488)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2021-01-01 12:14:35 +01:00
f999f58fa8 Update zigbee-herdsman-converters to 14.0.2 (#5474)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-31 10:37:00 +01:00
github-actions[bot]andnurikk 89272ce300 Update zigbee2mqtt-frontend to 0.2.129 (#5476)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-31 11:56:16 +08:00
github-actions[bot]andnurikk a203b1a0c0 Update zigbee2mqtt-frontend to 0.2.127 (#5475)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-31 09:51:44 +08:00
github-actions[bot]andnurikk 92f3caa1c9 Update zigbee2mqtt-frontend to 0.2.126 (#5469)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-30 22:55:07 +08:00
Koen Kanters 016137b82b Republish devices after configuring reporting. https://github.com/Koenkk/zigbee-herdsman-converters/commit/5f99e26eda41baad0d692eec397816168808ad5d 2020-12-30 12:20:38 +01:00
github-actions[bot]andnurikk 897f5a9324 Update zigbee2mqtt-frontend to 0.2.125 (#5467)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-30 09:32:15 +08:00
github-actions[bot]andnurikk 43d963ff5d Update zigbee2mqtt-frontend to 0.2.124 (#5466)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-30 07:47:29 +08:00
github-actions[bot]andKoenkk 2d1e99f89b Update zigbee-herdsman to 0.13.46 (#5461)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-29 20:45:47 +01:00
357b9c1e72 Update zigbee-herdsman-converters to 14.0.1 (#5460)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-29 20:14:32 +01:00
Koen Kanters 3558635797 Only reconfigure reporting for Ikea bulbs on device annouce when configuredReportings is empty, this is now done in https://github.com/Koenkk/zigbee-herdsman-converters/commit/5f99e26eda41baad0d692eec397816168808ad5d 2020-12-29 20:06:10 +01:00
Koen Kanters ff59480bce Expose model_id. 2020-12-29 18:50:57 +01:00
github-actions[bot]andnurikk 0c6406e7ff Update zigbee2mqtt-frontend to 0.2.123 (#5456)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-29 22:40:45 +08:00
github-actions[bot]andnurikk 451d612f70 Update zigbee2mqtt-frontend to 0.2.122 (#5453)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-29 22:10:23 +08:00
github-actions[bot]andKoenkk 41a0cc455b Update zigbee-herdsman to 0.13.45 (#5452)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-29 21:51:55 +08:00
John Doe db8a3d85a9 Revert "Update zigbee2mqtt-frontend to 0.2.118 (#5446)" (#5447)
This reverts commit 8575470ff2.
2020-12-29 19:19:31 +08:00
github-actions[bot]andnurikk 8575470ff2 Update zigbee2mqtt-frontend to 0.2.118 (#5446)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-29 19:03:51 +08:00
Koen Kanters 332ccee44a Log succesful configured reporting. 2020-12-29 10:56:46 +01:00
Koen Kanters 0e1d683c77 Republish devices after configure 2020-12-29 10:43:06 +01:00
Koen Kanters 09c5631b4d Expose configured reportings. 2020-12-28 23:12:40 +01:00
Koen Kanters c0fa732833 Add zigbee2mqtt/bridge/request/device/configure_reporting 2020-12-28 22:57:35 +01:00
github-actions[bot]andKoenkk 155e9119c0 Update zigbee-herdsman to 0.13.44 (#5440)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-28 22:39:14 +01:00
github-actions[bot]andKoenkk 03ef80c463 Update zigbee-herdsman-converters to 14.0.0 (#5438)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-28 21:54:40 +01:00
Koen Kanters 9345fe8c99 Pass logger to configure(). https://github.com/Koenkk/zigbee2mqtt/issues/5212 2020-12-28 21:48:07 +01:00
github-actions[bot]andKoenkk 59ab1e6c22 Update zigbee-herdsman to 0.13.43 (#5435)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-28 21:43:01 +01:00
d4a2f777fa Update zigbee-herdsman-converters to 13.0.38 (#5434)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-28 21:17:35 +01:00
Koen Kanters 6c4b345a58 Fix tests for zigbee-herdsman-converters 13.0.38 2020-12-28 21:15:45 +01:00
Koen Kanters 9b7ecff5d0 Clear outdated availability topics. #5414 2020-12-28 20:19:00 +01:00
Koen Kanters 2385cf62e5 Fix debug logging not logged on frontend. #5425 2020-12-28 18:53:22 +01:00
Koen Kanters 0bc86a97e7 Refactor homeassistant.js 2020-12-28 18:31:34 +01:00
github-actions[bot]andKoenkk 029afbe13c Update zigbee-herdsman-converters to 13.0.37 (#5433)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-28 17:25:28 +01:00
7c7df1426b Update zigbee-herdsman-converters to 13.0.36 (#5429)
* Update zigbee-herdsman-converters to 13.0.36

* Update homeassistant.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-28 14:05:58 +01:00
github-actions[bot]andKoenkk b53d9d18bc Update zigbee-herdsman to 0.13.42 (#5427)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-28 13:47:56 +01:00
Jakob NoheandKoen Kanters 0b8cd232af Do not fallback to string if array can be parsed (#5420)
* Do not fallback to string if array can be parsed

This in needed, otherwise ZIGBEE2MQTT_CONFIG_ADVANCED_NETWORK_KEY can never be set to a JSON object (array).

* Update settings.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-27 19:47:00 +01:00
Koen Kanters 20e40a278e Merge branch 'master' into dev 2020-12-27 19:29:27 +01:00
Koen Kanters 50053e34f8 Test case for https://github.com/Koenkk/zigbee2mqtt/issues/5413 2020-12-27 16:34:11 +01:00
github-actions[bot]andKoenkk 45e2cf75c6 Update zigbee-herdsman-converters to 13.0.35 (#5419)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-27 16:33:41 +01:00
93741bf731 Update zigbee-herdsman-converters to 13.0.34 (#5418)
* Update zigbee-herdsman-converters to 13.0.34

* Update bridge.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-27 14:44:36 +01:00
github-actions[bot]andKoenkk f33ce378de Update dependencies (#5417)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-27 13:45:51 +01:00
99c77d2e98 Update zigbee-herdsman-converters to 13.0.33 (#5403)
* Update zigbee-herdsman-converters to 13.0.33

* Update homeassistant.test.js

* Update bridge.test.js

* Update bridge.test.js

* Update homeassistant.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-25 13:13:09 +01:00
github-actions[bot]andKoenkk a1ae5ec9e0 Update zigbee-herdsman-converters to 13.0.32 (#5400)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-24 19:57:06 +01:00
Koen Kanters d1842ab69a Update new_device_support.md 2020-12-24 18:00:59 +01:00
github-actions[bot]andKoenkk 7045c1c669 Update zigbee-herdsman-converters to 13.0.31 (#5383)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-23 17:56:22 +01:00
github-actions[bot]andKoenkk fe2034f4d2 Update zigbee-herdsman-converters to 13.0.30 (#5375)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-22 19:11:20 +01:00
Koen Kanters 83221fd7dd Lint 2020-12-22 18:40:46 +01:00
github-actions[bot]andKoenkk 8e87cbd479 Update zigbee-herdsman-converters to 13.0.29 (#5364)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-21 22:34:28 +01:00
github-actions[bot]andnurikk be6b693198 Update zigbee2mqtt-frontend to 0.2.110 (#5361)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-21 18:54:42 +08:00
fb4b014940 Update zigbee-herdsman-converters to 13.0.28 (#5360)
* Update zigbee-herdsman-converters to 13.0.28

* Update otaUpdate.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-20 21:55:39 +01:00
Koen Kanters 5e226efe9d Add water to endpoint names. https://github.com/Koenkk/zigbee2mqtt/issues/5357 2020-12-20 21:40:23 +01:00
github-actions[bot]andKoenkk c174163e8e Update zigbee-herdsman-converters to 13.0.27 (#5354)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-20 10:36:29 +01:00
github-actions[bot]andKoenkk 8cc8e84afe Update dependencies (#5353)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-20 09:30:08 +01:00
github-actions[bot]andKoenkk 8e3dd2e666 Update zigbee-herdsman-converters to 13.0.25 (#5342)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-18 20:35:28 +01:00
github-actions[bot]andnurikk fdbd947451 Update zigbee2mqtt-frontend to 0.2.108 (#5337)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-18 11:56:01 +08:00
Rafael Xavier de Souza 90ee76c061 README: Update Zigbee clusters link (#5315) 2020-12-17 13:43:38 +01:00
github-actions[bot]andKoenkk eba8849d49 Update zigbee-herdsman-converters to 13.0.24 (#5317)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-16 08:43:35 +01:00
github-actions[bot]andKoenkk 38aaa9a5ab Update zigbee-herdsman-converters to 13.0.23 (#5310)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-15 19:15:25 +01:00
github-actions[bot]andKoenkk 619846002e Update zigbee-herdsman-converters to 13.0.22 (#5304)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-14 20:34:42 +01:00
github-actions[bot]andKoenkk 2468d61414 Update zigbee-herdsman-converters to 13.0.21 (#5294)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-13 21:14:23 +01:00
6b50f4074d Update zigbee-herdsman-converters to 13.0.20 (#5290)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-13 18:35:00 +01:00
Koen Kanters 9abcaddaba Fix tests 2020-12-13 18:29:08 +01:00
Koen Kanters 026f1bfd1c Fix no devices logged when publishing empty message to zigbee2mqtt/bridge/config/devices. #5289 2020-12-13 18:12:11 +01:00
github-actions[bot]andKoenkk bc4c74d5b6 Update dependencies (#5282)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-13 17:44:33 +01:00
dd68d1d2be Update zigbee-herdsman to 0.13.41 (#5270)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-11 20:20:16 +01:00
github-actions[bot]andKoenkk 2b64a476c9 Update zigbee-herdsman-converters to 13.0.19 (#5269)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-11 20:19:37 +01:00
e0fa6814a5 Update zigbee-herdsman-converters to 13.0.18 (#5253)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-11 08:31:50 +01:00
github-actions[bot]andnurikk 1f679213b5 Update zigbee2mqtt-frontend to 0.2.107 (#5260)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-11 09:10:14 +08:00
Hacker-CB d0132a4494 zStackEraseAllNvMem.js: fix osal/not osal items for ZStack 3.x (#5246) 2020-12-10 15:43:44 +01:00
github-actions[bot]andnurikk 4078f2da02 Update zigbee2mqtt-frontend to 0.2.106 (#5245)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-10 15:26:17 +08:00
github-actions[bot]andKoenkk b6c4c2d73c Update zigbee-herdsman-converters to 13.0.17 (#5242)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-09 19:51:41 +01:00
Koen Kanters ab3fd769d5 Allow to use IKEA TRADFRI OTA test server. https://github.com/Koenkk/zigbee2mqtt/issues/2921 2020-12-09 19:51:16 +01:00
github-actions[bot]andKoenkk c29ffcf39e Update zigbee-herdsman-converters to 13.0.16 (#5240)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-09 19:08:22 +01:00
github-actions[bot]andKoenkk ae4ea1120e Update zigbee-herdsman to 0.13.40 (#5239)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-09 18:35:30 +01:00
github-actions[bot]andnurikk 7ca8535714 Update zigbee2mqtt-frontend to 0.2.105 (#5235)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-09 20:27:54 +08:00
github-actions[bot]andnurikk 293c32d465 Update zigbee2mqtt-frontend to 0.2.104 (#5232)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-09 16:47:47 +08:00
github-actions[bot]andKoenkk 9b1e20f100 Update zigbee-herdsman-converters to 13.0.15 (#5228)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-08 20:24:26 +01:00
Koen Kanters 05142044cb Update Github discussions link 2020-12-08 20:13:03 +01:00
Koen Kanters fd7d39ca77 Add Github discussions 2020-12-08 20:12:14 +01:00
Koen Kanters 2134966f6e Home Assistant: separate discovered name by space instead of _ when friendly_name has no _. #5226 2020-12-08 19:41:34 +01:00
Koen Kanters c78206b9ef Support Home Assistant discovery for composite. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1873 2020-12-08 19:01:59 +01:00
John Doe 743c701ac5 Fix disabling HA discovery after device was discovered (#5200) 2020-12-08 16:45:31 +01:00
github-actions[bot]andKoenkk 3f2eec85b2 Update zigbee-herdsman-converters to 13.0.14 (#5219)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-07 19:34:06 +01:00
github-actions[bot]andKoenkk 92b942e4f2 Update zigbee-herdsman-converters to 13.0.13 (#5209)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-06 20:49:03 +01:00
github-actions[bot]andKoenkk 94c76b591d Update dependencies (#5205)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-06 19:43:45 +01:00
47d26c8887 Update zigbee-herdsman-converters to 13.0.12 (#5197)
* Update zigbee-herdsman-converters to 13.0.12

* Update homeassistant.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-12-04 16:58:33 +01:00
Koen Kanters 81704f1807 Fix setting brightness via "brightness_[ENDPOINT]" not working. #5186 2020-12-04 16:41:06 +01:00
github-actions[bot]andKoenkk 4bcdd22e28 Update zigbee-herdsman-converters to 13.0.11 (#5187)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-03 21:56:40 +01:00
github-actions[bot]andKoenkk be61249d04 Update zigbee-herdsman to 0.13.39 (#5184)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-03 20:51:17 +01:00
github-actions[bot]andKoenkk a5505f7fe2 Update zigbee-herdsman to 0.13.38 (#5174)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-02 22:23:34 +01:00
github-actions[bot]andKoenkk ee2032f3aa Update zigbee-herdsman-converters to 13.0.10 (#5173)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-02 22:18:34 +01:00
Koen Kanters 9ff232fbb2 Enable new api by default. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-12-02 20:38:48 +01:00
github-actions[bot]andKoenkk 1c634dde60 Update zigbee-herdsman-converters to 13.0.9 (#5171)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-02 19:50:46 +01:00
John Doe dba9b4d931 Fix network map request failing when device has no exposes. (#5161)
* Fix map request if external converter doesn't have exposes attribute

* Remove dead code
2020-12-02 19:25:56 +01:00
github-actions[bot]andKoenkk 0e648dcebd Update zigbee-herdsman-converters to 13.0.8 (#5157)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-12-01 22:57:02 +01:00
Koen Kanters 9da405a6e5 Promote to dev 2020-12-01 19:00:16 +01:00
Koen Kanters 04c15f7fe8 1.16.2 2020-12-01 18:57:53 +01:00
Koen Kanters 4ac8d0df95 Undev 2020-12-01 18:57:33 +01:00
github-actions[bot]andnurikk e7bb0c3def Update zigbee2mqtt-frontend to 0.2.100 (#5145)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-12-01 06:47:48 +08:00
github-actions[bot]andKoenkk 15d04eda7c Update zigbee-herdsman-converters to 13.0.7 (#5143)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-30 19:46:01 +01:00
Pedro Lamas 8b508971db Poll lamps with Philips, Atmel, Gledopto, Mueller-Licht manufacturer codes (#5139)
* Poll lamps with Philips or Atmel manufacturer code

* Fixes incorrect test

Following up on https://github.com/Koenkk/zigbee2mqtt/pull/2122#discussion_r532618336

* Adds GLEDOPTO_CO_LTD and MUELLER_LICHT_INT to lamp polling
2020-11-30 19:21:17 +01:00
github-actions[bot]andKoenkk b1b134fbf0 Update zigbee-herdsman to 0.13.37 (#5134)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-30 12:21:30 +01:00
github-actions[bot]andnurikk 3cbed1dcd2 Update zigbee2mqtt-frontend to 0.2.98 (#5129)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-30 13:38:39 +08:00
github-actions[bot]andKoenkk bda3548cd2 Update zigbee-herdsman-converters to 13.0.6 (#5126)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-29 17:38:13 +01:00
github-actions[bot]andKoenkk 200b099de1 Update dependencies (#5118)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-29 17:10:49 +01:00
github-actions[bot]andnurikk b8f5e67bee Update zigbee2mqtt-frontend to 0.2.97 (#5124)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-29 21:57:25 +08:00
github-actions[bot]andnurikk 9238748978 Update zigbee2mqtt-frontend to 0.2.96 (#5122)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-29 19:29:38 +08:00
github-actions[bot]andnurikk 9e0ea50da2 Update zigbee2mqtt-frontend to 0.2.95 (#5112)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-28 22:04:46 +08:00
github-actions[bot]andKoenkk e0c2d69244 Update zigbee-herdsman to 0.13.36 (#5111)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-28 14:53:01 +01:00
github-actions[bot]andKoenkk 26841f53aa Update zigbee-herdsman-converters to 13.0.5 (#5099)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-27 17:51:23 +01:00
Koen Kanters 6548250eb4 Allow read-only devices/groups files by allowing to specify devices/groups in multiple files. #2970 2020-11-27 17:32:32 +01:00
ab8035d6bb Update zigbee-herdsman-converters to 13.0.4 (#5095)
* Update zigbee-herdsman-converters to 13.0.4

* Update homeassistant.js

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-26 20:12:09 +01:00
github-actions[bot]andKoenkk 99207358d5 Update zigbee-herdsman to 0.13.35 (#5094)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-26 19:55:34 +01:00
github-actions[bot]andnurikk 7b98a00a24 Update zigbee2mqtt-frontend to 0.2.91 (#5088)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-26 19:54:56 +01:00
Koen Kanters 749e6789b8 Merge remote-tracking branch 'origin/master' into dev 2020-11-26 16:35:57 +01:00
John Doe 68f243221f Add auth to frontend and remove development server (#5079)
* Add frontend authentification

* Delete auth_token from bridge/info
2020-11-25 16:28:02 +01:00
github-actions[bot]andnurikk 4b1b1a4c3b Update zigbee2mqtt-frontend to 0.2.94 (#5080)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-25 13:36:36 +08:00
github-actions[bot]andKoenkk 9ead1a248e Update zigbee-herdsman-converters to 13.0.3 (#5078)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-24 19:34:44 +01:00
github-actions[bot]andKoenkk b5f62f15c7 Update zigbee-herdsman to 0.13.34 (#5075)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-24 16:34:47 +01:00
Marius cb9699e12a Automatic edge build trigger for zigbee2mqtt org (#5068)
Automatic edge build trigger for zigbee2mqtt/hassio-zigbee2mqtt
2020-11-24 09:59:36 +01:00
github-actions[bot]andKoenkk 9b79620bde Update zigbee-herdsman-converters to 13.0.2 (#5063)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-23 19:17:39 +01:00
481cdefafc Add host bind option for frontend (#5014)
* Added IP address bind to HTTP frontend listener

* Changed ip to host in configuration and code

Co-authored-by: romanius <me@romanius.me>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-23 19:09:47 +01:00
Koen Kanters 9ee35f6933 Home Assistant: don't include object_id in name if same as type (e.g. light.bulb_light -> light.bulb). #5054 2020-11-23 19:01:16 +01:00
a5c2c483ad Update zigbee-herdsman-converters to 13.0.1 (#5058)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-22 21:12:09 +01:00
github-actions[bot]andKoenkk 2fa70fea4d Update zigbee-herdsman to 0.13.31 (#5057)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-22 21:08:53 +01:00
github-actions[bot]andKoenkk 554f44e361 Update zigbee-herdsman-converters to 13.0.0 (#5052)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-22 13:00:31 +01:00
github-actions[bot]andnurikk 33a0a6a651 Update zigbee2mqtt-frontend to 0.2.93 (#5049)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-22 12:55:18 +01:00
Koen Kanters 982e918a50 Don't use supports anymore and prepare for next zigbee-herdsman-converters. 2020-11-22 12:54:19 +01:00
github-actions[bot]andKoenkk ebad3d673c Update dependencies (#5047)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-22 12:38:49 +01:00
github-actions[bot]andnurikk aa6554c1b7 Update zigbee2mqtt-frontend to 0.2.92 (#5046)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2020-11-22 07:16:26 +08:00
Koen Kanters fc19f2e903 Don't pass messages from coordinator to extensions. https://github.com/Koenkk/zigbee2mqtt/issues/5028 2020-11-21 16:20:48 +01:00
John Doe c1f7ce7389 Implement cli version of z2m (#5034) 2020-11-21 16:02:49 +01:00
John Doe 5f7553f624 Delete settings.json (#5033) 2020-11-21 11:42:38 +08:00
github-actions[bot]andKoenkk 7a774ef3ed Update zigbee-herdsman to 0.13.30 (#5030)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2020-11-20 17:57:56 +01:00
John Doe 153b82ca77 Fix loading external convertersThis fixes Error: Cannot find module 'zigbee-herdsman-converters'Caused by requiring converter from folder which is located outside z2m sources folder (ZIGBEE2MQTT_DATA) (#5027) 2020-11-20 22:22:08 +08:00
John Doe 4978d09eb1 Update peter-evans/create-pull-request to v3 (#5025) 2020-11-20 06:15:26 +08:00
John Doe 350ec1776e Update update_frontend.yml (#5021) 2020-11-20 06:01:19 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 8d01a20d6f Update zigbee2mqtt-frontend to 0.2.88 (#5020)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-20 05:44:43 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 1e9553fadc Update zigbee-herdsman-converters to 12.0.235 (#5008)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-18 19:09:00 +01:00
Koen Kanters 49f37acd18 Add adapter_delay option. https://github.com/Koenkk/zigbee2mqtt/issues/4884 2020-11-18 18:46:13 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> bce2877641 Update zigbee2mqtt-frontend to 0.2.85 (#5001)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-17 09:09:17 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
02a945d84b Update zigbee-herdsman-converters to 12.0.234 (#4998)
* Update zigbee-herdsman-converters to 12.0.234

* Update bridge.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-16 19:00:55 +01:00
Hacker-CB 1eaf14a861 Added ZStack NVMEM eraser (Erase all NVMEM items) (#4974)
* Added ZStack NVMMEM eraser script

* typo fix

* Compact switch/case

* Added process.exit(0)
2020-11-16 18:56:34 +01:00
Chris Nesbitt-SmithandKoen Kanters aabb88fbf4 Add force_disable_retain option (#4948)
* support configurable retain on mqtt settings since some servers throw errors and drop the connections if you try (e.g. aws iot)

* Revert "support configurable retain on mqtt settings since some servers throw errors and drop the connections if you try (e.g. aws iot)"

This reverts commit 40d3a9c0bc84c83d2b167e2e3c3a06ca6df80f47.

* support configurable retain on mqtt settings

* support subscribing to the whole base prefix

* Update mqtt.js

* Fixes

* Fixes

* Fix tests

* Updates

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-16 17:27:49 +01:00
Koen Kanters 9c8323326d Greatly reduce amount of subscribed topics. #4948 2020-11-16 17:03:22 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> da3b3b565f Update zigbee2mqtt-frontend to 0.2.84 (#4995)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-16 13:36:03 +08:00
Koen Kanters c1e5c75473 Fix bridge/state online not send after reconnect. https://github.com/Koenkk/zigbee2mqtt/issues/4854 2020-11-15 13:22:29 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6c22f285b4 Update dependencies (#4986)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-15 13:08:53 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 4c9dd749b9 Update zigbee2mqtt-frontend to 0.2.83 (#4988)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-15 11:59:09 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 918064feb3 Update zigbee2mqtt-frontend to 0.2.81 (#4987)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-15 10:01:03 +08:00
William SuttonandKoen Kanters 1c3ad9da72 Log zigbee-herdsman version on startup (#4930)
* add getZigbeeHerdsmanVersion Function

Allow current zigbee-herdsman version to be exposed to controller for logging and to startup output.

* Update utils.test.js

Add tests for getZigbeeHerdsmanVersion() function

* Update utils.js

Added getZigbeeHerdsman to module exports

* Update utils.js

Fixed path because I'm dumb.

* Update utils.test.js

Apparently version numbers are important when they're different.

* Update zigbee.js

Added actual display of herdsman version output.

* Update utils.js

Remove git checking in getZigbeeHerdsmanVersion()

* Update utils.test.js

Remove commitHash from getZigbeeHerdsmanVersion test

* Update utils.js

Remove commitHash from getZigbeeHerdsmanVersion

* Update utils.js

* Update utils.test.js

* Update utils.js

Try removing less code this time.

* Update utils.test.js

* Update zigbee.js

* Update utils.js

* Update utils.js

* Update utils.test.js

* Update utils.js

* Update utils.test.js

* Update utils.js

* Update utils.js

* Update zigbee.js

* Update utils.js

Generalize getZigbeeHerdsmanVersion() to getDependVersion(), so any node_module dependency can be checked

* Update zigbee.js

* Update utils.test.js

* Update utils.js

* Update zigbee.js

* Update utils.test.js

* Update zigbee.js

* Update zigbee.js

* Update zigbee.js

* Update zigbee.js

* Update zigbee.js

* Update utils.js

* Update zigbee.js

* Update utils.test.js

* Update zigbee.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-14 17:25:22 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 033863925a Update zigbee2mqtt-frontend to 0.2.80 (#4981)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-14 22:40:16 +08:00
Koen Kanters b5436d4b93 Fix devices marked unavailable in Home Assistant after restart. https://github.com/Koenkk/zigbee2mqtt/issues/4912 2020-11-13 19:45:27 +01:00
Koen Kanters cbf353e387 Fix linkquality N/A when refreshing frontend. https://github.com/Koenkk/zigbee2mqtt/issues/4942 2020-11-13 17:29:23 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ca33e228e6 Update zigbee2mqtt-frontend to 0.2.79 (#4966)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-13 05:08:22 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 97215c9072 Update zigbee2mqtt-frontend to 0.2.78 (#4962)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-12 21:24:56 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> dd582a3f7e Update zigbee2mqtt-frontend to 0.2.77 (#4961)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-12 20:47:32 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 8034ea272c Update zigbee-herdsman to 0.13.29 (#4955)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-12 11:11:49 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> e6124c2631 Update zigbee2mqtt-frontend to 0.2.76 (#4957)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-12 16:38:40 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 35813ff951 Update zigbee2mqtt-frontend to 0.2.75 (#4953)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-12 12:20:47 +08:00
Nonsense112andKoen Kanters 1ff4be4600 Fix state.json not pretty printed (#4943)
* state.json format

Since 9774031 the state.json file is not formatted anymore, it's just 1 line.

* Update state.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-11 18:36:15 +01:00
Drzony 7305960d53 Display manufacturer name for unsupported devices (#4938)
* Display manufacturer name for unsupported devices

* fixup! Display manufacturer name for unsupported devices
2020-11-11 18:27:20 +01:00
Kamil Trzciński d5d2b68e67 Expose position for compatible thermostats (#4936)
This exposes an absolute position.
2020-11-11 18:22:37 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 25b080a0f1 Update zigbee-herdsman to 0.13.28 (#4946)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-11 18:12:17 +01:00
Koen Kanters f8943011d4 Fix unbind for default_bind_group (901) not working from frontend. https://github.com/Koenkk/zigbee2mqtt/issues/4901 2020-11-11 18:11:18 +01:00
Koen Kanters 21b8e01149 Fix set/get with property including endpoint name having _ not working. 2020-11-11 17:11:54 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ee50fb40f2 Update zigbee2mqtt-frontend to 0.2.74 (#4935)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-11 18:44:28 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 3c218305fa Update zigbee2mqtt-frontend to 0.2.72 (#4932)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-11 16:54:15 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> f31961982d Update zigbee2mqtt-frontend to 0.2.71 (#4928)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-11 13:08:21 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
8c20fa5d83 Update zigbee-herdsman-converters to 12.0.233 (#4924)
* Update zigbee-herdsman-converters to 12.0.233

* Update publish.test.js

* Update publish.test.js

* Update publish.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-10 21:40:15 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6ef08e855c Update zigbee-herdsman to 0.13.27 (#4923)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-10 21:26:51 +01:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
431c7f7327 Update zigbee-herdsman-converters to 12.0.232 (#4913)
* Update zigbee-herdsman-converters to 12.0.232

* Update homeassistant.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-09 17:46:02 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ab7d507806 Update zigbee2mqtt-frontend to 0.2.69 (#4906)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-08 21:59:06 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
b1f129c6e8 Update zigbee-herdsman-converters to 12.0.231 (#4905)
* Update zigbee-herdsman-converters to 12.0.231

* Update homeassistant.js

* Update bridge.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-08 14:45:56 +01:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
5224f0f372 Update zigbee-herdsman-converters to 12.0.230 (#4896)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-08 13:24:11 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 30cd101adf Update dependencies (#4900)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-08 13:19:04 +01:00
Koen Kanters f99257ae83 Home Assistant: use device_class presence for presence binary sensor. 2020-11-07 19:16:16 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 0c6d4a0f05 Update zigbee-herdsman-converters to 12.0.229 (#4885)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-06 19:28:42 +01:00
Koen Kanters 752bb6c4d1 Merge branch 'master' into dev 2020-11-05 18:07:57 +01:00
Koen Kanters 6b32f30654 1.16.1 2020-11-05 18:02:13 +01:00
Koen Kanters ddddd88ef6 Downgrade mqtt version to 4.2.1. https://github.com/danielwelch/hassio-zigbee2mqtt/issues/460 2020-11-05 18:00:14 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 40619a5a53 Update zigbee-herdsman-converters to 12.0.228 (#4877)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-04 22:37:12 +01:00
Koen Kanters c27e66b618 Changes for exposes. 2020-11-04 22:33:00 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 3c2eab00d0 Update zigbee-herdsman-converters to 12.0.227 (#4875)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-04 18:18:47 +01:00
Koen Kanters dc89b92e2a Mark node 15 as supported. https://github.com/Koenkk/zigbee2mqtt/issues/4867 2020-11-04 17:39:09 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 828b4b3e4e Update zigbee-herdsman-converters to 12.0.226 (#4863)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-03 18:19:34 +01:00
Koen Kanters bd7d0be07a Clear device state when device leaves network. https://github.com/Koenkk/zigbee2mqtt/issues/4485 2020-11-02 18:27:06 +01:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
2ee3b5f12b Update zigbee-herdsman-converters to 12.0.225 (#4850)
* Update zigbee-herdsman-converters to 12.0.225

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-02 18:00:58 +01:00
Jan 195d56d4ef Enhanced MQTT logging when connecting (#4843)
* enhanced logging

* reduced loglevel
2020-11-02 18:00:02 +01:00
Koen Kanters ca53013661 Dev 2020-11-01 12:59:06 +01:00
Koen Kanters 9ed84e130f 1.16.0 2020-11-01 12:58:35 +01:00
Koen Kanters 47cd482461 Undev 2020-11-01 12:58:31 +01:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
4fb8d4820f Update zigbee-herdsman-converters to 12.0.224 (#4833)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-11-01 11:05:20 +01:00
Koen Kanters a09bb3bc00 Home Assistant: support multiendpoint for enum sensor 2020-11-01 11:02:35 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 4d3e6eb11f Update zigbee-herdsman to 0.13.26 (#4834)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-01 10:52:41 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 606f7f44cc Update dependencies (#4830)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-01 10:35:22 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 1933b0f29d Update zigbee2mqtt-frontend to 0.2.68 (#4828)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-11-01 07:21:51 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 98d49a77ed Update zigbee2mqtt-frontend to 0.2.67 (#4826)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-31 21:21:06 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 7cead8cb68 Update zigbee2mqtt-frontend to 0.2.66 (#4825)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-31 18:35:18 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 487cc20129 Update zigbee2mqtt-frontend to 0.2.65 (#4823)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-31 14:39:36 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 09ae27503e Update zigbee2mqtt-frontend to 0.2.64 (#4822)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-31 10:20:35 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
e1b5a105dd Update zigbee-herdsman-converters to 12.0.223 (#4820)
* Update zigbee-herdsman-converters to 12.0.223

* Update homeassistant.js

* Update bridge.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-30 23:39:26 +01:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
79275f9a4c Update zigbee-herdsman-converters to 12.0.222 (#4816)
* Update zigbee-herdsman-converters to 12.0.222

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-29 21:43:47 +01:00
Koen Kanters aac7cb1ff6 Fix brightness or state not read when reading state and brightness. https://github.com/Koenkk/zigbee2mqtt/issues/4803 2020-10-29 18:03:16 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d78610eecf Update zigbee2mqtt-frontend to 0.2.63 (#4810)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-29 13:41:04 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6880dd786f Update zigbee2mqtt-frontend to 0.2.62 (#4808)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-29 10:14:02 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> a62f8e17ca Update zigbee2mqtt-frontend to 0.2.61 (#4788)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-29 07:43:38 +08:00
Emil FlachandEmil Flach 084fccc53d Partial fix for #4571, changed current_heating_setpoint for occupied_heating_setpoint (#4784)
Co-authored-by: Emil Flach <emil.flach@skopei.com>
2020-10-28 17:54:31 +01:00
Drzony 5d643bac8e Home Assistant fixes for Saswell TRV (#4800)
* Home Assistant fixes for Saswell TRV

* fixup! Home Assistant fixes for Saswell TRV
2020-10-28 17:49:44 +01:00
Hacker-CB 82f3d7d9bb update.sh: add checking if data-backup exists (#4793) 2020-10-28 10:45:49 +01:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
697955997a Update zigbee-herdsman-converters to 12.0.221 (#4796)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-27 21:57:35 +01:00
Koen Kanters 9a53399a8c Changes for zigbee-herdsman-converters 12.0.221 2020-10-27 21:50:55 +01:00
Koen Kanters b2049b449b Home Assistant discovery: use availability instead of availability_topic. https://github.com/Koenkk/zigbee2mqtt/issues/775 2020-10-27 21:49:44 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> a2992ab144 Update zigbee2mqtt-frontend to 0.2.50 (#4787)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-27 05:52:29 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
21fcfb0b17 Update zigbee-herdsman-converters to 12.0.220 (#4782)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-26 17:34:46 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> e449b772cc Update zigbee-herdsman to 0.13.24 (#4781)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-26 17:31:28 +01:00
Koen Kanters 922f828696 Allow binary exposes not in lookup. 2020-10-26 17:25:41 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> fee631080e Update zigbee2mqtt-frontend to 0.2.48 (#4777)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-26 07:25:59 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 22681be3c7 Update dependencies (#4766)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-25 09:58:46 +01:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 7b0498aab0 Update zigbee2mqtt-frontend to 0.2.45 (#4770)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-25 16:25:37 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> c9e030bb19 Update zigbee2mqtt-frontend to 0.2.43 (#4768)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-25 13:20:12 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> c702badd98 Update zigbee2mqtt-frontend to 0.2.40 (#4767)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-25 10:54:01 +08:00
Koen Kanters 63044421fd Get linkquality from herdsman instead of mesage. https://github.com/Koenkk/zigbee2mqtt/issues/4758 2020-10-24 17:15:46 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 8895c14f42 Update zigbee-herdsman to 0.13.23 (#4762)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-24 17:13:26 +02:00
Koen Kanters ddbf936102 Mark ZIGBEE2MQTT_CONFIG as deprecated. https://github.com/Koenkk/zigbee2mqtt/issues/4697 2020-10-24 16:20:48 +02:00
Koen Kanters 70a72dd32a Ignore yaml configuration files in data. https://github.com/Koenkk/zigbee2mqtt/issues/4697 2020-10-24 15:58:49 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
b13d18fa9a Update zigbee-herdsman-converters to 12.0.219 (#4745)
* Update zigbee-herdsman-converters to 12.0.219

* Update homeassistant.js

* Update bridge.test.js

* Update package.json

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-24 14:35:21 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> fcf10680f4 Update zigbee-herdsman to 0.13.21 (#4761)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-24 14:29:57 +02:00
Jan bd91b704b7 Added manual mode for GS361A-H04 (#4755) 2020-10-24 09:58:45 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> bd149af508 Update zigbee-herdsman to 0.13.20 (#4753)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-23 19:26:00 +02:00
mr G1K aa9ba03228 adapter zigate (#4737) 2020-10-23 19:13:33 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 3cbe7e3f39 Update zigbee2mqtt-frontend to 0.2.39 (#4749)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-23 08:21:04 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 040f612cd5 Update zigbee-herdsman to 0.13.19 (#4740)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-22 16:11:52 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 851aef3b2d Update zigbee2mqtt-frontend to 0.2.36 (#4732)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-21 08:54:18 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
6e74cb571f Update zigbee-herdsman-converters to 12.0.217 (#4728)
* Update zigbee-herdsman-converters to 12.0.217

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-20 20:10:30 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 466e9636a5 Update zigbee2mqtt-frontend to 0.2.35 (#4724)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-20 08:16:24 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
099aa26c6f Update zigbee-herdsman-converters to 12.0.216 (#4723)
* Update zigbee-herdsman-converters to 12.0.216

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-19 19:06:49 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
d73aea8ede Update zigbee-herdsman-converters to 12.0.215 (#4721)
* Update zigbee-herdsman-converters to 12.0.215

* Update homeassistant.js

* Update publish.js

* Update bridge.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-19 16:48:09 +02:00
Koen Kanters 5134f0b689 Fix 0x0000000000000000 in networkmap. 2020-10-19 16:38:53 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b9662ed866 Update zigbee2mqtt-frontend to 0.2.33 (#4715)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-19 09:33:36 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 3de953aa2b Update zigbee2mqtt-frontend to 0.2.32 (#4714)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-19 08:13:59 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
09fbed6c75 Update zigbee-herdsman-converters to 12.0.214 (#4713)
* Update zigbee-herdsman-converters to 12.0.214

* Update bridge.test.js

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-18 21:51:32 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> a9106924c7 Update dependencies (#4702)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-18 17:11:00 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
9ac660bc22 Update zigbee-herdsman-converters to 12.0.213 (#4696)
* Update zigbee-herdsman-converters to 12.0.213

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-17 16:58:27 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 87cabc29d4 Update zigbee-herdsman to 0.13.18 (#4695)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-17 16:32:01 +02:00
Utyf a5c9fb2940 Add unit_of_measurement for DIYRuZ_Geiger. (#4689) 2020-10-17 16:17:36 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6837cfa2fc Update zigbee-herdsman-converters to 12.0.212 (#4685)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-16 18:40:46 +02:00
949a16eba0 Support JAVIS lock and TS0601 roller blind motor (#4652)
* Added support for Zemismart garage opener, Larkey dimmer & curtain switch

* support JAVIS lock

* support roller blind motor

* fix test coverage

* fix coding style

* update JAVIS lock name

* Update homeassistant.js

Co-authored-by: ChinhND <dinhchinh@gmail.com>
Co-authored-by: unknown <dungnguyen98nd@gmail.com>
Co-authored-by: TheEnd98 <49032426+TheEnd98@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-16 18:20:53 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 61e449430b Update zigbee-herdsman to 0.13.17 (#4684)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-16 17:33:13 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 9e4e8acdb0 Update zigbee-herdsman to 0.13.16 (#4675)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-15 19:22:22 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
84e725d5ce Update zigbee-herdsman-converters to 12.0.211 (#4667)
* Update zigbee-herdsman-converters to 12.0.211

* Update publish.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-14 22:18:51 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
8319cdbd61 Update zigbee-herdsman-converters to 12.0.210 (#4659)
* Update zigbee-herdsman-converters to 12.0.210

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-14 08:59:14 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 467be5410c Update zigbee2mqtt-frontend to 0.2.31 (#4658)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-14 06:29:33 +08:00
Marco MassarottoandKoen Kanters e63a2ac7f6 Allow redefine autodiscovery type (#4647)
* allow to redefine entity type and id in homeassistant autodiscovery

* Update homeassistant.test.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-13 20:33:48 +02:00
insipiensandKoen Kanters 24188a3eea add saswell TRV (#4644)
* add saswell TRV

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-12 17:30:36 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
c2f28d4ed6 Update zigbee-herdsman-converters to 12.0.209 (#4646)
* Update zigbee-herdsman-converters to 12.0.209

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-12 17:22:53 +02:00
Koen Kanters fa5ac2902f Update dumpHomeAssistantMapping.js 2020-10-12 17:20:27 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ebdf4bb2e2 Update zigbee2mqtt-frontend to 0.2.29 (#4645)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-12 07:13:33 +08:00
Koen Kanters 73bc34f419 Fix frontend not loading after update. #4266 2020-10-11 16:17:52 +02:00
Koen Kanters 9098bb1e06 Add missing test 2020-10-11 15:12:07 +02:00
Koen Kanters 8202a10837 Permit joining on specific device. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-10-11 15:05:21 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 2aa652f6e9 Update dependencies (#4636)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-11 14:01:41 +02:00
Koen Kanters 983340f44c Fix BHT-002-GCLZB HA discovery. https://github.com/Koenkk/zigbee2mqtt/pull/4537#issuecomment-706562247 2020-10-11 13:43:11 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d9b9b05494 Update zigbee-herdsman-converters to 12.0.208 (#4633)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-10 16:54:28 +02:00
Koen Kanters 723e3a3964 Fix optimistic group state not published on startup. https://github.com/Koenkk/zigbee2mqtt/issues/3461 2020-10-10 16:41:02 +02:00
timstanley1985 ad0905607b Fix typo is ota logs (#4628) 2020-10-10 16:00:10 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
e836984e5e Update zigbee-herdsman-converters to 12.0.207 (#4627)
* Update zigbee-herdsman-converters to 12.0.207

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-10 01:25:53 +02:00
Koen Kanters e92a852349 Don't setup reporting for TS0115. https://github.com/Koenkk/zigbee2mqtt/issues/4621 2020-10-09 23:51:48 +02:00
Koen Kanters eecd15ebfa Don't republish identical optimistic group states. #3461 (#4623)
* Don't republish identical optimistic state for groups. #3461

* Fixes
2020-10-09 23:29:34 +02:00
John DoeandKoen Kanters da91158f94 rePublish device state on rename (#4620)
* Republish device state on rename

* Update bridge.js

* Update bridge.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-09 22:59:10 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
9dc34c421f Update zigbee-herdsman-converters to 12.0.205 (#4625)
* Update zigbee-herdsman-converters to 12.0.205

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-09 22:53:07 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 759751629d Update zigbee-herdsman to 0.13.15 (#4624)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-09 22:44:46 +02:00
Koen Kanters 24d8e5f113 Expose linkquality sensor for all devices. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1638 2020-10-09 21:57:54 +02:00
Koen Kanters 9d29bcc566 Fix switches/plugs not controllable in group. https://github.com/Koenkk/zigbee2mqtt/issues/4558 2020-10-09 21:40:33 +02:00
Koen Kanters e2e51fc32c Revert "Does linux/386 work now?"
This reverts commit 75ca6f3970.
2020-10-09 18:21:50 +02:00
Koen Kanters 75ca6f3970 Does linux/386 work now? 2020-10-09 18:19:59 +02:00
Koen Kanters 33985bc976 Fix buildx command 2020-10-09 18:15:14 +02:00
Koen Kanters 17545a6f72 Fix ci.yml 2020-10-09 18:12:38 +02:00
Koen Kanters e36ca7f8f8 Merge branch 'master' into dev 2020-10-09 18:09:50 +02:00
Koen Kanters ed8b4e567b Migrate to docker setup QEMU/Buildx 2020-10-09 18:09:40 +02:00
Koen Kanters c1a1b91a25 Fix docker build 2020-10-09 15:20:05 +02:00
Koen Kanters 330927d4b7 Merge branch 'master' into dev 2020-10-09 14:25:22 +02:00
Koen Kanters 40ab11bc49 Revert "Use buildx 0.4.2"
This reverts commit a571949f49.
2020-10-09 14:25:11 +02:00
Koen Kanters f618926d09 Merge branch 'master' into dev 2020-10-09 14:21:35 +02:00
Koen Kanters 0e30a73a19 Drop linux/i386 image (causes build errors) 2020-10-09 14:21:26 +02:00
Koen Kanters fb7b8ba867 Merge branch 'master' into dev 2020-10-09 14:18:14 +02:00
Koen Kanters 6fa4807a5a linux/386 -> linux/i386 2020-10-09 14:18:00 +02:00
Koen Kanters 456fb4014c Merge branch 'master' into dev 2020-10-09 14:10:44 +02:00
Koen Kanters a571949f49 Use buildx 0.4.2 2020-10-09 14:01:35 +02:00
Koen Kanters ddf3b57ec5 Use 12-alpine3.12 as base Docker image 2020-10-09 13:55:36 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 5ec3ef5be6 Update zigbee2mqtt-frontend to 0.2.27 (#4619)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-09 18:43:01 +08:00
Koen Kanters 61e650e7b5 Don't add stale to "breaking change" issues. https://github.com/Koenkk/zigbee2mqtt/pull/4572 2020-10-08 22:21:00 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
8cae206c64 Update zigbee-herdsman-converters to 12.0.204 (#4605)
* Update zigbee-herdsman-converters to 12.0.204

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-08 22:08:18 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> e9c96e7a24 Update zigbee-herdsman to 0.13.14 (#4606)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-08 22:00:50 +02:00
434981b567 [ImgBot] Optimize images (#4602)
*Total -- 451.91kb -> 199.42kb (55.87%)

/images/logo_large.png -- 243.86kb -> 81.11kb (66.74%)
/images/logo_bee_only.png -- 89.06kb -> 29.77kb (66.57%)
/images/logo.png -- 3.62kb -> 2.28kb (36.82%)
/images/architecture.png -- 102.93kb -> 75.96kb (26.21%)
/images/logo_vector.svg -- 12.44kb -> 10.30kb (17.19%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>

Co-authored-by: ImgBotApp <ImgBotHelp@gmail.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-08 20:35:42 +02:00
Hacker-CB dcaaef286d Fix for HEIMAN Smart socket HS2SK (NXP version) haElectricalMeasurement. (#4596)
Device does not support reporting. Need to poll.
2020-10-08 19:43:18 +02:00
Marco MassarottoandKoen Kanters bc7a436241 allow to redefine homeassistant autodiscovery entity "type" and "object_id" (#4593)
* Add link for creating frontend issues. #4568

* allow to redefine entity type and object_id in homeassistant autodiscovery

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-08 19:38:25 +02:00
Koen Kanters 667bc42bee Merge branch 'master' into dev 2020-10-08 19:36:29 +02:00
Koen Kanters 9257cd82b3 Fix optimistic for groups. https://github.com/Koenkk/zigbee2mqtt/pull/4572 2020-10-08 17:59:39 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6989f303b8 Update zigbee2mqtt-frontend to 0.2.26 (#4592)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-08 06:26:30 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
ebca056ad9 Update zigbee-herdsman-converters to 12.0.203 (#4583)
* Update zigbee-herdsman-converters to 12.0.203

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-07 17:37:03 +02:00
Koen Kanters 172773a7f2 Sort in dumpHomeAssistantMapping.js 2020-10-07 17:34:48 +02:00
Koen Kanters 3a1f697d93 Don't log when including logger.js 2020-10-07 17:15:46 +02:00
Koen Kanters 8f40d18c0a Fix last seen unknown when opening frontend. #4266 2020-10-07 17:05:46 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> a132094be4 Update zigbee2mqtt-frontend to 0.2.24 (#4578)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-07 08:27:32 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
ba57e352b7 Update zigbee-herdsman-converters to 12.0.202 (#4576)
* Update zigbee-herdsman-converters to 12.0.202

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-06 22:10:40 +02:00
Koen Kanters 5d1975d60c Add optimistic option. https://github.com/Koenkk/zigbee2mqtt/issues/4524 (#4572) 2020-10-06 21:50:07 +02:00
Koen Kanters a982acc1ca Fix tests after https://github.com/Koenkk/zigbee2mqtt/pull/4510 2020-10-06 21:42:05 +02:00
Hacker-CB c045b90d2b Add tz.tuya_thermostat_away_mode (fix for https://github.com/Koenkk/z… (#4510)
* Add tz.tuya_thermostat_away_mode (fix for https://github.com/Koenkk/zigbee2mqtt/pull/4491)

* Added /* istanbul ignore else */
2020-10-06 21:37:15 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
34e82118a1 Update zigbee-herdsman-converters to 12.0.201 (#4575)
* Update zigbee-herdsman-converters to 12.0.201

* Update homeassistant.js

* Update utils.js

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-06 20:40:20 +02:00
Koen Kanters e90182642d Republish groups on device remove. https://github.com/nurikk/z2m-frontend/issues/31 2020-10-06 19:28:32 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6ca8982237 Update zigbee-herdsman to 0.13.13 (#4573)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-06 16:33:20 +02:00
Koen Kanters e30b2576b7 Add link for creating frontend issues. #4568 2020-10-06 12:49:56 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
20c643552c Update zigbee-herdsman-converters to 12.0.200 (#4566)
* Update zigbee-herdsman-converters to 12.0.200

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-05 19:36:32 +02:00
Nick RandellandKoen Kanters d5a3bf5d93 Added SmartPlug51AU (#4562)
* Added SmartPlug51AU

* Updated to fix conflicts

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-05 19:22:46 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> cb0cf20e46 Update zigbee-herdsman-converters to 12.0.199 (#4563)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-05 17:47:44 +02:00
Koen Kanters a2a7cebd07 Fix tests 2020-10-05 17:43:57 +02:00
Koen Kanters 2fb3cb62f6 Fix touchlink factory reset failing with ''BUFFER' not available' error. #4543 2020-10-05 16:21:20 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> a7f931b8e3 Update dependencies (#4553)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-05 11:38:00 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> aea803bec7 Update zigbee2mqtt-frontend to 0.2.23 (#4560)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-05 06:41:06 +08:00
John Doe 628ca0daa1 Remove mqtt password from bridge/info (#4556) 2020-10-04 20:42:38 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 75ec7c3e05 Update zigbee2mqtt-frontend to 0.2.22 (#4554)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-04 11:17:39 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
57b5529cd1 Update zigbee-herdsman-converters to 12.0.198 (#4551)
* Update zigbee-herdsman-converters to 12.0.198

* Update homeassistant.js

* Update publish.test.js

* Update publish.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-04 00:32:43 +02:00
insipiensandKoen Kanters 9df1ea4359 Moes room thermostat (#4537)
* Add Moes Room Thermostat entry

* Added entry for Moes Room thermostat

* Revert "Added entry for Moes Room thermostat"

This reverts commit 697c530023.

* Correct layout

* remove duplicate

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-03 23:33:31 +02:00
Koen Kanters 2a08127e13 Fix tests 2020-10-03 23:24:08 +02:00
Koen Kanters 0c36b7894b Fix json escaped raw networkmap. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-10-03 22:47:20 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 43f085b069 Update zigbee2mqtt-frontend to 0.2.21 (#4539)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-03 08:19:46 +08:00
Koen Kanters 14c96a1045 Exposes for switch. https://github.com/Koenkk/zigbee2mqtt/issues/4466 2020-10-02 17:26:08 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
145f1e862d Update zigbee-herdsman-converters to 12.0.197 (#4534)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-10-02 17:25:25 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b5dc732a91 Update zigbee-herdsman to 0.13.12 (#4535)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-02 17:24:24 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 30449565ac Update zigbee2mqtt-frontend to 0.2.20 (#4525)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-02 15:28:43 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 2117e79324 Update zigbee2mqtt-frontend to 0.2.18 (#4522)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-02 10:44:02 +08:00
Koen Kanters 50226d2c84 Exposes for lights. #4466 (#4516)
* Add dumpHomeAssistantMapping

* Add exposes for lights. https://github.com/Koenkk/zigbee2mqtt/issues/4466

* Updates

* Updates
2020-10-01 18:33:59 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> c75c89c388 Update zigbee-herdsman-converters to 12.0.196 (#4517)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-10-01 18:14:43 +02:00
Koen Kanters 4c2ce0d5eb Promote to dev 2020-10-01 16:49:55 +02:00
Koen Kanters 1bccc5d9f1 1.15.0 2020-10-01 16:44:12 +02:00
Koen Kanters 4de13ef02b Undev 2020-10-01 16:44:06 +02:00
Koen Kanters 87a1fe62cb More fixes for https://github.com/Koenkk/zigbee2mqtt/pull/4491 2020-09-30 20:06:47 +02:00
Koen Kanters a0499af62d Fixes for https://github.com/Koenkk/zigbee2mqtt/pull/4491 2020-09-30 20:04:06 +02:00
Hacker-CB 44224b4d6b Added ETOP HT-08 Thermostat and HT-10 TRV (#4491)
* Added ETOP HT-08 Thermostat

References:
* https://github.com/Koenkk/zigbee2mqtt/issues/4185
* https://github.com/Koenkk/zigbee2mqtt/issues/1856
* https://github.com/Koenkk/zigbee2mqtt/issues/4486
* http://www.etopcontrols.com/thermostat/detail/HT-08.html

* Rename `away` to `away_mode`

* Added ETOP HT-10 TRV
Minor fixes for HT-08

References:
* https://github.com/Koenkk/zigbee2mqtt/issues/1856
* http://www.etopcontrols.com/thermostat/detail/HT-10.html
2020-09-30 19:52:11 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
d5d7d076a7 Update zigbee-herdsman-converters to 12.0.194 (#4508)
* Update zigbee-herdsman-converters to 12.0.194

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-30 19:44:30 +02:00
jonasled 4afcff5cab added homeassistant config for ZS190000118 (#4492)
added homeassistant config for ZS190000118
2020-09-29 18:47:10 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 3b04e4c771 Update zigbee-herdsman to 0.13.11 (#4489)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-29 17:20:50 +02:00
embak 60e5a14776 Update Sinope TH1123ZB, TH1124ZB and TH1300ZB for Home Assistant (#4484)
* Update Sinope TH1123ZB, TH1124ZB and TH1300ZB for Home Assistant

Uniformized Home Assistant behavior/features for Sinope baseboards and floor thermostats.
TH1123ZB, TH1124ZB and TH1300ZB:
- change temperature setpoint resolution to 0,5C
TH1123ZB, and TH1124ZB:
- add energy entity
TH1124ZB and TH1300ZB:
- add local temperature entity
TH1124ZB:
- add keypad lockout (climate entity attribute)
- add power entity

* Linter correction
2020-09-29 17:00:22 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 08927fcb10 Update zigbee-herdsman to 0.13.10 (#4481)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-29 11:06:32 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 58d56b339c Update zigbee2mqtt-frontend to 0.2.17 (#4483)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-29 07:13:40 +08:00
Koen Kanters 051742e076 Logo bee only. https://github.com/nurikk/z2m-frontend/issues/17 2020-09-28 20:15:51 +02:00
Koen Kanters 0beea18adb Fix devices being undiscovered from Home Assistant when a non-standard Home Assistant discovery topic is used. #4480 2020-09-28 19:43:04 +02:00
Koen Kanters 4bb3ddcff2 Make frontend non-experimental. https://github.com/Koenkk/zigbee2mqtt/issues/4266 2020-09-27 22:18:48 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
546d6193a3 Update zigbee-herdsman-converters to 12.0.193 (#4476)
* Update zigbee-herdsman-converters to 12.0.193

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-27 22:13:31 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 939a2685af Update dependencies (#4471)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-27 17:38:44 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> fced7edc2d Update zigbee2mqtt-frontend to 0.2.15 (#4463)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-26 07:32:30 +08:00
Koen Kanters 49e621123a Fix Home Assistation device trigger not working after rename. #4452 2020-09-25 19:48:30 +02:00
Koen Kanters e286a66cea Don't rediscover Home Assistant device_automation (triggers). #4452 2020-09-25 18:47:28 +02:00
Koen Kanters 48cf4728bb Clear outdated Home Assistant device_automation discoveries. #4452 2020-09-25 18:20:27 +02:00
Koen Kanters 44f4c436d9 Mark node 13 as unsupported (not maintained anymore) 2020-09-25 17:48:05 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
6889f36ab0 Update zigbee-herdsman-converters to 12.0.192 (#4458)
* Update zigbee-herdsman-converters to 12.0.192

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-25 17:46:17 +02:00
Koen Kanters d386da6366 Fixes for 4f6797c365 2020-09-25 17:44:24 +02:00
Koen Kanters 4f6797c365 Fix topic not updated for Home Assistant sensor on rename. #4452 2020-09-25 17:32:40 +02:00
Hacker-CB cb5418e9fc Added more HEIMAN devices (#4431)
* Added HEIMAN HS2SS Smart scene switch

* Added HEIMAN HS2SW1A/HS2SW2A/HS2SW3A wall switches

* Added HEIMAN HS2IRC Smart IR Remote Control

* Added missing senosors to homeassistant for HEIMAN HS2SK

* Updated temperature -> device_temperature for genDeviceTempCfg cluster

* Fix device_temperature sensor mistake

* Fix device_temperature sensor 2nd mistake
2020-09-25 16:56:42 +02:00
Koen Kanters da2eb505fd Clear availability topic on device remove. #4432 2020-09-25 16:50:12 +02:00
qm3ster f26ddd93ff Replace "problematic" depenencies
Also one comment typo lol

`node-static` was abandoned and vulnerable, which might matter since
it's used in production usage and not development.
replaced with popular `serve-static` + `finalhandler`

`json-stable-stringify` depended on an unneeded and unlicensed
polyfill for JSON builtin.
2020-09-25 15:58:45 +02:00
potvcind f5e4859a93 Adding support for Sinope SP2600ZB Smart plug 2020-09-25 15:33:27 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> bbc7c7d5fb Update zigbee2mqtt-frontend to 0.2.14 (#4450)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-24 19:29:04 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 64a7840c4f Update zigbee2mqtt-frontend to 0.2.13 (#4448)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-24 10:49:07 +08:00
Koen Kanters b79fb2b6f5 Don't try to setup reporting for Philips devices that do not support it. https://github.com/Koenkk/zigbee-herdsman/issues/110 2020-09-22 17:42:03 +02:00
github-actions[bot] 1a51104931 Update zigbee-herdsman to 0.13.9 2020-09-22 15:19:11 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 610f77714f Update zigbee2mqtt-frontend to 0.2.10 (#4425)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-22 05:53:24 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
7a6ddc1118 Update zigbee-herdsman-converters to 12.0.191 (#4422)
* Update zigbee-herdsman-converters to 12.0.191

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-21 19:20:37 +02:00
carlos-villanueva bc91b798d2 Add support for Centralite 4200-C Smart Outlet in homeassistant.js (#4421) 2020-09-21 17:11:04 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d8b6e39c6a Update zigbee2mqtt-frontend to 0.2.9 (#4399)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-21 04:45:35 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
d2445ad2e3 Update zigbee-herdsman-converters to 12.0.190 (#4416)
* Update zigbee-herdsman-converters to 12.0.190

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-20 18:32:00 +02:00
Koen Kanters 92ce133e24 Enable scenes tests. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1531 2020-09-20 18:17:36 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 8314e4d841 Update dependencies (#4409)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-20 17:25:32 +02:00
Ryan Kim(True-World) 9ab3fc902b Add Dawon DNS new 4 devices (Zigbee 3.0) (#4404)
1. 1Gang Switch with router (No neutral wire)
2. 2Gang Switch with router (No neutral wire)
3. 3Gang Switch with router (No neutral wire)
4. IoT 16A outlet
2020-09-19 19:55:00 +02:00
Hacker-CBandPavel Sokolov a33622c52b Added set of HEIMAN devices (#4395)
* Added HEIMAN HS1VS-N water leak sensor

* Added HEIMAN HS1HT-N temperature and humidity sensor

* Added HEIMAN HS3DS Door sensor

* Added HEIMAN HS1RC-N Smart remote controller

* Added/updated HEIMAN HS1EB-E Smart emergency button

* Added HEIMAN HS2AQ-EM Air quality monitor

* Fix lint error

Co-authored-by: Pavel Sokolov <pavel@tvip.ru>
2020-09-19 19:48:09 +02:00
Koen Kanters 9eba6d62db Merge branch 'master' into dev 2020-09-19 11:48:58 +02:00
Koen Kanters 0cd4607856 Fix branch-switcher not working 2020-09-19 11:48:28 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
570c6da67b Update zigbee-herdsman-converters to 12.0.189 (#4403)
* Update zigbee-herdsman-converters to 12.0.189

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-19 11:45:50 +02:00
robinaartsmaandKoen Kanters bce2b34a9b Update homeassistant.js (#4396)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-19 11:23:08 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> e9c510539a Update zigbee-herdsman to 0.13.8 (#4402)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-19 11:08:19 +02:00
Koen Kanters 206f02b200 Updates for scenes. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1531 2020-09-19 11:07:54 +02:00
Koen Kanters 7fe3167e97 Fix crash when saving state.json fails. #4388 2020-09-19 10:59:12 +02:00
Koen Kanters 4f9c36ee44 Don't allow renaming to not allowed friendlyName. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-09-19 10:57:39 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> c0faae73bb Update zigbee2mqtt-frontend to 0.2.7 (#4387)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-17 21:09:54 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 9c2fd10d8f Update zigbee2mqtt-frontend to 0.2.4 (#4380)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-17 09:24:49 +08:00
KotMorderca 123c321306 Added mapping for 11830304 (#4385) 2020-09-16 22:09:14 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> e1e33a85a6 Update zigbee-herdsman to 0.13.7 (#4379)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-16 12:02:38 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d2f8e22712 Update zigbee2mqtt-frontend to 0.2.2 (#4377)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-16 06:46:34 +08:00
Koen Kanters 8db16cca3d Republish devices on OTA update. https://github.com/Koenkk/zigbee2mqtt/issues/4266 2020-09-15 22:13:30 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6234e2f40e Update zigbee-herdsman-converters to 12.0.188 (#4376)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-15 22:12:38 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b1bf87f845 Update zigbee-herdsman to 0.13.6 (#4373)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-15 20:26:19 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
1e9cb4d1cc Update zigbee-herdsman-converters to 12.0.187 (#4371)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-15 18:41:37 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d9b2e211d3 Update zigbee-herdsman to 0.13.5 (#4370)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-15 18:34:48 +02:00
Koen Kanters ba43744768 Don't discover to Home Assistant when device is still interviewing. #4363 2020-09-15 18:24:48 +02:00
Hacker-CBandPavel Sokolov a47217f1cc HEIMAN HS1VS-N Vibration sensor: added battery level reporting and tamper (#4365)
* HEIMAN HS1VS-N Vibration sensor: added battery level reporting and tamper

* Fix formatting

Co-authored-by: Pavel Sokolov <pavel@tvip.ru>
2020-09-15 16:55:19 +02:00
Hacker-CBandPavel Sokolov b4d32a9d14 Added HEIMAN HS1VS-N Vibration sensor (#4360)
Co-authored-by: Pavel Sokolov <pavel@tvip.ru>
2020-09-14 22:16:23 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ff37b4f8de Update zigbee2mqtt-frontend to 0.1.58 (#4357)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-14 12:25:45 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 63f527e697 Update zigbee-herdsman to 0.13.4 (#4355)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-13 17:05:07 +02:00
John DoeandKoen Kanters 2caaaa8d24 Fix mallformed (nullish) messages handling (#4347)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-13 15:38:10 +02:00
John DoeandKoen Kanters 59812f1ef6 Fix device removal (#4354)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-13 15:35:33 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
508ee10f0c Update dependencies (#4348)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-13 15:21:39 +02:00
7h0mas-RandKoen Kanters d0fbde8759 added Merten MEG5113-0300/MEG5165-0000 to Home Assistant mapping (#4345)
added Merten MEG5113-0300/MEG5165-0000 to mapping

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-13 15:16:46 +02:00
Koen Kanters e631bbeb60 Merge branch 'master' into dev 2020-09-13 15:14:29 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> aad36371a0 Update zigbee2mqtt-frontend to 0.1.57 (#4350)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-13 15:50:07 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 24a7250e8d Update zigbee-herdsman-converters to 12.0.186 (#4341)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-12 16:55:17 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b432f3693a Update zigbee-herdsman to 0.13.3 (#4339)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-12 16:36:33 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
ced2c00997 Update zigbee-herdsman-converters to 12.0.185 (#4337)
* Update zigbee-herdsman-converters to 12.0.185

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-12 10:15:54 +02:00
OzGav 7d7b2fc671 Add support for NUE-ZBFLB Update homeassistant.js (#4279)
* Update homeassistant.js

* Update utils.js

* Update utils.js

* Update homeassistant.js

* Update utils.js
2020-09-12 09:45:26 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b2b30685ba Update zigbee2mqtt-frontend to 0.1.56 (#4330)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-12 05:49:09 +08:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 37acdf5a63 Update zigbee-herdsman to 0.13.2 (#4335)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-11 23:14:39 +02:00
embak bd91beb9c0 Add keypad lockout feature to TH1300ZB (#4331) 2020-09-11 17:07:21 +02:00
Koen Kanters 166f1a8b87 Update new_device_support.md 2020-09-11 17:02:47 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 8757d72467 Update zigbee2mqtt-frontend to 0.1.53 (#4327)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-10 22:12:19 +08:00
John Doe 9cabe1e23a Fix frontend api messages pollution (#4326) 2020-09-10 20:54:03 +08:00
Koen Kanters 812909363b Update issue templates 2020-09-09 19:32:28 +02:00
Koen Kanters 9ca8c31448 Add issue templates. https://github.com/Koenkk/zigbee2mqtt/issues/4306 2020-09-09 19:27:05 +02:00
Koen Kanters 5d6a5cb19f Update issue templates 2020-09-09 19:19:17 +02:00
Koen Kanters c29cc784ba Touchlink identify. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-09-09 18:24:32 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 7f29c029a3 Update zigbee-herdsman to 0.13.1 (#4319)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-09 18:17:24 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6be1d7ae7d Update zigbee2mqtt-frontend to 0.1.52 (#4318)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-09 23:54:01 +08:00
Koen Kanters 14da75f4a7 Touchlink factory reset specific device and scan. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-09-08 20:24:49 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b94c5d7283 Update zigbee-herdsman to 0.13.0 (#4310)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-08 20:24:26 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> fd60669a04 Update zigbee-herdsman-converters to 12.0.184 (#4309)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-08 20:19:55 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> fb4c75ad0a Update zigbee2mqtt-frontend to 0.1.49 (#4305)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-08 19:30:06 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 80c9a6011d Update zigbee-herdsman to 0.12.132 (#4308)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-08 19:29:51 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d0011892b1 Update zigbee2mqtt-frontend to 0.1.48 (#4303)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-08 09:46:04 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
fe56483ba2 Update zigbee-herdsman-converters to 12.0.183 (#4301)
* Update zigbee-herdsman-converters to 12.0.183

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-07 19:05:43 +02:00
Koen Kanters beef2097e4 Pass options to onEvent. https://github.com/Koenkk/zigbee2mqtt/issues/3812 2020-09-07 18:46:46 +02:00
Koen Kanters b1cfafe6b7 Add BHT-002-GCLZB to homeassistant.js 2020-09-07 17:52:12 +02:00
Koen Kanters 7b226e6efe Clear retained messages on device/group rename or delete. #4290 2020-09-07 17:29:53 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 0233cc92b0 Update zigbee2mqtt-frontend to 0.1.47 (#4288)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-06 19:41:35 +08:00
John Doe 037d54a604 Update update_frontend.yml (#4286) 2020-09-06 19:35:53 +08:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
16db8e7dbc Update dependencies (#4280)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-06 13:32:19 +02:00
Koen Kanters 02ac4b17ba Don't auto update zigbee2mqtt-frontend 2020-09-06 13:32:07 +02:00
John Doe a10e5b011c Update update_frontend.yml (#4281)
FIx job name
2020-09-06 13:27:51 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
7d028d3f80 Update zigbee-herdsman-converters to 12.0.182 (#4278)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-06 13:27:15 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
a8e8f43421 Update zigbee-herdsman to 0.12.131 (#4277)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-06 00:47:16 +02:00
Koen Kanters 4f55667760 Lint 2020-09-05 23:43:46 +02:00
Koen KantersandTomáš Martinovič 703a8c19d6 Added Immax 4in1 sensor to homeassistant.js (#4276)
Added Immax 4in1 sensor.

Co-authored-by: Tomáš Martinovič <tomas.martinovic@vsb.cz>
2020-09-05 23:39:03 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
7103ba4219 Update zigbee-herdsman-converters to 12.0.181 (#4275)
* Update zigbee-herdsman-converters to 12.0.181

* Update group.test.js

* Update publish.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-05 23:34:49 +02:00
nur 25a953bbce Add update frontend gh action 2020-09-05 15:20:22 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
c9094e98df Update zigbee-herdsman-converters to 12.0.180 (#4269)
* Update zigbee-herdsman-converters to 12.0.180

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-04 22:22:35 +02:00
Koen Kanters 778665b35b Don't rename entity ID in Home Assistant by default. #4095 2020-09-04 21:13:40 +02:00
Koen KantersandJohn Doe ba7a85bbb5 Frontend (#4232)
* Initial implementation of backend for frontend.

* Frontend fixes (#4205)

* Send data to frontend api withoud baseTopic preffix

* Send frontend api requests to mqtt

* Fix topic name sanitisation

* Fix base_topic trimming

* Update frontend.js

* Add zigbee2mqtt-frontend dependency

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

* Dont' setup separate MQTT connection.

* Correctly stop

* Add frontend tests.

* [WIP] Bindings structure change (#4233)

* Change bindings location

* Bump frontend version

* Republish devices on bindings change

* Fix data structure

* Fix  payload double encoding

* Change endpoints structure

* Expose config to bridge/info

* Fix typo

* Updates

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

* Resend states on ws reconnect

* Update deps

* Bump frontend (#4264)

Co-authored-by: John Doe <nurikk@users.noreply.github.com>
2020-09-04 18:42:24 +02:00
embak 84029e2057 Add OWON WSP404 Smart Plug to Home Assistant MQTT (#4260)
Device with switch, power sensor and energy measurements entities.
2020-09-04 17:30:00 +02:00
PHISON HOANGandKoen Kanters 48b502714e Add home assistant sensor config for QBKG26LM (#4258)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-04 17:28:12 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> cb0dee2f10 Update zigbee-herdsman to 0.12.130 (#4265)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-04 17:19:15 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 7d53408278 Update zigbee-herdsman to 0.12.129 (#4262)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-04 11:50:18 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
b428070416 Update zigbee-herdsman-converters to 12.0.179 (#4249)
* Update zigbee-herdsman-converters to 12.0.179

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-09-02 22:59:52 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> c707e50292 Update zigbee-herdsman to 0.12.128 (#4247)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-02 22:47:05 +02:00
Koen Kanters f57ec9f0fd Add definition to raw networkmap 2020-09-02 17:17:35 +02:00
Koen Kanters 37c4c2e1f7 Dev 2020-09-02 16:45:16 +02:00
Koen Kanters 654817a66d 1.14.4 2020-09-02 16:44:42 +02:00
Koen Kanters bb2cdd893b Undev 2020-09-02 16:44:32 +02:00
Koen Kanters 2c80ada344 Merge branch 'master' into dev 2020-09-02 16:43:47 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 9515973f9e Update zigbee-herdsman-converters to 12.0.178 (#4236)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-09-01 18:42:34 +02:00
Koen Kanters a057f3c171 Update stale.yml 2020-09-01 18:22:47 +02:00
Koen Kanters 27566dc5d1 Add coordinator, endpoint binds/supported clusters to bridge/devices. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-08-31 18:48:04 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> af97b65926 Update zigbee-herdsman to 0.12.127 (#4226)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-31 18:44:16 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
bdd8567229 Update zigbee-herdsman-converters to 12.0.177 (#4220)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-30 22:51:07 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
e54137c8ab Update zigbee-herdsman to 0.12.126 (#4219)
* Update zigbee-herdsman to 0.12.126

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-30 22:49:00 +02:00
nobodypb 48d5ee70c0 Return friendlyNames as answer to get_group_membership (#4210)
* Return friendlyNames as answer to get_group_membership

It would be a lot more useful, if you'd return the friendly names of the groups 😉

* Make the linter happy

* Gracefully echo warning if response is undefined

* Making friendship with the linter

Sorry, really shoud have used an IDE
2020-08-30 22:45:40 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 1390803738 Update zigbee-herdsman to 0.12.125 (#4218)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-30 22:19:54 +02:00
Koen Kanters ad0f11cc0f Base supported groups converters of its members. https://github.com/Koenkk/zigbee2mqtt/issues/764 2020-08-30 11:30:38 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 7033177917 Update dependencies (#4212)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-30 09:25:01 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 6452500993 Update zigbee-herdsman to 0.12.124 (#4209)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-29 16:22:39 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
ce6005abdd Update zigbee-herdsman-converters to 12.0.176 (#4208)
* Update zigbee-herdsman-converters to 12.0.176

* Update publish.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-29 16:14:53 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
1893ff1150 Update zigbee-herdsman-converters to 12.0.175 (#4207)
* Update zigbee-herdsman-converters to 12.0.175

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-29 14:46:23 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 50f4f95e80 Update zigbee-herdsman to 0.12.123 (#4206)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-29 14:32:27 +02:00
Koen Kanters 52b273f530 Add branch switcher ignore label. 2020-08-29 13:17:30 +02:00
PHISON HOANG 1bf49cb720 Add sensor temperature config for QBKG23LM (#4199) 2020-08-28 21:23:27 +02:00
Volodymyr Yelnikov a78d0f608a added support for Aqara Opple MX480 (#4195) 2020-08-27 19:51:46 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
9b4ef70fca Update zigbee-herdsman-converters to 12.0.174 (#4191)
* Update zigbee-herdsman-converters to 12.0.174

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-26 23:12:28 +02:00
Ivan Podogov ef93dd2151 Lonsonho 2-gang switch module discovery (#4190)
See converter here: https://github.com/Koenkk/zigbee-herdsman-converters/pull/1509
2020-08-26 22:46:13 +02:00
Ivan Podogov e3e5dcd039 Lonsonho TS110F 1-gang Home Assistant discovery (#4183) 2020-08-26 22:39:23 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
5f8b9beaf3 Update zigbee-herdsman-converters to 12.0.173 (#4182)
* Update zigbee-herdsman-converters to 12.0.173

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-25 21:48:50 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 39480c9fc2 Update zigbee-herdsman to 0.12.122 (#4181)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-25 21:41:26 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
db6d9bd5bb Update zigbee-herdsman-converters to 12.0.172 (#4180)
* Update zigbee-herdsman-converters to 12.0.172

* Update homeassistant.js

* Update zigbeeHerdsman.js

* Update publish.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-25 20:01:46 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
57b3511aa6 Update zigbee-herdsman-converters to 12.0.170 (#4174)
* Update zigbee-herdsman-converters to 12.0.170

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-24 23:02:01 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
85365b5d19 Update zigbee-herdsman-converters to 12.0.169 (#4172)
* Update zigbee-herdsman-converters to 12.0.169

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-23 23:19:41 +02:00
Koen Kanters ac6e4c7dae Fix coverage 2020-08-23 23:17:15 +02:00
Koen Kanters d980b97413 Fix Home Assistant automations based on click event not working. #4168 2020-08-23 22:58:07 +02:00
mgromandKoen Kanters 54f164cc21 fixes related to #4070 (#4132)
* fix

* eslint fix

* don't use temp topic when low and high temp used

* fix for temp high

* Add tests

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-23 22:36:30 +02:00
Koen Kanters 676684158a Fix messages from Xiaomi devices skipped sometimes when send through Xiaomi router. #3592 (#4170)
* Update receive.js

* Fix messages from Xiaomi devices skipped sometimes when send through Xiaomi router. https://github.com/Koenkk/zigbee2mqtt/issues/3592
2020-08-23 22:05:48 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 9e150efce4 Update zigbee-herdsman to 0.12.121 (#4169)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-23 22:01:48 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d22f3b8b1f Update dependencies (#4164)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-23 21:20:16 +02:00
Fabian AffolterandKoen Kanters 9f1551181b Remove Hass.io (#4159)
Hass.io was renamed to Home Assistant

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-22 17:36:18 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
1d7b5832ca Update zigbee-herdsman-converters to 12.0.168 (#4158)
* Update zigbee-herdsman-converters to 12.0.168

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-22 13:29:09 +02:00
mog422andKoen Kanters e6f8cee968 Add TPZRCO2HT-Z3 homeassistant mapping (#4155)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-22 12:24:28 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> f15b314634 Update zigbee-herdsman to 0.12.120 (#4156)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-22 12:21:00 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
bffe4db029 Update zigbee-herdsman-converters to 12.0.167 (#4144)
* Update zigbee-herdsman-converters to 12.0.167

* Update homeassistant.js

* Update publish.test.js

* Update publish.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-20 22:03:00 +02:00
Koen Kanters 0b5d169b46 Provide state to fromZigbee converter 2020-08-20 21:54:59 +02:00
Koen Kanters 22f657ed4d Add device_announce event to new api. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-08-20 20:55:40 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 57729c140e Update zigbee-herdsman to 0.12.119 (#4141)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-20 16:34:12 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
d69c2c947a Update zigbee-herdsman-converters to 12.0.166 (#4136)
* Update zigbee-herdsman-converters to 12.0.166

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-19 22:30:51 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
e780dbcb82 Update zigbee-herdsman-converters to 12.0.165 (#4126)
* Update zigbee-herdsman-converters to 12.0.165

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-18 22:35:48 +02:00
Koen Kanters a20c6728b8 Also use state converter when value is open, close, stop, lock and unlock. #4123 2020-08-18 21:27:36 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
b7409295b5 Update zigbee-herdsman-converters to 12.0.164 (#4121)
* Update zigbee-herdsman-converters to 12.0.164

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-17 22:22:18 +02:00
Koen Kanters 0f6540c5fc Fix typo https://github.com/Koenkk/zigbee2mqtt/commit/9148977b3968b609add29807a780acd469dbed89#r41534643 2020-08-17 22:14:10 +02:00
KrisandKoen Kanters 5411de8618 Add Philips Hue Nyro (#4120)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-17 22:08:52 +02:00
Koen Kanters b80695cd18 Merge branch 'master' into dev 2020-08-17 22:08:17 +02:00
Koen Kanters 0db3f3ca0b Remove branch-cleanup 2020-08-17 21:52:47 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 30044bc8da Update zigbee-herdsman to 0.12.118 (#4118)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-17 21:51:59 +02:00
Koen Kanters 8c5fae900e Don't use state converter on invalid JSON and the payload is not on, off or toggle. https://github.com/Koenkk/zigbee2mqtt/issues/1348 2020-08-17 21:29:11 +02:00
Koen Kanters d167b149ad Refactor device options retrieval 2020-08-17 20:57:12 +02:00
Koen Kanters 9148977b39 Rename device entity_id in Home Assistant when changing friendly_name. #4096 2020-08-17 20:19:44 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
176d32b2de Update dependencies (#4114)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-17 17:32:01 +02:00
Koen Kanters 5f75c9c9f8 Clear outdated Home Assistant configs 2020-08-17 17:24:57 +02:00
felix schwenzel ffe810a471 Update homeassistant.js (#4113)
add MAXI JOLLY ZB3 LED driver, see https://github.com/Koenkk/zigbee-herdsman-converters/pull/1475.
2020-08-17 13:57:42 +02:00
Koen Kanters 410f6a0f95 Fix update state sensor object_id. 2020-08-14 13:48:19 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 4f27813d96 Update zigbee-herdsman-converters to 12.0.163 (#4100)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-14 11:51:22 +02:00
Koen Kanters 082c5d47be Merge branch 'master' into dev 2020-08-14 11:44:07 +02:00
mgromandKoen Kanters d3a22d49c1 Added presets (hold_modes) to climate sensor #3821 (#4070)
* Added presets (hold_modes) to climate sensor #3821

and removed thermostatHeatCool as it's partially redundant

* Added new configuration to TuYa thermostat TS0601_thermostat

* eslint fixes

* Added eco and comfort modes. Looks like they are usable.

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-14 11:43:52 +02:00
Koen Kanters 1213fd6ea6 Remove autosquash and add branch-cleanup 2020-08-14 11:43:35 +02:00
Koen Kanters c6ed37ab47 Switch to autosquash 2020-08-14 11:27:18 +02:00
Koen Kanters 43730cbbd1 Merge branch 'master' into dev 2020-08-14 11:23:04 +02:00
Koen Kanters 146a015455 Add rebase workflow 2020-08-14 11:22:08 +02:00
TomandKoen Kanters 08524953bf Add Environment Variable Override (#4085)
* Add Environment Variable Override

I need to be able to manage settings on this service via Environment Variables.   I've added the ability to override anything in the settings schema with a corresponding environment variable.  

e.g. to override settings.serial.port you can set ZIGBEE2MQTT_SERIAL_PORT=/dev/ttyS0
to override the mqtt username you can set ZIGBEE2MQTT_MQTT_USER=testusername

This new addition will not perform any action on existing installations unless the matching environment variable is set.  I have tested this setting string, number, boolean, object and array values.

* Adding test case for environment variables and slight modification to ensure 100% code coverage.

* Adding a test to confirm that env variables will set non default values.  Also realized that I was errantly applying the env variables to the defaults for testing.  Understanding what this is doing more clearly I realize that should be clean.

* Refactoring to

1. Remove the test variables from the schema and defaults and manually reflect the tests in the test.

2. Rename environment variable base from ZIGBEE2MQTT_ to ZIGBEE2MQTT_CONFIG_

* Small improvements

* Removing the unneeded test.

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-13 23:50:30 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
5de279c20e Update zigbee-herdsman-converters to 12.0.162 (#4097)
* Update zigbee-herdsman-converters to 12.0.162

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-13 21:57:36 +02:00
Koen Kanters 9774031169 Sort logged and published JSON objects alphabetically. #4091 2020-08-13 20:00:35 +02:00
Koen Kanters c66e65e0fb Merge branch 'master' into dev 2020-08-12 17:36:56 +02:00
Koen Kanters f8066e8da8 1.14.3 2020-08-12 17:36:28 +02:00
Koen Kanters ec28738784 Fix npm repo url. 2020-08-12 17:36:24 +02:00
Koen Kanters 8398bcb51d Revert "1.14.3"
This reverts commit c0143cb40d.
2020-08-12 17:35:22 +02:00
blakadder 3acd123ecd add direction sensor to AD for some dimmers (#4078) 2020-08-12 17:22:05 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 763ae7903e Update zigbee-herdsman to 0.12.117 (#4089)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-12 17:13:14 +02:00
Koen Kanters 66902b963c Dev 2020-08-12 17:07:19 +02:00
Koen Kanters c0143cb40d 1.14.3 2020-08-12 16:58:19 +02:00
Koen Kanters e4c939a643 Undev 2020-08-12 16:58:16 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
4f1a0ae9cd Update zigbee-herdsman-converters to 12.0.161 (#4083)
* Update zigbee-herdsman-converters to 12.0.161

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-11 21:38:19 +02:00
Koen Kanters fb2e149a41 Merge branch 'master' into dev 2020-08-11 21:27:18 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 29f90b77b4 Update zigbee-herdsman to 0.12.116 (#4084)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-11 21:26:38 +02:00
Koen Kanters 954b891698 Only run Docker login/setup on master tag push 2020-08-10 21:54:20 +02:00
Koen Kanters 7ea27b51e2 Merge branch 'master' into dev 2020-08-10 21:50:52 +02:00
Koen Kanters 02e198eca2 Use GitHub Actions badge 2020-08-10 21:50:45 +02:00
Koen Kanters e5e8c58903 Remove azure-pipelines 2020-08-10 21:48:30 +02:00
Koen Kanters aebef20536 Merge branch 'master' into dev 2020-08-10 21:45:20 +02:00
Koen Kanters a519577cf7 Migrate from Azure to Github actions. 2020-08-10 21:44:05 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
f9076b362d Update zigbee-herdsman-converters to 12.0.160 (#4075)
* Update zigbee-herdsman-converters to 12.0.160

* Update homeassistant.js

* Update publish.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-10 20:44:44 +02:00
Koen Kanters c2e28eaee1 Switch to Github actions stale 2020-08-10 20:43:50 +02:00
ChamondglandKoen Kanters 14712d6fe1 Add Home Assistant discovery for ROB_200-010-0 (#4074)
Robb Smarrt Zigbee Curtain Motor Controller ROB_200-010-0

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-10 20:31:40 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
ff0b812029 Update zigbee-herdsman-converters to 12.0.159 (#4069)
* Update zigbee-herdsman-converters to 12.0.159

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-09 22:34:13 +02:00
Koen Kanters afbbf70caa Fix null published for attribute output. https://github.com/Koenkk/zigbee2mqtt/issues/4054 2020-08-09 11:31:27 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> f85722da38 Update dependencies (#4065)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-09 11:23:49 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> e97fc903a5 Update zigbee-herdsman to 0.12.115 (#4063)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-08 16:38:20 +02:00
Koen Kanters 81db31b784 Fix attribute output not publishing all values. https://github.com/Koenkk/zigbee2mqtt/issues/4054 2020-08-08 16:36:58 +02:00
Koen Kanters ff2fe2b358 Separate Home Assisant name by space instead of _ when friendlyName contains space. #4048 2020-08-08 13:54:39 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> fbecb7e0d2 Update zigbee-herdsman-converters to 12.0.158 (#4058)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-07 17:48:48 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
1198a2d9ac Update zigbee-herdsman-converters to 12.0.157 (#4051)
* Update zigbee-herdsman-converters to 12.0.157

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-05 23:01:17 +02:00
mateusz-dziurdziakandMateusz Dziurdziak 7b74971006 Add TuYa SNTZ009 water leak sensor (#4045)
Co-authored-by: Mateusz Dziurdziak <mateusz.dziurdziak@fara.no>
2020-08-05 22:10:29 +02:00
Koen Kanters 3cdf7604a0 Fix no color_temp for group on changing color_xy and vice versa. #4034 2020-08-05 21:54:39 +02:00
Koen Kanters 516d53e9df Fix reporting being disabled every time IKEA device announces. https://github.com/Koenkk/zigbee2mqtt/issues/3826 2020-08-05 16:38:40 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
6c6dfc85cd Update zigbee-herdsman-converters to 12.0.156 (#4043)
* Update zigbee-herdsman-converters to 12.0.156

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-04 20:10:34 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 8a6a7409be Update zigbee-herdsman to 0.12.114 (#4042)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-04 19:32:38 +02:00
Koen Kanters 6345cb07bf Disable reporting on device when reporting is disabled. https://github.com/Koenkk/zigbee2mqtt/issues/3826 2020-08-04 19:11:13 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 35be95115d Update zigbee-herdsman to 0.12.113 (#4031)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-03 21:06:56 +02:00
Koen Kanters 852bca5a08 Implement update state for new api. https://github.com/Koenkk/zigbee2mqtt/issues/3634 https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-08-02 23:09:43 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
8aa3cf0c29 Update zigbee-herdsman-converters to 12.0.155 (#4025)
* Update zigbee-herdsman-converters to 12.0.155

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-08-02 10:51:51 +02:00
Koen Kanters 3e071a73df Invert cover tests. https://github.com/Koenkk/zigbee-herdsman-converters/issues/1447 2020-08-02 10:08:55 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b4cfa7b0b7 Update dependencies (#4023)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-02 10:02:13 +02:00
Koen Kanters 9a6397fe75 Make Zigbee2MQTT naming consistent 2020-08-01 10:36:20 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 22c24a16b3 Update zigbee-herdsman to 0.12.112 (#4021)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-08-01 09:39:00 +02:00
Zhongfu LiandKoen Kanters 3b29266be3 Fix Home Assistant auto-discovery for QBKG22LM, QBKG25LM (#3977)
* Update configuration for QBKG22LM, QBKG25LM

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-31 17:59:24 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
0fddfc9ffa Update zigbee-herdsman-converters to 12.0.154 (#4018)
* Update zigbee-herdsman-converters to 12.0.154

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-30 23:19:05 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> b2e588c1cf Update zigbee-herdsman to 0.12.111 (#4017)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-30 22:58:06 +02:00
lionel590andKoen Kanters ded3a58883 Network parameters / config displayed in zigbee2mqtt/bridge/config (#4010)
* Update zigbee.js

* added network parameters to zigbee2mqtt/bridge/config

* added network parameters to zigbee2mqtt/bridge/config

* added test for network config in zigbee2mqtt/bridge/config

* Fix network data

* Added test data for network parameters

* Update zigbee.js

* Update zigbee.js

* Update bridge.test.js

* Update bridge.test.js

* Update utils.js

* Update bridge.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-30 22:31:52 +02:00
Sebastian Karasek a5b03b5dad Add home-assistant mapping for NLG Q-FRAMELESS (#4012) 2020-07-30 22:19:01 +02:00
Matthew Garrett 469ddb7e76 Add support for Orvibo AM25 blinds (#4011) 2020-07-30 22:14:51 +02:00
Artyom Dudarev 64022897f8 Add support for Lonsonho X713A 3 gang switch (#4015) 2020-07-30 22:12:39 +02:00
Koen Kanters 274109bc85 Allow to disable Home Assistant via MQTT. #3281 (#4007)
* Initial

* Updates
2020-07-29 23:10:03 +02:00
Koen Kanters b9c52ef96e Fix exception in Home Assistant extension when click or action is null/undefined. #4005 2020-07-29 22:08:00 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
9474dfe249 Update zigbee-herdsman-converters to 12.0.153 (#4006)
* Update zigbee-herdsman-converters to 12.0.153

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-29 17:23:23 +02:00
Koen Kanters a7f990ef95 New api: log to MQTT. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-28 22:12:22 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
ae93e6fd0f Update zigbee-herdsman-converters to 12.0.152 (#4004)
* Update zigbee-herdsman-converters to 12.0.152

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-28 22:06:30 +02:00
Koen Kanters 946ebe16b6 Allow to specify which clusters are being bound/unbound. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-28 21:05:02 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> a0c895a88d Update zigbee-herdsman to 0.12.110 (#4002)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-28 20:07:59 +02:00
Koen Kanters 44b26f9b22 Parse attribute payload to JSON if possible. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1427 2020-07-27 23:04:59 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ef6572dfd0 Update zigbee-herdsman-converters to 12.0.151 (#3994)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-27 22:59:07 +02:00
Diego Rodríguez 7c6fe4d95e Add voltage to ZNCZ02LM (#3991) 2020-07-27 22:33:15 +02:00
Hamish MoffattandHamish Moffatt f5e5c76ca9 output plain text to syslog (#3985)
* output plain text to syslog (#3984)

* fix lint warnings

Co-authored-by: Hamish Moffatt <hamish@moffatt.id.au>
2020-07-27 22:22:02 +02:00
Koen Kanters 0d9ed11ceb Merge branch 'master' into dev 2020-07-27 22:21:00 +02:00
Koen Kanters b9ba635bea Fix crash when attribute value is undefined of null (publish empty payload in this case). #3980 2020-07-27 22:07:03 +02:00
iharyadiandKoen Kanters 88521b25d3 Add HA model mapping (#3974)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-26 14:28:17 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> efc971d2ca Update zigbee-herdsman-converters to 12.0.150 (#3979)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-26 14:22:36 +02:00
Koen Kanters 7d27e6db69 Changes for zigbee-herdsman-converters 12.0.150 2020-07-26 14:19:33 +02:00
Koen Kanters 812c4927e7 Handle group setup failure. https://github.com/Koenkk/zigbee2mqtt/issues/3966 2020-07-26 10:11:58 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> d7b678e636 Update dependencies (#3976)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-26 09:22:56 +02:00
Koen Kanters 00f836fce6 Don't discover sensor_click when legacy: false is set. https://github.com/Koenkk/zigbee-herdsman-converters/issues/1393 2020-07-24 22:53:10 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
992ebafc63 Update zigbee-herdsman-converters to 12.0.149 (#3963)
* Update zigbee-herdsman-converters to 12.0.149

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-23 21:06:13 +02:00
senax f0068d73cb Added 1746330P7/Philips Hue Appear (#3962) 2020-07-23 20:31:19 +02:00
Koen Kanters 867918bd63 Fix incorrect device type. https://github.com/Koenkk/zigbee2mqtt/issues/3953 2020-07-23 19:55:56 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 1fa547437f Update zigbee-herdsman to 0.12.109 (#3960)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-23 19:51:03 +02:00
Koen Kanters ad13564687 Improve error messages when configuration is invalid. #3943 2020-07-23 19:17:26 +02:00
Koen Kanters b91b456f98 Include zigbee-herdsman-(converters) version in pull request title. 2020-07-22 23:34:35 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
a01048487d Update zigbee-herdsman-converters to 12.0.148
* Update zigbee-herdsman-converters to 12.0.148

* Update publish.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-22 23:32:38 +02:00
Koen Kanters 2d3ab1cf8a Promote to dev 2020-07-22 22:19:15 +02:00
Koen Kanters faaf3e488f 1.14.2 2020-07-22 22:17:55 +02:00
Koen Kanters 1aa70cca91 Undev 2020-07-22 22:17:48 +02:00
Koen Kanters 28d48f3d96 Skip message when definition is undefined and still interviewing instead of modelID. https://github.com/Koenkk/zigbee2mqtt/issues/3947 2020-07-22 14:00:27 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
93cae0b09a Update zigbee-herdsman-converters to 12.0.147
* Update zigbee-herdsman-converters to 12.0.147

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-22 13:57:11 +02:00
Koen Kanters 6d9affaa49 Revert "Fix device incorrectly identified when still interviewing. #3947"
This reverts commit 1d3a577fc4.
2020-07-22 13:44:56 +02:00
Koen Kanters e06e54321c Revert "Fix device incorrectly identified when still interviewing (attempt 2) #3947"
This reverts commit 2e0b23f97c.
2020-07-22 13:44:47 +02:00
Koen Kanters db748a1333 Implement new api healthcheck. #3281 2020-07-21 21:16:52 +02:00
Koen Kanters 2e0b23f97c Fix device incorrectly identified when still interviewing (attempt 2) #3947 2020-07-21 20:47:05 +02:00
Koen Kanters 1d3a577fc4 Fix device incorrectly identified when still interviewing. #3947 2020-07-21 20:26:07 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
ad0bbbec97 Update zigbee-herdsman-converters to 12.0.146
* Update zigbee-herdsman-converters to 12.0.146

* Update publish.test.js

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-20 18:58:17 +02:00
Deadlystrike edcf1edae6 Add support for Embrighten Outlet 43102 (#3939) 2020-07-20 18:05:42 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 57b45f6624 Update zigbee-herdsman-converters to 12.0.141 (#3933)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-19 02:01:12 +02:00
Koen Kanters 85eb74b546 Merge branch 'master' into dev 2020-07-19 01:54:24 +02:00
Koen Kanters f26791aa2c Reduce days until stale 2020-07-19 01:54:13 +02:00
Koen Kanters 2728508c7f Update naming 2020-07-19 01:53:45 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 292c735ce8 Update dependencies (#3932)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-19 01:45:07 +02:00
Koen Kanters 3123dd5abb Add update_deps.yml 2020-07-19 01:29:32 +02:00
Koen Kanters 1f39ff6f57 Fix transition from device_options not applied. #3922 2020-07-19 00:04:39 +02:00
Koen Kanters 0e0a364da7 Validate experimental.output settings. #3928 2020-07-18 23:40:23 +02:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 38bf81ed84 Update zigbee-herdsman to 0.12.108 (#3931)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2020-07-18 23:04:18 +02:00
Koen Kanters 0cc80632da Merge branch 'master' into dev 2020-07-18 23:03:42 +02:00
Koen Kanters d07d90fe33 Fix CI not triggering on automatic PR 2020-07-18 23:03:33 +02:00
Koen Kanters a845d35b8e Update Birth & Will Topic for Home Assistant #3918 2020-07-16 23:16:59 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
570985b877 Update zigbee-herdsman-converters (#3917)
* Update zigbee-herdsman-converters to 12.0.140

* Update publish.test.js

* Update publish.test.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-16 22:59:30 +02:00
Koen Kanters 7d2ac63482 Merge branch 'master' into dev 2020-07-16 22:53:42 +02:00
Koen Kanters f8463d9bb0 Fix pr not triggering checks 2020-07-16 22:53:30 +02:00
Artyom DudarevandKoen Kanters 1223a06871 Add support for Lonsonho switches (#3901)
* Add support for Lonsonho switches

* Use cfg.switch for 1 gang switch

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-16 22:40:40 +02:00
Hannes GiesenowandKoen Kanters ec688cfa04 Add support for Osram Smart Switch 4x (#3242)
* Add support for Osram Smart Switch 4x

See https://github.com/Koenkk/zigbee-herdsman-converters/pull/1112 for
the converter

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-16 22:35:16 +02:00
Koen Kanters d140c55252 merge branch 'master' into dev 2020-07-16 22:17:04 +02:00
Koen Kanters 9b382595ea Add ci.yml 2020-07-16 22:16:55 +02:00
Koen Kanters 2de44b3f7d Prevent future merge conflicts on automatic updates. 2020-07-16 21:13:03 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
9b9eb84f4e Update zigbee-herdsman to 0.12.107 (#3916)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-16 21:12:04 +02:00
Mark SnellingandKoen Kanters 64e9d65b07 Added AOne 250w Smart Dimmer Module (#3915)
* Create update_zhc.yml

* Update update_zhc.yml

* Update update_zhc.yml

* Added AOne 250w Smart Dimmer Module

* Delete update_zhc.yml

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-16 21:10:05 +02:00
Koen Kanters 237019282d Add update_zh.yml 2020-07-16 21:06:30 +02:00
Koen Kanters 08a6c1a724 Update update_zhc.yml 2020-07-16 21:06:30 +02:00
Koen Kanters f93a1c8e29 Update update_zhc.yml 2020-07-16 21:06:30 +02:00
Koen Kanters ec50d3ec0c Create update_zhc.yml 2020-07-16 21:06:30 +02:00
github-actions[bot]github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>Koen Kanters
f86be3308e Update zigbee-herdsman-converters (#3914)
* Update zigbee-herdsman-converters to 12.0.139

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-16 21:04:47 +02:00
Koen Kanters e6df6c585a Add update_zh.yml 2020-07-16 20:49:04 +02:00
Koen Kanters 900ae813e9 Update update_zhc.yml 2020-07-16 20:32:47 +02:00
Koen Kanters 0a69b98dfb Update update_zhc.yml 2020-07-16 19:40:58 +02:00
Koen Kanters 7a992fa180 Create update_zhc.yml 2020-07-16 19:29:47 +02:00
Koen Kanters 67f02adbd0 Prefer blocklist/passlist over blacklist/whitelist 2020-07-15 23:22:32 +02:00
Koen Kanters ee9aedd0f3 Discover Home Assistant energy sensor for NET2GRID N2G-SP. #3909 2020-07-15 23:17:54 +02:00
Koen Kanters ff1a64b192 Change ID -> id for new api. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-15 22:16:18 +02:00
Koen Kanters 62b26ab4b9 Fix tests 2020-07-14 22:09:11 +02:00
Koen Kanters c900213218 Update converters 2020-07-14 22:04:33 +02:00
Koen Kanters 8415adc514 Make new api snake case. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-13 23:00:33 +02:00
Koen Kanters 57a2d435a9 Republish groups on change. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-13 21:45:44 +02:00
Koen Kanters ff8f16fedb Group MQTT api. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-12 23:50:15 +02:00
Koen Kanters d81f5575ff Bind for new api. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-12 21:56:11 +02:00
Koen Kanters d3b7fe222f Update herdsman and converters. 2020-07-12 17:14:56 +02:00
Koen Kanters e7a799d8cc Update converters 2020-07-12 15:42:33 +02:00
Jeremy Rea b76b244af7 Add Home Assistant support for Sinopé water leak detector (#3892) 2020-07-12 15:18:53 +02:00
TheMClaeysandKoen Kanters eac948498a Update homeassistant.js (#3889)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-12 14:52:30 +02:00
Koen Kanters 11a4759a9a Update converters 2020-07-10 22:09:28 +02:00
Koen Kanters b1a4926a30 Add cache_state_persistent and cache_state_send_on_startup options. #3496 2020-07-10 22:09:16 +02:00
Ryan Kim(True-World) 051d088172 Add PM-B540, TS0115 (#3886)
Support Dawon PM-B540,
UseeLink TS0115(https://ko.aliexpress.com/item/4000108371113.html?spm=a2g0o.productlist.0.0.55f169eaiSgWdl&algo_pvid=a2d855e8-89cc-42ea-ab68-8b04c981c537&algo_expid=a2d855e8-89cc-42ea-ab68-8b04c981c537-1&btsid=0ab6f82c15943852972118657e0a09&ws_ab_test=searchweb0_0,searchweb201602_,searchweb201603_)
TS0115 Model is multi type(EU, US, UK, Universal, Etc.) and 2 type Amp(10A, 16A)
2020-07-10 21:32:54 +02:00
Koen Kanters b4a6c6f0ba Update herdsman and converters 2020-07-09 22:00:17 +02:00
4fbfec3fdb ptvo.switch - updated HA integration settings. (#3880)
* ptvo.switch - updated HA integration settings.

* Update homeassistant.js

Co-authored-by: ptvoinfo <xagga@ya.ru>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-09 21:10:10 +02:00
krenclandKoen Kanters c72ccf1bd7 added LED controller YSRSAI ZB-CL01 support for hass.io (#3876)
* added LED controller YSRSAI ZB-CL01 support for hass.io

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-07-09 20:55:54 +02:00
Koen Kanters 0a84412d75 Implement OTA commands for new api. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-08 23:23:44 +02:00
Koen Kanters f1c785eedd Implement new api configure. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-07-08 21:46:00 +02:00
Koen Kanters ff5d11b50a Update converters 2020-07-07 22:41:16 +02:00
Koen Kanters 903e93845c Update herdsman 2020-07-07 21:27:08 +02:00
Koen Kanters ffa47b79e3 Remove devices from group when removing group. #3861 2020-07-07 21:16:35 +02:00
Koen Kanters 49ebf66b0b Update converters 2020-07-06 23:19:12 +02:00
Pedro Lamas 973f5c5d03 Adds support for Sunricher ZG2835RAC power and energy monitoring in Home Assistant (#3860) 2020-07-06 21:46:07 +02:00
Koen Kanters 22387fd637 Don't provide defaults for rtscts and baudrate (#3854)
* Don't provide defaults for rtscts and baudrate

* Update herdsman
2020-07-06 21:37:58 +02:00
Koen Kanters df5f740518 Update converters 2020-07-04 16:20:15 +02:00
Koen Kanters 8f725d38bd Update converters 2020-07-03 23:00:25 +02:00
Koen Kanters 4900a2501d Support Home Assistant configuration for external converters. https://github.com/Koenkk/zigbee-herdsman-converters/issues/1343 2020-07-03 21:20:22 +02:00
Koen Kanters 1796ba191c Update herdsman and converters 2020-07-01 22:15:02 +02:00
Jiří Furda e8c7314e90 Add support for IMMAX 07115L (#3829) 2020-06-30 17:49:43 +02:00
Koen Kanters 4b75fdb8a3 Dev 2020-06-30 17:40:05 +02:00
Koen Kanters 7e46435d86 1.14.1 2020-06-30 17:38:48 +02:00
Koen Kanters 1133e8e1ab Undev 2020-06-30 17:37:57 +02:00
Koen Kanters a74597ec85 Update converters 2020-06-29 19:52:31 +02:00
Koen Kanters a391f7dcf9 Update converters 2020-06-29 17:01:45 +02:00
Koen Kanters 715e20477d Small cosmetic 2020-06-29 16:17:11 +02:00
John Doe def6bf1d0b Implement external converters (#3810) 2020-06-29 16:16:16 +02:00
Koen Kanters 4b68a482b7 Update herdsman and converters 2020-06-28 18:31:21 +02:00
felixstorm 1b62a3cf06 Fix Reporting for Multi-Endpoint Devices (#3824)
* fix reporting on multi-endpoint devices

* add test
2020-06-28 18:08:37 +02:00
Koen Kanters 27972fb8d4 Provide lx unit for RTCGQ11LM illuminance sensor. #3805 2020-06-24 23:43:24 +02:00
qosmio 1e62021418 Add support for Sylvania Flex XL RGBW Strip (73773) (#3806) 2020-06-24 23:39:09 +02:00
Koen Kanters ade6123ede Home Assistant discover illuminance_lux sensor for RTCGQ11LM. #3805 2020-06-24 23:28:33 +02:00
Thomas Rose 242600f2b6 Added new Innr Outdoor Lights (#3796)
Added support for Innr Outdoor Spot Lights and Outdoor Color LED Strip
2020-06-24 15:30:18 +02:00
Koen Kanters c07c1d5f15 Update herdsman 2020-06-23 11:19:32 +02:00
Koen Kanters fb0f83dee7 Update converters 2020-06-22 15:24:50 +02:00
Koen Kanters 869d6a5234 Fix reporting setup ddosing adapter. #3756 2020-06-21 16:38:23 +02:00
Koen Kanters 48705c9a9e Fix not connecting to MQTT when permit join fails on startup. #3756 2020-06-21 16:36:36 +02:00
Koen Kanters 95208a1a2e Update converters 2020-06-20 16:06:54 +02:00
KrzysztofandKoen Kanters 1dd002e73f HGZB-44 HomeAssistant Autodiscovery support (#3775)
* Add homeassistant autodiscovery support for HGZB-44.

* Fix missing , at end of line

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-06-20 14:26:35 +02:00
Andreyanddivanikus 76745ca5c3 ZNCZ04LM extended attributes support (#3761)
* ZNCZ04LM extended attributes support

* Styles fixes

* Style fix

* Tabs

Co-authored-by: divanikus <d1pro@yandex.ru>
2020-06-17 19:54:08 +02:00
zrsmithsonandSmithson, Zachary <zachary.smithson@gtri.gatech.edu> 249bcff7d1 Add support for Ecosmart BR30 CCT Bulb A9BR3065WESDZ02 (#3751)
device similar to Ecosmart A19 CCT bulb

Co-authored-by: Smithson, Zachary <zachary.smithson@gtri.gatech.edu>
2020-06-16 17:05:37 +02:00
Koen Kanters f8d082e18d Networkmap #3281 2020-06-15 20:10:30 +02:00
Koen Kanters 79b4dbd24f Touchlink factory reset #3281 2020-06-15 19:19:57 +02:00
Koen Kanters 62dc88ec87 Republish bridge info on log level changes #3281 2020-06-15 19:06:08 +02:00
Koen Kanters d10c1c2155 Add some config options #3281 2020-06-15 18:58:32 +02:00
Koen Kanters 5027e97bb6 Update converters 2020-06-15 17:42:46 +02:00
Koen Kanters e0f5547160 Update converters 2020-06-14 18:01:25 +02:00
KostaandKonstantin Baumann b42c61d09a use relative timestamps (#3743)
Use relative timestamps for the network map (e.g, `1 hour, 43 minutes ago` or `15 minutes, 10 seconds ago`), since that is easier to understand/decode than the standard ISO timestamps.

This introduces an additional (light weight) dependency to [humanize-duration](https://github.com/EvanHahn/HumanizeDuration.js) which in itself doesn't have any additional dependencies.

Co-authored-by: Konstantin Baumann <konstantin.baumann@autodesk.com>
2020-06-14 17:43:27 +02:00
Koen Kanters c9aa8b24c0 Update converters 2020-06-14 16:27:47 +02:00
KostaandKonstantin Baumann a2ea520b0c add support for plantuml based network graphs (#3742)
Add support for [PlantUML](http://plantuml.com/guide) based network graphs, which can be pasted into [this online editor](https://www.planttext.com/).

The test configuration used for unit testing for example produces this output:

![output.svg](https://www.planttext.com/api/plantuml/svg/j5LTRzem57tVhxYFGSFbEbyG7gOoOBHggrMCQPsg2Zc9KwmwSPeufTjVsyD-qlx20dICZuJni4PHPDdtd7lkyRNpwyTFU7bESyqoNSJopP-PW6KXu3CYRNSwID7cjkEO3jok8_ONrqk4a0DXOBYEvJOWOaBoi0loKJGpLMYHt4-OBtabpNl58qYK_bIagSeq3wzKoENve3AOUcqaICjtWhIBs4NwTZbOHzojH_iLe--qeoZYWSiStzoes2-aNrlZ3igmqNAzHcNu-SMm1vDnR_1XV0wNmy6I68QcsngQRV0w2BA8UTA4KCJnmf4cp6T2SyXJ7kYiY9kWKYPV9esIWJgsCw9cTRh_w8QruyOqK59bntbYBJtnQZovdWafqXpE2WuZ1KQRsYwwU7rM7Lua3ucQ9qTLiDLzTAi2hLKo3LLHUZnzuD-EQs2wRE1EjR0RmLGieFV8CWOhPYYPOIuoBdcUmvn92VbSw606nfURYn6QbrUliN6RcXrle-mWC1qBfuiZn-ltRWTUbcnZjSn-aMiLGyYVHC1pC0RYQmDk-_r55bXbkJDcMgVTLYlLJ-f4995ghLGGd-Ky9D_5lSyv2PJAGf4mhJB2af2im8HIizK0OyLuClxuUJ8SlufZfkqllaXjc_4Dn_f_TTNxjGqsQipQKqZntmehpX8XxohITg4S7RgMwc2UUKooRR8o6SL3FLCBmtfOURhM6hVOIfY5-zQSyYHS_BT-0m00__y30000)

The generated script looks like this:

```
' paste into: https://www.planttext.com/

@startuml
card 0x0017880104e45525 [
0x0017880104e45525
---
0x0017880104e45525 (6536) failed: lqi,routingTable
---
Boef notSupportedModelID
---
1970-01-01T01:00:01+01:00
]

card 0x000b57fffec6a5b2 [
bulb
---
0x000b57fffec6a5b2 (40369)
---
IKEA TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white (LED1545G12)
---
1970-01-01T01:00:01+01:00
]

card 0x000b57fffec6a5b3 [
bulb_color
---
0x000b57fffec6a5b3 (40399)
---
Philips Hue Go (7146060PH)
---
unknown
]

card 0x0017880104e45521 [
button_double_key
---
0x0017880104e45521 (6538)
---
Xiaomi Aqara double key wireless wall switch (WXKG02LM)
---
1970-01-01T01:00:01+01:00
]

card 0x0017880104e45559 [
cc2530_router
---
0x0017880104e45559 (6540)
---
Custom devices (DiY) [CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/) (CC2530.ROUTER)
---
1970-01-01T01:00:01+01:00
]

card 0x00124b00120144ae [
Coordinator
---
0x00124b00120144ae (0)
---
1970-01-01T01:00:10+01:00
]

0x000b57fffec6a5b3 --> 0x00124b00120144ae: 120
0x000b57fffec6a5b2 --> 0x00124b00120144ae: 92
0x000b57fffec6a5b3 --> 0x000b57fffec6a5b2: 110
0x0017880104e45559 --> 0x000b57fffec6a5b2: 100
0x0017880104e45521 --> 0x0017880104e45559: 130

@enduml
```

Co-authored-by: Konstantin Baumann <konstantin.baumann@autodesk.com>
2020-06-14 15:48:50 +02:00
Koen Kanters 40f026cdf8 Update converters 2020-06-14 14:07:35 +02:00
jd1900andKoen Kanters 67c43fcee3 Add device '412015' from Legrand. DIN power consumption module. (#3739)
* Add device '412015' from Legrand. DIN power consumption module.

Add device '412015' from Legrand. DIN power consumption module. Complementary for this pull request https://github.com/Koenkk/zigbee-herdsman-converters/pull/1313

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-06-14 14:01:02 +02:00
AndronicR 1dd3523e64 added for homeassistant (#3737) 2020-06-14 11:00:36 +02:00
Koen Kanters 37122dba79 changeOptions -> options. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-06-14 00:28:24 +02:00
Koen Kanters 7f8fbe8b65 Lint 2020-06-13 23:46:04 +02:00
Koen Kanters 3658588618 Add group #3281 2020-06-13 23:42:58 +02:00
Koen Kanters a90ebce677 Change device options. #3181 2020-06-13 23:28:06 +02:00
Koen Kanters 7b3c07dcfe Implement renaming functionallity. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-06-13 19:35:09 +02:00
Koen Kanters 16f5812f6c Finish remove api. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-06-13 17:22:00 +02:00
Koen Kanters 1eed937c43 Update converters 2020-06-13 15:52:48 +02:00
Gabriele Besta e0a6b7d348 Add possibility to override execution command at runtime (#3722)
* Add possibility to override execution command at runtime

The entrypoint script initialize container data at runtime.
CMD defines the default executable and can be overridden at runtime.

* Set execution permission to entrypoint script

Necessary to prevent run errors, for example in windows env
2020-06-13 13:20:41 +02:00
Koen Kanters 4b845f923e Pass down logger to fromZigbee converters. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1305#pullrequestreview-430027596 2020-06-13 12:55:01 +02:00
Esteban Zapata Rojas 50ba54e99e new device: Auto discovery configuration for RS-23ZBS devices on HA. (#3720) 2020-06-12 22:32:50 +02:00
Koen Kanters c6e76165ff Always convert syslog type to string. https://github.com/Koenkk/zigbee2mqtt/issues/3725 2020-06-12 16:51:49 +02:00
ahaghshenas cecedbd5f8 Update homeassistant.js (#3718) 2020-06-11 21:33:29 +02:00
Koen Kanters c3561640e6 Update converters. 2020-06-10 21:20:43 +02:00
Koen Kanters c3a71ba6a8 Dev 2020-06-10 16:42:53 +02:00
Koen Kanters 9009de24ac 1.14.0 2020-06-10 16:42:27 +02:00
Koen Kanters a5b0c80a2e Undev 2020-06-10 16:42:24 +02:00
Koen Kanters d9391ac685 Update herdsman 2020-06-10 16:41:08 +02:00
Koen Kanters 2bdb0f9ae1 Merge branch 'master' into dev 2020-06-10 16:36:37 +02:00
Koen Kanters 56714d7c5a Update converters. 2020-06-09 19:52:48 +02:00
Koen Kanters 7dee99df52 Add colortemp_move for group. #3705 2020-06-09 19:37:45 +02:00
Koen Kanters e5f9a969ac Discovery Home Assistant battery sensor for Danalock V3. #3702 2020-06-09 19:24:47 +02:00
Koen Kanters 206a45d29a Update converters. 2020-06-07 13:58:28 +02:00
sprockersandKoen Kanters c14e18dabb Adding homeassistant mapping for Hive DWS003 contact sensor (#3682)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-06-07 13:25:52 +02:00
sprockers 3566af1b08 Removing illuminance from Hive MOT003 (#3685) 2020-06-07 13:23:45 +02:00
Mark BergsmaandKoen Kanters a7adfebcb3 Add discovery support for the Plugwise Plug 160-01 (#3679)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-06-07 11:36:04 +02:00
Koen Kanters f8ea6cb574 Update converters. 2020-06-06 14:45:43 +02:00
Mattia480andKoen Kanters d66e1c322b Add EchoStar SAGE by Hughes Doorbell Sensor (SAGE206612) (#3675)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-06-06 14:12:41 +02:00
Koen Kanters 43127e95a9 Fix lint 2020-06-06 13:13:09 +02:00
Koen Kanters 976e802af8 Update converters. 2020-06-06 10:31:50 +02:00
Dominik Röttsches 32b96d1d4c Add homeassistant mapping for Ledvance Z3 Tunable White Panel (#3666)
See https://github.com/Koenkk/zigbee-herdsman-converters/pull/1279
2020-06-06 09:52:58 +02:00
Koen Kanters 7f68fd3fc4 Initial syslog logging. #3647 2020-06-03 20:44:11 +02:00
Koen Kanters 6d9dff8832 Mark node 14 as supported. #3660 2020-06-03 19:37:11 +02:00
Koen Kanters 8dc535e3e3 Update converters 2020-06-02 18:45:29 +02:00
Koen Kanters fda1246fca Attempt to fix lastSeen incorrect leading to incorrect offline state. #3650 2020-06-01 16:38:24 +02:00
Koen Kanters a9b54ad668 Update converters 2020-06-01 16:37:16 +02:00
Koen Kanters c0d4aea5bd Fix lint 2020-05-31 15:02:25 +02:00
Koen Kanters d440de8069 Fix networkmap error when using Gledopto GL-C-008-2ID. #3623 2020-05-30 18:27:25 +02:00
Koen Kanters e4c3ffe38d Update converters 2020-05-30 17:11:54 +02:00
Will UtherandKoen Kanters 7c045af987 Add a brief internal architecture description. (#3639)
* Add Stitchy Dim to list of devices.

* Add an internal architecture paragraph.

Add a README paragraph with a basic architecture description.  This doesn't have a lot of detail, but links to docs with (much) more detail.

* Try to line up with upstream.

* Update README.md

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-05-30 16:03:57 +02:00
Koen Kanters 2cb234c934 Update dependencies. #3616 2020-05-30 16:01:47 +02:00
Crowbar ZandKoen Kanters 51a6b9226d Remove precision rounding from HA MQTT autodiscovery template (#3636)
* Remove precision rounding from HA MQTT autodiscovery template

Precision rounding should be handled in converters and made available to
all MQTT consumers (not just HA)

* Update homeassistant.test.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-05-29 23:13:09 +02:00
Koen Kanters 7d1a97841c Update herdsman and converters. 2020-05-29 23:09:09 +02:00
JaydenandKoen Kanters 9c71ba8754 Support E1E-G7F (#3630)
I couldn't see battery data in the output so I have only added the sensor_action type. This works and home assistant can see button presses + link quality.

This is linked to: https://github.com/Koenkk/zigbee-herdsman-converters/pull/1265

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-05-29 19:39:32 +02:00
Koen Kanters 5f63dcb0f2 Fix old state being published due to debounce. #3572 2020-05-29 19:24:59 +02:00
Koen Kanters 89a6c976cb Update converters 2020-05-28 19:49:38 +02:00
Koen Kanters f793eab4ab Republish availability on MQTT connected. #3625 2020-05-28 17:44:50 +02:00
Jonas Bergler d5604ab5ec Make thermostat more like thermostatHeatCool (#3613)
* Make thermostat more like thermostatHeatCool

This change tries to unify the two thermostat templates a little.
I'm making this change because I wanted to enable tracking the current
state of the Zen thermostat and noticed that the logic was very specific
to a subset of thermostats.

The matching change in zigbee-herdsman-converters ensures that the
thermostats that were sending the "operation" field use the new format
and should effectively behave the same after the change.

* 0.5 degree steps for Zen thermostat

Because it supports it.
2020-05-27 16:26:55 +02:00
Koen Kanters 780246fe74 Fix typo 2020-05-26 17:36:04 +02:00
Koen Kanters b706233604 Fix lint. 2020-05-25 22:05:34 +02:00
Koen Kanters c4ce339942 Update converters. 2020-05-25 22:04:30 +02:00
Koen Kanters 409fb2407a #3281 Add tests for new bridge API 2020-05-24 18:16:39 +02:00
Koen Kanters 1638b81723 Update converters 2020-05-24 15:57:29 +02:00
Koen Kanters 396bdf5592 Update converters 2020-05-24 14:41:40 +02:00
sswongandKoen Kanters 89b9b84f94 add support for QBKG22LM-aqara-double-key-wall-switch-without-neutral (#3600)
* add support for QBKG22LM-aqara-double-key-wall-switch-without-neutral (updated model variant)

* removed tab

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-05-24 14:19:51 +02:00
Koen Kanters 770a7e77e7 Update converters 2020-05-23 20:53:20 +02:00
Koen Kanters 49df5751b2 Log friendly error when endpoint does not exist on device. https://github.com/Koenkk/zigbee-herdsman-converters/issues/125 2020-05-23 20:48:07 +02:00
f594664f55 add support for WXKG06LM-aqara-single-key-wireless-wall-switch (#3593)
* add support for WXKG06LM-aqara-single-key-wireless-wall-switch

* Update homeassistant.js

Co-authored-by: sswong <saiseng.wong@wizvision.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-05-22 18:33:05 +02:00
Koen Kanters d9b8e1fc18 Fix messages being skipped for Xiaomi devices with Deconz adapter. #3592 2020-05-22 18:25:32 +02:00
Koen Kanters 94dbf9c505 Fix not able to read state from multiple endpoints at once. https://github.com/Koenkk/zigbee-herdsman-converters/issues/1252 2020-05-22 18:16:53 +02:00
Koen Kanters 83215c3290 Update converters. 2020-05-21 15:47:01 +02:00
Andrew N Golovkov adcec74f23 added Aqara Opple MX650 aka XDD12LM (#3579) 2020-05-21 14:55:37 +02:00
Koen Kanters 7e6c508263 Fix number action causing exception in Home Assistant extesion. #3578 2020-05-21 14:52:02 +02:00
Koen Kanters b2034943a5 Update converters. 2020-05-21 12:21:15 +02:00
Koen Kanters 6e382516cb Dev 2020-05-20 16:52:49 +02:00
Koen Kanters 3046680f61 1.13.1 2020-05-20 16:52:20 +02:00
Koen Kanters f206945506 Undev 2020-05-20 16:52:04 +02:00
Koen Kanters 2e96c8b03a Update converters 2020-05-20 16:51:11 +02:00
Koen Kanters 43699e133a Update converters. 2020-05-19 20:02:26 +02:00
Ryan Kim(True-World) a293b665b4 ADD DOWON_NEW_SW (#3570)
'PM-S140-ZB': [cfg.switch],
    'PM-S240-ZB': [switchEndpoint('top'), switchEndpoint('bottom')],
    'PM-S340-ZB': [switchEndpoint('top'), switchEndpoint('center'), switchEndpoint('bottom')],
2020-05-19 19:50:24 +02:00
Koen Kanters ad9421a9b0 Update converters. 2020-05-18 18:59:15 +02:00
Koen Kanters 134f67134b Update herdsman 2020-05-17 19:11:36 +02:00
Koen Kanters c7fddbc6e3 Fix devices not discovered in Home Assistant when repaired. https://github.com/home-assistant/core/issues/35684 2020-05-17 13:45:11 +02:00
Koen Kanters 29e5b9682c Update herdsman. 2020-05-17 13:44:02 +02:00
John Doe 33bed2bbfb Add more enpoins names for validation (#3552) 2020-05-15 16:54:36 +02:00
Koen Kanters 528539214c Also respect device_options for Home Assistant device specific configuration. #3541 2020-05-14 19:03:54 +02:00
Koen Kanters 855e9e0eb1 Don't add lastSeen to state. #3545 2020-05-14 18:47:27 +02:00
Michael Barrett 845bed4e11 add energy sensor for salus SP600 (#3551) 2020-05-14 18:39:48 +02:00
Michael Barrett 8e49dab722 add energy sensor for GP-WOU019BBDWG (#3550)
Simple metering support added for device in https://github.com/Koenkk/zigbee-herdsman-converters/pull/1234
2020-05-14 18:39:30 +02:00
kjkim74andKyungJong Kim 9a28f116b1 add support ECW-100-A03 (#3538)
Co-authored-by: KyungJong Kim <kyungjong74@gmail.com>
2020-05-12 17:57:08 +02:00
Koen Kanters cb64a865d9 Add requested_brightness_level and requested_brightness_percent Home Assistant sensor for IKEA E1745. #3535 2020-05-12 17:53:45 +02:00
Koen Kanters 520f59f47c Update converters 2020-05-11 18:35:45 +02:00
relaystarandTom Seeley c88666bde7 adding RS 229 T (#3527)
Co-authored-by: Tom Seeley <tom@tomseeley.co.uk>
2020-05-11 17:46:15 +02:00
Jussi Heikkilä 24a85abcd8 GL-C-008-2ID: White endpoint color temp control in Home Assistant (#3526) 2020-05-11 17:31:33 +02:00
hamsandoandKoen Kanters 8929544a12 Added ZBHT-1 (#3522)
* Added ZBHT-1

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-05-11 17:12:16 +02:00
Koen Kanters fed84cfd5e Update converters. 2020-05-09 16:32:24 +02:00
Koen Kanters 739e6fb66b Update converters. 2020-05-09 16:10:31 +02:00
Koen Kanters 2a6659582b Update herdsman. 2020-05-08 20:29:32 +02:00
Koen Kanters 3f8371bef2 Update azure-pipelines.yaml 2020-05-08 17:05:20 +02:00
Koen Kanters 3d79688ffd Update azure-pipelines.yaml 2020-05-08 16:50:46 +02:00
Koen Kanters 3795562383 More new api stuff. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-05-07 19:41:03 +02:00
Koen Kanters f816c8e740 Update converters. 2020-05-07 19:38:01 +02:00
nukusinji b2331da671 Update homeassistant.js (#3506)
Add Support TS0601
2020-05-07 19:32:26 +02:00
Koen Kanters e7e752a032 Dont log No converter available for.. on genTime messages. #3503 2020-05-07 18:01:09 +02:00
RicoGeandKoen Kanters fe0919d02a Added Linkind Door/Window Sensor Homeassistant config (#3500)
* Added Linkind Door/Window Sensor Homeassistant config

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-05-06 20:01:06 +02:00
Koen Kanters 5aedf6b2ee Fix lint 2020-05-05 13:43:37 +02:00
Koen Kanters 5244fa0ed8 Update herdsman and converters. 2020-05-05 10:42:40 +02:00
Koen Kanters 856ecf47f1 Start on new API implementation. #3281 2020-05-04 20:06:50 +02:00
Koen Kanters 772f6c0bde Update converters. 2020-05-04 15:11:17 +02:00
Arno Moonen ff61695355 Fix Home Assistant discovery for GL-FL-004TZS. See Koenkk/zigbee2mqtt#3480 (#3484) 2020-05-04 11:33:58 +02:00
Niall McAndrew 07446ce1c1 Add temp and consumption to ZNCZ02LM (#3476) 2020-05-04 11:21:49 +02:00
dramamoose 20df5e5639 Add AE 260 to homeassistant.js (#3473) 2020-05-02 13:56:16 +02:00
presslab-us 7ae77ea528 Fixes for homeassistant thermostatHeatCool (#3466)
Remove 'auto' mode for 3157100 thermostat
unit_of_measurement in JSON should be temperature_unit
2020-05-02 13:47:02 +02:00
presslab-us bf1111edcb Support leakSMART water leak sensor (#3465) 2020-05-02 13:44:36 +02:00
Markus Pfeiffer 4c57323eae Add Dresden ballast Homeassistant companion (#3452) 2020-05-02 13:33:54 +02:00
Koen Kanters 90d8326e0c Update herdsman. 2020-05-02 11:33:23 +02:00
Koen Kanters e792f8bc8c Prevent sending Home Assistant discovery messages when not connected to MQTT yet. #3451 2020-04-30 19:06:17 +02:00
Igor Gocalinski a12d9fb73e Add temp sensor for QBKG11LM switch. (#3458)
Xiaomi Wired Single Switch QBKG11LM does support temperature readout
2020-04-30 18:41:35 +02:00
swissbyteandKoen Kanters cb47c12b55 Added new device DTB-ED2004-012 and added new cfg light_switch (#3439)
* added new device and added new cfg light_switch

* Added new device DTB-ED2004-012 and added new cfg light_switch

* added cfg.switch to generic ED2004-012

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-30 18:39:58 +02:00
Koen Kanters 26e2757df6 Update converters. 2020-04-29 21:44:26 +02:00
Koen Kanters dabc944cd3 CC2530.router: state -> led. https://github.com/Koenkk/zigbee2mqtt/issues/3414 2020-04-29 21:27:58 +02:00
575e6fd4a3 3321 fixes (#3434)
* Add home assistant mapping for hive MOT003

* fix pipeline

* remove garbage

* Added 3321 battery sensor

* Update homeassistant.js

Co-authored-by: Iain Matchett <iain.matchett@beeksfx.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-29 21:18:30 +02:00
matchett808-ghandIain Matchett 305cb259b3 Add home assistant mapping for hive MOT003 (#3429)
* Add home assistant mapping for hive MOT003

* fix pipeline

* remove garbage

Co-authored-by: Iain Matchett <iain.matchett@beeksfx.com>
2020-04-29 17:36:49 +02:00
Jose Luis PedrosaandKoen Kanters 04bd928f3a Add support to home assistant for ZL1000700-22-EU-V1A02 (#3448)
* Add support to home assistant for ZL1000700-22-EU-V1A02 + missing devices

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-29 17:27:16 +02:00
Koen Kanters e0ba80249c Dev 2020-04-29 17:09:38 +02:00
Koen Kanters 55e628398b 1.13.0 2020-04-29 17:09:06 +02:00
Koen Kanters 835bba5414 Undev 2020-04-29 17:09:01 +02:00
Koen Kanters ce62f43edf Update converters. 2020-04-28 21:53:17 +02:00
Koen Kanters 7c0e1b0c65 Don't throw exception when device requets OTA but does not have OTA endpoint. #3339 2020-04-28 21:23:32 +02:00
Koen Kanters 4a6a88e0e8 Update converters. 2020-04-28 17:04:28 +02:00
Viet Dzung 89f1c709aa Support DIY DNCKAT_D001 dimmer (#3441) 2020-04-28 16:50:05 +02:00
Koen Kanters 785601476e Fix order of commands when turning bulb on. 2020-04-26 18:18:20 +02:00
dramamooseandKoen Kanters 134712322f Add support for Sengled Extra Bright A19 bulbs (#3425)
* Add support for Sengled Extra Bright A19 bulbs

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-26 10:29:53 +02:00
Koen Kanters d8ec59bd9f Don't add coordinator to configuration.yaml. #3421 2020-04-24 22:43:35 +02:00
Koen Kanters 48641f3028 Fix OTA percentage. #3422 2020-04-24 22:38:51 +02:00
James BrechtelandKoen Kanters 265d5c4877 Support Linkind PIR motion in HA (#3423)
* Support Linkind PIR motion in HA

This marks the Linkind PIR motion sensor as having
binary_sensor_occupancy with HomeAssistant.

The sensor likely has additional capabilities like battery reporting but
I don't know how to make sense of the rest of its information yet.

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-24 22:31:42 +02:00
Koen Kanters 63ecc1501d Update converters. 2020-04-23 22:36:17 +02:00
Jorge Schrauwen f0f7905782 Also pass settings to Extensions (#3410)
* Also pass settings to Extensions

* Swap order of settings and logger
2020-04-23 22:02:00 +02:00
Koen Kanters d073a7fc7a Fix lint. 2020-04-22 19:36:03 +02:00
Koen Kanters 4b0e427e6c Update converters. 2020-04-22 19:30:20 +02:00
Jorge SchrauwenandKoen Kanters 8d70ebd91a Don't try and load non .js extensions (#3409)
* only try and load extensions ending in .js

* Update controller.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-22 18:52:09 +02:00
freakshock88 99acd3b50f Added GL-FL-006TZ to homeassistant.js (#3408) 2020-04-21 22:31:02 +02:00
Koen Kanters f0ca71648b Pass down logger to extension. #3279 2020-04-21 22:15:12 +02:00
Koen Kanters d22e73ebb4 #3271 Allow to randomize network_key by settings 'network_key: GENERATE' 2020-04-21 21:58:43 +02:00
Philipp KolmannandKoen Kanters e1f9a3910d Update Invalid rename message format expected to be proper json (#3397)
* Update Invalid rename message format expected to be proper json

The example in the 'Invalid rename message format expected' error message, was not proper JSON and missing the last string end

* Updates

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-20 19:38:55 +02:00
Koen Kanters c0ed4aa9cc Update converters. 2020-04-19 20:15:08 +02:00
Koen Kanters a8793ab60b Load extensions from data directory. https://github.com/Koenkk/zigbee2mqtt/issues/3297 2020-04-19 20:08:24 +02:00
Koen Kanters 11fd5ffde6 Refactor 2020-04-19 18:10:53 +02:00
statte d00a1fed30 Update to support Zipato RGBW LED Bulb 2 (#3386) 2020-04-18 14:44:22 +02:00
Koen Kanters 9d6c7b2614 Revert "Use CMD alongside ENTRYPOINT in the Dockerfile (#3366)" (#3389)
This reverts commit d193673917.
2020-04-18 14:34:21 +02:00
Dominik 2177b33712 Add Zemismart ZM79E-DT as Home Assistant cover (#3377) 2020-04-17 16:47:59 +02:00
Jorge Schrauwen 4a771a75df Sort state/brightness to front or back depending on bulb state (#3368) 2020-04-16 21:42:47 +02:00
Koen Kanters c9298c5606 Update herdsman. 2020-04-16 21:35:19 +02:00
Koen Kanters 07dc837b76 Refactor receive 2020-04-15 22:34:59 +02:00
Koen Kanters 67151fba04 Refactor bind 2020-04-15 20:36:40 +02:00
Koen Kanters a56c5cfe50 Fix exception in Home Assistant extension when device not mapped. #3302 2020-04-15 20:03:02 +02:00
Koen Kanters 383561cbc4 Update herdsman and converters. 2020-04-15 18:16:19 +02:00
Pranas Ziaukas d193673917 Use CMD alongside ENTRYPOINT in the Dockerfile (#3366)
This allows for runtime customization, see #3362.
2020-04-15 18:07:01 +02:00
Jorge Schrauwen 62254bb67a #3352 Apply brightness_percent before others (#3361)
As mentioned, simply adding brightness_percent seems to fix the problem.

I'll look into doing the reverse if the state is off when I have more time.
2020-04-14 22:36:22 +02:00
ghostcode 85b57cd639 Fix missing color temp for ZG2819S/511.344 (#3360) 2020-04-14 22:31:23 +02:00
Koen Kanters 838cb6e702 Update converters. 2020-04-13 21:15:08 +02:00
simonses1andKoen Kanters 38acbb0234 Update homeassistant.js (#3349)
added HALIGHTDIMWWE14 for HA discovery
https://github.com/Koenkk/zigbee-herdsman-converters/pull/1153 for converter PR

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-13 17:36:49 +02:00
Koen Kanters 74aefcca76 Don't log no converter warning for genOta messages. #1620 2020-04-13 17:18:45 +02:00
Koen Kanters 5c3cd99288 Update converters. 2020-04-13 11:40:43 +02:00
Koen Kanters 121eaf3dcb settingUp -> queue. https://github.com/Koenkk/zigbee2mqtt/commit/eab988640281d60deef827a2692a2f0a01578a3f#r38455677 2020-04-13 11:28:19 +02:00
Koen Kanters 22126a3e5d Refactor 2020-04-12 20:32:14 +02:00
Koen Kanters eab9886402 Refactor. 2020-04-12 18:29:52 +02:00
Koen Kanters bab71fb5ea Refactor 2020-04-12 17:04:47 +02:00
Koen Kanters 29762b2720 Update converters. 2020-04-12 10:19:12 +02:00
TePazz edab607f7d Add thermostat Stelpro SMT402AD and new code for ST218 (#3341) 2020-04-12 10:09:31 +02:00
Koen Kanters 0aedbe0db3 Merge remote-tracking branch 'origin/master' into dev 2020-04-12 10:07:37 +02:00
Koen Kanters bd5cb7790a Only subsribe to legacy topic when enabled. 2020-04-11 20:59:52 +02:00
Koen Kanters a2d09b08ea Refactor DeviceConfigure 2020-04-11 20:58:22 +02:00
Koen Kanters 0cc834b4b6 Fix tests 2020-04-11 20:47:25 +02:00
Koen Kanters 10a47df33b Refactor 2020-04-11 20:45:50 +02:00
Koen Kanters 9da1a35bbd Refactor. 2020-04-11 20:34:50 +02:00
Koen Kanters cc008db2ad Refactor 2020-04-11 18:31:57 +02:00
Koen Kanters ba0d930ddd DeviceAvailability -> Availability 2020-04-11 18:14:40 +02:00
Koen Kanters b8b4ff9ee7 baseExtension -> extension 2020-04-11 18:10:56 +02:00
Koen Kanters 1573687979 Refactor deviceAvailability.js 2020-04-11 18:04:00 +02:00
Koen Kanters 2ce2876f04 Refactor 2020-04-11 17:44:31 +02:00
Koen Kanters e1ec16042f GreenPower devices don't support a network scan. #3322 2020-04-11 17:11:09 +02:00
Koen Kanters 911cd58ef2 Update ISSUE_TEMPLATE.md 2020-04-11 16:43:54 +02:00
Koen Kanters 4cc0e5d88e Update herdsman. #3238 2020-04-11 16:24:58 +02:00
Koen Kanters 2dcc74f9c6 Update herdsman. 2020-04-11 15:20:15 +02:00
Koen Kanters 4f81b7aa0b Refactor 2020-04-11 15:18:17 +02:00
Koen Kanters 2d66145c6e Update converters. 2020-04-10 18:12:25 +02:00
Koen Kanters 7824f102c8 Update herdsman and converters. 2020-04-09 22:01:09 +02:00
Koen Kanters 4b6add19d5 GreenPower defintions. (#3321) 2020-04-09 21:54:26 +02:00
Koen Kanters 637ad8d2e6 Update converters. 2020-04-09 20:02:59 +02:00
Koen Kanters 6857f2ad5e Don't setup reporting for TS0001. #3311 2020-04-09 20:00:24 +02:00
Koen Kanters 272892b112 Merge branch 'master' into dev
# Conflicts:
#	npm-shrinkwrap.json
#	package.json
2020-04-09 17:52:52 +02:00
Koen Kanters 7d27a54f8f 1.12.2 2020-04-09 17:48:12 +02:00
Koen Kanters e1355aa2e0 Update herdsman 2020-04-09 17:48:08 +02:00
mario-1024andKoen Kanters 2c2af0603b Add Schwaiger ZHS-15/SPW35Z-D0 power socket (#3313)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-08 19:12:34 +02:00
Koen Kanters 3f058c317c Dev 2020-04-08 17:57:44 +02:00
Koen Kanters 23805c25af 1.12.1 2020-04-08 17:54:22 +02:00
Koen Kanters 0cffae8118 Undev 2020-04-08 17:54:17 +02:00
Koen Kanters 864e8b26d5 Update converters. 2020-04-06 21:39:06 +02:00
Koen Kanters ad48ea2af6 Update herdsman. 2020-04-06 19:14:55 +02:00
ghostcodeandKoen Kanters 418b3d1e5d Action and click trigger for multiple endpoints and 511.344 / ZG2819S support (#3289)
* Home Assistant support for ZG2819S/511.344

* Added 'homeassistant_legacy_triggers' support for devices with multiple endpoints

* Changed code style to pass lint test

* Reverted fix for the action and click trigger to send an empty message for devices with multiple endpoints

* Home Assistant support for the updated ZG2819S converter

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-05 21:53:18 +02:00
Koen Kanters 4970d1a927 Update herdsman. 2020-04-05 21:32:24 +02:00
Koen Kanters e71485cd50 Refactor 2020-04-05 20:36:09 +02:00
Koen Kanters 552eec7baa Isolate legacy MQTT log. #3281 2020-04-05 18:36:08 +02:00
Koen Kanters 9df1589361 Move stateChange event to event bus. 2020-04-05 15:48:23 +02:00
Koen Kanters 1e6f99d88f Don't cache properties which start with action_ 2020-04-05 15:41:48 +02:00
Koen Kanters 4fa9aaa0b2 Refactor 2020-04-05 15:41:24 +02:00
Koen Kanters 3ef7555ca2 Refactor 2020-04-05 00:05:05 +02:00
Koen Kanters e0076367d3 Start on legacy api isolation. https://github.com/Koenkk/zigbee2mqtt/issues/3281 2020-04-04 22:47:23 +02:00
Koen Kanters 903cec5760 Allow to disable log rotation. #3280 2020-04-04 19:46:43 +02:00
Koen Kanters 1d9d63062a Add missing devices to configuration. #3263 2020-04-04 19:15:24 +02:00
Jorge Schrauwen 1e28c4285b entityPublish now passes in meta.mapped as an array for groups (#3283) 2020-04-04 18:59:14 +02:00
Koen Kanters 98cf258489 Update converters. 2020-04-03 21:38:43 +02:00
Koen Kanters b15e4d1ad9 Update converters. 2020-04-03 19:19:52 +02:00
Kiall Mac Innes 1abb5b6a48 Fix conflict between illuminance and illuminance_lux (#3275)
* Fix conflict between illuminance and illuminance_lux

On certain devices, e.g. GZCGQ01LM, 9290012607, 9290019758, TERNCY-PP01 etc, both
cfg.sensor_illuminance and cfg.sensor_illuminance_lux are applied. As both of these
had the same object_id, only one would show in Home Assistant. Oddly, a mix of both
would apply - e.g. I would get the illuminance value, with the illuminance_lux unit
of 'lx'.

* Add a test for duplicated type/object_id in HA discovery configs
2020-04-03 11:12:58 +02:00
Koen Kanters 496c5329a2 Update converters. 2020-04-02 18:15:10 +02:00
Koen Kanters 3e1db1787d ZM-CSW032-D doesn't support reporting. https://github.com/Koenkk/zigbee2mqtt/issues/3216 2020-04-02 18:11:49 +02:00
Daniel ZegarraandKoen Kanters 86c3ce3705 Added HA config for radiator valve Siterwell GS361 (#3259)
* Added HA config for radiator valve Siterwell GS361

* Updated payload and state keywords for mqtt msgs

* Update homeassistant.js

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-04-02 14:29:39 +02:00
Koen Kanters da01a504e7 Update herdsman 2020-04-01 22:36:14 +02:00
Koen Kanters 379847d6d0 Update herdsman and converters. 2020-04-01 21:52:35 +02:00
presslab-us 5952a2a12a Fix definition of Nyce NCZ-3011-HA (#3267) 2020-04-01 21:42:48 +02:00
Koen Kanters f95eb4527a Only setup supported color capabilities. https://github.com/Koenkk/zigbee2mqtt/issues/3260 2020-04-01 20:33:04 +02:00
Koen Kanters defe6a5ec1 Update herdsman. 2020-03-31 21:36:19 +02:00
Koen Kanters 5b34e14a62 Update converters. 2020-03-31 19:59:12 +02:00
presslab-usandKoen Kanters 87d6587779 Support Orvibo RL804QZB (#3252)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-31 19:01:24 +02:00
presslab-usandKoen Kanters 92b6510175 Support Leviton Omnistat2 thermostat (#3249)
* Support Leviton Omnistat2 thermostat

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-31 18:53:51 +02:00
Koen Kanters d6fccbd83e Fix tests. 2020-03-31 18:18:15 +02:00
Koen Kanters eeb85cf096 Update herdsman and converters. 2020-03-30 21:56:34 +02:00
Koen Kanters 7131c05255 DeviceReport: don't crash on binds to non-existing entities. #3245 2020-03-30 19:50:35 +02:00
danieledwardgeorgehitchcock 1ca34536de Added device support for Hue Beyond suspension light (#3246) 2020-03-30 19:45:08 +02:00
presslab-us 7e45ab05cf Fix colortemp ability for Paulmann RGBW Light (#3239) 2020-03-30 19:02:25 +02:00
Koen Kanters 545eca6708 Update converters. 2020-03-29 21:36:59 +02:00
presslab-usandKoen Kanters 6b01418a00 Support Centralite thermostat 3157100 (#3234)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-29 21:22:48 +02:00
presslab-usandKoen Kanters 3bd1f4dc4a Fix power reporting of Centralite 4257050-RZHAC (#3236)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-29 21:14:48 +02:00
presslab-us 00f0381d62 Support Iris hose faucet water timer 27087-03 (#3230) 2020-03-29 20:28:54 +02:00
Koen Kanters 3c9639048e Remove battery_low for HS1CG-E. https://github.com/Koenkk/zigbee2mqtt/issues/3041 2020-03-29 20:19:13 +02:00
Koen Kanters 78c7024980 Update herdsman. 2020-03-29 19:40:33 +02:00
Koen Kanters fb4d86cef5 Allow to change non-setted options via device_options. #3215 2020-03-28 19:48:05 +01:00
Koen Kanters e49b733fae Cover position for ZM-CSW032-D. https://github.com/Koenkk/zigbee2mqtt/issues/3216 2020-03-28 19:30:27 +01:00
Koen Kanters 5092a12298 Change unit of Home Assistant sensor_energy to kWh. https://github.com/Koenkk/zigbee-herdsman-converters/issues/974 2020-03-28 19:26:02 +01:00
presslab-us 15ee48c318 Support Iris smart button 3460-L (#3214) 2020-03-28 19:12:49 +01:00
Koen Kanters ac7ac1a464 Update converters. 2020-03-27 20:44:10 +01:00
presslab-usandKoen Kanters d73bcf3520 Support Sylvania iQBR30 (#3205)
* Support Sylvania iQBR30

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-27 17:45:34 +01:00
Koen Kanters a444a01fa7 Update converters. 2020-03-26 22:24:22 +01:00
presslab-usandKoen Kanters f7b2dff37e Support Centralite Night Light Repeater (#3203)
* Support Centralite Night Light Repeater

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-26 22:15:22 +01:00
presslab-us 676e7e08c6 Support wallyHOME Multi-Sensor (#3202) 2020-03-26 22:09:59 +01:00
Koen Kanters 1c8ba3d28e Mock water_leak value for Home Assistant when it's not available. #3146 2020-03-26 22:01:05 +01:00
presslab-us 4ce9370cc0 Add humidity support for SmartThings (Centralite) 3310-S (#3197) 2020-03-26 21:28:27 +01:00
Koen Kanters a7e38b6bb0 Update zigbee-herdsman. https://github.com/Koenkk/zigbee2mqtt/issues/3111 2020-03-26 20:20:59 +01:00
Koen Kanters 4fe23842cf Don't allow non existing entities on availability_blacklist or availability_whitelist. #3191 2020-03-25 20:46:20 +01:00
Koen Kanters a307747d8c Fix typo. 2020-03-25 20:05:18 +01:00
Koen Kanters 5cd1af569e Fix crash when removing device from group which has no devices in settings. #3185 2020-03-23 22:24:35 +01:00
Nico87LBS dfc897af1a Add Hue Impress outdoor Pedestal (#3186) 2020-03-23 21:51:07 +01:00
Koen Kanters a3b285d1ac Don't allow MQTT wildcard (# or +) in friendly_name. #3175 2020-03-23 19:59:49 +01:00
Koen Kanters 06c792f493 Update herdsman and converters. 2020-03-23 19:42:06 +01:00
Koen Kanters d52d520da8 Update herdsman. 2020-03-22 20:46:39 +01:00
Nico87LBS 5461b3c3f8 Added Hue Econic Outdoor Pedestal (#3174) 2020-03-22 16:36:14 +01:00
Koen Kanters 78c17f0a61 Update converters. 2020-03-21 21:59:10 +01:00
Jorge Schrauwen e226cd229e #3159 Fix incorrect unbind message (#3172) 2020-03-21 21:33:00 +01:00
Addison Lynch 2f557bd397 Add 75541 (#3167) 2020-03-21 15:37:43 +01:00
Koen Kanters ed37570ef0 Update converters. 2020-03-20 19:46:57 +01:00
Koen Kanters 6cc2689593 Log error when there is nothing to bind. #3159 2020-03-20 19:00:00 +01:00
Koen Kanters 92d8eb2b6b Fix unsupported device warnings when device is still being interviewed. #3158 2020-03-20 18:04:28 +01:00
Koen Kanters a30abba973 Make sure that there is always an update_available value for Home Assistant. https://github.com/Koenkk/zigbee2mqtt/issues/3146 2020-03-20 17:50:28 +01:00
Koen Kanters ac8a84feb2 Update converters. 2020-03-19 23:04:39 +01:00
Koen Kanters e3fafcdfed Update herdsman. 2020-03-19 19:39:36 +01:00
Koen Kanters 6b9baf0114 Allow to specify adapter type. https://github.com/Koenkk/zigbee-herdsman/issues/72 2020-03-19 19:34:11 +01:00
Koen Kanters 9b80b6785d Update converters. 2020-03-18 22:50:45 +01:00
Koen Kanters 73dab78c37 Promote to dev 2020-03-18 19:03:33 +01:00
Koen Kanters 840b9d966c 1.12.0 2020-03-18 19:01:45 +01:00
Koen Kanters d514c0b3c1 Undev 2020-03-18 19:01:41 +01:00
Koen Kanters dc856ff8bf Update herdsman and converters. 2020-03-17 18:31:50 +01:00
Koen Kanters 11ee61fb1c Update converters. 2020-03-16 20:20:00 +01:00
r1cht3r 43a2aa27cd changing 3323-G cfg.binary_sensor_contact to cfg.binary_sensor_occupancy (#3137) 2020-03-16 20:07:53 +01:00
Filip CornelissenandKoen Kanters 43c7ce8e8a add support for ROB_200-007-0 (#3125)
* add support for ROB_200-007-0

* Fix automatically discovery for Home assistant for ROB_200-007-0

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-15 22:42:39 +01:00
Koen Kanters 27b3fd2f03 Update converters. 2020-03-15 22:26:03 +01:00
Koen Kanters 66b68da318 Add vendor and description to 'zigbee2mqtt/bridge/config/devices'. #3133 2020-03-15 17:04:10 +01:00
Koen Kanters db57829068 Update converters. 2020-03-15 16:58:48 +01:00
Koen Kanters 15bef07328 Fix LifeControl_Door_Sensor Home Assistant discovery. #3108 2020-03-15 15:25:28 +01:00
Koen Kanters 4d3bbce687 Implement lightWithPostfix Home Assistant configuration. #3003 2020-03-15 09:38:39 +01:00
Koen Kanters cb87b31cdd Update herdsman. 2020-03-14 15:08:00 +01:00
Koen Kanters cee146b062 Update converters. 2020-03-13 19:24:20 +01:00
Kryzek cde5c9696d Update homeassistant.js (#3121)
Related to https://github.com/Koenkk/zigbee-herdsman-converters/pull/1063
2020-03-13 19:20:38 +01:00
Koen Kanters 882c725b13 Update converters. 2020-03-13 18:39:40 +01:00
Dustin SallingsandKoen Kanters 97a4b6b539 Add support for expiring retained messages. (#3082)
* Add support for expiring retained messages.

For most of my environmental monitoring use cases, I want the readings
retained so I can pick them up from clients at any time, but if the
sensor (or zigbee2mqtt) fails, I want the readings to go away so I can
tell the difference between a stale reading and a missing reading.

This is easily accomplished in MQTTv5 using the "message expiry
interval" property.  To add that to zigbee2mqtt, I added a 'version'
option to the mqtt section so I can specify to connect with version 5
and added a 'retention' property to devices allowing me to specify how
long items should be retained.

e.g.

    mqtt:
      base_topic: site/zigbee2mqtt
      server: 'mqtt://myserver'
      user: zigbee
      version: 5
    serial:
      port: /dev/ttyACM0
    devices:
      '0x00358d00022308da':
        friendly_name: someroom
        retain: true
        retention: 900

* Also get from deviceOptions

* Update settings.js

* Update controller.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-12 20:25:37 +01:00
Koen Kanters f1a685bea2 Reduce MQTT subscriptions in deviceBind. https://github.com/Koenkk/zigbee2mqtt/issues/3102 2020-03-11 21:30:01 +01:00
Koen Kanters a17d96c14a Revert "Reduce MQTT subscriptions. #3102"
This reverts commit 82080e3d22.
2020-03-11 21:24:59 +01:00
Koen Kanters 9b592d4546 Refuse to start when 'device_options: null' is set. #3107 2020-03-11 20:18:27 +01:00
Koen Kanters 444850f1bc Update converters. 2020-03-11 20:11:47 +01:00
Koen Kanters 82080e3d22 Reduce MQTT subscriptions. #3102 2020-03-11 19:02:24 +01:00
b59d761ca6 publish announces to log topic (#3101)
* publish announces to log topic

* publish announces to log topic #test fix

* Update controller.js

* Update controller.test.js

* Update deviceAvailability.test.js

Co-authored-by: Andrey Sergeew <avsergeev@neoflex.ru>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-11 18:21:06 +01:00
Koen Kanters 785079a712 Update herdsman. 2020-03-10 21:30:12 +01:00
Koen Kanters 59281fe1c2 Update herdsman. https://github.com/Koenkk/zigbee2mqtt/issues/2693 2020-03-10 20:29:46 +01:00
Koen Kanters ab85577132 Wait 30 seconds before publishing device states. https://github.com/Koenkk/zigbee2mqtt/issues/105 2020-03-10 19:32:44 +01:00
Koen Kanters da8b8aa373 Fix command_on_template for lightWithPostfix. https://github.com/Koenkk/zigbee2mqtt/issues/3003#issuecomment-596868209 2020-03-10 19:28:19 +01:00
Koen Kanters 052ccfa242 Update converters. 2020-03-10 18:40:16 +01:00
Koen Kanters 8e9729cbbd Update herdsman and converters. 2020-03-09 20:01:51 +01:00
netadmindaveandKoen Kanters 3f7d383ead added config for Third Reality Switch 3RSS007Z (#3089)
* added config for Third Reality Switch 3RSS007Z

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-09 18:59:48 +01:00
Koen Kanters b92e3c31d1 Update converters. 2020-03-09 18:09:15 +01:00
Koen Kanters 4d54e5038b Refuse to start when friendly_name ends with /DIGIT. #2645 2020-03-07 23:06:22 +01:00
Koen Kanters 407d329d4f Update herdsman and converters. 2020-03-06 23:34:36 +01:00
Koen Kanters 34b3e66fa5 Add l5 till l8 to postfixes. https://github.com/Koenkk/zigbee-herdsman-converters/pull/1041 2020-03-06 23:18:50 +01:00
Kiall Mac Innes 67b4bcf815 Update HA Discovery Info on Rename (#3040)
* Update HA Discovery Info on Rename

Update HA discovery info when a device is renamed. Adds a new deviceRenamed
event to the event bus, allowing the HA extension to react to the rename

Fixes #2440

* Handle Groups correctly wrt HA discovery data refresh

* Cleanup group handling

* Cleanup group handling
2020-03-04 12:55:08 +01:00
Koen Kanters 3b60a907c8 Fix error on OTA update message without mapped device. 2020-03-03 21:19:00 +01:00
Koen Kanters 2d10c15a94 Update herdsman and converters. 2020-03-03 20:33:10 +01:00
Jorge Schrauwen b17b9c76ef #3009 filtered_attributes should also work in device_options (#3057) 2020-03-03 18:30:54 +01:00
Magnus PernemarkandKoen Kanters 2454136b9b Added MQTT logging to TouchLink Reset process (#3053)
* MQTT logging for TouchLink reset process

* Changed status to be in meta

* Update bridgeConfig.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-03-03 18:22:28 +01:00
Koen Kanters dc8b6c5294 Update converters. 2020-03-02 21:11:54 +01:00
Jorge Schrauwen 658cc21b4d #3009 allow filtering of mqtt topics and payloads (#3037)
* Allow filtering of attributes in mqtt json payload or published attributes

* Add test for mqtt_attribute_filter

Just doing attribute_and_json should be fine as the code changes are run before this. Doing this tests lets us varify both json or seperate topic get properly filtered.

* Add test for mqtt_attribute_filter on group

* Rename mqtt_attribute_filter to filtered_attributes
2020-03-02 20:08:51 +01:00
Koen Kanters 68750fade0 Fix tests on node 12. https://github.com/Koenkk/zigbee2mqtt/issues/3031 2020-03-02 19:11:43 +01:00
Koen Kanters ed34422640 Merge branch 'master' into dev 2020-03-02 19:07:49 +01:00
Koen Kanters e140cf5de3 Add branch switcher. 2020-03-02 19:07:38 +01:00
Koen Kanters 43b744987b Add AV2010/32 Home Assistant discovery. #3038 2020-03-01 16:03:08 +01:00
Koen Kanters 9f1b8cf214 Allow to disable homeassistant legacy triggers. #3033 2020-03-01 15:55:20 +01:00
Koen Kanters ed75c85b69 Implement Home Assistant MQTT device trigger. #3033 2020-02-29 18:07:15 +01:00
Koen Kanters 2eb6f075dc Update converters. https://github.com/Koenkk/zigbee2mqtt/issues/3024 2020-02-29 13:53:35 +01:00
Koen Kanters a16e3542c0 Update herdsman. #3019 2020-02-29 12:43:53 +01:00
Koen Kanters dd3678f84b TEMP: disable OTA response. https://github.com/Koenkk/zigbee2mqtt/issues/3019 2020-02-28 23:52:30 +01:00
Koen Kanters a40ad0c52f Respond with ABORT when device checks for OTA. https://github.com/Koenkk/zigbee2mqtt/issues/3019 2020-02-28 23:42:59 +01:00
Koen Kanters f6aba5f64a Respond with image not available when OTA is requested but we don't support it. #3019 2020-02-28 23:30:33 +01:00
Koen Kanters 8f8180f84d Update converters and herdsman. 2020-02-28 23:27:12 +01:00
Cedric Girard 4803be2df9 Add necessary changes for NPM publishing (#3021) 2020-02-28 21:59:01 +01:00
Koen Kanters 05766fa39a Update dependencies. https://github.com/Koenkk/zigbee2mqtt/issues/3007 2020-02-28 20:56:32 +01:00
Koen Kanters 342d4c17b9 Fix debounce, debounce_ignore, retain and qos in device_options not honored. #3004 2020-02-27 21:06:27 +01:00
Christian Scheffler 69c477da7d added mqtt log events group_added and group_removed (#3016) 2020-02-27 21:03:56 +01:00
Koen Kanters 63be685201 Fix OTA update start on check with / as base_topic prefix. #3010 2020-02-27 20:33:04 +01:00
Koen Kanters 5c0bb33c1b Discover Home Assistant temperature sensor for QBKG12LM. https://github.com/Koenkk/zigbee-herdsman-converters/issues/1020 2020-02-26 22:02:04 +01:00
Koen Kanters 0036176098 Promote to dev. 2020-02-26 18:28:22 +01:00
Koen Kanters 31e56785e4 1.11.0 2020-02-26 18:25:39 +01:00
Koen Kanters 962282b38c Undev 2020-02-26 18:25:36 +01:00
Koen Kanters e241d5ac8a Update converters. 2020-02-26 18:22:36 +01:00
Koen Kanters 1a973d0cd7 Update converters. 2020-02-26 17:30:38 +01:00
Koen Kanters 11ec191580 Don't discover illuminance_lux for RTCGQ11LM. https://github.com/Koenkk/zigbee-herdsman-converters/issues/1017 2020-02-26 17:20:31 +01:00
Koen Kanters 95788b8847 Discover illuminance_lux sensor. 2020-02-25 20:37:42 +01:00
Koen Kanters a36f11a4fb Update converters. 2020-02-25 20:20:52 +01:00
Koen Kanters 9cc84feb67 Allow to rename groups through zigbee2mqtt/bridge/config/rename. https://github.com/Koenkk/zigbee2mqtt/issues/2991 2020-02-23 21:51:30 +01:00
Koen Kanters dd82b29629 Update converters. https://github.com/Koenkk/zigbee2mqtt/issues/2967 2020-02-23 20:47:38 +01:00
Koen Kanters 2a9d0d1875 Update converters. https://github.com/Koenkk/zigbee2mqtt/issues/2921 2020-02-23 20:26:13 +01:00
Koen Kanters 66173ff689 Update herdsman. 2020-02-23 20:02:29 +01:00
Koen Kanters 645da4e3c0 Update herdsman. 2020-02-23 19:01:02 +01:00
shades684 409df4c193 Matches this pull request: https://github.com/Koenkk/zigbee-herdsman-converters/pull/1010 (#2988) 2020-02-23 13:33:30 +01:00
Koen Kanters aca32e2f02 Update converters. 2020-02-22 19:03:06 +01:00
Koen Kanters 79116a1158 Fix Hue bulbs in a group controlled by a Hue dimmer not reporting off state. #2882 2020-02-22 18:45:30 +01:00
Koen Kanters ad59ff57bc Also remove group from herdsman on remove. #2265 2020-02-22 15:53:05 +01:00
Koen Kanters df67c429bf Undiscover ota_update sensor on device remove. 2020-02-22 00:32:15 +01:00
Koen Kanters 6b5b4ab433 Log when update is availabe. https://github.com/Koenkk/zigbee2mqtt/commit/58d987b52328a40b6ac92f343f3e8ceeae3f2a10#r37363068 2020-02-20 20:01:26 +01:00
Koen Kanters c25c32f1be Update converters. 2020-02-19 22:12:25 +01:00
Koen Kanters 9b644ff82d Update herdsman. 2020-02-19 21:46:25 +01:00
Koen Kanters 0289a6c30d Update converters. 2020-02-18 22:07:34 +01:00
Koen Kanters 2b3cdebe41 Fix AC08559 missing Home Assistant colorxy mapping. #2966 2020-02-18 22:05:32 +01:00
Takisg 6ef4fac30a GL-C-007S (#2955)
Gledopto GL-C-007S

Add support for Gledopto GL-C-007S
Zigbee LED controller RGBW plus model
2020-02-17 20:15:57 +01:00
Koen Kanters f0903cd02c Discover action sensor for WXKG11LM. #2953 2020-02-16 20:55:40 +01:00
Koen Kanters 58d987b523 Implement update_available attribute and discover Home Assistant sensor. #2948 2020-02-16 16:00:15 +01:00
Koen Kanters 9a87abd0f4 Update herdsman and converters. 2020-02-15 16:39:35 +01:00
timstanley1985andKoen Kanters b379830e36 Log ota message to MQTT (#2936)
* Log ota message to MQTT

* Fix lint

* Amend MQTT log messages

* Fix typo

* Fix lint

* some changes.

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-02-14 23:41:34 +01:00
Koen Kanters 97af26b340 Also poll hue bulbs on button 1/2 press of Hue dimmer switch. #2882 2020-02-14 22:41:04 +01:00
rbrack42 7de51340a0 Adding support for Sylvania 72567 Flushmount Light (#2943) 2020-02-14 16:52:07 +01:00
Koen Kanters bbf432eae5 Update herdsman and herdsman-converters. 2020-02-13 21:35:37 +01:00
Koen Kanters eac15a748a npm ci. https://github.com/Koenkk/zigbee2mqtt/issues/2918 2020-02-13 21:31:14 +01:00
Koen Kanters 87faaa1817 Don't crash when devices doesn't respond to read modelID after update. https://github.com/Koenkk/zigbee2mqtt/issues/2921 2020-02-13 21:10:44 +01:00
Koen Kanters 984bad4cb3 Major OTA improvements. https://github.com/Koenkk/zigbee2mqtt/issues/2921 2020-02-09 20:44:37 +01:00
Koen Kanters 13b996eb70 Update converters. 2020-02-08 23:41:22 +01:00
Ricardo Pereira fb7c3a31dd Adding availability support to Commercial Electric Downlight model 53170161 (#2922) 2020-02-08 23:23:44 +01:00
Boris PrüßmannandKoen Kanters 06b6d66090 Feedback requested: add polling for commandOn & commandOff (#2730)
* Add polling for commandOn & commandOf.

When using groups together with devices that do not support reporting, this is needed
to have the new state reflected.

* Update deviceReport.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-02-08 20:53:16 +01:00
Koen Kanters 3d897c55e2 v2.7.0 rocks. 2020-02-08 20:50:07 +01:00
Koen Kanters c5fb651481 Try with v2.8.0 2020-02-08 20:46:26 +01:00
Koen Kanters 7d52a013ad Something wrong with the alpine 12 image? 2020-02-08 20:27:28 +01:00
Koen Kanters e278bb0145 Downgrade node. 2020-02-08 20:20:27 +01:00
Koen Kanters b36da25d68 Attempt to fix Docker build. 2020-02-08 20:17:13 +01:00
Koen Kanters 83291e242e OTA https://github.com/Koenkk/zigbee-herdsman/issues/60 (#2920)
* ota

* Bla

* Update converters.
2020-02-08 19:55:26 +01:00
Koen Kanters 99dc214fbe Update herdsman. 2020-02-07 19:50:48 +01:00
Koen Kanters 5e152f2ce4 Promote to dev. 2020-02-05 21:45:47 +01:00
Koen Kanters 8df6be8813 1.10.0 2020-02-05 21:41:31 +01:00
Koen Kanters 415e764592 Undev 2020-02-05 21:40:58 +01:00
Koen Kanters e8d9cbc19b Update converters. 2020-02-05 21:38:42 +01:00
svh1985 e473590dd9 Added log_file name setting (#2894)
* Added log_file name setting

Added log_file to schema while preserving the default log.txt setting.
Added option to logger to use the filename and support for the %timestamp% var.

* Update logger.js

Added the filename to the console/log output.
2020-02-05 19:37:13 +01:00
Koen Kanters 558153ebd6 Update converters. 2020-02-04 20:28:47 +01:00
Koen Kanters a07a28cb65 Update herdsman. 2020-02-02 21:05:25 +01:00
Koen Kanters 6090f124c0 Update converters. 2020-02-02 14:30:53 +01:00
Koen Kanters 5d8a9a3e51 Update converters. 2020-02-01 17:35:20 +01:00
Koen Kanters 313edcc445 Keep latest log in log.txt (not in log1.txt, etc.). https://github.com/Koenkk/zigbee2mqtt/issues/2855 2020-01-31 23:13:15 +01:00
Koen Kanters 4926fb85ae Await permit join before continuing with startup. https://github.com/Koenkk/zigbee2mqtt/issues/2617 2020-01-31 22:52:39 +01:00
Koen Kanters 0111681cb7 Update converters. https://github.com/Koenkk/zigbee2mqtt/issues/2850 2020-01-31 22:42:24 +01:00
Koen Kanters 9bc427e32f Update converters. 2020-01-31 21:05:13 +01:00
Koen Kanters 36e39e2f02 Update herdsman. 2020-01-31 20:31:02 +01:00
Rob Long 58e08d1443 Update homeassistant.js (#2861)
Added 5900131C5
2020-01-31 16:27:46 +01:00
Koen Kanters 2e19a8f916 Update converters. 2020-01-30 20:08:31 +01:00
Koen Kanters 5488504809 Update converters. 2020-01-29 21:38:37 +01:00
Michal Szymura 82fb79820a Added support for Sengled E11-U2E (#2853) 2020-01-29 21:21:22 +01:00
Koen Kanters c87ccea9ba Update converters. 2020-01-29 18:34:40 +01:00
Koen Kanters b6cb7acf7e Update converters. 2020-01-27 22:20:48 +01:00
Markus Peter ad286cbbc6 Home assistant config for Philips Hue Discover 17435/30/P7 (#2834) 2020-01-27 21:48:04 +01:00
Koen Kanters fe62ceb0f9 Add unbind for default_bind_group. https://github.com/Koenkk/zigbee2mqtt/issues/2772 2020-01-27 20:56:11 +01:00
Koen Kanters 61a3f0e839 Update converters and fix tests for real. 2020-01-26 21:38:04 +01:00
Koen Kanters b58cbd4883 Fix tests. 2020-01-26 19:57:15 +01:00
a-bailey 833bfcd81a added home assistant extension for LS12128 (#2825) 2020-01-26 19:44:44 +01:00
Philipp Bender 9e413bf35a Added homeassistant mapping for OSRAM A60 DIM Z3 (#2824) 2020-01-26 19:39:43 +01:00
Koen Kanters 3c28ed8f0b Update herdsman. https://github.com/Koenkk/zigbee2mqtt/issues/2749 2020-01-26 19:21:30 +01:00
Koen Kanters 20ba6a5274 Add icon and unit to Home Assistant linkquality sensor. #2806 2020-01-25 20:43:51 +01:00
Koen Kanters bd30b0b4a3 Update converters. 2020-01-25 20:00:22 +01:00
Koen Kanters 93e96a2e5e Update converters. 2020-01-23 21:00:50 +01:00
Koen Kanters e1d51e6171 Fix error when configure section of device is removed. 2020-01-23 20:42:10 +01:00
Marco AddarioandKoen Kanters cb855373ac Added support for Linkind Smart Zigbee LED (#2804)
* Added support for Linkind Smart Zigbee LED

Added support for Linkind Smart Zigbee LED bulb
( https://www.linkind.com/product-page/smart-zigbee-led-9w-a19-bulb-dimmable-tunable-hub-required-alexa-control )

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-23 19:51:41 +01:00
Koen Kanters 145f8a577d Update converters. 2020-01-22 21:34:15 +01:00
Koen Kanters 0d3fa83ab1 Update herdsman. 2020-01-22 20:52:12 +01:00
Koen Kanters dae52a22d7 Update converters. 2020-01-21 21:19:11 +01:00
Koen Kanters e94b34caad Update converters. 2020-01-20 21:36:19 +01:00
wrcvr4andKoen Kanters 43c745df1d Support NUET56-DL27LX1.2 (#2784)
* Support DL27LX1.2

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-20 17:48:33 +01:00
Koen Kanters 2e958f863f Update herdsman. 2020-01-18 23:05:05 +01:00
Koen Kanters 3b1ef5179b Update herdsman. 2020-01-18 20:27:53 +01:00
Koen Kanters ae5330d090 Update converters. 2020-01-17 22:51:37 +01:00
Twan Coenraad dd0ca2a392 Add keepalive option for MQTT (#2767) 2020-01-17 21:38:46 +01:00
Koen Kanters 39ed95371e Log when using non-valid log_level. #2706 2020-01-16 23:33:17 +01:00
Koen Kanters 3f6a95bc0b Don't setup reporting for BASICZBR3 as it doesn't support it. #2740 2020-01-16 22:52:13 +01:00
Koen Kanters 42f1a37499 Promote to dev 2020-01-16 22:44:11 +01:00
Koen Kanters 287f843bbb 1.9.0 2020-01-16 22:32:17 +01:00
Koen Kanters cd4319d281 Remove dev from version. 2020-01-16 22:32:13 +01:00
Viet DzungandKoen Kanters 2188937eea Home Assistant 0.104 breaking change: support new HA separate lock state (#2753)
* Support new HA separate lock state for Xiaomi ZNMS12LM and ZNMS12LM

https://github.com/home-assistant/home-assistant/pull/29808

* Update homeassistant.js

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-16 22:25:58 +01:00
Koen Kanters a9cce7c222 Update converters. 2020-01-16 21:27:28 +01:00
jungmonam f9d85df51b Update homeassistant.js (#2758) 2020-01-16 21:17:55 +01:00
Ashton Kemerling 64315d0fc9 Home assistant bindings for Sylvania 72569 (#2754)
* Home assistant bindings for Sylvania 75269

Related to https://github.com/Koenkk/zigbee-herdsman-converters/pull/913.

* Fix Typo (Again)

Replace 75269 with 72569
2020-01-16 21:15:19 +01:00
MrNickllandKoen Kanters eba84647c1 Update TH1123ZB Home Assistant config (#2752)
* Update homeassistant.js

Added config parameters for Sinope TH1123ZB line voltage thermostat:
- Keypad lockout using the code for Stelpro thermostats.
- Power sensor.

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-16 21:08:14 +01:00
Boris Prüßmann 7d268732de Let ubisys devices expose power consumption via Home Assistant (#2743) 2020-01-15 12:58:03 +01:00
Boris PrüßmannandKoen Kanters a79b2bae81 Add support for Philips Fair Hue ceiling light (#2742)
* Added endpoints for Busch-Jaeger

* Added RM01 to homeassistant.js

* Updated mapping to reflect latest change in converter

* Renamed endpoint according to converted PR

* Support for Philips Hue Fair

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-15 12:57:08 +01:00
Koen Kanters 5c18734e68 Update converters. 2020-01-14 19:06:35 +01:00
Boris PrüßmannandKoen Kanters 2234fd1e8a Added endpoints for Busch-Jaeger (#2723)
* Added endpoints for Busch-Jaeger

* Added RM01 to homeassistant.js

* Updated mapping to reflect latest change in converter

* Renamed endpoint according to converted PR

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-14 18:47:32 +01:00
Koen Kanters 80838bd248 Update converters. 2020-01-13 22:09:21 +01:00
lukeIamandKoen Kanters 4a0059afcd Allow attribute and json in parallel (#2712)
* Allow attribute and json in parallel

* Fix tests

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-12 15:07:06 +01:00
Martin Raatz 4a14706638 adding support for LUPUS - 1 chanel relay with ZigBee (#2711) 2020-01-12 14:31:06 +01:00
Koen Kanters 9890fb3ae2 Update herdsman and converters. 2020-01-11 18:04:30 +01:00
jungmonam 15d984e21b Update homeassistant.js (#2720) 2020-01-11 16:20:45 +01:00
Koen Kanters 57a5253203 Discovery battery sensor for E1744. #2715 2020-01-11 16:17:22 +01:00
TilmanK 7a8bef3e60 Fixed check if entity is of type "device" in deviceConfigure.js. (#2713)
The current statement (!entity.type === 'device') will always evaluate to false since it compares a boolean to a string.
2020-01-11 15:50:00 +01:00
Daniel Chesterton 77fc851236 Update Docker to Node 12 and use multistage builds to reduce image size (#2703) 2020-01-11 15:11:27 +01:00
Koen Kanters e76633519f Update converters. 2020-01-09 22:10:16 +01:00
Roberto Barbero a652df6ed7 Added Sinope TH1400ZB and TH1500ZB (#2708)
Added for Home Assistant MQTT autodiscovery
2020-01-09 21:56:03 +01:00
Koen Kanters cb0b0b5af9 Clear Home Assistant MQTT discovery on device remove. #2678 2020-01-09 21:47:19 +01:00
Koen Kanters 3a463b0782 Update converters. 2020-01-08 20:06:01 +01:00
TilmanKandKoen Kanters 0df966755c Corrected several typos in "Successfully" within log messages (#2697)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-08 19:29:22 +01:00
Daniel Chesterton 94d0253f27 Update availability_blacklist and availability_whitelist to allow for friendly names (#2684) 2020-01-08 18:02:49 +01:00
Jevgeni Kiski 4ee34fd637 LLKZMK11LM Supports power, temperature and consumption (#2657)
* LLKZMK11LM Supports power, temperature and consumption

LLKZMK11LM already sends power, temperature and consumption in mqtt json.

```
info  2020-01-02 20:06:20: MQTT publish: topic 'zigbee2mqtt/front_outdoor_lights', payload '{"state_l1":"ON","linkquality":54,"state_l2":"OFF","power":35.1,"consumption":2.89,"temperature":33}'
```

Not sure in which units `consumption` is. Not adding right now.

* LLKZMK11LM power consumption

* Linter

* mdi-flash
2020-01-08 17:57:40 +01:00
Carl de Billy cabb1f3979 Added <operation>_failed logging (#2636)
* Added <operation>_failed logging
for external tools (like Zigbee2MqttAssistant), this will allow the tool to know when an operation is failed.
https://github.com/Koenkk/zigbee2mqtt/issues/2223

* Added _failed logging to binding operations too

* Added _failed to group operations
2020-01-07 21:06:48 +01:00
Koen Kanters 8a72916d7d Update converters. 2020-01-07 20:08:12 +01:00
Koen Kanters c041f0cddc Ignore setup reporting for closuresWindowCovering ZNLDP12LM. #2611 2020-01-07 19:59:43 +01:00
Koen Kanters 6245c729cf Update converters. 2020-01-06 21:55:43 +01:00
Carl de BillyandKoen Kanters e5b2f71fcd Added support for Stelpro Ki & Stelpro Maestro (#2628)
* fix potential null exception

* Added support for Stelpro Ki

* Stelpro Ki: Added support for action_mode

(cherry picked from commit 0f740f1aedbedb28d64245531f10a9bfd985e49b)

* Stelpro Ki: fix "lock" status update

(cherry picked from commit 6ac94411183d92d1f658a7d17a724e50587b8571)

* Fixed lint issues

* Stelpro: Fixed local_temperature sensor

* Added support for Stelpro Maestro

* Fix lint

* HASS: Fixed support for action_topic/action_template

* Prevent a non supported device from causing a null-ref

* Update naming.

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-06 21:36:45 +01:00
Koen Kanters d0e9889f7d Fix race condition when Zigbee starts. #2591 2020-01-03 23:43:04 +01:00
Koen Kanters d3aba2689c Update converters. 2020-01-03 23:29:28 +01:00
jasperroandKoen Kanters 7a6d5f9a42 Added hue/saturation mode and tamper to home assistant (#2603)
* Added hue/saturation mode to home assistant extension

* Added tamper to homeassistant

* Fix ESlint stuff

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-03 22:28:21 +01:00
AThomsenandKoen Kanters 89fb54d5c8 Add Nordtronic Box Dimmer 2.0 98425031 (#2629)
* Add Nordtronic Box Dimmer 2.0 98425031

* Update homeassistant.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2020-01-03 18:55:57 +01:00
Samuel Gaus afaed3f783 Support new IKEA GUNNARP round panel (#2653)
See: https://github.com/Koenkk/zigbee-herdsman-converters/pull/865
2020-01-03 09:09:28 +01:00
Kryzek dc6bf51b8e Update homeassistant.js (#2651)
Expose battery information to Home Assistant with couple of Trust battery-powered sensors.
Related to https://github.com/Koenkk/zigbee-herdsman-converters/pull/856
2020-01-03 09:04:21 +01:00
Koen Kanters 5f97f19d7f Add brightness_move for groups. #2620 2019-12-31 13:52:23 +01:00
Jack Wilsdon f04e01ff54 Use correct Home Assistant configuration for GL-S-007Z (#2616) 2019-12-27 15:56:24 +01:00
Koen Kanters f069a7e58e Update herdsman and converters. 2019-12-26 22:46:44 +01:00
Phi Dong 2197d4127d Update homeassistant.js (#2606)
Add support for Ecosmart-ZBT-A19-CCT-Bulb (A9A19A60WESDZ02) to Home Assistant
2019-12-26 21:32:34 +01:00
Martin Brooksbank 89fe701197 Added Ajax Online LED Strip HomeAssistant Mapping (#2592) 2019-12-23 21:08:40 +01:00
Koen Kanters e63d196966 Skip configure when device does not require it. https://github.com/Koenkk/zigbee2mqtt/issues/2588 2019-12-23 20:48:37 +01:00
fb22 9db1467ed8 Add 4023330P7 (#2574)
Add support for Philips Hue white suspension Amaze
2019-12-23 20:08:43 +01:00
Anthony Lavado 3bab32c1d7 Add support for the EcoSmart D1533 (#2570) 2019-12-23 19:56:55 +01:00
Koen Kanters 66b3bcb639 Update herdsman. 2019-12-19 21:52:45 +01:00
Koen Kanters 6f7d29392e Update herdsman and converters. 2019-12-17 21:35:47 +01:00
Koen Kanters 83e10f446e Update converters. 2019-12-17 19:59:22 +01:00
Koen Kanters af4184e3ff Always log 'No converter available...` to debug. #2543 2019-12-17 19:19:57 +01:00
Koen Kanters 316755a5c8 Fix get device group membership with friendly_name containing slashes. #2546 2019-12-17 19:02:11 +01:00
Wilmar den Ouden 5083bbcc16 feat: create environment variable for the config file (#2519)
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2019-12-16 20:49:25 +01:00
Koen Kanters 981612c64c Support tint_scene for group. https://github.com/Koenkk/zigbee-herdsman-converters/issues/281 2019-12-16 20:17:58 +01:00
Koen Kanters 960f9e44ad Update herdsman. 2019-12-15 20:11:22 +01:00
Koen Kanters 8545a341c9 Promote to dev 2019-12-15 20:04:10 +01:00
Koen Kanters da4d26af62 1.8.0 2019-12-15 17:33:54 +01:00
Koen Kanters f64bf16f6f Update converters. 2019-12-15 16:37:00 +01:00
Koen Kanters 0b9997b7a5 Update converters. 2019-12-15 15:55:10 +01:00
mailq 6f33529c79 Add GL-S-005Z RGBW GU5.3 MR16 (#2533) 2019-12-15 15:07:31 +01:00
Koen Kanters 1972eb450c Update converters. 2019-12-13 19:25:22 +01:00
Markus Pfeiffer f4f910f014 Support for Hive Thermostatic Radiator Valve (#2517) 2019-12-13 19:18:34 +01:00
Wilmar den Ouden 087d1b8761 fix: avoid creating the log/ directory when file not enabled (#2516)
Signed-off-by: wilmardo <info@wilmardenouden.nl>
2019-12-13 19:09:18 +01:00
Timo S 4334e01759 temp_step attribute for climate entities (#2515) 2019-12-13 19:00:02 +01:00
Koen Kanters 6fd059967a Support setting cover position and thermostat occupied heating setpoint via group. #2505 2019-12-13 18:26:03 +01:00
Koen Kanters 61f5776310 Update converters. 2019-12-12 20:55:57 +01:00
stumps444 3f2d50900d Added support for Lockwood keyless deadbolt (#2506) 2019-12-12 20:02:41 +01:00
Koen Kanters be601cffb0 Update herdsman and converters. 2019-12-11 21:54:16 +01:00
Koen Kanters 6b7bd9da37 Re-add model to device information. #2497 2019-12-11 20:15:42 +01:00
Koen Kanters 3a9dfb04a7 Bind closuresWindowCovering. https://github.com/Koenkk/zigbee2mqtt/issues/2496 2019-12-11 20:00:09 +01:00
Thomas Jager 67f8e97b12 Add namron dimmer - homeassistant extension (#2494)
https://github.com/Koenkk/zigbee-herdsman-converters/pull/808
2019-12-11 19:41:06 +01:00
Koen Kanters 37089e440a Update herdsman. 2019-12-11 19:08:22 +01:00
Koen Kanters d17eec5310 Don't allow postfix to be a friendly_name. #2486 2019-12-09 18:27:39 +01:00
Jorge Schrauwen bcf79a7e34 Device Availability: Allow battery devices to report offline/online based on device.lastSeen (#2464)
* Remove execution bits for deviceReceive.js

* deviceAvailability.isPingable should return true if 'availability_lastseen_timeout' is set for device

* deviceAvailability.handleInterval should know how to handle lastseen_timeout setting

* Allow availability_lastseen_timeout for all devices

* Use a default lastseen timeout of 24h

* Updates

* Updates

* Updates

* 25 hours instead of 24.
2019-12-09 18:12:13 +01:00
Koen Kanters 6bd9e74e0c Fix tests 2019-12-08 16:52:23 +01:00
dusanmsk 6aad019328 mqtt listener to rename last paired device. (#2478)
* mqtt listener to rename last paired device.
send zigbee2mqtt/bridge/config/rename_last with payload containing new name and last paired device will be renamed

* Updates
2019-12-08 16:50:18 +01:00
Sven Lankes d05a3a066a add support for Mueller Licht 44435 Tint LED Stripe (#2483) 2019-12-08 14:11:27 +01:00
Koen Kanters 5440aadec0 Log remove docs on failure. #2477 2019-12-07 17:57:39 +01:00
Koen Kanters be30067a39 Let devices only report when there is a change. #2424 2019-12-07 17:54:40 +01:00
Koen Kanters 17560ca885 Check if state is not null. #2450 2019-12-07 17:45:00 +01:00
Marius e00dbbf4a9 Support Hue Go with Bluetooth LCT026 (7602031P7) (#2474) 2019-12-07 17:29:37 +01:00
Koen Kanters 33201367f1 Update herdsman and converters. 2019-12-05 21:33:28 +01:00
Jaron Viëtor 60627ab6e3 Added support for accepting hex color on deviceName/set/color MQTT topic (#2441)
* Added support for accepting hex color on deviceName/set/color MQTT topic

* Update entityPublish.js
2019-12-04 21:23:46 +01:00
Koen Kanters 88a1c2884a Update herdsman and converters. 2019-12-04 21:12:27 +01:00
Koen Kanters a53a19026c Add extra logging when publish to device fails. #2450 2019-12-04 20:46:19 +01:00
Koen Kanters 1459ffea7a Publish availabilty when non pinagable device joins. #2452 2019-12-04 20:21:14 +01:00
Koen Kanters ba26887ea5 Update converters and herdsman. 2019-12-03 20:11:45 +01:00
Wilmar den Ouden 694c45fd96 Make logging transports configurable (#2231)
* feat: Make logging optional

Signed-off-by: wilmardo <info@wilmardenouden.nl>

* feat: be more verbose about what logging is enabled

Signed-off-by: wilmardo <info@wilmardenouden.nl>

* feat: adds tests

Signed-off-by: wilmardo <info@wilmardenouden.nl>

* Updates.

* Updates

* fix tests.

* Remove onlythis.

* Remove another onlythis

* Improve test stability

* Remove another onlythis
2019-11-29 23:36:57 +01:00
Koen Kanters 5e165810ec Allow to configure manually. https://github.com/Koenkk/zigbee2mqtt/issues/2365 https://github.com/Koenkk/zigbee-herdsman-converters/issues/779#issuecomment-559598591 2019-11-29 09:43:59 +01:00
Koen Kanters 99fd93f9a7 Allow setting transmit power. https://github.com/Koenkk/zigbee2mqtt/issues/2253 2019-11-27 22:02:49 +01:00
Koen Kanters c2be95777f Mark nodejs 10, 12 and 13 as supported. #2423 2019-11-27 20:02:18 +01:00
Koen Kanters acce25737f Update converters. 2019-11-27 19:57:25 +01:00
Koen Kanters 134f86a580 Update herdsman. 2019-11-27 18:49:41 +01:00
Koen Kanters 2a81a54609 Stop pinging device when removed. #2419 2019-11-27 18:14:39 +01:00
Koen Kanters 2fcddb5ad5 Update herdsman. 2019-11-26 21:24:41 +01:00
Koen Kanters ac0291f09c Update herdsman. 2019-11-26 20:08:45 +01:00
Koen Kanters 7d1635aff8 Update converters. 2019-11-25 18:39:12 +01:00
Koen Kanters 6c56c95e3f Always make endpoint 1 the coordinator endpoint. 2019-11-25 17:44:44 +01:00
Koen Kanters d37d9ee859 Factory reset device through Touchlink. 2019-11-23 20:44:23 +01:00
Koen Kanters e179e053ce Update herdsman and converters. 2019-11-23 20:19:38 +01:00
Koen Kanters 546a72ff53 Update dependencies. 2019-11-23 12:07:23 +01:00
Koen Kanters c9122eecda Update gitignore. 2019-11-23 12:07:07 +01:00
Kryzek 46d7176976 availability_whitelist (#2387)
* availability_whitelist

* Tests

* Cleanup

* Update deviceAvailability.js
2019-11-23 11:47:37 +01:00
Hans-Wilhelm Warlo 2df1acf532 Return false when mappedDevice is falsy (#2383) 2019-11-22 07:48:11 +01:00
himpich c5bd3a2450 Add support for Innr FL 130 C Color LED Strip - homeassistant extension (#2377) 2019-11-21 20:26:10 +01:00
frontend89 260d2904f3 Add device specific configuration option: debounceIndexes (#2370)
* Add device specific configuration option: debounceIndexes

* Rename debounceIndexes to debounce_ignore

* Lint
2019-11-20 21:21:23 +01:00
Koen Kanters 8ae57e7ef0 Update herdsman and converters. 2019-11-20 20:08:30 +01:00
Koen Kanters b23276f7f3 Re-configure when device rejoins. https://github.com/Koenkk/zigbee-herdsman-converters/issues/758 2019-11-20 19:06:04 +01:00
Koen Kanters fdc8fcc02b Allow to specify endpoint via property. #2356 2019-11-20 17:36:36 +01:00
Koen Kanters ef16fcd505 Fix tests. 2019-11-20 17:35:49 +01:00
Koen Kanters c5898598ae Fix json_attributes_topic discovery for climate. https://github.com/Koenkk/zigbee2mqtt/issues/2321 2019-11-19 20:50:55 +01:00
Koen Kanters 461544ed6a Update converters. 2019-11-18 21:34:23 +01:00
Koen Kanters 661b2f1cc0 Home Assistant: discover json_attributes_topic for all MQTT device types. https://github.com/Koenkk/zigbee2mqtt/issues/2321 2019-11-18 18:14:22 +01:00
Koen Kanters eea660374f Use correct endpoint for binding dimmer. https://github.com/Koenkk/zigbee2mqtt/issues/2343 2019-11-18 17:54:28 +01:00
Kryzek 878a88632b Customizable timestamp (#2357)
* Customizable timestamp

Add a customizable timestamp

* Revert "Customizable timestamp"

This reverts commit 7ae06e8e2c.

* Customizable timestamp

* Update settings.js
2019-11-17 21:29:53 +01:00
Koen Kanters 22c8f14659 Update herdsman and converters. 2019-11-17 21:22:24 +01:00
Koen Kanters d2c4133e56 Update herdsman. 2019-11-16 13:52:49 +01:00
Koen Kanters 44db557a0c Log in local timezone. https://github.com/Koenkk/zigbee2mqtt/issues/2341 2019-11-15 23:04:23 +01:00
胡明春 31246efc64 Add UI support to 'S31 Lite zb' and SA-003-Zigbee (#2340)
* Add UI support to 'S31 Lite zb' and SA-003-Zigbee

* Update homeassistant.js
2019-11-15 22:55:49 +01:00
Koen Kanters a7486d723f Update herdsman converters. 2019-11-14 20:43:20 +01:00
Koen Kanters e33b49e2ff Update herdsman and converters. 2019-11-12 19:40:52 +01:00
Koen Kanters e51ed89641 Promote to dev. 2019-11-12 18:50:38 +01:00
Koen Kanters b459c35219 1.7.1 2019-11-12 18:47:59 +01:00
Koen Kanters d8512c73df Fail gracefully when state retrieval fails after device reconnects. #2318 2019-11-11 19:25:11 +01:00
Koen Kanters fdcaaee955 Fix typo. 2019-11-11 17:45:11 +01:00
Koenkk e2858dc90f Fix topic postfix detection having number. #2309 2019-11-11 17:36:33 +01:00
Jorge Schrauwen 3dbf454d07 Fix minor type in entityPublish.js (#2311) 2019-11-11 17:27:26 +01:00
Koen Kanters fc98b951ff Update herdsman. 2019-11-10 22:31:37 +01:00
Koen Kanters 0b0a9bca4d Update converters. 2019-11-10 19:53:37 +01:00
Jorge Schrauwen be1c81a778 #2296 only publish /availability if the state has changed (#2303) 2019-11-10 17:56:01 +01:00
Koen Kanters b61723923e Promote to 1.7.0+dev. https://github.com/Koenkk/zigbee2mqtt/issues/2263 2019-11-09 21:04:38 +01:00
Koen Kanters 551a58a4a4 1.7.0 2019-11-09 20:40:40 +01:00
Koen Kanters d562541178 Shepherd -> herdsman. 2019-11-09 20:38:47 +01:00
Koen Kanters 720e3930e3 Update herdsman converters. 2019-11-08 18:59:27 +01:00
Koen Kanters 6c453738d4 Update herdsman and converters. 2019-11-07 18:28:17 +01:00
Koen Kanters 6245c6a59f Don't log link to how to support new devices when receiving message without converter. 2019-11-07 18:27:47 +01:00
Koen Kanters dcf1c83a25 Fix tests for real now. 2019-11-07 17:48:03 +01:00
Koen Kanters 2b7d9e6ee7 Fix tests. 2019-11-06 22:08:33 +01:00
Koen Kanters 019b087af1 Fix tests. 2019-11-06 20:51:31 +01:00
Koen Kanters af770acd2d Make retain a optional option and default it to false. 2019-11-06 20:30:33 +01:00
Koen Kanters 23cf8eade9 Make graphviz networkmap ISO_8601_local time. https://github.com/Koenkk/zigbee2mqtt/issues/2239 2019-11-06 19:49:03 +01:00
Tim Kent 45c6f2345c Fix extendedPanID parameter name (#2283)
* Fix extendedPanID parameter name

* Update herdsman and fix tests.
2019-11-06 19:43:12 +01:00
Koen Kanters 00bc4de943 Update herdsman. 2019-11-05 21:35:18 +01:00
Koen Kanters 5cdf820bf6 Update herdsman and converters. 2019-11-05 21:14:19 +01:00
Koen Kanters 99118a0ad8 Update herdsman. 2019-11-05 20:42:32 +01:00
Andreas Brett 34166a5535 fixed typo (#2275) 2019-11-05 07:39:51 +01:00
Jorge Schrauwen 5ad97325be Fix missing retain on add_group, allow specifying of groupID (#2266)
* Accept json for add_group so a groupID can be provided, also set retain property on group creation

* Update util/settings tests for groupID and retain

* Update bridgeConfig tests for add_group with json
2019-11-04 17:59:00 +01:00
Koen Kanters 2fb4e20e1d Update zigbee-herdsman-converters. 2019-11-03 21:23:41 +01:00
Koen Kanters 467c0062bb Dont' crash when removing non-existing device. https://github.com/Koenkk/zigbee2mqtt/issues/2241 2019-11-03 15:02:00 +01:00
Koen Kanters afbfdda0d7 Implement force remove. https://github.com/Koenkk/zigbee2mqtt/issues/2241 2019-11-03 14:54:03 +01:00
Koen Kanters 4265fe05c6 Correctly log name. #2256 2019-11-03 14:29:43 +01:00
Koen Kanters 833769af0c Log name instead of ieeeAddr on ping. https://github.com/Koenkk/zigbee2mqtt/issues/2256 2019-11-03 14:17:57 +01:00
Koen Kanters 8a5f39f6aa Subscribe to nested topics for bind. https://github.com/Koenkk/zigbee2mqtt/issues/2250 2019-11-02 00:03:22 +01:00
Koen Kanters 857fc230d4 Update herdsman. 2019-11-01 23:55:53 +01:00
Koen Kanters 6162dcc4f0 Update zigbee-herdsman. 2019-11-01 23:33:48 +01:00
Koen Kanters 7669682716 Update zigbee-herdsman. 2019-10-30 23:56:46 +01:00
Koen Kanters 4ca8e8e43e Update zigbee-herdsman-converters. 2019-10-30 23:27:46 +01:00
Koen Kanters 5f054862f0 Update zigbee-herdsman-converters. 2019-10-30 23:12:16 +01:00
Koen Kanters 964367fc66 Update zigbee-herdsman-[converters]. 2019-10-30 19:44:02 +01:00
Luke Pomfrey 84915dd1d4 Add homeassistant integration for innr SP 222 smart switch (#2230) 2019-10-30 16:32:55 +01:00
Koen Kanters 344cd60088 Update zigbee-herdsman-converters. 2019-10-28 18:48:20 +01:00
Koenkk 754db956b5 Don't turn on with 255 brightness when transition is provided. https://github.com/Koenkk/zigbee2mqtt/issues/2220 2019-10-28 18:07:15 +01:00
Koenkk 646cd34715 Support secret for network_key. https://github.com/Koenkk/zigbee2mqtt/issues/2209 2019-10-28 18:05:50 +01:00
Koen Kanters cb3ec45294 Fix lint. 2019-10-26 18:25:51 +02:00
Koen Kanters 9eac34a5bb Update zigbee-herdsman-[converters]. 2019-10-26 18:14:51 +02:00
Koen Kanters 7e9dfd4f41 Accept device without log when no ban or whitelist set. 2019-10-26 18:05:40 +02:00
Koen Kanters 63ffe279ea Log uninteresting messages without converters as debug. 2019-10-26 18:03:44 +02:00
Koen Kanters 6f92a41ca9 Update zigbee-herdsman-converters. 2019-10-25 20:43:38 +02:00
Tommy Goode ca19b77e8c Improve support for Centralite 4257050-ZHAC dimmable plug (#2187)
* Add HA power sensors for Centralite 4257050-ZHAC outlet.

* Enable dimming in HA for Centralite 4257050-ZHAC outlet.

* Add new HA sensors for the Iris 3210-L plug.
2019-10-25 20:10:14 +02:00
Koen Kanters 4983048191 Only poll on Hue dimmer switch brightness button. https://github.com/Koenkk/zigbee2mqtt/pull/2122 2019-10-25 19:42:47 +02:00
Koen Kanters 78531a0878 Finish https://github.com/Koenkk/zigbee2mqtt/issues/2201. 2019-10-25 19:17:47 +02:00
Koenkk 505be311a4 Allow to store MQTT credentials separate from configuration.yaml. https://github.com/Koenkk/zigbee2mqtt/issues/2201 2019-10-25 18:43:14 +02:00
Koenkk 02bf8a88bc Also subscribe to groups with slashes. https://github.com/Koenkk/zigbee2mqtt/issues/2200 2019-10-25 18:40:37 +02:00
Jorge Schrauwen a813663de5 Poll device when device does not support reporting. (#2122)
* Support emulation of attReport

Some device do not support attReport for some keys, this will emulate
it.

You can configure which keys that should be read when another device
send a message and the configured device a bind target or in a group the
message was send to.

```yaml
devices:
  '0x0017880104259333':
    friendly_name: bedroom/desk_lamp
    retain: true
    debounce: 0.5
    report_emulate:
      - brightness
      - color
```

Will have the brightness and color queried for example when a hue dimmer
sends commands to the bulb.

* Refactor polling.

* Finish poll tests.

* Update herdsman.

* Improve test stability.
2019-10-24 22:15:40 +02:00
Tommy Goode ec5064bc4d Store last_seen in state.json, so that it is sent out correctly on restart. (#2197) 2019-10-24 07:46:19 +02:00
Koen Kanters ebd2f264a9 Update herdsman. 2019-10-21 21:13:05 +02:00
Koen Kanters 5bd87d338b Update zigbee-herdsman-[converters]. 2019-10-21 20:35:58 +02:00
Koen Kanters ada9316148 birthtimeMS is not realiable on Linux leading to removal of latest instead of oldest log directory which makes the logging stop. 2019-10-21 18:11:16 +02:00
Koen Kanters b476bc2bf8 Update zigbee-herdsman-converters. 2019-10-20 22:52:00 +02:00
Koen Kanters 2076bbae5d Add more logo variants. https://github.com/Koenkk/zigbee2mqtt/issues/2171 2019-10-20 21:56:11 +02:00
Koen Kanters 593dd858d9 Update herdsman. 2019-10-20 21:52:27 +02:00
Koen Kanters c80be7bda2 Don't provide undefined state. https://github.com/Koenkk/zigbee2mqtt/issues/2164 2019-10-20 21:17:18 +02:00
Koen Kanters 01dfcd18ce Install eudev 2019-10-20 17:17:19 +02:00
Koen Kanters 3effa07cf8 Add udevadm #2157 2019-10-20 16:32:00 +02:00
Tommy Goode 6b97df7b47 Add support for battery percentage on Iris 3326-L motion sensor. (#2170) 2019-10-20 11:04:23 +02:00
Tristan Crichton 35a1dd6b0a Add autodiscovery for Innr BF 263 bayonet filament bulb (#2165) 2019-10-20 11:00:32 +02:00
Tommy Goode ff9e6cdacc Improve support for MCT-340 E, MCT-340 SMA, XHS2-SE (#2156)
* Add temperature and battery level reporting for Visonic MCT-340 E contact sensor.

* Improve HA sensors for MCT-340 SMA and XHS2-SE.
2019-10-19 10:32:39 +02:00
Koen Kanters f219e5df9f Fix ban todo. 2019-10-17 22:08:34 +02:00
Koen Kanters f64285703c Implement acceptJoiningDeviceHandler. 2019-10-17 22:01:39 +02:00
Koen Kanters f02ec9a8dd Update herdsman and herdsman-converters. 2019-10-17 19:42:40 +02:00
Tommy Goode 3ca35ad72f Allow a device to be configured even if the interview process fails (#2150)
* Allow a device to be configured even if the interview process fails. This fixes #2148.

* Adjust failing test to account for new behavior.
2019-10-17 18:36:55 +02:00
Timo S da58dcbd7c Eurotronic thermostat improvments (#2124)
* - Setting temperature_command_topic
 to current_heating_setpoint for Eurotronic thermostat
- Thermostat function to dynamically publish values to HA

* Function getTemperatureCommandTopicByVendor()

* strict compare

* Get right setpoint by function and mapping
for current_heating_setpoint

* fix lint

* Update homeassistant.js

* Update homeassistant.js

* Update homeassistant.js
2019-10-17 18:31:42 +02:00
Koen Kanters 7ffe255d93 Install udev. #2145 #2146 2019-10-16 21:54:46 +02:00
Koen Kanters 512f31fbb9 Update zigbee-herdsman. 2019-10-16 21:35:16 +02:00
Koen Kanters f415171036 Allow null for port. https://github.com/Koenkk/zigbee2mqtt/issues/2145 2019-10-16 21:21:52 +02:00
Koen Kanters 4164f01a6b Update zigbee-herdsman and zigbee-herdsman-converters. 2019-10-16 19:44:44 +02:00
Koen Kanters f1b4cd0480 Don't log start error twice. 2019-10-16 19:33:55 +02:00
Koen Kanters 1428e0bb87 Don't setup reporting for Gledopto devices. https://github.com/Koenkk/zigbee2mqtt/issues/2132 2019-10-15 20:16:04 +02:00
Koen Kanters d16981d539 Update zigbee-herdsman. 2019-10-15 20:15:12 +02:00
Dennis Neufeld 2f52878140 Update README.md badge url (#2138)
* Update README.md badge url

* Update README.md
2019-10-15 19:01:33 +02:00
Gabe Cook 9ebb1b96dd Group device staying off when already off (#2140)
* Fix devices within a group staying off if they are off when the group state changes

* Group test cleanups
2019-10-15 16:42:28 +02:00
Koen Kanters 0527b89b49 Update zigbee-herdsman-converters. 2019-10-14 20:32:01 +02:00
Koen Kanters 8bcbb5930a Update zigbee-herdsman-converters. #2133 2019-10-14 18:56:41 +02:00
Gabe Cook 09b7fe699e Fix optimistic group behavior whenever a device is shared between groups (#2134) 2019-10-14 18:04:04 +02:00
Koen Kanters 4abafa9527 Update zigbee-herdsman to 0.9.2. 2019-10-13 00:09:31 +02:00
Koen Kanters f3a51f66fd Make serial and serial.port optional. 2019-10-12 23:18:01 +02:00
Koen Kanters d5925efca7 Only try to configure reporting once. https://github.com/Koenkk/zigbee2mqtt/issues/2123 2019-10-12 18:02:15 +02:00
Koen Kanters 5e0d72c41c Update zigbee-herdsman to 0.9.1. https://github.com/Koenkk/zigbee2mqtt/issues/1429 2019-10-12 14:39:06 +02:00
Koen Kanters ba92f73961 Resolve Coordinator to coordinator. https://github.com/Koenkk/zigbee2mqtt/issues/2100 2019-10-09 19:40:46 +02:00
Koen Kanters f2132f6c50 Update badge. 2019-10-09 18:09:10 +02:00
Koen Kanters 6e6305253e Update zigbee-herdsman-converters. 2019-10-09 18:08:14 +02:00
Tommy Goode dcebba857b Fix power reporting for Iris 3210-L smart plug. (#2105) 2019-10-09 17:58:05 +02:00
Koen Kanters 8d97262d39 Discover thermostat and battery for SPZB0001. https://github.com/Koenkk/zigbee2mqtt/issues/2094 2019-10-07 22:21:41 +02:00
Koen Kanters a9b4188434 Improve test stability. 2019-10-07 22:06:27 +02:00
Koen Kanters 997c5d3e44 Allow to disable Home Assistant device discovery. https://github.com/Koenkk/zigbee2mqtt/issues/2089 2019-10-07 21:58:35 +02:00
Koen Kanters a3bbb93f99 Update zigbee-herdsman and zigbee-herdsman-converters. 2019-10-07 19:34:10 +02:00
Koen Kanters 41c8c2a146 Update zigbee-herdsman-converters. 2019-10-04 19:12:49 +02:00
Koen Kanters 8833fb57b5 Update zigbee-herdsman. https://github.com/Koenkk/zigbee2mqtt/issues/2017 2019-10-04 18:58:07 +02:00
Matt 4a996bd84d Add ZWallRemote0 homeassistant mapping (#2076)
* Add ZWallRemote0 homeassistant mapping

* Fix Spaces in list

* Update homeassistant.js
2019-10-04 18:38:12 +02:00
Koen Kanters 732a97ba0c Don’t write to configuration.yaml when it didn’t change. https://github.com/Koenkk/zigbee2mqtt/issues/2071 2019-10-03 20:06:31 +02:00
Koen Kanters e7bf5ee648 Update zigbee-herdsman-converters. 2019-10-03 19:03:36 +02:00
Gabe Cook 159a846c50 Do not publish a new optimistic group state if any devices within are (#2063)
on. Relates to #764
2019-10-03 17:41:36 +02:00
Koen Kanters a6d3e7209f Update zigbee-herdsman-converters. 2019-10-02 22:01:29 +02:00
Koen Kanters 1a48c85365 Update zigbee-shepherd-converters. 2019-10-01 21:11:44 +02:00
Koen Kanters 6a8abd8ff4 Fix tests. 2019-10-01 20:58:08 +02:00
Koen Kanters b492b0ce5f Improve logging. 2019-10-01 20:50:05 +02:00
Koen Kanters 518232e15e Zigbee-herdsman 0.8.0 2019-10-01 20:22:47 +02:00
Koen Kanters 90c70e8629 Bump zigbee-herdsman-converters. 2019-09-30 21:41:53 +02:00
Gabe Cook fe4f43843d Update other groups with a shared device when a group state updates (#2055)
* Update other groups with a shared device when a group state updates #764

* Add group to test which does not have the shared device to be sure it does not change
2019-09-30 21:18:07 +02:00
Koen Kanters a5ce7e6890 Fix azure pipline triggers and conditions. 2019-09-30 21:16:16 +02:00
Koen Kanters fc3a826f50 Bump zigbee-herdsman. https://github.com/Koenkk/zigbee2mqtt/issues/892 2019-09-30 21:16:00 +02:00
Koen Kanters ebd0415945 Remove triggers. 2019-09-30 20:49:06 +02:00
Koen Kanters ce08668543 Only trigger hassio on dev change. 2019-09-30 20:39:13 +02:00
Koen Kanters 80aa023f7f Azure badge 2019-09-30 20:36:40 +02:00
Koen Kanters e4df2ac66e Add azure pipelines. 2019-09-30 20:31:31 +02:00
Koenkk 9a21e9d956 Migrate to node Docker image and buildx. https://github.com/Koenkk/zigbee2mqtt/issues/2054 2019-09-30 17:29:58 +02:00
Koen Kanters a7e9ad70e3 Bump alpine to 3.10 and other docker improvements. 2019-09-29 21:55:40 +02:00
Koen Kanters 61e2087242 Bump zigbee-herdsman-converters. 2019-09-29 21:37:26 +02:00
Raymond Mouthaan 99ebc46981 Added tzdata and --virtual devtools (#2053)
* Update Dockerfile.arm32v6

using --virtual for devtools, added tzdata

* Update Dockerfile.arm64v8

* Update Dockerfile.amd64

* Lint
2019-09-29 21:32:11 +02:00
Koen Kanters c8eb503ae7 Simplify group optimistic mode. https://github.com/Koenkk/zigbee2mqtt/issues/764 2019-09-29 14:35:05 +02:00
Pauline Middelink 7507ad6dcb Remove caching for to_side and from_side. (#2048)
Stop caching `to_side` and `from_side` which only have meaning during the `flip90` action of the MFKZQ01LM Smart Cube.
Fixes #641
2019-09-29 13:42:58 +02:00
Koen Kanters 92fcf5a85a Update zigbee-herdsman-converters. 2019-09-28 18:11:02 +02:00
Koen Kanters 42bc5f274b Fix logger test writing to configuration.yaml. 2019-09-28 13:49:27 +02:00
Koen Kanters 7b8b2c5213 Update zigbee-shepherd-converters 2019-09-28 13:48:25 +02:00
Koen Kanters 9d8e56408a Fix device configuring when paired through zigbee-shepherd. 2019-09-28 13:08:32 +02:00
Koen Kanters caf92c5e30 Update zigbee-shepherd-converters. 2019-09-28 00:26:33 +02:00
Koen Kanters 67f6ccc8a8 Don’t allow duplicate friendly_name. #1876 2019-09-27 22:56:59 +02:00
Koen Kanters bf36f1e8a3 Update zigbee-herdsman-converters and zigbee-herdsman. 2019-09-27 21:58:49 +02:00
Koen Kanters d444969151 Update zigbee-herdsman-converters. 2019-09-26 09:43:40 +02:00
Andreas Brett d12943556c Update controller.js (#2040)
fixed typo
2019-09-26 09:30:12 +02:00
Koen Kanters 9964d8e462 Fix various crashes when removing a device. https://github.com/Koenkk/zigbee2mqtt/issues/2004 2019-09-26 01:14:58 +02:00
Koen Kanters 3083655072 Codeacy badge. 2019-09-26 00:16:24 +02:00
Koen Kanters 265bcf1de3 Add 100% coverage badge. 2019-09-26 00:10:36 +02:00
Koen Kanters bd93d09290 Update zigbee-herdsman-converters. 2019-09-25 23:51:38 +02:00
Koen Kanters ca481d7f76 Update zigbee-shepherd-converters. 2019-09-25 13:38:10 +02:00
Koen Kanters 62e67e99d2 Don’t publish chached states when cache_state is disabled.https://github.com/Koenkk/zigbee2mqtt/issues/2033 2019-09-25 13:15:30 +02:00
Koen Kanters d4011fabc7 Implement group optimistic ‘group_devices’ mode. https://github.com/Koenkk/zigbee2mqtt/issues/764#issuecomment-534146878 2019-09-25 12:51:17 +02:00
Koen Kanters cfefaeb73c Validate settings on startup with JSON schema. 2019-09-25 12:08:39 +02:00
Koen Kanters 34111159ae Update Winston logger to 3.x 2019-09-25 10:55:50 +02:00
Koen Kanters 9d4705fc1c Remove onlyThis. 2019-09-23 23:59:01 +02:00
Koen Kanters 007bc42bf7 Update zigbee-shepherd-converters. 2019-09-23 23:57:41 +02:00
Koen Kanters 3001e2d3a0 Add more properties for coordinator /devices/get. https://github.com/Koenkk/zigbee2mqtt/issues/2020 2019-09-23 23:10:29 +02:00
barrygwn f60b4ddd80 added support for IKEA LED1836G9: TRADFRI bulb E27 WW 806lm (#2022)
* added 'LED1836G9' TRADFRI bulb E27 WW 806lm

* added 'LED1836G9' TRADFRI bulb E27 WW 806lm

* Update homeassistant.js
2019-09-23 22:39:22 +02:00
Koen Kanters e56e620f54 Add test case for https://github.com/Koenkk/zigbee2mqtt/issues/1997 2019-09-23 22:24:03 +02:00
Koen Kanters 41e68c8ffe Update zigbee-herdsman to 0.7.0. 2019-09-23 22:21:27 +02:00
Koen Kanters 63acd4a43b Update zigbee-herdsman and zigbee-shepherd-converters. 2019-09-22 21:29:38 +02:00
Koen Kanters c5218bbd31 Update zigbee-herdsman. 2019-09-22 20:02:46 +02:00
alwashe 4dd9f0ee57 Update homeassistant.js (#2015) 2019-09-22 18:35:47 +02:00
Koen Kanters e441cf1752 Add extra logging for failed to configure. https://github.com/Koenkk/zigbee2mqtt/issues/1957 2019-09-22 18:01:10 +02:00
Koen Kanters e65f9d36d0 Add extra failed to setup reporting logging. https://github.com/Koenkk/zigbee2mqtt/issues/2005 2019-09-22 17:56:12 +02:00
Koen Kanters 9e94148459 Fix group membership args. https://github.com/Koenkk/zigbee2mqtt/issues/2003 2019-09-20 22:09:11 +02:00
Koen Kanters e3d0b97085 Update zigbee-herdsman. 2019-09-20 22:05:47 +02:00
Koen Kanters 5b71eeeed8 Update zigbee-herdsman zigbee-shepherd-converters. 2019-09-20 21:25:56 +02:00
Koen Kanters d4f01e6893 Replace Livolo extension with DeviceEvent. https://github.com/Koenkk/zigbee2mqtt/issues/592 2019-09-19 20:36:05 +02:00
Koen Kanters e9a336fd16 Update zigbee-herdsman to 0.6.13. https://github.com/Koenkk/zigbee2mqtt/issues/1960 2019-09-18 21:18:58 +02:00
Koen Kanters 5f203d15c4 Update zigbee-herdsman to 0.6.12. 2019-09-18 19:39:49 +02:00
felixstorm d7401c817c entityPublish.js - add logger to meta (#1988) 2019-09-17 21:46:16 +02:00
Koen Kanters bd29a5d35c Back to alpine 3.9 2019-09-17 19:59:58 +02:00
Koen Kanters 983f55ce3d npm don’t install dev dependencies. 2019-09-17 19:20:52 +02:00
Koen Kanters 130366575e Bump alpine to 3.10 2019-09-17 19:14:44 +02:00
Koen Kanters 7fb7dbbe0d Docker experimental is still needed. 2019-09-17 19:12:25 +02:00
Koen Kanters a7b3304b57 Is docker experimental still needed? 2019-09-17 19:07:21 +02:00
Koen Kanters c09f55873b Add group optimistic feature. https://github.com/Koenkk/zigbee2mqtt/issues/764 2019-09-17 19:01:57 +02:00
Koen Kanters ef7049f899 Update zigbee-herdsman to 0.6.11. https://github.com/Koenkk/zigbee-herdsman/issues/29 2019-09-17 18:41:46 +02:00
Koen Kanters 1a7331609a Fix lint. 2019-09-17 18:38:25 +02:00
Koenkk ff83840f76 Change group state when device state changes. https://github.com/Koenkk/zigbee2mqtt/issues/1971 2019-09-17 18:33:27 +02:00
Koenkk c8a07a5c2d Add base extension. 2019-09-17 18:32:16 +02:00
Koenkk 11aacb8620 Fix networkmap raw graph breaking change. https://github.com/azuwis/zigbee2mqtt-networkmap/issues/6 2019-09-17 18:19:42 +02:00
Koen Kanters d24c41cbba Update zigbee-herdsman. 2019-09-16 20:09:52 +02:00
Koen Kanters e758443190 Fix tests. 2019-09-16 20:03:51 +02:00
Koen Kanters 21dadd631c Don’t throw error when devices is null. https://github.com/Koenkk/zigbee2mqtt/issues/1973 2019-09-16 19:49:49 +02:00
Koen Kanters c32f8961b6 Update zigbee-shepherd-converters. 2019-09-16 19:38:24 +02:00
Koenkk 1f1c771075 Make logging consistent. https://github.com/Koenkk/zigbee2mqtt/issues/1965 2019-09-15 09:13:02 +02:00
Koenkk de8dd74968 Update zigbee-herdsman to 0.6.9. https://github.com/Koenkk/zigbee2mqtt/issues/1960 2019-09-14 08:32:20 +02:00
Koen Kanters f5463dbf0e Add last seen to zigbee2mqtt/bridge/config/devices/get. https://github.com/Koenkk/zigbee2mqtt/issues/1910 2019-09-12 22:50:51 +02:00
Koen Kanters 9c5b3bf4d1 Use lastSeen from zigbee-herdsman. 2019-09-12 22:48:23 +02:00
Koen Kanters 798a4ee565 Fix hardware and software version in devices payload. https://github.com/Koenkk/zigbee2mqtt/issues/1958 2019-09-12 20:58:57 +02:00
Koen Kanters 09743f13f9 Improve publish logging. https://github.com/Koenkk/zigbee2mqtt/issues/1958 2019-09-12 20:53:23 +02:00
Koen Kanters 8f4cf5e520 Update zigbee-herdsman to 0.6.7. https://github.com/Koenkk/zigbee2mqtt/issues/1952 2019-09-12 20:51:24 +02:00
Koen Kanters d53e1330f5 Improve error message when reading invalid YAML file. 2019-09-11 21:42:44 +02:00
Koen Kanters 17f1a865b4 Update zigbee-herdsman to 0.6.6. https://github.com/Koenkk/zigbee2mqtt/issues/1568 2019-09-11 21:12:41 +02:00
Koen Kanters 8b4e0fd865 Log stack on zigbee start error. 2019-09-10 22:07:31 +02:00
Koen Kanters cfae1bf3b0 Default transition for groups. https://github.com/Koenkk/zigbee2mqtt/issues/1948 2019-09-10 19:42:04 +02:00
Koen Kanters 411f1fab73 Update zigbee-herdsman. #1888. 2019-09-09 21:33:34 +02:00
Koen Kanters 053e646f50 Update zigbee-herdsman-converters. 2019-09-09 21:31:57 +02:00
Koen Kanters d83085ea7f Zigbee-herdsman (#1945)
* Update zigbee-herdsman and zigbee-shepherd-converters.

* Force Aqara S2 Lock endvices (#1764)

* Start on zigbee-herdsman controller refactor.

* More updates.

* Cleanup zapp.

* updates.

* Propagate adapter disconnected event.

* Updates.

* Initial refactor to zigbee-herdsman.

* Refactor deviceReceive to zigbee-herdsman.

* Rename

* Refactor deviceConfigure.

* Finish bridge config.

* Refactor availability.

* Active homeassistant extension and more refactors.

* Refactor groups.

* Enable soft reset.

* Activate group membership

* Start on tests.

* Enable reporting.

* Add more controller tests.

* Add more tests

* Fix linting error.

* Data en deviceReceive tests.

* Move to zigbee-herdsman-converters.

* More device publish tests.

* Cleanup dependencies.

* Bring device publish coverage to 100.

* Bring home assistant test coverage to 100.

* Device configure tests.

* Attempt to fix tests.

* Another attempt.

* Another one.

* Another one.

* Another.

* Add wait.

* Longer wait.

* Debug.

* Update dependencies.

* Another.

* Begin on availability tests.

* Improve availability tests.

* Complete deviceAvailability tests.

* Device bind tests.

* More tests.

* Begin networkmap refactors.

* start on networkmap tests.

* Network map tests.

* Add utils tests.

* Logger tests.

* Settings and logger tests.

* Ignore some stuff for coverage and add todos.

* Add remaining missing tests.

* Enforce 100% test coverage.

* Start on groups test and refactor entityPublish to resolveEntity

* Remove joinPathStorage, not used anymore as group information is stored into zigbee-herdsman database.

* Fix linting issues.

* Improve tests.

* Add groups.

* fix group membership.

* Group: log names.

* Convert MQTT message to string by default.

* Fix group name.

* Updates.

* Revert configuration.yaml.

* Add new line.

* Fixes.

* Updates.

* Fix tests.

* Ignore soft reset extension.
2019-09-09 19:48:09 +02:00
146 changed files with 38979 additions and 22136 deletions
+15 -5
View File
@@ -1,7 +1,17 @@
node_modules
.travis*
.eslintignore
.eslintrc.js
.git
.github
.gitignore
*.png
firmware
docker/Dockerfile*
.idea
.npmrc
.travis*
.travis.yml
README.md
docker/Dockerfile*
images
node_modules
scripts
test
coverage
update.sh
+2 -1
View File
@@ -1 +1,2 @@
node_modules/*
node_modules/*
test/
+45
View File
@@ -0,0 +1,45 @@
module.exports = {
'env': {
'jest/globals': true,
'es6': true,
'node': true,
},
'extends': ['eslint:recommended', 'google', 'plugin:jest/recommended', 'plugin:jest/style'],
'parserOptions': {
'ecmaVersion': 2018,
'sourceType': 'module',
},
'rules': {
'require-jsdoc': 'off',
'indent': ['error', 4],
'max-len': ['error', {'code': 120}],
'no-prototype-builtins': 'off',
},
'plugins': [
'jest',
],
'overrides': [{
files: ['*.ts'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/recommended'],
parserOptions: {
project: './tsconfig.json',
},
rules: {
'@typescript-eslint/await-thenable': 'error',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-unused-vars': 'error',
'@typescript-eslint/semi': ['error'],
'array-bracket-spacing': ['error', 'never'],
'indent': ['error', 4],
'max-len': ['error', {'code': 120}],
'no-return-await': 'error',
'object-curly-spacing': ['error', 'never'],
},
}],
};
-21
View File
@@ -1,21 +0,0 @@
{
"env": {
"jest/globals": true,
"es6": true,
"node": true
},
"extends": ["eslint:recommended", "google", "plugin:jest/recommended", "plugin:jest/style"],
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"require-jsdoc": "off",
"indent": ["error", 4],
"max-len": ["error", { "code": 120 }],
"no-prototype-builtins": "off"
},
"plugins": [
"jest"
]
}
+3 -1
View File
@@ -1,2 +1,4 @@
github: [koenkk]
custom: https://www.paypal.me/koenkk
custom:
- https://www.paypal.me/koenkk
- https://www.buymeacoffee.com/koenkk
+28 -12
View File
@@ -1,23 +1,38 @@
<!--
Before submitting an issue make sure you've searched for a similar issue and read the documentation: https://www.zigbee2mqtt.io/.
Rules (don't ignore these, your issue will be closed without further notice):
- English only
- Make sure you are on the latest Zigbee2MQTT version
- Provide a clear description of the problem
- DON'T copy logs directly here, post a link to https://hastebin.com/ or https://pastebin.com/.
- Make sure you are running the latest firmware https://github.com/koenkk/z-stack-firmware.
Did you read the FAQ?
https://www.zigbee2mqtt.io/information/FAQ.html
- https://www.zigbee2mqtt.io/information/FAQ.html
Zigbee2MQTT fails to start?
- https://www.zigbee2mqtt.io/information/FAQ.html#help-zigbee2mqtt-fails-to-start
Having issues when using a CC2531?
- Make sure the CC2531 is connected through a USB extension cable
- Try the source routing firmware: https://github.com/Koenkk/Z-Stack-firmware/tree/master/coordinator/Z-Stack_Home_1.2/bin/source_routing
- With larger networks (30/40+) devices, your CC2531 might not be powerful enough. This will cause weird issues, in this case it's advised to use a more powerful adapter: https://www.zigbee2mqtt.io/information/supported_adapters.html#texas-instruments-cc26x2r1
Unsupported device?
https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html
- https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html
A question?
Read the documentation: https://www.zigbee2mqtt.io/
Device does not pair or interview fails?
- https://www.zigbee2mqtt.io/information/FAQ.html#why-does-my-device-not-or-fail-to-pair
Bug report:
- First make sure you are on the latest version of zigbee2mqtt.
- Make sure you are running the latest CC253X firmware from https://github.com/koenkk/z-stack-firmware.
- Provide a clear description of the problem.
Bug report?
- If applicable, provide steps how to reproduce the problem.
- Provide a log with `log_level` set to `debug`, see https://www.zigbee2mqtt.io/configuration/configuration.html
- DON'T copy logs directly here, post a link to https://hastebin.com/ or https://pastebin.com/.
- Provide the herdsman debug logging: https://www.zigbee2mqtt.io/information/debug.html#zigbee-herdsman-debug-logging
-->
<!--Start your bug report below this line-->
# Bug Report
## What happened
@@ -26,5 +41,6 @@ Bug report:
## How to reproduce it (minimal and precise)
## Debug Info
zigbee2mqtt version:
CC253X firmware version:
Zigbee2MQTT version:
Adapter hardware: CC2531, CC2530, CC26X2R1 or CC1352P-2
Adapter firmware version:
+17
View File
@@ -0,0 +1,17 @@
blank_issues_enabled: false
contact_links:
- name: Questions/discussion
url: https://github.com/Koenkk/zigbee2mqtt/discussions/new
about: Ask questions, discuss about devices or show things you made
- name: Frontend issues
url: https://github.com/nurikk/z2m-frontend/issues
about: Issues related to the frontend.
- name: Home Assistant addon issues
url: https://github.com/zigbee2mqtt/hassio-zigbee2mqtt/issues
about: Issues related to the Home Assistant addon.
- name: FAQ
url: https://www.zigbee2mqtt.io/information/FAQ.html
about: Frequently asked questions.
- name: Support Chat
url: https://discord.gg/NyseBeK
about: Chat for feedback, questions and troubleshooting.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request
assignees: ''
---
## Is your feature request related to a problem? Please describe
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
## Describe the solution you'd like
A clear and concise description of what you want to happen.
## Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
## Additional context
Add any other context or screenshots about the feature request here.
@@ -0,0 +1,21 @@
---
name: New device support request
about: Request support for a new device
title: ''
labels: new device support
assignees: ''
---
<!--
VERY IMPORTANT: Before submitting a request, first (try to) follow: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html
Dumping just the info about this device without actually attemping adding support yourself will likely lead into this issue being ignored.
Clearly indicate what you tried and where you got stuck.
-->
## Information about the device + link
..
## data/database.db entry of the device
..
+54
View File
@@ -0,0 +1,54 @@
---
name: Problem report
about: Create a report to help us improve
title: ''
labels: problem
assignees: ''
---
<!--
Before submitting an issue make sure you've searched for a similar issue and read the documentation: https://www.zigbee2mqtt.io/.
Rules (don't ignore these, your issue will be closed without further notice):
- English only
- Make sure you are on the latest Zigbee2MQTT version
- Provide a clear description of the problem
- DON'T copy logs directly here, post a link to https://hastebin.com/ or https://pastebin.com/.
- Make sure you are running the latest firmware https://github.com/koenkk/z-stack-firmware.
Did you read the FAQ?
- https://www.zigbee2mqtt.io/information/FAQ.html
Zigbee2MQTT fails to start?
- https://www.zigbee2mqtt.io/information/FAQ.html#help-zigbee2mqtt-fails-to-start
Having issues when using a CC2531?
- Make sure the CC2531 is connected through a USB extension cable
- Try the source routing firmware: https://github.com/Koenkk/Z-Stack-firmware/tree/master/coordinator/Z-Stack_Home_1.2/bin/source_routing
- With larger networks (30/40+) devices, your CC2531 might not be powerful enough. This will cause weird issues, in this case it's advised to use a more powerful adapter: https://www.zigbee2mqtt.io/information/supported_adapters.html#texas-instruments-cc26x2r1
Unsupported device?
- https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html
Device does not pair or interview fails?
- https://www.zigbee2mqtt.io/information/FAQ.html#why-does-my-device-not-or-fail-to-pair
Bug report?
- If applicable, provide steps how to reproduce the problem.
- Provide the herdsman debug logging: https://www.zigbee2mqtt.io/information/debug.html#zigbee-herdsman-debug-logging
-->
<!--Start your bug report below this line-->
## What happened
## What did you expect to happen
## How to reproduce it (minimal and precise)
## Debug info
Zigbee2MQTT version:
Adapter hardware: CC2531, CC2530, CC26X2R1, CC1352P-2, Conbee II
Adapter firmware version:
+1
View File
@@ -0,0 +1 @@
preferredBranch: dev
-13
View File
@@ -1,13 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
+84
View File
@@ -0,0 +1,84 @@
name: CI
on: [push, pull_request]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2-beta
with:
node-version: 14
registry-url: https://registry.npmjs.org/
- name: Get NodeJS Version
id: nodeversion
run: |
echo "::set-output name=version::$(node --version)"
- name: Restore node_modules cache
id: cache-node-modules
uses: actions/cache@v2
with:
path: node_modules
key: ${{ runner.os }}-${{ steps.nodeversion.outputs.version }}-${{ hashFiles('npm-shrinkwrap.json') }}
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- name: Build
run: npm run build
- name: Test
run: npm run test-with-coverage
- name: Lint
run: npm run eslint
- name: Docker login
if: (github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push'
run: echo ${{ secrets.DOCKER_KEY }} | docker login -u koenkk --password-stdin
- name: Docker login ghcr.io
if: (github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push'
run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u koenkk --password-stdin
- name: Docker setup - QEMU
if: (github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push'
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: Docker setup - Buildx
if: (github.ref == 'refs/heads/dev' || startsWith(github.ref, 'refs/tags/')) && github.event_name == 'push'
id: buildx
uses: docker/setup-buildx-action@v1
with:
version: latest
- name: Docker build dev
if: github.ref == 'refs/heads/dev' && github.event_name == 'push'
run: |
docker buildx build \
--build-arg COMMIT=$(git rev-parse --short HEAD) \
--platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7 \
-f docker/Dockerfile \
--push \
-t koenkk/zigbee2mqtt:latest-dev -t ghcr.io/koenkk/zigbee2mqtt:latest-dev \
.
- name: Docker build release
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
run: |
TAG="$(git describe --tags)"
docker buildx build \
--build-arg COMMIT=$(git rev-parse --short HEAD) \
--platform linux/arm64/v8,linux/amd64,linux/arm/v6,linux/arm/v7 \
-f docker/Dockerfile \
--push \
-t koenkk/zigbee2mqtt:latest -t "koenkk/zigbee2mqtt:$TAG" -t ghcr.io/koenkk/zigbee2mqtt:latest -t "ghcr.io/koenkk/zigbee2mqtt:$TAG" \
.
- name: Publish to npm
if: startsWith(github.ref, 'refs/tags/') && github.event_name == 'push'
run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN }}
- name: Trigger zigbee2mqtt/hassio-zigbee2mqtt build
if: github.ref == 'refs/heads/dev' && github.event_name == 'push'
run: |
curl -s \
--request POST \
--header "Content-Type: application/json" \
--data '{"definition": {"id": 9}}' \
-u ${{ secrets.HASSIO_TRIGGER_SECRET }} \
"https://dev.azure.com/zigbee2mqtt/Zigbee2mqtt%20Add-on/_apis/build/builds?api-version=5.1"
+19
View File
@@ -0,0 +1,19 @@
name: "Close stale issues/pull requests"
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
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'
days-before-stale: 30
days-before-close: 7
operations-per-run: 500
exempt-issue-labels: 'breaking change'
+25
View File
@@ -0,0 +1,25 @@
name: Update dependencies
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 0"
jobs:
update_deps:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
with:
node-version: 14
- run: rm -rf npm-shrinkwrap.json
- run: npx npm-check-updates -u
- run: npm install && npm shrinkwrap --dev
- uses: peter-evans/create-pull-request@v3
with:
commit-message: Update dependencies
branch: "update_deps"
title: Update dependencies
+22
View File
@@ -0,0 +1,22 @@
name: Update zigbee-frontend
on:
repository_dispatch:
types: update_frontend
jobs:
update_frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
with:
node-version: 14
- run: npm install zigbee2mqtt-frontend@${{ github.event.client_payload.version }} --save-exact
- uses: peter-evans/create-pull-request@v3
with:
commit-message: Update zigbee2mqtt-frontend to ${{ github.event.client_payload.version }}
branch: "update_frontend"
title: Update zigbee-frontend to ${{ github.event.client_payload.version }}
+22
View File
@@ -0,0 +1,22 @@
name: Update zigbee-herdsman
on:
repository_dispatch:
types: update_zh
jobs:
update_zh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
with:
node-version: 14
- run: npm install zigbee-herdsman@${{ github.event.client_payload.version }} --save-exact
- uses: peter-evans/create-pull-request@v3
with:
commit-message: Update zigbee-herdsman to ${{ github.event.client_payload.version }}
branch: "update_zh"
title: Update zigbee-herdsman to ${{ github.event.client_payload.version }}
+22
View File
@@ -0,0 +1,22 @@
name: Update zigbee-herdsman-converters
on:
repository_dispatch:
types: update_zhc
jobs:
update_zhc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
with:
node-version: 14
- run: npm install zigbee-herdsman-converters@${{ github.event.client_payload.version }} --save-exact
- uses: peter-evans/create-pull-request@v3
with:
commit-message: Update zigbee-herdsman-converters to ${{ github.event.client_payload.version }}
branch: "update_zhc"
title: Update zigbee-herdsman-converters to ${{ github.event.client_payload.version }}
+15 -1
View File
@@ -11,6 +11,9 @@ pids
*.seed
*.pid.lock
# Compiled source
dist/*
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
@@ -65,4 +68,15 @@ data/state.json
data/log
data-backup/
data/coordinator_backup.json
data/.storage
data/.storage
data/database.db.backup
data/extension
# MacOS indexing file
.DS_Store
# IDE specific folders
.idea
# Ignore config
data/*.yaml
+27
View File
@@ -0,0 +1,27 @@
#tests
test
coverage
#build tools
.travis.yml
.jenkins.yml
.codeclimate.yml
.github
babel.config.js
#linters
.jscsrc
.jshintrc
.eslintrc*
.dockerignore
.eslintignore
.gitignore
#editor settings
.vscode
#src
lib
docs
docker
images
-33
View File
@@ -1,33 +0,0 @@
language: node_js
sudo: required
services:
- docker
node_js:
- "10"
before_install:
- "echo '{\"experimental\": true}' | sudo tee /etc/docker/daemon.json"
- sudo apt update -y
- sudo apt install --only-upgrade docker-ce -y
- sudo service docker restart
install:
- npm install
before_script:
- npm test
- npm run eslint
script:
- ".travis/docker.sh"
- ".travis/trigger-downstream.sh"
env:
global:
- DOCKER_USERNAME=koenkk
- secure: q5W9+mHz13PslLkTxuYNXivOau+N5OyB53sqgb+krOCPlbN9+gvi2Av9SribVd5jp2yx2O9rV/mr8eS0M2ykvBJ3UsIsCXiFL1dEPmsz1wlFAnW3kbD2EGhGFEV0dWRflSlA+5iQtcMPvbYu2PAOChUUoY7NNlhcz2EC+XXUapvvvaDwA1oSdtX+m61qyREshZb8B57DyXhziy6i/xjhFa84C0mR/iGFRWpZgcxmrNFH+/XDhSIpdq2KshhDWhjyag3ukAsTxTpqzLh1rFRlczjJEn0CcHG4WHsWHUFn9KK2lvT/YCDP8w0URnR1bCr8nyxGZJ2DLW6AzxZtJfWjvbeZYjO2R3WeHpzp6Jw6Qz5pG3gmu2FgeFpZ3FTEGtJ/Ev0/pjkY2Msx9mItzUJ7D8hY2noQZMPASar6oXEDYlkomx7gHHla0MPv3PKSJg5LX6Ybl137GIa6MLYYyz6SEKfyRUQhy3Itqrb/ID/ZP0UuLgyyDfShb8A6XOnsVqwZAsOPtU2UPnD1vsVXhjkpflK9+7QjL5m9MSqfAhg6qtwNsswl1KSiyhmdldGhZW5OfUasDxZKHyx7bsS1BhNnLi/iy4ifDh6KSr64aUW4iM0X99gkU+662Hgf73QpIG+oP41r30iEN0unTcRrFQDIbTSSapbA95bwUCBF1CgQC20=
- secure: em3lBVXvZ3kOVI4ipVlh93NIU6guLvyzHMmsLDuxhc92VFURqlYu3iXTTNEnknwyE31mziAkVFnmj+3OENd/VfzP01d4KKaYAQrbn2AnOMvcIIExLfaFU5QqbW1RMwRBIifhvrmboKt07pFsUy3Rghs80SwNSFDfLFoMhFMz+NdIZfJGW8LJy+gUPmz10YGzqh/chreowqOemgBBoswCGwIh1xB1KNejew3bQllnwQYGXcGuTDwDT4Wz+ObxlFt7YR/4n4oJY8jQYRPolM9qHQAGyn/Cn0TL3c8JqiBpVc1hm2OhYSDqvK0xf5IKsD+kIfFJPGa7nF2cwmhKdUNYR47oue3KB5tdrtDhwqUooTglvBOSXUIbthUR9Xu40ziyd5tHy0ixaLnDRGuKIIvEnXlcE6CgApoe3y2kHYa5dY+eUKxWwvH7b5hG+u82dYvw3VYpCHAnDQVgUzz4F63qZ2WZhcH0W3PF3/ytVAHyMu2vAMSrSXGi5xgM6el7Gp7SFVTFXBurbOaoJ3ZwwSEDP5d8mDyk1d8thmkQFL9P6iWtNnXOzjv4GIliEDWQg76BX6MLD3n3fnP0aq+RVmv+ev2Lp4xZZDfgGPek7g35IsaiohH6YvHloxE+ETQ0Ttb1lCQos9fj7LlI+ud6ExjwyRuEnzCOzr/qC/3Leg85Wc8=
- secure: GbJVFFY4nmQovp8i2VoQ1AOV8h9QoAcleBV9Mg5TItA8U2Y+6t9wx0iWbaclxOrzI727XZOk5HquMTKKTI430lT6OjU01+YJqwyq+k650YiX5PImsgJXGhFzBKeUcB3A53kKijfr9aEV00YiXRsKoKAn+Bl09m/9O+melBbTwO/YAQyt6EoUt21Yk0BoqpW2CTMPAgsU5tm6Ra3bbJ+IaUYVMYBtuHqtGiKg8jgTHqRhwKejDyV7+1dDxX8q51bK2Kb6PujbI1SS5wsJEpkU/eoPs7MuprmlYarYtBt1fDXSK1EOjcfpyEFRlrNLewIKiFEo3dkTOEtW2a4t3tcAiXOj8Hcvp+6RsjTfnjYmZweHVh/JKDhujjHBMviyTjwp4RnPaQSFou0iVIB5+Mo34hUhFDXc30SBzaux+lyR3rGoEu5pubZNjG5CkKIpw3IyduNKtIrlbCnfg+WDU3jrXmk0fzmwyriyXhx9BAzM+hyFiElZ+3xoXAlmDlwvaRZyJuQQNslwGPbZyX9EByIUkECjYPf92QPyD0mjbn8C32IphgQ515Up+15g2meDniugzowLJkDe3W86M5fB1kPQiDq5oT4M6TgAPRElLN6/ibyfOzDAtOdZgUiQvFnUQb1s9LunZqrc57AKzuzl2xG9Ok/cUkZFSOjrFr40jXgS2Lw=
-68
View File
@@ -1,68 +0,0 @@
#!/bin/bash -e
login() {
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
}
tag_push() {
docker tag $DOCKER_USERNAME/zigbee2mqtt:$1 $DOCKER_USERNAME/zigbee2mqtt:$2
docker push $DOCKER_USERNAME/zigbee2mqtt:$2
}
build_and_push() {
docker build --platform=$3 --build-arg COMMIT=$(git rev-parse --short HEAD) -t $DOCKER_USERNAME/zigbee2mqtt:$1 -f $2 .
docker push $DOCKER_USERNAME/zigbee2mqtt:$1
}
push_manifest() {
export DOCKER_CLI_EXPERIMENTAL=enabled
docker manifest create $DOCKER_USERNAME/zigbee2mqtt:latest$1 $DOCKER_USERNAME/zigbee2mqtt:latest$1 $DOCKER_USERNAME/zigbee2mqtt:arm32v6$1 $DOCKER_USERNAME/zigbee2mqtt:arm64v8$1
docker manifest annotate $DOCKER_USERNAME/zigbee2mqtt:latest$1 $DOCKER_USERNAME/zigbee2mqtt:arm32v6$1 --os linux --arch arm --variant v6
docker manifest annotate $DOCKER_USERNAME/zigbee2mqtt:latest$1 $DOCKER_USERNAME/zigbee2mqtt:arm64v8$1 --os linux --arch arm64 --variant v8
docker manifest inspect $DOCKER_USERNAME/zigbee2mqtt:latest$1
docker manifest push -p $DOCKER_USERNAME/zigbee2mqtt:latest$1
docker run --rm mplatform/mquery $DOCKER_USERNAME/zigbee2mqtt:latest$1
export DOCKER_CLI_EXPERIMENTAL=disabled
}
# Only update Docker images for:
# - dev branch
# - version release
if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ ! -z ${TRAVIS_TAG+x} ] && [ ! "$TRAVIS_TAG" = "" ]
then
echo "Updating docker images for master branch!"
login
# Push versioned images
build_and_push "$TRAVIS_TAG" docker/Dockerfile.amd64 amd64
build_and_push "$TRAVIS_TAG-arm32v6" docker/Dockerfile.arm32v6 arm
build_and_push "$TRAVIS_TAG-arm64v8" docker/Dockerfile.arm64v8 arm64
# Push latest images.
tag_push "$TRAVIS_TAG-arm32v6" "arm32v6"
tag_push "$TRAVIS_TAG-arm64v8" "arm64v8"
tag_push "$TRAVIS_TAG" latest
# Push manifest
push_manifest ""
elif [ "$TRAVIS_BRANCH" = "dev" -a "$TRAVIS_PULL_REQUEST" = "false" ]
then
echo "Updating docker images for dev branch!"
login
build_and_push latest-dev docker/Dockerfile.amd64 amd64
build_and_push arm32v6-dev docker/Dockerfile.arm32v6 arm
build_and_push arm64v8-dev docker/Dockerfile.arm64v8 arm64
# Push manifest
push_manifest "-dev"
else
echo "Not updating docker images, triggered by pull request or not on master/dev branch"
fi
-30
View File
@@ -1,30 +0,0 @@
#!/bin/bash
function travis_trigger() {
local org=$1 && shift
local repo=$1 && shift
local branch=${1:-master} && shift
body="{
\"request\": {
\"branch\": \"${branch}\"
}
}"
curl -s -X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Travis-API-Version: 3" \
-H "Authorization: token $TRAVIS_TOKEN" \
-d "$body" \
"https://api.travis-ci.org/repo/${org}%2F${repo}/requests"
}
# Only trigger downstream if on dev branch and not pull request
if [ "$TRAVIS_BRANCH" = "dev" -a "$TRAVIS_PULL_REQUEST" = "false" ]
then
echo "Triggering build of downstream projects!"
travis_trigger "danielwelch" "hassio-zigbee2mqtt" "master"
else
echo "Not triggering build of downstream projects, triggered by pull request or not on dev branch"
fi
+132
View File
@@ -0,0 +1,132 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
+8
View File
@@ -0,0 +1,8 @@
# Contributing to Zigbee2MQTT
Everybody is invited and welcome to contribute to Zigbee2MQTT. Zigbee2MQTT is writen in JavaScript and is based upon [zigbee-herdsman](https://github.com/koenkk/zigbee-herdsman) and [zigbee-herdsman-converters](https://github.com/koenkk/zigbee-herdsman-converters). Zigbee-herdsman-converters contains all device definition, zigbee-herdsman is responsible for handling all communication with the adapter.
- Pull requests are always created against the [**dev**](https://github.com/Koenkk/zigbee2mqtt/tree/dev) branch.
- Easiest way to start developing Zigbee2MQTT is by setting up a development environment (aka bare-metal installation). You can follow this [guide](https://www.zigbee2mqtt.io/getting_started/running_zigbee2mqtt.html#running-zigbee2mqtt) to do this.
- You can run the tests locally by executing `npm test`. Zigbee2MQTT enforces 100% code coverage, in case you add new code check if you code is covered by running `npm run test-with-coverage`. The coverage report can be found under `coverage/lcov-report/index.html`. Linting is also enforced and can be run with `npm run eslint`.
- When you want to add support for a new devices no changes to Zigbee2MQTT have to be made, only to zigbee-herdsman-converters. You can find a guide for it [here](https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html).
+20 -5
View File
@@ -5,8 +5,8 @@
<br>
<br>
<div style="display: flex;">
<a href="https://travis-ci.org/Koenkk/zigbee2mqtt/">
<img src="https://img.shields.io/travis/Koenkk/zigbee2mqtt.svg">
<a href="https://github.com/Koenkk/zigbee2mqtt/actions?query=workflow%3ACI">
<img src="https://github.com/koenkk/zigbee2mqtt/workflows/CI/badge.svg">
</a>
<a href="https://github.com/Koenkk/zigbee2mqtt/releases">
<img src="https://img.shields.io/github/release/koenkk/zigbee2mqtt.svg">
@@ -23,8 +23,17 @@
<a href="http://zigbee2mqtt.discourse.group/">
<img src="https://img.shields.io/discourse/https/zigbee2mqtt.discourse.group/status.svg">
</a>
<a>
<img src="https://img.shields.io/badge/Coverage-100%25-brightgreen.svg">
</a>
<a href="https://www.codacy.com/manual/Koenkk/zigbee2mqtt?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=Koenkk/zigbee2mqtt&amp;utm_campaign=Badge_Grade">
<img src="https://api.codacy.com/project/badge/Grade/24f1e0fe39f04daa810e8a1416693d3f">
</a>
<a href="https://www.npmjs.com/package/zigbee2mqtt">
<img src="https://img.shields.io/npm/v/zigbee2mqtt">
</a>
</div>
<h1>Zigbee2mqtt 🌉 🐝</h1>
<h1>Zigbee2MQTT 🌉 🐝</h1>
<p>
Allows you to use your Zigbee devices <b>without</b> the vendors bridge or gateway.
</p>
@@ -39,12 +48,12 @@ The [documentation](https://www.zigbee2mqtt.io/) provides you all the informatio
If you aren't familiar with **Zigbee** terminology make sure you [read this](https://www.zigbee2mqtt.io/information/zigbee_network.html) to help you out.
## [Integrations](https://www.zigbee2mqtt.io/#integration)
Zigbee2mqtt integrates well with (almost) every home automation solution because it uses MQTT. However the following integrations are worth mentioning:
Zigbee2MQTT integrates well with (almost) every home automation solution because it uses MQTT. However the following integrations are worth mentioning:
<img align="left" height="100px" width="100px" src="https://user-images.githubusercontent.com/7738048/40914297-49e6e560-6800-11e8-8904-36cce896e5a8.png">
### [Home Assistant](https://www.home-assistant.io/)
- [Hassio](https://www.home-assistant.io/hassio/): Using [the official addon](https://github.com/danielwelch/hassio-zigbee2mqtt) from [danielwelch](https://github.com/danielwelch)
- [Home Assistant](https://www.home-assistant.io/hassio/): Using [the official addon](https://github.com/zigbee2mqtt/hassio-zigbee2mqtt)
- Generic install or Hassbian: Using instructions [here](https://www.zigbee2mqtt.io/integration/home_assistant.html)
<img align="left" height="100px" width="100px" src="https://user-images.githubusercontent.com/2734836/47615848-b8dd8700-dabd-11e8-9d77-175002dd8987.png">
@@ -57,6 +66,12 @@ Zigbee2mqtt integrates well with (almost) every home automation solution because
## Architecture
![Architecture](images/architecture.png)
### Internal Architecture
Zigbee2MQTT is made up of three modules, each developed in its own Github project. Starting from the hardware (adapter) and moving up; [zigbee-herdsman](https://github.com/koenkk/zigbee-herdsman) connects to your Zigbee adapter an makes an API available to the higher levels of the stack. For e.g. Texas Instruments hardware, zigbee-herdsman uses the [TI zStack monitoring and test API](https://github.com/koenkk/zigbee-herdsman/raw/master/docs/Z-Stack%20Monitor%20and%20Test%20API.pdf) to communicate with the adapter. Zigbee-herdsman handles the core Zigbee communication. The module [zigbee-herdsman-converters](https://github.com/koenkk/zigbee-herdsman-converters) handles the mapping from individual device models to the Zigbee clusters they support. [Zigbee clusters](https://github.com/Koenkk/zigbee-herdsman/raw/master/docs/Zigbee%20Cluster%20Library%20Specification%20v7.pdf) are the layers of the Zigbee protocol on top of the base protocol that define things like how lights, sensors and switches talk to each other over the Zigbee network. Finally, the Zigbee2MQTT module drives zigbee-herdsman and maps the zigbee messages to MQTT messages. Zigbee2MQTT also keeps track of the state of the system. It uses a `database.db` file to store this state; a text file with a JSON database of connected devices and their capabilities.
### Developing
Zigbee2MQTT uses TypeScript (partially for now). Therefore after making changes to files in the `lib/` directory you need to recompile Zigbee2MQTT. This can be done by executing `npm run build`. For faster development instead of running `npm run build` you can run `npm run build-watch` in another terminal session, this will recompile as you change files.
## Supported devices
See [Supported devices](https://www.zigbee2mqtt.io/information/supported_devices.html) to check whether your device is supported. There is quite an extensive list, including devices from vendors like Xiaomi, Ikea, Philips, OSRAM and more.
+11
View File
@@ -0,0 +1,11 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
assumptions: {setPublicClassFields: true},
plugins: [
['@babel/plugin-proposal-decorators', {'legacy': true}],
['@babel/plugin-proposal-class-properties'],
],
};
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env node
const path = require('path');
process.env['ZIGBEE2MQTT_DATA'] = process.env['ZIGBEE2MQTT_DATA'] || path.join(process.env['HOME'], '.z2m');
require('./index');
+37
View File
@@ -0,0 +1,37 @@
FROM node:14-alpine3.12 as base
WORKDIR /app
RUN apk add --no-cache tzdata eudev tini
COPY package.json ./
# Dependencies and build
FROM base as dependencies_and_build
COPY npm-shrinkwrap.json tsconfig.json index.js ./
COPY lib ./lib
RUN apk add --no-cache --virtual .buildtools make gcc g++ python3 linux-headers git && \
npm ci --no-audit --no-optional --no-update-notifier && \
npm run build && \
rm -rf node_modules && \
npm ci --production --no-audit --no-optional --no-update-notifier && \
apk del .buildtools
# Release
FROM base as release
COPY --from=dependencies_and_build /app/node_modules ./node_modules
COPY --from=dependencies_and_build /app/dist ./dist
COPY LICENSE index.js data/configuration.yaml ./
COPY docker/docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
RUN mkdir /app/data
ARG COMMIT
RUN echo "$COMMIT" > dist/.hash
ENTRYPOINT ["docker-entrypoint.sh"]
CMD [ "/sbin/tini", "--", "node", "index.js"]
-20
View File
@@ -1,20 +0,0 @@
FROM alpine:3.9
# Copy files
ADD . /app
RUN cp /app/data/configuration.yaml /app
RUN cp /app/docker/run.sh /app
RUN chmod +x /app/run.sh
WORKDIR /app
# Write .hash.json
ARG COMMIT
RUN echo "{\"hash\": \"$COMMIT\"}" > .hash.json
# Install dependencies
RUN apk add --update --no-cache make gcc g++ python linux-headers udev nodejs npm git && \
npm install --unsafe-perm && \
apk del make gcc g++ python linux-headers udev git
# Entrypoint
ENTRYPOINT ["./run.sh"]
-22
View File
@@ -1,22 +0,0 @@
FROM arm32v6/alpine:3.9
# Setup cross-build
ENV QEMU_EXECVE 1
COPY docker/qemu-arm-static /usr/bin
WORKDIR /app
# Write .hash.json
ARG COMMIT
RUN [ "qemu-arm-static", "/bin/sh", "-c", "echo {\\\"hash\\\": \\\"$COMMIT\\\"} > .hash.json" ]
# Copy files & install dependencies
ADD . /app
RUN [ "qemu-arm-static", "/bin/sh", "-c", \
"cp /app/data/configuration.yaml /app && \
cp /app/docker/run.sh /app && chmod +x /app/run.sh && \
apk add --update --no-cache make gcc g++ python linux-headers udev nodejs npm git && \
npm install --unsafe-perm && \
apk del make gcc g++ python linux-headers udev git"]
# Entrypoint
ENTRYPOINT ["./run.sh"]
-22
View File
@@ -1,22 +0,0 @@
FROM arm64v8/alpine:3.9
# Setup cross-build
ENV QEMU_EXECVE 1
COPY docker/qemu-aarch64-static /usr/bin
WORKDIR /app
# Write .hash.json
ARG COMMIT
RUN [ "qemu-aarch64-static", "/bin/sh", "-c", "echo {\\\"hash\\\": \\\"$COMMIT\\\"} > .hash.json" ]
# Copy files & install dependencies
ADD . /app
RUN [ "qemu-aarch64-static", "/bin/sh", "-c", \
"cp /app/data/configuration.yaml /app && \
cp /app/docker/run.sh /app && chmod +x /app/run.sh && \
apk add --update --no-cache make gcc g++ python linux-headers udev nodejs npm git && \
npm install --unsafe-perm && \
apk del make gcc g++ python linux-headers udev git"]
# Entrypoint
ENTRYPOINT ["./run.sh"]
-1
View File
@@ -1 +0,0 @@
qemu-aarch64-static and qemu-arm-static are taken from https://github.com/resin-io/qemu/releases/tag/v2.9.0%2Bresin1
@@ -1,4 +1,5 @@
#!/bin/sh
set -e
if [ ! -z "$ZIGBEE2MQTT_DATA" ]; then
DATA="$ZIGBEE2MQTT_DATA"
@@ -13,4 +14,4 @@ if [ ! -f "$DATA/configuration.yaml" ]; then
cp /app/configuration.yaml "$DATA/configuration.yaml"
fi
exec npm start
exec "$@"
Binary file not shown.
Binary file not shown.
-1
View File
@@ -1 +0,0 @@
theme: jekyll-theme-cayman
-1
View File
@@ -1 +0,0 @@
Moved to [https://www.zigbee2mqtt.io](https://www.zigbee2mqtt.io)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 76 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

+1
View File
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

+108 -16
View File
@@ -1,23 +1,115 @@
const semver = require('semver');
const engines = require('./package.json').engines;
const indexJsRestart = 'indexjs.restart';
const fs = require('fs');
const path = require('path');
const {exec} = require('child_process');
const rimraf = require('rimraf');
require('source-map-support').install();
const version = engines.node;
if (!semver.satisfies(process.version, version)) {
console.log(`\t\tZigbee2mqtt requires node version ${version}, you are running ${process.version}!\n`); // eslint-disable-line
}
const Controller = require('./lib/controller');
const controller = new Controller();
controller.start();
process.on('SIGINT', handleQuit);
process.on('SIGTERM', handleQuit);
let controller;
let stopping = false;
function handleQuit() {
if (!stopping) {
stopping = true;
controller.stop(() => process.exit());
const hashFile = path.join(__dirname, 'dist', '.hash');
async function restart() {
await stop(indexJsRestart);
await start();
}
async function exit(code, reason) {
if (reason !== indexJsRestart) {
process.exit(code);
}
}
async function currentHash() {
const git = require('git-last-commit');
return new Promise((resolve) => {
git.getLastCommit((err, commit) => {
if (err) resolve('unknown');
else resolve(commit.shortHash);
});
});
}
async function writeHash() {
const hash = await currentHash();
fs.writeFileSync(hashFile, hash);
}
async function build(reason) {
return new Promise((resolve, reject) => {
process.stdout.write(`Building Zigbee2MQTT... (${reason})`);
rimraf.sync('dist');
exec('npm run build', {cwd: __dirname}, async (err, stdout, stderr) => {
if (err) {
process.stdout.write(', failed\n');
reject(err);
} else {
process.stdout.write(', finished\n');
resolve();
}
});
});
}
async function checkDist() {
if (!fs.existsSync(hashFile)) {
await build('initial build');
}
const distHash = fs.readFileSync(hashFile, 'utf-8');
const hash = await currentHash();
if (hash !== 'unknown' && distHash !== hash) {
await build('hash changed');
}
}
async function start() {
await checkDist();
const version = engines.node;
if (!semver.satisfies(process.version, version)) {
console.log(`\t\tZigbee2MQTT requires node version ${version}, you are running ${process.version}!\n`); // eslint-disable-line
}
// Validate settings
const settings = require('./dist/util/settings');
settings.reRead();
const errors = settings.validate();
if (errors.length > 0) {
console.log(`\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!`);
console.log(' READ THIS CAREFULLY\n');
console.log(`Refusing to start because configuration is not valid, found the following errors:`);
for (const error of errors) {
console.log(`- ${error}`);
}
console.log(`\nIf you don't know how to solve this, read https://www.zigbee2mqtt.io/information/configuration.html`); // eslint-disable-line
console.log(`\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n`);
exit(1);
}
const Controller = require('./dist/controller');
controller = new Controller(restart, exit);
await controller.start();
}
async function stop(reason=null) {
await controller.stop(reason);
}
async function handleQuit() {
if (!stopping && controller) {
stopping = true;
await stop();
}
}
if (process.argv.length === 3 && process.argv[2] === 'writehash') {
writeHash();
} else {
process.on('SIGINT', handleQuit);
process.on('SIGTERM', handleQuit);
start();
}
+339 -208
View File
@@ -1,102 +1,149 @@
const MQTT = require('./mqtt');
const Zigbee = require('./zigbee');
const EventBus = require('./eventBus');
const State = require('./state');
const logger = require('./util/logger');
const settings = require('./util/settings');
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
const objectAssignDeep = require('object-assign-deep');
const utils = require('./util/utils');
const stringify = require('json-stable-stringify-without-jsonify');
const assert = require('assert');
// Extensions
const ExtensionFrontend = require('./extension/frontend');
const ExtensionPublish = require('./extension/publish');
const ExtensionReceive = require('./extension/receive');
const ExtensionNetworkMap = require('./extension/networkMap');
const ExtensionSoftReset = require('./extension/softReset');
const ExtensionXiaomi = require('./extension/xiaomi');
const ExtensionDevicePublish = require('./extension/devicePublish');
const ExtensionSoftReset = require('./extension/legacy/softReset');
const ExtensionHomeAssistant = require('./extension/homeassistant');
const ExtensionDeviceConfigure = require('./extension/deviceConfigure');
const ExtensionDeviceGroupMembership = require('./extension/deviceGroupMembership');
const ExtensionDeviceReceive = require('./extension/deviceReceive');
const ExtensionBridgeConfig = require('./extension/bridgeConfig');
const ExtensionConfigure = require('./extension/configure');
const ExtensionDeviceGroupMembership = require('./extension/legacy/deviceGroupMembership');
const ExtensionBridgeLegacy = require('./extension/legacy/bridgeLegacy');
const ExtensionBridge = require('./extension/bridge');
const ExtensionGroups = require('./extension/groups');
const ExtensionDeviceAvailability = require('./extension/deviceAvailability');
const ExtensionDeviceBind = require('./extension/deviceBind');
const ExtensionDeviceReport = require('./extension/deviceReport');
const ExtensionLivolo = require('./extension/livolo');
const ExtensionResponder = require('./extension/responder');
const ExtensionAvailabilityLegacy = require('./extension/legacy/availability');
const ExtensionAvailability = require('./extension/availability');
const ExtensionBind = require('./extension/bind');
const ExtensionReport = require('./extension/legacy/report');
const ExtensionOnEvent = require('./extension/onEvent');
const ExtensionOTAUpdate = require('./extension/otaUpdate');
const ExtensionExternalConverters = require('./extension/externalConverters');
const ExtensionExternalExtension = require('./extension/externalExtension');
const AllExtensions = [
ExtensionPublish, ExtensionReceive, ExtensionNetworkMap, ExtensionSoftReset, ExtensionHomeAssistant,
ExtensionConfigure, ExtensionDeviceGroupMembership, ExtensionBridgeLegacy, ExtensionBridge, ExtensionGroups,
ExtensionAvailabilityLegacy, ExtensionBind, ExtensionReport, ExtensionOnEvent, ExtensionOTAUpdate,
ExtensionExternalConverters, ExtensionFrontend, ExtensionExternalExtension, ExtensionAvailability,
];
class Controller {
constructor() {
this.zigbee = new Zigbee();
this.mqtt = new MQTT();
this.state = new State();
constructor(restartCallback, exitCallback) {
// eslint-disable-next-line
this.eventBus = new EventBus.default();
// eslint-disable-next-line
this.zigbee = new Zigbee.default(this.eventBus);
// eslint-disable-next-line
this.mqtt = new MQTT.default(this.eventBus);
this.state = new State(this.eventBus);
this.restartCallback = restartCallback;
this.exitCallback = exitCallback;
// Bind methods
this.onMQTTConnected = this.onMQTTConnected.bind(this);
this.onZigbeeMessage = this.onZigbeeMessage.bind(this);
this.onMQTTMessage = this.onMQTTMessage.bind(this);
this.publishEntityState = this.publishEntityState.bind(this);
this.enableDisableExtension = this.enableDisableExtension.bind(this);
this.onZigbeeAdapterDisconnected = this.onZigbeeAdapterDisconnected.bind(this);
this.addExtension = this.addExtension.bind(this);
// Initialize extensions.
const args = [this.zigbee, this.mqtt, this.state, this.publishEntityState, this.eventBus,
this.enableDisableExtension, this.restartCallback, this.addExtension];
this.extensions = [
new ExtensionDeviceReceive(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionDeviceGroupMembership(this.zigbee, this.mqtt, this.publishEntityState),
new ExtensionDeviceConfigure(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionDevicePublish(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionNetworkMap(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionXiaomi(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionBridgeConfig(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionGroups(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionDeviceBind(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionResponder(this.zigbee, this.mqtt, this.state, this.publishEntityState),
new ExtensionBridge(...args),
new ExtensionPublish(...args),
new ExtensionReceive(...args),
new ExtensionDeviceGroupMembership(...args),
new ExtensionConfigure(...args),
new ExtensionNetworkMap(...args),
new ExtensionGroups(...args),
new ExtensionBind(...args),
new ExtensionOnEvent(...args),
new ExtensionOTAUpdate(...args),
new ExtensionReport(...args),
];
if (settings.get().advanced.report) {
this.extensions.push(new ExtensionDeviceReport(
this.zigbee, this.mqtt, this.state, this.publishEntityState
));
if (settings.get().frontend) {
this.extensions.push(new ExtensionFrontend(...args));
}
if (settings.get().advanced.legacy_api) {
this.extensions.push(new ExtensionBridgeLegacy(...args));
}
if (settings.get().external_converters.length) {
this.extensions.push(new ExtensionExternalConverters(...args));
}
if (settings.get().homeassistant) {
this.extensions.push(new ExtensionHomeAssistant(
this.zigbee, this.mqtt, this.state, this.publishEntityState
));
this.extensions.push(new ExtensionHomeAssistant(...args));
}
/* istanbul ignore next */
if (settings.get().advanced.soft_reset_timeout !== 0) {
this.extensions.push(new ExtensionSoftReset(
this.zigbee, this.mqtt, this.state, this.publishEntityState
));
this.extensions.push(new ExtensionSoftReset(...args));
}
if (settings.get().advanced.availability_timeout) {
this.extensions.push(new ExtensionDeviceAvailability(
this.zigbee, this.mqtt, this.state, this.publishEntityState
));
/* istanbul ignore else */
if (settings.get().experimental.availability_new) {
this.extensions.push(new ExtensionAvailability(...args));
} else {
if (settings.get().advanced.availability_timeout) {
this.extensions.push(new ExtensionAvailabilityLegacy(...args));
}
}
if (settings.get().experimental.livolo) {
// https://github.com/Koenkk/zigbee2mqtt/issues/592
this.extensions.push(new ExtensionLivolo(
this.zigbee, this.mqtt, this.state, this.publishEntityState
));
}
this.extensions.push(new ExtensionExternalExtension(...args));
}
onMQTTConnected() {
// Resend all cached states.
this.sendAllCachedStates();
async start() {
this.state.start();
logger.logOutput();
// Call extensions
this.extensions.filter((e) => e.onMQTTConnected).forEach((e) => e.onMQTTConnected());
}
const info = await utils.getZigbee2MQTTVersion();
logger.info(`Starting Zigbee2MQTT version ${info.version} (commit #${info.commitHash})`);
onZigbeeStarted() {
// Log zigbee clients on startup and configure.
const devices = this.zigbee.getAllClients();
// Start zigbee
let startResult;
try {
startResult = await this.zigbee.start();
this.callExtensionMethod('onZigbeeStarted', []);
this.eventBus.on('event', this.onZigbeeEvent.bind(this), this.constructor.name);
this.eventBus.onAdapterDisconnected(this, this.onZigbeeAdapterDisconnected);
} catch (error) {
logger.error('Failed to start zigbee');
// eslint-disable-next-line
logger.error('Check https://www.zigbee2mqtt.io/information/FAQ.html#help-zigbee2mqtt-fails-to-start for possible solutions');
logger.error('Exiting...');
logger.error(error.stack);
this.exitCallback(1);
}
// Disable some legacy options on new network creation
if (startResult === 'reset') {
settings.set(['advanced', 'homeassistant_legacy_entity_attributes'], false);
settings.set(['advanced', 'legacy_api'], false);
settings.set(['device_options', 'legacy'], false);
this.enableDisableExtension(false, 'BridgeLegacy');
}
// Log zigbee clients on startup
const devices = this.zigbee.getClientsLegacy();
logger.info(`Currently ${devices.length} devices are joined:`);
devices.forEach((device) => {
logger.info(this.getDeviceStartupLogMessage(device));
});
for (const device of devices) {
const entity = this.zigbee.resolveEntityLegacy(device);
const model = entity.definition ?
`${entity.definition.model} - ${entity.definition.vendor} ${entity.definition.description}` :
'Not supported';
logger.info(`${entity.name} (${entity.device.ieeeAddr}): ${model} (${entity.device.type})`);
}
// Enable zigbee join.
if (settings.get().permit_join) {
@@ -105,206 +152,290 @@ class Controller {
logger.warn('Set `permit_join` to `false` once you joined all devices.');
}
this.zigbee.permitJoin(settings.get().permit_join);
// Connect to MQTT broker
this.mqtt.connect(this.onMQTTMessage, this.onMQTTConnected);
// Call extensions
this.extensions.filter((e) => e.onZigbeeStarted).forEach((e) => e.onZigbeeStarted());
}
onZigbeeMessage(message) {
// Variables
let device = null;
let mappedDevice = null;
// Check if message has a device
if (message.endpoints && message.endpoints.length && message.endpoints[0].device) {
device = message.endpoints[0].device;
try {
await this.zigbee.permitJoinLegacy(settings.get().permit_join);
} catch (error) {
logger.error(`Failed to set permit join to ${settings.get().permit_join}`);
}
// Retrieve modelId from message
if (device && device.modelId) {
mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
}
// MQTT
this.onMQTTMessage = this.onMQTTMessage.bind(this);
this.eventBus.onMQTTMessage(this.constructor.name, this.onMQTTMessage);
await this.mqtt.connect();
// Log
logger.debug(
`Received zigbee message of type '${message.type}' with data '${JSON.stringify(message.data)}'` +
(device ? ` of device '${device.modelId}' (${device.ieeeAddr})` : '') +
(message.groupid ? ` with groupID ${message.groupid}` : '') +
(message.endpoints && message.endpoints.length ? ` of endpoint ${message.endpoints[0].epId}` : '')
);
// Call extensions.
this.extensions
.filter((e) => e.onZigbeeMessage)
.forEach((e) => e.onZigbeeMessage(message, device, mappedDevice));
}
onMQTTMessage(topic, message) {
logger.debug(`Received MQTT message on '${topic}' with data '${message}'`);
// Call extensions
const results = this.extensions
.filter((e) => e.onMQTTMessage)
.map((e) => e.onMQTTMessage(topic, message));
if (!results.includes(true)) {
logger.warn(`Cannot handle MQTT message on '${topic}' with data '${message}'`);
}
}
start() {
logger.info(`Logging to directory: '${logger.directory}'`);
logger.cleanup();
this.state.start();
this.startupLogVersion(() => {
this.zigbee.start(this.onZigbeeMessage, (error) => {
if (error) {
logger.error('Failed to start', error);
logger.error('Exiting...');
process.exit(1);
} else {
this.onZigbeeStarted();
// Send all cached states.
if (settings.get().advanced.cache_state_send_on_startup && settings.get().advanced.cache_state) {
for (const device of this.zigbee.getClientsLegacy()) {
if (this.state.exists(device.ieeeAddr)) {
this.publishEntityState(device.ieeeAddr, this.state.get(device.ieeeAddr));
}
});
});
}
}
// Add devices which are in database but not in configuration to configuration
for (const device of this.zigbee.getClientsLegacy()) {
if (!settings.getDevice(device.ieeeAddr)) {
settings.addDevice(device.ieeeAddr);
}
}
// Call extensions
await this.callExtensionMethod('onMQTTConnected', []);
await this.callExtensionMethod('start', []);
}
stop(callback) {
async enableDisableExtension(enable, name) {
if (!enable) {
const extension = this.extensions.find((e) => e.constructor.name === name);
if (extension) {
await this.callExtensionMethod('stop', [], [extension]);
this.extensions.splice(this.extensions.indexOf(extension), 1);
}
} else {
const Extension = AllExtensions.find((e) => e.name === name);
assert(Extension, `Extension '${name}' does not exist`);
const extension = new Extension(this.zigbee, this.mqtt, this.state, this.publishEntityState, this.eventBus,
this.enableDisableExtension, this.restartCallback, this.addExtension);
this.extensions.push(extension);
await this.callExtensionMethod('onZigbeeStarted', [], [extension]);
await this.callExtensionMethod('onMQTTConnected', [], [extension]);
await this.callExtensionMethod('start', [], [extension]);
}
}
async addExtension(extension) {
this.extensions.push(extension);
await this.callExtensionMethod('onZigbeeStarted', [], [extension]);
await this.callExtensionMethod('onMQTTConnected', [], [extension]);
await this.callExtensionMethod('start', [], [extension]);
}
async stop(reason=null) {
// Call extensions
this.extensions.filter((e) => e.stop).forEach((e) => e.stop());
await this.callExtensionMethod('stop', []);
this.eventBus.removeListeners(this.constructor.name);
// Wrap-up
this.state.stop();
await this.mqtt.disconnect();
this.mqtt.disconnect();
this.zigbee.stop(callback);
try {
await this.zigbee.stop();
logger.info('Stopped Zigbee2MQTT');
this.exitCallback(0, reason);
} catch (error) {
logger.error('Failed to stop Zigbee2MQTT');
this.exitCallback(1, reason);
}
}
startupLogVersion(callback) {
utils.getZigbee2mqttVersion((info) => {
logger.info(`Starting zigbee2mqtt version ${info.version} (commit #${info.commitHash})`);
callback();
});
async onZigbeeAdapterDisconnected() {
logger.error('Adapter disconnected, stopping');
await this.stop();
}
getDeviceStartupLogMessage(device) {
let friendlyName = 'unknown';
let type = 'unknown';
let friendlyDevice = {model: 'unkown', description: 'unknown'};
const mappedModel = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
if (mappedModel) {
friendlyDevice = mappedModel;
async onZigbeeEvent(type, data) {
const resolvedEntity = this.zigbee.resolveEntityLegacy(data.device || data.ieeeAddr);
if (data.device && data.device.type === 'Coordinator') {
logger.debug('Ignoring message from coordinator');
return;
}
if (settings.getDevice(device.ieeeAddr)) {
friendlyName = settings.getDevice(device.ieeeAddr).friendly_name;
if (data.device && !settings.getDevice(data.device.ieeeAddr)) {
// Only deviceLeave doesn't have a device (not interesting to add to settings)
resolvedEntity.settings = {...settings.get().device_options, ...settings.addDevice(data.device.ieeeAddr)};
}
if (device.type) {
type = utils.correctDeviceType(device);
}
const name = resolvedEntity && resolvedEntity.settings ? resolvedEntity.settings.friendlyName : null;
return `${friendlyName} (${device.ieeeAddr}): ${friendlyDevice.model} - ` +
`${friendlyDevice.vendor} ${friendlyDevice.description} (${type})`;
}
if (type === 'message') {
logger.debug(
`Received Zigbee message from '${name}', type '${data.type}', cluster '${data.cluster}'` +
`, data '${stringify(data.data)}' from endpoint ${data.endpoint.ID}` +
(data.hasOwnProperty('groupID') ? ` with groupID ${data.groupID}` : ``),
);
} else if (type === 'deviceJoined') {
logger.info(`Device '${name}' joined`);
} else if (type === 'deviceInterview') {
if (data.status === 'successful') {
logger.info(`Successfully interviewed '${name}', device has successfully been paired`);
sendAllCachedStates() {
this.zigbee.getAllClients().forEach((device) => {
if (this.state.exists(device.ieeeAddr)) {
this.publishEntityState(device.ieeeAddr, this.state.get(device.ieeeAddr));
if (resolvedEntity.definition) {
const {vendor, description, model} = resolvedEntity.definition;
logger.info(`Device '${name}' is supported, identified as: ${vendor} ${description} (${model})`);
} else {
logger.warn(
`Device '${name}' with Zigbee model '${data.device.modelID}' and manufacturer name ` +
`'${data.device.manufacturerName}' is NOT supported, ` +
`please follow https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html`,
);
}
} else if (data.status === 'failed') {
logger.error(`Failed to interview '${name}', device has not successfully been paired`);
} else {
/* istanbul ignore else */
if (data.status === 'started') {
logger.info(`Starting interview of '${name}'`);
}
}
});
} else if (type === 'deviceAnnounce') {
logger.debug(`Device '${name}' announced itself`);
} else if (type === 'deviceNetworkAddressChanged') {
logger.debug(`Device '${name}' changed network address`);
} else {
/* istanbul ignore else */
if (type === 'deviceLeave') {
const settingsDevice = settings.getDevice(data.ieeeAddr);
logger.warn(`Device '${settingsDevice ? settingsDevice.friendlyName : data.ieeeAddr}' ` +
`left the network`);
this.state.remove(data.ieeeAddr);
}
}
// Call extensions
await this.callExtensionMethod('onZigbeeEvent', [type, data, resolvedEntity]);
// In case this message is not handled by the receive extension and last_seen is enabled, publish
// a message to update the last_seen.
// TODO
// if (name && !result[ExtensionReceive.prototype.constructor.name] &&
// settings.get().advanced.last_seen !== 'disable' && type !== 'deviceLeave') {
// this.publishEntityState(name, {});
// }
}
publishEntityState(entityID, payload) {
const entity = settings.resolveEntity(entityID);
const appSettings = settings.get();
onMQTTMessage(payload) {
const {topic, message} = payload;
logger.debug(`Received MQTT message on '${topic}' with data '${message}'`);
// Call extensions
this.callExtensionMethod('onMQTTMessage', [topic, message]);
}
async publishEntityState(IDorName, payload, stateChangeReason=null) {
const resolvedEntity = this.zigbee.resolveEntityLegacy(IDorName);
if (!resolvedEntity || !resolvedEntity.settings) {
logger.error(`'${IDorName}' does not exist, skipping publish`);
return;
}
let messagePayload = {...payload};
const currentState = this.state.exists(entityID) ? this.state.get(entityID) : {};
const newState = objectAssignDeep.noMutate(currentState, payload);
// Update state cache with new state.
this.state.set(entityID, newState);
const newState = this.state.set(resolvedEntity.settings.ID, payload, stateChangeReason);
if (settings.get().advanced.cache_state) {
// Add cached state to payload
messagePayload = newState;
}
const entitySettings = entity.type === 'device' ? settings.getDevice(entityID) : settings.getGroup(entityID);
const options = {
retain: entitySettings ? entitySettings.retain : false,
qos: entitySettings && entitySettings.qos ? entitySettings.qos : 0,
retain: utils.getObjectProperty(resolvedEntity.settings, 'retain', false),
qos: utils.getObjectProperty(resolvedEntity.settings, 'qos', 0),
};
if (entity.type === 'device' && appSettings.mqtt.include_device_information) {
messagePayload.device = this.getDeviceInfoForMqtt(entityID);
const retention = utils.getObjectProperty(resolvedEntity.settings, 'retention', false);
if (retention !== false) {
options.properties = {messageExpiryInterval: retention};
}
const isDevice = resolvedEntity.type === 'device';
if (isDevice && settings.get().mqtt.include_device_information) {
const attributes = [
'ieeeAddr', 'networkAddress', 'type', 'manufacturerID', 'manufacturerName', 'powerSource',
'applicationVersion', 'stackVersion', 'zclVersion', 'hardwareVersion', 'dateCode', 'softwareBuildID',
];
messagePayload.device = {
friendlyName: resolvedEntity.name,
model: resolvedEntity.definition ? resolvedEntity.definition.model : 'unknown',
};
attributes.forEach((a) => messagePayload.device[a] = resolvedEntity.device[a]);
}
// Add lastseen
const lastSeen = settings.get().advanced.last_seen;
if (isDevice && lastSeen !== 'disable' && resolvedEntity.device.lastSeen) {
messagePayload.last_seen = utils.formatDate(resolvedEntity.device.lastSeen, lastSeen);
}
// Add device linkquality.
if (resolvedEntity.type === 'device' && resolvedEntity.device.linkquality !== undefined) {
messagePayload.linkquality = resolvedEntity.device.linkquality;
}
// filter mqtt message attributes
if (resolvedEntity.settings.filtered_attributes) {
resolvedEntity.settings.filtered_attributes.forEach((a) => delete messagePayload[a]);
}
for (const extension of this.extensions) {
if (extension.adjustMessagePayloadBeforePublish) {
extension.adjustMessagePayloadBeforePublish(resolvedEntity, messagePayload);
}
}
if (Object.entries(messagePayload).length) {
if (settings.get().experimental.output === 'json') {
this.mqtt.publish(entity.friendlyName, JSON.stringify(messagePayload), options);
} else if (settings.get().experimental.output === 'attribute') {
this.iteratePayloadForAttrOutput(entity.friendlyName+'/', messagePayload, options);
const output = settings.get().experimental.output;
if (output === 'attribute_and_json' || output === 'json') {
await this.mqtt.publish(resolvedEntity.name, stringify(messagePayload), options);
}
if (output === 'attribute_and_json' || output === 'attribute') {
await this.iteratePayloadAttributeOutput(`${resolvedEntity.name}/`, messagePayload, options);
}
}
this.eventBus.emit('publishEntityState', {messagePayload, entity: resolvedEntity, stateChangeReason, payload,
ieeeAddr: resolvedEntity.type === 'device' && resolvedEntity.device.ieeeAddr});
}
iteratePayloadForAttrOutput(topicRoot, payload, options) {
Object.keys(payload).forEach((key) => {
let subPayload = payload[key];
let message;
async iteratePayloadAttributeOutput(topicRoot, payload, options) {
for (const [key, value] of Object.entries(payload)) {
let subPayload = value;
let message = null;
// Special cases
if (key === 'color' &&
subPayload.r !== undefined &&
subPayload.g !== undefined &&
subPayload.b !== undefined) {
if (key === 'color' && utils.objectHasProperties(subPayload, ['r', 'g', 'b'])) {
subPayload = [subPayload.r, subPayload.g, subPayload.b];
}
// Check Array first, since it is also an Object
if (Array.isArray(subPayload)) {
if (subPayload === null || subPayload === undefined) {
message = '';
} else if (Array.isArray(subPayload)) {
message = subPayload.map((x) => `${x}`).join(',');
} else if (typeof subPayload === 'object') {
return this.iteratePayloadForAttrOutput(topicRoot+key+'-', subPayload, options);
this.iteratePayloadAttributeOutput(`${topicRoot}${key}-`, subPayload, options);
} else {
message = typeof subPayload === 'string' ? subPayload : JSON.stringify(subPayload);
message = typeof subPayload === 'string' ? subPayload : stringify(subPayload);
}
this.mqtt.publish(`${topicRoot}${key}`, message, options);
});
if (message !== null) {
await this.mqtt.publish(`${topicRoot}${key}`, message, options);
}
}
}
getDeviceInfoForMqtt(ieeeAddr) {
const device = this.zigbee.getDevice(ieeeAddr);
const {
type, nwkAddr, manufId, manufName, powerSource, modelId, hwVersion, swBuildId, status, dateCode,
} = device;
const deviceSettings = settings.getDevice(device.ieeeAddr);
return {
ieeeAddr,
friendlyName: deviceSettings ? (deviceSettings.friendly_name || '') : '',
type,
nwkAddr,
manufId,
manufName,
powerSource,
modelId,
hwVersion: hwVersion ? hwVersion : 'unknown',
swBuildId: swBuildId ? swBuildId : 'unknown',
dateCode: dateCode ? dateCode : 'unknown',
status,
};
async callExtensionMethod(method, parameters, extensions=null) {
const result = {};
for (const extension of extensions || this.extensions) {
if (extension[method]) {
try {
result[extension.constructor.name] = await extension[method](...parameters);
} catch (error) {
/* istanbul ignore next */
logger.error(`Failed to call '${extension.constructor.name}' '${method}' (${error.stack})`);
/* istanbul ignore next */
if (process.env.JEST_WORKER_ID !== undefined) {
throw error;
}
}
}
}
return result;
}
}
+139
View File
@@ -0,0 +1,139 @@
/* eslint-disable brace-style */
import events from 'events';
import * as ZHEvents from 'zigbee-herdsman/dist/controller/events';
import ExtensionTS from './extension/extensionts';
declare global {
interface EventDeviceRenamed { device: Device, homeAssisantRename: boolean, from: string, to: string }
// TODO: remove resolved entity, replace by Device
interface EventDeviceRemoved { resolvedEntity: ResolvedEntity}
type EventMQTTMessage = { topic: string, message: string };
type EventMQTTMessagePublished = { topic: string, payload: string, options: {retain: boolean, qos: number} };
type EventPermitJoinChanged = ZHEvents.PermitJoinChangedPayload;
type EventLastSeenChanged = { device: Device };
type EventDeviceNetworkAddressChanged = { device: Device };
type EventDeviceAnnounce = { device: Device };
type EventDeviceInterview = { device: Device, status: 'started' | 'successful' | 'failed' };
type EventDeviceJoined = { device: Device };
type EventReportingDisabled = { device: ZHDevice }; // TODO zhdevice -> device
type EventDeviceLeave = { ieeeAddr: string };
// TODO: remove resolved entity, replace by Group
type EventGroupMembersChanged = { group: ResolvedEntity }; // TODO fill
type EventPublishEntityState = {
// TODO: remove resolved entity, replace by Device | Group and remove ieeeAddr
messagePayload: KeyValue, entity: ResolvedEntity, stateChangeReason: 'publishDebounce', payload: KeyValue,
ieeeAddr: string,
};
type EventDeviceMessage = {
type: ZHEvents.MessagePayloadType;
device: Device;
endpoint: ZHEndpoint;
linkquality: number;
groupID: number;
cluster: string | number;
data: KeyValue | Array<string | number>;
meta: {
zclTransactionSequenceNumber?: number;
};
};
}
type ListenerKey = string | ExtensionTS;
export default class EventBus {
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
private callbacksByExtension: { [s: string]: { event: string, callback: (...args: any[]) => void }[] } = {};
private emitter = new events.EventEmitter();
public emitAdapterDisconnected(): void {this.emitter.emit('adapterDisconnected');}
public onAdapterDisconnected(key: ListenerKey, callback: () => void): void {
this.on('adapterDisconnected', callback, key);}
public emitPermitJoinChanged(data: EventPermitJoinChanged): void {this.emitter.emit('permitJoinChanged', data);}
public onPermitJoinChanged(key: ListenerKey, callback: (data: EventPermitJoinChanged) => void): void {
this.on('permitJoinChanged', callback, key);}
// public emitDeviceRenamed(data: EventDeviceRenamed): void {this.emitter.emit('deviceRenamed', data);}
public onDeviceRenamed(key: ListenerKey, callback: (data: EventDeviceRenamed) => void): void {
this.on('deviceRenamed', callback, key);}
// public emitDeviceRemoved(data: EventDeviceRemoved): void {this.emitter.emit('deviceRemoved', data);}
public onDeviceRemoved(key: ListenerKey, callback: (data: EventDeviceRemoved) => void): void {
this.on('deviceRemoved', callback, key);}
public emitLastSeenChanged(data: EventLastSeenChanged): void {this.emitter.emit('lastSeenChanged', data);}
public onLastSeenChanged(key: ListenerKey, callback: (data: EventLastSeenChanged) => void): void {
this.on('lastSeenChanged', callback, key);}
public emitDeviceNetworkAddressChanged(data: EventDeviceNetworkAddressChanged): void {
this.emitter.emit('deviceNetworkAddressChanged', data);}
public onDeviceNetworkAddressChanged(
key: ListenerKey, callback: (data: EventDeviceNetworkAddressChanged) => void): void {
this.on('deviceNetworkAddressChanged', callback, key);}
public emitDeviceAnnounce(data: EventDeviceAnnounce): void {this.emitter.emit('deviceAnnounce', data);}
public onDeviceAnnounce(key: ListenerKey, callback: (data: EventDeviceAnnounce) => void): void {
this.on('deviceAnnounce', callback, key);}
public emitDeviceInterview(data: EventDeviceInterview): void {this.emitter.emit('deviceInterview', data);}
public onDeviceInterview(key: ListenerKey, callback: (data: EventDeviceInterview) => void): void {
this.on('deviceInterview', callback, key);}
public emitDeviceJoined(data: EventDeviceJoined): void {this.emitter.emit('deviceJoined', data);}
public onDeviceJoined(key: ListenerKey, callback: (data: EventDeviceJoined) => void): void {
this.on('deviceJoined', callback, key);}
public emitDeviceLeave(data: EventDeviceLeave): void {this.emitter.emit('deviceLeave', data);}
public onDeviceLeave(key: ListenerKey, callback: (data: EventDeviceLeave) => void): void {
this.on('deviceLeave', callback, key);}
public emitDeviceMessage(data: EventDeviceMessage): void {this.emitter.emit('deviceMessage', data);}
public onDeviceMessage(key: ListenerKey, callback: (data: EventDeviceMessage) => void): void {
this.on('deviceMessage', callback, key);}
public emitMQTTMessage(data: EventMQTTMessage): void {this.emitter.emit('mqttMessage', data);}
public onMQTTMessage(key: ListenerKey, callback: (data: EventMQTTMessage) => void): void {
this.on('mqttMessage', callback, key);}
public emitMQTTMessagePublished(data: EventMQTTMessagePublished): void {
this.emitter.emit('mqttMessagePublished', data);}
public onMQTTMessagePublished(key: ListenerKey, callback: (data: EventMQTTMessagePublished) => void): void {
this.on('mqttMessagePublished', callback, key);}
// public emitPublishEntityState(data: EventPublishEntityState): void {
// this.emitter.emit('publishEntityState', data);}
public onPublishEntityState(key: ListenerKey, callback: (data: EventPublishEntityState) => void): void {
this.on('publishEntityState', callback, key);}
// public emitGroupMembersChanged(data: EventGroupMembersChanged): void {
// this.emitter.emit('groupMembersChanged', data);}
public onGroupMembersChanged(key: ListenerKey, callback: (data: EventGroupMembersChanged) => void): void {
this.on('groupMembersChanged', callback, key);}
public emitDevicesChanged(): void {this.emitter.emit('devicesChanged');}
public onDevicesChanged(key: ListenerKey, callback: () => void): void {this.on('devicesChanged', callback, key);}
// public emitReportingDisabled(data: EventReportingDisabled): void {
// this.emitter.emit('reportingDisabled', data);}
public onReportingDisabled(key: ListenerKey, callback: (data: EventReportingDisabled) => void): void {
this.on('reportingDisabled', callback, key);}
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
private on(event: string, callback: (...args: any[]) => void, key: ListenerKey): void {
key = typeof key === 'string' ? key : key.constructor.name;
if (!this.callbacksByExtension[key]) this.callbacksByExtension[key] = [];
this.callbacksByExtension[key].push({event, callback});
this.emitter.on(event, callback);
}
// TODO: remove
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
emit(event: string, ...args: any[]): void {
this.emitter.emit(event, ...args);
}
public removeListeners(key: ListenerKey): void {
key = typeof key === 'string' ? key : key.constructor.name;
this.callbacksByExtension[key]?.forEach((e) => this.emitter.removeListener(e.event, e.callback));
}
}
+194
View File
@@ -0,0 +1,194 @@
import ExtensionTS from './extensionts';
import logger from '../util/logger';
import {sleep, hours, minutes, seconds, isAvailabilityEnabledForDevice} from '../util/utils';
import * as settings from '../util/settings';
import debounce from 'debounce';
import bind from 'bind-decorator';
// TODO
// - Enable for HA addon
// - Add to setting schema (when old availability is removed)
export default class Availability extends ExtensionTS {
private timers: {[s: string]: NodeJS.Timeout} = {};
private availabilityCache: {[s: string]: boolean} = {};
private retrieveStateDebouncers: {[s: string]: () => void} = {};
private pingQueue: Device[] = [];
private pingQueueExecuting = false;
private getTimeout(device: Device): number {
if (typeof device.settings.availability === 'object' && device.settings.availability?.timeout != null) {
return minutes(device.settings.availability.timeout);
}
const key = this.isActiveDevice(device) ? 'active' : 'passive';
const availabilitySettings = settings.get().availability;
if (typeof availabilitySettings === 'object' && availabilitySettings[key]?.timeout != null) {
return minutes(availabilitySettings[key]?.timeout);
}
return key === 'active' ? minutes(10) : hours(25);
}
private isActiveDevice(device: Device): boolean {
return (device.type === 'Router' && device.powerSource !== 'Battery') ||
device.powerSource === 'Mains (single phase)';
}
private isAvailable(device: Device): boolean {
const ago = Date.now() - device.lastSeen;
return ago < this.getTimeout(device);
}
private resetTimer(device: Device): void {
clearTimeout(this.timers[device.ieeeAddr]);
// If the timer triggers, the device is not avaiable anymore otherwise resetTimer already have been called
if (this.isActiveDevice(device)) {
// If device did not check in, ping it, if that fails it will be marked as offline
this.timers[device.ieeeAddr] = setTimeout(
() => this.addToPingQueue(device), this.getTimeout(device) + seconds(1));
} else {
this.timers[device.ieeeAddr] = setTimeout(
() => this.publishAvailability(device, true), this.getTimeout(device) + seconds(1));
}
}
private addToPingQueue(device: Device): void {
this.pingQueue.push(device);
this.pingQueueExecuteNext();
}
private removeFromPingQueue(device: Device): void {
const index = this.pingQueue.findIndex((d) => d.ieeeAddr === device.ieeeAddr);
index != -1 && this.pingQueue.splice(index, 1);
}
private async pingQueueExecuteNext(): Promise<void> {
if (this.pingQueue.length === 0 || this.pingQueueExecuting) return;
this.pingQueueExecuting = true;
const device = this.pingQueue[0];
let pingedSuccessfully = false;
const available = this.availabilityCache[device.ieeeAddr] || this.isAvailable(device);
const attempts = available ? 2 : 1;
for (let i = 0; i < attempts; i++) {
try {
// Enable recovery if device is marked as available and first ping fails.
const disableRecovery = !(i == 1 && available);
await device.ping(disableRecovery);
pingedSuccessfully = true;
logger.debug(`Succesfully pinged '${device.name}' (attempt ${i + 1}/${attempts})`);
break;
} catch (error) {
logger.error(`Failed to ping '${device.name}' (attempt ${i + 1}/${attempts}, ${error.message})`);
// Try again in 3 seconds.
const lastAttempt = i - 1 === attempts;
!lastAttempt && await sleep(3);
}
}
this.publishAvailability(device, !pingedSuccessfully);
this.resetTimer(device);
this.removeFromPingQueue(device);
// Sleep 2 seconds before executing next ping
await sleep(2);
this.pingQueueExecuting = false;
this.pingQueueExecuteNext();
}
override async start(): Promise<void> {
logger.warn('Using experimental new availability feature');
this.eventBus.onDeviceRenamed(this, (data: EventDeviceRenamed) =>
this.publishAvailability(data.device, false, true));
this.eventBus.onDeviceLeave(this, (data: EventDeviceLeave) => clearTimeout(this.timers[data.ieeeAddr]));
this.eventBus.onDeviceAnnounce(this, (data: EventDeviceAnnounce) => this.retrieveState(data.device));
this.eventBus.onLastSeenChanged(this, this.onLastSeenChanged);
for (const device of this.zigbee.getClients()) {
if (isAvailabilityEnabledForDevice(device, settings.get())) {
// Publish initial availablility
this.publishAvailability(device, true);
this.resetTimer(device);
// If an active device is initially unavailable, ping it.
if (this.isActiveDevice(device) && !this.isAvailable(device)) {
this.addToPingQueue(device);
}
}
}
}
private publishAvailability(device: Device, logLastSeen: boolean, forcePublish=false): void {
if (logLastSeen) {
const ago = Date.now() - device.lastSeen;
if (this.isActiveDevice(device)) {
logger.debug(
`Active device '${device.name}' was last seen '${(ago / minutes(1)).toFixed(2)}' minutes ago.`);
} else {
logger.debug(
`Passive device '${device.name}' was last seen '${(ago / hours(1)).toFixed(2)}' hours ago.`);
}
}
const available = this.isAvailable(device);
if (!forcePublish && this.availabilityCache[device.ieeeAddr] == available) {
return;
}
if (device.ieeeAddr in this.availabilityCache && available &&
this.availabilityCache[device.ieeeAddr] === false) {
logger.debug(`Device '${device.name}' reconnected`);
this.retrieveState(device);
}
const topic = `${device.name}/availability`;
const payload = available ? 'online' : 'offline';
this.availabilityCache[device.ieeeAddr] = available;
this.mqtt.publish(topic, payload, {retain: true, qos: 0});
}
@bind private onLastSeenChanged(data: EventLastSeenChanged): void {
if (isAvailabilityEnabledForDevice(data.device, settings.get())) {
// Remove from ping queue, not necessary anymore since we know the device is online.
this.removeFromPingQueue(data.device);
this.resetTimer(data.device);
this.publishAvailability(data.device, false);
}
}
override async stop(): Promise<void> {
super.stop();
Object.values(this.timers).forEach((t) => clearTimeout(t));
}
private retrieveState(device: Device): void {
/**
* Retrieve state of a device in a debounced manner, this function is called on a 'deviceAnnounce' which a
* device can send multiple times after each other.
*/
if (device.definition && !device.interviewing && !this.retrieveStateDebouncers[device.ieeeAddr]) {
this.retrieveStateDebouncers[device.ieeeAddr] = debounce(async () => {
try {
logger.debug(`Retrieving state of '${device.name}' after reconnect`);
// Color and color temperature converters do both, only needs to be called once.
const keySet = [['state'], ['brightness'], ['color', 'color_temp']];
for (const keys of keySet) {
const converter = device.definition.toZigbee.find((c) => c.key.find((k) => keys.includes(k)));
await converter?.convertGet?.(device.endpoint(), keys[0],
{message: this.state.get(device.ieeeAddr) || {}, mapped: device.definition});
}
} catch (error) {
logger.error(`Failed to read state of '${device.name}' after reconnect (${error.message})`);
}
}, seconds(2));
}
this.retrieveStateDebouncers[device.ieeeAddr]?.();
}
}
// TODO_finished: : change class to export default
module.exports = Availability;
+466
View File
@@ -0,0 +1,466 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const utils = require('../util/utils');
const legacyTopicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/(bind|unbind)/.+$`);
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/request/device/(bind|unbind)`);
const Extension = require('./extension');
const stringify = require('json-stable-stringify-without-jsonify');
const debounce = require('debounce');
const zigbeeHersdman = require('zigbee-herdsman');
const clusterCandidates = ['genScenes', 'genOnOff', 'genLevelCtrl', 'lightingColorCtrl', 'closuresWindowCovering',
'hvacThermostat', 'msTemperatureMeasurement'];
// See zigbee-herdsman-converters
const defaultBindGroup = {type: 'group_number', ID: 901};
const defaultReportConfiguration = {
minimumReportInterval: 5, maximumReportInterval: 3600, reportableChange: 1,
};
const getColorCapabilities = async (endpoint) => {
if (endpoint.getClusterAttributeValue('lightingColorCtrl', 'colorCapabilities') == null) {
await endpoint.read('lightingColorCtrl', ['colorCapabilities']);
}
const value = endpoint.getClusterAttributeValue('lightingColorCtrl', 'colorCapabilities');
return {
colorTemperature: (value & 1<<4) > 0,
colorXY: (value & 1<<3) > 0,
};
};
const reportClusters = {
'genOnOff': [
{attribute: 'onOff', ...defaultReportConfiguration, minimumReportInterval: 0, reportableChange: 0},
],
'genLevelCtrl': [
{attribute: 'currentLevel', ...defaultReportConfiguration},
],
'lightingColorCtrl': [
{
attribute: 'colorTemperature', ...defaultReportConfiguration,
condition: async (endpoint) => (await getColorCapabilities(endpoint)).colorTemperature,
},
{
attribute: 'currentX', ...defaultReportConfiguration,
condition: async (endpoint) => (await getColorCapabilities(endpoint)).colorXY,
},
{
attribute: 'currentY', ...defaultReportConfiguration,
condition: async (endpoint) => (await getColorCapabilities(endpoint)).colorXY,
},
],
'closuresWindowCovering': [
{attribute: 'currentPositionLiftPercentage', ...defaultReportConfiguration},
{attribute: 'currentPositionTiltPercentage', ...defaultReportConfiguration},
],
};
const pollOnMessage = [
{
// On messages that have the cluster and type of below
cluster: {
manuSpecificPhilips: [
{type: 'commandHueNotification', data: {button: 2}},
{type: 'commandHueNotification', data: {button: 3}},
],
genLevelCtrl: [
{type: 'commandStep', data: {}},
{type: 'commandStepWithOnOff', data: {}},
{type: 'commandStop', data: {}},
{type: 'commandMoveWithOnOff', data: {}},
{type: 'commandStopWithOnOff', data: {}},
{type: 'commandMove', data: {}},
{type: 'commandMoveToLevelWithOnOff', data: {}},
],
genScenes: [
{type: 'commandRecall', data: {}},
],
},
// Read the following attributes
read: {cluster: 'genLevelCtrl', attributes: ['currentLevel']},
// When the bound devices/members of group have the following manufacturerIDs
manufacturerIDs: [
zigbeeHersdman.Zcl.ManufacturerCode.Philips,
zigbeeHersdman.Zcl.ManufacturerCode.ATMEL,
zigbeeHersdman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHersdman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
],
},
{
cluster: {
genLevelCtrl: [
{type: 'commandStepWithOnOff', data: {}},
{type: 'commandMoveWithOnOff', data: {}},
{type: 'commandStopWithOnOff', data: {}},
{type: 'commandMoveToLevelWithOnOff', data: {}},
],
genOnOff: [
{type: 'commandOn', data: {}},
{type: 'commandOff', data: {}},
{type: 'commandOffWithEffect', data: {}},
{type: 'commandToggle', data: {}},
],
genScenes: [
{type: 'commandRecall', data: {}},
],
manuSpecificPhilips: [
{type: 'commandHueNotification', data: {button: 1}},
{type: 'commandHueNotification', data: {button: 4}},
],
},
read: {cluster: 'genOnOff', attributes: ['onOff']},
manufacturerIDs: [
zigbeeHersdman.Zcl.ManufacturerCode.Philips,
zigbeeHersdman.Zcl.ManufacturerCode.ATMEL,
zigbeeHersdman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHersdman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
],
},
{
cluster: {
genScenes: [
{type: 'commandRecall', data: {}},
],
},
read: {
cluster: 'lightingColorCtrl',
attributes: [],
// Since not all devices support the same attributes they need to be calculated dynamically
// depending on the capabilities of the endpoint.
attributesForEndpoint: async (endpoint) => {
const supportedAttrs = await getColorCapabilities(endpoint);
const readAttrs = [];
supportedAttrs.colorXY && readAttrs.push('currentX', 'currentY');
supportedAttrs.colorTemperature && readAttrs.push('colorTemperature');
return readAttrs;
},
},
manufacturerIDs: [
zigbeeHersdman.Zcl.ManufacturerCode.Philips,
zigbeeHersdman.Zcl.ManufacturerCode.ATMEL,
zigbeeHersdman.Zcl.ManufacturerCode.GLEDOPTO_CO_LTD,
zigbeeHersdman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
],
},
];
class Bind extends Extension {
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
super(zigbee, mqtt, state, publishEntityState, eventBus);
this.legacyApi = settings.get().advanced.legacy_api;
this.eventBus.on(`groupMembersChanged`, (d) => this.groupMembersChanged(d), this.constructor.name);
this.pollDebouncers = {};
}
parseMQTTMessage(topic, message) {
let type = null;
let sourceKey = null;
let targetKey = null;
let clusters = null;
let skipDisableReporting = false;
if (this.legacyApi && topic.match(legacyTopicRegex)) {
topic = topic.replace(`${settings.get().mqtt.base_topic}/bridge/`, '');
type = topic.split('/')[0];
sourceKey = topic.replace(`${type}/`, '');
targetKey = message;
} else if (topic.match(topicRegex)) {
type = topic.endsWith('unbind') ? 'unbind' : 'bind';
message = JSON.parse(message);
sourceKey = message.from;
targetKey = message.to;
clusters = message.clusters;
skipDisableReporting = 'skip_disable_reporting' in message ? message.skip_disable_reporting : false;
}
return {type, sourceKey, targetKey, clusters, skipDisableReporting};
}
async onMQTTMessage(topic, message) {
const {type, sourceKey, targetKey, clusters, skipDisableReporting} = this.parseMQTTMessage(topic, message);
if (!type) return null;
message = utils.parseJSON(message, message);
let error = null;
const source = this.zigbee.resolveEntityLegacy(sourceKey);
const target = targetKey === 'default_bind_group' ?
defaultBindGroup : this.zigbee.resolveEntityLegacy(targetKey);
const responseData = {from: sourceKey, to: targetKey};
if (!source || source.type !== 'device') {
error = `Source device '${sourceKey}' does not exist`;
} else if (!target) {
error = `Target device or group '${targetKey}' does not exist`;
} else {
const sourceName = source.settings.friendlyName;
const targetName = targetKey === 'default_bind_group' ? targetKey : target.settings.friendlyName;
const successfulClusters = [];
const failedClusters = [];
const attemptedClusters = [];
let bindTarget = null;
if (target.type === 'group') bindTarget = target.group;
else if (target.type === 'group_number') bindTarget = target.ID;
else bindTarget = target.endpoint;
// Find which clusters are supported by both the source and target.
// Groups are assumed to support all clusters.
for (const cluster of clusterCandidates) {
if (clusters && !clusters.includes(cluster)) continue;
let matchingClusters = false;
const anyClusterValid = target.type === 'group' || target.type === 'group_number' ||
target.device.type === 'Coordinator';
if (!anyClusterValid) {
matchingClusters = ((target.endpoint.supportsInputCluster(cluster) &&
source.endpoint.supportsOutputCluster(cluster)) ||
(source.endpoint.supportsInputCluster(cluster) &&
target.endpoint.supportsOutputCluster(cluster)) );
}
const sourceValid = source.endpoint.supportsInputCluster(cluster) ||
source.endpoint.supportsOutputCluster(cluster);
if ( sourceValid && (anyClusterValid || matchingClusters)) {
logger.debug(`${type}ing cluster '${cluster}' from '${sourceName}' to '${targetName}'`);
attemptedClusters.push(cluster);
try {
if (type === 'bind') {
await source.endpoint.bind(cluster, bindTarget);
} else {
await source.endpoint.unbind(cluster, bindTarget);
}
successfulClusters.push(cluster);
logger.info(
`Successfully ${type === 'bind' ? 'bound' : 'unbound'} cluster '${cluster}' from ` +
`'${sourceName}' to '${targetName}'`,
);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
this.mqtt.publish(
'bridge/log',
stringify({type: `device_${type}`,
message: {from: sourceName, to: targetName, cluster}}),
);
}
} catch (error) {
failedClusters.push(cluster);
logger.error(
`Failed to ${type} cluster '${cluster}' from '${sourceName}' to ` +
`'${targetName}' (${error})`,
);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
this.mqtt.publish(
'bridge/log',
stringify({type: `device_${type}_failed`,
message: {from: sourceName, to: targetName, cluster}}),
);
}
}
}
}
if (attemptedClusters.length === 0) {
logger.error(`Nothing to ${type} from '${sourceName}' to '${targetName}'`);
error = `Nothing to ${type}`;
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
this.mqtt.publish(
'bridge/log',
stringify({type: `device_${type}_failed`, message: {from: sourceName, to: targetName}}),
);
}
} else if (failedClusters.length === attemptedClusters.length) {
error = `Failed to ${type}`;
}
responseData[`clusters`] = successfulClusters;
responseData[`failed`] = failedClusters;
if (successfulClusters.length !== 0) {
if (type === 'bind') {
await this.setupReporting(source.endpoint.binds.filter((b) =>
successfulClusters.includes(b.cluster.name) && b.target === bindTarget));
} else if ((target.type !== 'group_number') && !skipDisableReporting) {
await this.disableUnnecessaryReportings(bindTarget);
}
}
}
const triggeredViaLegacyApi = topic.match(legacyTopicRegex);
if (!triggeredViaLegacyApi) {
const response = utils.getResponse(message, responseData, error);
await this.mqtt.publish(`bridge/response/device/${type}`, stringify(response));
}
if (error) {
logger.error(error);
} else {
this.eventBus.emit(`devicesChanged`);
}
}
async groupMembersChanged(data) {
if (data.action === 'add') {
const bindsToGroup = this.zigbee.getClientsLegacy().map((c) => c.endpoints)
.reduce((a, v) => a.concat(v)).map((e) => e.binds)
.reduce((a, v) => a.concat(v)).filter((b) => b.target === data.group.group);
await this.setupReporting(bindsToGroup);
} else { // action === remove/remove_all
if (!data.skipDisableReporting) {
await this.disableUnnecessaryReportings(data.endpoint);
}
}
}
getSetupReportingEndpoints(bind, coordinatorEp) {
const endpoints = bind.target.constructor.name === 'Group' ? bind.target.members : [bind.target];
return endpoints.filter((e) => {
const supportsInputCluster = e.supportsInputCluster(bind.cluster.name);
const hasConfiguredReporting = !!e.configuredReportings.find((c) => c.cluster.name === bind.cluster.name);
const hasBind = !!e.binds.find((b) => b.cluster.name === bind.cluster.name && b.target === coordinatorEp);
return supportsInputCluster && !(hasBind && hasConfiguredReporting);
});
}
async setupReporting(binds) {
const coordinator = this.zigbee.getDevicesByTypeLegacy('Coordinator')[0];
const coordinatorEndpoint = coordinator.getEndpoint(1);
for (const bind of binds.filter((b) => b.cluster.name in reportClusters)) {
for (const endpoint of this.getSetupReportingEndpoints(bind, coordinatorEndpoint)) {
const entity = `${this.zigbee.resolveEntityLegacy(endpoint.getDevice()).name}/${endpoint.ID}`;
try {
await endpoint.bind(bind.cluster.name, coordinatorEndpoint);
const items = await reportClusters[bind.cluster.name]
.filter(async (a) => !a.condition || await a.condition(endpoint))
.map((a) => {
const result = {...a};
delete result.condition;
return result;
});
await endpoint.configureReporting(bind.cluster.name, items);
logger.info(`Succesfully setup reporting for '${entity}' cluster '${bind.cluster.name}'`);
} catch (error) {
logger.warn(`Failed to setup reporting for '${entity}' cluster '${bind.cluster.name}'`);
}
}
}
this.eventBus.emit(`devicesChanged`);
}
async disableUnnecessaryReportings(target) {
const coordinator = this.zigbee.getDevicesByTypeLegacy('Coordinator')[0];
const coordinatorEndpoint = coordinator.getEndpoint(1);
const endpoints = target.constructor.name === 'Group' ? target.members : [target];
for (const endpoint of endpoints) {
const entity = `${this.zigbee.resolveEntityLegacy(endpoint.getDevice()).name}/${endpoint.ID}`;
const boundClusters = endpoint.binds.filter((b) => b.target === coordinatorEndpoint)
.map((b) => b.cluster.name);
const requiredClusters = this.zigbee.getClientsLegacy().map((c) => c.endpoints)
.reduce((a, v) => a.concat(v))
.map((e) => e.binds).reduce((a, v) => a.concat(v)).filter((bind) => {
if (bind.target.constructor.name === 'Group') {
return bind.target.members.includes(endpoint);
} else {
return bind.target === endpoint;
}
}).map((b) => b.cluster.name).filter((v, i, a) => a.indexOf(v) === i);
for (const cluster of boundClusters.filter((c) => !requiredClusters.includes(c) && c in reportClusters)) {
try {
await endpoint.unbind(cluster, coordinatorEndpoint);
const items = await reportClusters[cluster]
.filter(async (a) => !a.condition || await a.condition(endpoint))
.map((a) => {
const result = {...a, maximumReportInterval: 0xFFFF};
delete result.condition;
return result;
});
await endpoint.configureReporting(cluster, items);
logger.info(`Succesfully disabled reporting for '${entity}' cluster '${cluster}'`);
} catch (error) {
logger.warn(`Failed to disable reporting for '${entity}' cluster '${cluster}'`);
}
}
this.eventBus.emit('reportingDisabled', {device: endpoint.getDevice()});
}
}
async onZigbeeEvent(type, data, resolvedEntity) {
if (type === 'message') {
this.poll(data);
}
}
async poll(message) {
/**
* This method poll bound endpoints and group members for state changes.
*
* A use case is e.g. a Hue Dimmer switch bound to a Hue bulb.
* Hue bulbs only report their on/off state.
* When dimming the bulb via the dimmer switch the state is therefore not reported.
* When we receive a message from a Hue dimmer we read the brightness from the bulb (if bound).
*/
const polls = pollOnMessage.filter((p) =>
p.cluster[message.cluster] && p.cluster[message.cluster].find((c) => c.type === message.type &&
utils.equalsPartial(message.data, c.data)),
);
if (polls.length) {
let toPoll = [];
// Add bound devices
toPoll = toPoll.concat([].concat(...message.device.endpoints.map((e) =>
e.binds.map((e) => e).filter((e) => e.target))));
toPoll = toPoll.filter((e) => e.target.constructor.name === 'Endpoint');
toPoll = toPoll.filter((e) => e.target.getDevice().type !== 'Coordinator');
toPoll = toPoll.map((e) => e.target);
// If message is published to a group, add members of the group
const group = message.groupID !== 0 ? this.zigbee.getGroupByIDLegacy(message.groupID) : null;
if (group) {
toPoll = toPoll.concat(group.members);
}
toPoll = new Set(toPoll);
for (const endpoint of toPoll) {
for (const poll of polls) {
if (!poll.manufacturerIDs.includes(endpoint.getDevice().manufacturerID) ||
!endpoint.supportsInputCluster(poll.read.cluster)) {
continue;
}
let readAttrs = poll.read.attributes;
if (poll.read.attributesForEndpoint) {
const attrsForEndpoint = await poll.read.attributesForEndpoint(endpoint);
readAttrs = [...poll.read.attributes, ...attrsForEndpoint];
}
const key = `${endpoint.deviceIeeeAddress}_${endpoint.ID}_${pollOnMessage.indexOf(poll)}`;
if (!this.pollDebouncers[key]) {
this.pollDebouncers[key] = debounce(async () => {
await endpoint.read(poll.read.cluster, readAttrs);
}, 1000);
}
this.pollDebouncers[key]();
}
}
}
}
}
module.exports = Bind;
+671
View File
@@ -0,0 +1,671 @@
/* eslint-disable camelcase */
import logger from '../util/logger';
import * as utils from '../util/utils';
import * as settings from '../util/settings';
import Transport from 'winston-transport';
import bind from 'bind-decorator';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
import objectAssignDeep from 'object-assign-deep';
import {detailedDiff} from 'deep-object-diff';
import ExtensionTS from './extensionts';
import Device from '../model/device';
import Group from '../model/group';
const requestRegex = new RegExp(`${settings.get().mqtt.base_topic}/bridge/request/(.*)`);
class Bridge extends ExtensionTS {
private zigbee2mqttVersion: {commitHash: string, version: string};
private coordinatorVersion: CoordinatorVersion;
private restartRequired = false;
private lastJoinedDeviceIeeeAddr: string;
private requestLookup: {[key: string]: (message: KeyValue | string) => Promise<MQTTResponse>};
override async start(): Promise<void> {
this.requestLookup = {
'device/options': this.deviceOptions,
'device/configure_reporting': this.deviceConfigureReporting,
'device/remove': this.deviceRemove,
'device/rename': this.deviceRename,
'group/add': this.groupAdd,
'group/options': this.groupOptions,
'group/remove': this.groupRemove,
'group/rename': this.groupRename,
'permit_join': this.permitJoin,
'restart': this.restart,
'touchlink/factory_reset': this.touchlinkFactoryReset,
'touchlink/identify': this.touchlinkIdentify,
'touchlink/scan': this.touchlinkScan,
'health_check': this.healthCheck,
'options': this.bridgeOptions,
// Below are deprecated
'config/last_seen': this.configLastSeen,
'config/homeassistant': this.configHomeAssistant,
'config/elapsed': this.configElapsed,
'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();
}
}
// @ts-ignore TODO fix typing
logger.addTransport(new EventTransport());
this.zigbee2mqttVersion = await utils.getZigbee2MQTTVersion();
this.coordinatorVersion = await this.zigbee.getCoordinatorVersion();
this.eventBus.onDeviceRenamed(this, () => this.publishInfo());
this.eventBus.onGroupMembersChanged(this, () => this.publishGroups());
this.eventBus.onDevicesChanged(this, () => this.publishDevices() && this.publishInfo());
this.eventBus.onPermitJoinChanged(this, () => !this.zigbee.isStopping() && this.publishInfo());
// Zigbee events
const publishEvent = (type: string, data: KeyValue): Promise<void> =>
this.mqtt.publish('bridge/event', stringify({type, data}), {retain: false, qos: 0});
this.eventBus.onDeviceJoined(this, (data) => {
this.lastJoinedDeviceIeeeAddr = data.device.ieeeAddr;
this.publishDevices();
publishEvent('device_joined', {friendly_name: data.device.name, ieee_address: data.device.ieeeAddr});
});
this.eventBus.onDeviceLeave(this, (data) => {
this.publishDevices();
publishEvent('device_leave',
{ieee_address: data.ieeeAddr, friendly_name: settings.getDevice(data.ieeeAddr)?.friendlyName});
});
this.eventBus.onDeviceNetworkAddressChanged(this, () => this.publishDevices());
this.eventBus.onDeviceInterview(this, (data) => {
this.publishDevices();
const payload: KeyValue =
{friendly_name: data.device.name, status: data.status, ieee_address: data.device.ieeeAddr};
if (data.status === 'successful') {
payload.supported = !!data.device.definition;
payload.definition = this.getDefinitionPayload(data.device);
}
publishEvent('device_interview', payload);
});
this.eventBus.onDeviceAnnounce(this, (data) => {
this.publishDevices();
publishEvent('device_announce', {friendly_name: data.device.name, ieee_address: data.device.ieeeAddr});
});
await this.publishInfo();
await this.publishDevices();
await this.publishGroups();
this.onMQTTMessage_ = this.onMQTTMessage_.bind(this);
this.eventBus.onMQTTMessage(this, this.onMQTTMessage_);
}
// TODO remove trailing _
@bind async onMQTTMessage_(data: EventMQTTMessage): Promise<void> {
const match = data.topic.match(requestRegex);
const key = match?.[1]?.toLowerCase();
if (key in this.requestLookup) {
const message = utils.parseJSON(data.message, data.message);
try {
const response = await this.requestLookup[key](message);
await this.mqtt.publish(`bridge/response/${match[1]}`, stringify(response));
} catch (error) {
logger.error(`Request '${data.topic}' failed with error: '${error.message}'`);
const response = utils.getResponse(message, {}, error.message);
await this.mqtt.publish(`bridge/response/${match[1]}`, stringify(response));
}
}
}
/**
* Requests
*/
@bind async deviceOptions(message: KeyValue | string): Promise<MQTTResponse> {
return this.changeEntityOptions('device', message);
}
@bind async groupOptions(message: KeyValue | string): Promise<MQTTResponse> {
return this.changeEntityOptions('group', message);
}
@bind async bridgeOptions(message: KeyValue | string): Promise<MQTTResponse> {
if (typeof message !== 'object' || typeof message.options !== 'object') {
throw new Error(`Invalid payload`);
}
const diff: KeyValue = detailedDiff(settings.get(), message.options);
// Remove any settings that are in the deleted.diff but not in the passed options
const cleanupDeleted = (options: KeyValue, deleted: KeyValue): void => {
for (const key of Object.keys(deleted)) {
if (!(key in options)) {
delete deleted[key];
} else if (!Array.isArray(options[key])) {
cleanupDeleted(options[key], deleted[key]);
}
}
};
cleanupDeleted(message.options, diff.deleted);
const newSettings = objectAssignDeep({}, diff.added, diff.updated, diff.deleted);
// deep-object-diff converts arrays to objects, set original array back here
const convertBackArray = (before: KeyValue, after: KeyValue): void => {
for (const [key, afterValue] of Object.entries(after)) {
const beforeValue = before[key];
if (Array.isArray(beforeValue)) {
after[key] = beforeValue;
} else if (afterValue && typeof beforeValue === 'object') {
convertBackArray(beforeValue, afterValue);
}
}
};
convertBackArray(message.options, newSettings);
const restartRequired = settings.apply(newSettings);
if (restartRequired) this.restartRequired = true;
// Apply some settings on-the-fly.
if (newSettings.hasOwnProperty('permit_join')) {
await this.zigbee.permitJoin(newSettings.permit_join);
}
if (newSettings.hasOwnProperty('homeassistant')) {
await this.enableDisableExtension(newSettings.homeassistant, 'HomeAssistant');
}
if (newSettings.hasOwnProperty('advanced') && newSettings.advanced.hasOwnProperty('log_level')) {
// @ts-ignore fix type
logger.setLevel(newSettings.advanced.log_level);
}
logger.info('Succesfully changed options');
this.publishInfo();
return utils.getResponse(message, {restart_required: this.restartRequired}, null);
}
@bind async deviceRemove(message: string | KeyValue): Promise<MQTTResponse> {
return this.removeEntity('device', message);
}
@bind async groupRemove(message: string | KeyValue): Promise<MQTTResponse> {
return this.removeEntity('group', message);
}
@bind async healthCheck(message: string | KeyValue): Promise<MQTTResponse> {
return utils.getResponse(message, {healthy: true}, null);
}
@bind async groupAdd(message: string | KeyValue): Promise<MQTTResponse> {
if (typeof message === 'object' && !message.hasOwnProperty('friendly_name')) {
throw new Error(`Invalid payload`);
}
const friendlyName = typeof message === 'object' ? message.friendly_name : message;
const ID = typeof message === 'object' && message.hasOwnProperty('id') ? message.id : null;
const group = settings.addGroup(friendlyName, ID);
this.zigbee.createGroup(group.ID);
this.publishGroups();
return utils.getResponse(message, {friendly_name: group.friendlyName, id: group.ID}, null);
}
@bind async deviceRename(message: string | KeyValue): Promise<MQTTResponse> {
return this.renameEntity('device', message);
}
@bind async groupRename(message: string | KeyValue): Promise<MQTTResponse> {
return this.renameEntity('group', message);
}
@bind async restart(message: string | KeyValue): Promise<MQTTResponse> {
// Wait 500 ms before restarting so response can be send.
setTimeout(this.restartCallback, 500);
logger.info('Restarting Zigbee2MQTT');
return utils.getResponse(message, {}, null);
}
@bind async permitJoin(message: KeyValue | string): Promise<MQTTResponse> {
if (typeof message === 'object' && !message.hasOwnProperty('value')) {
throw new Error('Invalid payload');
}
let value: boolean | string;
let time: number;
let device: Device = null;
if (typeof message === 'object') {
value = message.value;
time = message.time;
if (message.device) {
const resolved = this.zigbee.resolveEntity(message.device);
if (resolved instanceof Device) {
device = resolved;
} else {
throw new Error(`Device '${message.device}' does not exist`);
}
}
} else {
value = message;
}
if (typeof value === 'string') {
value = value.toLowerCase() === 'true';
}
await this.zigbee.permitJoin(value, device, time);
const response: {value: boolean, device?: string, time?: number} = {value};
if (device && typeof message === 'object') response.device = message.device;
if (time && typeof message === 'object') response.time = message.time;
return utils.getResponse(message, response, null);
}
// Deprecated
@bind async configLastSeen(message: KeyValue | string): Promise<MQTTResponse> {
const allowed = ['disable', 'ISO_8601', 'epoch', 'ISO_8601_local'];
const value = this.getValue(message);
if (typeof value !== 'string' || !allowed.includes(value)) {
throw new Error(`'${value}' is not an allowed value, allowed: ${allowed}`);
}
settings.set(['advanced', 'last_seen'], value);
this.publishInfo();
return utils.getResponse(message, {value}, null);
}
// Deprecated
@bind async configHomeAssistant(message: string | KeyValue): Promise<MQTTResponse> {
const allowed = [true, false];
const value = this.getValue(message);
if (typeof value !== 'boolean' || !allowed.includes(value)) {
throw new Error(`'${value}' is not an allowed value, allowed: ${allowed}`);
}
await this.enableDisableExtension(value, 'HomeAssistant');
settings.set(['homeassistant'], value);
this.publishInfo();
return utils.getResponse(message, {value}, null);
}
// Deprecated
@bind async configElapsed(message: KeyValue | string): Promise<MQTTResponse> {
const allowed = [true, false];
const value = this.getValue(message);
if (typeof value !== 'boolean' || !allowed.includes(value)) {
throw new Error(`'${value}' is not an allowed value, allowed: ${allowed}`);
}
settings.set(['advanced', 'elapsed'], value);
this.publishInfo();
return utils.getResponse(message, {value}, null);
}
// Deprecated
@bind async configLogLevel(message: KeyValue | string): Promise<MQTTResponse> {
const allowed = ['error', 'warn', 'info', 'debug'];
const value = this.getValue(message);
if (typeof value !== 'string' || !allowed.includes(value)) {
throw new Error(`'${value}' is not an allowed value, allowed: ${allowed}`);
}
// @ts-ignore TODO fix type
logger.setLevel(value);
this.publishInfo();
return utils.getResponse(message, {value}, null);
}
@bind async touchlinkIdentify(message: KeyValue | string): Promise<MQTTResponse> {
if (typeof message !== 'object' || !message.hasOwnProperty('ieee_address') ||
!message.hasOwnProperty('channel')) {
throw new Error('Invalid payload');
}
logger.info(`Start Touchlink identify of '${message.ieee_address}' on channel ${message.channel}`);
await this.zigbee.touchlinkIdentify(message.ieee_address, message.channel);
return utils.getResponse(message, {ieee_address: message.ieee_address, channel: message.channel}, null);
}
@bind async touchlinkFactoryReset(message: KeyValue | string): Promise<MQTTResponse> {
let result = false;
const payload: {ieee_address?: string, channel?: number} = {};
if (typeof message === 'object' && message.hasOwnProperty('ieee_address') &&
message.hasOwnProperty('channel')) {
logger.info(`Start Touchlink factory reset of '${message.ieee_address}' on channel ${message.channel}`);
result = await this.zigbee.touchlinkFactoryReset(message.ieee_address, message.channel);
payload.ieee_address = message.ieee_address;
payload.channel = message.channel;
} else {
logger.info('Start Touchlink factory reset of first found device');
result = await this.zigbee.touchlinkFactoryResetFirst();
}
if (result) {
logger.info('Successfully factory reset device through Touchlink');
return utils.getResponse(message, payload, null);
} else {
logger.error('Failed to factory reset device through Touchlink');
throw new Error('Failed to factory reset device through Touchlink');
}
}
@bind async touchlinkScan(message: KeyValue | string): Promise<MQTTResponse> {
logger.info('Start Touchlink scan');
const result = await this.zigbee.touchlinkScan();
const found = result.map((r) => {
return {ieee_address: r.ieeeAddr, channel: r.channel};
});
logger.info('Finished Touchlink scan');
return utils.getResponse(message, {found}, null);
}
/**
* Utils
*/
getValue(message: KeyValue | string): string | boolean | number {
if (typeof message === 'object') {
if (!message.hasOwnProperty('value')) {
throw new Error('No value given');
}
return message.value;
} else {
return message;
}
}
async changeEntityOptions(entityType: 'device' | 'group', message: KeyValue | string): Promise<MQTTResponse> {
if (typeof message !== 'object' || !message.hasOwnProperty('id') || !message.hasOwnProperty('options')) {
throw new Error(`Invalid payload`);
}
const cleanup = (o: KeyValue): KeyValue => {
delete o.friendlyName; delete o.friendly_name; delete o.ID; delete o.type; delete o.devices;
return o;
};
const ID = message.id;
const entity = this.getEntity(entityType, ID);
const oldOptions = objectAssignDeep({}, cleanup(entity.settings));
settings.changeEntityOptions(ID, message.options);
const newOptions = cleanup(settings.getEntity(ID));
await this.publishInfo();
logger.info(`Changed config for ${entityType} ${ID}`);
return utils.getResponse(message, {from: oldOptions, to: newOptions, id: ID}, null);
}
@bind async deviceConfigureReporting(message: string | KeyValue): Promise<MQTTResponse> {
if (typeof message !== 'object' || !message.hasOwnProperty('id') || !message.hasOwnProperty('cluster') ||
!message.hasOwnProperty('maximum_report_interval') || !message.hasOwnProperty('minimum_report_interval') ||
!message.hasOwnProperty('reportable_change') || !message.hasOwnProperty('attribute')) {
throw new Error(`Invalid payload`);
}
const parsedID = utils.parseEntityID(message.id);
const endpoint = (this.getEntity('device', parsedID.ID) as Device).endpoint(parsedID.endpoint);
const coordinatorEndpoint = this.zigbee.getFirstCoordinatorEndpoint();
await endpoint.bind(message.cluster, coordinatorEndpoint);
await endpoint.configureReporting(message.cluster, [{
attribute: message.attribute, minimumReportInterval: message.minimum_report_interval,
maximumReportInterval: message.maximum_report_interval, reportableChange: message.reportable_change,
}]);
this.publishDevices();
logger.info(`Configured reporting for '${message.id}', '${message.cluster}.${message.attribute}'`);
return utils.getResponse(message, {
id: message.id, cluster: message.cluster, maximum_report_interval: message.maximum_report_interval,
minimum_report_interval: message.minimum_report_interval, reportable_change: message.reportable_change,
attribute: message.attribute,
}, null);
}
async renameEntity(entityType: 'group' | 'device', message: string | KeyValue): Promise<MQTTResponse> {
const deviceAndHasLast = entityType === 'device' && typeof message === 'object' && message.last === true;
if (typeof message !== 'object' || (!message.hasOwnProperty('from') && !deviceAndHasLast) ||
!message.hasOwnProperty('to')) {
throw new Error(`Invalid payload`);
}
if (deviceAndHasLast && !this.lastJoinedDeviceIeeeAddr) {
throw new Error('No device has joined since start');
}
const from = deviceAndHasLast ? this.lastJoinedDeviceIeeeAddr : message.from;
const to = message.to;
const homeAssisantRename = message.hasOwnProperty('homeassistant_rename') ?
message.homeassistant_rename : false;
const entity = this.getEntity(entityType, from);
const oldFriendlyName = entity.settings.friendlyName;
settings.changeFriendlyName(from, to);
// Clear retained messages
this.mqtt.publish(oldFriendlyName, '', {retain: true});
if (entity instanceof Device) {
this.publishDevices();
this.eventBus.emit(`deviceRenamed`, {device: entity, homeAssisantRename, from: oldFriendlyName, to});
} else {
this.publishGroups();
this.publishInfo();
}
// Repulish entity state
this.publishEntityState(to, {});
return utils.getResponse(
message,
{from: oldFriendlyName, to, homeassistant_rename: homeAssisantRename},
null,
);
}
async removeEntity(entityType: 'group' | 'device', message: string | KeyValue): Promise<MQTTResponse> {
const ID = typeof message === 'object' ? message.id : message.trim();
const entity = this.getEntity(entityType, ID);
const friendlyName = entity.name;
const entityID = entity.ID;
let block = false;
let force = false;
let blockForceLog = '';
if (entityType === 'device' && typeof message === 'object') {
block = !!message.block;
force = !!message.force;
blockForceLog = ` (block: ${block}, force: ${force})`;
} else if (entityType === 'group' && typeof message === 'object') {
force = !!message.force;
blockForceLog = ` (force: ${force})`;
}
try {
logger.info(`Removing ${entityType} '${entity.settings.friendlyName}'${blockForceLog}`);
if (entity instanceof Device) {
if (block) {
settings.blockDevice(entity.ieeeAddr);
}
if (force) {
await entity.zhDevice.removeFromDatabase();
} else {
await entity.zhDevice.removeFromNetwork();
}
} else {
if (force) {
entity.zhGroup.removeFromDatabase();
} else {
await entity.zhGroup.removeFromNetwork();
}
}
// Fire event
if (entity instanceof Device) {
this.eventBus.emit('deviceRemoved', {resolvedEntity: entity});
}
// Remove from configuration.yaml
if (entity instanceof Device) {
settings.removeDevice(entityID as string);
} else {
settings.removeGroup(entityID);
}
// Remove from state
this.state.remove(entityID);
// Clear any retained messages
this.mqtt.publish(friendlyName, '', {retain: true});
logger.info(`Successfully removed ${entityType} '${friendlyName}'${blockForceLog}`);
if (entity instanceof Device) {
this.publishGroups();
this.publishDevices();
return utils.getResponse(message, {id: ID, block, force}, null);
} else {
this.publishGroups();
return utils.getResponse(message, {id: ID, force: force}, null);
}
} catch (error) {
throw new Error(
`Failed to remove ${entityType} '${friendlyName}'${blockForceLog} (${error})`,
);
}
}
getEntity(type: 'group' | 'device', ID: string): Device | Group {
const entity = this.zigbee.resolveEntity(ID);
if (!entity || entity.constructor.name.toLowerCase() !== type) {
throw new Error(`${utils.capitalize(type)} '${ID}' does not exist`);
}
return entity;
}
async publishInfo(): Promise<void> {
const config = objectAssignDeep({}, settings.get());
delete config.advanced.network_key;
delete config.mqtt.password;
config.frontend && delete config.frontend.auth_token;
const payload = {
version: this.zigbee2mqttVersion.version,
commit: this.zigbee2mqttVersion.commitHash,
coordinator: this.coordinatorVersion,
network: utils.toSnakeCase(await this.zigbee.getNetworkParameters()),
// @ts-ignore TODO fix type
log_level: logger.getLevel(),
permit_join: this.zigbee.getPermitJoin(),
permit_join_timeout: this.zigbee.getPermitJoinTimeout(),
restart_required: this.restartRequired,
config,
config_schema: settings.schema,
};
await this.mqtt.publish(
'bridge/info', stringify(payload), {retain: true, qos: 0}, settings.get().mqtt.base_topic, true);
}
async publishDevices(): Promise<void> {
interface Data {
bindings: {cluster: string, target: {type: string, endpoint?: number, ieee_address?: string, id?: number}}[]
configured_reportings: {cluster: string, attribute: string | number,
minimum_report_interval: number, maximum_report_interval: number, reportable_change: number}[],
clusters: {input: string[], output: string[]}
}
const devices = this.zigbee.getDevices().map((device) => {
const endpoints: {[s: number]: Data} = {};
for (const endpoint of device.endpoints) {
const data: Data = {
bindings: [],
configured_reportings: [],
clusters: {
input: endpoint.getInputClusters().map((c) => c.name),
output: endpoint.getOutputClusters().map((c) => c.name),
},
};
for (const bind of endpoint.binds) {
const target = utils.isEndpoint(bind.target) ?
{type: 'endpoint', ieee_address: bind.target.getDevice().ieeeAddr, endpoint: bind.target.ID} :
{type: 'group', id: bind.target.groupID};
data.bindings.push({cluster: bind.cluster.name, target});
}
for (const configuredReporting of endpoint.configuredReportings) {
data.configured_reportings.push({
cluster: configuredReporting.cluster.name,
attribute: configuredReporting.attribute.name || configuredReporting.attribute.ID,
minimum_report_interval: configuredReporting.minimumReportInterval,
maximum_report_interval: configuredReporting.maximumReportInterval,
reportable_change: configuredReporting.reportableChange,
});
}
endpoints[endpoint.ID] = data;
}
return {
ieee_address: device.ieeeAddr,
type: device.type,
network_address: device.networkAddress,
supported: !!device.definition,
friendly_name: device.name,
definition: this.getDefinitionPayload(device),
power_source: device.powerSource,
software_build_id: device.softwareBuildID,
date_code: device.dateCode,
model_id: device.modelID,
interviewing: device.interviewing,
interview_completed: device.interviewCompleted,
manufacturer: device.manufacturerName,
endpoints,
};
});
await this.mqtt.publish('bridge/devices', stringify(devices),
{retain: true, qos: 0}, settings.get().mqtt.base_topic, true);
}
async publishGroups(): Promise<void> {
const groups = this.zigbee.getGroups().map((g) => {
return {
id: g.ID,
friendly_name: g.ID === 901 ? 'default_bind_group' : g.name,
members: g.members.map((e) => {
return {ieee_address: e.getDevice().ieeeAddr, endpoint: e.ID};
}),
};
});
await this.mqtt.publish(
'bridge/groups', stringify(groups), {retain: true, qos: 0}, settings.get().mqtt.base_topic, true);
}
getDefinitionPayload(device: Device):
{model: string, vendor: string, description: string, exposes: unknown[], supports_ota: boolean, icon: string} {
if (!device.definition) return null;
let icon = device.settings.icon ? device.settings.icon : device.definition.icon;
if (icon) {
icon = icon.replace('${zigbeeModel}', utils.sanitizeImageParameter(device.modelID));
icon = icon.replace('${model}', utils.sanitizeImageParameter(device.definition.model));
}
return {
model: device.definition.model,
vendor: device.definition.vendor,
description: device.definition.description,
exposes: device.definition.exposes,
supports_ota: !!device.definition.ota,
icon,
};
}
}
module.exports = Bridge;
-289
View File
@@ -1,289 +0,0 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
const utils = require('../util/utils');
const configRegex = new RegExp(`${settings.get().mqtt.base_topic}/bridge/config/((?:\\w+/get)|(?:\\w+))`);
const allowedLogLevels = ['error', 'warn', 'info', 'debug'];
class BridgeConfig {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
// Bind functions
this.permitJoin = this.permitJoin.bind(this);
this.lastSeen = this.lastSeen.bind(this);
this.elapsed = this.elapsed.bind(this);
this.reset = this.reset.bind(this);
this.logLevel = this.logLevel.bind(this);
this.devices = this.devices.bind(this);
this.groups = this.groups.bind(this);
this.rename = this.rename.bind(this);
this.remove = this.remove.bind(this);
this.ban = this.ban.bind(this);
this.deviceOptions = this.deviceOptions.bind(this);
this.addGroup = this.addGroup.bind(this);
this.removeGroup = this.removeGroup.bind(this);
this.whitelist= this.whitelist.bind(this);
// Set supported options
this.supportedOptions = {
'permit_join': this.permitJoin,
'last_seen': this.lastSeen,
'elapsed': this.elapsed,
'reset': this.reset,
'log_level': this.logLevel,
'devices': this.devices,
'groups': this.groups,
'devices/get': this.devices,
'rename': this.rename,
'remove': this.remove,
'ban': this.ban,
'device_options': this.deviceOptions,
'add_group': this.addGroup,
'remove_group': this.removeGroup,
'whitelist': this.whitelist,
};
}
whitelist(topic, message) {
message = message.toString();
const IDByFriendlyName = settings.getIeeeAddrByFriendlyName(message);
const deviceID = IDByFriendlyName ? IDByFriendlyName : message;
const whitelisted = settings.whitelistDevice(deviceID);
whitelisted ? logger.info(`Whitelisted '${deviceID}'`) : logger.error(`Failed to whitelist '${deviceID}'`);
this.mqtt.log('device_whitelisted', deviceID);
}
deviceOptions(topic, message) {
let json = null;
try {
json = JSON.parse(message.toString());
} catch (e) {
logger.error('Failed to parse message as JSON');
return;
}
if (!json.hasOwnProperty('friendly_name') || !json.hasOwnProperty('options')) {
logger.error('Invalid JSON message, should contain "friendly_name" and "options"');
return;
}
const ieeeAddr = settings.getIeeeAddrByFriendlyName(json.friendly_name);
if (!ieeeAddr) {
logger.error(`Failed to find device '${json.friendly_name}'`);
return;
}
settings.changeDeviceOptions(ieeeAddr, json.options);
logger.info(`Changed device specific options of '${json.friendly_name}' (${JSON.stringify(json.options)})`);
}
permitJoin(topic, message) {
this.zigbee.permitJoin(message.toString().toLowerCase() === 'true', () => this.publish());
}
reset(topic, message) {
this.zigbee.softReset((error) => {
if (error) {
logger.error('Soft reset failed');
} else {
logger.info('Soft resetted ZNP');
}
});
}
lastSeen(topic, message) {
const allowed = ['disable', 'ISO_8601', 'epoch', 'ISO_8601_local'];
message = message.toString();
if (!allowed.includes(message)) {
logger.error(`${message} is not an allowed value, possible: ${allowed}`);
return;
}
settings.set(['advanced', 'last_seen'], message);
logger.info(`Set last_seen to ${message}`);
}
elapsed(topic, message) {
const allowed = ['true', 'false'];
message = message.toString();
if (!allowed.includes(message)) {
logger.error(`${message} is not an allowed value, possible: ${allowed}`);
return;
}
settings.set(['advanced', 'elapsed'], message === 'true');
logger.info(`Set elapsed to ${message}`);
}
logLevel(topic, message) {
const level = message.toString().toLowerCase();
if (allowedLogLevels.includes(level)) {
logger.info(`Switching log level to '${level}'`);
logger.transports.console.level = level;
logger.transports.file.level = level;
} else {
logger.error(`Could not set log level to '${level}'. Allowed level: '${allowedLogLevels.join(',')}'`);
}
this.publish();
}
devices(topic, message) {
const devices = this.zigbee.getDevices().map((device) => {
const payload = {
ieeeAddr: device.ieeeAddr,
type: device.type,
};
if (device.type !== 'Coordinator') {
const mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
const friendlyDevice = settings.getDevice(device.ieeeAddr);
payload.model = mappedDevice ? mappedDevice.model : device.modelId;
payload.friendly_name = friendlyDevice ? friendlyDevice.friendly_name : device.ieeeAddr;
payload.nwkAddr = device.nwkAddr;
payload.manufId = device.manufId;
payload.manufName = device.manufName;
payload.powerSource = device.powerSource;
payload.modelId = device.modelId;
payload.hwVersion = device.hwVersion;
payload.swBuildId = device.swBuildId;
payload.dateCode = device.dateCode;
}
return payload;
});
if (topic.split('/').pop() == 'get') {
this.mqtt.publish(`bridge/config/devices`, JSON.stringify(devices), {});
} else {
this.mqtt.log('devices', devices);
}
}
groups(topic, message) {
this.mqtt.log('groups', settings.getGroups());
}
rename(topic, message) {
const invalid = `Invalid rename message format expected {old: 'friendly_name', new: 'new_name} ` +
`got ${message.toString()}`;
let json = null;
try {
json = JSON.parse(message.toString());
} catch (e) {
logger.error(invalid);
return;
}
// Validate message
if (!json.new || !json.old) {
logger.error(invalid);
return;
}
if (settings.changeFriendlyName(json.old, json.new)) {
logger.info(`Successfully renamed - ${json.old} to ${json.new} `);
this.mqtt.log('device_renamed', {from: json.old, to: json.new});
} else {
logger.error(`Failed to renamed - ${json.old} to ${json.new}`);
return;
}
}
addGroup(topic, message) {
const name = message.toString();
const added = settings.addGroup(name);
added ? logger.info(`Added group '${name}'`) : logger.error(`Failed to add group '${name}'`);
}
removeGroup(topic, message) {
const name = message.toString();
const removed = settings.removeGroup(name);
removed ? logger.info(`Removed group '${name}'`) : logger.error(`Failed to remove group '${name}'`);
}
remove(topic, message) {
this.removeOrBan(false, message);
}
ban(topic, message) {
this.removeOrBan(true, message);
}
removeOrBan(ban, message) {
message = message.toString();
const IDByFriendlyName = settings.getIeeeAddrByFriendlyName(message);
const deviceID = IDByFriendlyName ? IDByFriendlyName : message;
const device = this.zigbee.getDevice(deviceID);
const cleanup = () => {
// Remove from configuration.yaml
settings.removeDevice(deviceID);
// Remove from state
this.state.remove(deviceID);
logger.info(`Successfully ${ban ? 'banned' : 'removed'} ${deviceID}`);
this.mqtt.log(ban ? 'device_banned' : 'device_removed', message);
};
// Remove from zigbee network.
if (device) {
this.zigbee.removeDevice(deviceID, ban, (error) => {
if (!error) {
cleanup();
} else {
logger.error(`Failed to ${ban ? 'ban' : 'remove'} ${deviceID}`);
}
});
} else {
cleanup();
}
}
onMQTTConnected() {
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/config/+`);
this.publish();
}
onMQTTMessage(topic, message) {
if (!topic.match(configRegex)) {
return false;
}
const option = topic.match(configRegex)[1];
if (!this.supportedOptions.hasOwnProperty(option)) {
return false;
}
this.supportedOptions[option](topic, message);
return true;
}
publish() {
utils.getZigbee2mqttVersion((info) => {
const topic = `bridge/config`;
const payload = {
version: info.version,
commit: info.commitHash,
coordinator: this.zigbee.getFirmwareVersion(),
log_level: logger.transports.console.level,
permit_join: this.zigbee.getPermitJoin(),
};
this.mqtt.publish(topic, JSON.stringify(payload), {retain: true, qos: 0}, null);
});
}
}
module.exports = BridgeConfig;
+140
View File
@@ -0,0 +1,140 @@
import * as settings from '../util/settings';
import * as utils from '../util/utils';
import logger from '../util/logger';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
// @ts-ignore
import zhc from 'zigbee-herdsman-converters';
import ExtensionTS from './extensionts';
import bind from 'bind-decorator';
import Device from '../model/device';
/**
* This extension calls the zigbee-herdsman-converters definition configure() method
*/
class Configure extends ExtensionTS {
private configuring = new Set();
private attempts: {[s: string]: number} = {};
private topic = `${settings.get().mqtt.base_topic}/bridge/request/device/configure`;
private legacyTopic = `${settings.get().mqtt.base_topic}/bridge/configure`;
@bind private async onReportingDisabled(data: EventReportingDisabled): Promise<void> {
// Disabling reporting unbinds some cluster which could be bound by configure, re-setup.
const device = this.zigbee.resolveEntity(data.device) as Device; // TODO assert device
if (device.zhDevice.meta?.hasOwnProperty('configured')) {
delete device.zhDevice.meta.configured;
device.zhDevice.save();
}
await this.configure(device, 'reporting_disabled');
}
// TODO remove trailing _
@bind private async onMQTTMessage_(data: EventMQTTMessage): Promise<void> {
if (data.topic === this.legacyTopic) {
const device = this.zigbee.resolveEntity(data.message);
if (!device || !(device instanceof Device)) {
logger.error(`Device '${data.message}' does not exist`);
return;
}
if (!device.definition || !device.definition.configure) {
logger.warn(`Skipping configure of '${device.name}', device does not require this.`);
return;
}
this.configure(device, 'mqtt_message', true);
} else if (data.topic === this.topic) {
const message = utils.parseJSON(data.message, data.message);
const ID = typeof message === 'object' && message.hasOwnProperty('id') ? message.id : message;
let error = null;
const device = this.zigbee.resolveEntity(ID);
if (!device || !(device instanceof Device)) {
error = `Device '${ID}' does not exist`;
} else if (!device.definition || !device.definition.configure) {
error = `Device '${device.name}' cannot be configured`;
} else {
try {
await this.configure(device, 'mqtt_message', true, true);
} catch (e) {
error = `Failed to configure (${e.message})`;
}
}
const response = utils.getResponse(message, {id: ID}, error);
await this.mqtt.publish(`bridge/response/device/configure`, stringify(response));
}
}
override async start(): Promise<void> {
for (const device of this.zigbee.getClients()) {
await this.configure(device, 'started');
}
this.eventBus.onDeviceJoined(this, (data) => {
if (data.device.zhDevice.meta.hasOwnProperty('configured')) {
delete data.device.zhDevice.meta.configured;
data.device.zhDevice.save();
}
this.configure(data.device, 'zigbee_event');
});
this.eventBus.onLastSeenChanged(this, (data) => this.configure(data.device, 'zigbee_event'));
this.eventBus.onMQTTMessage(this, this.onMQTTMessage_);
this.eventBus.onReportingDisabled(this, this.onReportingDisabled);
}
private async configure(device: Device, event: 'started' | 'zigbee_event' | 'reporting_disabled' | 'mqtt_message',
force=false, thowError=false): Promise<void> {
if (!force) {
if (!device.definition?.configure || device.zhDevice.interviewing) {
return;
}
if (device.zhDevice.meta?.hasOwnProperty('configured') &&
device.zhDevice.meta.configured === zhc.getConfigureKey(device.definition)) {
return;
}
// Only configure end devices when it is active, otherwise it will likely fails as they are sleeping.
if (device.zhDevice.type === 'EndDevice' && event !== 'zigbee_event') {
return;
}
}
if (this.configuring.has(device.ieeeAddr) || (this.attempts[device.ieeeAddr] >= 3 && !force)) {
return;
}
this.configuring.add(device.ieeeAddr);
if (!this.attempts.hasOwnProperty(device.ieeeAddr)) {
this.attempts[device.ieeeAddr] = 0;
}
logger.info(`Configuring '${device.name}'`);
try {
await device.definition.configure(device.zhDevice, this.zigbee.getFirstCoordinatorEndpoint(), logger);
logger.info(`Successfully configured '${device.name}'`);
device.zhDevice.meta.configured = zhc.getConfigureKey(device.definition);
device.zhDevice.save();
this.eventBus.emitDevicesChanged();
this.eventBus.emit(`devicesChanged`);
} catch (error) {
this.attempts[device.ieeeAddr]++;
const attempt = this.attempts[device.ieeeAddr];
const msg = `Failed to configure '${device.name}', attempt ${attempt} (${error.stack})`;
logger.error(msg);
if (thowError) {
throw error;
}
}
this.configuring.delete(device.ieeeAddr);
}
}
module.exports = Configure;
-182
View File
@@ -1,182 +0,0 @@
const logger = require('../util/logger');
const settings = require('../util/settings');
const utils = require('../util/utils');
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
// Some EndDevices should be pinged
// e.g. E11-G13 https://github.com/Koenkk/zigbee2mqtt/issues/775#issuecomment-453683846
const pingableDevices = [
zigbeeShepherdConverters.devices.find((d) => d.model === 'E11-G13'),
];
const toZigbeeCandidates = ['state', 'color', 'color_temp'];
/**
* This extensions pings devices to check if they are online.
*/
class DeviceAvailability {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.availability_timeout = settings.get().advanced.availability_timeout;
this.timers = {};
this.pending = [];
this.state = {};
// Initialize blacklist
this.blacklist = settings.get().advanced.availability_blacklist.map((e) => {
return settings.getIeeeAddrByFriendlyName(e) || e;
});
}
isPingable(device) {
logger.trace(`Checking if ${device.ieeeAddr} is pingable`);
if (this.blacklist.includes(device.ieeeAddr)) {
logger.trace(`${device.ieeeAddr} is not pingable because of blacklist`);
return false;
}
if (pingableDevices.find((d) => d.zigbeeModel.includes(device.modelId))) {
logger.trace(`${device.ieeeAddr} is pingable because in pingable devices`);
return true;
}
const result = utils.isRouter(device) && !utils.isBatteryPowered(device);
logger.trace(`${device.ieeeAddr} is pingable (${result}) not router or battery powered`);
return result;
}
getAllPingableDevices() {
return this.zigbee.getAllClients().filter((d) => this.isPingable(d));
}
onMQTTConnected() {
// As some devices are not checked for availability (e.g. battery powered devices)
// we mark all device as online by default.
this.zigbee.getDevices()
.filter((d) => d.type !== 'Coordinator')
.forEach((device) => this.publishAvailability(device.ieeeAddr, true));
// Start timers for all devices
this.getAllPingableDevices().forEach((device) => this.setTimer(device));
}
handleInterval(device) {
// Check if a job is already pending.
// This avoids overflowing of the queue in case the queue is not able to catch-up with the jobs being added.
const ieeeAddr = device.ieeeAddr;
if (this.pending.includes(ieeeAddr)) {
logger.debug(`Skipping ping for ${ieeeAddr} becuase job is already in queue`);
return;
}
this.pending.push(ieeeAddr);
// When a device is already unavailable, log the ping failed on 'debug' instead of 'error'.
const errorLogLevel = this.state.hasOwnProperty(ieeeAddr) && !this.state[ieeeAddr] ? 'debug' : 'error';
const mechanism = utils.isXiaomiDevice(device) ? 'basic' : 'default';
this.zigbee.ping(ieeeAddr, errorLogLevel, (error) => {
this.publishAvailability(ieeeAddr, !error);
// Remove from pending jobs.
const index = this.pending.indexOf(ieeeAddr);
if (index !== -1) {
this.pending.splice(index, 1);
}
this.setTimer(device);
}, mechanism);
}
setTimer(device) {
if (this.timers[device.ieeeAddr]) {
clearTimeout(this.timers[device.ieeeAddr]);
}
this.timers[device.ieeeAddr] = setTimeout(() => {
this.handleInterval(device);
}, utils.secondsToMilliseconds(this.availability_timeout));
}
stop() {
this.zigbee.getDevices()
.filter((d) => d.type !== 'Coordinator')
.forEach((device) => this.publishAvailability(device.ieeeAddr, false));
}
onReconnect(ieeeAddr) {
const device = this.zigbee.getDevice(ieeeAddr);
let mappedDevice = null;
if (device && device.modelId) {
mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
}
if (mappedDevice) {
const converters = mappedDevice.toZigbee.filter((tz) => {
return tz.key.find((k) => toZigbeeCandidates.includes(k));
});
converters.forEach((converter) => {
const convertedResults = converter.convert(null, null, null, 'get');
if (convertedResults && convertedResults.length) {
convertedResults.forEach((converted) => {
this.zigbee.publish(
ieeeAddr, 'device', converted.cid, converted.cmd, converted.cmdType,
converted.zclData, converted.cfg, null, () => {}
);
});
}
});
}
}
publishAvailability(ieeeAddr, available) {
if (this.state.hasOwnProperty(ieeeAddr) && !this.state[ieeeAddr] && available) {
this.onReconnect(ieeeAddr);
}
this.state[ieeeAddr] = available;
const deviceSettings = settings.getDevice(ieeeAddr);
const name = deviceSettings ? deviceSettings.friendly_name : ieeeAddr;
const topic = `${name}/availability`;
const payload = available ? 'online' : 'offline';
this.mqtt.publish(topic, payload, {retain: true, qos: 0});
}
onZigbeeMessage(message, device, mappedDevice) {
if (device && this.isPingable(this.zigbee.getDevice(device.ieeeAddr))) {
// When a zigbee message from a device is received we know the device is still alive.
// => reset the timer.
this.setTimer(device);
const online = this.state.hasOwnProperty(device.ieeeAddr) && this.state[device.ieeeAddr];
const offline = this.state.hasOwnProperty(device.ieeeAddr) && !this.state[device.ieeeAddr];
if (!online && !offline) {
// A new device has been connected
this.publishAvailability(device.ieeeAddr, true);
} else if (offline) {
// When a message is received and the device is marked as offline, mark it online.
this.publishAvailability(device.ieeeAddr, true);
} else if (online) {
/**
* In case the device is powered off AND on within the availability timeout,
* zigbee2qmtt does not detect the device as offline (device is still marked online).
* When a device is turned on again the state could be out of sync.
* https://github.com/Koenkk/zigbee2mqtt/issues/1383#issuecomment-489412168
* endDeviceAnnce is typically send when a device comes online.
*
* This isn't needed for TRADFRI devices as they already send the state themself.
*/
if (message.type === 'endDeviceAnnce' && !utils.isIkeaTradfriDevice(device)) {
this.onReconnect(device.ieeeAddr);
}
}
}
}
}
module.exports = DeviceAvailability;
-128
View File
@@ -1,128 +0,0 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const utils = require('../util/utils');
const postfixes = utils.getPostfixes();
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/(bind|unbind)/.+$`);
const allowedClusters = [
5, // genScenes
6, // genOnOff
8, // genLevelCtrl
768, // lightingColorCtrl
];
class DeviceBind {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
}
onMQTTConnected() {
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/bind/+`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/bind/+/+`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/unbind/+`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/unbind/+/+`);
}
getIDAndPostfix(topic) {
let postfix = null;
if (postfixes.find((p) => topic.endsWith(`/${p}`))) {
postfix = topic.substr(topic.lastIndexOf('/') + 1, topic.length);
// Remove postfix from topic
topic = topic.replace(`/${postfix}`, '');
}
return {ID: topic, postfix};
}
parseTopic(topic) {
if (!topic.match(topicRegex)) {
return null;
}
// Remove base from topic
topic = topic.replace(`${settings.get().mqtt.base_topic}/bridge/`, '');
// Parse type from topic
const type = topic.split('/')[0];
// Remove type from topic
topic = topic.replace(`${type}/`, '');
return {type, ...this.getIDAndPostfix(topic)};
}
onMQTTMessage(topic, message) {
topic = this.parseTopic(topic);
if (!topic) {
return false;
}
// Find source; can only be a device.
const sourceEntity = settings.resolveEntity(topic.ID);
const source = utils.getEndpointByEntityID(this.zigbee, sourceEntity.ID, topic.postfix);
const targetEntityIDPostfix= this.getIDAndPostfix(message.toString());
const targetEntity = settings.resolveEntity(targetEntityIDPostfix.ID);
let target = null;
if (targetEntity.type === 'device') {
target = utils.getEndpointByEntityID(this.zigbee, targetEntity.ID, targetEntityIDPostfix.postfix);
} else if (targetEntity.type === 'group') {
target = targetEntity.ID;
}
if (!source || !target) {
return false;
}
// Find which clusters are supported by both the source and target.
// Groups are assumed to support all clusters (as we don't know which devices are in)
let supported = [];
if (targetEntity.type === 'device') {
supported = target.getSimpleDesc().inClusterList.filter((cluster) => {
return allowedClusters.includes(cluster);
});
} else if (targetEntity.type === 'group') {
supported = allowedClusters;
}
const clusters = source.getSimpleDesc().outClusterList.filter((cluster) => {
return supported.includes(cluster);
});
// Bind
clusters.forEach((cluster) => {
logger.debug(
`${topic.type}ing cluster '${cluster}' from '${sourceEntity.ID}' ` +
`(${source.epId}) to '${targetEntity.ID}'`
);
this.zigbee[topic.type](source, cluster, target, (error) => {
if (error) {
logger.error(
`Failed to ${topic.type} cluster '${cluster}' from '${sourceEntity.ID}' to ` +
`'${targetEntity.ID}' (${error})`
);
} else {
logger.info(
`Successfully ${topic.type === 'bind' ? 'bound' : 'unbound'} cluster '${cluster}' from ` +
`'${sourceEntity.ID}' to '${targetEntity.ID}'`
);
this.mqtt.log(
`device_${topic.type}`,
{from: sourceEntity.ID, to: targetEntity.ID, cluster}
);
}
});
});
return true;
}
}
module.exports = DeviceBind;
-89
View File
@@ -1,89 +0,0 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
const Queue = require('queue');
/**
* This extensions handles configuration of devices.
*/
class DeviceConfigure {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.configured = {};
this.attempts = {};
this.queue = new Queue();
this.queue.concurrency = 1;
this.queue.autostart = true;
}
onZigbeeStarted() {
this.zigbee.getAllClients().forEach((device) => {
const mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
if (mappedDevice) {
this.configure(device.ieeeAddr, mappedDevice);
}
});
}
onZigbeeMessage(message, device, mappedDevice) {
if (device && mappedDevice) {
const ieeeAddr = device.ieeeAddr;
if (!this.configured[ieeeAddr]) {
this.configure(ieeeAddr, mappedDevice);
}
}
}
configure(ieeeAddr, mappedDevice) {
if (!this.attempts.hasOwnProperty(ieeeAddr)) {
this.attempts[ieeeAddr] = 0;
}
if (mappedDevice.configure) {
const friendlyName = settings.getDevice(ieeeAddr) ? settings.getDevice(ieeeAddr).friendly_name : 'unknown';
// mark device as currently being configured to prevent race conditions
this.configured[ieeeAddr] = 'configuring';
this.queue.push((queueCallback) => {
logger.debug(`Configuring ${friendlyName} (${ieeeAddr}) ...`);
// Call configure function of this device.
mappedDevice.configure(ieeeAddr, this.zigbee.shepherd, this.zigbee.getCoordinator(), (ok, msg) => {
if (ok) {
logger.info(`Successfully configured ${friendlyName} (${ieeeAddr})`);
this.configured[ieeeAddr] = 'configured';
} else {
// If a device is not joined in the network the configure command may fail
// (especially, immediately after zigbee start)
// also, this command may fail if the network is busy or lost data packets
if (this.attempts[ieeeAddr] > 1) {
// Give up after 3 attempts.
this.configured[ieeeAddr] = 'failed';
} else {
// we're not done yet so mark not busy
delete this.configured[ieeeAddr];
}
logger.warn(
`Failed to configure ${friendlyName} (${ieeeAddr}) ('${msg}')` +
` (attempt #${this.attempts[ieeeAddr] + 1})`
);
logger.warn(`This can be ignored if the device is working properly`);
this.attempts[ieeeAddr] += 1;
}
queueCallback();
});
});
} else {
// no need to configure anyting. So just mark as done
this.configured[ieeeAddr] = 'configured';
}
}
}
module.exports = DeviceConfigure;
-73
View File
@@ -1,73 +0,0 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/device/.+/get_group_membership$`);
class DeviceGroupMembership {
constructor(zigbee, mqtt, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.publishEntityState = publishEntityState;
}
onMQTTConnected() {
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/device/+/get_group_membership`);
}
parseTopic(topic) {
if (!topic.match(topicRegex)) {
return null;
}
// Remove base from topic
topic = topic.replace(`${settings.get().mqtt.base_topic}/bridge/device/`, '');
// Remove command from topic
topic = topic.replace(`/get_group_membership`, '');
return {friendlyName: topic};
}
onMQTTMessage(topic, message) {
topic = this.parseTopic(topic);
if (!topic) {
return false;
}
// Map message to ieeeAddr and check if device exist.
const friendlyName = topic.friendlyName;
const ieeeAddr = settings.getIeeeAddrByFriendlyName(friendlyName) || friendlyName;
if (!this.zigbee.getDevice(ieeeAddr)) {
logger.error(`Failed to find device '${friendlyName}'`);
return;
}
const callback = (error, rsp) => {
if (error) {
logger.error(`Failed to get membership of ${ieeeAddr}`);
} else {
const {grouplist, capacity} = rsp;
const msgGroupList = `${ieeeAddr} is in groups [${grouplist}]`;
let msgCapacity;
if (capacity === 254) {
msgCapacity = 'it can be a part of at least 1 more group';
} else {
msgCapacity = `its remaining group capacity is ${capacity === 255 ? 'unknown' : capacity}`;
}
logger.info(`${msgGroupList} and ${msgCapacity}`);
this.publishEntityState(ieeeAddr, {group_list: grouplist, group_capacity: capacity});
}
};
this.zigbee.publish(
ieeeAddr, 'device', 'genGroups', 'getMembership', 'functional',
{groupcount: 0, grouplist: []}, null, null, callback,
);
return true;
}
}
module.exports = DeviceGroupMembership;
-235
View File
@@ -1,235 +0,0 @@
const settings = require('../util/settings');
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
const logger = require('../util/logger');
const utils = require('../util/utils');
const objectAssignDeep = require(`object-assign-deep`);
const postfixes = utils.getPostfixes();
const topicRegex = new RegExp(`^(.+?)(?:/(${postfixes.join('|')}))?/(get|set)(?:/(.+))?`);
const maxDepth = 20;
const groupConverters = [
zigbeeShepherdConverters.toZigbeeConverters.light_onoff_brightness,
zigbeeShepherdConverters.toZigbeeConverters.light_colortemp,
zigbeeShepherdConverters.toZigbeeConverters.light_color,
zigbeeShepherdConverters.toZigbeeConverters.light_alert,
zigbeeShepherdConverters.toZigbeeConverters.ignore_transition,
];
class DevicePublish {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
}
onMQTTConnected() {
// Subscribe to topics.
const baseTopic = settings.get().mqtt.base_topic;
for (let step = 1; step < maxDepth; step++) {
const topic = `${baseTopic}/${'+/'.repeat(step)}`;
this.mqtt.subscribe(`${topic}set`);
this.mqtt.subscribe(`${topic}set/+`);
this.mqtt.subscribe(`${topic}get`);
this.mqtt.subscribe(`${topic}get/+`);
}
}
parseTopic(topic) {
const match = topic.match(topicRegex);
if (!match) {
return null;
}
const ID = match[1].replace(`${settings.get().mqtt.base_topic}/`, '');
// If we didn't repalce base_topic we received something we don't care about
if (ID === match[1] || ID.match(/bridge\/config/)) {
return null;
}
return {ID: ID, postfix: match[2] || '', type: match[3], attribute: match[4]};
}
handlePublishError(entity, message, error) {
const meta = {
entity,
message: message.toString(),
};
this.mqtt.log('zigbee_publish_error', error.toString(), meta);
}
handlePublished(entity, topic, converter, converted, key, value) {
if (topic.type === 'set' && converted.hasOwnProperty('newState') && converted.newState) {
const msg = converted.newState;
if (topic.postfix) {
msg[`state_${topic.postfix}`] = msg.state;
delete msg.state;
}
if (settings.get().advanced.last_seen !== 'disable') {
msg.last_seen = utils.formatDate(Date.now(), settings.get().advanced.last_seen);
}
this.publishEntityState(entity.ID, msg);
}
}
onMQTTMessage(topic, message) {
topic = this.parseTopic(topic);
if (!topic) {
return false;
}
// Resolve the entity
const entity = settings.resolveEntity(topic.ID);
// Get entity details
let endpoint = null;
let converters = null;
let device = null;
let options = {};
if (entity.type === 'device') {
device = this.zigbee.getDevice(entity.ID);
if (!device) {
logger.error(`Failed to find device with ieeeAddr: '${entity.ID}'`);
this.mqtt.log('entity_not_found', entity.ID);
return;
}
// Map device to a model
const model = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
if (!model) {
logger.warn(`Device with modelID '${device.modelId}' is not supported.`);
logger.warn(`Please see: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html`);
return;
}
// Determine endpoint to publish to.
if (model.hasOwnProperty('ep')) {
const eps = model.ep(device);
endpoint = eps.hasOwnProperty(topic.postfix) ? eps[topic.postfix] : null;
if (endpoint === null && eps.hasOwnProperty('default')) {
endpoint = eps['default'];
}
}
converters = model.toZigbee;
const deviceSettings = settings.getDevice(entity.ID);
options = objectAssignDeep.noMutate({}, model.options, deviceSettings);
} else if (entity.type === 'group') {
converters = groupConverters;
options = objectAssignDeep.noMutate({}, settings.getGroup(entity.ID));
}
// Convert the MQTT message to a Zigbee message.
let json = {};
if (topic.hasOwnProperty('attribute') && topic.attribute) {
json[topic.attribute] = message.toString();
} else {
try {
json = JSON.parse(message);
} catch (e) {
// Cannot be parsed to JSON, assume state message.
json = {state: message.toString()};
}
}
/**
* Home Assistant always publishes 'state', even when e.g. only setting
* the color temperature. This would lead to 2 zigbee publishes, where the first one
* (state) is probably unecessary.
*/
if (settings.get().homeassistant) {
const deviceState = this.state.get(entity.ID);
const hasColorTemp = json.hasOwnProperty('color_temp');
const hasColor = json.hasOwnProperty('color');
const hasBrightness = json.hasOwnProperty('brightness');
const isOn = deviceState && deviceState.state === 'ON' ? true : false;
if (isOn && (hasColorTemp || hasColor) && !hasBrightness) {
delete json.state;
logger.debug('Skipping state because of Home Assistant');
}
}
// Ensure that state and brightness are executed before other commands.
const keys = Object.keys(json);
keys.sort((a, b) => (['state', 'brightness'].includes(a) ? -1 : 1));
// For each key in the JSON message find the matching converter.
const usedConverters = [];
keys.forEach((key) => {
const converter = converters.find((c) => c.key.includes(key));
if (usedConverters.includes(converter)) {
// Use a converter only once (e.g. light_onoff_brightness converters can convert state and brightness)
return;
}
if (!converter) {
logger.error(`No converter available for '${key}' (${json[key]})`);
return;
}
// Converter didn't return a result, skip
const convertedResults = converter.convert(key, json[key], json, topic.type, topic.postfix, options);
if (!convertedResults || !convertedResults.length) {
return;
}
convertedResults.forEach((converted) => {
this.zigbee.publish(
entity.ID,
entity.type,
converted.cid,
converted.cmd,
converted.cmdType,
converted.zclData,
converted.cfg,
endpoint,
(error, rsp) => {
if (!error) {
this.handlePublished(entity, topic, converter, converted, key, json[key]);
} else {
this.handlePublishError(entity, message, error);
}
}
);
// It's possible for devices to get out of sync when writing an attribute that's not reportable.
// So here we re-read the value after a specified timeout, this timeout could for example be the
// transition time of a color change or for forcing a state read for devices that don't
// automatically report a new state when set.
// When reporting is requested for a device (report: true in device-specific settings) we won't
// ever issue a read here, as we assume the device will properly report changes.
// Only do this when the retrieve_state option is enabled for this device.
const deviceSettings = settings.getDevice(entity.ID);
if (topic.type === 'set' && entity.type === 'device' &&
converted.hasOwnProperty('readAfterWriteTime') && deviceSettings && deviceSettings.retrieve_state) {
const getConvertedResults = converter.convert(key, json[key], json, 'get', '', options);
getConvertedResults.forEach((getConverted) => {
setTimeout(() => {
this.zigbee.publish(
entity.ID, entity.type, getConverted.cid, getConverted.cmd, getConverted.cmdType,
getConverted.zclData, getConverted.cfg, endpoint, () => {}
);
}, converted.readAfterWriteTime);
});
}
usedConverters.push(converter);
});
});
return true;
}
}
module.exports = DevicePublish;
-212
View File
@@ -1,212 +0,0 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const utils = require('../util/utils');
const debounce = require('debounce');
/**
* This extensions handles messages received from devices.
*/
class DeviceReceive {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
this.coordinator = null;
this.elapsed = {};
this.debouncers = {};
}
onZigbeeStarted() {
this.coordinator = this.zigbee.getCoordinator().device.ieeeAddr;
}
publishDebounce(ieeeAddr, payload, time) {
if (!this.debouncers[ieeeAddr]) {
this.debouncers[ieeeAddr] = {
payload: {},
publish: debounce(() => {
this.publishEntityState(ieeeAddr, this.debouncers[ieeeAddr].payload);
this.debouncers[ieeeAddr].payload = {};
}, time * 1000),
};
}
this.debouncers[ieeeAddr].payload = {...this.debouncers[ieeeAddr].payload, ...payload};
this.debouncers[ieeeAddr].publish();
}
onZigbeeMessage(message, device, mappedDevice) {
if (message.type == 'devInterview') {
if (!settings.getDevice(message.data)) {
logger.info('Connecting with device...');
this.mqtt.log('pairing', 'connecting with device');
}
return;
}
if (message.type == 'devIncoming') {
logger.info('Device incoming...');
this.mqtt.log('pairing', 'device incoming');
}
if (!device) {
logger.warn('Message without device!');
return;
}
if (device.ieeeAddr === this.coordinator) {
logger.debug('Ignoring message from coordinator');
return;
}
// Check if this is a new device.
const settingsDevice = settings.getDevice(device.ieeeAddr);
if (!settingsDevice) {
logger.info(`New device '${device.modelId}' with address ${device.ieeeAddr} connected!`);
settings.addDevice(device.ieeeAddr);
this.mqtt.log('device_connected', device.ieeeAddr, {modelID: device.modelId});
}
if (!mappedDevice) {
logger.warn(`Device with modelID '${device.modelId}' is not supported.`);
logger.warn(`Please see: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html`);
return;
}
// After this point we cant handle message withoud cid or cmdId anymore.
if (!message.data || (!message.data.cid && !message.data.cmdId)) {
return;
}
/**
* Don't handle re-transmitted Xiaomi messages.
* https://github.com/Koenkk/zigbee2mqtt/issues/1238
*
* Some Xiaomi router devices re-transmit messages from Xiaomi end devices.
* The source address of these message is set to the one of the Xiaomi router.
* Therefore it looks like if the message came from the Xiaomi router, while in
* fact it came from the end device.
* Handling these message would result in false state updates.
* The group ID attribute of these message defines the source address of the end device.
* As the same message is also received directly from the end device, it makes no sense
* to handle these messages.
*/
const hasGroupID = message.hasOwnProperty('groupid') && message.groupid != 0;
if (utils.isXiaomiDevice(device) && utils.isRouter(device) && hasGroupID) {
logger.debug('Skipping re-transmitted Xiaomi message');
return;
}
// Find a conveter for this message.
const cid = message.data.cid;
const cmdId = message.data.cmdId;
const converters = mappedDevice.fromZigbee.filter((c) => {
if (cid) {
// readRsp messages have the same structure as attReport messages.
// search for attReport converters on readRsp.
if (c.cid === cid) {
if (c.type instanceof Array) {
return c.type.includes(message.type);
} else {
return c.type === message.type;
}
}
return false;
} else if (cmdId) {
return c.cmd === cmdId;
}
return false;
});
// Check if there is an available converter
if (!converters.length) {
if (cid) {
// Don't log readRsp messages, they are not interesting most of the time.
if (message.type === 'readRsp') {
return;
}
logger.warn(
`No converter available for '${mappedDevice.model}' with cid '${cid}', ` +
`type '${message.type}' and data '${JSON.stringify(message.data)}'`
);
} else if (cmdId) {
logger.warn(
`No converter available for '${mappedDevice.model}' with cmd '${cmdId}' ` +
`and data '${JSON.stringify(message.data)}'`
);
}
logger.warn(`Please see: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html.`);
return;
}
// Convert this Zigbee message to a MQTT message.
// Get payload for the message.
// - If a payload is returned publish it to the MQTT broker
// - If NO payload is returned do nothing. This is for non-standard behaviour
// for e.g. click switches where we need to count number of clicks and detect long presses.
const publish = (payload) => {
// Add device linkquality.
if (message.hasOwnProperty('linkquality')) {
payload.linkquality = message.linkquality;
}
// Add last seen timestamp
const now = Date.now();
if (settings.get().advanced.last_seen !== 'disable') {
payload.last_seen = utils.formatDate(now, settings.get().advanced.last_seen);
}
if (settings.get().advanced.elapsed) {
if (this.elapsed[device.ieeeAddr]) {
payload.elapsed = now - this.elapsed[device.ieeeAddr];
}
this.elapsed[device.ieeeAddr] = now;
}
// Check if we have to debounce
if (settingsDevice && settingsDevice.hasOwnProperty('debounce')) {
this.publishDebounce(device.ieeeAddr, payload, settingsDevice.debounce);
} else {
this.publishEntityState(device.ieeeAddr, payload);
if (settings.get().homeassistant) {
/**
* Publish an empty value for click and action payload, in this way Home Assistant
* can use Home Assistant entities in automations.
* https://github.com/Koenkk/zigbee2mqtt/issues/959#issuecomment-480341347
*/
Object.keys(payload).forEach((key) => {
if (['action', 'click'].includes(key)) {
const counterPayload = {};
counterPayload[key] = '';
this.publishEntityState(device.ieeeAddr, counterPayload);
}
});
}
}
};
let payload = {};
converters.forEach((converter) => {
const options = {...settings.get().device_options, ...settings.getDevice(device.ieeeAddr)};
const converted = converter.convert(mappedDevice, message, publish, options);
if (converted) {
payload = {...payload, ...converted};
}
});
if (Object.keys(payload).length) {
publish(payload);
}
}
}
module.exports = DeviceReceive;
-120
View File
@@ -1,120 +0,0 @@
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
const logger = require('../util/logger');
const CC2530Router = zigbeeShepherdConverters.devices.find((d) => d.model === 'CC2530.ROUTER');
const utils = require('../util/utils');
const candidates = {
'genOnOff': {
attrs: ['onOff'],
reportIntervalMin: 3,
reportIntervalMax: 300,
reportableChange: 0,
},
'genLevelCtrl': {
attrs: ['currentLevel'],
},
'lightingColorCtrl': {
attrs: ['colorTemperature', 'currentX', 'currentY'],
},
'closuresWindowCovering': {
attrs: ['currentPositionLiftPercentage', 'currentPositionTiltPercentage'],
reportIntervalMin: 2,
reportIntervalMax: 300,
},
};
const reportInterval = {
min: 3,
max: 3600,
};
const reportableChange = 1;
class DeviceReport {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
}
setupReporting(mappedDevice, device) {
let epId = null;
if (mappedDevice === CC2530Router) {
logger.debug('Not setting up reporting for CC2530 router');
return;
}
// Check if this device uses a different epId.
if (mappedDevice.hasOwnProperty('ep')) {
const eps = mappedDevice.ep(device);
epId = eps[''] || null;
}
const endpoint = this.zigbee.getEndpoint(device.ieeeAddr, epId);
if (!endpoint) {
logger.error(`Failed to setup reporting for ${device.ieeeAddr}, endpoint not found`);
return;
}
logger.debug(`Setting up reporting for ${device.ieeeAddr}`);
Object.values(endpoint.clusters).filter((c) => c).forEach((c) => {
const cluster = c.attrs.cid;
if (candidates[cluster]) {
const candidate = candidates[cluster];
let attributeNames = candidate.attrs.filter((a) => c.attrs.hasOwnProperty(a));
// Sometimes a cluster has no attributes, in this case setup reporting for all attributes.
attributeNames = attributeNames.length ? attributeNames : candidate.attrs;
const attributes = attributeNames.map((attribute) => {
return {
attr: attribute,
min: candidate.hasOwnProperty('reportIntervalMin')?
candidate.reportIntervalMin:reportInterval.min,
max: candidate.hasOwnProperty('reportIntervalMax')?
candidate.reportIntervalMax:reportInterval.max,
change: candidate.hasOwnProperty('reportableChange')?
candidate.reportableChange:reportableChange,
};
});
if (attributes.length > 0) {
this.zigbee.report(endpoint, cluster, attributes);
}
}
});
}
shouldSetupReporting(device) {
return utils.isRouter(device) && !utils.isBatteryPowered(device);
}
onZigbeeStarted() {
this.zigbee.getAllClients()
.filter((d) => this.shouldSetupReporting(d))
.forEach((device) => {
const mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
if (mappedDevice) {
this.setupReporting(mappedDevice, device);
}
});
}
onZigbeeMessage(message, device, mappedDevice) {
// Handle messages of type endDeviceAnnce and devIncoming.
// This message is typically send when a device comes online after being powered off
// Ikea TRADFRI tend to forget their reporting after powered off.
// Re-setup reporting.
// https://github.com/Koenkk/zigbee2mqtt/issues/966
if (device && mappedDevice && ['endDeviceAnnce', 'devIncoming'].includes(message.type) &&
this.shouldSetupReporting(device)) {
this.setupReporting(mappedDevice, device);
}
}
}
module.exports = DeviceReport;
@@ -1,8 +1,4 @@
/**
* This extensions is for documentation purposes only.
* It describes all methods that are called by the controller.
*/
class ExtensionTemplate {
class Extension {
/**
* Besides intializing variables, the constructor should do nothing!
*
@@ -10,31 +6,34 @@ class ExtensionTemplate {
* @param {MQTT} mqtt MQTT controller
* @param {State} state State controller
* @param {Function} publishEntityState Method to publish device state to MQTT.
* @param {EventBus} eventBus The event bus
*/
constructor(zigbee, mqtt, state, publishEntityState) {
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
this.eventBus = eventBus;
}
/**
* This method is called by the controller once Zigbee has been started.
*/
onZigbeeStarted() {}
// onZigbeeStarted() {}
/**
* This method is called by the controller once connected to the MQTT server.
*/
onMQTTConnected() {}
// onMQTTConnected() {}
/**
* Is called when a Zigbee message from a device is received.
* @param {Object?} message The received message (can be null)
* @param {Object?} device The device of the message (can be null)
* @param {Object?} mappedDevice The mapped device (can be null)
* @param {string} type Type of the message
* @param {Object} data Data of the message
* @param {Object?} resolvedEntity Resolved entity returned from this.zigbee.resolveEntityLegacy()
* @param {Object?} settingsDevice Device settings
*/
onZigbeeMessage(message, device, mappedDevice) {}
// onZigbeeEvent(type, data, resolvedEntity) {}
/**
* Is called when a MQTT message is received
@@ -42,14 +41,14 @@ class ExtensionTemplate {
* @param {Object} message The received message
* @return {boolean} if the message was handled
*/
onMQTTMessage(topic, message) {
return false;
}
// onMQTTMessage(topic, message) {}
/**
* Is called once the extension has to stop
*/
stop() {}
stop() {
this.eventBus.removeListeners(this.constructor.name);
}
}
module.exports = ExtensionTemplate;
module.exports = Extension;
+51
View File
@@ -0,0 +1,51 @@
// TODO: tempState -> State, rename to extension
abstract class ExtensionTS {
protected zigbee: Zigbee;
protected mqtt: MQTT;
protected state: TempState;
protected publishEntityState: PublishEntityState;
protected eventBus: EventBus;
protected enableDisableExtension: (enable: boolean, name: string) => Promise<void>;
protected restartCallback: () => void;
protected addExtension: (extension: ExternalConverterClass) => void;
/**
* Besides intializing variables, the constructor should do nothing!
*
* @param {Zigbee} zigbee Zigbee controller
* @param {MQTT} mqtt MQTT controller
* @param {State} state State controller
* @param {Function} publishEntityState Method to publish device state to MQTT.
* @param {EventBus} eventBus The event bus
* @param {enableDisableExtension} enableDisableExtension Enable/disable extension method
* @param {restartCallback} restartCallback Restart Zigbee2MQTT
* @param {addExtension} addExtension Add an extension
*/
constructor(zigbee: Zigbee, mqtt: MQTT, state: TempState, publishEntityState: PublishEntityState,
eventBus: EventBus, enableDisableExtension: (enable: boolean, name: string) => Promise<void>,
restartCallback: () => void, addExtension: (extension: ExternalConverterClass) => void) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
this.eventBus = eventBus;
this.enableDisableExtension = enableDisableExtension;
this.restartCallback = restartCallback;
this.addExtension = addExtension;
}
/**
* Is called once the extension has to start
*/
/* istanbul ignore next */
async start(): Promise<void> {}
/**
* Is called once the extension has to stop
*/
async stop(): Promise<void> {
this.eventBus.removeListeners(this);
}
}
export default ExtensionTS;
+17
View File
@@ -0,0 +1,17 @@
// @ts-ignore
import zhc from 'zigbee-herdsman-converters';
import * as settings from '../util/settings';
import * as utils from '../util/utils';
import ExtensionTS from './extensionts';
class ExternalConverters extends ExtensionTS {
override async start(): Promise<void> {
for (const definition of utils.getExternalConvertersDefinitions(settings)) {
const toAdd = {...definition};
delete toAdd['homeassistant'];
zhc.addDeviceDefinition(toAdd);
}
}
}
module.exports = ExternalConverters;
+111
View File
@@ -0,0 +1,111 @@
import * as settings from '../util/settings';
import * as utils from '../util/utils';
import fs from 'fs';
import * as data from './../util/data';
import path from 'path';
import logger from './../util/logger';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
import bind from 'bind-decorator';
import ExtensionTS from './extensionts';
const requestRegex = new RegExp(`${settings.get().mqtt.base_topic}/bridge/request/extension/(save|remove)`);
class ExternalExtension extends ExtensionTS {
private requestLookup: {[s: string]: (message: KeyValue) => MQTTResponse};
override async start(): Promise<void> {
this.eventBus.onMQTTMessage(this, this.onMQTTMessage_);
this.requestLookup = {'save': this.saveExtension, 'remove': this.removeExtension};
this.loadUserDefinedExtensions();
await this.publishExtensions();
}
private getExtensionsBasePath(): string {
return data.joinPath('extension');
}
private getListOfUserDefinedExtensions(): {name: string, code: string}[] {
const basePath = this.getExtensionsBasePath();
if (fs.existsSync(basePath)) {
return fs.readdirSync(basePath).filter((f) => f.endsWith('.js')).map((fileName) => {
const extensonFilePath = path.join(basePath, fileName);
return {'name': fileName, 'code': fs.readFileSync(extensonFilePath, 'utf-8')};
});
} else {
return [];
}
}
@bind private removeExtension(message: KeyValue): MQTTResponse {
const {name} = message;
const extensions = this.getListOfUserDefinedExtensions();
const extensionToBeRemoved = extensions.find((e) => e.name === name);
if (extensionToBeRemoved) {
this.enableDisableExtension(false, extensionToBeRemoved.name);
const basePath = this.getExtensionsBasePath();
const extensionFilePath = path.join(basePath, path.basename(name));
fs.unlinkSync(extensionFilePath);
this.publishExtensions();
logger.info(`Extension ${name} removed`);
return utils.getResponse(message, {}, null);
} else {
return utils.getResponse(message, {}, `Extension ${name} doesn't exists`);
}
}
@bind private saveExtension(message: KeyValue): MQTTResponse {
const {name, code} = message;
const ModuleConstructor = utils.loadModuleFromText(code) as ExternalConverterClass;
this.loadExtension(ModuleConstructor);
const basePath = this.getExtensionsBasePath();
/* istanbul ignore else */
if (!fs.existsSync(basePath)) {
fs.mkdirSync(basePath);
}
const extensonFilePath = path.join(basePath, path.basename(name));
fs.writeFileSync(extensonFilePath, code);
this.publishExtensions();
logger.info(`Extension ${name} loaded`);
return utils.getResponse(message, {}, null);
}
@bind async onMQTTMessage_(data: EventMQTTMessage): Promise<void> {
const match = data.topic.match(requestRegex);
if (match && this.requestLookup[match[1].toLowerCase()]) {
const message = utils.parseJSON(data.message, data.message) as KeyValue;
try {
const response = this.requestLookup[match[1].toLowerCase()](message);
await this.mqtt.publish(`bridge/response/extension/${match[1]}`, stringify(response));
} catch (error) {
logger.error(`Request '${data.topic}' failed with error: '${error.message}'`);
const response = utils.getResponse(message, {}, error.message);
await this.mqtt.publish(`bridge/response/extension/${match[1]}`, stringify(response));
}
}
}
@bind private loadExtension(ConstructorClass: ExternalConverterClass): void {
this.enableDisableExtension(false, ConstructorClass.name);
this.addExtension(new ConstructorClass(
this.zigbee, this.mqtt, this.state, this.publishEntityState, this.eventBus, settings, logger));
}
private loadUserDefinedExtensions(): void {
const extensions = this.getListOfUserDefinedExtensions();
extensions
.map(({code}) => utils.loadModuleFromText(code))
.map(this.loadExtension);
}
private async publishExtensions(): Promise<void> {
const extensions = this.getListOfUserDefinedExtensions();
await this.mqtt.publish('bridge/extensions', stringify(extensions), {
retain: true,
qos: 0,
}, settings.get().mqtt.base_topic, true);
}
}
module.exports = ExternalExtension;
+143
View File
@@ -0,0 +1,143 @@
import http from 'http';
import serveStatic from 'serve-static';
import finalhandler from 'finalhandler';
import logger from '../util/logger';
// @ts-ignore
import frontend from 'zigbee2mqtt-frontend';
import WebSocket from 'ws';
import net from 'net';
import url from 'url';
import * as settings from '../util/settings';
import * as utils from '../util/utils';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
import ExtensionTS from './extensionts';
import bind from 'bind-decorator';
/**
* This extension servers the frontend
*/
class Frontend extends ExtensionTS {
private mqttBaseTopic = settings.get().mqtt.base_topic;
private host = settings.get().frontend.host || '0.0.0.0';
private port = settings.get().frontend.port || 8080;
private authToken = settings.get().frontend.auth_token || false;
private retainedMessages = new Map();
private server: http.Server;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private fileServer: serveStatic.RequestHandler<any>;
private wss: WebSocket.Server = null;
constructor(zigbee: Zigbee, mqtt: MQTT, state: TempState, publishEntityState: PublishEntityState,
eventBus: EventBus, enableDisableExtension: (enable: boolean, name: string) => Promise<void>,
restartCallback: () => void, addExtension: (extension: ExternalConverterClass) => void) {
super(zigbee, mqtt, state, publishEntityState, eventBus, enableDisableExtension, restartCallback, addExtension);
this.eventBus.onMQTTMessagePublished(this, this.onMQTTPublishMessage);
}
override async start(): Promise<void> {
this.server = http.createServer(this.onRequest);
this.server.on('upgrade', this.onUpgrade);
/* istanbul ignore next */ // eslint-disable-next-line @typescript-eslint/no-explicit-any
const options = {setHeaders: (res: any, path: any): void => {
if (path.endsWith('index.html')) {
res.setHeader('Cache-Control', 'no-store');
}
}};
this.fileServer = serveStatic(frontend.getPath(), options);
this.wss = new WebSocket.Server({noServer: true});
this.wss.on('connection', this.onWebSocketConnection);
this.server.listen(this.port, this.host);
logger.info(`Started frontend on port ${this.host}:${this.port}`);
}
override async stop(): Promise<void> {
super.stop();
for (const client of this.wss.clients) {
client.send(stringify({topic: 'bridge/state', payload: 'offline'}));
client.terminate();
}
this.wss.close();
return new Promise((cb: () => void) => this.server.close(cb));
}
@bind private onRequest(request: http.IncomingMessage, response: http.ServerResponse): void {
// @ts-ignore
this.fileServer(request, response, finalhandler(request, response));
}
private authenticate(request: http.IncomingMessage, cb: (authenticate: boolean) => void): void {
const {query} = url.parse(request.url, true);
cb(!this.authToken || this.authToken === query.token);
}
@bind private onUpgrade(request: http.IncomingMessage, socket: net.Socket, head: Buffer): void {
this.wss.handleUpgrade(request, socket, head, (ws) => {
this.authenticate(request, (isAuthentificated) => {
if (isAuthentificated) {
this.wss.emit('connection', ws, request);
} else {
ws.close(4401, 'Unauthorized');
}
});
});
}
@bind private onWebSocketConnection(ws: WebSocket): void {
ws.on('message', (data: Buffer, isBinary: boolean) => {
if (!isBinary && data) {
const message = data.toString();
const {topic, payload} = JSON.parse(message);
this.mqtt.onMessage(`${this.mqttBaseTopic}/${topic}`, stringify(payload));
}
});
for (const [key, value] of this.retainedMessages) {
ws.send(stringify({topic: key, payload: value}));
}
for (const device of this.zigbee.getClients()) {
let payload: KeyValue = {};
if (this.state.exists(device.ieeeAddr)) {
payload = {...payload, ...this.state.get(device.ieeeAddr)};
}
const lastSeen = settings.get().advanced.last_seen;
/* istanbul ignore if */
if (lastSeen !== 'disable') {
payload.last_seen = utils.formatDate(device.lastSeen, lastSeen);
}
if (device.zhDevice.linkquality !== undefined) {
payload.linkquality = device.zhDevice.linkquality;
}
ws.send(stringify({topic: device.name, payload}));
}
}
@bind private onMQTTPublishMessage(data: EventMQTTMessagePublished): void {
if (data.topic.startsWith(`${this.mqttBaseTopic}/`)) {
// Send topic without base_topic
const topic = data.topic.substring(this.mqttBaseTopic.length + 1);
const payload = utils.parseJSON(data.payload, data.payload);
if (data.options.retain) {
this.retainedMessages.set(topic, payload);
}
if (this.wss) {
for (const client of this.wss.clients) {
/* istanbul ignore else */
if (client.readyState === WebSocket.OPEN) {
client.send(stringify({topic, payload}));
}
}
}
}
}
}
module.exports = Frontend;
+351 -215
View File
@@ -1,241 +1,377 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const data = require('../util/data');
const Extension = require('./extension');
const utils = require('../util/utils');
const fs = require('fs');
const diff = require('deep-diff');
const stringify = require('json-stable-stringify-without-jsonify');
const equals = require('fast-deep-equal/es6');
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/group/.+/(remove|add|remove_all)$`);
const topicRegexRemoveAll = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/group/(remove|add|remove_all)$`);
const topicRegex =
new RegExp(`^${settings.get().mqtt.base_topic}/bridge/request/group/members/(remove|add|remove_all)$`);
const legacyTopicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/group/(.+)/(remove|add|remove_all)$`);
const legacyTopicRegexRemoveAll = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/group/remove_all$`);
class Groups {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
const stateProperties = {
'state': (value, definition) => true,
'brightness': (value, definition) =>
definition.exposes.find((e) => e.type === 'light' && e.features.find((f) => f.name === 'brightness')),
'color_temp': (value, definition) =>
definition.exposes.find((e) => e.type === 'light' && e.features.find((f) => f.name === 'color_temp')),
'color': (value, definition) =>
definition.exposes.find((e) => e.type === 'light' &&
e.features.find((f) => f.name === 'color_xy' || f.name === 'color_hs')),
'color_mode': (value, definition) =>
definition.exposes.find((e) => e.type === 'light' && (
(e.features.find((f) => f.name === `color_${value}`)) ||
(value === 'color_temp' && e.features.find((f) => f.name === 'color_temp')) )),
};
class Groups extends Extension {
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
super(zigbee, mqtt, state, publishEntityState, eventBus);
this.onStateChange = this.onStateChange.bind(this);
this.groupsCacheFile = data.joinPathStorage('groups_cache.json');
this.groupsCache = this.readGroupsCache();
this.legacyApi = settings.get().advanced.legacy_api;
this.lastOptimisticState = {};
}
readGroupsCache() {
return fs.existsSync(this.groupsCacheFile) ? JSON.parse(fs.readFileSync(this.groupsCacheFile, 'utf8')) : {};
async onZigbeeStarted() {
this.eventBus.on('stateChange', this.onStateChange, this.constructor.name);
await this.syncGroupsWithSettings();
}
writeGroupsCache() {
fs.writeFileSync(this.groupsCacheFile, JSON.stringify(this.groupsCache), 'utf8');
}
async syncGroupsWithSettings() {
const settingsGroups = settings.getGroups();
const zigbeeGroups = this.zigbee.getGroupsLegacy();
onMQTTConnected() {
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/group/+/remove`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/group/+/add`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/group/+/remove_all`);
this.mqtt.subscribe(`${settings.get().mqtt.base_topic}/bridge/group/remove_all`);
}
apply(from, to) {
const sortGroups = (obj) => Object.keys(obj).forEach((key) => obj[key] = obj[key].sort());
sortGroups(from);
sortGroups(to);
const differences = diff(from, to);
if (differences) {
differences.forEach((diff) => {
const groupID = diff.path[0];
if (diff.kind === 'N') {
diff.rhs.forEach((ID) => this.updateDeviceGroup(ID, 'add', groupID));
} else if (diff.kind === 'A') {
if (diff.item.lhs) {
this.updateDeviceGroup(diff.item.lhs, 'remove', groupID);
} else {
this.updateDeviceGroup(diff.item.rhs, 'add', groupID);
}
} else if (diff.kind === 'D') {
diff.lhs.forEach((ID) => this.updateDeviceGroup(ID, 'remove', groupID));
} else if (diff.kind === 'E') {
this.updateDeviceGroup(diff.rhs, 'add', groupID);
this.updateDeviceGroup(diff.lhs, 'remove', groupID);
}
});
}
}
parseID(ID) {
let entityID = ID;
let endpointID = null;
const postfix = utils.getPostfixes().find((p) => entityID.endsWith(`/${p}`));
if (postfix) {
// Found a postfix, retrieve the endpoint which correspodns to the postfix
entityID = entityID.substring(0, entityID.length - (postfix.length + 1));
const endpoint = utils.getEndpointByEntityID(this.zigbee, entityID, postfix);
if (!endpoint) {
return;
}
endpointID = endpoint.epId;
}
return {endpointID, entityID};
}
getGroupsOfDevice(entityID) {
return Object.keys(settings.getGroups()).filter((groupID) => {
return settings.getGroup(groupID).devices.includes(entityID);
});
}
onStateChange(ieeeAddr, from, to) {
const properties = ['state', 'brightness', 'color_temp', 'color'];
const payload = {};
properties.forEach((prop) => {
if (to.hasOwnProperty(prop) && (!from || from[prop] != to[prop])) {
payload[prop] = to[prop];
}
});
if (Object.keys(payload)) {
const groups = this.getGroupsOfDevice(ieeeAddr);
groups.forEach((groupID) => {
this.publishEntityState(groupID, payload);
});
}
}
onZigbeeStarted() {
this.state.registerOnStateChangeListener(this.onStateChange);
const settingsGroups = {};
Object.keys(settings.getGroups()).forEach((groupID) => {
settingsGroups[groupID] = settings.getGroup(groupID).devices;
});
this.apply(this.groupsCache, settingsGroups);
}
parseTopic(topic) {
if (!topic.match(topicRegex) && !topic.match(topicRegexRemoveAll)) {
return null;
}
// Remove base from topic
topic = topic.replace(`${settings.get().mqtt.base_topic}/bridge/group/`, '');
// Parse type from topic
const type = topic.substr(topic.lastIndexOf('/') + 1, topic.length);
// Remove type from topic
topic = topic.replace(`/${type}`, '');
return {friendly_name: type === 'remove_all' ? null : topic, type};
}
updateDeviceGroup(ID, cmd, groupID) {
let payload = null;
if (cmd === 'add') {
payload = {groupid: groupID, groupname: ''};
cmd = 'add';
} else if (cmd === 'remove') {
payload = {groupid: groupID};
cmd = 'remove';
} else if (cmd === 'remove_all') {
payload = {};
cmd = 'removeAll';
}
const {entityID, endpointID} = this.parseID(ID);
const ieeeAddr = settings.resolveEntity(entityID).ID;
const cb = (error, rsp) => {
if (error) {
logger.error(`Failed to ${cmd} ${ieeeAddr} from ${groupID}`);
} else {
logger.info(`Successfully ${cmd} ${ieeeAddr} to ${groupID}`);
// Log to MQTT
const lookup = {
'add': 'device_group_add',
'remove': 'device_group_remove',
'removeAll': 'device_group_remove_all',
};
this.mqtt.log({
type: lookup[cmd],
message: {
device: settings.getDevice(ieeeAddr).friendly_name,
group: groupID,
},
});
// Update group cache
if (cmd === 'add') {
if (!this.groupsCache[groupID]) {
this.groupsCache[groupID] = [];
}
if (!this.groupsCache[groupID].includes(ieeeAddr)) {
this.groupsCache[groupID].push(ieeeAddr);
}
} else if (cmd === 'remove') {
if (this.groupsCache[groupID]) {
this.groupsCache[groupID] = this.groupsCache[groupID].filter((device) => device != ieeeAddr);
}
} else if (cmd === 'removeAll') {
Object.keys(this.groupsCache).forEach((groupID_) => {
this.groupsCache[groupID_] = this.groupsCache[groupID_].filter((device) => device != ieeeAddr);
});
}
this.writeGroupsCache();
// Update settings
if (cmd === 'add') {
settings.addDeviceToGroup(groupID, ieeeAddr);
} else if (cmd === 'remove') {
settings.removeDeviceFromGroup(groupID, ieeeAddr);
} else if (cmd === 'removeAll') {
Object.keys(settings.get().groups).forEach((groupID_) => {
settings.removeDeviceFromGroup(groupID_, ieeeAddr);
});
const addRemoveFromGroup = async (action, deviceName, groupName, endpoint, group) => {
try {
logger.info(`${action === 'add' ? 'Adding' : 'Removing'} '${deviceName}' to group '${groupName}'`);
if (action === 'remove') {
await endpoint.removeFromGroup(group);
} else {
await endpoint.addToGroup(group);
}
} catch (error) {
logger.error(`Failed to ${action} '${deviceName}' from '${groupName}'`);
logger.debug(error.stack);
}
};
this.zigbee.publish(
ieeeAddr, 'device', 'genGroups', cmd, 'functional',
payload, null, endpointID, cb,
);
}
for (const settingGroup of settingsGroups) {
const groupID = settingGroup.ID;
const zigbeeGroup = zigbeeGroups.find((g) =>
g.groupID === groupID) || this.zigbee.createGroupLegacy(groupID);
const settingsEntity = settingGroup.devices.map((d) => {
const entity = this.zigbee.resolveEntityLegacy(d);
if (!entity) logger.error(`Cannot find '${d}' of group '${settingGroup.friendlyName}'`);
return entity;
}).filter((e) => e != null);
onMQTTMessage(topic, message) {
topic = this.parseTopic(topic);
if (!topic) {
return false;
}
// Find ID of this group.
let groupID = null;
if (topic.type !== 'remove_all') {
groupID = settings.getGroupIDByFriendlyName(topic.friendly_name);
if (!groupID) {
logger.error(`Group with friendly_name '${topic.friendly_name}' doesn't exist`);
return;
// In settings but not in zigbee
for (const entity of settingsEntity) {
if (!zigbeeGroup.hasMember(entity.endpoint)) {
addRemoveFromGroup('add', entity.name, settingGroup.friendlyName, entity.endpoint, zigbeeGroup);
}
}
groupID = groupID.toString();
// In zigbee but not in settings
for (const endpoint of zigbeeGroup.members) {
if (!settingsEntity.find((e) => e.endpoint === endpoint)) {
const deviceName = settings.getDevice(endpoint.getDevice().ieeeAddr).friendlyName;
addRemoveFromGroup('remove', deviceName, settingGroup.friendlyName, endpoint, zigbeeGroup);
}
}
}
// Send command to the device.
this.updateDeviceGroup(message.toString(), topic.type, groupID);
for (const zigbeeGroup of zigbeeGroups) {
if (!settingsGroups.find((g) => g.ID === zigbeeGroup.groupID)) {
for (const endpoint of zigbeeGroup.members) {
const deviceName = settings.getDevice(endpoint.getDevice().ieeeAddr).friendlyName;
addRemoveFromGroup('remove', deviceName, zigbeeGroup.groupID, endpoint, zigbeeGroup);
}
}
}
}
async onStateChange(data) {
const reason = 'group_optimistic';
if (data.reason === reason) {
return;
}
const payload = {};
let endpointName;
for (let [prop, value] of Object.entries(data.update)) {
const endpointNameMatch = utils.endpointNames.find((n) => prop.endsWith(`_${n}`));
if (endpointNameMatch) {
prop = prop.substring(0, prop.length - endpointNameMatch.length - 1);
endpointName = endpointNameMatch;
}
if (prop in stateProperties) {
payload[prop] = value;
}
}
if (Object.keys(payload).length) {
const resolvedEntity =
this.zigbee.resolveEntityLegacy(`${data.ID}${endpointName ? `/${endpointName}` : ''}`);
const zigbeeGroups = this.zigbee.getGroupsLegacy().filter((zigbeeGroup) => {
const settingsGroup = settings.getGroup(zigbeeGroup.groupID);
return settingsGroup && (!settingsGroup.hasOwnProperty('optimistic') || settingsGroup.optimistic);
});
if (resolvedEntity.type === 'device') {
for (const zigbeeGroup of zigbeeGroups) {
if (zigbeeGroup.hasMember(resolvedEntity.endpoint) &&
!equals(this.lastOptimisticState[zigbeeGroup.groupID], payload)) {
if (!payload || payload.state !== 'OFF' || this.areAllMembersOff(zigbeeGroup)) {
this.lastOptimisticState[zigbeeGroup.groupID] = payload;
await this.publishEntityState(zigbeeGroup.groupID, payload, reason);
}
}
}
} else {
// Invalidate the last optimistic group state when group state is changed directly.
delete this.lastOptimisticState[resolvedEntity.group.groupID];
const groupIDsToPublish = new Set();
for (const member of resolvedEntity.group.members) {
const resolvedEntity = this.zigbee.resolveEntityLegacy(member);
const memberPayload = {};
Object.keys(payload).forEach((key) => {
if (stateProperties[key](payload[key], resolvedEntity.definition)) {
memberPayload[key] = payload[key];
}
});
const endpointName = resolvedEntity.endpointName;
if (endpointName) {
Object.keys(memberPayload).forEach((key) => {
memberPayload[`${key}_${endpointName}`] = memberPayload[key];
delete memberPayload[key];
});
}
await this.publishEntityState(member.getDevice().ieeeAddr, memberPayload, reason);
for (const zigbeeGroup of zigbeeGroups) {
if (zigbeeGroup.hasMember(member)) {
if (!payload || payload.state !== 'OFF' || this.areAllMembersOff(zigbeeGroup)) {
groupIDsToPublish.add(zigbeeGroup.groupID);
}
}
}
}
groupIDsToPublish.delete(resolvedEntity.group.groupID);
for (const groupID of groupIDsToPublish) {
await this.publishEntityState(groupID, payload, reason);
}
}
}
}
areAllMembersOff(zigbeeGroup) {
for (const member of zigbeeGroup.members) {
const device = member.getDevice();
if (this.state.exists(device.ieeeAddr)) {
const state = this.state.get(device.ieeeAddr);
if (state && state.state === 'ON') {
return false;
}
}
}
return true;
}
parseMQTTMessage(topic, message) {
let type = null;
let resolvedEntityGroup = null;
let resolvedEntityDevice = null;
let hasEndpointName = null;
let error = null;
let groupKey = null;
let deviceKey = null;
let triggeredViaLegacyApi = false;
let skipDisableReporting = false;
/* istanbul ignore else */
const topicRegexMatch = topic.match(topicRegex);
const legacyTopicRegexRemoveAllMatch = topic.match(legacyTopicRegexRemoveAll);
const legacyTopicRegexMatch = topic.match(legacyTopicRegex);
if (this.legacyApi && (legacyTopicRegexMatch || legacyTopicRegexRemoveAllMatch)) {
triggeredViaLegacyApi = true;
if (legacyTopicRegexMatch) {
resolvedEntityGroup = this.zigbee.resolveEntityLegacy(legacyTopicRegexMatch[1]);
type = legacyTopicRegexMatch[2];
if (!resolvedEntityGroup || resolvedEntityGroup.type !== 'group') {
logger.error(`Group '${legacyTopicRegexMatch[1]}' does not exist`);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {
friendly_name: message, group: legacyTopicRegexMatch[1], error: 'group doesn\'t exists',
};
this.mqtt.publish(
'bridge/log',
stringify({type: `device_group_${type}_failed`, message: payload}),
);
}
return {};
}
} else {
type = 'remove_all';
}
resolvedEntityDevice = this.zigbee.resolveEntityLegacy(message);
if (!resolvedEntityDevice || !resolvedEntityDevice.type === 'device') {
logger.error(`Device '${message}' does not exist`);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {
friendly_name: message, group: legacyTopicRegexMatch[1], error: 'entity doesn\'t exists',
};
this.mqtt.publish(
'bridge/log',
stringify({type: `device_group_${type}_failed`, message: payload}),
);
}
return {};
}
hasEndpointName = utils.endpointNames.find((p) => message.endsWith(`/${p}`));
} else if (topicRegexMatch) {
type = topicRegexMatch[1];
message = JSON.parse(message);
deviceKey = message.device;
skipDisableReporting = 'skip_disable_reporting' in message ? message.skip_disable_reporting : false;
if (type !== 'remove_all') {
groupKey = message.group;
resolvedEntityGroup = this.zigbee.resolveEntityLegacy(message.group);
if (!resolvedEntityGroup || resolvedEntityGroup.type !== 'group') {
error = `Group '${message.group}' does not exist`;
}
}
resolvedEntityDevice = this.zigbee.resolveEntityLegacy(message.device);
if (!error && (!resolvedEntityDevice || !resolvedEntityDevice.type === 'device')) {
error = `Device '${message.device}' does not exist`;
}
hasEndpointName = utils.endpointNames.find((p) => message.device.endsWith(`/${p}`));
}
return {
resolvedEntityGroup, resolvedEntityDevice, type, hasEndpointName, error, groupKey, deviceKey,
triggeredViaLegacyApi, skipDisableReporting,
};
}
async onMQTTMessage(topic, message) {
let {
resolvedEntityGroup, resolvedEntityDevice, type, hasEndpointName, error, triggeredViaLegacyApi,
groupKey, deviceKey, skipDisableReporting,
} = this.parseMQTTMessage(topic, message);
if (!type) return;
message = utils.parseJSON(message, message);
const responseData = {device: deviceKey};
if (groupKey) {
responseData.group = groupKey;
}
if (!error) {
try {
const keys = [
`${resolvedEntityDevice.device.ieeeAddr}/${resolvedEntityDevice.endpoint.ID}`,
`${resolvedEntityDevice.name}/${resolvedEntityDevice.endpoint.ID}`,
];
const definition = resolvedEntityDevice.definition;
const endpoints = definition && definition.endpoint ?
definition.endpoint(resolvedEntityDevice.device) : null;
let endpointName = null;
if (endpoints) {
const matches = Object.entries(endpoints).find((e) => e[1] === resolvedEntityDevice.endpoint.ID);
endpointName = matches && matches[0];
}
if (endpointName) {
keys.push(`${resolvedEntityDevice.device.ieeeAddr}/${endpointName}`);
keys.push(`${resolvedEntityDevice.name}/${endpointName}`);
}
if (!hasEndpointName) {
keys.push(resolvedEntityDevice.name);
keys.push(resolvedEntityDevice.device.ieeeAddr);
}
if (type === 'add') {
logger.info(`Adding '${resolvedEntityDevice.name}' to '${resolvedEntityGroup.name}'`);
await resolvedEntityDevice.endpoint.addToGroup(resolvedEntityGroup.group);
settings.addDeviceToGroup(resolvedEntityGroup.settings.ID, keys);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: resolvedEntityDevice.name, group: resolvedEntityGroup.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `device_group_add`, message: payload}),
);
}
} else if (type === 'remove') {
logger.info(`Removing '${resolvedEntityDevice.name}' from '${resolvedEntityGroup.name}'`);
await resolvedEntityDevice.endpoint.removeFromGroup(resolvedEntityGroup.group);
settings.removeDeviceFromGroup(resolvedEntityGroup.settings.ID, keys);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: resolvedEntityDevice.name, group: resolvedEntityGroup.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `device_group_remove`, message: payload}),
);
}
} else { // remove_all
logger.info(`Removing '${resolvedEntityDevice.name}' from all groups`);
await resolvedEntityDevice.endpoint.removeFromAllGroups();
for (const settingsGroup of settings.getGroups()) {
settings.removeDeviceFromGroup(settingsGroup.ID, keys);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const payload = {friendly_name: resolvedEntityDevice.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `device_group_remove_all`, message: payload}),
);
}
}
}
} catch (e) {
error = `Failed to ${type} from group (${e.message})`;
logger.debug(e.stack);
}
}
if (!triggeredViaLegacyApi) {
const response = utils.getResponse(message, responseData, error);
await this.mqtt.publish(`bridge/response/group/members/${type}`, stringify(response));
}
if (error) {
logger.error(error);
} else {
this.eventBus.emit('groupMembersChanged',
{group: resolvedEntityGroup, action: type, endpoint: resolvedEntityDevice.endpoint,
skipDisableReporting: skipDisableReporting});
}
}
}
module.exports = Groups;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+227
View File
@@ -0,0 +1,227 @@
const logger = require('../../util/logger');
const settings = require('../../util/settings');
const utils = require('../../util/utils');
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
const Extension = require('../extension');
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/(.*)/availability`);
// Pingable end devices, some end devices should be pinged
// e.g. E11-G13 https://github.com/Koenkk/zigbee2mqtt/issues/775#issuecomment-453683846
const pingableEndDevices = [
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'E11-G13'),
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'E11-N1EA'),
zigbeeHerdsmanConverters.devices.find((d) => d.model === '53170161'),
];
const Hours25 = 1000 * 60 * 60 * 25;
const AvailabilityLagRatio = 0.1;
function timeoutLag(timeout, ratio) {
const lag = timeout * ratio;
return Math.floor(Math.random() * Math.floor(lag));
}
/**
* This extensions pings devices to check if they are online.
*/
class AvailabilityLegacy extends Extension {
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
super(zigbee, mqtt, state, publishEntityState, eventBus);
this.availability_timeout = settings.get().advanced.availability_timeout;
this.timers = {};
this.state = {};
this.eventBus.on('deviceRemoved', (data) => this.onDeviceRemoved(data.resolvedEntity), this.constructor.name);
this.eventBus.on('deviceRenamed', (data) => this.onDeviceRenamed(data), this.constructor.name);
this.blocklist = settings.get().advanced.availability_blocklist
.concat(settings.get().advanced.availability_blacklist)
.map((e) => settings.getEntity(e).ID);
this.passlist = settings.get().advanced.availability_passlist
.concat(settings.get().advanced.availability_whitelist)
.map((e) => settings.getEntity(e).ID);
}
onDeviceRenamed(data) {
this.mqtt.publish(`${data.from}/availability`, null, {retain: true, qos: 0});
}
onDeviceRemoved(resolvedEntity) {
this.mqtt.publish(`${resolvedEntity.name}/availability`, null, {retain: true, qos: 0});
delete this.state[resolvedEntity.device.ieeeAddr];
clearTimeout(this.timers[resolvedEntity.device.ieeeAddr]);
}
inPasslistOrNotInBlocklist(device) {
const ieeeAddr = device.ieeeAddr;
const deviceSettings = settings.getDevice(ieeeAddr);
const name = deviceSettings && deviceSettings.friendlyName;
// Passlist is not empty and device is in it, enable availability
if (this.passlist.length > 0) {
return this.passlist.includes(ieeeAddr) || (name && this.passlist.includes(name));
}
// Device is on blocklist, disable availability
if (this.blocklist.includes(ieeeAddr) || (name && this.blocklist.includes(name))) {
return false;
}
return true;
}
isPingable(device) {
if (pingableEndDevices.find((d) => d.hasOwnProperty('zigbeeModel') && d.zigbeeModel.includes(device.modelID))) {
return true;
}
// Device is a mains powered router
return device.type === 'Router' && device.powerSource !== 'Battery';
}
onMQTTConnected() {
for (const device of this.zigbee.getClientsLegacy()) {
// Mark all devices as online on start
const ieeeAddr = device.ieeeAddr;
this.publishAvailability(device, this.state.hasOwnProperty(ieeeAddr) ? this.state[ieeeAddr] : true, true);
if (this.inPasslistOrNotInBlocklist(device)) {
if (this.isPingable(device)) {
this.setTimerPingable(device);
} else {
this.timers[ieeeAddr] = setInterval(() => {
this.handleIntervalNotPingable(device);
}, utils.seconds(300));
}
}
}
}
async onMQTTMessage(topic, message) {
// Clear topics for non-existing devices
const match = topic.match(topicRegex);
if (match && (!this.zigbee.resolveEntityLegacy(match[1]) ||
this.zigbee.resolveEntityLegacy(match[1]).name !== match[1])) {
this.mqtt.publish(`${match[1]}/availability`, null, {retain: true, qos: 0});
}
}
async handleIntervalPingable(device) {
// When a device is already unavailable, log the ping failed on 'debug' instead of 'error'.
const resolvedEntity = this.zigbee.resolveEntityLegacy(device.ieeeAddr);
if (!resolvedEntity) {
logger.debug(`Stop pinging '${device.ieeeAddr}', device is not known anymore`);
return;
}
const level = this.state.hasOwnProperty(device.ieeeAddr) && !this.state[device.ieeeAddr] ? 'debug' : 'error';
try {
await device.ping();
this.publishAvailability(device, true);
logger.debug(`Successfully pinged '${resolvedEntity.name}'`);
} catch (error) {
this.publishAvailability(device, false);
logger[level](`Failed to ping '${resolvedEntity.name}'`);
} finally {
this.setTimerPingable(device);
}
}
async handleIntervalNotPingable(device) {
const resolvedEntity = this.zigbee.resolveEntityLegacy(device.ieeeAddr);
if (!resolvedEntity || !device.lastSeen) {
return;
}
const ago = Date.now() - resolvedEntity.device.lastSeen;
logger.debug(`Non-pingable device '${resolvedEntity.name}' was last seen '${ago / 1000}' seconds ago.`);
if (ago > Hours25) {
this.publishAvailability(device, false);
}
}
setTimerPingable(device) {
const timeout = this.availability_timeout + timeoutLag(this.availability_timeout, AvailabilityLagRatio);
clearTimeout(this.timers[device.ieeeAddr]);
this.timers[device.ieeeAddr] = setTimeout(async () => {
await this.handleIntervalPingable(device);
}, utils.seconds(timeout));
}
async stop() {
super.stop();
for (const timer of Object.values(this.timers)) {
clearTimeout(timer);
}
this.zigbee.getClientsLegacy().forEach((device) => this.publishAvailability(device, false));
}
async onReconnect(device) {
const resolvedEntity = this.zigbee.resolveEntityLegacy(device);
if (resolvedEntity && resolvedEntity.definition) {
try {
for (const key of ['state', 'brightness', 'color', 'color_temp']) {
const converter = resolvedEntity.definition.toZigbee.find((tz) => tz.key.includes(key));
if (converter) {
await converter.convertGet(device.endpoints[0], key, {});
}
}
} catch (error) {
logger.error(`Failed to read state of '${resolvedEntity.name}' after reconnect`);
}
}
}
publishAvailability(device, available, force=false) {
const ieeeAddr = device.ieeeAddr;
if (this.state.hasOwnProperty(ieeeAddr) && !this.state[ieeeAddr] && available) {
this.onReconnect(device);
}
const resolvedEntity = this.zigbee.resolveEntityLegacy(device);
const topic = `${resolvedEntity.name}/availability`;
const payload = available ? 'online' : 'offline';
if (this.state[ieeeAddr] !== available || force) {
this.state[ieeeAddr] = available;
this.mqtt.publish(topic, payload, {retain: true, qos: 0});
}
}
onZigbeeEvent(type, data, resolvedEntity) {
const device = data.device;
if (!device) {
return;
}
if (this.inPasslistOrNotInBlocklist(device)) {
this.publishAvailability(data.device, true);
if (this.isPingable(device)) {
// When a zigbee message from a device is received we know the device is still alive.
// => reset the timer.
this.setTimerPingable(device);
const online = this.state.hasOwnProperty(device.ieeeAddr) && this.state[device.ieeeAddr];
if (online && type === 'deviceAnnounce' && !utils.isIkeaTradfriDevice(device)) {
/**
* In case the device is powered off AND on within the availability timeout,
* zigbee2qmtt does not detect the device as offline (device is still marked online).
* When a device is turned on again the state could be out of sync.
* https://github.com/Koenkk/zigbee2mqtt/issues/1383#issuecomment-489412168
* deviceAnnounce is typically send when a device comes online.
*
* This isn't needed for TRADFRI devices as they already send the state themself.
*/
this.onReconnect(device);
}
}
}
}
}
module.exports = AvailabilityLegacy;
+473
View File
@@ -0,0 +1,473 @@
const settings = require('../../util/settings');
const logger = require('../../util/logger');
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
const utils = require('../../util/utils');
const assert = require('assert');
const Extension = require('../extension');
const stringify = require('json-stable-stringify-without-jsonify');
const configRegex =
new RegExp(`${settings.get().mqtt.base_topic}/bridge/config/((?:\\w+/get)|(?:\\w+/factory_reset)|(?:\\w+))`);
const allowedLogLevels = ['error', 'warn', 'info', 'debug'];
class BridgeLegacy extends Extension {
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
super(zigbee, mqtt, state, publishEntityState, eventBus);
// Bind functions
this.permitJoin = this.permitJoin.bind(this);
this.lastSeen = this.lastSeen.bind(this);
this.elapsed = this.elapsed.bind(this);
this.reset = this.reset.bind(this);
this.logLevel = this.logLevel.bind(this);
this.devices = this.devices.bind(this);
this.groups = this.groups.bind(this);
this.rename = this.rename.bind(this);
this.renameLast = this.renameLast.bind(this);
this.remove = this.remove.bind(this);
this.forceRemove = this.forceRemove.bind(this);
this.ban = this.ban.bind(this);
this.deviceOptions = this.deviceOptions.bind(this);
this.addGroup = this.addGroup.bind(this);
this.removeGroup = this.removeGroup.bind(this);
this.whitelist = this.whitelist.bind(this);
this.touchlinkFactoryReset = this.touchlinkFactoryReset.bind(this);
this.lastJoinedDeviceName = null;
// Set supported options
this.supportedOptions = {
'permit_join': this.permitJoin,
'last_seen': this.lastSeen,
'elapsed': this.elapsed,
'reset': this.reset,
'log_level': this.logLevel,
'devices': this.devices,
'groups': this.groups,
'devices/get': this.devices,
'rename': this.rename,
'rename_last': this.renameLast,
'remove': this.remove,
'force_remove': this.forceRemove,
'ban': this.ban,
'device_options': this.deviceOptions,
'add_group': this.addGroup,
'remove_group': this.removeGroup,
'force_remove_group': this.removeGroup,
'whitelist': this.whitelist,
'touchlink/factory_reset': this.touchlinkFactoryReset,
};
}
whitelist(topic, message) {
try {
const entity = settings.getEntity(message);
assert(entity, `Entity '${message}' does not exist`);
settings.whitelistDevice(entity.ID);
logger.info(`Whitelisted '${entity.friendlyName}'`);
this.mqtt.publish(
'bridge/log',
stringify({type: 'device_whitelisted', message: {friendly_name: entity.friendlyName}}),
);
} catch (error) {
logger.error(`Failed to whitelist '${message}' '${error}'`);
}
}
deviceOptions(topic, message) {
let json = null;
try {
json = JSON.parse(message);
} catch (e) {
logger.error('Failed to parse message as JSON');
return;
}
if (!json.hasOwnProperty('friendly_name') || !json.hasOwnProperty('options')) {
logger.error('Invalid JSON message, should contain "friendly_name" and "options"');
return;
}
const entity = settings.getEntity(json.friendly_name);
assert(entity, `Entity '${json.friendly_name}' does not exist`);
settings.changeEntityOptions(entity.ID, json.options);
logger.info(`Changed device specific options of '${json.friendly_name}' (${stringify(json.options)})`);
}
async permitJoin(topic, message) {
await this.zigbee.permitJoinLegacy(message.toLowerCase() === 'true');
this.publish();
}
async reset(topic, message) {
try {
await this.zigbee.reset('soft');
logger.info('Soft resetted ZNP');
} catch (error) {
logger.error('Soft reset failed');
}
}
lastSeen(topic, message) {
const allowed = ['disable', 'ISO_8601', 'epoch', 'ISO_8601_local'];
if (!allowed.includes(message)) {
logger.error(`${message} is not an allowed value, possible: ${allowed}`);
return;
}
settings.set(['advanced', 'last_seen'], message);
logger.info(`Set last_seen to ${message}`);
}
elapsed(topic, message) {
const allowed = ['true', 'false'];
if (!allowed.includes(message)) {
logger.error(`${message} is not an allowed value, possible: ${allowed}`);
return;
}
settings.set(['advanced', 'elapsed'], message === 'true');
logger.info(`Set elapsed to ${message}`);
}
logLevel(topic, message) {
const level = message.toLowerCase();
if (allowedLogLevels.includes(level)) {
logger.info(`Switching log level to '${level}'`);
logger.setLevel(level);
} else {
logger.error(`Could not set log level to '${level}'. Allowed level: '${allowedLogLevels.join(',')}'`);
}
this.publish();
}
async devices(topic, message) {
const coordinator = await this.zigbee.getCoordinatorVersion();
const devices = this.zigbee.getDevicesLegacy().map((device) => {
const payload = {
ieeeAddr: device.ieeeAddr,
type: device.type,
networkAddress: device.networkAddress,
};
if (device.type !== 'Coordinator') {
const definition = zigbeeHerdsmanConverters.findByDevice(device);
const friendlyDevice = settings.getDevice(device.ieeeAddr);
payload.model = definition ? definition.model : device.modelID;
payload.vendor = definition ? definition.vendor : '-';
payload.description = definition ? definition.description : '-';
payload.friendly_name = friendlyDevice ? friendlyDevice.friendly_name : device.ieeeAddr;
payload.manufacturerID = device.manufacturerID;
payload.manufacturerName = device.manufacturerName;
payload.powerSource = device.powerSource;
payload.modelID = device.modelID;
payload.hardwareVersion = device.hardwareVersion;
payload.softwareBuildID = device.softwareBuildID;
payload.dateCode = device.dateCode;
payload.lastSeen = device.lastSeen;
} else {
payload.friendly_name = 'Coordinator';
payload.softwareBuildID = coordinator.type;
payload.dateCode = coordinator.meta.revision.toString();
payload.lastSeen = Date.now();
}
return payload;
});
if (topic.split('/').pop() == 'get') {
this.mqtt.publish(
`bridge/config/devices`, stringify(devices), {}, settings.get().mqtt.base_topic, false, false,
);
} else {
this.mqtt.publish('bridge/log', stringify({type: 'devices', message: devices}));
}
}
groups(topic, message) {
const payload = settings.getGroups().map((g) => {
const group = {...g};
delete group.friendlyName;
return group;
});
this.mqtt.publish('bridge/log', stringify({type: 'groups', message: payload}));
}
rename(topic, message) {
const invalid =
`Invalid rename message format expected {"old": "friendly_name", "new": "new_name"} got ${message}`;
let json = null;
try {
json = JSON.parse(message);
} catch (e) {
logger.error(invalid);
return;
}
// Validate message
if (!json.new || !json.old) {
logger.error(invalid);
return;
}
this._renameInternal(json.old, json.new);
}
renameLast(topic, message) {
if (!this.lastJoinedDeviceName) {
logger.error(`Cannot rename last joined device, no device has joined during this session`);
return;
}
this._renameInternal(this.lastJoinedDeviceName, message);
}
_renameInternal(from, to) {
try {
const isGroup = settings.getGroup(from) !== null;
settings.changeFriendlyName(from, to);
logger.info(`Successfully renamed - ${from} to ${to} `);
const entity = this.zigbee.resolveEntityLegacy(to);
const eventData = isGroup ? {group: entity.group} : {device: entity.device, from, to};
eventData.homeAssisantRename = false;
this.eventBus.emit(`${isGroup ? 'group' : 'device'}Renamed`, eventData);
this.mqtt.publish(
'bridge/log',
stringify({type: `${isGroup ? 'group' : 'device'}_renamed`, message: {from, to}}),
);
} catch (error) {
logger.error(`Failed to rename - ${from} to ${to}`);
}
}
addGroup(topic, message) {
let id = null;
let name = null;
try {
// json payload with id and friendly_name
const json = JSON.parse(message);
if (json.hasOwnProperty('id')) {
id = json.id;
name = `group_${id}`;
}
if (json.hasOwnProperty('friendly_name')) {
name = json.friendly_name;
}
} catch (e) {
// just friendly_name
name = message;
}
if (name == null) {
logger.error('Failed to add group, missing friendly_name!');
return;
}
const group = settings.addGroup(name, id);
this.zigbee.createGroupLegacy(group.ID);
this.mqtt.publish('bridge/log', stringify({type: `group_added`, message: name}));
logger.info(`Added group '${name}'`);
}
removeGroup(topic, message) {
const name = message;
const entity = this.zigbee.resolveEntityLegacy(message);
assert(entity && entity.type === 'group', `Group '${message}' does not exist`);
if (topic.includes('force')) {
entity.group.removeFromDatabase();
} else {
entity.group.removeFromNetwork();
}
settings.removeGroup(message);
this.mqtt.publish('bridge/log', stringify({type: `group_removed`, message}));
logger.info(`Removed group '${name}'`);
}
async forceRemove(topic, message) {
await this.removeForceRemoveOrBan('force_remove', message);
}
async remove(topic, message) {
await this.removeForceRemoveOrBan('remove', message);
}
async ban(topic, message) {
await this.removeForceRemoveOrBan('ban', message);
}
async removeForceRemoveOrBan(action, message) {
const entity = this.zigbee.resolveEntityLegacy(message.trim());
const lookup = {
ban: ['banned', 'Banning', 'ban'],
force_remove: ['force_removed', 'Force removing', 'force remove'],
remove: ['removed', 'Removing', 'remove'],
};
if (!entity) {
logger.error(`Cannot ${lookup[action][2]}, device '${message}' does not exist`);
this.mqtt.publish('bridge/log', stringify({type: `device_${lookup[action][0]}_failed`, message}));
return;
}
const cleanup = () => {
// Fire event
this.eventBus.emit('deviceRemoved', {resolvedEntity: entity});
// Remove from configuration.yaml
settings.removeDevice(entity.settings.ID);
// Remove from state
this.state.remove(entity.settings.ID);
logger.info(`Successfully ${lookup[action][0]} ${entity.settings.friendlyName}`);
this.mqtt.publish('bridge/log', stringify({type: `device_${lookup[action][0]}`, message}));
};
try {
logger.info(`${lookup[action][1]} '${entity.settings.friendlyName}'`);
if (action === 'force_remove') {
await entity.device.removeFromDatabase();
} else {
await entity.device.removeFromNetwork();
}
cleanup();
} catch (error) {
logger.error(`Failed to ${lookup[action][2]} ${entity.settings.friendlyName} (${error})`);
// eslint-disable-next-line
logger.error(`See https://www.zigbee2mqtt.io/information/mqtt_topics_and_message_structure.html#zigbee2mqttbridgeconfigremove for more info`);
this.mqtt.publish('bridge/log', stringify({type: `device_${lookup[action][0]}_failed`, message}));
}
if (action === 'ban') {
settings.banDevice(entity.settings.ID);
}
}
async onMQTTConnected() {
await this.publish();
}
async onMQTTMessage(topic, message) {
if (!topic.match(configRegex)) {
return false;
}
const option = topic.match(configRegex)[1];
if (!this.supportedOptions.hasOwnProperty(option)) {
return false;
}
await this.supportedOptions[option](topic, message);
return true;
}
async publish() {
const info = await utils.getZigbee2MQTTVersion();
const coordinator = await this.zigbee.getCoordinatorVersion();
const topic = `bridge/config`;
const payload = {
version: info.version,
commit: info.commitHash,
coordinator,
network: await this.zigbee.getNetworkParameters(),
log_level: logger.getLevel(),
permit_join: this.zigbee.getPermitJoin(),
};
await this.mqtt.publish(topic, stringify(payload), {retain: true, qos: 0});
}
onZigbeeEvent(type, data, resolvedEntity) {
if (type === 'deviceJoined' && resolvedEntity) {
this.lastJoinedDeviceName = resolvedEntity.name;
}
if (type === 'deviceJoined') {
this.mqtt.publish(
'bridge/log',
stringify({type: `device_connected`, message: {friendly_name: resolvedEntity.name}}),
);
} else if (type === 'deviceInterview') {
if (data.status === 'successful') {
if (resolvedEntity.definition) {
const {vendor, description, model} = resolvedEntity.definition;
const log = {friendly_name: resolvedEntity.name, model, vendor, description, supported: true};
this.mqtt.publish(
'bridge/log',
stringify({type: `pairing`, message: 'interview_successful', meta: log}),
);
} else {
const meta = {friendly_name: resolvedEntity.name, supported: false};
this.mqtt.publish(
'bridge/log',
stringify({type: `pairing`, message: 'interview_successful', meta}),
);
}
} else if (data.status === 'failed') {
const meta = {friendly_name: resolvedEntity.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `pairing`, message: 'interview_failed', meta}),
);
} else {
/* istanbul ignore else */
if (data.status === 'started') {
const meta = {friendly_name: resolvedEntity.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `pairing`, message: 'interview_started', meta}),
);
}
}
} else if (type === 'deviceAnnounce') {
const meta = {friendly_name: resolvedEntity.name};
this.mqtt.publish('bridge/log', stringify({type: `device_announced`, message: 'announce', meta}));
} else {
/* istanbul ignore else */
if (type === 'deviceLeave') {
const name = resolvedEntity ? resolvedEntity.name : data.ieeeAddr;
const meta = {friendly_name: name};
this.mqtt.publish(
'bridge/log',
stringify({type: `device_removed`, message: 'left_network', meta}),
);
}
}
}
async touchlinkFactoryReset() {
logger.info('Starting touchlink factory reset...');
this.mqtt.publish(
'bridge/log',
stringify({type: `touchlink`, message: 'reset_started', meta: {status: 'started'}}),
);
const result = await this.zigbee.touchlinkFactoryResetFirst();
if (result) {
logger.info('Successfully factory reset device through Touchlink');
this.mqtt.publish(
'bridge/log',
stringify({type: `touchlink`, message: 'reset_success', meta: {status: 'success'}}),
);
} else {
logger.warn('Failed to factory reset device through Touchlink');
this.mqtt.publish(
'bridge/log',
stringify({type: `touchlink`, message: 'reset_failed', meta: {status: 'failed'}}),
);
}
}
}
module.exports = BridgeLegacy;
@@ -0,0 +1,50 @@
/* istanbul ignore file */
const settings = require('../../util/settings');
const logger = require('../../util/logger');
const Extension = require('../extension');
const topicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/device/(.+)/get_group_membership$`);
class DeviceGroupMembership extends Extension {
async onMQTTMessage(topic, message) {
const match = topic.match(topicRegex);
if (!match) {
return null;
}
const entity = this.zigbee.resolveEntityLegacy(match[1]);
if (!entity || entity.type !== 'device') {
logger.error(`Device '${match[1]}' does not exist`);
return;
}
const response = await entity.endpoint.command(
`genGroups`, 'getMembership', {groupcount: 0, grouplist: []}, {}, true,
);
if (!response) {
logger.warn(`Couldn't get group membership of ${entity.device.ieeeAddr}`);
return;
}
let {grouplist, capacity} = response;
grouplist = grouplist.map((gid) => {
const g = settings.getGroup(gid);
return g ? g.friendlyName : gid;
});
const msgGroupList = `${entity.device.ieeeAddr} is in groups [${grouplist}]`;
let msgCapacity;
if (capacity === 254) {
msgCapacity = 'it can be a part of at least 1 more group';
} else {
msgCapacity = `its remaining group capacity is ${capacity === 255 ? 'unknown' : capacity}`;
}
logger.info(`${msgGroupList} and ${msgCapacity}`);
this.publishEntityState(entity.device.ieeeAddr, {group_list: grouplist, group_capacity: capacity});
}
}
module.exports = DeviceGroupMembership;
+193
View File
@@ -0,0 +1,193 @@
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
const logger = require('../../util/logger');
const settings = require('../../util/settings');
const ZNLDP12LM = zigbeeHerdsmanConverters.devices.find((d) => d.model === 'ZNLDP12LM');
const utils = require('../../util/utils');
const Extension = require('../extension');
const defaultConfiguration = {
minimumReportInterval: 3, maximumReportInterval: 300, reportableChange: 1,
};
const devicesNotSupportingReporting = [
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'CC2530.ROUTER'),
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'BASICZBR3'),
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'ZM-CSW032-D'),
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'TS0001'),
zigbeeHerdsmanConverters.devices.find((d) => d.model === 'TS0115'),
];
const reportKey = 1;
const getColorCapabilities = async (endpoint) => {
if (endpoint.getClusterAttributeValue('lightingColorCtrl', 'colorCapabilities') === undefined) {
await endpoint.read('lightingColorCtrl', ['colorCapabilities']);
}
const value = endpoint.getClusterAttributeValue('lightingColorCtrl', 'colorCapabilities');
return {
colorTemperature: (value & 1<<4) > 0,
colorXY: (value & 1<<3) > 0,
};
};
const clusters = {
'genOnOff': [
{attribute: 'onOff', ...defaultConfiguration, minimumReportInterval: 0, reportableChange: 0},
],
'genLevelCtrl': [
{attribute: 'currentLevel', ...defaultConfiguration},
],
'lightingColorCtrl': [
{
attribute: 'colorTemperature', ...defaultConfiguration,
condition: async (endpoint) => (await getColorCapabilities(endpoint)).colorTemperature,
},
{
attribute: 'currentX', ...defaultConfiguration,
condition: async (endpoint) => (await getColorCapabilities(endpoint)).colorXY,
},
{
attribute: 'currentY', ...defaultConfiguration,
condition: async (endpoint) => (await getColorCapabilities(endpoint)).colorXY,
},
],
'closuresWindowCovering': [
{attribute: 'currentPositionLiftPercentage', ...defaultConfiguration},
{attribute: 'currentPositionTiltPercentage', ...defaultConfiguration},
],
};
class Report extends Extension {
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
super(zigbee, mqtt, state, publishEntityState, eventBus);
this.queue = new Set();
this.failed = new Set();
this.enabled = settings.get().advanced.report;
}
shouldIgnoreClusterForDevice(cluster, definition) {
if (definition === ZNLDP12LM && cluster === 'closuresWindowCovering') {
// Device announces it but doesn't support it
// https://github.com/Koenkk/zigbee2mqtt/issues/2611
return true;
}
return false;
}
async setupReporting(resolvedEntity) {
const {device, definition} = resolvedEntity;
if (this.queue.has(device.ieeeAddr) || this.failed.has(device.ieeeAddr)) return;
this.queue.add(device.ieeeAddr);
const term1 = this.enabled ? 'Setup' : 'Disable';
const term2 = this.enabled ? 'setup' : 'disabled';
try {
for (const ep of device.endpoints) {
for (const [cluster, configuration] of Object.entries(clusters)) {
if (ep.supportsInputCluster(cluster) && !this.shouldIgnoreClusterForDevice(cluster, definition)) {
logger.debug(`${term1} reporting for '${device.ieeeAddr}' - ${ep.ID} - ${cluster}`);
const items = [];
for (const entry of configuration) {
if (!entry.hasOwnProperty('condition') || (await entry.condition(ep))) {
const toAdd = {...entry};
if (!this.enabled) toAdd.maximumReportInterval = 0xFFFF;
items.push(toAdd);
delete items[items.length - 1].condition;
}
}
this.enabled ?
await ep.bind(cluster, this.coordinatorEndpoint) :
await ep.unbind(cluster, this.coordinatorEndpoint);
await ep.configureReporting(cluster, items);
logger.info(
`Successfully ${term2} reporting for '${device.ieeeAddr}' - ${ep.ID} - ${cluster}`,
);
}
}
}
if (this.enabled) {
device.meta.reporting = reportKey;
} else {
delete device.meta.reporting;
this.eventBus.emit('reportingDisabled', {device});
}
this.eventBus.emit(`devicesChanged`);
} catch (error) {
logger.error(
`Failed to ${term1.toLowerCase()} reporting for '${device.ieeeAddr}' - ${error.stack}`,
);
this.failed.add(device.ieeeAddr);
}
device.save();
this.queue.delete(device.ieeeAddr);
}
shouldSetupReporting(resolvedEntity, messageType) {
if (!resolvedEntity || !resolvedEntity.device || !resolvedEntity.definition ||
messageType === 'deviceLeave') return false;
const {device, definition} = resolvedEntity;
// Handle messages of type endDeviceAnnce and devIncoming.
// This message is typically send when a device comes online after being powered off
// Ikea TRADFRI tend to forget their reporting after powered off.
// Re-setup reporting.
// Only resetup reporting if configuredReportings was not populated yet,
// else reconfigure is done in zigbee-herdsman-converters ikea.js/bulbOnEvent
// configuredReportings are saved since Zigbee2MQTT 1.17.0
// https://github.com/Koenkk/zigbee2mqtt/issues/966
if (this.enabled && messageType === 'deviceAnnounce' && utils.isIkeaTradfriDevice(device) &&
device.endpoints.filter((e) => e.configuredReportings.length === 0).length === device.endpoints.length) {
return true;
}
// These do not support reproting.
// https://github.com/Koenkk/zigbee-herdsman/issues/110
const philipsIgnoreSw = ['5.127.1.26581', '5.130.1.30000'];
if (device.manufacturerName === 'Philips' && philipsIgnoreSw.includes(device.softwareBuildID)) return false;
if (resolvedEntity.device.interviewing === true) return false;
if (device.type !== 'Router' || device.powerSource === 'Battery') return false;
// Gledopto devices don't support reporting.
if (devicesNotSupportingReporting.includes(definition) || definition.vendor === 'Gledopto') return false;
if (this.enabled && device.meta.hasOwnProperty('reporting') && device.meta.reporting === reportKey) {
return false;
}
if (!this.enabled && !device.meta.hasOwnProperty('reporting')) {
return false;
}
return true;
}
async onZigbeeStarted() {
this.coordinatorEndpoint = this.zigbee.getDevicesByTypeLegacy('Coordinator')[0].getEndpoint(1);
for (const device of this.zigbee.getClientsLegacy()) {
const resolvedEntity = this.zigbee.resolveEntityLegacy(device);
if (this.shouldSetupReporting(resolvedEntity, null)) {
await this.setupReporting(resolvedEntity);
}
}
}
async onZigbeeEvent(type, data, resolvedEntity) {
if (this.shouldSetupReporting(resolvedEntity, type)) {
await this.setupReporting(resolvedEntity);
}
}
}
module.exports = Report;
+66
View File
@@ -0,0 +1,66 @@
/* istanbul ignore file */
// DEPRECATED
const settings = require('../../util/settings');
const logger = require('../../util/logger');
const utils = require('../../util/utils');
const Extension = require('../extension');
/**
* This extensions soft resets the ZNP after a certain timeout.
*/
class SoftReset extends Extension {
constructor(zigbee, mqtt, state, publishEntityState, eventBus) {
super(zigbee, mqtt, state, publishEntityState, eventBus);
this.timer = null;
this.timeout = utils.seconds(settings.get().advanced.soft_reset_timeout);
}
onZigbeeStarted() {
logger.debug(`Soft reset timeout set to ${this.timeout / 1000} seconds`);
this.resetTimer();
}
clearTimer() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
resetTimer() {
if (this.timeout === 0) {
return;
}
this.clearTimer();
this.timer = setTimeout(() => this.handleTimeout(), this.timeout);
}
async handleTimeout() {
logger.warn('Soft reset timeout triggered');
try {
await this.zigbee.reset('soft');
logger.warn('Soft resetted ZNP due to timeout');
} catch (error) {
logger.warn('Soft reset failed, trying stop/start');
await this.zigbee.stop();
logger.warn('Zigbee stopped');
try {
await this.zigbee.start();
} catch (error) {
logger.error('Failed to restart!');
}
}
this.resetTimer();
}
onZigbeeEvent() {
this.resetTimer();
}
}
module.exports = SoftReset;
-183
View File
@@ -1,183 +0,0 @@
const utils = require('../util/utils');
const interval = utils.secondsToMilliseconds(1);
const logger = require('../util/logger');
const foundationCfg = {manufSpec: 0, disDefaultRsp: 0};
/**
* Extension required for Livolo device support.
*/
class Livolo {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.timer = null;
this.configured = {};
}
onZigbeeStarted() {
this.startTimer();
}
_resetDeviceState(ieeeAddr) {
this.configured[ieeeAddr] = {
stage: 0,
retry: 0,
waitresp: false,
};
}
onZigbeeMessage(message, device, mappedDevice) {
if (!device) {
return;
}
if ((message.type == 'devInterview') ||
(message.type == 'devIncoming') ||
(message.type == 'endDeviceAnnce') ||
(message.type == 'devStatus')) {
if (this.configured.hasOwnProperty(device.ieeeAddr)) {
logger.info(`LIVOLO ${device.ieeeAddr}. (Re)joins in the network (after power off?)`);
this._resetDeviceState(device.ieeeAddr);
}
return;
}
}
startTimer() {
this.clearTimer();
this.timer = setInterval(() => this.handleInterval(), interval);
}
clearTimer() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
stop() {
this.clearTimer();
}
_handleCommandRespSimple(err, rsp) {
this.ext.configured[this.ieeeAddr].waitresp = false;
if (err) {
if (this.ctype === 'toggle') {
logger.debug(`LIVOLO ${this.ieeeAddr}. Toggle command error:`, err.message);
}
} else {
logger.debug(`LIVOLO ${this.ieeeAddr}. Sucessfully configured`, rsp);
this.ext.configured[this.ieeeAddr].stage = 1; // sucessfully send command
this.ext.configured[this.ieeeAddr].retry = 0;
this.device.status = 'online';
}
}
_handleCommandRespWithData(err, rsp) {
this.ext.configured[this.ieeeAddr].waitresp = false;
if (err) {
logger.info(`LIVOLO ${this.ieeeAddr}. ${this.cid}.${this.ctype} response error:`, err.message);
if (this.ext.configured[this.ieeeAddr].retry >= 3) {
// errors in three sequental reads, stop polling, wait for a device message
this.device.status = 'offline';
logger.info(`LIVOLO ${this.ieeeAddr}. Stopped polling after 3 unsuccessful attempts`);
}
} else {
this.ext.configured[this.ieeeAddr].retry = 0;
this.device.status = 'online';
if (this.ext.zigbee) {
this.ext.zigbee.shepherd.emit('ind:reported', this.ep, this.cid, rsp, this.ep.last_af_msg);
}
}
}
// msg: { groupid, clusterid, srcaddr, srcendpoint, dstendpoint, wasbroadcast,
// linkquality, securityuse, timestamp, transseqnumber, len, data }
_handleAfMessage(msg, ep) {
ep.linkquality = msg.linkquality;
ep.last_af_msg = msg;
}
_sendToggle(zdev, ieeeAddr, ep, retry) {
this.zigbee.queue.push(ieeeAddr, (queueCallback) => {
const cfg = {};
logger.debug(`LIVOLO ${ieeeAddr}. Sending the 'toggle' command. Retry: ${retry}`);
ep.functional('genOnOff', 'toggle', [cfg], foundationCfg,
this._handleCommandRespSimple.bind({
device: zdev,
ieeeAddr,
cid: 'genOnOff',
ctype: 'toggle',
ext: this,
}));
queueCallback();
});
}
_sendPoll(zdev, ieeeAddr, ep, retry) {
this.zigbee.queue.push(ieeeAddr, (queueCallback) => {
ep.foundation('genOnOff', 'read', [{
attrId: 0, // onOff
}], this._handleCommandRespWithData.bind({
device: zdev,
ieeeAddr,
ep,
cid: 'genOnOff',
ctype: 'read',
ext: this,
}));
queueCallback();
});
}
handleInterval() {
this.zigbee.getAllClients()
.filter((d) => d.manufName && d.manufName.startsWith('LIVOLO')) // LIVOLO
.filter((d) => d.type === 'EndDevice') // Filter end devices
.filter((d) => d.powerSource && d.powerSource !== 'Battery') // Remove battery powered devices
.forEach((d) => {
const zdev = this.zigbee.shepherd._findDevByAddr(d.ieeeAddr);
if (zdev && zdev.endpoints) {
const eplist = Object.keys(zdev.endpoints).filter((epId) => {
const ep2 = zdev.getEndpoint(epId);
const clist = ep2.getClusterList();
return clist && clist.includes(6); // 6 - genOnOff
});
if (eplist.length > 0) {
const ep = zdev.getEndpoint(eplist[0]);
ep.onAfIncomingMsg = this._handleAfMessage;
if (!this.configured.hasOwnProperty(d.ieeeAddr)) {
this._resetDeviceState(d.ieeeAddr);
}
const state = this.configured[d.ieeeAddr];
if (state.waitresp) {
return;
}
if (state.retry < 3) {
if (state.stage === 0) {
state.retry += 1;
state.waitresp = true;
this._sendToggle(zdev, d.ieeeAddr, ep, state.retry);
} else if (state.stage === 1) {
state.retry += 1;
state.waitresp = true;
this._sendPoll(zdev, d.ieeeAddr, ep, state.retry);
}
}
}
}
});
return true;
}
}
module.exports = Livolo;
-145
View File
@@ -1,145 +0,0 @@
const settings = require('../util/settings');
const utils = require('../util/utils');
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
class NetworkMap {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.lastSeenMap = {};
// Subscribe to topic.
this.topic = `${settings.get().mqtt.base_topic}/bridge/networkmap`;
this.topicRoutes = `${settings.get().mqtt.base_topic}/bridge/networkmap/routes`;
// Bind
this.raw = this.raw.bind(this);
this.graphviz = this.graphviz.bind(this);
// Set supported formats
this.supportedFormats = {
'raw': this.raw,
'graphviz': this.graphviz,
};
}
onZigbeeMessage(message, device, mappedDevice) {
if (device) {
this.lastSeenMap[device.ieeeAddr] = Date.now();
}
}
onMQTTConnected() {
this.mqtt.subscribe(this.topic);
this.mqtt.subscribe(this.topicRoutes);
}
onMQTTMessage(topic, message) {
message = message.toString();
const includeRoutes = (topic === this.topicRoutes) ? 1: 0;
if ((topic === this.topic || topic === this.topicRoutes) &&
this.supportedFormats.hasOwnProperty(message)) {
this.zigbee.networkScan(includeRoutes, (result)=> {
const converted = this.supportedFormats[message](this.zigbee, result);
this.mqtt.publish(`bridge/networkmap/${message}`, converted, {});
});
return true;
}
return false;
}
raw(zigbee, topology) {
return JSON.stringify(topology);
}
graphviz(zigbee, topology) {
const colors = settings.get().map_options.graphviz.colors;
let text = 'digraph G {\nnode[shape=record];\n';
let devStyle = '';
topology.nodes.forEach((device) => {
const labels = [];
// Add friendly name
labels.push(`${device.friendlyName}`);
// Add the device short network address and scan note (if any)
let scanNote = '';
if (device.scanfailed.includes('lqi')) {
scanNote += ' no lqi';
}
if (device.scanfailed.includes('rtg')) {
scanNote += ' no routes';
}
labels.push(`0x${device.nwkAddr.toString(16)} ${scanNote}`);
// Add the device model
const mappedModel = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
if (mappedModel) {
labels.push(`${mappedModel.vendor} ${mappedModel.description} (${mappedModel.model})`);
} else {
// This model is not supported by zigbee-shepherd-converters, add zigbee model information, if available
const zigbeeModel = [device.manufName, device.modelId].filter((a) => a).join(' ');
labels.push(zigbeeModel ? zigbeeModel : 'No model information available');
}
// Add the device status (online/offline) and last_seen timestamp
let lastSeen = 'unknown';
if (device.type == 'Coordinator') {
lastSeen = utils.formatDate(Date.now(), settings.get().advanced.last_seen,
utils.toLocalISOString(new Date(Date.now())));
} else {
if (this.lastSeenMap[device.ieeeAddr]) {
const lastSeenAgo =
`${new Date(Date.now() - this.lastSeenMap[device.ieeeAddr]).toISOString().substr(11, 8)}s ago`;
lastSeen = utils.formatDate(this.lastSeenMap[device.ieeeAddr],
settings.get().advanced.last_seen, lastSeenAgo);
}
}
labels.push(`${device.status} (${lastSeen})`);
// Shape the record according to device type
if (device.type == 'Coordinator') {
devStyle = `style="bold, filled", fillcolor="${colors.fill.coordinator}", ` +
`fontcolor="${colors.font.coordinator}"`;
} else if (device.type == 'Router') {
devStyle = `style="rounded, filled", fillcolor="${colors.fill.router}", ` +
`fontcolor="${colors.font.router}"`;
} else {
devStyle = `style="rounded, dashed, filled", fillcolor="${colors.fill.enddevice}", ` +
`fontcolor="${colors.font.enddevice}"`;
}
// Add the device with its labels to the graph as a node.
text += ` "${device.ieeeAddr}" [`+devStyle+`, label="{${labels.join('|')}}"];\n`;
/**
* Add an edge between the device and its child to the graph
* NOTE: There are situations where a device is NOT in the topology, this can be e.g.
* due to not responded to the lqi scan. In that case we do not add an edge for this device.
*/
topology.links.filter((e) => (e.sourceIeeeAddr === device.ieeeAddr) || (e.SourceNwkAddr === device.nwkAddr))
.forEach((e) => {
const lineStyle = (device.type=='EndDevice') ? 'penwidth=1, ' : (!e.routes.length) ?
'penwidth=0.5, ' : 'penwidth=2, ';
const lineWeight = (!e.routes.length) ? `weight=0, color="${colors.line.inactive}", ` :
`weight=1, color="${colors.line.active}", `;
const textRoutes = e.routes.map((r) => `0x${r.toString(16)}`);
const lineLabels = (!e.routes.length) ? `label="${e.lqi}"` :
`label="${e.lqi}\\n[${textRoutes.join(']\\n[')}]"`;
text += ` "${device.ieeeAddr}" -> "${e.targetIeeeAddr}"`;
text += ` [${lineStyle}${lineWeight}${lineLabels}]\n`;
});
});
text += '}';
return text.replace(/\0/g, '');
}
}
module.exports = NetworkMap;
+324
View File
@@ -0,0 +1,324 @@
import * as settings from '../util/settings';
import * as utils from '../util/utils';
import logger from '../util/logger';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
import ExtensionTS from './extensionts';
import bind from 'bind-decorator';
interface Link {
source: {ieeeAddr: string, networkAddress: number}, target: {ieeeAddr: string, networkAddress: number},
linkquality: number, depth: number, routes: RoutingTableEntry[],
sourceIeeeAddr: string, targetIeeeAddr: string, sourceNwkAddr: number, lqi: number, relationship: number,
}
interface Topology {
nodes: {
ieeeAddr: string, friendlyName: string, type: string, networkAddress: number, manufacturerName: string,
modelID: string, failed: string[], lastSeen: number,
definition: {model: string, vendor: string, supports: string, description: string}}[],
links: Link[],
}
/**
* This extension creates a network map
*/
class NetworkMap extends ExtensionTS {
private legacyApi = settings.get().advanced.legacy_api;
private legacyTopic = `${settings.get().mqtt.base_topic}/bridge/networkmap`;
private legacyTopicRoutes = `${settings.get().mqtt.base_topic}/bridge/networkmap/routes`;
private topic = `${settings.get().mqtt.base_topic}/bridge/request/networkmap`;
private supportedFormats: {[s: string]: (topology: Topology) => KeyValue | string};
override async start(): Promise<void> {
this.eventBus.onMQTTMessage(this, this.onMQTTMessage_);
this.supportedFormats = {
'raw': this.raw,
'graphviz': this.graphviz,
'plantuml': this.plantuml,
};
}
@bind async onMQTTMessage_(data: EventMQTTMessage): Promise<void> {
/* istanbul ignore else */
if (this.legacyApi) {
if ((data.topic === this.legacyTopic || data.topic === this.legacyTopicRoutes) &&
this.supportedFormats.hasOwnProperty(data.message)) {
const includeRoutes = data.topic === this.legacyTopicRoutes;
const topology = await this.networkScan(includeRoutes);
let converted = this.supportedFormats[data.message](topology);
converted = data.message === 'raw' ? stringify(converted) : converted;
this.mqtt.publish(`bridge/networkmap/${data.message}`, converted as string, {});
}
}
if (data.topic === this.topic) {
const message = utils.parseJSON(data.message, data.message);
try {
const type = typeof message === 'object' ? message.type : message;
if (!this.supportedFormats.hasOwnProperty(type)) {
throw new Error(`Type '${type}' not supported, allowed are: ${Object.keys(this.supportedFormats)}`);
}
const routes = typeof message === 'object' && message.routes;
const topology = await this.networkScan(routes);
const value = this.supportedFormats[type](topology);
await this.mqtt.publish(
'bridge/response/networkmap',
stringify(utils.getResponse(message, {routes, type, value}, null)),
);
} catch (error) {
await this.mqtt.publish(
'bridge/response/networkmap',
stringify(utils.getResponse(message, {}, error.message)),
);
}
}
}
@bind raw(topology: Topology): KeyValue {
return topology;
}
@bind graphviz(topology: Topology): string {
const colors = settings.get().map_options.graphviz.colors;
let text = 'digraph G {\nnode[shape=record];\n';
let style = '';
topology.nodes.forEach((node) => {
const labels = [];
// Add friendly name
labels.push(`${node.friendlyName}`);
// Add the device short network address, ieeaddr and scan note (if any)
labels.push(
`${node.ieeeAddr} (${utils.toNetworkAddressHex(node.networkAddress)})` +
((node.failed && node.failed.length) ? `failed: ${node.failed.join(',')}` : ''),
);
// Add the device model
if (node.type !== 'Coordinator') {
if (node.definition) {
labels.push(`${node.definition.vendor} ${node.definition.description} (${node.definition.model})`);
} else {
// This model is not supported by zigbee-herdsman-converters, add zigbee model information
labels.push(`${node.manufacturerName} ${node.modelID}`);
}
}
// Add the device last_seen timestamp
let lastSeen = 'unknown';
const date = node.type === 'Coordinator' ? Date.now() : node.lastSeen;
if (date) {
lastSeen = utils.formatDate(date, 'relative') as string;
}
labels.push(lastSeen);
// Shape the record according to device type
if (node.type == 'Coordinator') {
style = `style="bold, filled", fillcolor="${colors.fill.coordinator}", ` +
`fontcolor="${colors.font.coordinator}"`;
} else if (node.type == 'Router') {
style = `style="rounded, filled", fillcolor="${colors.fill.router}", ` +
`fontcolor="${colors.font.router}"`;
} else {
style = `style="rounded, dashed, filled", fillcolor="${colors.fill.enddevice}", ` +
`fontcolor="${colors.font.enddevice}"`;
}
// Add the device with its labels to the graph as a node.
text += ` "${node.ieeeAddr}" [`+style+`, label="{${labels.join('|')}}"];\n`;
/**
* Add an edge between the device and its child to the graph
* NOTE: There are situations where a device is NOT in the topology, this can be e.g.
* due to not responded to the lqi scan. In that case we do not add an edge for this device.
*/
topology.links.filter((e) => (e.source.ieeeAddr === node.ieeeAddr)).forEach((e) => {
const lineStyle = (node.type=='EndDevice') ? 'penwidth=1, ' :
(!e.routes.length) ? 'penwidth=0.5, ' : 'penwidth=2, ';
const lineWeight = (!e.routes.length) ? `weight=0, color="${colors.line.inactive}", ` :
`weight=1, color="${colors.line.active}", `;
const textRoutes = e.routes.map((r) => utils.toNetworkAddressHex(r.destinationAddress));
const lineLabels = (!e.routes.length) ? `label="${e.linkquality}"` :
`label="${e.linkquality} (routes: ${textRoutes.join(',')})"`;
text += ` "${node.ieeeAddr}" -> "${e.target.ieeeAddr}"`;
text += ` [${lineStyle}${lineWeight}${lineLabels}]\n`;
});
});
text += '}';
return text.replace(/\0/g, '');
}
@bind plantuml(topology: Topology): string {
const text = [];
text.push(`' paste into: https://www.planttext.com/`);
text.push(``);
text.push('@startuml');
topology.nodes.sort((a, b) => a.friendlyName.localeCompare(b.friendlyName)).forEach((node) => {
// Add friendly name
text.push(`card ${node.ieeeAddr} [`);
text.push(`${node.friendlyName}`);
text.push(`---`);
// Add the device short network address, ieeaddr and scan note (if any)
text.push(
`${node.ieeeAddr} (${utils.toNetworkAddressHex(node.networkAddress)})` +
((node.failed && node.failed.length) ? ` failed: ${node.failed.join(',')}` : ''),
);
// Add the device model
if (node.type !== 'Coordinator') {
text.push(`---`);
const definition = this.zigbee.resolveEntityLegacy(node.ieeeAddr).definition;
if (definition) {
text.push(`${definition.vendor} ${definition.description} (${definition.model})`);
} else {
// This model is not supported by zigbee-herdsman-converters, add zigbee model information
text.push(`${node.manufacturerName} ${node.modelID}`);
}
}
// Add the device last_seen timestamp
let lastSeen = 'unknown';
const date = node.type === 'Coordinator' ? Date.now() : node.lastSeen;
if (date) {
lastSeen = utils.formatDate(date, 'relative') as string;
}
text.push(`---`);
text.push(lastSeen);
text.push(`]`);
text.push(``);
});
/**
* Add edges between the devices
* NOTE: There are situations where a device is NOT in the topology, this can be e.g.
* due to not responded to the lqi scan. In that case we do not add an edge for this device.
*/
topology.links.forEach((link) => {
text.push(`${link.sourceIeeeAddr} --> ${link.targetIeeeAddr}: ${link.lqi}`);
});
text.push('');
text.push(`@enduml`);
return text.join(`\n`);
}
async networkScan(includeRoutes: boolean): Promise<Topology> {
logger.info(`Starting network scan (includeRoutes '${includeRoutes}')`);
const devices = this.zigbee.getDevices().filter((d) => d.type !== 'GreenPower');
const lqis: Map<Device, LQI> = new Map();
const routingTables: Map<Device, RoutingTable> = new Map();
const failed: Map<Device, string[]> = new Map();
for (const device of devices.filter((d) => d.type != 'EndDevice')) {
failed.set(device, []);
await utils.sleep(1); // sleep 1 second between each scan to reduce stress on network.
const doRequest = async <T>(request: () => Promise<T>, firstAttempt = true): Promise<T> => {
try {
return await request();
} catch (error) {
if (!firstAttempt) {
throw error;
} else {
// Network is possibly congested, sleep 5 seconds to let the network settle.
await utils.sleep(5);
return doRequest(request, false);
}
}
};
try {
const result = await doRequest<LQI>(async () => device.lqi());
lqis.set(device, result);
logger.debug(`LQI succeeded for '${device.name}'`);
} catch (error) {
failed.get(device).push('lqi');
logger.error(`Failed to execute LQI for '${device.name}'`);
}
if (includeRoutes) {
try {
const result = await doRequest(async () => device.routingTable());
routingTables.set(device, result);
logger.debug(`Routing table succeeded for '${device.name}'`);
} catch (error) {
failed.get(device).push('routingTable');
logger.error(`Failed to execute routing table for '${device.name}'`);
}
}
}
logger.info(`Network scan finished`);
const topology: Topology = {nodes: [], links: []};
// Add nodes
for (const device of devices) {
const definition = device.definition ? {
model: device.definition.model,
vendor: device.definition.vendor,
description: device.definition.description,
supports: Array.from(new Set((device.definition.exposes).map((e) => {
return e.hasOwnProperty('name') ? e.name :
`${e.type} (${e.features.map((f) => f.name).join(', ')})`;
}))).join(', '),
} : null;
topology.nodes.push({
ieeeAddr: device.ieeeAddr, friendlyName: device.name, type: device.type,
networkAddress: device.networkAddress, manufacturerName: device.manufacturerName,
modelID: device.modelID, failed: failed.get(device), lastSeen: device.lastSeen,
definition,
});
}
// Add links
lqis.forEach((lqi, device) => {
for (const neighbor of lqi.neighbors) {
if (neighbor.relationship > 3) {
// Relationship is not active, skip it
continue;
}
// Some Xiaomi devices return 0x00 as the neighbor ieeeAddr (obviously not correct).
// Determine the correct ieeeAddr based on the networkAddress.
const neighborDevice = this.zigbee.deviceByNetworkAddress(neighbor.networkAddress);
if (neighbor.ieeeAddr === '0x0000000000000000' && neighborDevice) {
neighbor.ieeeAddr = neighborDevice.ieeeAddr;
}
const link: Link = {
source: {ieeeAddr: neighbor.ieeeAddr, networkAddress: neighbor.networkAddress},
target: {ieeeAddr: device.ieeeAddr, networkAddress: device.networkAddress},
linkquality: neighbor.linkquality, depth: neighbor.depth, routes: [],
// DEPRECATED:
sourceIeeeAddr: neighbor.ieeeAddr, targetIeeeAddr: device.ieeeAddr,
sourceNwkAddr: neighbor.networkAddress, lqi: neighbor.linkquality,
relationship: neighbor.relationship,
};
const routingTable = routingTables.get(device);
if (routingTable) {
link.routes = routingTable.table
.filter((t) => t.status === 'ACTIVE' && t.nextHop === neighbor.networkAddress);
}
topology.links.push(link);
}
});
return topology;
}
}
module.exports = NetworkMap;
+45
View File
@@ -0,0 +1,45 @@
// @ts-ignore
import zhc from 'zigbee-herdsman-converters';
import ExtensionTS from './extensionts';
/**
* This extension calls the zigbee-herdsman-converters onEvent.
*/
class OnEvent extends ExtensionTS {
override async start(): Promise<void> {
for (const device of this.zigbee.getClients()) {
await this.callOnEvent(device, 'start', {});
}
this.eventBus.onDeviceMessage(this, (data) => this.callOnEvent(data.device, 'message', this.convertData(data)));
this.eventBus.onDeviceJoined(this,
(data) => this.callOnEvent(data.device, 'deviceJoined', this.convertData(data)));
this.eventBus.onDeviceInterview(this,
(data) => this.callOnEvent(data.device, 'deviceInterview', this.convertData(data)));
this.eventBus.onDeviceAnnounce(this,
(data) => this.callOnEvent(data.device, 'deviceAnnounce', this.convertData(data)));
this.eventBus.onDeviceNetworkAddressChanged(this,
(data) => this.callOnEvent(data.device, 'deviceNetworkAddressChanged', this.convertData(data)));
}
private convertData(data: KeyValue): KeyValue {
return {...data, device: data.device.zhDevice};
}
override async stop(): Promise<void> {
super.stop();
for (const device of this.zigbee.getClients()) {
await this.callOnEvent(device, 'stop', {});
}
}
private async callOnEvent(device: Device, type: string, data: KeyValue): Promise<void> {
zhc.onEvent(type, data, device.zhDevice, device.settings);
if (device.definition?.onEvent) {
await device.definition.onEvent(type, data, device.zhDevice, device.settings);
}
}
}
module.exports = OnEvent;
+281
View File
@@ -0,0 +1,281 @@
import * as settings from '../util/settings';
import logger from '../util/logger';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
import * as utils from '../util/utils';
// @ts-ignore
import tradfriOTA from 'zigbee-herdsman-converters/lib/ota/tradfri';
import ExtensionTS from './extensionts';
import bind from 'bind-decorator';
import Device from '../model/device';
type UpdateState = 'updating' | 'idle' | 'available';
interface UpdatePayload {
// eslint-disable-next-line camelcase
update: {progress?: number, remaining?: number, state: UpdateState}, update_available?: boolean}
const legacyTopicRegex = new RegExp(`^${settings.get().mqtt.base_topic}/bridge/ota_update/.+$`);
const topicRegex =
new RegExp(`^${settings.get().mqtt.base_topic}/bridge/request/device/ota_update/(update|check)`, 'i');
class OTAUpdate extends ExtensionTS {
private inProgress = new Set();
private lastChecked: {[s: string]: number} = {};
private legacyApi = settings.get().advanced.legacy_api;
override async start(): Promise<void> {
this.eventBus.onMQTTMessage(this, this.onMQTTMessage_);
this.eventBus.onDeviceMessage(this, this.onZigbeeEvent);
if (settings.get().advanced.ikea_ota_use_test_url) {
tradfriOTA.useTestURL();
}
for (const device of this.zigbee.getClients()) {
// In case Zigbee2MQTT is restared during an update, progress and remaining values are still in state.
// remove them.
this.removeProgressAndRemainingFromState(device);
}
}
private removeProgressAndRemainingFromState(device: Device): void {
this.state.removeKey(device.ieeeAddr, ['update', 'progress']);
this.state.removeKey(device.ieeeAddr, ['update', 'remaining']);
}
@bind private async onZigbeeEvent(data: EventDeviceMessage): Promise<void> {
if (settings.get().ota.disable_automatic_update_check) return;
if (data.type !== 'commandQueryNextImageRequest' || !data.device.definition) return;
logger.debug(`Device '${data.device.name}' requested OTA`);
const supportsOTA = data.device.definition.hasOwnProperty('ota');
if (supportsOTA) {
// When a device does a next image request, it will usually do it a few times after each other
// with only 10 - 60 seconds inbetween. It doesn't make sense to check for a new update
// each time, so this interval can be set by the user. The default is 1,440 minutes (one day).
const updateCheckInterval = settings.get().ota.update_check_interval * 1000 * 60;
const check = this.lastChecked.hasOwnProperty(data.device.ieeeAddr) ?
(Date.now() - this.lastChecked[data.device.ieeeAddr]) > updateCheckInterval : true;
if (!check || this.inProgress.has(data.device.ieeeAddr)) return;
this.lastChecked[data.device.ieeeAddr] = Date.now();
const available = await data.device.definition.ota.isUpdateAvailable(
data.device.zhDevice, logger, data.data);
const payload = this.getEntityPublishPayload(available ? 'available' : 'idle');
this.publishEntityState(data.device.ieeeAddr, payload);
if (available) {
const message = `Update available for '${data.device.name}'`;
logger.info(message);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: 'available', device: data.device.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `ota_update`, message, meta}),
);
}
}
}
// Respond to the OTA request:
// - In case we don't support OTA: respond with NO_IMAGE_AVAILABLE (0x98) (so the client stops requesting OTAs)
// - In case we do support OTA: respond with ABORT (0x95) as we don't want to update now.
const endpoint = data.device.endpoints.find((e) => e.supportsOutputCluster('genOta'));
if (endpoint) {
// Some devices send OTA requests without defining OTA cluster as input cluster.
await endpoint.commandResponse('genOta', 'queryNextImageResponse', {status: supportsOTA ? 0x95 : 0x98});
}
}
private async readSoftwareBuildIDAndDateCode(device: Device, update: boolean):
Promise<{softwareBuildID: string, dateCode: string}> {
try {
const endpoint = device.endpoints.find((e) => e.supportsInputCluster('genBasic'));
const result = await endpoint.read('genBasic', ['dateCode', 'swBuildId']);
if (update) {
device.zhDevice.softwareBuildID = result.swBuildId;
device.zhDevice.dateCode = result.dateCode;
device.zhDevice.save();
}
return {softwareBuildID: result.swBuildId, dateCode: result.dateCode};
} catch (e) {
return null;
}
}
private getEntityPublishPayload(state: UpdateState, progress: number=null, remaining: number=null): UpdatePayload {
const payload: UpdatePayload = {update: {state}};
if (progress !== null) payload.update.progress = progress;
if (remaining !== null) payload.update.remaining = Math.round(remaining);
/* istanbul ignore else */
if (this.legacyApi) {
payload.update_available = state === 'available';
}
return payload;
}
@bind async onMQTTMessage_(data: EventMQTTMessage): Promise<void> {
if ((!this.legacyApi || !data.topic.match(legacyTopicRegex)) && !data.topic.match(topicRegex)) {
return null;
}
const message = utils.parseJSON(data.message, data.message);
const ID = (typeof message === 'object' && message.hasOwnProperty('id') ? message.id : message) as string;
const device = this.zigbee.resolveEntity(ID);
const type = data.topic.substring(data.topic.lastIndexOf('/') + 1);
const responseData: {id: string, updateAvailable?: boolean, from?: string, to?: string}= {id: ID};
let error = null;
let errorStack = null;
if (!(device instanceof Device)) {
error = `Device '${ID}' does not exist`;
} else if (!device.definition || !device.definition.ota) {
error = `Device '${device.name}' does not support OTA updates`;
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `not_supported`, device: device.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `ota_update`, message: error, meta}),
);
}
} else if (this.inProgress.has(device.ieeeAddr)) {
error = `Update or check for update already in progress for '${device.name}'`;
} else {
this.inProgress.add(device.ieeeAddr);
if (type === 'check') {
const msg = `Checking if update available for '${device.name}'`;
logger.info(msg);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `checking_if_available`, device: device.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `ota_update`, message: msg, meta}),
);
}
try {
const available = await device.definition.ota.isUpdateAvailable(device.zhDevice, logger);
const msg = `${available ? 'Update' : 'No update'} available for '${device.name}'`;
logger.info(msg);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: available ? 'available' : 'not_available', device: device.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `ota_update`, message: msg, meta}),
);
}
const payload = this.getEntityPublishPayload(available ? 'available' : 'idle');
this.publishEntityState(device.ieeeAddr, payload);
this.lastChecked[device.ieeeAddr] = Date.now();
responseData.updateAvailable = available;
} catch (e) {
error = `Failed to check if update available for '${device.name}' (${e.message})`;
errorStack = e.stack;
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `check_failed`, device: device.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `ota_update`, message: error, meta}),
);
}
}
} else { // type === 'update'
const msg = `Updating '${device.name}' to latest firmware`;
logger.info(msg);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_in_progress`, device: device.name};
this.mqtt.publish(
'bridge/log',
stringify({type: `ota_update`, message: msg, meta}),
);
}
try {
const onProgress = (progress: number, remaining: number): void => {
let msg = `Update of '${device.name}' at ${progress.toFixed(2)}%`;
if (remaining) {
msg += `, ≈ ${Math.round(remaining / 60)} minutes remaining`;
}
logger.info(msg);
const payload = this.getEntityPublishPayload('updating', progress, remaining);
this.publishEntityState(device.ieeeAddr, payload);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_progress`, device: device.name, progress};
this.mqtt.publish('bridge/log', stringify({type: `ota_update`, message: msg, meta}));
}
};
const from_ = await this.readSoftwareBuildIDAndDateCode(device, false);
await device.definition.ota.updateToLatest(device.zhDevice, logger, onProgress);
const to = await this.readSoftwareBuildIDAndDateCode(device, true);
const [fromS, toS] = [stringify(from_), stringify(to)];
const msg = `Finished update of '${device.name}'` +
(to ? `, from '${fromS}' to '${toS}'` : ``);
logger.info(msg);
this.removeProgressAndRemainingFromState(device);
const payload = this.getEntityPublishPayload('idle');
this.publishEntityState(device.ieeeAddr, payload);
responseData.from = from_ ? utils.toSnakeCase(from_) : null;
responseData.to = to ? utils.toSnakeCase(to) : null;
this.eventBus.emit(`devicesChanged`);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_succeeded`, device: device.name, from: from_, to};
this.mqtt.publish('bridge/log', stringify({type: `ota_update`, message, meta}));
}
} catch (e) {
logger.debug(`Update of '${device.name}' failed (${e})`);
error = `Update of '${device.name}' failed (${e.message})`;
errorStack = e.stack;
this.removeProgressAndRemainingFromState(device);
const payload = this.getEntityPublishPayload('available');
this.publishEntityState(device.ieeeAddr, payload);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
const meta = {status: `update_failed`, device: device.name};
this.mqtt.publish('bridge/log', stringify({type: `ota_update`, message: error, meta}));
}
}
}
this.inProgress.delete(device.ieeeAddr);
}
const triggeredViaLegacyApi = data.topic.match(legacyTopicRegex);
if (!triggeredViaLegacyApi) {
const response = utils.getResponse(message, responseData, error);
await this.mqtt.publish(`bridge/response/device/ota_update/${type}`, stringify(response));
}
if (error) {
logger.error(error);
errorStack && logger.debug(errorStack);
}
}
}
module.exports = OTAUpdate;
+289
View File
@@ -0,0 +1,289 @@
import * as settings from '../util/settings';
// @ts-ignore
import zhc from 'zigbee-herdsman-converters';
import logger from '../util/logger';
import * as utils from '../util/utils';
import ExtensionTS from './extensionts';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
import Group from '../model/group';
import Device from '../model/device';
import bind from 'bind-decorator';
const topicRegex = new RegExp(`^(.+?)(?:/(${utils.endpointNames.join('|')}))?/(get|set)(?:/(.+))?`);
const propertyEndpointRegex = new RegExp(`^(.*)_(${utils.endpointNames.join('|')})$`);
const stateValues = ['on', 'off', 'toggle', 'open', 'close', 'stop', 'lock', 'unlock'];
// Legacy: don't provide default converters anymore, this is required by older z2m installs not saving group members
const defaultGroupConverters = [
zhc.toZigbeeConverters.light_onoff_brightness,
zhc.toZigbeeConverters.light_color_colortemp,
zhc.toZigbeeConverters.effect,
zhc.toZigbeeConverters.ignore_transition,
zhc.toZigbeeConverters.cover_position_tilt,
zhc.toZigbeeConverters.thermostat_occupied_heating_setpoint,
zhc.toZigbeeConverters.tint_scene,
zhc.toZigbeeConverters.light_brightness_move,
zhc.toZigbeeConverters.light_brightness_step,
zhc.toZigbeeConverters.light_colortemp_step,
zhc.toZigbeeConverters.light_colortemp_move,
zhc.toZigbeeConverters.light_hue_saturation_move,
zhc.toZigbeeConverters.light_hue_saturation_step,
];
interface ParsedTopic {ID: string, endpoint: string, attribute: string, type: 'get' | 'set'}
class Publish extends ExtensionTS {
async start(): Promise<void> {
this.eventBus.onMQTTMessage(this, this.onMQTTMessage_);
}
parseTopic(topic: string): ParsedTopic | null {
const match = topic.match(topicRegex);
if (!match) {
return null;
}
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;
}
return {ID: ID, endpoint: match[2], type: match[3] as 'get' | 'set', attribute: match[4]};
}
parseMessage(parsedTopic: ParsedTopic, data: EventMQTTMessage): KeyValue | null {
if (parsedTopic.attribute) {
try {
return {[parsedTopic.attribute]: JSON.parse(data.message)};
} catch (e) {
return {[parsedTopic.attribute]: data.message};
}
} else {
try {
return JSON.parse(data.message);
} catch (e) {
if (stateValues.includes(data.message.toLowerCase())) {
return {state: data.message};
} else {
return null;
}
}
}
}
legacyLog(payload: KeyValue): void {
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
this.mqtt.publish('bridge/log', stringify(payload));
}
}
legacyRetrieveState(re: Device | Group, converter: ToZigbeeConverter, result: ToZigbeeConverterResult,
target: ZHEndpoint | ZHGroup, key: string, meta: ToZigbeeConverterGetMeta): void {
// It's possible for devices to get out of sync when writing an attribute that's not reportable.
// So here we re-read the value after a specified timeout, this timeout could for example be the
// transition time of a color change or for forcing a state read for devices that don't
// automatically report a new state when set.
// When reporting is requested for a device (report: true in device-specific settings) we won't
// ever issue a read here, as we assume the device will properly report changes.
// Only do this when the retrieve_state option is enabled for this device.
// retrieve_state == decprecated
if (re instanceof Device && result && result.hasOwnProperty('readAfterWriteTime') &&
re.settings.retrieve_state
) {
setTimeout(() => converter.convertGet(target, key, meta), result.readAfterWriteTime);
}
}
updateMessageHomeAssistant(message: KeyValue, entityState: KeyValue): void {
/**
* Home Assistant always publishes 'state', even when e.g. only setting
* the color temperature. This would lead to 2 zigbee publishes, where the first one
* (state) is probably unecessary.
*/
if (settings.get().homeassistant) {
const hasColorTemp = message.hasOwnProperty('color_temp');
const hasColor = message.hasOwnProperty('color');
const hasBrightness = message.hasOwnProperty('brightness');
const isOn = entityState.state === 'ON' ? true : false;
if (isOn && (hasColorTemp || hasColor) && !hasBrightness) {
delete message.state;
logger.debug('Skipping state because of Home Assistant');
}
}
}
// TODO remove trailing _
@bind async onMQTTMessage_(data: EventMQTTMessage): Promise<void> {
const parsedTopic = this.parseTopic(data.topic);
if (!parsedTopic) return;
const re = this.zigbee.resolveEntity(parsedTopic.ID);
if (re == null) {
this.legacyLog({type: `entity_not_found`, message: {friendly_name: parsedTopic.ID}});
logger.error(`Entity '${parsedTopic.ID}' is unknown`);
return;
}
// Get entity details
const definition = re instanceof Device ? re.definition : re.membersDefinitions();
if (definition == null) {
logger.error(`Cannot publish to unsupported device '${re.name}'`);
return;
}
const target = re instanceof Group ? re.zhGroup : re.endpoint(parsedTopic.endpoint);
if (target == null) {
logger.error(`Device '${re.name}' has no endpoint '${parsedTopic.endpoint}'`);
return;
}
const device = re instanceof Device ? re.zhDevice : null;
const entitySettings = re.settings;
const entityState = this.state.get(re.ID) || {};
const membersState = re instanceof Group ?
Object.fromEntries(re.membersIeeeAddr().map((e) => [e, this.state.get(e)])) : null;
let converters: ToZigbeeConverter[];
{
if (Array.isArray(definition)) {
const c = new Set(definition.map((d) => d.toZigbee).flat());
if (c.size == 0) converters = defaultGroupConverters;
else converters = Array.from(c);
} else {
converters = definition.toZigbee;
}
}
// Convert the MQTT message to a Zigbee message.
const message = this.parseMessage(parsedTopic, data);
if (message == null) {
logger.error(`Invalid message '${message}', skipping...`);
return;
}
this.updateMessageHomeAssistant(message, entityState);
/**
* Order state & brightness based on current bulb state
*
* Not all bulbs support setting the color/color_temp while it is off
* this results in inconsistant behavior between different vendors.
*
* bulb on => move state & brightness to the back
* bulb off => move state & brightness to the front
*/
const entries = Object.entries(message);
const sorter = typeof message.state === 'string' && message.state.toLowerCase() === 'off' ? 1 : -1;
entries.sort((a) => (['state', 'brightness', 'brightness_percent'].includes(a[0]) ? sorter : sorter * -1));
// For each attribute call the corresponding converter
const usedConverters: {[s: number]: ToZigbeeConverter[]} = {};
const toPublish: {[s: number | string]: KeyValue} = {};
const addToToPublish = (ID: number | string, payload: KeyValue): void => {
if (!(ID in toPublish)) toPublish[ID] = {};
toPublish[ID] = {...toPublish[ID], ...payload};
};
for (let [key, value] of entries) {
let endpointName = parsedTopic.endpoint;
let localTarget = target;
// @ts-ignore TODO fix
let endpointOrGroupID = target.constructor.name === 'Endpoint' ? target.ID : target.groupID;
// When the key has a endpointName included (e.g. state_right), this will override the target.
const propertyEndpointMatch = key.match(propertyEndpointRegex);
if (re instanceof Device && propertyEndpointMatch) {
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;
}
if (!usedConverters.hasOwnProperty(endpointOrGroupID)) usedConverters[endpointOrGroupID] = [];
const converter = converters.find((c) => c.key.includes(key));
if (parsedTopic.type === 'set' && usedConverters[endpointOrGroupID].includes(converter)) {
// Use a converter for set only once
// (e.g. light_onoff_brightness converters can convert state and brightness)
continue;
}
if (!converter) {
logger.error(`No converter available for '${key}' (${message[key]})`);
continue;
}
// Converter didn't return a result, skip
const meta = {endpoint_name: endpointName, options: entitySettings, message: {...message}, logger, device,
state: entityState, membersState, mapped: definition};
// Strip endpoint name from meta.message properties.
if (endpointName) {
for (const [key, value] of Object.entries(meta.message)) {
if (key.endsWith(endpointName)) {
delete meta.message[key];
const keyWithoutEndpoint = key.substring(0, key.length - endpointName.length - 1);
meta.message[keyWithoutEndpoint] = value;
}
}
}
try {
if (parsedTopic.type === 'set' && converter.convertSet) {
logger.debug(`Publishing '${parsedTopic.type}' '${key}' to '${re.name}'`);
const result = await converter.convertSet(localTarget, key, value, meta);
const optimistic = !entitySettings.hasOwnProperty('optimistic') || entitySettings.optimistic;
if (result && result.state && optimistic) {
const msg = result.state;
if (endpointName) {
for (const key of Object.keys(msg)) {
msg[`${key}_${endpointName}`] = msg[key];
delete msg[key];
}
}
// filter out attribute listed in filtered_optimistic
entitySettings.filtered_optimistic?.forEach((a) => delete msg[a]);
addToToPublish(re.ID, msg);
}
if (result && result.membersState && optimistic) {
for (const [ieeeAddr, state] of Object.entries(result.membersState)) {
addToToPublish(ieeeAddr, state);
}
}
this.legacyRetrieveState(re, converter, result, localTarget, key, meta);
} else if (parsedTopic.type === 'get' && converter.convertGet) {
logger.debug(`Publishing get '${parsedTopic.type}' '${key}' to '${re.name}'`);
await converter.convertGet(localTarget, key, meta);
} else {
logger.error(`No converter available for '${parsedTopic.type}' '${key}' (${message[key]})`);
continue;
}
} catch (error) {
const message =
`Publish '${parsedTopic.type}' '${key}' to '${re.name}' failed: '${error}'`;
logger.error(message);
logger.debug(error.stack);
this.legacyLog({type: `zigbee_publish_error`, message, meta: {friendly_name: re.name}});
}
usedConverters[endpointOrGroupID].push(converter);
}
for (const [ID, payload] of Object.entries(toPublish)) {
if (Object.keys(payload).length != 0) {
this.publishEntityState(ID, payload);
}
}
}
}
// TODO_finished: : change class to export default
module.exports = Publish;
+162
View File
@@ -0,0 +1,162 @@
import * as settings from '../util/settings';
import logger from '../util/logger';
import debounce from 'debounce';
import ExtensionTS from './extensionts';
// @ts-ignore
import stringify from 'json-stable-stringify-without-jsonify';
import bind from 'bind-decorator';
class Receive extends ExtensionTS {
private elapsed: {[s: string]: number} = {};
// eslint-disable-next-line
private debouncers: {[s: string]: {payload: KeyValue, publish: any}} = {}; //TODO fix type
async start(): Promise<void> {
this.eventBus.onPublishEntityState(this, this.onPublishEntityState);
this.eventBus.onDeviceMessage(this, this.onDeviceMessage);
}
@bind async onPublishEntityState(data: EventPublishEntityState): Promise<void> {
/**
* Prevent that outdated properties are being published.
* In case that e.g. the state is currently held back by a debounce and a new state is published
* remove it from the to be send debounced message.
*/
if (data.ieeeAddr && this.debouncers[data.ieeeAddr] && data.stateChangeReason !== 'publishDebounce') {
for (const key of Object.keys(data.payload)) {
delete this.debouncers[data.ieeeAddr].payload[key];
}
}
}
publishDebounce(ieeeAddr: string, payload: KeyValue, time: number, debounceIgnore: string[]): void {
if (!this.debouncers[ieeeAddr]) {
this.debouncers[ieeeAddr] = {
payload: {},
publish: debounce(() => {
this.publishEntityState(ieeeAddr, this.debouncers[ieeeAddr].payload, 'publishDebounce');
this.debouncers[ieeeAddr].payload = {};
}, time * 1000),
};
}
if (this.isPayloadConflicted(payload, this.debouncers[ieeeAddr].payload, debounceIgnore)) {
// publish previous payload immediately
this.debouncers[ieeeAddr].publish.flush();
}
// extend debounced payload with current
this.debouncers[ieeeAddr].payload = {...this.debouncers[ieeeAddr].payload, ...payload};
this.debouncers[ieeeAddr].publish();
}
// if debounce_ignore are specified (Array of strings)
// then all newPayload values with key present in debounce_ignore
// should equal or be undefined in oldPayload
// otherwise payload is conflicted
isPayloadConflicted(newPayload: KeyValue, oldPayload: KeyValue, debounceIgnore: string[] | null): boolean {
let result = false;
Object.keys(oldPayload)
.filter((key) => (debounceIgnore || []).includes(key))
.forEach((key) => {
if (typeof newPayload[key] !== 'undefined' && newPayload[key] !== oldPayload[key]) {
result = true;
}
});
return result;
}
shouldProcess(data: EventDeviceMessage): boolean {
if (!data.device.definition) {
if (data.device.interviewing) {
logger.debug(`Skipping message, definition is undefined and still interviewing`);
} else {
logger.warn(
`Received message from unsupported device with Zigbee model '${data.device.modelID}' ` +
`and manufacturer name '${data.device.manufacturerName}'`);
logger.warn(`Please see: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html.`);
}
return false;
}
return true;
}
@bind onDeviceMessage(data: EventDeviceMessage): void {
/* istanbul ignore next */
if (!data.device) return;
/**
* Handling of re-transmitted Xiaomi messages.
* https://github.com/Koenkk/zigbee2mqtt/issues/1238
* https://github.com/Koenkk/zigbee2mqtt/issues/3592
*
* Some Xiaomi router devices re-transmit messages from Xiaomi end devices.
* The network address of these message is set to the one of the Xiaomi router.
* Therefore it looks like if the message came from the Xiaomi router, while in
* fact it came from the end device.
* Handling these message would result in false state updates.
* The group ID attribute of these message defines the network address of the end device.
*/
if (data.device.isXiaomiDevice() && data.device.isRouter() && data.groupID) {
logger.debug('Handling re-transmitted Xiaomi message');
data = {...data, device: this.zigbee.deviceByNetworkAddress(data.groupID)};
}
if (!this.shouldProcess(data)) return;
const converters = data.device.definition.fromZigbee.filter((c) => {
const type = Array.isArray(c.type) ? c.type.includes(data.type) : c.type === data.type;
return c.cluster === data.cluster && type;
});
// Check if there is an available converter, genOta messages are not interesting.
const ignoreClusters: (string | number)[] = ['genOta', 'genTime', 'genBasic'];
if (converters.length == 0 && !ignoreClusters.includes(data.cluster)) {
logger.debug(`No converter available for '${data.device.definition.model}' with ` +
`cluster '${data.cluster}' and type '${data.type}' and data '${stringify(data.data)}'`);
return;
}
// Convert this Zigbee message to a MQTT message.
// Get payload for the message.
// - If a payload is returned publish it to the MQTT broker
// - If NO payload is returned do nothing. This is for non-standard behaviour
// for e.g. click switches where we need to count number of clicks and detect long presses.
const publish = (payload: KeyValue): void => {
if (settings.get().advanced.elapsed) {
const now = Date.now();
if (this.elapsed[data.device.ieeeAddr]) {
payload.elapsed = now - this.elapsed[data.device.ieeeAddr];
}
this.elapsed[data.device.ieeeAddr] = now;
}
// Check if we have to debounce
if (data.device.settings.debounce) {
this.publishDebounce(data.device.ieeeAddr, payload, data.device.settings.debounce,
data.device.settings.debounce_ignore);
} else {
this.publishEntityState(data.device.ieeeAddr, payload);
}
};
const meta = {device: data.device.zhDevice, logger, state: this.state.get(data.device.ieeeAddr)};
let payload = {};
converters.forEach((converter) => {
const converted = converter.convert(data.device.definition, data, publish, data.device.settings, meta);
if (converted) {
payload = {...payload, ...converted};
}
});
if (Object.keys(payload).length) {
publish(payload);
}
}
}
module.exports = Receive;
-75
View File
@@ -1,75 +0,0 @@
const Zcl = require('zigbee-herdsman/dist/zcl');
const OneJanuary2000 = new Date('January 01, 2000 00:00:00').getTime();
/**
* This extensions is reponsible for respondig to device requests.
*/
class ExtensionResponder {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.mqtt = mqtt;
this.state = state;
this.publishEntityState = publishEntityState;
this.onZclFoundation = this.onZclFoundation.bind(this);
this.configured = [];
}
setupOnZclFoundation(device) {
if (device && device.epList && !this.configured.includes(device.ieeeAddr)) {
this.configured.push(device.ieeeAddr);
device.epList.forEach((epID) => {
const ep = this.zigbee.getEndpoint(device.ieeeAddr, epID);
ep.onZclFoundation = this.onZclFoundation;
});
}
}
onZigbeeStarted() {
this.zigbee.getAllClients().forEach((device) => this.setupOnZclFoundation(device));
}
onZigbeeMessage(message, device, mappedDevice) {
this.setupOnZclFoundation(device);
}
readResponse(message, endpoint) {
const clusterID = message.clusterid;
const cluster = Zcl.getClusterLegacy(clusterID).key;
const attributes = message.zclMsg.payload.map((p) => Zcl.getAttributeLegacy(message.clusterid, p.attrId));
const response = [];
attributes.forEach((attribute) => {
if (cluster === 'genTime' && attribute.key === 'time') {
const time = Math.round(((new Date()).getTime() - OneJanuary2000) / 1000);
response.push(this.createReadResponseRec(clusterID, attribute.value, time));
}
});
this.zigbee.publish(
endpoint.device.ieeeAddr, 'device', cluster, 'readRsp', 'foundation', response,
{direction: 1, seqNum: message.zclMsg.seqNum, disDefaultRsp: 1}, endpoint.epId,
);
}
createReadResponseRec(cId, attrId, value) {
return {
attrId: attrId,
status: 0,
attrData: value,
dataType: Zcl.getAttributeTypeLegacy(cId, attrId).value,
};
}
onZclFoundation(message, endpoint) {
const cmd = message.zclMsg.cmdId;
if (cmd === 'read') {
this.readResponse(message, endpoint);
}
}
}
module.exports = ExtensionResponder;
-63
View File
@@ -1,63 +0,0 @@
const settings = require('../util/settings');
const logger = require('../util/logger');
const utils = require('../util/utils');
/**
* This extensions soft resets the ZNP after a certain timeout.
*/
class SoftReset {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.timer = null;
this.timeout = utils.secondsToMilliseconds(settings.get().advanced.soft_reset_timeout);
}
onZigbeeStarted() {
logger.debug(`Soft reset timeout set to ${utils.millisecondsToSeconds(this.timeout)} seconds`);
this.resetTimer();
}
clearTimer() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
resetTimer() {
if (this.timeout === 0) {
return;
}
this.clearTimer();
this.timer = setTimeout(() => this.handleTimeout(), this.timeout);
}
handleTimeout() {
logger.warn('Soft reset timeout triggered');
this.zigbee.softReset((error) => {
if (error) {
logger.warn('Soft reset failed, trying stop/start');
this.zigbee.stop((error) => {
logger.warn('Zigbee stopped');
this.zigbee.start((error) => {
if (error) {
logger.error('Failed to restart!');
}
});
});
} else {
logger.warn('Soft resetted ZNP due to timeout');
}
this.resetTimer();
});
}
onZigbeeMessage(message, device, mappedDevice) {
this.resetTimer();
}
}
module.exports = SoftReset;
-70
View File
@@ -1,70 +0,0 @@
const utils = require('../util/utils');
const interval = utils.secondsToMilliseconds(60);
const logger = require('../util/logger');
const settings = require('../util/settings');
/**
* This extensions handles Xiaomi devices.
* - Marks Xiaomi devices as online.
* - Polls Xiaomi routers to keep them awake.
*/
class Xiaomi {
constructor(zigbee, mqtt, state, publishEntityState) {
this.zigbee = zigbee;
this.timer = null;
}
onZigbeeStarted() {
// Set all Xiaomi devices to be online, so shepherd won't try
// to query info from devices (which would fail because they go to sleep).
const devices = this.zigbee.getAllClients();
devices.forEach((d) => {
if (utils.isXiaomiDevice(d)) {
const device = this.zigbee.shepherd.find(d.ieeeAddr, 1);
if (device) {
device.getDevice().update({
status: 'online',
joinTime: Math.floor(Date.now() / 1000),
});
}
}
});
/**
* Device availability already pings Xiaomi devices.
*/
if (!settings.get().advanced.availability_timeout) {
this.startTimer();
} else {
logger.debug('Disabled pinging of Xiaomi devices in Xiaomi extension because availability is enabled');
}
}
startTimer() {
this.clearTimer();
this.timer = setInterval(() => this.handleInterval(), interval);
}
clearTimer() {
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
}
stop() {
this.clearTimer();
}
ping(ieeeAddr) {
this.zigbee.ping(ieeeAddr, 'error', null, 'basic');
}
handleInterval() {
this.zigbee.getAllClients()
.filter((d) => utils.isXiaomiDevice(d) && utils.isRouter(d) && !utils.isBatteryPowered(d))
.forEach((d) => this.ping(d.ieeeAddr));
}
}
module.exports = Xiaomi;
+71
View File
@@ -0,0 +1,71 @@
/* eslint-disable brace-style */
import * as settings from '../util/settings';
// @ts-ignore
import zhc from 'zigbee-herdsman-converters';
export default class Device {
private device: ZHDevice;
private _definition: Definition;
get endpoints(): ZHEndpoint[] {return this.device.endpoints;}
get zhDevice(): ZHDevice {return this.device;}
get ieeeAddr(): string {return this.device.ieeeAddr;}
get ID(): string {return this.device.ieeeAddr;}
get settings(): DeviceSettings {return {...settings.get().device_options, ...settings.getDevice(this.ieeeAddr)};}
get name(): string {
return this.type === 'Coordinator' ? 'Coordinator' : this.settings?.friendlyName || this.ieeeAddr;}
get lastSeen(): number {return this.device.lastSeen;}
get modelID(): string {return this.device.modelID;}
get softwareBuildID(): string {return this.device.softwareBuildID;}
get dateCode(): string {return this.device.dateCode;}
get interviewCompleted(): boolean {return this.device.interviewCompleted;}
get networkAddress(): number {return this.device.networkAddress;}
get manufacturerName(): string {return this.device.manufacturerName;}
get interviewing(): boolean {return this.device.interviewing;}
get type(): 'Coordinator' | 'Router' | 'EndDevice' | 'Unknown' | 'GreenPower' {return this.device.type;}
get powerSource(): string {return this.device.powerSource;}
get definition(): Definition | undefined {
if (!this._definition && !this.device.interviewing) {
this._definition = zhc.findByDevice(this.device);
}
return this._definition;
}
constructor(device: ZHDevice) {
this.device = device;
}
async ping(disableRecovery: boolean): Promise<void> {await this.device.ping(disableRecovery);}
async removeFromNetwork(): Promise<void> {await this.device.removeFromNetwork();}
endpoint(key?: string): ZHEndpoint {
let endpoint: ZHEndpoint;
if (key == null) key = 'default';
if (!isNaN(Number(key))) {
endpoint = this.device.getEndpoint(Number(key));
} else if (this.definition?.endpoint) {
const ID = this.definition?.endpoint?.(this.device)[key];
if (ID) endpoint = this.device.getEndpoint(ID);
else if (key === 'default') endpoint = this.device.endpoints[0];
else return null;
} else {
/* istanbul ignore next */
if (key !== 'default') return null;
endpoint = this.device.endpoints[0];
}
return endpoint;
}
isXiaomiDevice(): boolean {
const xiaomiManufacturerID = [4151, 4447];
/* istanbul ignore next */
return this.zhDevice.modelID !== 'lumi.router' && xiaomiManufacturerID.includes(this.zhDevice.manufacturerID) &&
(!this.zhDevice.manufacturerName || !this.zhDevice.manufacturerName.startsWith('Trust'));
}
isRouter(): boolean {return this.zhDevice.type === 'Router';}
lqi(): Promise<LQI> {return this.zhDevice.lqi();}
routingTable(): Promise<RoutingTable> {return this.zhDevice.routingTable();}
}
+26
View File
@@ -0,0 +1,26 @@
/* eslint-disable brace-style */
import * as settings from '../util/settings';
// @ts-ignore
import zhc from 'zigbee-herdsman-converters';
export default class Group {
private group: ZHGroup;
get zhGroup(): ZHGroup {return this.group;}
get ID(): number {return this.group.groupID;}
get settings(): GroupSettings {return settings.getGroup(this.ID);}
get name(): string {return this.settings?.friendlyName || this.ID.toString();}
get members(): ZHEndpoint[] {return this.group.members;}
constructor(group: ZHGroup) {
this.group = group;
}
membersDefinitions(): Definition[] {
return this.members.map((m) => zhc.findByDevice(m.getDevice())).filter((d) => d) as Definition[];
}
membersIeeeAddr(): string[] {
return this.members.map((m) => m.getDevice().ieeeAddr);
}
}
-136
View File
@@ -1,136 +0,0 @@
const mqtt = require('mqtt');
const logger = require('./util/logger');
const settings = require('./util/settings');
const fs = require('fs');
class MQTT {
constructor() {
this.onConnect = this.onConnect.bind(this);
this.onMessage = this.onMessage.bind(this);
this.messageHandler = null;
}
connect(messageHandler, callback) {
const mqttSettings = settings.get().mqtt;
logger.info(`Connecting to MQTT server at ${mqttSettings.server}`);
const options = {
will: {
topic: `${settings.get().mqtt.base_topic}/bridge/state`,
payload: 'offline',
retain: true,
},
};
if (mqttSettings.ca) {
logger.debug(`MQTT SSL/TLS: Path to CA certificate = ${mqttSettings.ca}`);
const ca = fs.readFileSync(mqttSettings.ca);
if (ca) {
options.ca = ca;
} else {
logger.error(`Error loading CA certificate for MQTT SSL/TLS configuration.`);
}
}
if (mqttSettings.key && mqttSettings.cert) {
logger.debug(`MQTT SSL/TLS: Path to client key = ${mqttSettings.key}`);
logger.debug(`MQTT SSL/TLS: Path to client certificate = ${mqttSettings.cert}`);
const key = fs.readFileSync(mqttSettings.key);
const cert = fs.readFileSync(mqttSettings.cert);
if (key && cert) {
options.key = key;
options.cert = cert;
} else {
logger.error(`Error loading key and/or certificate for MQTT SSL/TLS client authentication.`);
}
}
if (mqttSettings.user && mqttSettings.password) {
options.username = mqttSettings.user;
options.password = mqttSettings.password;
}
if (mqttSettings.client_id) {
logger.debug(`Using MQTT client ID: '${mqttSettings.client_id}'`);
options.clientId = mqttSettings.client_id;
}
if (mqttSettings.hasOwnProperty('reject_unauthorized') && !mqttSettings.reject_unauthorized) {
logger.debug(`MQTT reject_unauthorized set false, ignoring certificate warnings.`);
options.rejectUnauthorized = false;
}
this.client = mqtt.connect(mqttSettings.server, options);
// Register callbacks.
this.client.on('connect', () => {
this.onConnect();
callback();
});
this.client.on('message', this.onMessage);
// Set timer at interval to check if connected to MQTT server.
const interval = 10 * 1000; // seconds * 1000.
this.connectionTimer = setInterval(() => {
if (this.client.reconnecting) {
logger.error('Not connected to MQTT server!');
}
}, interval);
this.messageHandler = messageHandler;
}
disconnect() {
clearTimeout(this.connectionTimer);
this.connectionTimer = null;
this.publish('bridge/state', 'offline', {retain: true, qos: 0}, () => {
logger.info('Disconnecting from MQTT server');
this.client.end();
});
}
onConnect() {
logger.info('Connected to MQTT server');
this.publish('bridge/state', 'online', {retain: true, qos: 0});
}
subscribe(topic) {
this.client.subscribe(topic);
}
onMessage(topic, message) {
if (this.messageHandler) {
this.messageHandler(topic, message);
}
}
publish(topic, payload, options, callback, base=settings.get().mqtt.base_topic) {
topic = `${base}/${topic}`;
if (!this.client || this.client.reconnecting) {
logger.error(`Not connected to MQTT server!`);
logger.error(`Cannot send message: topic: '${topic}', payload: '${payload}`);
return;
}
logger.info(`MQTT publish: topic '${topic}', payload '${payload}'`);
this.client.publish(topic, payload, options, callback);
}
log(type, message, meta=null) {
const payload = {type, message};
if (meta) {
payload.meta = meta;
}
this.publish('bridge/log', JSON.stringify(payload), {retain: false});
}
}
module.exports = MQTT;
+153
View File
@@ -0,0 +1,153 @@
import mqtt from 'mqtt';
import logger from './util/logger';
import * as settings from './util/settings';
import {seconds} from './util/utils';
import fs from 'fs';
export default class MQTT {
private publishedTopics: Set<string> = new Set();
private connectionTimer: NodeJS.Timeout;
private client: mqtt.MqttClient;
private eventBus: EventBus;
constructor(eventBus: EventBus) {
this.eventBus = eventBus;
this.onMessage = this.onMessage.bind(this);
this.onConnect = this.onConnect.bind(this);
}
async connect(): Promise<void> {
const mqttSettings = settings.get().mqtt;
logger.info(`Connecting to MQTT server at ${mqttSettings.server}`);
const options: mqtt.IClientOptions = {
will: {
topic: `${settings.get().mqtt.base_topic}/bridge/state`,
payload: 'offline',
retain: settings.get().mqtt.force_disable_retain ? false : true,
qos: 1,
},
};
if (mqttSettings.version) {
options.protocolVersion = mqttSettings.version;
}
if (mqttSettings.keepalive) {
logger.debug(`Using MQTT keepalive: ${mqttSettings.keepalive}`);
options.keepalive = mqttSettings.keepalive;
}
if (mqttSettings.ca) {
logger.debug(`MQTT SSL/TLS: Path to CA certificate = ${mqttSettings.ca}`);
options.ca = fs.readFileSync(mqttSettings.ca);
}
if (mqttSettings.key && mqttSettings.cert) {
logger.debug(`MQTT SSL/TLS: Path to client key = ${mqttSettings.key}`);
logger.debug(`MQTT SSL/TLS: Path to client certificate = ${mqttSettings.cert}`);
options.key = fs.readFileSync(mqttSettings.key);
options.cert = fs.readFileSync(mqttSettings.cert);
}
if (mqttSettings.user && mqttSettings.password) {
logger.debug(`Using MQTT login with username: ${mqttSettings.user}`);
options.username = mqttSettings.user;
options.password = mqttSettings.password;
} else {
logger.debug(`Using MQTT anonymous login`);
}
if (mqttSettings.client_id) {
logger.debug(`Using MQTT client ID: '${mqttSettings.client_id}'`);
options.clientId = mqttSettings.client_id;
}
if (mqttSettings.hasOwnProperty('reject_unauthorized') && !mqttSettings.reject_unauthorized) {
logger.debug(`MQTT reject_unauthorized set false, ignoring certificate warnings.`);
options.rejectUnauthorized = false;
}
return new Promise((resolve) => {
this.client = mqtt.connect(mqttSettings.server, options);
const onConnect = this.onConnect;
this.client.on('connect', async () => {
await onConnect();
resolve();
});
this.client.on('message', this.onMessage);
});
}
private async onConnect(): Promise<void> {
// Set timer at interval to check if connected to MQTT server.
clearTimeout(this.connectionTimer);
this.connectionTimer = setInterval(() => {
if (this.client.reconnecting) {
logger.error('Not connected to MQTT server!');
}
}, seconds(10));
logger.info('Connected to MQTT server');
this.subscribe(`${settings.get().mqtt.base_topic}/#`);
await this.publish('bridge/state', 'online', {retain: true, qos: 0});
}
async disconnect(): Promise<void> {
clearTimeout(this.connectionTimer);
await this.publish('bridge/state', 'offline', {retain: true, qos: 0});
logger.info('Disconnecting from MQTT server');
this.client.end();
}
subscribe(topic: string): void {
this.client.subscribe(topic);
}
public onMessage(topic: string, message: string): void {
// Since we subscribe to zigbee2mqtt/# we also receive the message we send ourselves, skip these.
if (!this.publishedTopics.has(topic)) {
this.eventBus.emitMQTTMessage({topic, message: message + ''});
}
}
isConnected(): boolean {
return this.client && !this.client.reconnecting;
}
async publish(topic: string, payload: string, options: {qos?: mqtt.QoS, retain?: boolean}={},
base=settings.get().mqtt.base_topic, skipLog=false, skipReceive=true,
): Promise<void> {
const defaultOptions: {qos: mqtt.QoS, retain: boolean} = {qos: 0, retain: false};
topic = `${base}/${topic}`;
if (skipReceive) {
this.publishedTopics.add(topic);
}
this.eventBus.emitMQTTMessagePublished({topic, payload, options: {...defaultOptions, ...options}});
if (!this.isConnected()) {
if (!skipLog) {
logger.error(`Not connected to MQTT server!`);
logger.error(`Cannot send message: topic: '${topic}', payload: '${payload}`);
}
return;
}
if (!skipLog) {
logger.info(`MQTT publish: topic '${topic}', payload '${payload}'`);
}
const actualOptions: mqtt.IClientPublishOptions = {...defaultOptions, ...options};
if (settings.get().mqtt.force_disable_retain) {
actualOptions.retain = false;
}
return new Promise((resolve) => {
this.client.publish(topic, payload, actualOptions, () => resolve());
});
}
}
+53 -53
View File
@@ -1,26 +1,23 @@
const logger = require('./util/logger');
const data = require('./util/data');
const fs = require('fs');
const settings = require('./util/settings');
const fs = require('fs');
const objectAssignDeep = require('object-assign-deep');
const saveInterval = 1000 * 60 * 5; // 5 minutes
const dontCacheProperties = [
'action', 'button', 'button_left', 'button_right', 'click', 'forgotten', 'keyerror',
'step_size', 'transition_time', 'action_color_temperature', 'action_color',
'action_group', 'group_list', 'group_capacity', 'no_occupancy_since',
'step_mode', 'transition_time', 'duration', 'elapsed',
'^action$', '^action_.*$', '^button$', '^button_left$', '^button_right$', '^click$', '^forgotten$', '^keyerror$',
'^step_size$', '^transition_time$', '^group_list$', '^group_capacity$', '^no_occupancy_since$',
'^step_mode$', '^transition_time$', '^duration$', '^elapsed$', '^from_side$', '^to_side$',
];
class State {
constructor() {
constructor(eventBus) {
this.state = {};
this.file = data.joinPath('state.json');
this.timer = null;
this.stateChangeListeners = [];
this.handleSettingsChanged = this.handleSettingsChanged.bind(this);
this.eventBus = eventBus;
}
start() {
@@ -29,31 +26,6 @@ class State {
// Save the state on every interval
this.clearTimer();
this.timer = setInterval(() => this.save(), saveInterval);
// Listen for on settings changed events.
settings.addOnChangeHandler(this.handleSettingsChanged);
this.checkLastSeen();
}
handleSettingsChanged() {
this.checkLastSeen();
}
registerOnStateChangeListener(listener) {
this.stateChangeListeners.push(listener);
}
checkLastSeen() {
if (settings.get().advanced.last_seen === 'disable') {
Object.values(this.state).forEach((s) => {
if (s.hasOwnProperty('last_seen')) {
delete s.last_seen;
}
});
this.save();
}
}
clearTimer() {
@@ -82,36 +54,64 @@ class State {
}
save() {
logger.debug(`Saving state to file ${this.file}`);
const json = JSON.stringify(this.state, null, 4);
fs.writeFileSync(this.file, json, 'utf8');
if (settings.get().advanced.cache_state_persistent) {
logger.debug(`Saving state to file ${this.file}`);
const json = JSON.stringify(this.state, null, 4);
try {
fs.writeFileSync(this.file, json, 'utf8');
} catch (e) {
logger.error(`Failed to write state to '${this.file}' (${e.message})`);
}
} else {
logger.debug(`Not saving state`);
}
}
exists(ieeeAddr) {
return this.state.hasOwnProperty(ieeeAddr);
exists(ID) {
return this.state.hasOwnProperty(ID);
}
get(ieeeAddr) {
return this.state[ieeeAddr];
get(ID) {
return this.state[ID];
}
set(ieeeAddr, state) {
const toState = objectAssignDeep.noMutate(state);
dontCacheProperties.forEach((property) => {
if (toState.hasOwnProperty(property)) {
set(ID, update, reason=null) {
const fromState = this.state[ID] || {};
const toState = objectAssignDeep.noMutate(fromState, update);
const result = {...toState};
for (const property of Object.keys(toState)) {
if (dontCacheProperties.find((p) => property.match(p))) {
delete toState[property];
}
});
}
const fromState = this.state[ieeeAddr];
this.stateChangeListeners.forEach((listener) => listener(ieeeAddr, fromState, toState));
this.state[ieeeAddr] = toState;
this.state[ID] = toState;
this.eventBus.emit('stateChange', {ID, from: fromState, to: toState, reason, update});
return result;
}
remove(ieeeAddr) {
if (this.exists(ieeeAddr)) {
delete this.state[ieeeAddr];
removeKey(ID, path) {
if (this.exists(ID)) {
let state = this.state[ID];
for (let i = 0; i < path.length; i++) {
const key = path[i];
if (i === path.length - 1) {
delete state[key];
} else {
if (state[key]) {
state = state[key];
} else {
break;
}
}
}
}
}
remove(ID) {
if (this.exists(ID)) {
delete this.state[ID];
}
}
}
+279
View File
@@ -0,0 +1,279 @@
import type {
Device as ZZHDevice,
Group as ZZHGroup,
Endpoint as ZZHEndpoint,
} from 'zigbee-herdsman/dist/controller/model';
import {
NetworkParameters as ZHNetworkParameters,
CoordinatorVersion as ZHCoordinatorVersion,
LQI as ZHLQI,
RoutingTable as ZHRoutingTable,
RoutingTableEntry as ZHRoutingTableEntry,
} from 'zigbee-herdsman/dist/adapter/tstype';
import * as D from 'lib/model/device';
import * as Z from 'lib/zigbee';
import * as E from 'lib/eventBus';
import * as M from 'lib/mqtt';
// TODO: check all
declare global {
type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
type EventBus = E.default;
type MQTT = M.default;
type Zigbee = Z.default;
type Device = D.default;
type ZHEndpoint = ZZHEndpoint;
type ZHDevice = ZZHDevice;
type LQI = ZHLQI;
type RoutingTable = ZHRoutingTable;
type RoutingTableEntry = ZHRoutingTableEntry;
type ZHGroup = ZZHGroup;
type CoordinatorVersion = ZHCoordinatorVersion;
type NetworkParameters = ZHNetworkParameters;
type ZigbeeEventType = 'deviceLeave' | 'deviceAnnounce';
interface ZigbeeEventData {
ieeeAddr: string;
}
/* eslint-disable */
// Controller
interface KeyValue {
[s: string]: any,
}
interface Settings {
homeassistant?: boolean,
devices?: {[s: string]: {friendly_name: string, retention?: number}},
groups?: {[s: string]: {friendly_name: string, devices?: string[]}},
passlist: string[],
blocklist: string[],
whitelist: string[],
ban: string[],
availability?: boolean | {
active?: {timeout?: number},
passive?: {timeout?: number}
},
permit_join: boolean,
frontend?: {
auth_token?: string,
host?: string,
port?: number,
},
mqtt: {
base_topic: string,
include_device_information: boolean,
force_disable_retain: boolean
version?: number,
user?: string,
password?: string,
server: string,
ca?: string,
keepalive?: number,
key?: string,
cert?: string,
client_id?: string,
reject_unauthorized?: boolean,
},
serial: {
disable_led?: boolean,
port?: string,
adapter?: 'deconz' | 'zstack' | 'ezsp' | 'zigate'
},
device_options: {[s: string]: unknown},
map_options: {
graphviz: {
colors: {
fill: {
enddevice: string,
coordinator: string,
router: string,
},
font: {
coordinator: string,
router: string,
enddevice: string,
},
line: {
active: string,
inactive: string,
},
},
},
},
experimental: {
output: 'json' | 'attribute' | 'attribute_and_json',
availability_new?: boolean,
transmit_power?: number,
},
advanced: {
legacy_api: boolean,
log_rotation: boolean,
log_symlink_current: boolean,
log_output: ('console' | 'file')[],
log_directory: string,
log_file: string,
log_level: 'debug' | 'info' | 'error' | 'warn',
log_syslog: {},
soft_reset_timeout: number,
pan_id: number | 'GENERATE',
ext_pan_id: number[],
channel: number,
adapter_concurrent: number | null,
adapter_delay: number | null,
availability_timeout: number,
availability_blocklist: string[],
availability_passlist: string[],
availability_blacklist: string[],
availability_whitelist: string[],
cache_state: boolean,
cache_state_persistent: boolean,
cache_state_send_on_startup: boolean,
last_seen: 'disable' | 'ISO_8601' | 'ISO_8601_local' | 'epoch',
elapsed: boolean,
network_key: number[] | 'GENERATE',
report: boolean,
homeassistant_discovery_topic: string,
homeassistant_status_topic: string,
homeassistant_legacy_entity_attributes: boolean,
homeassistant_legacy_triggers: boolean,
timestamp_format: string,
baudrate?: number,
rtscts?: boolean,
ikea_ota_use_test_url?: boolean,
},
ota: {
update_check_interval: number,
disable_automatic_update_check: boolean
},
external_converters: string[],
}
interface DeviceSettings {
friendlyName: string,
ID: string,
retention?: number,
availability?: boolean | {timeout: number},
optimistic?: boolean,
retrieve_state?: boolean,
debounce?: number,
debounce_ignore?: string[],
filtered_optimistic?: string[],
icon?: string,
homeassistant?: KeyValue,
legacy?: boolean,
}
interface GroupSettings {
friendlyName: string,
devices: string[],
ID: number,
optimistic?: boolean,
filtered_optimistic?: string[],
retrieve_state?: boolean,
homeassistant?: KeyValue,
}
type EntitySettings = {
type: 'device' | 'group'
ID: number | string,
friendlyName: string,
}
interface ResolvedEntity {
type: 'device' | 'group',
device: ZHDevice,
name: string,
}
interface ToZigbeeConverterGetMeta {message: {}, mapped: Definition | Definition[]}
interface ToZigbeeConverterResult {state: KeyValue, membersState: {[s: string]: KeyValue}, readAfterWriteTime?: number}
interface ToZigbeeConverter {
key: string[],
convertGet?: (entity: ZHEndpoint | ZHGroup, key: string, meta: ToZigbeeConverterGetMeta) => Promise<void>
convertSet?: (entity: ZHEndpoint | ZHGroup, key: string, value: any, meta: {state: KeyValue}) => Promise<ToZigbeeConverterResult>
}
// interface Logger {
// error: (message: string) => void;
// warn: (message: string) => void;
// debug: (message: string) => void;
// info: (message: string) => void;
// }
interface FromZigbeeConverter {
cluster: string,
type: string[] | string,
convert: (model: Definition, msg: KeyValue, publish: (payload: KeyValue) => void, options: KeyValue,
meta: {state: KeyValue, logger: any, device: ZHDevice}) => KeyValue,
}
interface DefinitionExposeFeature {name: string, endpoint?: string, property: string, value_max?: number, value_min?: number, value_off?: string, value_on?: string, value_step?: number, values: string[], access: number}
interface DefinitionExpose {type: string, name?: string, features?: DefinitionExposeFeature[], endpoint?: string, values?: string[], value_off?: string, value_on?: string, access: number, property: string, unit?: string, value_min?: number, value_max?: number}
interface Definition {
model: string
endpoint?: (device: ZHDevice) => {[s: string]: number}
toZigbee: ToZigbeeConverter[]
fromZigbee: FromZigbeeConverter[]
icon?: string
description: string
vendor: string
exposes: DefinitionExpose[] // TODO
configure?: (device: ZHDevice, coordinatorEndpoint: ZZHEndpoint, logger: unknown) => Promise<void>;
onEvent?: (type: string, data: KeyValue, device: ZHDevice, settings: KeyValue) => Promise<void>;
ota?: {
isUpdateAvailable: (device: ZHDevice, logger: unknown, data?: KeyValue) => Promise<boolean>;
updateToLatest: (device: ZHDevice, logger: unknown, onProgress: (progress: number, remaining: number) => void) => Promise<void>;
}
}
interface ResolvedDevice {
type: 'device',
definition?: Definition,
name: string,
endpoint: ZHEndpoint,
device: ZHDevice,
settings: {
friendlyName: string,
availability?: {timeout?: number} | boolean,
}
}
interface TempMQTT {
publish: (topic: string, payload: string, options: {}, base?: string, skipLog?: boolean, skipReceive?: boolean) => Promise<void>;
}
interface TempState {
get: (ID: string | number) => KeyValue | null;
remove: (ID: string | number) => void;
removeKey: (ID: string, keys: string[]) => void;
exists: (ID: string) => boolean;
}
interface ExternalConverterClass {
new(zigbee: Zigbee, mqtt: MQTT, state: TempState, publishEntityState: PublishEntityState,
eventBus: EventBus, settings: unknown, logger: unknown): ExternalConverterClass;
}
interface MQTTResponse {data: KeyValue, status: string, error?: string, transaction?: string}
type PublishEntityState = (ID: string | number, payload: KeyValue, stateChangeReason?: 'publishDebounce') => void;
}
-33
View File
@@ -1,33 +0,0 @@
const path = require('path');
const fs = require('fs');
let dataPath = null;
function load() {
if (process.env.ZIGBEE2MQTT_DATA) {
dataPath = process.env.ZIGBEE2MQTT_DATA;
} else {
dataPath = path.join(__dirname, '..', '..', 'data');
dataPath = path.normalize(dataPath);
}
}
load();
function joinPathStorage(file) {
const storagePath = path.join(dataPath, '.storage');
if (!fs.existsSync(storagePath)) {
fs.mkdirSync(storagePath);
}
return path.join(storagePath, file);
}
module.exports = {
joinPath: (file) => path.join(dataPath, file),
joinPathStorage: (file) => joinPathStorage(file),
getPath: () => dataPath,
// For test only.
_reload: () => load(),
};
+27
View File
@@ -0,0 +1,27 @@
import path from 'path';
let dataPath: string = null;
function load(): void {
if (process.env.ZIGBEE2MQTT_DATA) {
dataPath = process.env.ZIGBEE2MQTT_DATA;
} else {
dataPath = path.join(__dirname, '..', '..', 'data');
dataPath = path.normalize(dataPath);
}
}
load();
export function joinPath(file: string): string {
return path.join(dataPath, file);
}
export function getPath(): string {
return dataPath;
}
// eslint-disable-next-line camelcase
export function __testingOnly_reload(): void {
load();
}
-16
View File
@@ -1,16 +0,0 @@
const yaml = require('js-yaml');
const fs = require('fs');
function readYaml(file) {
return yaml.safeLoad(fs.readFileSync(file, 'utf8'));
}
function readYamlIfExists(file) {
return fs.existsSync(file) ? readYaml(file) : null;
}
function writeYaml(file, content) {
fs.writeFileSync(file, yaml.safeDump(content));
}
module.exports = {readYaml, readYamlIfExists, writeYaml};
+123 -48
View File
@@ -5,61 +5,109 @@ const path = require('path');
const fs = require('fs');
const fx = require('mkdir-recursive');
const rimraf = require('rimraf');
const colorizer = winston.format.colorize();
const assert = require('assert');
// Determine the log level.
const level = settings.get().advanced.log_level;
// What transports to enable
const output = settings.get().advanced.log_output;
// Directoy to log to
// Directory to log to
const timestamp = moment(Date.now()).format('YYYY-MM-DD.HH-mm-ss');
const directory = settings.get().advanced.log_directory.replace('%TIMESTAMP%', timestamp);
const logFilename = settings.get().advanced.log_file.replace('%TIMESTAMP%', timestamp);
// Make sure that log directoy exsists
fx.mkdirSync(directory);
// Make sure that log directoy exsists when not logging to stdout only
if (output.includes('file')) {
fx.mkdirSync(directory);
// Custom level
const levels = {
levels: {
error: 0,
warn: 1,
info: 2,
debug: 3,
trace: 4,
},
colors: {
error: 'red',
warn: 'yellow',
info: 'green',
debug: 'blue',
trace: 'magenta',
},
if (settings.get().advanced.log_symlink_current) {
const current = settings.get().advanced.log_directory.replace('%TIMESTAMP%', 'current');
const actual = './' + timestamp;
if (fs.existsSync(current)) {
fs.unlinkSync(current);
}
fs.symlinkSync(actual, current);
}
}
const z2mToWinstonLevel = (level) => level === 'warn' ? 'warning' : level;
const winstonToZ2mLevel = (level) => level === 'warning' ? 'warn' : level;
// Determine the log level.
let level = settings.get().advanced.log_level;
const validLevels = ['info', 'error', 'warn', 'debug'];
assert(validLevels.includes(level), `'${level}' is not a valid log_level, use one of '${validLevels.join(', ')}'`);
level = z2mToWinstonLevel(level);
const levelWithCompensatedLength = {
'info': 'info ',
'error': 'error',
'warn': 'warn ',
'debug': 'debug',
};
/* istanbul ignore next */
const timestampFormat = () => moment().format(settings.get().advanced.timestamp_format);
// Setup default console logger
const transportsToUse = [
new winston.transports.Console({
level,
silent: !output.includes('console'),
format: winston.format.combine(
winston.format.timestamp({format: timestampFormat}),
winston.format.printf(/* istanbul ignore next */(info) => {
let {timestamp, level, message} = info;
level = winstonToZ2mLevel(level);
const prefix = colorizer.colorize(level, `Zigbee2MQTT:${levelWithCompensatedLength[level]}`);
return `${prefix} ${timestamp.split('.')[0]}: ${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 = {
filename: path.join(directory, logFilename),
json: false,
level,
format: winston.format.combine(
winston.format.timestamp({format: timestampFormat}),
winston.format.printf(/* istanbul ignore next */(info) => {
let {timestamp, level, message} = info;
level = winstonToZ2mLevel(level);
return `${levelWithCompensatedLength[level]} ${timestamp.split('.')[0]}: ${message}`;
}),
),
};
if (settings.get().advanced.log_rotation) {
transportFileOptions.tailable = true;
transportFileOptions.maxFiles = 3; // Keep last 3 files
transportFileOptions.maxsize = 10000000; // 10MB
}
if (output.includes('file')) {
transportsToUse.push(new winston.transports.File(transportFileOptions));
}
/* istanbul ignore next */
if (output.includes('syslog')) {
require('winston-syslog').Syslog;
const options = {
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();
transportsToUse.push(new winston.transports.Syslog(options));
}
// Create logger
const logger = new winston.Logger({
levels: levels.levels,
transports: [
new winston.transports.File({
filename: path.join(directory, 'log.txt'),
json: false,
level,
maxFiles: 3, // Keep last 3 files
maxsize: 10000000, // 10MB
timestamp: () => new Date().toLocaleString(),
}),
new winston.transports.Console({
timestamp: () => new Date().toLocaleString(),
formatter: (options) =>
winston.config.colorize(options.level, ' zigbee2mqtt:' + options.level.toLowerCase()) + ' ' +
options.timestamp() + ' ' + (options.message ? options.message : '') +
(options.meta && Object.keys(options.meta).length ? '\n\t'+ JSON.stringify(options.meta) : '' ),
}),
],
});
// Add colors
winston.addColors(levels.colors);
logger.transports.console.level = level;
const logger = winston.createLogger({transports: transportsToUse, levels: winston.config.syslog.levels});
// Cleanup any old log directory.
function cleanup() {
@@ -68,7 +116,7 @@ function cleanup() {
let directories = fs.readdirSync(rootDirectory).map((d) => {
d = path.join(rootDirectory, d);
return {path: d, birth: fs.statSync(d).birthtimeMs};
return {path: d, birth: fs.statSync(d).mtime};
});
directories.sort((a, b) => b.birth - a.birth);
@@ -80,7 +128,34 @@ function cleanup() {
}
}
// Print to user what logging is enabled
function logOutput() {
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}`);
}
logger.cleanup();
} else if (output.includes('console')) {
logger.info(`Logging to console only'`);
}
}
logger.addTransport = (transport) => {
transport.level = transportsToUse[0].level;
logger.add(transport);
};
logger.cleanup = cleanup;
logger.directory = directory;
logger.logOutput = logOutput;
logger.getLevel = () => winstonToZ2mLevel(transportsToUse[0].level);
logger.setLevel = (level) => {
level = z2mToWinstonLevel(level);
logger.transports.forEach((transport) => transport.level = level);
};
// winston.config.syslog.levels doesnt have warn, but is required for syslog.
/* istanbul ignore next */
logger.warn = (message) => logger.warning(message);
module.exports = logger;
-420
View File
@@ -1,420 +0,0 @@
const data = require('./data');
const file = data.joinPath('configuration.yaml');
const objectAssignDeep = require(`object-assign-deep`);
const path = require('path');
const fs = require('./fs');
const onChangeHandlers = [];
const defaults = {
whitelist: [],
ban: [],
permit_join: false,
mqtt: {
include_device_information: false,
},
groups: {},
device_options: {},
map_options: {
graphviz: {
colors: {
fill: {
enddevice: '#fff8ce',
coordinator: '#e04e5d',
router: '#4ea3e0',
},
font: {
coordinator: '#ffffff',
router: '#ffffff',
enddevice: '#000000',
},
line: {
active: '#009900',
inactive: '#994444',
},
},
},
},
queue: {
delay: 250,
simultaneously: 5,
},
experimental: {
livolo: false,
// json or attribute
output: 'json',
},
advanced: {
log_directory: path.join(data.getPath(), 'log', '%TIMESTAMP%'),
log_level: process.env.DEBUG ? 'debug' : 'info',
soft_reset_timeout: 0,
pan_id: 0x1a62,
ext_pan_id: [0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD],
channel: 11,
baudrate: 115200,
rtscts: true,
// Availability timeout in seconds, disabled by default.
availability_timeout: 0,
availability_blacklist: [],
/**
* Home Assistant requires ALL attributes to be present in ALL MQTT messages send by the device.
* https://community.home-assistant.io/t/missing-value-with-mqtt-only-last-data-set-is-shown/47070/9
*
* Therefore zigbee2mqtt BY DEFAULT caches all values and resend it with every message.
* advanced.cache_state in configuration.yaml allows to configure this.
* https://www.zigbee2mqtt.io/configuration/configuration.html
*/
cache_state: true,
/**
* Add a last_seen attribute to mqtt messages, contains date/time of zigbee message arrival
* "ISO_8601": ISO 8601 format
* "ISO_8601_local": Local ISO 8601 format (instead of UTC-based)
* "epoch": milliseconds elapsed since the UNIX epoch
* "disable": no last_seen attribute (default)
*/
last_seen: 'disable',
// Optional: Add an elapsed attribute to MQTT messages, contains milliseconds since the previous msg
elapsed: false,
/**
* https://github.com/Koenkk/zigbee2mqtt/issues/685#issuecomment-449112250
*
* Network key will serve as the encryption key of your network.
* Changing this will require you to repair your devices.
*/
network_key: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
/**
* Enables reporting feature
*/
report: false,
/**
* Home Assistant discovery topic
*/
homeassistant_discovery_topic: 'homeassistant',
/**
* Home Assistant status topic
*/
homeassistant_status_topic: 'hass/status',
},
};
let _settings;
function getSettings() {
if (!_settings) {
_settings = read();
}
if (_settings.hasOwnProperty('advanced') && !_settings.advanced) {
delete _settings.advanced;
}
return _settings;
}
function get() {
const _settings = objectAssignDeep.noMutate(defaults, getSettings());
if (!_settings.whitelist) {
_settings.whitelist = [];
}
return _settings;
}
function writeRead() {
write();
_settings = read();
onChangeHandlers.forEach((handler) => handler());
}
function write() {
const settings = getSettings();
const toWrite = objectAssignDeep.noMutate(settings);
// Read settings to check if we have to split devices/groups into separate file.
const actual = fs.readYaml(file);
if (typeof actual.devices === 'string') {
fs.writeYaml(data.joinPath(actual.devices), settings.devices);
toWrite.devices = actual.devices;
}
if (typeof actual.groups === 'string') {
fs.writeYaml(data.joinPath(actual.groups), settings.groups);
toWrite.groups = actual.groups;
}
fs.writeYaml(file, toWrite);
}
function read() {
const s = fs.readYaml(file);
// Read devices/groups configuration from separate file.
if (typeof s.devices === 'string') {
const file = data.joinPath(s.devices);
s.devices = fs.readYamlIfExists(file);
}
if (typeof s.groups === 'string') {
const file = data.joinPath(s.groups);
s.groups = fs.readYamlIfExists(file);
}
return s;
}
function set(path, value) {
let obj = getSettings();
for (let i = 0; i < path.length; i++) {
const key = path[i];
if (i === path.length - 1) {
obj[key] = value;
} else {
if (!obj[key]) {
obj[key] = {};
}
obj = obj[key];
}
}
writeRead();
}
const getDevices = () => getSettings().devices || [];
const getDevice = (ieeeAddr) => getDevices()[ieeeAddr];
const getGroups = () => getSettings().groups || {};
const getGroup = (ID) => {
const group = getGroups()[ID];
if (group && !group.hasOwnProperty('devices')) {
group.devices = [];
}
return group;
};
function addDevice(ieeeAddr) {
const settings = getSettings();
if (!settings.devices) {
settings.devices = {};
}
settings.devices[ieeeAddr] = {friendly_name: ieeeAddr, retain: false};
writeRead();
}
function whitelistDevice(ieeeAddr) {
const settings = getSettings();
if (!settings.whitelist) {
settings.whitelist = [];
}
settings.whitelist.push(ieeeAddr);
writeRead();
}
function banDevice(ieeeAddr) {
const settings = getSettings();
if (!settings.ban) {
settings.ban = [];
}
settings.ban.push(ieeeAddr);
writeRead();
}
function removeDevice(ieeeAddr) {
const settings = getSettings();
if (!settings.devices || !settings.devices[ieeeAddr]) return;
delete settings.devices[ieeeAddr];
writeRead();
}
function addGroup(groupName) {
const settings = getSettings();
if (!settings.groups) {
settings.groups = {};
}
let ID = '1';
while (settings.groups.hasOwnProperty(ID)) {
ID = (Number.parseInt(ID) + 1).toString();
}
if (Object.values(settings.groups).find((g) => g.friendly_name === groupName)) {
return false; // Duplicate group names are not allowed
}
settings.groups[ID] = {friendly_name: groupName};
writeRead();
return true;
}
function addDeviceToGroup(ID, ieeeAddr) {
const settings = getSettings();
const group = settings.groups[ID];
if (!group.devices) {
group.devices = [];
}
if (!group.devices.includes(ieeeAddr)) {
group.devices.push(ieeeAddr);
writeRead();
return true;
} else {
return false;
}
}
function removeDeviceFromGroup(ID, ieeeAddr) {
const settings = getSettings();
const group = settings.groups[ID];
if (group.devices && group.devices.includes(ieeeAddr)) {
group.devices = group.devices.filter((d) => d != ieeeAddr);
writeRead();
return true;
} else {
return false;
}
}
function removeGroup(name) {
const settings = getSettings();
if (!settings.groups) return;
const ID = Object.keys(settings.groups).find((key) => {
return settings.groups[key].friendly_name === name;
});
if (ID) {
delete settings.groups[ID];
writeRead();
return true;
} else {
return false;
}
}
function getIeeeAddrByFriendlyName(friendlyName) {
const entry = Object.entries(getDevices()).find(([ieeeAddr, device]) =>
device.friendly_name === friendlyName
);
return entry && entry[0];
}
function getGroupIDByFriendlyName(friendlyName) {
const entry = Object.entries(getGroups()).find(([ID, group]) =>
group.friendly_name === friendlyName
);
return entry && entry[0];
}
function changeDeviceOptions(ieeeAddr, newOptions) {
const settings = getSettings();
const currentOptions = settings.devices[ieeeAddr];
if (!currentOptions) {
return;
}
Object.keys(currentOptions).forEach((key) => {
if (newOptions[key]) {
currentOptions[key] = newOptions[key];
}
});
writeRead();
}
function changeFriendlyName(old, new_) {
const settings = getSettings();
const ieeeAddr = getIeeeAddrByFriendlyName(old);
if (!ieeeAddr) {
return false;
}
settings.devices[ieeeAddr].friendly_name = new_;
writeRead();
return true;
}
// An entity can be either a group or a device.
function resolveEntity(ID) {
let type = null;
let friendlyName = null;
if (module.exports.getIeeeAddrByFriendlyName(ID)) {
// Check if the ID is a friendly_name of a device.
friendlyName = ID;
ID = module.exports.getIeeeAddrByFriendlyName(ID);
type = 'device';
} else if (module.exports.getGroupIDByFriendlyName(ID)) {
// Check if the ID is a friendly_name of a group.
friendlyName = ID;
ID = Number(module.exports.getGroupIDByFriendlyName(ID));
type = 'group';
} else if (module.exports.getGroup(ID)) {
friendlyName = module.exports.getGroup(ID).friendly_name;
ID = Number(ID);
type = 'group';
} else {
// By default it is a device with ID as ID.
type = 'device';
const device = module.exports.getDevice(ID);
friendlyName = device ? device.friendly_name : ID;
}
return {ID, type, friendlyName};
}
module.exports = {
get: () => get(),
write: () => write(),
set: (path, value) => set(path, value),
getDevice,
getGroup,
getGroups,
getDevices,
whitelistDevice: (ieeeAddr) => whitelistDevice(ieeeAddr),
banDevice: (ieeeAddr) => banDevice(ieeeAddr),
addDevice: (ieeeAddr) => addDevice(ieeeAddr),
removeDevice: (ieeeAddr) => removeDevice(ieeeAddr),
addGroup: (name) => addGroup(name),
removeGroup: (name) => removeGroup(name),
addDeviceToGroup: (ID, ieeeAddr) => addDeviceToGroup(ID, ieeeAddr),
removeDeviceFromGroup: (ID, ieeeAddr) => removeDeviceFromGroup(ID, ieeeAddr),
getIeeeAddrByFriendlyName: (friendlyName) => getIeeeAddrByFriendlyName(friendlyName),
getGroupIDByFriendlyName: (friendlyName) => getGroupIDByFriendlyName(friendlyName),
changeFriendlyName: (old, new_) => changeFriendlyName(old, new_),
changeDeviceOptions: (ieeeAddr, options) => changeDeviceOptions(ieeeAddr, options),
resolveEntity,
addOnChangeHandler: (handler) => onChangeHandlers.push(handler),
// For test
_getDefaults: () => {
return objectAssignDeep.noMutate(defaults);
},
_clear: () => _settings = undefined,
};
+767
View File
@@ -0,0 +1,767 @@
{
"type": "object",
"properties": {
"device_options": {
"type": "object"
},
"homeassistant": {
"title": "Home Assistant integration",
"type": "boolean",
"description": "Home Assistant integration (MQTT discovery)",
"default": false
},
"permit_join": {
"type": "boolean",
"default": false,
"title": "Permit join",
"description": "Allow new devices to join (re-applied at restart)"
},
"external_converters": {
"type": "array",
"title": "External converters",
"description": "You can define external converters to e.g. add support for a DiY device",
"requiresRestart": true,
"items": {
"type": "string"
},
"examples": ["DIYRuZ_FreePad.js"]
},
"mqtt": {
"type": "object",
"title": "MQTT",
"properties": {
"base_topic": {
"type": "string",
"title": "Base topic",
"requiresRestart": true,
"description": "MQTT base topic for Zigbee2MQTT MQTT messages",
"examples": ["zigbee2mqtt"]
},
"server": {
"type": "string",
"title": "MQTT server",
"requiresRestart": true,
"description": "MQTT server URL (use mqtts:// for SSL/TLS connection)",
"examples": ["mqtt://localhost:1883"]
},
"keepalive": {
"type": "number",
"title": "Keepalive",
"requiresRestart": true,
"description": "MQTT keepalive in second",
"default": 60
},
"ca": {
"type": "string",
"title": "Certificate authority",
"requiresRestart": true,
"description": "Absolute path to SSL/TLS certificate of CA used to sign server and client certificates",
"examples": ["/etc/ssl/mqtt-ca.crt"]
},
"key": {
"type": "string",
"title": "SSL/TLS key",
"requiresRestart": true,
"description": "Absolute path to SSL/TLS key for client-authentication",
"examples": ["/etc/ssl/mqtt-client.key"]
},
"cert": {
"type": "string",
"title": "SSL/TLS certificate",
"description": "Absolute path to SSL/TLS certificate for client-authentication",
"requiresRestart": true,
"examples": ["/etc/ssl/mqtt-client.crt"]
},
"user": {
"type": "string",
"title": "User",
"requiresRestart": true,
"description": "MQTT server authentication user",
"examples": ["johnnysilverhand"]
},
"password": {
"type": "string",
"title": "Password",
"requiresRestart": true,
"description": "MQTT server authentication password",
"examples": ["ILOVEPELMENI"]
},
"client_id": {
"type": "string",
"title": "Client ID",
"requiresRestart": true,
"description": "MQTT client ID",
"examples": ["MY_CLIENT_ID"]
},
"reject_unauthorized": {
"type": "boolean",
"title": "Reject unauthorized",
"requiresRestart": true,
"description": "Disable self-signed SSL certificate",
"default": true
},
"include_device_information": {
"type": "boolean",
"title": "Include device information",
"description": "Include device information to mqtt messages",
"default": false
},
"version": {
"type": ["number", "null"],
"title": "Version",
"requiresRestart": true,
"description": "MQTT protocol version",
"default": 4,
"examples": [5]
},
"force_disable_retain": {
"type": "boolean",
"title": "Force disable retain",
"requiresRestart": true,
"description": "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
}
},
"required": ["base_topic", "server"]
},
"serial": {
"type": "object",
"title": "Serial",
"properties": {
"port": {
"type": ["string", "null"],
"title": "Port",
"requiresRestart": true,
"description": "Location of the adapter. To autodetect the port, set null",
"examples": ["/dev/ttyACM0"]
},
"disable_led": {
"type": "boolean",
"title": "Disable led",
"requiresRestart": true,
"description": "Disable LED of the adapter if supported",
"default": false
},
"adapter": {
"type": ["string"],
"enum": ["deconz", "zstack", "zigate", "ezsp", "auto"],
"title": "Adapter",
"default": "auto",
"requiresRestart": true,
"description": "Adapter type, not needed unless you are experiencing problems"
}
}
},
"blocklist": {
"title": "Blocklist",
"requiresRestart": true,
"description": "Block devices from the network (by ieeeAddr)",
"type": "array",
"items": {
"type": "string"
}
},
"passlist": {
"title": "Passlist",
"requiresRestart": true,
"description": "Allow only certain devices to join the network (by ieeeAddr). Note that all devices not on the passlist will be removed from the network!",
"type": "array",
"items": {
"type": "string"
}
},
"whitelist": {
"readOnly": true,
"type": "array",
"requiresRestart": true,
"title": "Whitelist (deprecated, use passlist)",
"items": {
"type": "string"
}
},
"ban": {
"readOnly": true,
"type": "array",
"requiresRestart": true,
"title": "Ban (deprecated, use blocklist)",
"items": {
"type": "string"
}
},
"experimental": {
"type": "object",
"title": "Experimental",
"properties": {
"transmit_power": {
"type": ["number", "null"],
"title": "Transmit power",
"requiresRestart": true,
"description": "Transmit power of adapter, only available for Z-Stack (CC253*/CC2652/CC1352) adapters, CC2652 = 5dbm, CC1352 max is = 20dbm (5dbm default)"
},
"output": {
"type": "string",
"enum": ["attribute_and_json", "attribute", "json"],
"title": "MQTT output type",
"description": "Examples when 'state' of a device is published json: topic: 'zigbee2mqtt/my_bulb' payload '{\"state\": \"ON\"}' attribute: topic 'zigbee2mqtt/my_bulb/state' payload 'ON' attribute_and_json: both json and attribute (see above)"
}
}
},
"advanced": {
"type": "object",
"title": "Advanced",
"properties": {
"legacy_api": {
"type": "boolean",
"title": "Legacy API",
"requiresRestart": true,
"description": "Disables the legacy api (false = disable)",
"default": true
},
"pan_id": {
"oneOf": [{
"type": "string",
"title": "Pan ID (string)"
},
{
"type": "number",
"title": "Pan ID (number)"
}
],
"title": "Pan ID",
"requiresRestart": true,
"description": "ZigBee pan ID, changing requires repairing all devices!"
},
"ext_pan_id": {
"type": "array",
"items": {
"type": "number"
},
"title": "Ext Pan ID",
"requiresRestart": true,
"description": "Zigbee extended pan ID, changing requires repairing all devices!"
},
"channel": {
"type": "number",
"minimum": 11,
"maximum": 26,
"default": 11,
"title": "ZigBee channel",
"requiresRestart": true,
"description": "Zigbee channel, changing requires repairing all devices! (Note: use a ZLL channel: 11, 15, 20, or 25 to avoid Problems)",
"examples": [15, 20, 25]
},
"cache_state": {
"type": "boolean",
"title": "Cache state",
"description": "MQTT message payload will contain all attributes, not only changed ones. Has to be true when integrating via Home Assistant",
"default": true
},
"cache_state_persistent": {
"type": "boolean",
"title": "Persist cache state",
"description": "Persist cached state, only used when cache_state: true",
"default": true
},
"cache_state_send_on_startup": {
"type": "boolean",
"title": "Send cached state on startup",
"description": "Send cached state on startup, only used when cache_state: true",
"default": true
},
"log_rotation": {
"type": "boolean",
"title": "Log rotation",
"requiresRestart": true,
"description": "Log rotation",
"default": true
},
"log_symlink_current": {
"type": "boolean",
"title": "Log symlink current",
"requiresRestart": true,
"description": "Create symlink to current logs in the log directory",
"default": false
},
"log_level": {
"type": "string",
"enum": ["info", "warn", "error", "debug"],
"title": "Log level",
"description": "Logging level",
"default": "info"
},
"log_output": {
"type": "array",
"requiresRestart": true,
"items": {
"type": "string",
"enum": ["console", "file", "syslog"]
},
"title": "Log output",
"description": "Output location of the log, leave empty to supress logging"
},
"log_directory": {
"type": "string",
"title": "Log directory",
"requiresRestart": true,
"description": "Location of log directory",
"examples": ["data/log/%TIMESTAMP%"]
},
"log_file": {
"type": "string",
"title": "Log file",
"requiresRestart": true,
"description": "Log file name, can also contain timestamp",
"examples": ["zigbee2mqtt_%TIMESTAMP%.log"],
"default": "log.txt"
},
"baudrate": {
"type": "number",
"title": "Baudrate",
"requiresRestart": true,
"description": "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",
"examples": [38400, 57600, 115200]
},
"rtscts": {
"type": "boolean",
"title": "RTS / CTS",
"requiresRestart": true,
"description": "RTS / CTS Hardware Flow Control for serial port"
},
"soft_reset_timeout": {
"type": "number",
"minimum": 0,
"requiresRestart": true,
"title": "Soft reset timeout (deprecated)",
"description": "Soft reset ZNP after timeout",
"readOnly": true
},
"network_key": {
"oneOf": [{
"type": "string",
"title": "Network key(string)"
},
{
"type": "array",
"items": {
"type": "number"
},
"title": "Network key(array)"
}
],
"title": "Network key",
"requiresRestart": true,
"description": "Network encryption key, changing requires repairing all devices!"
},
"last_seen": {
"type": "string",
"enum": ["disable", "ISO_8601", "ISO_8601_local", "epoch"],
"title": "Last seen",
"description": "Add a last_seen attribute to MQTT messages, contains date/time of last Zigbee message",
"default": "disable"
},
"elapsed": {
"type": "boolean",
"title": "Elapsed",
"description": "Add an elapsed attribute to MQTT messages, contains milliseconds since the previous msg",
"default": false
},
"availability_timeout": {
"type": "number",
"minimum": 0,
"default": 0,
"requiresRestart": true,
"title": "Availability Timeout",
"description": "Availability timeout in seconds when enabled, devices will be checked if they are still online. Only AC powered routers are checked for availability"
},
"availability_blocklist": {
"type": "array",
"items": {
"type": "string"
},
"requiresRestart": true,
"title": "Availability Blocklist",
"description": "Prevent devices from being checked for availability"
},
"availability_passlist": {
"type": "array",
"items": {
"type": "string"
},
"requiresRestart": true,
"title": "Availability passlist",
"description": "Only enable availability check for certain devices"
},
"availability_blacklist": {
"type": "array",
"readOnly": true,
"requiresRestart": true,
"title": "Availability blacklist (deprecated, use availability_blocklist)",
"items": {
"type": "string"
}
},
"availability_whitelist": {
"type": "array",
"readOnly": true,
"requiresRestart": true,
"items": {
"type": "string"
},
"title": "Availability whitelist (deprecated, use passlist)"
},
"report": {
"type": "boolean",
"title": "Reporting",
"requiresRestart": true,
"readOnly": true,
"description": "Enables report feature (deprecated)"
},
"homeassistant_discovery_topic": {
"type": "string",
"title": "Homeassistant discovery topic",
"description": "Home Assistant discovery topic",
"requiresRestart": true,
"examples": ["homeassistant"]
},
"homeassistant_legacy_entity_attributes": {
"type": "boolean",
"title": "Home Assistant legacy entity attributes",
"description": "Home Assistant legacy entity attributes, when enabled Zigbee2MQTT will add state attributes to each entity, additional to the separate entities and devices it already creates",
"default": true
},
"homeassistant_status_topic": {
"type": "string",
"title": "Home Assistant status topic",
"description": "Home Assistant status topic",
"requiresRestart": true,
"examples": ["homeassistant/status"]
},
"timestamp_format": {
"type": "string",
"title": "Timestamp format",
"requiresRestart": true,
"description": "Log timestamp format",
"examples": ["YYYY-MM-DD HH:mm:ss"]
},
"adapter_concurrent": {
"title": "Adapter concurrency",
"requiresRestart": true,
"type": ["number", "null"],
"description": "Adapter concurrency (e.g. 2 for CC2531 or 16 for CC26X2R1) (default: null, uses recommended value)"
},
"adapter_delay": {
"type": ["number", "null"],
"requiresRestart": true,
"title": "Adapter delay",
"description": "Adapter delay"
},
"ikea_ota_use_test_url": {
"type": "boolean",
"title": "IKEA TRADFRI OTA use test url",
"requiresRestart": true,
"description": "Use IKEA TRADFRI OTA test server, see OTA updates documentation",
"default": false
},
"homeassistant_legacy_triggers": {
"type": "boolean",
"title": "Home Assistant legacy triggers",
"description": "Home Assistant legacy triggers, when enabled Zigbee2mqt will send an empty 'action' or 'click' after one has been send. A 'sensor_action' and 'sensor_click' will be discoverd",
"default": true
},
"log_syslog": {
"type": "object",
"title": "syslog",
"properties": {
"host": {
"type": "string",
"title": "Host",
"description": "The host running syslogd, defaults to localhost.",
"default": "localhost"
},
"port": {
"type": "number",
"title": "Port",
"description": "The port on the host that syslog is running on, defaults to syslogd's default port.",
"default": 123
},
"protocol": {
"type": "string",
"title": "Protocol",
"description": "The network protocol to log over (e.g. tcp4, udp4, tls4, unix, unix-connect, etc).",
"default": "tcp4",
"examples": [
"udp4",
"tls4",
"unix",
"unix-connect"
]
},
"path": {
"type": "string",
"title": "Path",
"description": "The path to the syslog dgram socket (i.e. /dev/log or /var/run/syslog for OS X).",
"default": "/dev/log",
"examples": [
"/var/run/syslog"
]
},
"pid": {
"type": "string",
"title": "PID",
"description": "PID of the process that log messages are coming from (Default process.pid).",
"default": "process.pid"
},
"localhost": {
"type": "string",
"title": "Localhost",
"description": "Host to indicate that log messages are coming from (Default: localhost).",
"default": "localhost"
},
"type": {
"type": "string",
"title": "Type",
"description": "The type of the syslog protocol to use (Default: BSD, also valid: 5424).",
"default": "5424"
},
"app_name": {
"type": "string",
"title": "Localhost",
"description": "The name of the application (Default: Zigbee2MQTT).",
"default": "Zigbee2MQTT"
},
"eol": {
"type": "string",
"title": "eol",
"description": "The end of line character to be added to the end of the message (Default: Message without modifications).",
"default": "/n"
}
}
}
}
},
"map_options": {
"type": "object",
"title": "Networkmap",
"properties": {
"graphviz": {
"type": "object",
"properties": {
"colors": {
"type": "object",
"properties": {
"fill": {
"type": "object",
"properties": {
"enddevice": {
"type": "string"
},
"coordinator": {
"type": "string"
},
"router": {
"type": "string"
}
}
},
"font": {
"type": "object",
"properties": {
"enddevice": {
"type": "string"
},
"coordinator": {
"type": "string"
},
"router": {
"type": "string"
}
}
},
"line": {
"type": "object",
"properties": {
"active": {
"type": "string"
},
"inactive": {
"type": "string"
}
}
}
}
}
}
}
}
},
"ota": {
"type": "object",
"title": "OTA updates",
"properties": {
"update_check_interval": {
"type": "number",
"title": "Update check interval",
"description": "Your device may request a check for a new firmware update. This value determines how frequently third party servers may actually be contacted to look for firmware updates. The value is set in minutes, and the default is 1 day.",
"default": 1440
},
"disable_automatic_update_check": {
"type": "boolean",
"title": "Disable automatic update check",
"description": "Zigbee devices may request a firmware update, and do so frequently, causing Zigbee2MQTT to reach out to third party servers. If you disable these device initiated checks, you can still initiate a firmware update check manually.",
"default": false
}
}
},
"devices": {
"type": "object",
"propertyNames": {
"pattern": "^0x[\\d\\w]{16}$"
},
"patternProperties": {
"^.*$": {
"$ref": "#/definitions/device"
}
}
},
"groups": {
"type": "object",
"propertyNames": {
"pattern": "^[\\w].*$"
},
"patternProperties": {
"^.*$": {
"$ref": "#/definitions/group"
}
}
},
"frontend": {
"type": "object",
"title": "Frontend",
"properties": {
"port": {
"type": "number",
"title": "Port",
"description": "Frontend binding port",
"default": 8080,
"requiresRestart": true
},
"host": {
"type": "string",
"title": "Bind host",
"description": "Frontend binding host",
"default":" 0.0.0.0",
"requiresRestart": true
},
"auth_token": {
"type": ["string", "null"],
"title": "Auth token",
"description": "Enables authentication, disabled by default",
"requiresRestart": true
}
}
}
},
"required": ["mqtt"],
"definitions": {
"device": {
"type": "object",
"properties": {
"friendly_name": {
"type": "string",
"title": "Friendly name",
"description": "Used in the MQTT topic of a device. By default this is the device ID",
"readOnly": true
},
"retain": {
"type": "boolean",
"title": "Retain",
"description": "Retain MQTT messages of this device"
},
"retention": {
"type": "number",
"title": "Retention",
"description": "Sets the MQTT Message Expiry in seconds, Make sure to set mqtt.version to 5"
},
"qos": {
"type": "number",
"title": "QoS",
"description": "QoS level for MQTT messages of this device"
},
"debounce": {
"type": "number",
"title": "Debounce",
"description": "Debounces messages of this device"
},
"debounce_ignore": {
"type": "array",
"items": {
"type": "string"
},
"examples": ["action"],
"title": "Ignore debounce",
"description": "Protects unique payload values of specified payload properties from overriding within debounce time"
},
"optimistic": {
"type": "boolean",
"title": "Optimistic",
"description": "Publish optimistic state after set",
"default": true
},
"filtered_optimistic": {
"type": "array",
"items": {
"type": "string"
},
"examples": ["color_mode", "color_temp", "color"],
"title": "Filtered optimistic attributes",
"description": "Filter attributes from optimistic publish payload when calling /set. (This has no effect if optimistic is set to false)."
},
"filtered_attributes": {
"type": "array",
"items": {
"type": "string"
},
"examples": ["temperature", "battery", "action"],
"title": "Filtered publish attributes",
"description": "Filter attributes from publish payload."
},
"icon": {
"type": "string",
"title": "Icon",
"description": "The user-defined device icon for the frontend. It can be a link to an image (not a path to a file) or base64 encoded data URL like: image/svg+xml;base64,PHN2ZyB3aW....R0aD"
}
},
"required": ["friendly_name"]
},
"group": {
"type": "object",
"properties": {
"friendly_name": {
"type": "string"
},
"retain": {
"type": "boolean"
},
"devices": {
"type": "array",
"items": {
"type": "string"
}
},
"optimistic": {
"type": "boolean"
},
"qos": {
"type": "number"
},
"filtered_attributes": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": ["friendly_name"]
}
}
}
+710
View File
@@ -0,0 +1,710 @@
import * as data from './data';
import * as utils from './utils';
import objectAssignDeep from 'object-assign-deep';
import path from 'path';
import * as yaml from './yaml';
import Ajv from 'ajv';
import schemaJson from './settings.schema.json';
export const schema = schemaJson;
// TODO: check all
// DEPRECATED ZIGBEE2MQTT_CONFIG: https://github.com/Koenkk/zigbee2mqtt/issues/4697
const file = process.env.ZIGBEE2MQTT_CONFIG ?? data.joinPath('configuration.yaml');
const ajvSetting = new Ajv({allErrors: true}).addKeyword('requiresRestart').compile(schema);
const ajvRestartRequired = new Ajv({allErrors: true})
.addKeyword({keyword: 'requiresRestart', validate: (schema: unknown) => !schema}).compile(schema);
const defaults: RecursivePartial<Settings> = {
passlist: [],
blocklist: [],
// Deprecated: use block/passlist
whitelist: [],
ban: [],
permit_join: false,
mqtt: {
include_device_information: false,
/**
* Configurable force disable retain flag on mqtt publish.
* https://github.com/Koenkk/zigbee2mqtt/pull/4948
*/
force_disable_retain: false,
},
serial: {
disable_led: false,
},
device_options: {},
map_options: {
graphviz: {
colors: {
fill: {
enddevice: '#fff8ce',
coordinator: '#e04e5d',
router: '#4ea3e0',
},
font: {
coordinator: '#ffffff',
router: '#ffffff',
enddevice: '#000000',
},
line: {
active: '#009900',
inactive: '#994444',
},
},
},
},
experimental: {
// json or attribute or attribute_and_json
output: 'json',
},
advanced: {
legacy_api: true,
log_rotation: true,
log_symlink_current: false,
log_output: ['console', 'file'],
log_directory: path.join(data.getPath(), 'log', '%TIMESTAMP%'),
log_file: 'log.txt',
log_level: /* istanbul ignore next */ process.env.DEBUG ? 'debug' : 'info',
log_syslog: {},
soft_reset_timeout: 0,
pan_id: 0x1a62,
ext_pan_id: [0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD],
channel: 11,
adapter_concurrent: null,
adapter_delay: null,
// Availability timeout in seconds, disabled by default.
availability_timeout: 0,
availability_blocklist: [],
availability_passlist: [],
// Deprecated, use block/passlist
availability_blacklist: [],
availability_whitelist: [],
/**
* Home Assistant requires ALL attributes to be present in ALL MQTT messages send by the device.
* https://community.home-assistant.io/t/missing-value-with-mqtt-only-last-data-set-is-shown/47070/9
*
* Therefore Zigbee2MQTT BY DEFAULT caches all values and resend it with every message.
* advanced.cache_state in configuration.yaml allows to configure this.
* https://www.zigbee2mqtt.io/configuration/configuration.html
*/
cache_state: true,
cache_state_persistent: true,
cache_state_send_on_startup: true,
/**
* Add a last_seen attribute to mqtt messages, contains date/time of zigbee message arrival
* "ISO_8601": ISO 8601 format
* "ISO_8601_local": Local ISO 8601 format (instead of UTC-based)
* "epoch": milliseconds elapsed since the UNIX epoch
* "disable": no last_seen attribute (default)
*/
last_seen: 'disable',
// Optional: Add an elapsed attribute to MQTT messages, contains milliseconds since the previous msg
elapsed: false,
/**
* https://github.com/Koenkk/zigbee2mqtt/issues/685#issuecomment-449112250
*
* Network key will serve as the encryption key of your network.
* Changing this will require you to repair your devices.
*/
network_key: [1, 3, 5, 7, 9, 11, 13, 15, 0, 2, 4, 6, 8, 10, 12, 13],
/**
* Enables reporting feature
*/
report: false,
/**
* Home Assistant discovery topic
*/
homeassistant_discovery_topic: 'homeassistant',
/**
* Home Assistant status topic
*/
homeassistant_status_topic: 'hass/status',
/**
* Home Assistant legacy entity attributes, when enabled:
* Zigbee2MQTT will send additional states as attributes with each entity.
* For example, A temperature & humidity sensor will have 2 entities for
* the temperature and humidity, with this setting enabled both entities
* will also have an temperature and humidity attribute.
*/
homeassistant_legacy_entity_attributes: true,
/**
* Home Assistant legacy triggers, when enabled:
* - Zigbee2mqt will send an empty 'action' or 'click' after one has been send
* - A 'sensor_action' and 'sensor_click' will be discoverd
*/
homeassistant_legacy_triggers: true,
/**
* Configurable timestampFormat
* https://github.com/Koenkk/zigbee2mqtt/commit/44db557a0c83f419d66755d14e460cd78bd6204e
*/
timestamp_format: 'YYYY-MM-DD HH:mm:ss',
},
ota: {
/**
* Minimal time delta in minutes between polling third party server for potential firmware updates
*/
update_check_interval: 24 * 60,
/**
* Completely disallow Zigbee devices to initiate a search for a potential firmware update.
* If set to true, only a user-initiated update search will be possible.
*/
disable_automatic_update_check: false,
},
external_converters: [],
};
let _settings: Partial<Settings>;
let _settingsWithDefaults: Settings;
function write(): void {
const settings = getInternalSettings();
/* eslint-disable-line */ // @ts-ignore
const toWrite = objectAssignDeep.noMutate(settings);
// Read settings to check if we have to split devices/groups into separate file.
const actual = yaml.read(file);
// In case the setting is defined in a separte file (e.g. !secret network_key) update it there.
for (const path of [
['mqtt', 'user'],
['mqtt', 'password'],
['advanced', 'network_key'],
['frontend', 'auth_token'],
]) {
if (actual[path[0]] && actual[path[0]][path[1]]) {
const match = /!(.*) (.*)/g.exec(actual[path[0]][path[1]]);
if (match) {
yaml.updateIfChanged(data.joinPath(`${match[1]}.yaml`), match[2], toWrite[path[0]][path[1]]);
toWrite[path[0]][path[1]] = actual[path[0]][path[1]];
}
}
}
// Write devices/groups to separate file if required.
const writeDevicesOrGroups = (type: 'devices' | 'groups'): void => {
if (typeof actual[type] === 'string' || Array.isArray(actual[type])) {
const fileToWrite = Array.isArray(actual[type]) ? actual[type][0] : actual[type];
/* eslint-disable-line */ // @ts-ignore
const content = objectAssignDeep.noMutate(settings[type]);
// If an array, only write to first file and only devices which are not in the other files.
if (Array.isArray(actual[type])) {
actual[type].filter((f: string, i: number) => i !== 0)
.map((f: string) => yaml.readIfExists(data.joinPath(f), {}))
.map((c: KeyValue) => Object.keys(c))
.forEach((k: string) => delete content[k]);
}
yaml.writeIfChanged(data.joinPath(fileToWrite), content);
toWrite[type] = actual[type];
}
};
writeDevicesOrGroups('devices');
writeDevicesOrGroups('groups');
yaml.writeIfChanged(file, toWrite);
_settings = read();
/* eslint-disable-line */ // @ts-ignore
_settingsWithDefaults = objectAssignDeep.noMutate(defaults, getInternalSettings());
}
export function validate(): string[] {
try {
getInternalSettings();
} catch (error) {
if (error.name === 'YAMLException') {
return [
`Your YAML file: '${error.file}' is invalid ` +
`(use https://jsonformatter.org/yaml-validator to find and fix the issue)`,
];
}
return [error.message];
}
if (!ajvSetting(_settings)) {
return ajvSetting.errors.map((v) => `${v.instancePath.substring(1)} ${v.message}`);
}
const errors = [];
if (_settings.advanced && _settings.advanced.network_key && typeof _settings.advanced.network_key === 'string' &&
_settings.advanced.network_key !== 'GENERATE') {
errors.push(`advanced.network_key: should be array or 'GENERATE' (is '${_settings.advanced.network_key}')`);
}
if (_settings.advanced && _settings.advanced.pan_id && typeof _settings.advanced.pan_id === 'string' &&
_settings.advanced.pan_id !== 'GENERATE') {
errors.push(`advanced.pan_id: should be number or 'GENERATE' (is '${_settings.advanced.pan_id}')`);
}
// Verify that all friendly names are unique
const names: string[] = [];
const check = (name: string): void => {
if (names.includes(name)) errors.push(`Duplicate friendly_name '${name}' found`);
errors.push(...utils.validateFriendlyName(name));
names.push(name);
};
const settingsWithDefaults = get();
Object.values(settingsWithDefaults.devices).forEach((d) => check(d.friendly_name));
Object.values(settingsWithDefaults.groups).forEach((g) => check(g.friendly_name));
if (settingsWithDefaults.mqtt.version !== 5) {
for (const device of Object.values(settingsWithDefaults.devices)) {
if (device.retention) {
errors.push('MQTT retention requires protocol version 5');
}
}
}
const checkAvailabilityList = (list: string[], type: string): void => {
list.forEach((e) => {
if (!getEntity(e)) {
errors.push(`Non-existing entity '${e}' specified in '${type}'`);
}
});
};
checkAvailabilityList(settingsWithDefaults.advanced.availability_blacklist, 'availability_blacklist');
checkAvailabilityList(settingsWithDefaults.advanced.availability_whitelist, 'availability_whitelist');
checkAvailabilityList(settingsWithDefaults.advanced.availability_blocklist, 'availability_blocklist');
checkAvailabilityList(settingsWithDefaults.advanced.availability_passlist, 'availability_passlist');
return errors;
}
function read(): Settings {
const s = yaml.read(file) as Settings;
// Read !secret MQTT username and password if set
// eslint-disable-next-line
const interpetValue = (value: any): any => {
const re = /!(.*) (.*)/g;
const match = re.exec(value);
if (match) {
const file = data.joinPath(`${match[1]}.yaml`);
const key = match[2];
return yaml.read(file)[key];
} else {
return value;
}
};
if (s.mqtt?.user && s.mqtt?.password) {
s.mqtt.user = interpetValue(s.mqtt.user);
s.mqtt.password = interpetValue(s.mqtt.password);
}
if (s.advanced?.network_key) {
s.advanced.network_key = interpetValue(s.advanced.network_key);
}
if (s.frontend?.auth_token) {
s.frontend.auth_token = interpetValue(s.frontend.auth_token);
}
// Read devices/groups configuration from separate file if specified.
const readDevicesOrGroups = (type: 'devices' | 'groups'): void => {
if (typeof s[type] === 'string' || Array.isArray(s[type])) {
/* eslint-disable-line */ // @ts-ignore
const files: string[] = Array.isArray(s[type]) ? s[type] : [s[type]];
s[type] = {};
for (const file of files) {
const content = yaml.readIfExists(data.joinPath(file), {});
/* eslint-disable-line */ // @ts-ignore
s[type] = objectAssignDeep.noMutate(s[type], content);
}
}
};
readDevicesOrGroups('devices');
readDevicesOrGroups('groups');
return s;
}
function applyEnvironmentVariables(settings: Partial<Settings>): void {
const iterate = (obj: KeyValue, path: string[]): void => {
Object.keys(obj).forEach((key) => {
if (key !== 'type') {
if (key !== 'properties' && obj[key]) {
const type = (obj[key].type || 'object').toString();
const envPart = path.reduce((acc, val) => `${acc}${val}_`, '');
const envVariableName = (`ZIGBEE2MQTT_CONFIG_${envPart}${key}`).toUpperCase();
if (process.env[envVariableName]) {
const setting = path.reduce((acc, val) => {
/* eslint-disable-line */ // @ts-ignore
acc[val] = acc[val] || {};
/* eslint-disable-line */ // @ts-ignore
return acc[val];
}, settings);
if (type.indexOf('object') >= 0 || type.indexOf('array') >= 0) {
setting[key] = JSON.parse(process.env[envVariableName]);
} else if (type.indexOf('number') >= 0) {
/* eslint-disable-line */ // @ts-ignore
setting[key] = process.env[envVariableName] * 1;
} else if (type.indexOf('boolean') >= 0) {
setting[key] = process.env[envVariableName].toLowerCase() === 'true';
} else {
/* istanbul ignore else */
if (type.indexOf('string') >= 0) {
setting[key] = process.env[envVariableName];
}
}
}
}
if (typeof obj[key] === 'object' && obj[key]) {
const newPath = [...path];
if (key !== 'properties') {
newPath.push(key);
}
iterate(obj[key], newPath);
}
}
});
};
iterate(schema.properties, []);
}
function getInternalSettings(): Partial<Settings> {
if (!_settings) {
_settings = read();
applyEnvironmentVariables(_settings);
}
return _settings;
}
export function get(): Settings {
if (!_settingsWithDefaults) {
/* eslint-disable-line */ // @ts-ignore
_settingsWithDefaults = objectAssignDeep.noMutate(defaults, getInternalSettings());
}
if (!_settingsWithDefaults.devices) {
_settingsWithDefaults.devices = {};
}
if (!_settingsWithDefaults.groups) {
_settingsWithDefaults.groups = {};
}
return _settingsWithDefaults;
}
export function set(path: string[], value: string | number | boolean | KeyValue): void {
/* eslint-disable-next-line */
let settings: any = getInternalSettings();
for (let i = 0; i < path.length; i++) {
const key = path[i];
if (i === path.length - 1) {
settings[key] = value;
} else {
if (!settings[key]) {
settings[key] = {};
}
settings = settings[key];
}
}
write();
}
export function apply(newSettings: Record<string, unknown>): boolean {
ajvSetting(newSettings);
const errors = ajvSetting.errors && ajvSetting.errors.filter((e) => e.keyword !== 'required');
if (errors.length) {
const error = errors[0];
throw new Error(`${error.instancePath.substring(1)} ${error.message}`);
}
getInternalSettings(); // Ensure _settings is intialized.
/* eslint-disable-line */ // @ts-ignore
_settings = objectAssignDeep.noMutate(_settings, newSettings);
write();
ajvRestartRequired(newSettings);
const restartRequired = ajvRestartRequired.errors &&
!!ajvRestartRequired.errors.find((e) => e.keyword === 'requiresRestart');
return restartRequired;
}
export function getGroup(IDorName: string | number): GroupSettings {
const settings = get();
const byID = settings.groups[IDorName];
if (byID) {
return {devices: [], ...byID, ID: Number(IDorName), friendlyName: byID.friendly_name};
}
for (const [ID, group] of Object.entries(settings.groups)) {
if (group.friendly_name === IDorName) {
return {devices: [], ...group, ID: Number(ID), friendlyName: group.friendly_name};
}
}
return null;
}
export function getGroups(): GroupSettings[] {
const settings = get();
return Object.entries(settings.groups).map(([ID, group]) => {
return {devices: [], ...group, ID: Number(ID), friendlyName: group.friendly_name};
});
}
function getGroupThrowIfNotExists(IDorName: string): GroupSettings {
const group = getGroup(IDorName);
if (!group) {
throw new Error(`Group '${IDorName}' does not exist`);
}
return group;
}
export function getDevice(IDorName: string): DeviceSettings {
const settings = get();
const byID = settings.devices[IDorName];
if (byID) {
return {...byID, ID: IDorName, friendlyName: byID.friendly_name};
}
for (const [ID, device] of Object.entries(settings.devices)) {
if (device.friendly_name === IDorName) {
return {...device, ID, friendlyName: device.friendly_name};
}
}
return null;
}
function getDeviceThrowIfNotExists(IDorName: string): DeviceSettings {
const device = getDevice(IDorName);
if (!device) {
throw new Error(`Device '${IDorName}' does not exist`);
}
return device;
}
export function getEntity(IDorName: string): EntitySettings {
const device = getDevice(IDorName);
if (device) {
return {...device, type: 'device'};
}
const group = getGroup(IDorName);
if (group) {
return {...group, type: 'group'};
}
return null;
}
export function addDevice(ID: string): DeviceSettings {
if (getDevice(ID)) {
throw new Error(`Device '${ID}' already exists`);
}
const settings = getInternalSettings();
if (!settings.devices) {
settings.devices = {};
}
settings.devices[ID] = {friendly_name: ID};
write();
return getDevice(ID);
}
export function whitelistDevice(ID: string): void {
const settings = getInternalSettings();
if (!settings.whitelist) {
settings.whitelist = [];
}
if (settings.whitelist.includes(ID)) {
throw new Error(`Device '${ID}' already whitelisted`);
}
settings.whitelist.push(ID);
write();
}
export function blockDevice(ID: string): void {
const settings = getInternalSettings();
if (!settings.blocklist) {
settings.blocklist = [];
}
settings.blocklist.push(ID);
write();
}
export function banDevice(ID: string): void {
const settings = getInternalSettings();
if (!settings.ban) {
settings.ban = [];
}
settings.ban.push(ID);
write();
}
export function removeDevice(IDorName: string): void {
const device = getDeviceThrowIfNotExists(IDorName);
const settings = getInternalSettings();
delete settings.devices[device.ID];
// Remove device from groups
if (settings.groups) {
const regex =
new RegExp(`^(${device.friendlyName}|${device.ID})(/(\\d|${utils.endpointNames.join('|')}))?$`);
for (const group of Object.values(settings.groups).filter((g) => g.devices)) {
group.devices = group.devices.filter((device) => !device.match(regex));
}
}
write();
}
export function addGroup(name: string, ID?: string): GroupSettings {
utils.validateFriendlyName(name, true);
if (getGroup(name) || getDevice(name)) {
throw new Error(`friendly_name '${name}' is already in use`);
}
const settings = getInternalSettings();
if (!settings.groups) {
settings.groups = {};
}
if (ID == null) {
// look for free ID
ID = '1';
while (settings.groups.hasOwnProperty(ID)) {
ID = (Number.parseInt(ID) + 1).toString();
}
} else {
// ensure provided ID is not in use
ID = ID.toString();
if (settings.groups.hasOwnProperty(ID)) {
throw new Error(`Group ID '${ID}' is already in use`);
}
}
settings.groups[ID] = {friendly_name: name};
write();
return getGroup(ID);
}
function groupGetDevice(group: {devices?: string[]}, keys: string[]): string {
for (const device of group.devices ?? []) {
if (keys.includes(device)) return device;
}
return null;
}
export function addDeviceToGroup(IDorName: string, keys: string[]): void {
const groupID = getGroupThrowIfNotExists(IDorName).ID;
const settings = getInternalSettings();
const group = settings.groups[groupID];
if (!groupGetDevice(group, keys)) {
if (!group.devices) group.devices = [];
group.devices.push(keys[0]);
write();
}
}
export function removeDeviceFromGroup(IDorName: string, keys: string[]): void {
const groupID = getGroupThrowIfNotExists(IDorName).ID;
const settings = getInternalSettings();
const group = settings.groups[groupID];
if (!group.devices) {
return;
}
const key = groupGetDevice(group, keys);
if (key) {
group.devices = group.devices.filter((d) => d != key);
write();
}
}
export function removeGroup(IDorName: string | number): void {
const groupID = getGroupThrowIfNotExists(IDorName.toString()).ID;
const settings = getInternalSettings();
delete settings.groups[groupID];
write();
}
export function changeEntityOptions(IDorName: string, newOptions: KeyValue): void {
const settings = getInternalSettings();
delete newOptions.friendly_name;
delete newOptions.devices;
if (getDevice(IDorName)) {
objectAssignDeep(settings.devices[getDevice(IDorName).ID], newOptions);
utils.removeNullPropertiesFromObject(settings.devices[getDevice(IDorName).ID]);
} else if (getGroup(IDorName)) {
objectAssignDeep(settings.groups[getGroup(IDorName).ID], newOptions);
utils.removeNullPropertiesFromObject(settings.groups[getGroup(IDorName).ID]);
} else {
throw new Error(`Device or group '${IDorName}' does not exist`);
}
write();
}
export function changeFriendlyName(IDorName: string, newName: string): void {
utils.validateFriendlyName(newName, true);
if (getGroup(newName) || getDevice(newName)) {
throw new Error(`friendly_name '${newName}' is already in use`);
}
const settings = getInternalSettings();
if (getDevice(IDorName)) {
settings.devices[getDevice(IDorName).ID].friendly_name = newName;
} else if (getGroup(IDorName)) {
settings.groups[getGroup(IDorName).ID].friendly_name = newName;
} else {
throw new Error(`Device or group '${IDorName}' does not exist`);
}
write();
}
export function reRead(): void {
_settings = null;
getInternalSettings();
_settingsWithDefaults = null;
get();
}
export const testing = {
write,
clear: (): void => {
_settings = null;
_settingsWithDefaults = null;
},
defaults,
};
-152
View File
@@ -1,152 +0,0 @@
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
const logger = require('../util/logger');
// Xiaomi uses 4151 and 4447 (lumi.plug) as manufacturer ID.
const xiaomiManufacturerID = [4151, 4447];
const ikeaTradfriManufacturerID = [4476];
// construct a local ISO8601 string (instead of UTC-based)
// Example:
// - ISO8601 (UTC) = 2019-03-01T15:32:45.941+0000
// - ISO8601 (local) = 2019-03-01T16:32:45.941+0100 (for timezone GMT+1)
function toLocalISOString(dDate) {
const tzOffset = -dDate.getTimezoneOffset();
const plusOrMinus = tzOffset >= 0 ? '+' : '-';
const pad = function(num) {
const norm = Math.floor(Math.abs(num));
return (norm < 10 ? '0' : '') + norm;
};
return dDate.getFullYear() +
'-' + pad(dDate.getMonth() + 1) +
'-' + pad(dDate.getDate()) +
'T' + pad(dDate.getHours()) +
':' + pad(dDate.getMinutes()) +
':' + pad(dDate.getSeconds()) +
plusOrMinus + pad(tzOffset / 60) +
':' + pad(tzOffset % 60);
}
const postfixes = [
'left', 'right', 'center', 'bottom_left', 'bottom_right', 'l1', 'l2',
'top_left', 'top_right', 'white', 'rgb', 'system', 'top', 'bottom', 'center_left', 'center_right',
];
function flatten(arr) {
return arr.reduce((flat, toFlatten) => {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}
const forceEndDevice = flatten(
['QBKG03LM', 'QBKG04LM', 'ZNMS13LM']
.map((model) => zigbeeShepherdConverters.devices.find((d) => d.model === model))
.map((mappedModel) => mappedModel.zigbeeModel));
function getEndpointByEntityID(zigbee, entityID, epName) {
const device = zigbee.getDevice(entityID);
if (!device) {
logger.error(`Failed to find device with entity ID '${entityID}'`);
return;
}
const mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
if (!mappedDevice) {
logger.error(`Device with model ID ${device.modelId} is not supported`);
return;
}
let epID = null;
if (epName) {
if (!mappedDevice.ep) {
logger.error(`Device ${mappedDevice.model} doesn't define eps`);
return;
}
epID = mappedDevice.ep(device)[epName];
if (!epID) {
logger.error(`Device ${mappedDevice.model} doesn't have ep named '${epName}'`);
return;
}
} else if (mappedDevice.hasOwnProperty('ep')) {
const eps = mappedDevice.ep(device);
epID = eps[''] || null;
}
const endpoint = zigbee.getEndpoint(entityID, epID);
if (!endpoint) {
logger.error(`Failed to retrieve for entity ID ${entityID} and endpoint ID ${epID}`);
}
return endpoint;
}
function getZigbee2mqttVersion(callback) {
const git = require('git-last-commit');
const packageJSON = require('../../package.json');
const version = packageJSON.version;
git.getLastCommit((err, commit) => {
let commitHash = null;
if (err) {
try {
commitHash = require('../../.hash.json').hash;
} catch (error) {
commitHash = 'unknown';
}
} else {
commitHash = commit.shortHash;
}
callback({commitHash, version});
});
}
function formatDate(date, type, _default) {
let result;
switch (type) {
case 'ISO_8601':
result = new Date(date).toISOString();
break;
case 'ISO_8601_local':
result = toLocalISOString(new Date(date));
break;
case 'epoch':
result = date;
break;
default:
result = _default;
break;
}
return result;
}
module.exports = {
millisecondsToSeconds: (milliseconds) => milliseconds / 1000,
secondsToMilliseconds: (seconds) => seconds * 1000,
isXiaomiDevice: (device) => {
return device.modelId !== 'lumi.router' && xiaomiManufacturerID.includes(device.manufId) &&
(!device.manufName || !device.manufName.startsWith('Trust'));
},
isIkeaTradfriDevice: (device) => ikeaTradfriManufacturerID.includes(device.manufId),
isRouter: (device) => device.type === 'Router' && !forceEndDevice.includes(device.modelId),
isBatteryPowered: (device) => device.powerSource && device.powerSource === 'Battery',
isNumeric: (string) => /^\d+$/.test(string),
toLocalISOString: (dDate) => toLocalISOString(dDate),
getPostfixes: () => postfixes,
formatDate: (date, type, _default=null) => formatDate(date, type, _default),
correctDeviceType: (device) => {
if (device) {
if (forceEndDevice.includes(device.modelId)) {
return 'EndDevice';
}
}
return device.type;
},
getEndpointByEntityID,
getZigbee2mqttVersion,
};
+328
View File
@@ -0,0 +1,328 @@
import equals from 'fast-deep-equal/es6';
import humanizeDuration from 'humanize-duration';
import * as data from './data';
import vm from 'vm';
import fs from 'fs';
import path from 'path';
import {Endpoint} from 'zigbee-herdsman/dist/controller/model';
// TODO: check all
// construct a local ISO8601 string (instead of UTC-based)
// Example:
// - ISO8601 (UTC) = 2019-03-01T15:32:45.941+0000
// - ISO8601 (local) = 2019-03-01T16:32:45.941+0100 (for timezone GMT+1)
function toLocalISOString(date: Date): string {
const tzOffset = -date.getTimezoneOffset();
const plusOrMinus = tzOffset >= 0 ? '+' : '-';
const pad = (num: number): string => {
const norm = Math.floor(Math.abs(num));
return (norm < 10 ? '0' : '') + norm;
};
return date.getFullYear() +
'-' + pad(date.getMonth() + 1) +
'-' + pad(date.getDate()) +
'T' + pad(date.getHours()) +
':' + pad(date.getMinutes()) +
':' + pad(date.getSeconds()) +
plusOrMinus + pad(tzOffset / 60) +
':' + pad(tzOffset % 60);
}
export 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',
'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',
];
export function capitalize(s: string): string {
return s[0].toUpperCase() + s.slice(1);
}
export async function getZigbee2MQTTVersionSimple(): Promise<string> {
const packageJSON = await import('../..' + '/package.json');
return packageJSON.version;
}
export async function getZigbee2MQTTVersion(): Promise<{commitHash: string, version: string}> {
const git = await import('git-last-commit');
const packageJSON = await import('../..' + '/package.json');
return new Promise((resolve) => {
const version = packageJSON.version;
git.getLastCommit((err: Error, commit: {shortHash: string}) => {
let commitHash = null;
if (err) {
try {
commitHash = fs.readFileSync(path.join(__dirname, '..', '..', 'dist', '.hash'), 'utf-8');
} catch (error) {
/* istanbul ignore next */
commitHash = 'unknown';
}
} else {
commitHash = commit.shortHash;
}
resolve({commitHash, version});
});
});
}
export async function getDependencyVersion(depend: string): Promise<{version: string}> {
const packageJSON = await import(path.join(__dirname, '..', '..', 'node_modules', depend, 'package.json'));
const version = packageJSON.version;
return {version};
}
export function formatDate(time: number, type: 'ISO_8601' | 'ISO_8601_local' | 'epoch' | 'relative'): string | number {
if (type === 'ISO_8601') return new Date(time).toISOString();
else if (type === 'ISO_8601_local') return toLocalISOString(new Date(time));
else if (type === 'epoch') return time;
else { // relative
return humanizeDuration(Date.now() - time, {language: 'en', largest: 2, round: true}) + ' ago';
}
}
export function objectHasProperties(object: {[s: string]: unknown}, properties: string[]): boolean {
for (const property of properties) {
if (!object.hasOwnProperty(property)) {
return false;
}
}
return true;
}
export function equalsPartial(object: {[s: string]: unknown}, expected: {[s: string]: unknown}): boolean {
for (const [key, value] of Object.entries(expected)) {
if (!equals(object[key], value)) {
return false;
}
}
return true;
}
export function getObjectProperty(object: {[s: string]: unknown}, key: string, defaultValue: unknown): unknown {
return object && object.hasOwnProperty(key) ? object[key] : defaultValue;
}
export function getResponse(request: KeyValue | string, data: KeyValue, error: string): MQTTResponse {
const response: {data: unknown, status: string, error?: string, transaction?: string} =
{data, status: error ? 'error' : 'ok'};
if (error) response.error = error;
if (typeof request === 'object' && request.hasOwnProperty('transaction')) {
response.transaction = request.transaction;
}
return response;
}
export function parseJSON(value: string, failedReturnValue: string): KeyValue | string {
try {
return JSON.parse(value);
} catch (e) {
return failedReturnValue;
}
}
export function loadModuleFromText(moduleCode: string): unknown {
const moduleFakePath = path.join(__dirname, 'externally-loaded.js');
const sandbox = {
require: require,
module: {},
console,
setTimeout,
clearTimeout,
setInterval,
clearInterval,
setImmediate,
clearImmediate,
};
vm.runInNewContext(moduleCode, sandbox, moduleFakePath);
/* eslint-disable-line */ // @ts-ignore
return sandbox.module.exports;
}
export function loadModuleFromFile(modulePath: string): unknown {
const moduleCode = fs.readFileSync(modulePath, {encoding: 'utf8'});
return loadModuleFromText(moduleCode);
}
/* eslint-disable-next-line */
export function* getExternalConvertersDefinitions(settings: any): any {
const externalConverters = settings.get().external_converters;
for (const moduleName of externalConverters) {
let converter;
if (moduleName.endsWith('.js')) {
converter = loadModuleFromFile(data.joinPath(moduleName));
} else {
converter = require(moduleName);
}
if (Array.isArray(converter)) {
for (const item of converter) {
yield item;
}
} else {
yield converter;
}
}
}
export function removeNullPropertiesFromObject(obj: KeyValue): void {
for (const key of Object.keys(obj)) {
const value = obj[key];
if (value == null) {
delete obj[key];
} else if (typeof value === 'object') {
removeNullPropertiesFromObject(value);
}
}
}
export function getKey(
object: KeyValue, value: unknown, fallback: unknown, convertTo: (v: unknown) => unknown): unknown {
for (const key in object) {
if (object[key]===value) {
return convertTo ? convertTo(key) : key;
}
}
return fallback;
}
export function toNetworkAddressHex(value: number): string {
const hex = value.toString(16);
return `0x${'0'.repeat(4 - hex.length)}${hex}`;
}
// eslint-disable-next-line
export function toSnakeCase(value: string | KeyValue): any {
if (typeof value === 'object') {
value = {...value};
for (const key of Object.keys(value)) {
const keySnakeCase = toSnakeCase(key);
if (key !== keySnakeCase) {
value[keySnakeCase] = value[key];
delete value[key];
}
}
return value;
} else {
return value.replace(/\.?([A-Z])/g, (x, y) => '_' + y.toLowerCase()).replace(/^_/, '').replace('_i_d', '_id');
}
}
export 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 (name.endsWith(String.fromCharCode(0))) errors.push(`friendly_name is not allowed to contain null 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}')`);
}
if (throwFirstError && errors.length) {
throw new Error(errors[0]);
}
return errors;
}
export function sleep(seconds: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
export function sanitizeImageParameter(parameter: string): string {
const replaceByDash = [/\?/g, /&/g, /[^a-z\d\- _./:]/gi];
let sanitized = parameter;
replaceByDash.forEach((r) => sanitized = sanitized.replace(r, '-'));
return sanitized;
}
export function isAvailabilityEnabledForDevice(device: Device, settings: Settings): boolean {
/* istanbul ignore next */
if (!settings.experimental.availability_new) return false;
if (device.settings.hasOwnProperty('availability')) {
return !!device.settings.availability;
}
// availability_timeout = deprecated
const enabledGlobal = settings.advanced.availability_timeout || settings.availability;
if (!enabledGlobal) return false;
const passlist = settings.advanced.availability_passlist.concat(settings.advanced.availability_whitelist);
if (passlist.length > 0) {
return passlist.includes(device.name) || passlist.includes(device.ieeeAddr);
}
const blocklist = settings.advanced.availability_blacklist.concat(settings.advanced.availability_blocklist);
return !blocklist.includes(device.name) && !blocklist.includes(device.ieeeAddr);
}
/* istanbul ignore next */
export function isAvailabilityEnabledForDeviceLegacy(rd: ResolvedDevice, settings: Settings): boolean {
if (!settings.experimental.availability_new) return false;
if (rd.settings.hasOwnProperty('availability')) {
return !!rd.settings.availability;
}
// availability_timeout = deprecated
const enabledGlobal = settings.advanced.availability_timeout || settings.availability;
if (!enabledGlobal) return false;
const passlist = settings.advanced.availability_passlist.concat(settings.advanced.availability_whitelist);
if (passlist.length > 0) {
return passlist.includes(rd.name) || passlist.includes(rd.device.ieeeAddr);
}
const blocklist = settings.advanced.availability_blacklist.concat(settings.advanced.availability_blocklist);
return !blocklist.includes(rd.name) && !blocklist.includes(rd.device.ieeeAddr);
}
export function isXiaomiDevice(device: ZHDevice): boolean {
const xiaomiManufacturerID = [4151, 4447];
return device.modelID !== 'lumi.router' && xiaomiManufacturerID.includes(device.manufacturerID) &&
(!device.manufacturerName || !device.manufacturerName.startsWith('Trust'));
}
export function isIkeaTradfriDevice(device: ZHDevice): boolean {
return [4476].includes(device.manufacturerID);
}
const entityIDRegex = new RegExp(`^(.+?)(?:/(${endpointNames.join('|')}|\\d+))?$`);
export function parseEntityID(ID: string): {ID: string, endpoint: string} {
const match = ID.match(entityIDRegex);
return match && {ID: match[1], endpoint: match[2]};
}
export function isEndpoint(obj: unknown): obj is Endpoint {
return obj.constructor.name.toLowerCase() === 'endpoint';
}
export const hours = (hours: number): number => 1000 * 60 * 60 * hours;
export const minutes = (minutes: number): number => 1000 * 60 * minutes;
export const seconds = (seconds: number): number => 1000 * seconds;
+36
View File
@@ -0,0 +1,36 @@
import yaml from 'js-yaml';
import fs from 'fs';
import equals from 'fast-deep-equal/es6';
// TODO: check all
export function read(file: string): KeyValue {
try {
/* eslint-disable-line */ // @ts-ignore
return yaml.load(fs.readFileSync(file, 'utf8'));
} catch (error) {
if (error.name === 'YAMLException') {
error.file = file;
}
throw error;
}
}
export function readIfExists(file: string, default_?: KeyValue): KeyValue {
return fs.existsSync(file) ? read(file) : default_;
}
export function writeIfChanged(file: string, content: KeyValue): void {
const before = readIfExists(file);
if (!equals(before, content)) {
fs.writeFileSync(file, yaml.dump(content));
}
}
export function updateIfChanged(file: string, key: string, value: KeyValue): void {
const content = read(file);
if (content[key] !== value) {
content[key] = value;
writeIfChanged(file, content);
}
}
-97
View File
@@ -1,97 +0,0 @@
const settings = require('./settings');
const maxSimultaneouslyRunning = settings.get().queue.simultaneously;
const delay = settings.get().queue.delay;
const error17Retries = 3;
const logger = require('./logger');
class ZigbeeQueue {
constructor() {
this.queue = [];
this.active = [];
this.timer = null;
this.running = false;
this.ID = 0;
}
start() {
this.running = true;
this.resetTimer();
}
push(entityID, func) {
this.ID++;
this.queue.push({entityID, func, attempts: 0, ID: this.ID});
this.log(`Added new job with ID ${this.ID} for ${entityID}`);
}
log(message) {
logger.trace(`zigbeeQueue: ${message}`);
}
stopTimer() {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
}
resetTimer() {
this.stopTimer();
this.timer = setInterval(() => {
this.executeNext();
}, delay);
}
stop() {
this.stopTimer();
this.running = false;
}
handleJobComplete(job, error) {
this.log(`Completed job with ID ${job.ID} for ${job.entityID}${error ? ` with error ${error}` : ''}`);
if (error && error.message === 'rsp error: 17' && job.attempts < error17Retries) {
// Error 17 means that the buffer of the ZNP was full,
// retry this for a maximum of 3 times.
job.attempts++;
this.active.splice(this.active.indexOf(job), 1);
} else {
this.active.splice(this.active.indexOf(job), 1);
this.queue.splice(this.queue.indexOf(job), 1);
}
}
executeNext() {
if (!this.running) {
return;
}
const next = this.getNext();
if (next) {
this.active.push(next);
this.log(`Executing job with ID ${next.ID} for ${next.entityID}`);
next.func((error) => this.handleJobComplete(next, error));
}
}
getNext() {
if (this.active.length > (maxSimultaneouslyRunning - 1)) {
return null;
}
for (let i = 0; i < this.queue.length; i++) {
const job = this.queue[i];
const activeDeviceJob = this.active.find((j) => j.entityID === job.entityID);
if (!activeDeviceJob) {
return job;
}
}
return null;
}
}
module.exports = ZigbeeQueue;
-23
View File
@@ -1,23 +0,0 @@
/**
* This is a fake cie app which makes it possible for some iAS devices to join the network.
* Based on: https://github.com/zigbeer/zapp-cie
*/
const Ziee = require('zigbee-herdsman/dist/deprecated/ziee');
const Zive = require('zigbee-herdsman/dist/deprecated/zive');
const cieClusters = new Ziee();
// Direction-Value 1: input, 2: output, 3: input/output
// IasZone Cluster-Init Direction
cieClusters.init('ssIasZone', 'dir', {value: 2}); // Client Side(Output)
// Init Command Response Handler
cieClusters.init('ssIasZone', 'cmdRsps', {
enrollReq: (zapp, argObj, cb) => {},
statusChangeNotification: (zapp, argObj, cb) => {},
});
// Create Zive with profId: 0x0104 (Decimal: 260 / HA), devId: 0x0400 (Decimal: 1024 / iasControlIndicatingEquipment)
// Check the Values by https://github.com/zigbeer/zcl-id/wiki#5-table-of-identifiers
const cieApp = new Zive({profId: 0x0104, devId: 0x0400, discCmds: []}, cieClusters);
module.exports = cieApp;
-663
View File
@@ -1,663 +0,0 @@
const ZShepherd = require('zigbee-herdsman');
const logger = require('./util/logger');
const settings = require('./util/settings');
const data = require('./util/data');
const utils = require('./util/utils');
const ZigbeeQueue = require('./util/zigbeeQueue');
const cieApp = require('./zapp/cie');
const objectAssignDeep = require('object-assign-deep');
const Zcl = require('zigbee-herdsman/dist/zcl');
const advancedSettings = settings.get().advanced;
if (advancedSettings.channel < 11 || advancedSettings.channel > 26) {
throw new Error(`'${advancedSettings.channel}' is an invalid channel, use a channel between 11 - 26.`);
}
const shepherdSettings = {
net: {
panId: advancedSettings.pan_id,
extPanId: advancedSettings.ext_pan_id,
channelList: [advancedSettings.channel],
precfgkey: settings.get().advanced.network_key,
},
dbPath: data.joinPath('database.db'),
coordBackupPath: data.joinPath('coordinator_backup.json'),
sp: {
baudRate: advancedSettings.baudrate,
rtscts: advancedSettings.rtscts,
},
};
const defaultCfg = {
manufSpec: 0,
disDefaultRsp: 0,
};
// Don't print network key.
const shepherdSettingsLog = objectAssignDeep.noMutate(shepherdSettings);
shepherdSettingsLog.net.precfgkey = 'HIDDEN';
class Zigbee {
constructor() {
this.onReady = this.onReady.bind(this);
this.onMessage = this.onMessage.bind(this);
this.onError = this.onError.bind(this);
this.messageHandler = null;
this.permitJoinTimer = null;
this.queue = new ZigbeeQueue();
}
start(messageHandler, callback) {
logger.info(`Starting zigbee-shepherd`);
logger.debug(`Using zigbee-shepherd with settings: '${JSON.stringify(shepherdSettingsLog)}'`);
this.messageHandler = messageHandler;
this.shepherd = new ZShepherd(settings.get().serial.port, shepherdSettings);
this.shepherd.start((error) => {
if (error) {
logger.info(`Error while starting zigbee-shepherd, attempting to fix... (takes 60 seconds) (${error})`);
this.shepherd.controller._znp.close((() => null));
setTimeout(() => {
logger.info(`Starting zigbee-shepherd`);
this.shepherd.start((error) => {
if (error) {
logger.error(`Error while starting zigbee-shepherd! (${error})`);
logger.error(
'Press the reset button on the stick (the one closest to the USB) and start again'
);
callback(error);
} else {
this._handleStarted();
callback(null);
}
});
}, utils.secondsToMilliseconds(60));
} else {
this._handleStarted();
callback(null);
}
});
// Register callbacks.
this.shepherd.on('ready', this.onReady);
this.shepherd.on('ind', this.onMessage);
this.shepherd.on('error', this.onError);
this._acceptDevIncoming = this._acceptDevIncoming.bind(this);
this.shepherd.acceptDevIncoming = this._acceptDevIncoming;
}
_handleStarted() {
this.logStartupInfo();
this.getAllClients().forEach((device) => {
// If set whitelist devices, all other device will be ban or reject to join the network
if (settings.get().whitelist.size>0) {
if (!settings.get().whitelist.includes(device.ieeeAddr)) {
logger.warn(`Blacklist device is connected (${device.ieeeAddr}), removing...`);
this.removeDevice(device.ieeeAddr, true, () => {});
}
} else {
if (settings.get().ban.includes(device.ieeeAddr)) {
logger.warn(`Banned device is connected (${device.ieeeAddr}), removing...`);
this.removeDevice(device.ieeeAddr, false, () => {});
}
}
});
this.shepherd.backupCoordinator(() => {});
}
_acceptDevIncoming(devInfo, callback) {
logger.debug(
`Accept device incoming with ieeeAddr '${devInfo.ieeeAddr}' permit join is '${this.getPermitJoin()}'`
);
// If set whitelist devices, all other device will be ban or reject to join the network
if (settings.get().whitelist.size>0) {
if (settings.get().whitelist.includes(devInfo.ieeeAddr)) {
logger.info(`whitelist device tried to connect (${devInfo.ieeeAddr})`);
callback(null, true);
} else {
logger.debug(`Not allowing device '${devInfo.ieeeAddr}' to join`);
callback(null, false);
}
} else {
if (settings.get().ban.includes(devInfo.ieeeAddr)) {
logger.info(`Banned device tried to connect (${devInfo.ieeeAddr})`);
callback(null, false);
} else {
logger.debug(`Allowing device '${devInfo.ieeeAddr}' to join`);
callback(null, true);
}
}
}
logStartupInfo() {
logger.info('zigbee-shepherd started');
logger.info(`Coordinator firmware version: '${this.getFirmwareVersion()}'`);
logger.debug(`zigbee-shepherd info: ${JSON.stringify(this.shepherd.info())}`);
}
getFirmwareVersion() {
return this.shepherd.info().firmware.revision;
}
softReset(callback) {
this.shepherd.reset('soft', callback);
}
stop(callback) {
if (this.permitJoinTimer) {
clearInterval(this.permitJoinTimer);
}
this.queue.stop();
// Backup coordinator
this.shepherd.backupCoordinator(() => {
this.shepherd.stop((error) => {
logger.info('zigbee-shepherd stopped');
callback(error);
});
});
}
onReady() {
// Mount cieApp
this.shepherd.mount(cieApp, (err, epId) => {
if (!err) {
logger.debug(`Mounted the cieApp (epId ${epId})`);
} else {
logger.error(`Failed to mount the cieApp`);
}
});
// Check if we have to turn off the led
if (settings.get().serial.disable_led) {
this.shepherd.controller.request('UTIL', 'ledControl', {ledid: 3, mode: 0});
}
// Wait some time before we start the queue, many calls skip this queue which hangs the stick
setTimeout(() => {
this.queue.start();
}, 2000);
logger.info('zigbee-shepherd ready');
}
onError(message) {
// This event may appear if zigbee-shepherd cannot decode bad packets (invalid checksum).
logger.error(message);
}
permitJoin(permit, callback) {
if (permit) {
logger.info('Zigbee: allowing new devices to join.');
} else {
logger.info('Zigbee: disabling joining new devices.');
}
// In zigbee 3.0 a network automatically closes after 254 seconds.
// As a workaround, we enable joining again.
if (this.permitJoinTimer) {
clearInterval(this.permitJoinTimer);
}
if (permit) {
this.permitJoinTimer = setInterval(() => {
this.shepherd.permitJoin(255, (error) => {
if (error) {
logger.error('Failed to reenable joining');
} else {
logger.info('Successfully reenabled joining');
}
});
}, utils.secondsToMilliseconds(160));
}
this.shepherd.permitJoin(permit ? 255 : 0, (error) => {
if (error) {
logger.info(error);
}
if (callback) {
callback();
}
});
}
getPermitJoin() {
return this.shepherd.controller._permitJoinTime === 255;
}
getAllClients() {
return this.getDevices().filter((device) => device.type !== 'Coordinator');
}
removeDevice(deviceID, ban, callback) {
if (ban) {
settings.banDevice(deviceID);
}
const friendlyName = this.getDeviceFriendlyName(deviceID);
this.shepherd.remove(deviceID, {reJoin: true}, (error) => {
if (error) {
logger.warn(`Failed to remove '${friendlyName}', trying force remove...`);
this.forceRemove(deviceID, callback);
} else {
logger.info(`Removed ${friendlyName}`);
callback(null);
}
});
}
forceRemove(deviceID, callback) {
const device = this.shepherd._findDevByAddr(deviceID);
if (device) {
const friendlyName = this.getDeviceFriendlyName(deviceID);
return this.shepherd._unregisterDev(device, (error) => {
logger.info(`Force removed ${friendlyName}`);
callback(error);
});
} else {
logger.warn(`Could not find ${deviceID} for force removal`);
callback(true);
}
}
onMessage(message) {
if (this.messageHandler) {
this.messageHandler(message);
}
}
getDevices() {
return this.shepherd.list();
}
getDevice(ieeeAddr) {
return this.getDevices().find((d) => d.ieeeAddr === ieeeAddr);
}
getDeviceFriendlyName(ieeeAddr) {
const device = settings.getDevice(ieeeAddr);
return device ? device.friendly_name || ieeeAddr : ieeeAddr;
}
getCoordinator() {
const device = this.getDevices().find((d) => d.type === 'Coordinator');
return this.shepherd.find(device.ieeeAddr, 1);
}
getScanable() {
return this.getDevices().filter((d) => d.type != 'EndDevice');
}
getGroup(ID) {
return this.shepherd.getGroup(ID);
}
getGroupFriendlyName(ID) {
let friendlyName = null;
friendlyName = settings.getGroup(ID).friendly_name;
return (friendlyName ? friendlyName : ID);
}
networkScan(includeRoutes, callback) {
logger.info(`Starting network scan includeRoutes='${includeRoutes}'...`);
const lqiScanList = new Set();
const rtgScanList = new Set();
const linkMap = [];
const routeMap = [];
// Gather the lqi and the route info into separate lists and only collate them when done.
const collateMap = () => {
linkMap.sort();
logger.debug(`Link map: %j`, linkMap);
logger.debug(`Route map: %j`, routeMap);
// Merge the routes into the linkMap by matching on 'source|target' link short addresses
linkMap.forEach((link) => {
routeMap.filter((e) => e.key === link.key).forEach((e) => {
link.routes.push(e.destAddr);
});
link.routes.sort(function(a, b) {
return a-b;
});
delete link.key;
});
const networkMap = {nodes: [], links: linkMap};
this.getDevices().forEach((device) => {
const friendlyDevice = settings.getDevice(device.ieeeAddr);
const friendlyName = friendlyDevice ? friendlyDevice.friendly_name : device.ieeeAddr;
const deviceType = utils.correctDeviceType(device);
const scanfailed = [];
if (lqiScanList.has(device.ieeeAddr)) {
scanfailed.push('lqi');
}
if (rtgScanList.has(device.ieeeAddr)) {
scanfailed.push('rtg');
}
networkMap.nodes.push({ieeeAddr: device.ieeeAddr, friendlyName: friendlyName, type: deviceType,
nwkAddr: device.nwkAddr, manufName: device.manufName, modelId: device.modelId,
status: device.status, scanfailed: scanfailed});
});
// Clear remaining devices so they don't process when/if they eventually complete
lqiScanList.clear();
rtgScanList.clear();
logger.debug(`Merged map: %j`, networkMap);
callback(networkMap);
};
const processLqiResponse = (error, rsp, targetIeeeAddr, targetNwkAddr) => {
if (error) {
logger.warn(`Failed network lqi scan for device: '${targetIeeeAddr}' with error: '${error}'`);
} else {
if (lqiScanList.has(targetIeeeAddr)) {
// Haven't processed this one yet
if (rsp && rsp.status === 0 && rsp.neighborlqilist) {
logger.debug(`lqi scan: '${targetIeeeAddr}' with '${rsp.neighborlqilistcount}' neighbors`);
rsp.neighborlqilist.forEach(function(neighbor) {
// only include active relationships
if (neighbor.relationship <= 3) {
// lqi is measured at receiver so link is from neighbor (source) to scanned router
const key = neighbor.nwkAddr + '|' + targetNwkAddr;
linkMap.push({
key: key, sourceIeeeAddr: neighbor.extAddr, targetIeeeAddr: targetIeeeAddr,
sourceNwkAddr: neighbor.nwkAddr, lqi: neighbor.lqi, depth: neighbor.depth,
relationship: neighbor.relationship, routes: []});
}
});
// Remove from scan list and if both lists are done return the completed network map
lqiScanList.delete(targetIeeeAddr);
if (lqiScanList.size === 0 && rtgScanList.size === 0) {
logger.info('Network scan completed');
collateMap();
} else {
logger.debug(`Outstanding network lqi scans for devices: '${[...lqiScanList].join(' ')}'`);
logger.debug(`Outstanding network rtg scans for devices: '${[...rtgScanList].join(' ')}'`);
}
} else {
logger.warn(`Empty network lqi scan result for: '${targetIeeeAddr}'`);
}
} else {
// This target has already had timeout so don't add to result network map
logger.warn(`Ignoring late network lqi scan result for: '${targetIeeeAddr}'`);
}
}
};
const processRtgResponse = (error, rsp, sourceIeeeAddr, sourceNwkAddr) => {
if (error) {
logger.warn(`Failed network rtg scan for device: '${sourceIeeeAddr}' with error: '${error}'`);
} else {
if (rtgScanList.has(sourceIeeeAddr)) {
// Haven't processed this one yet
if (rsp && rsp.status === 0 && rsp.routingtablelist) {
logger.debug(`rtg scan: '${sourceIeeeAddr}' with '${rsp.routingtablelistcount}' entries`);
rsp.routingtablelist.forEach(function(route) {
if (route.routeStatus === 0) {
const key = sourceNwkAddr + '|' + route.nextHopNwkAddr;
routeMap.push({
key: key, destAddr: route.destNwkAddr});
}
});
// Remove from scan list and if both lists are done return the completed network map
rtgScanList.delete(sourceIeeeAddr);
if (lqiScanList.size === 0 && rtgScanList.size === 0) {
logger.info('Network scan completed');
collateMap();
} else {
logger.debug(`Outstanding network lqi scans for devices: '${[...lqiScanList].join(' ')}'`);
logger.debug(`Outstanding network rtg scans for devices: '${[...rtgScanList].join(' ')}'`);
}
} else {
logger.warn(`Empty network rtg scan result for: '${sourceIeeeAddr}'`);
}
} else {
// This source has already had timeout so don't add to result network map
logger.warn(`Ignoring late network rtg scan result for: '${sourceIeeeAddr}'`);
}
}
};
// Queue up an lqi scan and an rtg scan for coordinator and each router
this.getScanable().forEach((dev) => {
logger.debug(`Queing network scans for device: '${dev.ieeeAddr}'`);
lqiScanList.add(dev.ieeeAddr);
this.queue.push(dev.ieeeAddr, (queueCallback) => {
this.shepherd.controller.request('ZDO', 'mgmtLqiReq', {dstaddr: dev.nwkAddr, startindex: 0},
(error, rsp, ieeeAddr, nwkAddr) => {
processLqiResponse(error, rsp, dev.ieeeAddr, dev.nwkAddr);
queueCallback(error);
});
});
if (includeRoutes) {
rtgScanList.add(dev.ieeeAddr);
this.queue.push(dev.ieeeAddr, (queueCallback) => {
this.shepherd.controller.request('ZDO', 'mgmtRtgReq', {dstaddr: dev.nwkAddr, startindex: 0},
(error, rsp, ieeeAddr, nwkAddr) => {
processRtgResponse(error, rsp, dev.ieeeAddr, dev.nwkAddr);
queueCallback(error);
});
});
}
});
// Wait for all device scans before forcing map with whatever results are already in
setTimeout(() => {
if (lqiScanList.size === 0 && rtgScanList.size === 0) {
logger.info('Network scan timeout no outstanding requests');
} else {
logger.warn(`Network scan timeout, skipping outstanding lqi scans for '${[...lqiScanList].join(' ')}'`);
logger.warn(`Network scan timeout, skipping outstanding rtg scans for '${[...rtgScanList].join(' ')}'`);
collateMap();
}
}, lqiScanList.size * 1000);
}
getEndpoint(ieeeAddr, ep) {
// If no ep is given, the first endpoint will be returned
// Find device in zigbee-shepherd
const device = this.getDevice(ieeeAddr);
if (!device || !device.epList || !device.epList.length) {
logger.error(`Zigbee cannot determine endpoint for '${ieeeAddr}'`);
return null;
}
ep = ep ? ep : device.epList[0];
const endpoint = this.shepherd.find(ieeeAddr, ep);
return endpoint;
}
publish(entityID, entityType, cid, cmd, cmdType, zclData, cfg=defaultCfg, ep, callback) {
let entity = null;
let friendlyName = null;
if (entityType === 'device') {
entity = this.getEndpoint(entityID, ep);
friendlyName = this.getDeviceFriendlyName(entityID);
} else if (entityType === 'group') {
entity = this.getGroup(entityID);
friendlyName = this.getGroupFriendlyName(entityID);
}
if (!entity) {
logger.error(
`Cannot publish message to ${entityType} because '${entityID}' is not known by zigbee-shepherd`
);
return;
}
this.queue.push(entityID, (queueCallback) => {
logger.info(
`Zigbee publish to ${entityType} '${friendlyName}', ${cid} - ${cmd} - ` +
`${JSON.stringify(zclData)} - ${JSON.stringify(cfg)} - ${entity.epId}`
);
const callback_ = (error, rsp) => {
if (error) {
logger.error(
`Zigbee publish to ${entityType} '${friendlyName}', ${cid} ` +
`- ${cmd} - ${JSON.stringify(zclData)} ` +
`- ${JSON.stringify(cfg)} - ${ep} ` +
`failed with error ${error}`);
}
if (callback) {
callback(error, rsp);
}
queueCallback(error);
};
if (cmdType === 'functional' && entity.functional) {
entity.functional(cid, cmd, zclData, cfg, callback_);
} else if (cmdType === 'foundation' && entity.foundation) {
entity.foundation(cid, cmd, zclData, cfg, callback_);
} else {
logger.error(`Unknown zigbee publish cmdType ${cmdType}`);
}
});
}
ping(ieeeAddr, errorLogLevel='error', cb, mechanism='default') {
const friendlyName = this.getDeviceFriendlyName(ieeeAddr);
const callback = (error) => {
if (error) {
logger[errorLogLevel](`Failed to ping '${friendlyName}'`);
} else {
logger.debug(`Successfully pinged '${friendlyName}'`);
}
if (cb) {
cb(error);
}
};
if (mechanism === 'default') {
const device = this.shepherd._findDevByAddr(ieeeAddr);
if (device) {
logger.debug(`Ping ${ieeeAddr} (default)`);
this.queue.push(ieeeAddr, (queueCallback) => {
this.shepherd.controller.checkOnline(device, (error) => {
callback(error);
queueCallback(error);
});
});
}
} else if (mechanism === 'basic') {
const endpoint = this.getEndpoint(ieeeAddr, null);
if (endpoint) {
logger.debug(`Ping ${ieeeAddr} (basic)`);
this.queue.push(ieeeAddr, (queueCallback) => {
endpoint.foundation('genBasic', 'read', [{attrId: 0}], (error) => {
callback(error);
queueCallback(error);
});
});
}
}
}
bind(ep, cluster, target, callback) {
const friendlyName = this.getDeviceFriendlyName(ep.device.ieeeAddr);
const log = ` '${friendlyName}' - ${cluster}`;
target = !target ? this.getCoordinator() : target;
this.queue.push(ep.device.ieeeAddr, (queueCallback) => {
logger.debug(`Binding ${log}`);
ep.bind(cluster, target, (error) => {
if (error) {
logger.error(`Failed to bind ${log} - (${error})`);
} else {
logger.debug(`Successfully bound ${log}`);
}
callback(error);
queueCallback(error);
});
});
}
unbind(ep, cluster, target, callback) {
const friendlyName = this.getDeviceFriendlyName(ep.device.ieeeAddr);
const log = ` '${friendlyName}' - ${cluster}`;
target = !target ? this.getCoordinator() : target;
this.queue.push(ep.device.ieeeAddr, (queueCallback) => {
logger.debug(`Unbinding ${log}`);
ep.unbind(cluster, target, (error) => {
if (error) {
logger.error(`Failed to unbind ${log} - (${error})`);
} else {
logger.debug(`Successfully unbound ${log}`);
}
callback(error);
queueCallback(error);
});
});
}
/*
* Setup reporting.
* Attributes is an array of attribute objects.
* each attribute object should contain the following properties:
* attr the attribute name,
* min the minimal time between reports in seconds,
* max the maximum time between reports in seconds,
* change the minimum amount of change before sending a report
*/
report(ep, cluster, attributes) {
const friendlyName = this.getDeviceFriendlyName(ep.device.ieeeAddr);
const cfgArr = attributes.map((attribute) => {
const attrId = Zcl.getAttributeLegacy(cluster, attribute.attr).value;
const dataType = Zcl.getAttributeTypeLegacy(cluster, attribute.attr).value;
return {
direction: 0,
attrId,
dataType,
minRepIntval: attribute.min,
maxRepIntval: attribute.max,
repChange: attribute.change,
};
});
const log=`for '${friendlyName}' - ${cluster} - ${attributes.length}`;
const configReport = () => {
this.queue.push(ep.device.ieeeAddr, (queueCallback) => {
ep.foundation(cluster, 'configReport', cfgArr, defaultCfg, (error) => {
if (error) {
logger.error(`Failed to setup reporting ${log} - (${error})`);
} else {
logger.debug(`Successfully setup reporting ${log}`);
}
queueCallback(error);
});
});
};
this.queue.push(ep.device.ieeeAddr, (queueCallback) => {
logger.debug(`Setup reporting ${log}`);
ep.bind(cluster, this.getCoordinator(), (error) => {
if (error) {
logger.error(`Failed to bind for reporting ${log} - (${error})`);
} else {
// Only if binding succeeds, setting-up reporting makes sense.
configReport();
}
queueCallback(error);
});
});
}
}
module.exports = Zigbee;

Some files were not shown because too many files have changed in this diff Show More