Compare commits

...
341 Commits
Author SHA1 Message Date
Koen Kanters d381f2daa4 1.27.1 2022-09-01 08:41:47 +02:00
Koen Kanters b05b4adf57 Undev 2022-09-01 08:40:53 +02:00
Koen Kanters 96d72103f2 Merge branch 'dev' 2022-09-01 08:37:54 +02:00
github-actions[bot]andKoenkk 97ffa9610b Update zigbee-herdsman-converters to 14.0.610 (#13782)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-31 16:46:59 +00:00
github-actions[bot]andKoenkk 09d6c8601c Update zigbee-herdsman to 0.14.51 (#13781)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-31 16:04:14 +00:00
github-actions[bot]andKoenkk fc409a6884 Update zigbee-herdsman-converters to 14.0.609 (#13769)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-30 15:38:45 +00:00
github-actions[bot]andnurikk fa63ede4b6 Update zigbee2mqtt-frontend to 0.6.110 (#13757)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-08-29 19:21:24 +00:00
github-actions[bot]andKoenkk fd24c8186e Update zigbee-herdsman to 0.14.50 (#13753)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-29 18:06:26 +00:00
github-actions[bot]andKoenkk 0816d07b93 Update zigbee-herdsman-converters to 14.0.608 (#13752)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-29 16:39:36 +00:00
github-actions[bot]andnurikk c1b9345613 Update zigbee2mqtt-frontend to 0.6.109 (#13748)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-08-29 10:30:15 +00:00
github-actions[bot]andKoenkk 7f198d18ac Update zigbee-herdsman-converters to 14.0.607 (#13739)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-28 17:49:58 +00:00
github-actions[bot]andKoenkk 802bccd1f3 Update zigbee-herdsman to 0.14.49 (#13736)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-28 15:26:35 +00:00
github-actions[bot]andKoenkk 77bd76d1ca Update zigbee-herdsman-converters to 14.0.606 (#13710)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-27 08:14:22 +00:00
github-actions[bot]andKoenkk 8dd8b2848c Update zigbee-herdsman-converters to 14.0.605 (#13703)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-26 19:23:43 +00:00
github-actions[bot]andKoenkk c5d54a845a Update zigbee-herdsman-converters to 14.0.604 (#13687)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-25 16:04:17 +00:00
github-actions[bot]andKoenkk f1a19151fc Update zigbee-herdsman-converters to 14.0.603 (#13670)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-24 17:08:37 +00:00
963c2d86d3 Update zigbee-herdsman-converters to 14.0.602 (#13654)
* Update zigbee-herdsman-converters to 14.0.602

* Fix tests

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-08-23 19:53:49 +00:00
9e6b4083b2 Update zigbee-herdsman-converters to 14.0.601 (#13646)
* Update zigbee-herdsman-converters to 14.0.601

* Fix tests

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-08-22 18:06:45 +00:00
github-actions[bot]andKoenkk f29c4a24c2 Update zigbee-herdsman-converters to 14.0.600 (#13634)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-21 18:23:36 +00:00
github-actions[bot]andKoenkk a75e1c2b2b Update dependencies (#13630)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-21 09:30:25 +02:00
github-actions[bot]andKoenkk 62499483ce Update zigbee-herdsman-converters to 14.0.599 (#13618)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-20 07:39:24 +00:00
github-actions[bot]andKoenkk 304bb7b9d1 Update zigbee-herdsman-converters to 14.0.598 (#13611)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-19 19:06:19 +00:00
github-actions[bot]andKoenkk 15a069e3c7 Update zigbee-herdsman to 0.14.48 (#13610)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-19 19:01:11 +00:00
Koen Kanters e0a9323d6e Update dont-stale label 2022-08-19 20:57:44 +02:00
github-actions[bot]andKoenkk a0182c2e39 Update zigbee-herdsman-converters to 14.0.597 (#13596)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-18 17:23:05 +00:00
github-actions[bot]andKoenkk 327f816c0e Update zigbee-herdsman-converters to 14.0.596 (#13586)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-17 18:29:55 +00:00
github-actions[bot]andnurikk 040d2a1b36 Update zigbee2mqtt-frontend to 0.6.108 (#13573)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-08-16 20:51:02 +00:00
github-actions[bot]andKoenkk 497a48b8b0 Update zigbee-herdsman-converters to 14.0.595 (#13569)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-16 18:59:33 +00:00
github-actions[bot]andKoenkk 36a4754430 Update zigbee-herdsman-converters to 14.0.594 (#13542)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-14 16:29:56 +00:00
Koen Kanters 60b9f6f6b2 Home Assistant discovery: add enums with only SET (e.g. selftest). https://github.com/Koenkk/zigbee2mqtt/issues/13532 2022-08-14 18:22:35 +02:00
github-actions[bot]andKoenkk 2bdc7b7aca Update dependencies (#13535)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-14 09:58:14 +02:00
github-actions[bot]andKoenkk fea5d44a57 Update zigbee-herdsman-converters to 14.0.593 (#13517)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-12 14:59:07 +00:00
Koen Kanters 281e3870d3 Fix tests 2022-08-11 20:32:01 +02:00
Koen Kanters c9b2a7f6d4 Revert "Publish device and bridge availability when Home Assistant comes online. https://github.com/Koenkk/zigbee2mqtt/issues/13382"
This reverts commit 619d5232db.
2022-08-11 20:23:40 +02:00
Koen Kanters 6314b86d9b Better fix for #13382 2022-08-11 20:23:19 +02:00
Koen Kanters 619d5232db Publish device and bridge availability when Home Assistant comes online. https://github.com/Koenkk/zigbee2mqtt/issues/13382 2022-08-11 19:50:46 +02:00
Koen Kanters da4a3b9a77 Fix exception when using group remove_all. https://github.com/Koenkk/zigbee2mqtt/issues/13484 2022-08-10 22:38:04 +02:00
github-actions[bot]andKoenkk 62284dbd1a Update zigbee-herdsman-converters to 14.0.592 (#13489)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-10 17:41:21 +00:00
wysiwyng addb09275a Add category and icon for flip_indicator_light Home Assistant discovery (#13477) 2022-08-10 16:57:31 +02:00
github-actions[bot]andKoenkk 9c45a5fdf0 Update zigbee-herdsman-converters to 14.0.591 (#13469)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-09 15:06:24 +00:00
Koen Kanters 0aa29a0fab Home Assistant discovery: always expose cover state. https://github.com/zigbee2mqtt/hassio-zigbee2mqtt/issues/359 2022-08-09 17:01:22 +02:00
github-actions[bot]andKoenkk 5f778a7570 Update zigbee-herdsman-converters to 14.0.590 (#13458)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-08 15:54:36 +00:00
github-actions[bot]andKoenkk e8f6def246 Update zigbee-herdsman-converters to 14.0.589 (#13447)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-07 16:27:47 +00:00
github-actions[bot]andKoenkk 99485fa324 Update dependencies (#13441)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-07 09:20:22 +02:00
github-actions[bot]andKoenkk 483ff4aa8a Update zigbee-herdsman-converters to 14.0.588 (#13424)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-06 08:02:28 +00:00
github-actions[bot]andKoenkk b6c0afc129 Update zigbee-herdsman-converters to 14.0.587 (#13402)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-04 19:55:35 +00:00
github-actions[bot]andKoenkk 7def5ea9bf Update zigbee-herdsman to 0.14.47 (#13394)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-03 16:06:19 +00:00
github-actions[bot]andKoenkk 4e590ece19 Update zigbee-herdsman-converters to 14.0.586 (#13376)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-02 17:42:22 +00:00
c2faa3815a Update zigbee-herdsman-converters to 14.0.585 (#13362)
* Update zigbee-herdsman-converters to 14.0.585

* Fix tests

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-08-01 18:12:28 +00:00
Koen Kanters 52f8753a09 Promote to dev 2022-08-01 17:44:02 +02:00
Koen Kanters a9b8808237 1.27.0 2022-08-01 17:43:26 +02:00
Koen Kanters 26b323e1f6 Undev 2022-08-01 17:43:20 +02:00
Koen Kanters 5990bb384a Merge branch 'dev' 2022-08-01 17:42:35 +02:00
github-actions[bot]andKoenkk be70b83be5 Update zigbee-herdsman-converters to 14.0.583 (#13355)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-08-01 15:08:54 +00:00
github-actions[bot]andKoenkk 7f28c557cd Update dependencies (#13340)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-31 09:55:29 +02:00
github-actions[bot]andKoenkk b1f9f5f3b3 Update zigbee-herdsman-converters to 14.0.582 (#13332)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-30 08:52:22 +00:00
github-actions[bot]andKoenkk f5740021a1 Update zigbee-herdsman-converters to 14.0.581 (#13327)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-29 15:16:24 +00:00
github-actions[bot]andKoenkk 2996cfaf07 Update zigbee-herdsman-converters to 14.0.580 (#13321)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-28 16:33:03 +00:00
github-actions[bot]andKoenkk eda087af99 Update zigbee-herdsman-converters to 14.0.579 (#13303)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-26 18:10:02 +00:00
Koen Kanters 343ef7fd9f Only republish retained messages when none are received. #9629 2022-07-25 19:37:33 +02:00
Koen Kanters 316daee49d Republish retained messages when reconnected to MQTT server. #9629 2022-07-24 22:17:29 +02:00
github-actions[bot]andKoenkk 68aae1a450 Update zigbee-herdsman-converters to 14.0.578 (#13272)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-24 15:23:53 +00:00
github-actions[bot]andKoenkk d92b2f2ea9 Update dependencies (#13266)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-24 16:59:01 +02:00
github-actions[bot]andKoenkk e132a22f20 Update zigbee-herdsman-converters to 14.0.577 (#13260)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-23 15:36:49 +00:00
github-actions[bot]andKoenkk ebcf49b504 Update zigbee-herdsman-converters to 14.0.576 (#13254)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-23 10:30:57 +00:00
github-actions[bot]andKoenkk 6a2de3cd3b Update zigbee-herdsman-converters to 14.0.575 (#13237)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-21 20:58:00 +00:00
github-actions[bot]andKoenkk 8d8da9f286 Update zigbee-herdsman-converters to 14.0.574 (#13226)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-20 18:16:35 +00:00
Andrew Lamchenko 759c2f3f00 Add new clusters for bind (#13214)
* Add new clasters for bind

Add new clasters for bind

* Add new clasters for bind

Add new clasters for bind
2022-07-20 19:41:46 +02:00
github-actions[bot]andKoenkk b140e4bfe6 Update zigbee-herdsman-converters to 14.0.573 (#13213)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-19 18:18:04 +00:00
github-actions[bot]andKoenkk 4ef9ea749d Update zigbee-herdsman-converters to 14.0.571 (#13187)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-17 20:56:28 +00:00
github-actions[bot]andKoenkk 11f3f5b170 Update zigbee-herdsman to 0.14.46 (#13185)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-17 20:30:52 +00:00
github-actions[bot]andKoenkk b6f88aad80 Update dependencies (#13173)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-17 22:14:33 +02:00
Koen Kanters d07b65a03d Fix coverage 2022-07-17 22:14:02 +02:00
Koen Kanters aabc010191 Log error stack on fromZigbee converter error. https://github.com/Koenkk/zigbee2mqtt/issues/13138 2022-07-17 22:03:24 +02:00
github-actions[bot]andnurikk cf8e7b10db Update zigbee2mqtt-frontend to 0.6.107 (#13175)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-07-17 03:15:43 +00:00
github-actions[bot]andKoenkk 63777464cc Update zigbee-herdsman-converters to 14.0.570 (#13162)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-15 15:33:36 +00:00
Koen Kanters 26fc4609f0 Enable publish to ghcr.io 2022-07-15 12:50:43 +02:00
github-actions[bot]andKoenkk 1d8d6fe070 Update zigbee-herdsman-converters to 14.0.569 (#13150)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-14 15:31:24 +00:00
Koen Kanters ca2186a9c5 Finally fix for https://github.com/Koenkk/zigbee2mqtt/issues/13080 2022-07-13 22:04:27 +02:00
github-actions[bot]andKoenkk 7d8b506c49 Update zigbee-herdsman-converters to 14.0.568 (#13134)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-13 17:39:24 +00:00
Koen Kanters 994de20f49 Another attempt to fix https://github.com/Koenkk/zigbee2mqtt/issues/13080 2022-07-13 18:05:45 +02:00
github-actions[bot]andKoenkk f553601ff1 Update zigbee-herdsman to 0.14.45 (#13132)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-13 15:40:54 +00:00
Koen Kanters 3478715926 Update ci.yml 2022-07-12 22:15:26 +02:00
Koen Kanters ed351ee712 TEMP: disable ghcr.io Docker build since ghcr.io is unstable 2022-07-12 22:09:43 +02:00
github-actions[bot]andKoenkk affa15cbae Update zigbee-herdsman to 0.14.44 (#13121)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-12 19:58:07 +00:00
Koen Kanters c6d504a5df Set device_class to temperature for local_temperature_calibration. https://github.com/Koenkk/zigbee2mqtt/issues/13080 2022-07-12 21:45:20 +02:00
Koen Kanters 420b34c909 Fix group and device states changing when cached states are published. https://github.com/Koenkk/zigbee2mqtt/issues/13028 2022-07-12 17:01:29 +02:00
github-actions[bot]andnurikk 4347034ba1 Update zigbee2mqtt-frontend to 0.6.106 (#13110)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-07-12 03:01:48 +00:00
github-actions[bot]andKoenkk ec8e7ed946 Update zigbee-herdsman-converters to 14.0.567 (#13104)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-11 15:57:15 +00:00
Koen Kanters 440fc74368 Fix Home Assistant discovery error: expected NumberDeviceClass or one of 'temperature' for dictionary value @ data['device_class']. https://github.com/Koenkk/zigbee2mqtt/issues/13080 2022-07-11 17:44:08 +02:00
Jorge Schrauwen a0255d0f2c Always treat filtered_* as full matches (#13083)
* Revert "update tests to use regex ^$ anchors"

This reverts commit 3d9bc552e9.

* utils: filterProperties should ensure full match
2022-07-11 17:24:34 +02:00
github-actions[bot]andKoenkk 14216b7454 Update zigbee-herdsman-converters to 14.0.566 (#13093)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-10 08:11:17 +00:00
github-actions[bot]andKoenkk 0da033ce95 Update zigbee-herdsman to 0.14.43 (#13092)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-10 07:57:07 +00:00
3bd3196a40 Update dependencies (#13089)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-07-10 09:23:51 +02:00
github-actions[bot]andnurikk 47e05c32ec Update zigbee2mqtt-frontend to 0.6.105 (#13090)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-07-10 01:55:15 +00:00
github-actions[bot]andKoenkk bcd19509fb Update zigbee-herdsman-converters to 14.0.565 (#13085)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-09 18:32:35 +00:00
github-actions[bot]andKoenkk 05a9920638 Update zigbee-herdsman to 0.14.42 (#13084)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-09 18:05:19 +00:00
Koen Kanters 8af3ad5541 Fix crash when ZIGBEE2MQTT_CONFIG_ADVANCED_NETWORK_KEY environment variable is set to GENERATE. https://github.com/Koenkk/zigbee2mqtt/issues/12999 2022-07-08 16:58:23 +02:00
Koen Kanters 6ef9e4f479 Fix matrix test jobs unstable (#13068)
* Update ci.yml

* Update ci.yml
2022-07-07 15:21:37 +02:00
183dad97e7 Update zigbee-herdsman to 0.14.41 (#13063)
* Update zigbee-herdsman to 0.14.41

* Update package-lock.json

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-07-07 07:44:34 +00:00
github-actions[bot]andKoenkk 3bbdf17fed Update zigbee-herdsman-converters to 14.0.564 (#13062)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-06 15:50:54 +00:00
Jorge Schrauwen db021e6711 Allow regexes for filtered_attributes, filtered_cache and filtered_optimistic options (#13047)
* Ensure filtered_attributes and filtered_optimistic are also regex

Bring filtered_attributes and filtered_optimistic in line with the newer filtered_cache.
All three of them are now regex matches instead of absolute matches.

* update tests to use regex ^$ anchors

* utils: add filterProperties
2022-07-06 17:07:22 +02:00
github-actions[bot]andKoenkk 4a58dbf84c Update zigbee-herdsman-converters to 14.0.563 (#13049)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-05 15:20:46 +00:00
github-actions[bot]andKoenkk ee227d85c7 Update zigbee-herdsman-converters to 14.0.562 (#13035)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-04 15:20:19 +00:00
github-actions[bot]andKoenkk d8c0ef8a9c Update dependencies (#13023)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-04 17:05:01 +02:00
github-actions[bot]andKoenkk 53ae00c46f Update zigbee-herdsman-converters to 14.0.561 (#13022)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-02 18:53:10 +00:00
Jorge SchrauwenandKoen Kanters dedbf336af Add filtered_cache option (#12988)
* want a way to prevent attribute from being cached

* Update filtered_cache description to be more clear

* Fix emitStateChange was returning wrong payload in to parameter

* Directly get filtered_cache from entity and forgo parameter to State.set()

* Add tests to cover filtered_cache

* Update state.ts

* Update controller.test.js

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-07-02 20:33:04 +02:00
Sam bc4ffc00b6 add search before issue create requirement (#13021) 2022-07-02 20:28:30 +02:00
5662e6c29e Update zigbee-herdsman-converters to 14.0.560 (#13016)
* Update zigbee-herdsman-converters to 14.0.560

* Fix tests

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-07-01 21:35:16 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 4cc838accf Bump actions/dependency-review-action from 1 to 2 (#13009)
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 1 to 2.
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: actions/dependency-review-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-01 23:10:32 +02:00
github-actions[bot]andnurikk 3b58ac79dc Update zigbee2mqtt-frontend to 0.6.104 (#13008)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-07-01 15:20:07 +00:00
bab764e2be Binding to msRelativeHumidity (#12877)
* Binding to new clusters

Binding to new clusters. This is necessary for new EFEKTA devices.

* Update bind.ts

* Fix tests

Co-authored-by: nurikk <ainur@yojee.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-07-01 17:02:34 +02:00
Koen Kanters 81892ef70d Promote to dev 2022-07-01 16:42:33 +02:00
Koen Kanters cd23aeaa46 1.26.0 2022-07-01 16:41:38 +02:00
Koen Kanters 5d5b731053 Undev 2022-07-01 16:41:00 +02:00
Koen Kanters c973632efd Merge branch 'dev' 2022-07-01 16:40:18 +02:00
github-actions[bot]andKoenkk e0b63f2baa Update zigbee-herdsman-converters to 14.0.559 (#13004)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-07-01 14:39:37 +00:00
github-actions[bot]andKoenkk 3d406c3c0d Update zigbee-herdsman-converters to 14.0.558 (#12984)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-29 16:06:12 +00:00
github-actions[bot]andKoenkk d4811791fc Update zigbee-herdsman to 0.14.40 (#12983)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-29 16:01:43 +00:00
github-actions[bot]andKoenkk 3b7ef63300 Update zigbee-herdsman-converters to 14.0.557 (#12975)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-28 15:15:39 +00:00
github-actions[bot]andKoenkk 8adb2f1247 Update zigbee-herdsman-converters to 14.0.556 (#12967)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-27 17:18:22 +00:00
Vladimir Vitkov 326c2aaa90 Allow to specify MQTT server in secrets (#12904)
* add server, pan_id, ext_pan_id to secrets

* fix tests

* clean secrets before every test run

* add interpolation of mqtt.server, advanced.pan_id, advanced.ext_pan_id and split mqtt.user, mqtt.pass requirement

* remove pan_id and ext_pan_id from secrets processing
2022-06-27 18:42:05 +02:00
e291687870 Update zigbee-herdsman-converters to 14.0.555 (#12951)
* Update zigbee-herdsman-converters to 14.0.555

* Fix tests

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-06-26 17:01:17 +02:00
Koen Kanters 80f8fb4d98 Node 17 is EOL 2022-06-26 16:56:01 +02:00
RoboMagus 402081e39d Fix EnvVar parsing of settings scheme with 'oneOf'. (#12948) 2022-06-26 16:16:44 +02:00
Koen Kanters 05309db92b Fix crash when poll of bounded device fails. https://github.com/Koenkk/zigbee2mqtt/issues/12918 2022-06-26 16:14:21 +02:00
github-actions[bot]andKoenkk d3fa977ebf Update dependencies (#12942)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-26 09:46:15 +02:00
github-actions[bot]andKoenkk 92f7bc8eb5 Update zigbee-herdsman to 0.14.39 (#12926)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-24 14:19:32 +00:00
github-actions[bot]andKoenkk 80b6f1dfa3 Update zigbee-herdsman-converters to 14.0.554 (#12906)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-22 15:20:07 +00:00
github-actions[bot]andKoenkk 1eaa73bb52 Update zigbee-herdsman-converters to 14.0.553 (#12895)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-21 14:39:48 +00:00
github-actions[bot]andKoenkk 0fc831cd82 Update zigbee-herdsman-converters to 14.0.552 (#12886)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-20 16:20:23 +00:00
github-actions[bot]andKoenkk 59c18af1f7 Update dependencies (#12874)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-20 17:47:45 +02:00
github-actions[bot]andnurikk 0fd47c0ad1 Update zigbee2mqtt-frontend to 0.6.103 (#12885)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-06-20 15:32:50 +00:00
github-actions[bot]andnurikk 6b643f0e67 Update zigbee2mqtt-frontend to 0.6.102 (#12884)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-06-20 14:55:48 +00:00
github-actions[bot]andKoenkk 3c9fab143c Update zigbee-herdsman-converters to 14.0.551 (#12871)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-18 17:50:50 +00:00
Koen Kanters f2e953cf18 Add group off_state option (#12868) 2022-06-18 15:47:06 +02:00
github-actions[bot]andKoenkk ecb18a6c41 Update zigbee-herdsman-converters to 14.0.550 (#12864)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-18 09:24:55 +00:00
github-actions[bot]andKoenkk d405c43202 Update zigbee-herdsman-converters to 14.0.549 (#12862)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-18 08:30:31 +00:00
github-actions[bot]andKoenkk 24e7a368cb Update zigbee-herdsman to 0.14.38 (#12861)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-18 08:22:20 +00:00
github-actions[bot]andKoenkk 8848e1e6ce Update zigbee-herdsman-converters to 14.0.548 (#12856)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-17 15:08:56 +00:00
John Doeandnurikk 820c20af80 Fix windows tests (#12840)
Co-authored-by: nurikk <ainur@yojee.com>
2022-06-16 14:00:09 +08:00
github-actions[bot]andnurikk 4b8b951c28 Update zigbee2mqtt-frontend to 0.6.101 (#12839)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-06-16 05:37:34 +00:00
github-actions[bot]andnurikk 8964421350 Update zigbee2mqtt-frontend to 0.6.100 (#12838)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-06-16 05:13:27 +00:00
github-actions[bot]andKoenkk 0895f29a83 Update zigbee-herdsman-converters to 14.0.547 (#12833)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-15 16:00:32 +00:00
Koen Kanters f213729dcb Remove Home Assistant away_mode_* discovery. https://github.com/Koenkk/zigbee2mqtt/issues/11738 2022-06-15 17:56:13 +02:00
rikroeandKoen Kanters 6df20010dd Change HA hold_mode to preset_mode (#12565)
* Update homeassistant.ts

* Update homeassistant.test.js

* Update homeassistant.ts

* Update homeassistant.ts

* Updates

* Updates

* Updates

* Updates

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-06-15 17:40:44 +02:00
github-actions[bot]andKoenkk a5204cdeb1 Update zigbee-herdsman to 0.14.37 (#12832)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-15 15:14:36 +00:00
Koen Kanters dd129830d3 Create herdsman backup before backup. https://github.com/Koenkk/zigbee2mqtt/pull/12797 2022-06-15 17:05:20 +02:00
github-actions[bot]andKoenkk a8233e0521 Update zigbee-herdsman to 0.14.36 (#12831)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-15 17:04:20 +02:00
Koen Kanters 9b2a92106e Disable ghcr_cleanup 2022-06-15 17:03:16 +02:00
github-actions[bot]andKoenkk 8fe6ab4866 Update zigbee-herdsman-converters to 14.0.546 (#12826)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-14 18:36:31 +00:00
Koen Kanters a08ff9bf6d Prepare for zhc 14.0.546 2022-06-14 20:31:25 +02:00
Koen Kanters 83b490a968 Add zigbee2mqtt/bridge/request/backup (#12797)
* Add backup call

* Updates
2022-06-14 20:14:01 +02:00
github-actions[bot]andnurikk 3498c6e260 Update zigbee2mqtt-frontend to 0.6.99 (#12812)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-06-13 14:28:42 +00:00
github-actions[bot]andKoenkk 5c93aaf6db Update zigbee-herdsman-converters to 14.0.545 (#12804)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-12 19:51:52 +00:00
github-actions[bot]andKoenkk e860978564 Update zigbee-herdsman-converters to 14.0.544 (#12796)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-12 07:17:00 +00:00
github-actions[bot]andKoenkk 2d7a6e9f42 Update dependencies (#12795)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-12 08:48:41 +02:00
github-actions[bot]andKoenkk 1390bc1d04 Update zigbee-herdsman-converters to 14.0.543 (#12783)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-11 08:12:40 +00:00
github-actions[bot]andKoenkk a9349ac49d Update zigbee-herdsman to 0.14.35 (#12782)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-11 08:07:05 +00:00
github-actions[bot]andKoenkk 5bed214aef Update zigbee-herdsman-converters to 14.0.542 (#12781)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-11 07:53:34 +00:00
github-actions[bot]andKoenkk 4f181b0107 Update zigbee-herdsman-converters to 14.0.541 (#12767)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-09 19:25:49 +00:00
Koen Kanters 8e2f0f613f Send cached group state on startup and when Home Assistant comes online. https://github.com/Koenkk/zigbee2mqtt/issues/12693 2022-06-09 20:52:39 +02:00
github-actions[bot]andKoenkk 2bb4f91d1c Update zigbee-herdsman-converters to 14.0.540 (#12756)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-08 18:29:55 +00:00
Koen Kanters 389ff844c4 Revert "Revert "Revert "Temp: disable ghcr.io since it makes build fail"""
This reverts commit 975eb7d6ae.
2022-06-08 16:40:20 +02:00
github-actions[bot]andKoenkk cb0542eaad Update zigbee-herdsman-converters to 14.0.539 (#12746)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-07 16:17:18 +00:00
Koen Kanters 300b2973e1 Update ci.yml 2022-06-06 13:32:44 +02:00
Koen Kanters 5c44582b69 Update zigbee2mqtt/hassio-zigbee2mqtt trigger 2022-06-06 12:58:37 +02:00
github-actions[bot]andKoenkk 2f2a66db2e Update zigbee-herdsman-converters to 14.0.538 (#12728)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-05 20:07:53 +00:00
github-actions[bot]andKoenkk b075d6bbda Update dependencies (#12727)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-05 22:02:11 +02:00
Koen Kanters a252914ecd Update update_deps.yml 2022-06-05 21:48:26 +02:00
github-actions[bot]andKoenkk 87edd1e6f1 Update zigbee-herdsman-converters to 14.0.537 (#12712)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-04 12:25:18 +00:00
github-actions[bot]andKoenkk ba69e1788f Update zigbee-herdsman-converters to 14.0.536 (#12709)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-04 08:42:26 +00:00
Naveen 05538ec28b chore: Enable codeql action (#12708)
This action runs GitHub's industry-leading semantic code analysis engine,
CodeQL, against a repository's source code to find security vulnerabilities.

https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/about-code-scanning-with-codeql

https://github.com/ossf/scorecard/blob/main/docs/checks.md#sast
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
2022-06-04 10:28:44 +02:00
NaveenandKoen Kanters 2676c3f641 chore(deps): Included dependency review (#12695)
* chore(deps): Included dependency review

> Dependency Review GitHub Action in your repository to enforce dependency
> reviews on your pull requests.
> The action scans for vulnerable versions of dependencies introduced by package version
> changes in pull requests,
> and warns you about the associated security vulnerabilities.
> This gives you better visibility of what's changing in a pull request,
> and helps prevent vulnerabilities being added to your repository.

https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>

* Update depsreview.yaml

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-06-03 16:41:06 +02:00
github-actions[bot]andKoenkk e525919160 Update zigbee-herdsman-converters to 14.0.535 (#12692)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-02 16:13:26 +00:00
John Doeandnurikk d064a73131 Rework ci and use package-lock.json instead of npm-shrinkwrap.json (#12631)
* Update ci

* Use package-lock

* Use package-lock.json

* Use cache for ci

* Enable node18 windows

* Revert "Enable node18 windows"

This reverts commit e427551acdd64c3a256b48a5b8e86b3c4c986405.

* Remove redundant cache

* Don't do shrinkwrap

* Remove shrinkwrap

* Remove redundant step

* Cache node-gyp

* Debug

* Add key

* Update ci.yml

* Add cache detection

* Fix

* Add deps

* Fix2

* Update caches

* Fix ci

* Update patsh

* Update paths

* Update paths

* Fix max cache path

* Change cache key

* Remove spaces

* Split caches

* Fix linux cache

* Fix linux cache

* Merge caches

* Ignore errs

* Find only dirs

* Run find after ci

* Fix mac cache

* Fix caches

* Remove env run

Co-authored-by: nurikk <ainur@yojee.com>
2022-06-02 14:38:07 +00:00
Koen Kanters 64ab3b0492 Revert "Downgrade docker/setup-qemu-action to v1"
This reverts commit 35b9e01230.
2022-06-02 16:27:18 +02:00
Koen Kanters e1c9d68c68 Revert "Check if ghcr.io build works again"
This reverts commit 1596714ccb.
2022-06-02 16:27:11 +02:00
Koen Kanters 35b9e01230 Downgrade docker/setup-qemu-action to v1 2022-06-02 16:13:40 +02:00
Koen Kanters 1596714ccb Check if ghcr.io build works again 2022-06-02 16:02:51 +02:00
Koen Kanters e852851273 Update ghcr_cleanup.yml 2022-06-02 08:30:55 +02:00
github-actions[bot]andKoenkk 24e9c5bc9f Update zigbee-herdsman-converters to 14.0.534 (#12676)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-01 17:22:40 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> dc4f4ad047 Bump actions/github-script from 3 to 6 (#12674)
Bumps [actions/github-script](https://github.com/actions/github-script) from 3 to 6.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/v3...v6)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-01 19:16:21 +02:00
neilnaveenandKoen Kanters cc42ab7584 chore: Set permissions for GitHub actions (#12626)
Restrict the GitHub token permissions only to the required ones; this way, even if the attackers will succeed in compromising your workflow, they won’t be able to do much.

- Included permissions for the action. https://github.com/ossf/scorecard/blob/main/docs/checks.md#token-permissions

https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions

https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs

[Keeping your GitHub Actions and workflows secure Part 1: Preventing pwn requests](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/)

Signed-off-by: neilnaveen <42328488+neilnaveen@users.noreply.github.com>

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-06-01 19:15:06 +02:00
Koen Kanters 03fdb0cb88 Fix Home Assistant rename creating duplicate entities. #12610 2022-06-01 18:57:02 +02:00
Koen Kanters f7c6518506 Promote to dev 2022-06-01 17:38:46 +02:00
Koen Kanters 3c5854fa9f 1.25.2 2022-06-01 17:38:09 +02:00
Koen Kanters 900175af47 Undev 2022-06-01 17:37:39 +02:00
Koen Kanters 9b9e2289d3 Merge remote-tracking branch 'origin/master' into dev 2022-06-01 17:36:50 +02:00
github-actions[bot]andKoenkk ea10936641 Update zigbee-herdsman-converters to 14.0.533 (#12672)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-01 15:14:02 +00:00
github-actions[bot]andKoenkk 6b56b0bcf8 Update zigbee-herdsman-converters to 14.0.532 (#12671)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-06-01 15:03:10 +00:00
Koen Kanters 975eb7d6ae Revert "Revert "Temp: disable ghcr.io since it makes build fail""
This reverts commit 4e28df88ae.
2022-06-01 16:57:47 +02:00
Koen Kanters 4de04c19c0 Update ghcr_cleanup.yml 2022-06-01 15:12:32 +02:00
Koen Kanters 1db12612e6 Add GHCR cleanup (#12669)
* Create ghcr_cleanup.yml

* Update ghcr_cleanup.yml

* Update ghcr_cleanup.yml

* Update ghcr_cleanup.yml

* Update ghcr_cleanup.yml
2022-06-01 14:18:41 +02:00
github-actions[bot]andKoenkk ec010df79a Update zigbee-herdsman-converters to 14.0.531 (#12659)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-31 15:17:42 +00:00
github-actions[bot]andKoenkk 88b65625de Update zigbee-herdsman to 0.14.34 (#12658)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-31 14:58:08 +00:00
Koen Kanters 4e28df88ae Revert "Temp: disable ghcr.io since it makes build fail"
This reverts commit a1db076c02.
2022-05-31 08:28:36 +02:00
github-actions[bot]andKoenkk 44815435e7 Update zigbee-herdsman-converters to 14.0.530 (#12645)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-30 16:11:37 +00:00
Koen Kanters fe011ba7b3 Disable node 18 testing for now (fails quite often) 2022-05-29 10:21:23 +02:00
Koen Kanters 68035a1256 Fix restart not working (#12629) 2022-05-29 08:15:47 +00:00
github-actions[bot]andKoenkk cc535f11c6 Update zigbee-herdsman-converters to 14.0.529 (#12628)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-29 07:23:01 +00:00
github-actions[bot]andKoenkk 7001b2fc79 Update dependencies (#12627)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-29 06:46:27 +00:00
Koen Kanters 05975109a4 Lock connect-gzip-static https://github.com/Koenkk/zigbee2mqtt/pull/12624/files#r884205347 2022-05-29 08:43:02 +02:00
github-actions[bot]andKoenkk 502443aae8 Update zigbee-herdsman-converters to 14.0.528 (#12615)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-27 19:15:31 +00:00
Koen Kanters 43a82ad835 Delete ghcr_delete_untagged.yml 2022-05-27 16:29:50 +02:00
Koen Kanters a1db076c02 Temp: disable ghcr.io since it makes build fail 2022-05-27 16:23:34 +02:00
Koen Kanters bfc70c3bb8 Update ghcr_delete_untagged.yml 2022-05-27 15:09:48 +02:00
Koen Kanters b268b1ed75 Update ghcr_delete_untagged.yml 2022-05-27 12:08:55 +02:00
Koen Kanters 64769b3e9f Update ghcr_delete_untagged.yml 2022-05-27 12:05:51 +02:00
Koen Kanters 66e804d71e Create ghcr_delete_untagged.yml 2022-05-27 12:01:21 +02:00
github-actions[bot]andKoenkk 1c30a4f4bc Update zigbee-herdsman to 0.14.33 (#12612)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-27 09:51:49 +00:00
Koen Kanters be55e3ee80 Revert "Temp disable ghcr.io push (seems to make build fail)"
This reverts commit c1372852e9.
2022-05-27 11:47:43 +02:00
github-actions[bot]andnurikk 1aa7971ca1 Update zigbee2mqtt-frontend to 0.6.97 (#12605)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-05-26 11:25:29 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 6e2ab644a0 Bump peter-evans/create-pull-request from 3 to 4 (#12602)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 3 to 4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v3...v4)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-26 09:54:13 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 4fa6c33622 Bump peter-evans/enable-pull-request-automerge from 1 to 2 (#12600)
Bumps [peter-evans/enable-pull-request-automerge](https://github.com/peter-evans/enable-pull-request-automerge) from 1 to 2.
- [Release notes](https://github.com/peter-evans/enable-pull-request-automerge/releases)
- [Commits](https://github.com/peter-evans/enable-pull-request-automerge/compare/v1...v2)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-26 09:53:39 +02:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 3fd405e570 Bump actions/stale from 3 to 5 (#12601)
Bumps [actions/stale](https://github.com/actions/stale) from 3 to 5.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v3...v5)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-05-26 09:53:15 +02:00
Koen Kanters c1372852e9 Temp disable ghcr.io push (seems to make build fail) 2022-05-26 09:50:39 +02:00
Koen Kanters 95eedc9ec1 Add dependabot.yml 2022-05-26 09:48:43 +02:00
Koen Kanters d7b926d47f Update ci.yml dependencies 2022-05-26 09:43:11 +02:00
github-actions[bot]andKoenkk 67039a1a94 Update zigbee-herdsman-converters to 14.0.527 (#12599)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-26 07:27:42 +00:00
github-actions[bot]andKoenkk f79fb16e41 Update zigbee-herdsman-converters to 14.0.526 (#12595)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-25 16:58:18 +00:00
Koen Kanters d910c05e6e Improve tests 2022-05-25 11:38:37 +02:00
github-actions[bot]andnurikk 4858e06060 Update zigbee2mqtt-frontend to 0.6.96 (#12592)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-05-25 09:31:15 +00:00
f71db6816a Update zigbee-herdsman-converters to 14.0.525 (#12585)
* Update zigbee-herdsman-converters to 14.0.525

* Fix tests

* Ignore

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-05-24 18:27:17 +00:00
github-actions[bot]andnurikk c6b129c68d Update zigbee2mqtt-frontend to 0.6.95 (#12572)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-05-23 04:59:27 +00:00
e5dbe01329 Update zigbee-herdsman-converters to 14.0.522 (#12568)
* Update zigbee-herdsman-converters to 14.0.522

* Fix

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-05-22 20:32:15 +00:00
Koen Kanters c00768b7c7 Move ci before tests 2022-05-21 15:08:07 +02:00
Koen Kanters ad070c99ef Add official support for node 18 and drop for node 10, 12, 15 (#12553) 2022-05-21 08:29:22 +00:00
aec082c0cf Update zigbee-herdsman-converters to 14.0.521 (#12552)
* Update zigbee-herdsman-converters to 14.0.521

* Fixes

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-05-21 08:20:37 +00:00
github-actions[bot]andKoenkk cc84452f23 Update zigbee-herdsman to 0.14.32 (#12551)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-21 07:45:02 +00:00
John Doeandnurikk 84bac2b8d8 Add compatibility tests (#12527)
* Add tests gh action

* Fix zigbee_ota_override_index_location

* Fix Shouldnt crash when it cannot save state test

* Add node17

* Update tests.yml

* Drop old versions

* Move to ci.yml

* Update controller.test.js

* Fix linebraks on windows

* Ignore windows and node 17

* Fail on error

* Add comment

* Mark node 18 as supported

Co-authored-by: nurikk <ainur@yojee.com>
2022-05-21 08:37:39 +02:00
github-actions[bot]andKoenkk 29a9d227de Update zigbee-herdsman-converters to 14.0.520 (#12546)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-20 14:58:14 +00:00
github-actions[bot]andnurikk 39ae0c775a Update zigbee2mqtt-frontend to 0.6.94 (#12540)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-05-20 02:44:04 +00:00
github-actions[bot]andKoenkk f1eaf2d7aa Update zigbee-herdsman-converters to 14.0.519 (#12530)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-18 15:35:44 +00:00
Koen Kanters c6840a9a43 Mark node 17 as supported 2022-05-18 14:56:17 +02:00
John Doeandnurikk 3a1c64a88e Downgrade connect-gzip-static to 2.1.1 (#12525)
Co-authored-by: nurikk <ainur@yojee.com>
2022-05-18 17:30:04 +08:00
github-actions[bot]andnurikk d4a0c93c91 Update zigbee2mqtt-frontend to 0.6.86 (#12524)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-05-18 08:14:56 +00:00
github-actions[bot]andKoenkk 5ae8347317 Update zigbee-herdsman-converters to 14.0.518 (#12518)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-17 15:06:53 +00:00
github-actions[bot]andKoenkk afbfa4631f Update zigbee-herdsman to 0.14.31 (#12504)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-16 16:05:24 +00:00
github-actions[bot]andKoenkk 096f906ac7 Update zigbee-herdsman-converters to 14.0.517 (#12503)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-16 14:44:14 +00:00
github-actions[bot]andnurikk b844f607ee Update zigbee2mqtt-frontend to 0.6.85 (#12502)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-05-16 13:59:21 +00:00
github-actions[bot]andKoenkk 6002bc475b Update dependencies (#12479)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-16 15:19:07 +02:00
github-actions[bot]andKoenkk 24cfdf4594 Update zigbee-herdsman to 0.14.30 (#12466)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-13 13:15:51 +00:00
github-actions[bot]andKoenkk bc5fd1a52f Update zigbee-herdsman to 0.14.29 (#12464)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-13 08:30:16 +00:00
Koen Kanters fd344a3017 Revert "Additional logging for https://github.com/Koenkk/zigbee2mqtt/issues/12432"
This reverts commit 920b4924b0.
2022-05-13 10:05:49 +02:00
github-actions[bot]andKoenkk f9bd184543 Update zigbee-herdsman-converters to 14.0.516 (#12460)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-12 17:53:53 +00:00
github-actions[bot]andKoenkk f2c1e85b4b Update zigbee-herdsman-converters to 14.0.515 (#12447)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-11 18:21:27 +00:00
Koen Kanters 920b4924b0 Additional logging for https://github.com/Koenkk/zigbee2mqtt/issues/12432 2022-05-11 17:22:48 +02:00
github-actions[bot]andKoenkk 99e67b1495 Update zigbee-herdsman-converters to 14.0.514 (#12435)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-10 18:03:45 +00:00
github-actions[bot]andKoenkk e65344c9fa Update zigbee-herdsman-converters to 14.0.513 (#12429)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-09 18:15:01 +00:00
147fe22f08 Update dependencies (#12416)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-05-08 10:01:25 +02:00
Koen Kanters 7f1f1497c6 Always return a device state 2022-05-08 09:58:30 +02:00
Koen Kanters 6278c86d02 Pass device options in global on event. https://github.com/Koenkk/zigbee2mqtt/commit/723dd8358f3cee0b90d624f27989a8bb587e25b0#comments 2022-05-07 14:40:25 +02:00
6f09d45a7b Update zigbee-herdsman-converters to 14.0.512 (#12413)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-05-07 12:39:32 +00:00
Koen Kanters 49a730f77d Update tests for https://github.com/Koenkk/zigbee2mqtt/pull/12413 2022-05-07 14:37:29 +02:00
github-actions[bot]andKoenkk e5a74894d2 Update zigbee-herdsman-converters to 14.0.511 (#12409)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-07 08:43:02 +00:00
Jorge SchrauwenandKoen Kanters 723dd8358f Pass device state to zhc onEvent (#12407)
* onEvent: want device state as argument

* onEvent: test should check deviceOptions and deviceState returns

* Update onEvent.ts

* Update onEvent.ts

* Fix

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-05-07 08:36:03 +00:00
github-actions[bot]andKoenkk 47a22cce2a Update zigbee-herdsman-converters to 14.0.510 (#12403)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-06 15:24:31 +00:00
github-actions[bot]andKoenkk b3791684fd Update zigbee-herdsman-converters to 14.0.509 (#12392)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-05 16:43:18 +00:00
github-actions[bot]andKoenkk ebd3255fc6 Update zigbee-herdsman to 0.14.28 (#12390)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-05 16:17:04 +00:00
github-actions[bot]andKoenkk 9b594a4cba Update zigbee-herdsman-converters to 14.0.508 (#12380)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-04 19:08:08 +00:00
Koen Kanters d0530b8214 Don't allow friendly names to include control character. #12379 2022-05-04 21:00:29 +02:00
5c7e968028 Update zigbee-herdsman-converters to 14.0.507 (#12368)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-05-03 17:42:17 +00:00
Koen Kanters 40ef638e0e Fix null not allowed for Home Assistant device options. #12340 2022-05-03 19:39:30 +02:00
github-actions[bot]andKoenkk b9499618d3 Update zigbee-herdsman-converters to 14.0.506 (#12354)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-02 17:35:37 +00:00
Alex Kay 6618872839 Add new config and diagnostic entities to HA (#12353) 2022-05-02 19:23:40 +02:00
Alex Kay b977dd1140 Add battery2 for HA (#12332) 2022-05-02 14:20:45 +00:00
github-actions[bot]andnurikk 71d5c7b4a2 Update zigbee2mqtt-frontend to 0.6.84 (#12351)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-05-02 12:31:28 +00:00
github-actions[bot]andKoenkk dd8a83e592 Update zigbee-herdsman-converters to 14.0.505 (#12338)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-01 18:45:05 +00:00
Koen Kanters 664182def2 Promote to dev 2022-05-01 20:16:18 +02:00
Koen Kanters 3f6a13786e 1.25.1 2022-05-01 20:14:19 +02:00
Koen Kanters a800197262 Undev 2022-05-01 20:14:12 +02:00
github-actions[bot]andKoenkk 0c145d81cf Update zigbee-herdsman-converters to 14.0.504 (#12336)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-05-01 17:53:38 +00:00
github-actions[bot]andKoenkk 7d7f8aabfe Update zigbee-herdsman-converters to 14.0.503 (#12321)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-30 07:50:44 +00:00
github-actions[bot]andKoenkk 95c2fcfb00 Update zigbee-herdsman-converters to 14.0.502 (#12317)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-29 20:45:59 +00:00
github-actions[bot]andKoenkk 2a6a6c43ce Update zigbee-herdsman-converters to 14.0.501 (#12309)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-28 16:26:57 +00:00
github-actions[bot]andKoenkk 47ed86d735 Update zigbee-herdsman-converters to 14.0.500 (#12294)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-27 07:34:32 +00:00
github-actions[bot]andKoenkk 50990d1f7a Update zigbee-herdsman-converters to 14.0.499 (#12288)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-26 18:05:33 +00:00
Koen Kanters f7b484f24f Log stack trace of "Failed to execute LQI" error. https://github.com/Koenkk/zigbee2mqtt/issues/11968 2022-04-26 20:02:18 +02:00
github-actions[bot]andKoenkk f6ad3c9926 Update zigbee-herdsman-converters to 14.0.498 (#12280)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-25 18:31:28 +00:00
11b415634c Update zigbee-herdsman to 0.14.27 (#12267)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-04-24 18:40:24 +00:00
github-actions[bot]andKoenkk d980d38747 Update zigbee-herdsman-converters to 14.0.497 (#12266)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-24 18:32:09 +00:00
github-actions[bot]andKoenkk 808671dd59 Update dependencies (#12256)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-24 13:55:36 +02:00
Koen Kanters cf22dd60a0 Always respond to OTA request (#12247)
* Always respond to OTA request

* Improve

* Rename
2022-04-23 10:12:29 +02:00
github-actions[bot]andKoenkk 3b820bae9f Update zigbee-herdsman-converters to 14.0.496 (#12249)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-22 18:35:06 +00:00
github-actions[bot]andKoenkk 60a987c004 Update zigbee-herdsman-converters to 14.0.495 (#12240)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-21 15:46:27 +00:00
github-actions[bot]andKoenkk d90be2dc66 Update zigbee-herdsman-converters to 14.0.494 (#12233)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-20 17:09:34 +00:00
Koen Kanters e305ecf571 Improve #ec2bf1a95d6c45c093f68df832bc6bcbdd372a5a 2022-04-20 17:59:16 +02:00
Koen Kanters ec2bf1a95d Fix out of memory error when starting on system with low RAM. #12034 2022-04-20 16:59:30 +02:00
github-actions[bot]andKoenkk 7d5c44a5bd Update zigbee-herdsman-converters to 14.0.493 (#12213)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-19 07:09:28 +00:00
github-actions[bot]andKoenkk 8c4312db72 Update zigbee-herdsman-converters to 14.0.492 (#12210)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-18 17:32:40 +00:00
github-actions[bot]andKoenkk 037a72e0f3 Update zigbee-herdsman-converters to 14.0.491 (#12200)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-17 18:18:25 +00:00
github-actions[bot]andKoenkk d657ea48cf Update dependencies (#12195)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-17 11:47:00 +02:00
github-actions[bot]andKoenkk b4e0c3afcf Update zigbee-herdsman-converters to 14.0.490 (#12193)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-16 07:32:45 +00:00
John Doeandnurikk 27bc646cf6 Add home assistant name to settings schema (#12191)
Co-authored-by: nurikk <ainur@yojee.com>
2022-04-16 10:27:41 +08:00
github-actions[bot]andKoenkk 23ef22e9ba Update zigbee-herdsman-converters to 14.0.489 (#12190)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-15 22:09:50 +00:00
github-actions[bot]andKoenkk 84c8da2532 Update zigbee-herdsman-converters to 14.0.488 (#12186)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-15 15:05:35 +00:00
github-actions[bot]andnurikk e6ec66c844 Update zigbee2mqtt-frontend to 0.6.83 (#12185)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-04-15 14:16:14 +00:00
github-actions[bot]andnurikk d1c26f9aa0 Update zigbee2mqtt-frontend to 0.6.82 (#12181)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-04-15 12:44:03 +00:00
github-actions[bot]andnurikk a7704b9038 Update zigbee2mqtt-frontend to 0.6.81 (#12179)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-04-15 09:36:36 +00:00
github-actions[bot]andKoenkk eabd662757 Update zigbee-herdsman-converters to 14.0.487 (#12172)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-14 15:38:56 +00:00
github-actions[bot]andKoenkk 764895b9d2 Update zigbee-herdsman-converters to 14.0.486 (#12164)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-13 17:48:12 +00:00
Míguel Ángel Mulero MartínezandKoen Kanters 8f5b26a2fb Mark calibration, calibration_time and motor_reversal as config sensors (#12146)
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-04-13 19:37:41 +02:00
github-actions[bot]andKoenkk 533cd36ffd Update zigbee-herdsman to 0.14.26 (#12159)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-12 19:26:50 +02:00
github-actions[bot]andKoenkk 3a77ebf52d Update zigbee-herdsman-converters to 14.0.485 (#12156)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-12 15:11:50 +00:00
github-actions[bot]andKoenkk 0e3bef7e42 Update zigbee-herdsman to 0.14.25 (#12155)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-12 15:00:48 +00:00
github-actions[bot]andKoenkk dda63bd65a Update zigbee-herdsman-converters to 14.0.484 (#12145)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-11 15:59:24 +00:00
github-actions[bot]andKoenkk 2aa1b4ead3 Update zigbee-herdsman-converters to 14.0.483 (#12133)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-10 08:12:57 +00:00
github-actions[bot]andKoenkk 422b7e0168 Update dependencies (#12128)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-10 09:48:40 +02:00
github-actions[bot]andKoenkk 8053eceb84 Update zigbee-herdsman-converters to 14.0.482 (#12124)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-09 16:14:15 +00:00
github-actions[bot]andKoenkk d10d3c9b56 Update zigbee-herdsman-converters to 14.0.481 (#12118)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-08 14:54:54 +00:00
github-actions[bot]andKoenkk 6ff45b1006 Update zigbee-herdsman-converters to 14.0.480 (#12109)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-07 20:39:48 +00:00
github-actions[bot]andKoenkk c901e66e7a Update zigbee-herdsman-converters to 14.0.479 (#12103)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-07 16:01:10 +00:00
github-actions[bot]andKoenkk 6ee7f56df3 Update zigbee-herdsman-converters to 14.0.478 (#12094)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-06 15:38:55 +00:00
github-actions[bot]andKoenkk d7073409d4 Update zigbee-herdsman to 0.14.24 (#12092)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-06 15:27:58 +00:00
github-actions[bot]andKoenkk e46ddb8c79 Update zigbee-herdsman-converters to 14.0.477 (#12091)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-06 15:12:18 +00:00
github-actions[bot]andKoenkk f91d0f6bfe Update zigbee-herdsman-converters to 14.0.476 (#12084)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-05 18:21:15 +00:00
github-actions[bot]andKoenkk 7e61252d11 Update zigbee-herdsman-converters to 14.0.475 (#12069)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-04 18:26:35 +00:00
github-actions[bot]andKoenkk 67c5481965 Update zigbee-herdsman-converters to 14.0.474 (#12068)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-04 18:22:54 +00:00
github-actions[bot]andKoenkk e251fc0803 Update zigbee-herdsman-converters to 14.0.473 (#12060)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-03 19:27:11 +00:00
Koen Kanters 5d4268515c Fix garage door status incorrect in Home Assistant. https://github.com/Koenkk/zigbee2mqtt/issues/12038 2022-04-03 21:09:26 +02:00
github-actions[bot]andKoenkk 91d80f1bb0 Update zigbee-herdsman-converters to 14.0.472 (#12056)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-03 12:14:53 +00:00
github-actions[bot]andKoenkk c9fbc6d52e Update zigbee-herdsman to 0.14.23 (#12055)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-03 12:08:18 +00:00
github-actions[bot]andKoenkk b84ad454e5 Update zigbee-herdsman-converters to 14.0.471 (#12049)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-03 07:31:13 +00:00
github-actions[bot]andKoenkk 51ae801cb8 Update dependencies (#12047)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-03 08:49:18 +02:00
Koen Kanters cabef43421 Revert "Switch to package-lock.json"
This reverts commit 0163b7281a.
2022-04-03 08:49:03 +02:00
Koen Kanters 8fd8df75be Reduce Docker image size again. 2022-04-02 21:50:12 +02:00
Koen Kanters 51f8c1c487 Fix Docker build 2022-04-02 21:13:22 +02:00
Koen Kanters aeb9927c20 Reduce Docker image build time 2022-04-02 21:09:02 +02:00
Koen Kanters 0163b7281a Switch to package-lock.json 2022-04-02 20:57:44 +02:00
Koen Kanters 0471eb5501 Switch to package-lock.json 2022-04-02 20:51:32 +02:00
2679219d87 Update zigbee-herdsman to 0.14.22 (#12046)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-04-02 18:47:51 +00:00
Koen Kanters d83eb72c4b Add registry url 2022-04-02 20:44:16 +02:00
Koen Kanters 414ea10b14 Update actions 2022-04-02 20:41:18 +02:00
github-actions[bot]andKoenkk d6e29538b1 Update zigbee-herdsman-converters to 14.0.470 (#12045)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-02 18:38:36 +00:00
Koen Kanters eb9b764cc5 Anoter attempt to fix shrinkwrap 2022-04-02 20:25:02 +02:00
Koen Kanters db642832f8 Update shrinkwrap 2022-04-02 19:59:40 +02:00
github-actions[bot]andKoenkk a56e5e0f36 Update zigbee-herdsman to 0.14.21 (#12043)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-04-02 17:58:11 +00:00
Koen Kanters 1b0fbf556b Fix invalid Home Assistant device class for garage_door_contact. #12038 2022-04-02 19:31:32 +02:00
Artem Draft 3e7eddf3ce Improve handle motor_state in HA (#12028) 2022-04-02 19:17:36 +02:00
Koen Kanters ad24c4f677 Promote to dev 2022-04-01 08:28:18 +02:00
54 changed files with 18227 additions and 23291 deletions
+1
View File
@@ -15,6 +15,7 @@ module.exports = {
'indent': ['error', 4],
'max-len': ['error', {'code': 120}],
'no-prototype-builtins': 'off',
'linebreak-style': ['error', (process.platform === 'win32' ? 'windows' : 'unix')], // https://stackoverflow.com/q/39114446/2771889
},
'plugins': [
'jest',
@@ -8,6 +8,7 @@ body:
value: |
**IMPORTANT:** Before submitting:
- Make sure this device is not already supported in the [dev branch](https://www.zigbee2mqtt.io/advanced/more/switch-to-dev-branch.html)
- Make sure there is no existing issue or PR for this device already, search for your device here: https://github.com/Koenkk/zigbee2mqtt/issues
- Follow this [guide](https://www.zigbee2mqtt.io/advanced/support-new-devices/01_support_new_devices.html)
- If you are using the Home Assistant addon and are still on 1.18.1, check the first point of [this](https://github.com/Koenkk/zigbee2mqtt/releases/tag/1.19.0)
- type: input
+13
View File
@@ -0,0 +1,13 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
target-branch: dev
- package-ecosystem: "docker"
directory: "/docker"
schedule:
interval: "daily"
target-branch: dev
+39 -21
View File
@@ -2,26 +2,20 @@ name: CI
on: [push, pull_request]
permissions:
contents: read
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- 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') }}
registry-url: https://registry.npmjs.org/
cache: 'npm'
- name: Install dependencies
if: steps.cache-node-modules.outputs.cache-hit != 'true'
run: npm ci
- name: Build
run: npm run build
@@ -37,13 +31,13 @@ jobs:
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
uses: docker/setup-qemu-action@v2
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
uses: docker/setup-buildx-action@v2
with:
version: latest
- name: Docker build dev
@@ -75,9 +69,33 @@ jobs:
- 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"
curl \
-X POST \
-H "Authorization: token ${{ secrets.CR_PAT }}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/zigbee2mqtt/hassio-zigbee2mqtt/actions/workflows/ci.yml/dispatches \
-d '{"ref":"master","inputs":{}}'
tests:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [14, 16, 18]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
registry-url: https://registry.npmjs.org/
cache: 'npm'
- name: Install dependencies
# --ignore-scripts prevents the serialport build which often fails on Windows
run: npm ci --ignore-scripts
- name: Lint
run: npm run eslint
- name: Build
run: npm run build
- name: Test
run: npm run test-with-coverage
+34
View File
@@ -0,0 +1,34 @@
name: "Code Scanning - Action"
on:
pull_request:
push:
jobs:
CodeQL-Build:
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
runs-on: ubuntu-latest
permissions:
# required for all workflows
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below).
- name: Autobuild
uses: github/codeql-action/autobuild@v2
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
+14
View File
@@ -0,0 +1,14 @@
name: 'Dependency review'
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout repository'
uses: actions/checkout@v3
- name: 'Dependency review'
uses: actions/dependency-review-action@v2
+33
View File
@@ -0,0 +1,33 @@
on:
workflow_dispatch:
name: GHCR cleanup
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Delete untagged images
uses: actions/github-script@v6
with:
github-token: ${{ secrets.CR_PAT }}
script: |
const response = await github.request("GET /${{ env.OWNER }}/packages/container/${{ env.PACKAGE_NAME }}/versions",
{ per_page: ${{ env.PER_PAGE }}
});
for(version of response.data) {
if (version.metadata.container.tags.length == 0) {
try {
console.log("delete " + version.id)
const deleteResponse = await github.request("DELETE /${{ env.OWNER }}/packages/container/${{ env.PACKAGE_NAME }}/versions/" + version.id, { });
console.log("status " + deleteResponse.status)
} catch (e) {
console.log("failed")
}
}
}
env:
OWNER: user
PACKAGE_NAME: zigbee2mqtt
PER_PAGE: 2000
+8 -2
View File
@@ -4,11 +4,17 @@ on:
- cron: "0 0 * * *"
workflow_dispatch:
permissions:
contents: read
jobs:
stale:
permissions:
issues: write # for actions/stale to close stale issues
pull-requests: write # for actions/stale to close stale PRs
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
- uses: actions/stale@v5
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'
@@ -16,4 +22,4 @@ jobs:
days-before-stale: 30
days-before-close: 7
operations-per-run: 500
exempt-issue-labels: 'breaking change'
exempt-issue-labels: dont-stale
+11 -6
View File
@@ -4,21 +4,26 @@ on:
schedule:
- cron: "0 0 * * 0"
permissions:
contents: read
jobs:
update_deps:
permissions:
contents: write # for peter-evans/create-pull-request to create branch
pull-requests: write # for peter-evans/create-pull-request to create a PR
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
- uses: actions/setup-node@v3
with:
node-version: 16
- 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
- run: npx npm-check-updates -u -x connect-gzip-static # connect-gzip-static only supports node 16
- run: npm install
- uses: peter-evans/create-pull-request@v4
with:
commit-message: Update dependencies
branch: "update_deps"
+4 -4
View File
@@ -7,22 +7,22 @@ jobs:
update_frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install zigbee2mqtt-frontend@${{ github.event.client_payload.version }} --save-exact
- uses: peter-evans/create-pull-request@v3
- uses: peter-evans/create-pull-request@v4
id: cpr
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 }}
- run: sleep 5 # Otherwise pull request may not exist yet causing automerge to fail
- uses: peter-evans/enable-pull-request-automerge@v1
- uses: peter-evans/enable-pull-request-automerge@v2
if: steps.cpr.outputs.pull-request-operation == 'created'
with:
token: ${{ secrets.CR_PAT }}
+4 -4
View File
@@ -7,22 +7,22 @@ jobs:
update_zh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install zigbee-herdsman@${{ github.event.client_payload.version }} --save-exact
- uses: peter-evans/create-pull-request@v3
- uses: peter-evans/create-pull-request@v4
id: cpr
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 }}
- run: sleep 5 # Otherwise pull request may not exist yet causing automerge to fail
- uses: peter-evans/enable-pull-request-automerge@v1
- uses: peter-evans/enable-pull-request-automerge@v2
if: steps.cpr.outputs.pull-request-operation == 'created'
with:
token: ${{ secrets.CR_PAT }}
+4 -4
View File
@@ -7,22 +7,22 @@ jobs:
update_zhc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
ref: dev
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- uses: actions/setup-node@v2-beta
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm install zigbee-herdsman-converters@${{ github.event.client_payload.version }} --save-exact
- uses: peter-evans/create-pull-request@v3
- uses: peter-evans/create-pull-request@v4
id: cpr
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 }}
- run: sleep 5 # Otherwise pull request may not exist yet causing automerge to fail
- uses: peter-evans/enable-pull-request-automerge@v1
- uses: peter-evans/enable-pull-request-automerge@v2
if: steps.cpr.outputs.pull-request-operation == 'created'
with:
token: ${{ secrets.CR_PAT }}
+4 -9
View File
@@ -3,18 +3,13 @@ FROM node:16-alpine3.15 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 package*.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
@@ -22,8 +17,8 @@ RUN apk add --no-cache --virtual .buildtools make gcc g++ python3 linux-headers
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 dist ./dist
COPY package.json LICENSE index.js data/configuration.yaml ./
COPY docker/docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
@@ -34,4 +29,4 @@ ARG COMMIT
RUN echo "$COMMIT" > dist/.hash
ENTRYPOINT ["docker-entrypoint.sh"]
CMD [ "/sbin/tini", "--", "node", "index.js"]
CMD [ "/sbin/tini", "--", "node", "index.js"]
+16 -8
View File
@@ -2,8 +2,8 @@ require('core-js/features/object/from-entries');
require('core-js/features/array/flat');
const semver = require('semver');
const engines = require('./package.json').engines;
const indexJsRestart = 'indexjs.restart';
const fs = require('fs');
const os = require('os');
const path = require('path');
const {exec} = require('child_process');
const rimraf = require('rimraf');
@@ -15,12 +15,12 @@ let stopping = false;
const hashFile = path.join(__dirname, 'dist', '.hash');
async function restart() {
await stop(indexJsRestart);
await stop(true);
await start();
}
async function exit(code, reason) {
if (reason !== indexJsRestart) {
async function exit(code, restart) {
if (!restart) {
process.exit(code);
}
}
@@ -44,7 +44,15 @@ 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) => {
const env = {...process.env};
const _600mb = 629145600;
if (_600mb > os.totalmem() && !env.NODE_OPTIONS) {
// Prevent OOM on tsc compile for system with low memory
// https://github.com/Koenkk/zigbee2mqtt/issues/12034
env.NODE_OPTIONS = '--max_old_space_size=256';
}
exec('npm run build', {env, cwd: __dirname}, async (err, stdout, stderr) => {
if (err) {
process.stdout.write(', failed\n');
if (err.code === 134) {
@@ -101,14 +109,14 @@ async function start() {
await controller.start();
}
async function stop(reason=null) {
await controller.stop(reason);
async function stop(restart) {
await controller.stop(restart);
}
async function handleQuit() {
if (!stopping && controller) {
stopping = true;
await stop();
await stop(false);
}
}
+12 -13
View File
@@ -45,11 +45,12 @@ class Controller {
private state: State;
private mqtt: MQTT;
private restartCallback: () => void;
private exitCallback: (code: number) => void;
private exitCallback: (code: number, restart: boolean) => void;
private extensions: Extension[];
private extensionArgs: ExtensionArgs;
constructor(restartCallback: () => void, exitCallback: (code: number) => void) {
logger.init();
this.eventBus = new EventBus( /* istanbul ignore next */ (error) => {
logger.error(`Error: ${error.message}`);
logger.debug(error.stack);
@@ -154,9 +155,9 @@ class Controller {
// Send all cached states.
if (settings.get().advanced.cache_state_send_on_startup && settings.get().advanced.cache_state) {
for (const device of devices) {
if (this.state.exists(device)) {
this.publishEntityState(device, this.state.get(device));
for (const entity of [...devices, ...this.zigbee.groups()]) {
if (this.state.exists(entity)) {
this.publishEntityState(entity, this.state.get(entity), 'publishCached');
}
}
}
@@ -186,7 +187,7 @@ class Controller {
await this.callExtensions('start', [extension]);
}
async stop(): Promise<void> {
async stop(restart = false): Promise<void> {
// Call extensions
await this.callExtensions('stop', this.extensions);
this.eventBus.removeListeners(this);
@@ -198,16 +199,16 @@ class Controller {
try {
await this.zigbee.stop();
logger.info('Stopped Zigbee2MQTT');
await this.exit(0);
await this.exit(0, restart);
} catch (error) {
logger.error('Failed to stop Zigbee2MQTT');
await this.exit(1);
await this.exit(1, restart);
}
}
async exit(code: number): Promise<void> {
async exit(code: number, restart = false): Promise<void> {
await logger.end();
this.exitCallback(code);
this.exitCallback(code, restart);
}
@bind async onZigbeeAdapterDisconnected(): Promise<void> {
@@ -264,10 +265,8 @@ class Controller {
extension.adjustMessageBeforePublish?.(entity, message);
}
// filter mqtt message attributes
if (entity.options.filtered_attributes) {
entity.options.filtered_attributes.forEach((a) => delete message[a]);
}
// Filter mqtt message attributes
utils.filterProperties(entity.options.filtered_attributes, message);
if (Object.entries(message).length) {
const output = settings.get().advanced.output;
+1 -1
View File
@@ -200,7 +200,7 @@ export default class Availability extends Extension {
if (item.condition && this.state.get(device) && !item.condition(this.state.get(device))) continue;
const converter = device.definition.toZigbee.find((c) => c.key.find((k) => item.keys.includes(k)));
await converter?.convertGet?.(device.endpoint(), item.keys[0],
{message: this.state.get(device) || {}, mapped: device.definition})
{message: this.state.get(device), mapped: device.definition})
.catch((e) => {
logger.error(`Failed to read state of '${device.name}' after reconnect (${e.message})`);
});
+8 -2
View File
@@ -13,7 +13,8 @@ const legacyApi = settings.get().advanced.legacy_api;
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 clusterCandidates = ['genScenes', 'genOnOff', 'genLevelCtrl', 'lightingColorCtrl', 'closuresWindowCovering',
'hvacThermostat', 'msTemperatureMeasurement'];
'hvacThermostat', 'msIlluminanceMeasurement', 'msTemperatureMeasurement', 'msRelativeHumidity',
'msSoilMoisture', 'msCO2'];
// See zigbee-herdsman-converters
const defaultBindGroup = {type: 'group_number', ID: 901, name: 'default_bind_group'};
@@ -469,7 +470,12 @@ export default class Bind extends Extension {
const key = `${endpoint.getDevice().ieeeAddr}_${endpoint.ID}_${pollOnMessage.indexOf(poll)}`;
if (!this.pollDebouncers[key]) {
this.pollDebouncers[key] = debounce(async () => {
await endpoint.read(poll.read.cluster, readAttrs);
try {
await endpoint.read(poll.read.cluster, readAttrs);
} catch (error) {
logger.error(`Failed to poll ${readAttrs} from ` +
`${this.zigbee.resolveEntity(endpoint.getDevice()).name}`);
}
}, 1000);
}
+15
View File
@@ -10,6 +10,9 @@ import {detailedDiff} from 'deep-object-diff';
import Extension from './extension';
import Device from '../model/device';
import Group from '../model/group';
import data from '../util/data';
import JSZip from 'jszip';
import fs from 'fs';
const requestRegex = new RegExp(`${settings.get().mqtt.base_topic}/bridge/request/(.*)`);
@@ -38,6 +41,7 @@ export default class Bridge extends Extension {
'group/rename': this.groupRename,
'permit_join': this.permitJoin,
'restart': this.restart,
'backup': this.backup,
'touchlink/factory_reset': this.touchlinkFactoryReset,
'touchlink/identify': this.touchlinkIdentify,
'touchlink/scan': this.touchlinkScan,
@@ -233,6 +237,17 @@ export default class Bridge extends Extension {
return utils.getResponse(message, {}, null);
}
@bind async backup(message: string | KeyValue): Promise<MQTTResponse> {
await this.zigbee.backup();
const dataPath = data.getPath();
const files = utils.getAllFiles(dataPath).map((f) => [f, f.substring(dataPath.length + 1)])
.filter((f) => !f[1].startsWith('log'));
const zip = new JSZip();
files.forEach((f) => zip.file(f[1], fs.readFileSync(f[0])));
const base64Zip = await zip.generateAsync({type: 'base64'});
return utils.getResponse(message, {zip: base64Zip}, null);
}
@bind async permitJoin(message: KeyValue | string): Promise<MQTTResponse> {
if (typeof message === 'object' && !message.hasOwnProperty('value')) {
throw new Error('Invalid payload');
+1 -5
View File
@@ -100,11 +100,7 @@ export default class Frontend extends Extension {
}
for (const device of this.zigbee.devices(false)) {
let payload: KeyValue = {};
if (this.state.exists(device)) {
payload = {...payload, ...this.state.get(device)};
}
const payload = this.state.get(device);
const lastSeen = settings.get().advanced.last_seen;
/* istanbul ignore if */
if (lastSeen !== 'disable') {
+24 -13
View File
@@ -101,7 +101,7 @@ export default class Groups extends Extension {
@bind async onStateChange(data: eventdata.StateChange): Promise<void> {
const reason = 'groupOptimistic';
if (data.reason === reason) {
if (data.reason === reason || data.reason === 'publishCached') {
return;
}
@@ -129,11 +129,10 @@ export default class Groups extends Extension {
if (entity instanceof Device) {
for (const group of groups) {
if (group.zh.hasMember(entity.endpoint(endpointName)) &&
!equals(this.lastOptimisticState[group.ID], payload)) {
if (!payload || payload.state !== 'OFF' || this.areAllMembersOff(group)) {
this.lastOptimisticState[group.ID] = payload;
await this.publishEntityState(group, payload, reason);
}
!equals(this.lastOptimisticState[group.ID], payload) &&
this.shouldPublishPayloadForGroup(group, payload)) {
this.lastOptimisticState[group.ID] = payload;
await this.publishEntityState(group, payload, reason);
}
}
} else {
@@ -161,10 +160,9 @@ export default class Groups extends Extension {
await this.publishEntityState(device, memberPayload, reason);
for (const zigbeeGroup of groups) {
if (zigbeeGroup.zh.hasMember(member)) {
if (!payload || payload.state !== 'OFF' || this.areAllMembersOff(zigbeeGroup)) {
groupsToPublish.add(zigbeeGroup);
}
if (zigbeeGroup.zh.hasMember(member) &&
this.shouldPublishPayloadForGroup(zigbeeGroup, payload)) {
groupsToPublish.add(zigbeeGroup);
}
}
}
@@ -176,12 +174,19 @@ export default class Groups extends Extension {
}
}
private shouldPublishPayloadForGroup(group: Group, payload: KeyValue): boolean {
if (group.options.off_state === 'last_member_state') return true;
if (!payload || payload.state !== 'OFF') return true;
if (this.areAllMembersOff(group)) return true;
return false;
}
private areAllMembersOff(group: Group): boolean {
for (const member of group.zh.members) {
const device = this.zigbee.resolveEntity(member.getDevice());
if (this.state.exists(device)) {
const state = this.state.get(device);
if (state && state.state === 'ON') {
if (state.state === 'ON') {
return false;
}
}
@@ -287,6 +292,7 @@ export default class Groups extends Extension {
groupKey, deviceKey, skipDisableReporting, resolvedEntityEndpoint,
} = parsed;
const message = utils.parseJSON(data.message, data.message);
let changedGroups: Group[] = [];
const responseData: KeyValue = {device: deviceKey};
if (groupKey) {
@@ -315,6 +321,7 @@ export default class Groups extends Extension {
logger.info(`Adding '${resolvedEntityDevice.name}' to '${resolvedEntityGroup.name}'`);
await resolvedEntityEndpoint.addToGroup(resolvedEntityGroup.zh);
settings.addDeviceToGroup(resolvedEntityGroup.ID.toString(), keys);
changedGroups.push(resolvedEntityGroup);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
@@ -328,6 +335,7 @@ export default class Groups extends Extension {
logger.info(`Removing '${resolvedEntityDevice.name}' from '${resolvedEntityGroup.name}'`);
await resolvedEntityEndpoint.removeFromGroup(resolvedEntityGroup.zh);
settings.removeDeviceFromGroup(resolvedEntityGroup.ID.toString(), keys);
changedGroups.push(resolvedEntityGroup);
/* istanbul ignore else */
if (settings.get().advanced.legacy_api) {
@@ -339,6 +347,7 @@ export default class Groups extends Extension {
}
} else { // remove_all
logger.info(`Removing '${resolvedEntityDevice.name}' from all groups`);
changedGroups = this.zigbee.groups().filter((g) => g.zh.members.includes(resolvedEntityEndpoint));
await resolvedEntityEndpoint.removeFromAllGroups();
for (const settingsGroup of settings.getGroups()) {
settings.removeDeviceFromGroup(settingsGroup.ID.toString(), keys);
@@ -367,8 +376,10 @@ export default class Groups extends Extension {
if (error) {
logger.error(error);
} else {
this.eventBus.emitGroupMembersChanged({
group: resolvedEntityGroup, action: type, endpoint: resolvedEntityEndpoint, skipDisableReporting});
for (const group of changedGroups) {
this.eventBus.emitGroupMembersChanged({
group, action: type, endpoint: resolvedEntityEndpoint, skipDisableReporting});
}
}
}
}
+97 -100
View File
@@ -284,19 +284,11 @@ export default class HomeAssistant extends Extension {
const preset = firstExpose.features.find((f) => f.name === 'preset');
if (preset) {
discoveryEntry.discovery_payload.hold_modes = preset.values;
discoveryEntry.discovery_payload.hold_command_topic = true;
discoveryEntry.discovery_payload.hold_state_template =
discoveryEntry.discovery_payload.preset_modes = preset.values;
discoveryEntry.discovery_payload.preset_mode_command_topic = 'preset';
discoveryEntry.discovery_payload.preset_mode_value_template =
`{{ value_json.${preset.property} }}`;
discoveryEntry.discovery_payload.hold_state_topic = true;
}
const awayMode = firstExpose.features.find((f) => f.name === 'away_mode');
if (awayMode) {
discoveryEntry.discovery_payload.away_mode_command_topic = true;
discoveryEntry.discovery_payload.away_mode_state_topic = true;
discoveryEntry.discovery_payload.away_mode_state_template =
`{{ value_json.${awayMode.property} }}`;
discoveryEntry.discovery_payload.preset_mode_state_topic = true;
}
const tempCalibration = firstExpose.features.find((f) => f.name === 'local_temperature_calibration');
@@ -310,6 +302,7 @@ export default class HomeAssistant extends Extension {
command_topic: true,
command_topic_prefix: endpoint,
command_topic_postfix: tempCalibration.property,
device_class: 'temperature',
entity_category: 'config',
icon: 'mdi:math-compass',
...(tempCalibration.unit && {unit_of_measurement: tempCalibration.unit}),
@@ -382,6 +375,7 @@ export default class HomeAssistant extends Extension {
const tilt = exposes.find((expose) => expose.features.find((e) => e.name === 'tilt'));
const motorState = definitionExposes?.find((e) => e.type === 'enum' && e.name === 'motor_state' &&
e.access === ACCESS_STATE);
const running = definitionExposes?.find((e) => e.type === 'binary' && e.name === 'running');
const discoveryEntry: DiscoveryEntry = {
type: 'cover',
@@ -389,54 +383,38 @@ export default class HomeAssistant extends Extension {
object_id: endpoint ? `cover_${endpoint}` : 'cover',
discovery_payload: {
command_topic_prefix: endpoint,
command_topic: true,
state_topic: true,
},
};
// For covers only supporting tilt don't discover the command/state_topic, otherwise
// HA does not correctly reflect the state
// - https://github.com/home-assistant/core/issues/51793
// - https://github.com/Koenkk/zigbee-herdsman-converters/pull/2663
if (!tilt || (tilt && position)) {
discoveryEntry.discovery_payload.command_topic = true;
discoveryEntry.discovery_payload.state_topic = !position;
discoveryEntry.discovery_payload.command_topic_prefix = endpoint;
// For curtains that have `motor_state` lookup a possible state names and make this
// available for discovery. If the curtains only support the `running` value,
// then we use it anyway. The movement direction is calculated (assumed) in this case.
if (motorState) {
const openingLookup = ['opening', 'open', 'forward', 'up', 'rising'];
const closingLookup = ['closing', 'close', 'backward', 'back', 'reverse', 'down', 'declining'];
const stoppedLookup = ['stopped', 'stop', 'pause', 'paused'];
// For curtains that have `motor_state` lookup a possible state names and make this
// available for discovery. If the curtains only support the `running` value,
// then we use it anyway. The movement direction is calculated (assumed) in this case.
if (motorState) {
const openingLookup = ['opening', 'open', 'forward', 'up', 'rising'];
const closingLookup = ['closing', 'close', 'backward', 'back', 'reverse', 'down', 'declining'];
const stoppedLookup = ['stopped', 'stop', 'pause', 'paused'];
const openingState = motorState.values.find((s) => openingLookup.includes(s.toLowerCase()));
const closingState = motorState.values.find((s) => closingLookup.includes(s.toLowerCase()));
const stoppedState = motorState.values.find((s) => stoppedLookup.includes(s.toLowerCase()));
const openingState = motorState.values.find((s) => openingLookup.includes(s.toLowerCase()));
const closingState = motorState.values.find((s) => closingLookup.includes(s.toLowerCase()));
const stoppedState = motorState.values.find((s) => stoppedLookup.includes(s.toLowerCase()));
if (openingState) {
discoveryEntry.discovery_payload.state_opening = openingState;
}
if (closingState) {
discoveryEntry.discovery_payload.state_closing = closingState;
}
if (stoppedState) {
discoveryEntry.discovery_payload.state_stopped = stoppedState;
}
if (openingState || closingState || stoppedState) {
discoveryEntry.discovery_payload.state_topic = true;
discoveryEntry.discovery_payload.value_template = `{{ value_json.motor_state }}`;
}
} else {
const running = definitionExposes?.find((e) => e.type === 'binary' && e.name === 'running');
if (running) {
discoveryEntry.discovery_payload.state_topic = true;
discoveryEntry.discovery_payload.value_template = `{% if not value_json.running %} ` +
`stopped {% else %} {% if value_json.position > 0 %} closing {% else %} ` +
`opening {% endif %} {% endif %}`;
}
if (openingState && closingState && stoppedState) {
discoveryEntry.discovery_payload.state_opening = openingState;
discoveryEntry.discovery_payload.state_closing = closingState;
discoveryEntry.discovery_payload.state_stopped = stoppedState;
discoveryEntry.discovery_payload.value_template = `{% if not value_json.motor_state %} ` +
`${stoppedState} {% else %} {{ value_json.motor_state }} {% endif %}`;
}
} else if (running) {
discoveryEntry.discovery_payload.value_template = `{% if not value_json.running %} ` +
`stopped {% else %} {% if value_json.position > 0 %} closing {% else %} ` +
`opening {% endif %} {% endif %}`;
} else {
discoveryEntry.discovery_payload.value_template = `{{ value_json.state }}`;
discoveryEntry.discovery_payload.state_open = 'OPEN';
discoveryEntry.discovery_payload.state_closed = 'CLOSE';
}
if (!position && !tilt) {
@@ -520,7 +498,7 @@ export default class HomeAssistant extends Extension {
discoveryEntry.discovery_payload.speed_range_max = speeds.length - 1;
assert(presets.length !== 0);
discoveryEntry.discovery_payload.preset_mode_state_topic = true;
discoveryEntry.discovery_payload.preset_mode_command_topic = true;
discoveryEntry.discovery_payload.preset_mode_command_topic = 'fan_mode';
discoveryEntry.discovery_payload.preset_mode_value_template =
`{{ value_json.${speed.property} if value_json.${speed.property} in [${presetList}]` +
` else 'None' | default('None') }}`;
@@ -532,20 +510,23 @@ export default class HomeAssistant extends Extension {
const lookup: {[s: string]: KeyValue}= {
battery_low: {entity_category: 'diagnostic', device_class: 'battery'},
button_lock: {entity_category: 'config', icon: 'mdi:lock'},
calibration: {entity_category: 'config', icon: 'mdi:progress-wrench'},
carbon_monoxide: {device_class: 'safety'},
card: {entity_category: 'config', icon: 'mdi:clipboard-check'},
child_lock: {entity_category: 'config', icon: 'mdi:account-lock'},
color_sync: {entity_category: 'config', icon: 'mdi:sync-circle'},
consumer_connected: {entity_category: 'diagnostic', device_class: 'connectivity'},
contact: {device_class: 'door'},
garage_door_contact: {device_class: 'garage'},
garage_door_contact: {device_class: 'garage_door', payload_on: false, payload_off: true},
eco_mode: {entity_category: 'config', icon: 'mdi:leaf'},
expose_pin: {entity_category: 'config', icon: 'mdi:pin'},
flip_indicator_light: {entity_category: 'config', icon: 'mdi:arrow-left-right'},
gas: {device_class: 'gas'},
invert_cover: {entity_category: 'config', icon: 'mdi:arrow-left-right'},
led_disabled_night: {entity_category: 'config', icon: 'mdi:led-off'},
led_indication: {entity_category: 'config', icon: 'mdi:led-on'},
legacy: {entity_category: 'config', icon: 'mdi:cog'},
motor_reversal: {entity_category: 'config', icon: 'mdi:arrow-left-right'},
moving: {device_class: 'moving'},
no_position_support: {entity_category: 'config', icon: 'mdi:minus-circle-outline'},
occupancy: {device_class: 'motion'},
@@ -554,6 +535,7 @@ export default class HomeAssistant extends Extension {
smoke: {device_class: 'smoke'},
sos: {device_class: 'safety'},
tamper: {device_class: 'tamper'},
temperature_scale: {entity_category: 'config', icon: 'mdi:temperature-celsius'},
test: {entity_category: 'diagnostic', icon: 'mdi:test-tube'},
vibration: {device_class: 'vibration'},
water_leak: {device_class: 'moisture'},
@@ -614,9 +596,11 @@ export default class HomeAssistant extends Extension {
away_preset_days: {entity_category: 'config', icon: 'mdi:timer'},
away_preset_temperature: {entity_category: 'config', icon: 'mdi:thermometer'},
battery: {device_class: 'battery', entity_category: 'diagnostic', state_class: 'measurement'},
battery2: {device_class: 'battery', entity_category: 'diagnostic', state_class: 'measurement'},
battery_voltage: {device_class: 'voltage', entity_category: 'diagnostic', state_class: 'measurement'},
boost_time: {entity_category: 'config', icon: 'mdi:timer'},
calibration: {entity_category: 'config'},
calibration: {entity_category: 'config', icon: 'mdi:wrench-clock'},
calibration_time: {entity_category: 'config', icon: 'mdi:wrench-clock'},
co2: {device_class: 'carbon_dioxide', state_class: 'measurement'},
comfort_temperature: {entity_category: 'config', icon: 'mdi:thermometer'},
cpu_temperature: {
@@ -645,6 +629,7 @@ export default class HomeAssistant extends Extension {
device_temperature: {
device_class: 'temperature', entity_category: 'diagnostic', state_class: 'measurement',
},
duration: {entity_category: 'config', icon: 'mdi:timer'},
eco2: {device_class: 'carbon_dioxide', state_class: 'measurement'},
eco_temperature: {entity_category: 'config', icon: 'mdi:thermometer'},
energy: {device_class: 'energy', state_class: 'total_increasing'},
@@ -652,6 +637,10 @@ export default class HomeAssistant extends Extension {
gas_density: {icon: 'mdi:google-circles-communities', state_class: 'measurement'},
hcho: {icon: 'mdi:air-filter', state_class: 'measurement'},
humidity: {device_class: 'humidity', state_class: 'measurement'},
humidity_calibration: {entity_category: 'config', icon: 'mdi:wrench-clock'},
humidity_max: {entity_category: 'config', icon: 'mdi:water-percent'},
humidity_min: {entity_category: 'config', icon: 'mdi:water-percent'},
illuminance_calibration: {entity_category: 'config', icon: 'mdi:wrench-clock'},
illuminance_lux: {device_class: 'illuminance', state_class: 'measurement'},
illuminance: {device_class: 'illuminance', enabled_by_default: false, state_class: 'measurement'},
linkquality: {
@@ -676,6 +665,7 @@ export default class HomeAssistant extends Extension {
precision: {entity_category: 'config', icon: 'mdi:decimal-comma-increase'},
pressure: {device_class: 'pressure', state_class: 'measurement'},
presence_timeout: {entity_category: 'config', icon: 'mdi:timer'},
reporting_time: {entity_category: 'config', icon: 'mdi:clock-time-one-outline'},
requested_brightness_level: {
enabled_by_default: false, entity_category: 'diagnostic', icon: 'mdi:brightness-5',
},
@@ -685,6 +675,9 @@ export default class HomeAssistant extends Extension {
smoke_density: {icon: 'mdi:google-circles-communities', state_class: 'measurement'},
soil_moisture: {icon: 'mdi:water-percent', state_class: 'measurement'},
temperature: {device_class: 'temperature', state_class: 'measurement'},
temperature_calibration: {entity_category: 'config', icon: 'mdi:wrench-clock'},
temperature_max: {entity_category: 'config', icon: 'mdi:thermometer-plus'},
temperature_min: {entity_category: 'config', icon: 'mdi:thermometer-minus'},
transition: {entity_category: 'config', icon: 'mdi:transition'},
voc: {device_class: 'volatile_organic_compounds', state_class: 'measurement'},
vibration_timeout: {entity_category: 'config', icon: 'mdi:timer'},
@@ -754,6 +747,12 @@ export default class HomeAssistant extends Extension {
},
};
if (lookup[firstExpose.name]?.device_class === 'temperature') {
discoveryEntry.discovery_payload.device_class == lookup[firstExpose.name]?.device_class;
} else {
delete discoveryEntry.discovery_payload.device_class;
}
if (firstExpose.value_min != null) discoveryEntry.discovery_payload.min = firstExpose.value_min;
if (firstExpose.value_max != null) discoveryEntry.discovery_payload.max = firstExpose.value_max;
@@ -767,11 +766,15 @@ export default class HomeAssistant extends Extension {
backlight_auto_dim: {entity_category: 'config', icon: 'mdi:brightness-auto'},
backlight_mode: {entity_category: 'config', icon: 'mdi:lightbulb'},
color_power_on_behavior: {entity_category: 'config', icon: 'mdi:palette'},
control_mode: {entity_category: 'config', icon: 'mdi:tune'},
device_mode: {entity_category: 'config', icon: 'mdi:tune'},
effect: {enabled_by_default: false, icon: 'mdi:palette'},
force: {enabled_by_default: false, icon: 'mdi:valve'},
keep_time: {entity_category: 'config', icon: 'mdi:av-timer'},
keypad_lockout: {entity_category: 'config', icon: 'mdi:lock'},
load_detection_mode: {entity_category: 'config', icon: 'mdi:tune'},
load_dimmable: {entity_category: 'diagnostic', icon: 'mdi:chart-bell-curve'},
load_type: {entity_category: 'diagnostic', icon: 'mdi:led-on'},
melody: {entity_category: 'config', icon: 'mdi:music-note'},
mode_phase_control: {entity_category: 'config', icon: 'mdi:tune'},
mode: {entity_category: 'config', icon: 'mdi:tune'},
@@ -779,6 +782,8 @@ export default class HomeAssistant extends Extension {
operation_mode: {entity_category: 'config', icon: 'mdi:tune'},
power_on_behavior: {entity_category: 'config', icon: 'mdi:power-settings'},
power_outage_memory: {entity_category: 'config', icon: 'mdi:power-settings'},
power_supply_mode: {entity_category: 'diagnostic', icon: 'mdi:power-settings'},
power_type: {entity_category: 'diagnostic', icon: 'mdi:lightning-bolt-circle'},
sensitivity: {entity_category: 'config', icon: 'mdi:tune'},
sensors_type: {entity_category: 'config', icon: 'mdi:tune'},
sound_volume: {entity_category: 'config', icon: 'mdi:volume-high'},
@@ -789,39 +794,42 @@ export default class HomeAssistant extends Extension {
week: {entity_category: 'config', icon: 'mdi:calendar-clock'},
};
const valueTemplate = firstExpose.access & ACCESS_STATE ?
`{{ value_json.${firstExpose.property} }}` : undefined;
if (firstExpose.access & ACCESS_STATE) {
discoveryEntries.push({
type: 'sensor',
object_id: firstExpose.property,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
value_template: `{{ value_json.${firstExpose.property} }}`,
value_template: valueTemplate,
enabled_by_default: !(firstExpose.access & ACCESS_SET),
...lookup[firstExpose.name],
},
});
}
/**
* If enum attribute has SET access then expose as SELECT entity too.
* Note: currently both sensor and select are discovered, this is to avoid
* breaking changes for sensors already existing in HA (legacy).
*/
if ((firstExpose.access & ACCESS_SET)) {
discoveryEntries.push({
type: 'select',
object_id: firstExpose.property,
mockProperties: [{property: firstExpose.property, value: null}],
discovery_payload: {
value_template: `{{ value_json.${firstExpose.property} }}`,
state_topic: true,
command_topic_prefix: endpoint,
command_topic: true,
command_topic_postfix: firstExpose.property,
options: firstExpose.values.map((v) => v.toString()),
...lookup[firstExpose.name],
},
});
}
/**
* If enum attribute has SET access then expose as SELECT entity too.
* Note: currently both sensor and select are discovered, this is to avoid
* breaking changes for sensors already existing in HA (legacy).
*/
if ((firstExpose.access & ACCESS_SET)) {
discoveryEntries.push({
type: 'select',
object_id: firstExpose.property,
mockProperties: [], // Already mocked above in case access STATE is supported
discovery_payload: {
value_template: valueTemplate,
state_topic: !!(firstExpose.access & ACCESS_STATE),
command_topic_prefix: endpoint,
command_topic: true,
command_topic_postfix: firstExpose.property,
options: firstExpose.values.map((v) => v.toString()),
...lookup[firstExpose.name],
},
});
}
} else if (firstExpose.type === 'text' || firstExpose.type === 'composite') {
if (firstExpose.access & ACCESS_STATE) {
@@ -919,7 +927,7 @@ export default class HomeAssistant extends Extension {
}
}
@bind onEntityRenamed(data: eventdata.EntityRenamed): void {
@bind async onEntityRenamed(data: eventdata.EntityRenamed): Promise<void> {
logger.debug(`Refreshing Home Assistant discovery topic for '${data.entity.name}'`);
// Clear before rename so Home Assistant uses new friendly_name
@@ -929,6 +937,10 @@ export default class HomeAssistant extends Extension {
const topic = this.getDiscoveryTopic(config, data.entity);
this.mqtt.publish(topic, null, {retain: true, qos: 0}, this.discoveryTopic, false, false);
}
// Make sure Home Assistant deletes the old entity first otherwise another one (_2) is created
// https://github.com/Koenkk/zigbee2mqtt/issues/12610
await utils.sleep(2);
}
this.discover(data.entity, true);
@@ -1169,22 +1181,6 @@ export default class HomeAssistant extends Extension {
payload.mode_command_topic = `${baseTopic}/${commandTopicPrefix}set/system_mode`;
}
if (payload.hold_command_topic) {
payload.hold_command_topic = `${baseTopic}/${commandTopicPrefix}set/preset`;
}
if (payload.hold_state_topic) {
payload.hold_state_topic = stateTopic;
}
if (payload.away_mode_state_topic) {
payload.away_mode_state_topic = stateTopic;
}
if (payload.away_mode_command_topic) {
payload.away_mode_command_topic = `${baseTopic}/${commandTopicPrefix}set/away_mode`;
}
if (payload.current_temperature_topic) {
payload.current_temperature_topic = stateTopic;
}
@@ -1237,7 +1233,8 @@ export default class HomeAssistant extends Extension {
}
if (payload.preset_mode_command_topic) {
payload.preset_mode_command_topic = `${baseTopic}/${commandTopicPrefix}set/fan_mode`;
payload.preset_mode_command_topic = `${baseTopic}/${commandTopicPrefix}set/` +
payload.preset_mode_command_topic;
}
if (payload.action_topic) {
@@ -1339,9 +1336,9 @@ export default class HomeAssistant extends Extension {
data.message.toLowerCase() === 'online') {
const timer = setTimeout(async () => {
// Publish all device states.
for (const device of this.zigbee.devices(false)) {
if (this.state.exists(device)) {
this.publishEntityState(device, this.state.get(device));
for (const entity of [...this.zigbee.devices(false), ...this.zigbee.groups()]) {
if (this.state.exists(entity)) {
this.publishEntityState(entity, this.state.get(entity), 'publishCached');
}
}
+1
View File
@@ -244,6 +244,7 @@ export default class NetworkMap extends Extension {
} catch (error) {
failed.get(device).push('lqi');
logger.error(`Failed to execute LQI for '${device.name}'`);
logger.debug(error.stack);
}
if (includeRoutes) {
+3 -2
View File
@@ -40,10 +40,11 @@ export default class OnEvent extends Extension {
}
private async callOnEvent(device: Device, type: string, data: KeyValue): Promise<void> {
zhc.onEvent(type, data, device.zh);
const state = this.state.get(device);
zhc.onEvent(type, data, device.zh, device.options, state);
if (device.definition?.onEvent) {
await device.definition.onEvent(type, data, device.zh, device.options);
await device.definition.onEvent(type, data, device.zh, device.options, state);
}
}
}
+7 -6
View File
@@ -65,24 +65,25 @@ export default class OTAUpdate extends Extension {
}
private removeProgressAndRemainingFromState(device: Device): void {
delete this.state.get(device)?.update?.progress;
delete this.state.get(device)?.update?.remaining;
delete this.state.get(device).update?.progress;
delete this.state.get(device).update?.remaining;
}
@bind private async onZigbeeEvent(data: eventdata.DeviceMessage): Promise<void> {
if (settings.get().ota.disable_automatic_update_check) return;
if (data.type !== 'commandQueryNextImageRequest' || !data.device.definition) return;
if (data.type !== 'commandQueryNextImageRequest' || !data.device.definition ||
this.inProgress.has(data.device.ieeeAddr)) return;
logger.debug(`Device '${data.device.name}' requested OTA`);
const automaticOTACheckDisabled = settings.get().ota.disable_automatic_update_check;
let supportsOTA = data.device.definition.hasOwnProperty('ota');
if (supportsOTA) {
if (supportsOTA && !automaticOTACheckDisabled) {
// 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;
if (!check) return;
this.lastChecked[data.device.ieeeAddr] = Date.now();
let available = false;
+3 -2
View File
@@ -135,7 +135,7 @@ export default class Publish extends Extension {
}
const device = re instanceof Device ? re.zh : null;
const entitySettings = re.options;
const entityState = this.state.get(re) || {};
const entityState = this.state.get(re);
const membersState = re instanceof Group ?
Object.fromEntries(re.zh.members.map((e) => [e.getDevice().ieeeAddr,
this.state.get(this.zigbee.resolveEntity(e.getDevice().ieeeAddr))])) : null;
@@ -256,7 +256,8 @@ export default class Publish extends Extension {
}
// filter out attribute listed in filtered_optimistic
entitySettings.filtered_optimistic?.forEach((a) => delete msg[a]);
utils.filterProperties(entitySettings.filtered_optimistic, msg);
addToToPublish(re, msg);
}
+2 -2
View File
@@ -145,9 +145,9 @@ export default class Receive extends Extension {
if (converted) {
payload = {...payload, ...converted};
}
} catch (error) {
// istanbul ignore next
} catch (error) /* istanbul ignore next */ {
logger.error(`Exception while calling fromZigbee converter: ${error.message}}`);
logger.debug(error.stack);
}
}
+30 -1
View File
@@ -10,6 +10,10 @@ export default class MQTT {
private connectionTimer: NodeJS.Timeout;
private client: mqtt.MqttClient;
private eventBus: EventBus;
private initialConnect = true;
private republishRetainedTimer: NodeJS.Timer;
private retainedMessages: {[s: string]: {payload: string, options: MQTTOptions,
skipLog: boolean, skipReceive: boolean, topic: string, base: string}} = {};
constructor(eventBus: EventBus) {
this.eventBus = eventBus;
@@ -94,8 +98,19 @@ export default class MQTT {
}, utils.seconds(10));
logger.info('Connected to MQTT server');
this.subscribe(`${settings.get().mqtt.base_topic}/#`);
await this.publishStateOnline();
if (!this.initialConnect) {
this.republishRetainedTimer = setTimeout(() => {
// Republish retained messages in case MQTT broker does not persist them.
// https://github.com/Koenkk/zigbee2mqtt/issues/9629
Object.values(this.retainedMessages).forEach((e) =>
this.publish(e.topic, e.payload, e.options, e.base, e.skipLog, e.skipReceive));
}, 2000);
}
this.initialConnect = false;
this.subscribe(`${settings.get().mqtt.base_topic}/#`);
}
async publishStateOnline(): Promise<void> {
@@ -121,6 +136,11 @@ export default class MQTT {
logger.debug(`Received MQTT message on '${topic}' with data '${message}'`);
this.eventBus.emitMQTTMessage({topic, message: message + ''});
}
if (this.republishRetainedTimer && topic == `${settings.get().mqtt.base_topic}/bridge/state`) {
clearTimeout(this.republishRetainedTimer);
this.republishRetainedTimer = null;
}
}
isConnected(): boolean {
@@ -137,6 +157,15 @@ export default class MQTT {
this.publishedTopics.add(topic);
}
if (options.retain) {
if (payload) {
this.retainedMessages[topic] =
{payload, options, skipReceive, skipLog, topic: topic.substring(base.length + 1), base};
} else {
delete this.retainedMessages[topic];
}
}
this.eventBus.emitMQTTMessagePublished({topic, payload, options: {...defaultOptions, ...options}});
if (!this.isConnected()) {
+10 -12
View File
@@ -1,15 +1,16 @@
import logger from './util/logger';
import data from './util/data';
import * as settings from './util/settings';
import utils from './util/utils';
import fs from 'fs';
import objectAssignDeep from 'object-assign-deep';
const saveInterval = 1000 * 60 * 5; // 5 minutes
const dontCacheProperties = [
'^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$',
'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 {
@@ -68,23 +69,20 @@ class State {
}
get(entity: Group | Device): KeyValue {
return this.state[entity.ID];
return this.state[entity.ID] || {};
}
set(entity: Group | Device, update: KeyValue, reason: string=null): KeyValue {
const fromState = this.state[entity.ID] || {};
const toState = objectAssignDeep({}, fromState, update);
const result = {...toState};
const newCache = {...toState};
const entityDontCacheProperties = entity.options.filtered_cache || [];
for (const property of Object.keys(toState)) {
if (dontCacheProperties.find((p) => property.match(p))) {
delete toState[property];
}
}
utils.filterProperties(dontCacheProperties.concat(entityDontCacheProperties), newCache);
this.state[entity.ID] = toState;
this.state[entity.ID] = newCache;
this.eventBus.emitStateChange({entity, from: fromState, to: toState, reason, update});
return result;
return toState;
}
remove(ID: string | number): void {
+8 -4
View File
@@ -42,7 +42,7 @@ declare global {
// Types
interface MQTTResponse {data: KeyValue, status: 'error' | 'ok', error?: string, transaction?: string}
interface MQTTOptions {qos?: mqtt.QoS, retain?: boolean, properties?: {messageExpiryInterval: number}}
type StateChangeReason = 'publishDebounce' | 'groupOptimistic' | 'lastSeenChanged';
type StateChangeReason = 'publishDebounce' | 'groupOptimistic' | 'lastSeenChanged' | 'publishCached';
type PublishEntityState = (entity: Device | Group, payload: KeyValue,
stateChangeReason?: StateChangeReason) => Promise<void>;
type RecursivePartial<T> = {[P in keyof T]?: RecursivePartial<T[P]>;};
@@ -117,7 +117,8 @@ declare global {
exposes: DefinitionExpose[] | ((device: zh.Device, options: KeyValue) => DefinitionExpose[])
configure?: (device: zh.Device, coordinatorEndpoint: zh.Endpoint, logger: Logger,
options?: DeviceOptions) => Promise<void>;
onEvent?: (type: string, data: KeyValue, device: zh.Device, settings: KeyValue) => Promise<void>;
onEvent?: (type: string, data: KeyValue, device: zh.Device,
settings: KeyValue, state: KeyValue) => Promise<void>;
ota?: {
isUpdateAvailable: (device: zh.Device, logger: Logger, data?: KeyValue) => Promise<boolean>;
updateToLatest: (device: zh.Device, logger: Logger,
@@ -279,11 +280,12 @@ declare global {
retrieve_state?: boolean,
debounce?: number,
debounce_ignore?: string[],
filtered_attributes?: string[],
filtered_cache?: string[],
filtered_optimistic?: string[],
icon?: string,
homeassistant?: KeyValue,
legacy?: boolean,
filtered_attributes?: string[],
friendly_name: string,
description?: string,
qos?: 0 | 1 | 2,
@@ -293,10 +295,12 @@ declare global {
devices?: string[],
ID?: number,
optimistic?: boolean,
off_state?: 'all_members_off' | 'last_member_state'
filtered_attributes?: string[],
filtered_cache?: string[],
filtered_optimistic?: string[],
retrieve_state?: boolean,
homeassistant?: KeyValue,
filtered_attributes?: string[],
friendly_name: string,
description?: string,
qos?: 0 | 1 | 2,
+2 -1
View File
@@ -4,7 +4,8 @@ declare module 'zigbee-herdsman-converters' {
export const toZigbeeConverters: {[s: string]: zhc.ToZigbeeConverter};
export const definitions: zhc.Definition[];
export function addDeviceDefinition(definition: zhc.Definition): Promise<void>;
export function onEvent(type: string, data: KeyValue, device: zh.Device): Promise<void>;
export function onEvent(type: string, data: KeyValue, device: zh.Device, settings: KeyValue,
state: KeyValue): Promise<void>;
}
declare module 'zigbee-herdsman-converters/lib/ota/tradfri' {
+98 -88
View File
@@ -9,40 +9,12 @@ import assert from 'assert';
const colorizer = winston.format.colorize();
// What transports to enable
const output = settings.get().advanced.log_output;
// 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 when not logging to stdout only
if (output.includes('file')) {
fx.mkdirSync(directory);
if (settings.get().advanced.log_symlink_current) {
const current = settings.get().advanced.log_directory.replace('%TIMESTAMP%', 'current');
const actual = './' + timestamp;
if (fs.existsSync(current)) {
fs.unlinkSync(current);
}
fs.symlinkSync(actual, current);
}
}
type Z2MLogLevel = 'warn' | 'debug' | 'info' | 'error';
type WinstonLogLevel = 'warning' | 'debug' | 'info' | 'error';
const z2mToWinstonLevel = (level: Z2MLogLevel): WinstonLogLevel => level === 'warn' ? 'warning' : level;
const winstonToZ2mLevel = (level: WinstonLogLevel): Z2MLogLevel => level === 'warning' ? 'warn' : level;
// Determine the log level.
const z2mLevel = settings.get().advanced.log_level;
const validLevels = ['info', 'error', 'warn', 'debug'];
assert(validLevels.includes(z2mLevel), `'${z2mLevel}' is not valid log_level, use one of '${validLevels.join(', ')}'`);
const level = z2mToWinstonLevel(z2mLevel);
const levelWithCompensatedLength: {[s: string]: string} = {
'info': 'info ',
'error': 'error',
@@ -50,76 +22,113 @@ const levelWithCompensatedLength: {[s: string]: string} = {
'debug': 'debug',
};
const timestampFormat = (): string => moment().format(settings.get().advanced.timestamp_format);
let logger: winston.Logger;
let fileTransport : winston.transport;
let output: string[];
let directory: string;
let logFilename: string;
let transportsToUse: winston.transport[];
// Setup default console logger
const transportsToUse: winston.transport[] = [
new winston.transports.Console({
function init(): void {
// What transports to enable
output = settings.get().advanced.log_output;
// Directory to log to
const timestamp = moment(Date.now()).format('YYYY-MM-DD.HH-mm-ss');
directory = settings.get().advanced.log_directory.replace('%TIMESTAMP%', timestamp);
logFilename = settings.get().advanced.log_file.replace('%TIMESTAMP%', timestamp);
// Make sure that log directoy exsists when not logging to stdout only
if (output.includes('file')) {
fx.mkdirSync(directory);
if (settings.get().advanced.log_symlink_current) {
const current = settings.get().advanced.log_directory.replace('%TIMESTAMP%', 'current');
const actual = './' + timestamp;
/* istanbul ignore next */
if (fs.existsSync(current)) {
fs.unlinkSync(current);
}
fs.symlinkSync(actual, current);
}
}
// Determine the log level.
const z2mLevel = settings.get().advanced.log_level;
const validLevels = ['info', 'error', 'warn', 'debug'];
assert(validLevels.includes(z2mLevel),
`'${z2mLevel}' is not valid log_level, use one of '${validLevels.join(', ')}'`);
const level = z2mToWinstonLevel(z2mLevel);
const timestampFormat = (): string => moment().format(settings.get().advanced.timestamp_format);
// Setup default console logger
transportsToUse = [
new winston.transports.Console({
level,
silent: !output.includes('console'),
format: winston.format.combine(
winston.format.timestamp({format: timestampFormat}),
winston.format.printf(/* istanbul ignore next */(info) => {
const {timestamp, level, message} = info;
const l = winstonToZ2mLevel(level as WinstonLogLevel);
const plainPrefix = `Zigbee2MQTT:${levelWithCompensatedLength[l]}`;
let prefix = plainPrefix;
if (process.stdout.isTTY) {
prefix = colorizer.colorize(l, plainPrefix);
}
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: KeyValue = {
filename: path.join(directory, logFilename),
json: false,
level,
silent: !output.includes('console'),
format: winston.format.combine(
winston.format.timestamp({format: timestampFormat}),
winston.format.printf(/* istanbul ignore next */(info) => {
const {timestamp, level, message} = info;
const l = winstonToZ2mLevel(level as WinstonLogLevel);
const plainPrefix = `Zigbee2MQTT:${levelWithCompensatedLength[l]}`;
let prefix = plainPrefix;
if (process.stdout.isTTY) {
prefix = colorizer.colorize(l, plainPrefix);
}
return `${prefix} ${timestamp.split('.')[0]}: ${message}`;
return `${levelWithCompensatedLength[l]} ${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: KeyValue = {
filename: path.join(directory, logFilename),
json: false,
level,
format: winston.format.combine(
winston.format.timestamp({format: timestampFormat}),
winston.format.printf(/* istanbul ignore next */(info) => {
const {timestamp, level, message} = info;
const l = winstonToZ2mLevel(level as WinstonLogLevel);
return `${levelWithCompensatedLength[l]} ${timestamp.split('.')[0]}: ${message}`;
}),
),
};
if (settings.get().advanced.log_rotation) {
transportFileOptions.tailable = true;
transportFileOptions.maxFiles = 3; // Keep last 3 files
transportFileOptions.maxsize = 10000000; // 10MB
}
let fileTransport : winston.transport;
if (output.includes('file')) {
fileTransport = new winston.transports.File(transportFileOptions);
transportsToUse.push(fileTransport);
}
/* istanbul ignore next */
if (output.includes('syslog')) {
// eslint-disable-next-line
require('winston-syslog').Syslog;
const options: KeyValue = {
app_name: 'Zigbee2MQTT',
format: winston.format.printf(/* istanbul ignore next */(info) => {
return `${info.message}`;
}),
...settings.get().advanced.log_syslog,
};
if (options.hasOwnProperty('type')) options.type = options.type.toString();
// @ts-ignore
transportsToUse.push(new winston.transports.Syslog(options));
}
// Create logger
const logger = winston.createLogger({transports: transportsToUse, levels: winston.config.syslog.levels});
if (settings.get().advanced.log_rotation) {
transportFileOptions.tailable = true;
transportFileOptions.maxFiles = 3; // Keep last 3 files
transportFileOptions.maxsize = 10000000; // 10MB
}
if (output.includes('file')) {
fileTransport = new winston.transports.File(transportFileOptions);
transportsToUse.push(fileTransport);
}
/* istanbul ignore next */
if (output.includes('syslog')) {
// eslint-disable-next-line
require('winston-syslog').Syslog;
const options: KeyValue = {
app_name: 'Zigbee2MQTT',
format: winston.format.printf(/* istanbul ignore next */(info) => {
return `${info.message}`;
}),
...settings.get().advanced.log_syslog,
};
if (options.hasOwnProperty('type')) options.type = options.type.toString();
// @ts-ignore
transportsToUse.push(new winston.transports.Syslog(options));
}
logger = winston.createLogger({transports: transportsToUse, levels: winston.config.syslog.levels});
}
// Cleanup any old log directory.
function cleanup(): void {
@@ -211,5 +220,6 @@ async function end(): Promise<void> {
}
export default {
logOutput, warn, warning, error, info, debug, setLevel, getLevel, cleanup, addTransport, end, winston: logger,
init, logOutput, warn, warning, error, info, debug, setLevel, getLevel, cleanup, addTransport, end,
winston: (): winston.Logger => logger,
};
+39 -11
View File
@@ -812,28 +812,48 @@
"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"],
"examples": ["^temperature$", "^battery$", "^action$"],
"title": "Filtered publish attributes",
"description": "Filter attributes from publish payload."
"description": "Filter attributes with regex from published payload."
},
"filtered_cache": {
"type": "array",
"items": {
"type": "string"
},
"examples": ["^input_actions$"],
"title": "Filtered attributes from cache",
"description": "Filter attributes with regex from being added to the cache, this prevents the attribute from being in the published payload when the value didn't change."
},
"filtered_optimistic": {
"type": "array",
"items": {
"type": "string"
},
"examples": ["^color_(mode|temp)$", "color"],
"title": "Filtered optimistic attributes",
"description": "Filter attributes with regex from optimistic publish payload when calling /set. (This has no effect if optimistic is set to false)."
},
"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"
},
"homeassistant": {
"type": ["object", "null"],
"title": "Home Assistant",
"properties": {
"name": {
"type": "string",
"title": "Home Assistant name",
"description": "Name of the device in Home Assistant"
}
}
}
},
"required": ["friendly_name"]
@@ -859,6 +879,14 @@
"qos": {
"type": "number"
},
"off_state": {
"type": ["string"],
"enum": ["all_members_off", "last_member_state"],
"title": "Group off state",
"default": "auto",
"requiresRestart": true,
"description": "Control when to publish state OFF for a group. 'all_members_off': only publish state OFF when all group memebers are in state OFF, 'last_member_state': publish state OFF whenever one of its members changes to OFF"
},
"filtered_attributes": {
"type": "array",
"items": {
+15 -3
View File
@@ -196,6 +196,7 @@ function write(): void {
// In case the setting is defined in a separte file (e.g. !secret network_key) update it there.
for (const path of [
['mqtt', 'server'],
['mqtt', 'user'],
['mqtt', 'password'],
['advanced', 'network_key'],
@@ -323,11 +324,18 @@ function read(): Settings {
}
};
if (s.mqtt?.user && s.mqtt?.password) {
if (s.mqtt?.user) {
s.mqtt.user = interpetValue(s.mqtt.user);
}
if (s.mqtt?.password) {
s.mqtt.password = interpetValue(s.mqtt.password);
}
if (s.mqtt?.server) {
s.mqtt.server = interpetValue(s.mqtt.server);
}
if (s.advanced?.network_key) {
s.advanced.network_key = interpetValue(s.advanced.network_key);
}
@@ -373,7 +381,11 @@ function applyEnvironmentVariables(settings: Partial<Settings>): void {
}, settings);
if (type.indexOf('object') >= 0 || type.indexOf('array') >= 0) {
setting[key] = JSON.parse(process.env[envVariableName]);
try {
setting[key] = JSON.parse(process.env[envVariableName]);
} catch (error) {
setting[key] = process.env[envVariableName];
}
} else if (type.indexOf('number') >= 0) {
/* eslint-disable-line */ // @ts-ignore
setting[key] = process.env[envVariableName] * 1;
@@ -390,7 +402,7 @@ function applyEnvironmentVariables(settings: Partial<Settings>): void {
if (typeof obj[key] === 'object' && obj[key]) {
const newPath = [...path];
if (key !== 'properties') {
if (key !== 'properties' && key !== 'oneOf' && !Number.isInteger(Number(key))) {
newPath.push(key);
}
iterate(obj[key], newPath);
+48 -1
View File
@@ -210,6 +210,43 @@ function toSnakeCase(value: string | KeyValue): any {
}
}
function charRange(start: string, stop: string): number[] {
const result = [];
for (let idx=start.charCodeAt(0), end=stop.charCodeAt(0); idx <=end; ++idx) {
result.push(idx);
}
return result;
}
const controlCharacters = [
...charRange('\u0000', '\u001F'),
...charRange('\u007f', '\u009F'),
...charRange('\ufdd0', '\ufdef'),
];
function containsControlCharacter(str: string): boolean {
for (let i = 0; i < str.length; i++) {
const ch = str.charCodeAt(i);
if (controlCharacters.includes(ch) || [0xFFFE, 0xFFFF].includes(ch & 0xFFFF)) {
return true;
}
}
return false;
}
function getAllFiles(path_: string): string[] {
const result = [];
for (let item of fs.readdirSync(path_)) {
item = path.join(path_, item);
if (fs.lstatSync(item).isFile()) {
result.push(item);
} else {
result.push(...getAllFiles(item));
}
}
return result;
}
function validateFriendlyName(name: string, throwFirstError=false): string[] {
const errors = [];
for (const endpointName of endpointNames) {
@@ -220,7 +257,7 @@ function validateFriendlyName(name: string, throwFirstError=false): string[] {
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 (containsControlCharacter(name)) errors.push(`friendly_name is not allowed to contain control char`);
if (endpointNames.includes(name)) errors.push(`Following friendly_name are not allowed: '${endpointNames}'`);
if (name.match(/.*\/\d*$/)) errors.push(`Friendly name cannot end with a "/DIGIT" ('${name}')`);
if (name.includes('#') || name.includes('+')) {
@@ -304,6 +341,15 @@ function publishLastSeen(data: eventdata.LastSeenChanged, settings: Settings, al
}
}
function filterProperties(filter: string[], data: KeyValue): void {
if (filter) {
for (const property of Object.keys(data)) {
if (filter.find((p) => property.match(`^${p}$`))) {
delete data[property];
}
}
}
}
export default {
endpointNames, capitalize, getZigbee2MQTTVersion, getDependencyVersion, formatDate, objectHasProperties,
@@ -311,4 +357,5 @@ export default {
getExternalConvertersDefinitions, removeNullPropertiesFromObject, toNetworkAddressHex, toSnakeCase,
parseEntityID, isEndpoint, isZHGroup, hours, minutes, seconds, validateFriendlyName, sleep,
sanitizeImageParameter, isAvailabilityEnabledForEntity, publishLastSeen, availabilityPayload,
getAllFiles, filterProperties,
};
+4
View File
@@ -183,6 +183,10 @@ export default class Zigbee {
return this.herdsman.isStopping();
}
async backup(): Promise<void> {
return this.herdsman.backup();
}
async getNetworkParameters(): Promise<zh.NetworkParameters> {
return this.herdsman.getNetworkParameters();
}
-22883
View File
File diff suppressed because it is too large Load Diff
+17320
View File
File diff suppressed because it is too large Load Diff
+26 -25
View File
@@ -1,6 +1,6 @@
{
"name": "zigbee2mqtt",
"version": "1.25.0",
"version": "1.27.1",
"description": "Zigbee to MQTT bridge using Zigbee-herdsman",
"main": "index.js",
"repository": {
@@ -8,7 +8,7 @@
"url": "git+https://github.com/Koenkk/zigbee2mqtt.git"
},
"engines": {
"node": "^10 || ^12 || ^14 || ^15 || ^16"
"node": "^14 || ^16 || ^18"
},
"keywords": [
"xiaomi",
@@ -37,54 +37,55 @@
"dependencies": {
"ajv": "^8.11.0",
"bind-decorator": "^1.0.11",
"connect-gzip-static": "^2.1.1",
"core-js": "^3.21.1",
"connect-gzip-static": "2.1.1",
"core-js": "^3.24.1",
"debounce": "^1.2.1",
"deep-object-diff": "^1.1.7",
"fast-deep-equal": "^3.1.3",
"finalhandler": "^1.2.0",
"git-last-commit": "^1.0.1",
"humanize-duration": "^3.27.1",
"humanize-duration": "^3.27.2",
"js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
"jszip": "^3.10.1",
"mkdir-recursive": "^0.4.0",
"moment": "^2.29.1",
"moment": "^2.29.4",
"mqtt": "4.3.7",
"object-assign-deep": "^0.4.0",
"rimraf": "^3.0.2",
"semver": "^7.3.5",
"semver": "^7.3.7",
"source-map-support": "^0.5.21",
"uri-js": "^4.4.1",
"winston": "^3.6.0",
"winston-syslog": "^2.5.0",
"winston": "^3.8.1",
"winston-syslog": "^2.6.0",
"winston-transport": "^4.5.0",
"ws": "^8.5.0",
"zigbee-herdsman": "0.14.20",
"zigbee-herdsman-converters": "14.0.467",
"zigbee2mqtt-frontend": "0.6.80"
"ws": "^8.8.1",
"zigbee-herdsman": "0.14.51",
"zigbee-herdsman-converters": "14.0.610",
"zigbee2mqtt-frontend": "0.6.110"
},
"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/plugin-proposal-decorators": "^7.17.8",
"@babel/preset-env": "^7.16.11",
"@babel/preset-typescript": "^7.16.7",
"@babel/core": "^7.18.10",
"@babel/plugin-proposal-decorators": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"@babel/preset-typescript": "^7.18.6",
"@types/debounce": "^1.2.1",
"@types/finalhandler": "^1.1.1",
"@types/humanize-duration": "^3.27.1",
"@types/jest": "^27.4.1",
"@types/jest": "^28.1.7",
"@types/js-yaml": "^4.0.5",
"@types/object-assign-deep": "^0.4.0",
"@types/rimraf": "^3.0.2",
"@types/ws": "^8.5.3",
"@typescript-eslint/eslint-plugin": "^5.16.0",
"@typescript-eslint/parser": "^5.16.0",
"babel-jest": "^27.5.1",
"eslint": "^8.12.0",
"@typescript-eslint/eslint-plugin": "^5.33.1",
"@typescript-eslint/parser": "^5.33.1",
"babel-jest": "^28.1.3",
"eslint": "^8.22.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-jest": "^26.1.3",
"jest": "^27.5.1",
"eslint-plugin-jest": "^26.8.5",
"jest": "^28.1.3",
"tmp": "^0.2.1",
"typescript": "^4.6.3"
"typescript": "^4.7.4"
},
"jest": {
"coverageThreshold": {
+2 -1
View File
@@ -588,6 +588,7 @@ describe('Bind', () => {
it('Should poll bounded Hue bulb when receiving message from scene controller', async () => {
const remote = zigbeeHerdsman.devices.bj_scene_switch;
const data = {"action": "recall_2_row_1"};
zigbeeHerdsman.devices.bulb_color_2.getEndpoint(1).read.mockImplementationOnce(() => {throw new Error('failed')});
const payload = {data, cluster: 'genScenes', device: remote, endpoint: remote.getEndpoint(10), type: 'commandRecall', linkquality: 10, groupID: 0};
await zigbeeHerdsman.events.message(payload);
await flushPromises();
@@ -595,7 +596,7 @@ describe('Bind', () => {
expect(debounce).toHaveBeenCalledTimes(3);
expect(zigbeeHerdsman.devices.bulb_color_2.getEndpoint(1).read).toHaveBeenCalledWith("genOnOff", ["onOff"]);
expect(zigbeeHerdsman.devices.bulb_color_2.getEndpoint(1).read).toHaveBeenCalledWith("genLevelCtrl", ["currentLevel"]);
expect(zigbeeHerdsman.devices.bulb_color_2.getEndpoint(1).read).toHaveBeenCalledWith("lightingColorCtrl", ["currentX", "currentY", "colorTemperature"]);
expect(zigbeeHerdsman.devices.bulb_color_2.getEndpoint(1).read).toHaveBeenCalledWith("lightingColorCtrl", ["currentX", "currentY", "colorTemperature"]);
});
it('Should poll grouped Hue bulb when receiving message from TRADFRI remote', async () => {
+40 -1
View File
File diff suppressed because one or more lines are too long
+69 -7
View File
@@ -120,6 +120,7 @@ describe('Controller', () => {
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", stringify({"state":"ON","brightness":50,"color_temp":370,"linkquality":99}), {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/remote", stringify({"brightness":255}), {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/group_1", stringify({"state":'ON'}), {"qos": 0, "retain":false}, expect.any(Function));
});
it('Start controller should not publish cached states when disabled', async () => {
@@ -203,7 +204,7 @@ describe('Controller', () => {
await flushPromises();
expect(logger.error).toHaveBeenCalledWith('MQTT failed to connect: addr not found');
expect(mockExit).toHaveBeenCalledTimes(1);
expect(mockExit).toHaveBeenCalledWith(1);
expect(mockExit).toHaveBeenCalledWith(1, false);
});
it('Start controller with permit join true', async () => {
@@ -220,13 +221,13 @@ describe('Controller', () => {
expect(zigbeeHerdsman.setTransmitPower).toHaveBeenCalledWith(14);
});
it('Start controller and stop', async () => {
it('Start controller and stop with restart', async () => {
await controller.start();
await controller.stop();
await controller.stop(true);
expect(MQTT.end).toHaveBeenCalledTimes(1);
expect(zigbeeHerdsman.stop).toHaveBeenCalledTimes(1);
expect(mockExit).toHaveBeenCalledTimes(1);
expect(mockExit).toHaveBeenCalledWith(0);
expect(mockExit).toHaveBeenCalledWith(0, true);
});
it('Start controller and stop', async () => {
@@ -236,7 +237,7 @@ describe('Controller', () => {
expect(MQTT.end).toHaveBeenCalledTimes(1);
expect(zigbeeHerdsman.stop).toHaveBeenCalledTimes(1);
expect(mockExit).toHaveBeenCalledTimes(1);
expect(mockExit).toHaveBeenCalledWith(1);
expect(mockExit).toHaveBeenCalledWith(1, false);
});
it('Start controller adapter disconnects', async () => {
@@ -247,7 +248,7 @@ describe('Controller', () => {
expect(MQTT.end).toHaveBeenCalledTimes(1);
expect(zigbeeHerdsman.stop).toHaveBeenCalledTimes(1);
expect(mockExit).toHaveBeenCalledTimes(1);
expect(mockExit).toHaveBeenCalledWith(1);
expect(mockExit).toHaveBeenCalledWith(1, false);
});
it('Handle mqtt message', async () => {
@@ -489,6 +490,46 @@ describe('Controller', () => {
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", stringify({"state":"ON","brightness":200}), {"qos": 0, "retain": true}, expect.any(Function));
});
it('Publish entity state attribute_json output filtered cache', async () => {
await controller.start();
settings.set(['advanced', 'output'], 'attribute_and_json');
settings.set(['devices', zigbeeHerdsman.devices.bulb.ieeeAddr, 'filtered_cache'], ['linkquality']);
MQTT.publish.mockClear();
const device = controller.zigbee.resolveEntity('bulb');
expect(controller.state.state[device.ieeeAddr]).toStrictEqual({"brightness":50,"color_temp":370,"linkquality":99,"state":"ON"});
await controller.publishEntityState(device, {state: 'ON', brightness: 200, color_temp: 370, linkquality: 87});
await flushPromises();
expect(controller.state.state[device.ieeeAddr]).toStrictEqual({"brightness":200,"color_temp":370,"state":"ON"});
expect(MQTT.publish).toHaveBeenCalledTimes(5);
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb/state", "ON", {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb/brightness", "200", {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb/linkquality", "87", {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", stringify({"state":"ON","brightness":200,"color_temp":370,"linkquality":87}), {"qos": 0, "retain": true}, expect.any(Function));
});
it('Publish entity state attribute_json output filtered cache (device_options)', async () => {
await controller.start();
settings.set(['advanced', 'output'], 'attribute_and_json');
settings.set(['device_options', 'filtered_cache'], ['linkquality']);
MQTT.publish.mockClear();
const device = controller.zigbee.resolveEntity('bulb');
expect(controller.state.state[device.ieeeAddr]).toStrictEqual({"brightness":50,"color_temp":370,"linkquality":99,"state":"ON"});
await controller.publishEntityState(device, {state: 'ON', brightness: 200, color_temp: 370, linkquality: 87});
await flushPromises();
expect(controller.state.state[device.ieeeAddr]).toStrictEqual({"brightness":200,"color_temp":370,"state":"ON"});
expect(MQTT.publish).toHaveBeenCalledTimes(5);
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb/state", "ON", {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb/brightness", "200", {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb/linkquality", "87", {"qos": 0, "retain": true}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb", stringify({"state":"ON","brightness":200,"color_temp":370,"linkquality":87}), {"qos": 0, "retain": true}, expect.any(Function));
});
it('Publish entity state with device information', async () => {
await controller.start();
settings.set(['mqtt', 'include_device_information'], true);
@@ -569,7 +610,7 @@ describe('Controller', () => {
logger.error.mockClear();
controller.state.file = "/";
await controller.state.save();
expect(logger.error).toHaveBeenCalledWith(`Failed to write state to '/' (EISDIR: illegal operation on a directory, open '/')`);
expect(logger.error).toHaveBeenCalledWith(expect.stringMatching(/Failed to write state to \'\/\'/));
});
it('Publish should not cache when set', async () => {
@@ -604,6 +645,27 @@ describe('Controller', () => {
expect(MQTT.connect).toHaveBeenCalledWith("mqtt://localhost", expected);
});
it('Should republish retained messages on MQTT reconnect', async () => {
await controller.start();
MQTT.publish.mockClear();
MQTT.events['connect']();
await flushPromises();
jest.runOnlyPendingTimers();
expect(MQTT.publish).toHaveBeenCalledTimes(13);
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/bridge/info', expect.any(String), { retain: true, qos: 0 }, expect.any(Function));
});
it('Should not republish retained messages on MQTT reconnect when retained message are sent', async () => {
await controller.start();
MQTT.publish.mockClear();
MQTT.events['connect']();
await flushPromises();
await MQTT.events.message('zigbee2mqtt/bridge/state', 'online');
jest.runOnlyPendingTimers();
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/bridge/state', expect.any(String), { retain: true, qos: 0 }, expect.any(Function));
});
it('Should prevent any message being published with retain flag when force_disable_retain is set', async () => {
settings.set(['mqtt', 'force_disable_retain'], true);
await controller.mqtt.connect()
+24
View File
@@ -469,6 +469,30 @@ describe('Groups', () => {
expect(MQTT.publish).toHaveBeenCalledWith("zigbee2mqtt/bulb_color", stringify({state:"OFF"}), {"retain": false, qos: 0}, expect.any(Function));
});
it('Should publish state change off if any lights within are still on when changed via device when off_state: last_member_state is used', async () => {
const device_1 = zigbeeHerdsman.devices.bulb_color;
const device_2 = zigbeeHerdsman.devices.bulb;
const endpoint_1 = device_1.getEndpoint(1);
const endpoint_2 = device_2.getEndpoint(1);
const group = zigbeeHerdsman.groups.group_1;
group.members.push(endpoint_1);
group.members.push(endpoint_2);
settings.set(['groups'], {
'1': {friendly_name: 'group_1', devices: [device_1.ieeeAddr, device_2.ieeeAddr], retain: false, off_state: 'last_member_state'}
});
await resetExtension();
await MQTT.events.message('zigbee2mqtt/group_1/set', stringify({state: 'ON'}));
await flushPromises();
MQTT.publish.mockClear();
await MQTT.events.message('zigbee2mqtt/bulb_color/set', stringify({state: 'OFF'}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(2);
expect(MQTT.publish).toHaveBeenNthCalledWith(1, "zigbee2mqtt/group_1", stringify({state:"OFF"}), {"retain": false, qos: 0}, expect.any(Function));
expect(MQTT.publish).toHaveBeenNthCalledWith(2, "zigbee2mqtt/bulb_color", stringify({state:"OFF"}), {"retain": false, qos: 0}, expect.any(Function));
});
it('Should not publish state change off if any lights within are still on when changed via shared group', async () => {
const device_1 = zigbeeHerdsman.devices.bulb_color;
const device_2 = zigbeeHerdsman.devices.bulb;
+27 -16
View File
@@ -752,9 +752,6 @@ describe('HomeAssistant extension', () => {
"topic":"zigbee2mqtt/bridge/state"
}
],
"away_mode_command_topic":"zigbee2mqtt/TS0601_thermostat/set/away_mode",
"away_mode_state_template":"{{ value_json.away_mode }}",
"away_mode_state_topic":"zigbee2mqtt/TS0601_thermostat",
"current_temperature_template":"{{ value_json.local_temperature }}",
"current_temperature_topic":"zigbee2mqtt/TS0601_thermostat",
"device":{
@@ -766,8 +763,8 @@ describe('HomeAssistant extension', () => {
"name":"TS0601_thermostat",
"sw_version":null
},
"hold_command_topic":"zigbee2mqtt/TS0601_thermostat/set/preset",
"hold_modes":[
"preset_mode_command_topic":"zigbee2mqtt/TS0601_thermostat/set/preset",
"preset_modes":[
"schedule",
"manual",
"boost",
@@ -775,8 +772,8 @@ describe('HomeAssistant extension', () => {
"comfort",
"eco"
],
"hold_state_template":"{{ value_json.preset }}",
"hold_state_topic":"zigbee2mqtt/TS0601_thermostat",
"preset_mode_value_template":"{{ value_json.preset }}",
"preset_mode_state_topic":"zigbee2mqtt/TS0601_thermostat",
"json_attributes_topic":"zigbee2mqtt/TS0601_thermostat",
"max_temp":"35",
"min_temp":"5",
@@ -814,6 +811,10 @@ describe('HomeAssistant extension', () => {
set_position_topic: 'zigbee2mqtt/smart vent/set',
set_position_template: '{ "position": {{ position }} }',
position_template: '{{ value_json.position }}',
state_topic: 'zigbee2mqtt/smart vent',
value_template: `{{ value_json.state }}`,
state_open: 'OPEN',
state_closed: 'CLOSE',
json_attributes_topic: 'zigbee2mqtt/smart vent',
name: 'smart vent',
unique_id: '0x0017880104e45551_cover_zigbee2mqtt',
@@ -1042,6 +1043,12 @@ describe('HomeAssistant extension', () => {
{ retain: true, qos: 0 },
expect.any(Function)
);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/group_1',
stringify({"state":'ON'}),
{ retain: false, qos: 0 },
expect.any(Function)
);
});
it('Should send all status when home assistant comes online', async () => {
@@ -1178,6 +1185,8 @@ describe('HomeAssistant extension', () => {
MQTT.publish.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/request/device/rename', stringify({"from": "weather_sensor", "to": "weather_sensor_renamed","homeassistant_rename":true}));
await flushPromises();
jest.runOnlyPendingTimers();
await flushPromises();
const payload = {
'unit_of_measurement': '°C',
@@ -1240,6 +1249,8 @@ describe('HomeAssistant extension', () => {
MQTT.publish.mockClear();
MQTT.events.message('zigbee2mqtt/bridge/request/group/rename', stringify({"from": "ha_discovery_group", "to": "ha_discovery_group_new","homeassistant_rename":true}));
await flushPromises();
jest.runOnlyPendingTimers();
await flushPromises();
const payload = {
"availability":[{"topic":"zigbee2mqtt/bridge/state"}],
@@ -1354,7 +1365,7 @@ describe('HomeAssistant extension', () => {
it('Should discover trigger when click is published', async () => {
const discovered = MQTT.publish.mock.calls.filter((c) => c[0].includes('0x0017880104e45520')).map((c) => c[0]);
expect(discovered.length).toBe(5);
expect(discovered.length).toBe(7);
expect(discovered).toContain('homeassistant/sensor/0x0017880104e45520/click/config');
expect(discovered).toContain('homeassistant/sensor/0x0017880104e45520/action/config');
@@ -1429,21 +1440,21 @@ describe('HomeAssistant extension', () => {
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/button',
stringify({action: "single", click: "single", battery: null, linkquality: null, voltage: null}),
stringify({action: "single", click: "single", battery: null, linkquality: null, voltage: null, power_outage_count: null, device_temperature: null}),
{ retain: false, qos: 0 },
expect.any(Function),
);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/button',
stringify({action: "", battery: null, linkquality: null, voltage: null, click: null}),
stringify({action: "", battery: null, linkquality: null, voltage: null, click: null, power_outage_count: null, device_temperature: null}),
{ retain: false, qos: 0 },
expect.any(Function),
);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/button',
stringify({click: "", action: null, battery: null, linkquality: null, voltage: null}),
stringify({click: "", action: null, battery: null, linkquality: null, voltage: null, power_outage_count: null, device_temperature: null}),
{ retain: false, qos: 0 },
expect.any(Function),
);
@@ -1530,7 +1541,7 @@ describe('HomeAssistant extension', () => {
await resetExtension();
const discovered = MQTT.publish.mock.calls.filter((c) => c[0].includes('0x0017880104e45520')).map((c) => c[0]);
expect(discovered.length).toBe(4);
expect(discovered.length).toBe(6);
expect(discovered).toContain('homeassistant/sensor/0x0017880104e45520/action/config');
expect(discovered).toContain('homeassistant/sensor/0x0017880104e45520/battery/config');
expect(discovered).toContain('homeassistant/sensor/0x0017880104e45520/linkquality/config');
@@ -1541,7 +1552,7 @@ describe('HomeAssistant extension', () => {
await resetExtension();
const discovered = MQTT.publish.mock.calls.filter((c) => c[0].includes('0x0017880104e45520')).map((c) => c[0]);
expect(discovered.length).toBe(3);
expect(discovered.length).toBe(5);
expect(discovered).not.toContain('homeassistant/sensor/0x0017880104e45520/click/config');
expect(discovered).not.toContain('homeassistant/sensor/0x0017880104e45520/action/config');
@@ -1586,7 +1597,7 @@ describe('HomeAssistant extension', () => {
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/button',
stringify({action: "single", "battery":null,"linkquality":null,"voltage":null}),
stringify({action: "single", "battery":null,"linkquality":null,"voltage":null, "power_outage_count": null, "device_temperature": null}),
{ retain: false, qos: 0 },
expect.any(Function),
);
@@ -1623,10 +1634,10 @@ describe('HomeAssistant extension', () => {
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(4);
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/button');
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({action: 'single', click: null, battery: null, linkquality: null, voltage: null});
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({action: 'single', click: null, battery: null, linkquality: null, voltage: null, power_outage_count: null, device_temperature: null});
expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false});
expect(MQTT.publish.mock.calls[1][0]).toStrictEqual('zigbee2mqtt/button');
expect(JSON.parse(MQTT.publish.mock.calls[1][1])).toStrictEqual({action: '', click: null, battery: null, linkquality: null, voltage: null});
expect(JSON.parse(MQTT.publish.mock.calls[1][1])).toStrictEqual({action: '', click: null, battery: null, linkquality: null, voltage: null, power_outage_count: null, device_temperature: null});
expect(MQTT.publish.mock.calls[1][2]).toStrictEqual({"qos": 0, "retain": false});
expect(MQTT.publish.mock.calls[2][0]).toStrictEqual('homeassistant/device_automation/0x0017880104e45520/action_single/config');
expect(MQTT.publish.mock.calls[3][0]).toStrictEqual('zigbee2mqtt/button/action');
+26 -13
View File
@@ -25,6 +25,7 @@ describe('Logger', () => {
it('Create log directory', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const dirs = fs.readdirSync(dir.name);
expect(dirs.length).toBe(1);
@@ -32,6 +33,7 @@ describe('Logger', () => {
it('Should cleanup', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
for (const d of fs.readdirSync(dir.name)) {
@@ -49,6 +51,7 @@ describe('Logger', () => {
it('Should not cleanup when there is no timestamp set', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
for (let i = 30; i < 40; i++) {
fs.mkdirSync(path.join(dir.name, `log_${i}`));
@@ -62,6 +65,7 @@ describe('Logger', () => {
it('Set and get log level', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
logger.setLevel('debug');
expect(logger.getLevel()).toBe('debug');
@@ -74,23 +78,26 @@ describe('Logger', () => {
}
const logger = require('../lib/util/logger').default;
expect(logger.winston.transports.length).toBe(2);
logger.init();
expect(logger.winston().transports.length).toBe(2);
logger.addTransport(new DummyTransport());
expect(logger.winston.transports.length).toBe(3);
expect(logger.winston().transports.length).toBe(3);
});
it('Set and get log level warn <-> warning', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
logger.setLevel('warn');
expect(logger.winston.transports[0].level).toBe('warning');
expect(logger.winston().transports[0].level).toBe('warning');
expect(logger.getLevel()).toBe('warn');
});
it('Logger should be console and file by default', () => {
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston._readableState.pipes;
const pipes = logger.winston()._readableState.pipes;
expect(pipes.length).toBe(2);
expect(pipes[0].constructor.name).toBe('Console');
expect(pipes[0].silent).toBe(false);
@@ -101,8 +108,9 @@ describe('Logger', () => {
it('Logger can be file only', () => {
settings.set(['advanced', 'log_output'], ['file']);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston._readableState.pipes;
const pipes = logger.winston()._readableState.pipes;
expect(pipes.length).toBe(2);
expect(pipes[0].constructor.name).toBe('Console');
expect(pipes[0].silent).toBe(true);
@@ -113,8 +121,9 @@ describe('Logger', () => {
it('Logger can be console only', () => {
settings.set(['advanced', 'log_output'], ['console']);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston._readableState.pipes;
const pipes = logger.winston()._readableState.pipes;
expect(pipes.constructor.name).toBe('Console');
expect(pipes.silent).toBe(false);
});
@@ -122,8 +131,9 @@ describe('Logger', () => {
it('Logger can be nothing', () => {
settings.set(['advanced', 'log_output'], []);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston._readableState.pipes;
const pipes = logger.winston()._readableState.pipes;
expect(pipes.constructor.name).toBe('Console');
expect(pipes.silent).toBe(true);
});
@@ -131,8 +141,9 @@ describe('Logger', () => {
it('Should allow to disable log rotation', () => {
settings.set(['advanced', 'log_rotation'], false);
const logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
const pipes = logger.winston._readableState.pipes;
const pipes = logger.winston()._readableState.pipes;
expect(pipes[1].constructor.name).toBe('File');
expect(pipes[1].maxFiles).toBeNull();
expect(pipes[1].tailable).toBeFalsy();
@@ -142,6 +153,7 @@ describe('Logger', () => {
it('Should allow to symlink logs to current directory', () => {
settings.set(['advanced', 'log_symlink_current'], true);
let logger = require('../lib/util/logger').default;
logger.init();
logger.logOutput();
expect(fs.readdirSync(dir.name).includes('current')).toBeTruthy()
@@ -151,23 +163,24 @@ describe('Logger', () => {
it('Log', () => {
const logger = require('../lib/util/logger').default;
const warn = jest.spyOn(logger.winston, 'warning');
logger.init();
const warn = jest.spyOn(logger.winston(), 'warning');
logger.warn('warn');
expect(warn).toHaveBeenCalledWith('warn');
const debug = jest.spyOn(logger.winston, 'debug');
const debug = jest.spyOn(logger.winston(), 'debug');
logger.debug('debug');
expect(debug).toHaveBeenCalledWith('debug');
const warning = jest.spyOn(logger.winston, 'warning');
const warning = jest.spyOn(logger.winston(), 'warning');
logger.warning('warning');
expect(warning).toHaveBeenCalledWith('warning');
const info = jest.spyOn(logger.winston, 'info');
const info = jest.spyOn(logger.winston(), 'info');
logger.info('info');
expect(info).toHaveBeenCalledWith('info');
const error = jest.spyOn(logger.winston, 'error');
const error = jest.spyOn(logger.winston(), 'error');
logger.error('error');
expect(error).toHaveBeenCalledWith('error');
});
+2 -2
View File
@@ -102,7 +102,7 @@ describe('Networkmap', () => {
let call = MQTT.publish.mock.calls[0];
expect(call[0]).toStrictEqual('zigbee2mqtt/bridge/networkmap/raw');
const expected = {"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Aqara double key wireless wall switch (2016 model)","model":"WXKG02LM_rev1","supports":"battery, action, voltage, linkquality","vendor":"Xiaomi"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":null,"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description": "external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]};
const expected = {"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Aqara double key wireless wall switch (2016 model)","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Xiaomi"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":null,"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description": "external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]};
expect(JSON.parse(call[1])).toStrictEqual(expected);
/**
@@ -276,7 +276,7 @@ describe('Networkmap', () => {
let call = MQTT.publish.mock.calls[0];
expect(call[0]).toStrictEqual('zigbee2mqtt/bridge/response/networkmap');
const expected = {"data":{"routes":true,"type":"raw","value":{"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Aqara double key wireless wall switch (2016 model)","model":"WXKG02LM_rev1","supports":"battery, action, voltage, linkquality","vendor":"Xiaomi"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":null,"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]}},"status":"ok"};
const expected = {"data":{"routes":true,"type":"raw","value":{"links":[{"depth":1,"linkquality":120,"lqi":120,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[{"destinationAddress":6540,"nextHop":40369,"status":"ACTIVE"}],"source":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"sourceIeeeAddr":"0x000b57fffec6a5b2","sourceNwkAddr":40369,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":1,"linkquality":92,"lqi":92,"relationship":2,"routes":[],"source":{"ieeeAddr":"0x0017880104e45511","networkAddress":1114},"sourceIeeeAddr":"0x0017880104e45511","sourceNwkAddr":1114,"target":{"ieeeAddr":"0x00124b00120144ae","networkAddress":0},"targetIeeeAddr":"0x00124b00120144ae"},{"depth":2,"linkquality":110,"lqi":110,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x000b57fffec6a5b3","networkAddress":40399},"sourceIeeeAddr":"0x000b57fffec6a5b3","sourceNwkAddr":40399,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":100,"lqi":100,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"sourceIeeeAddr":"0x0017880104e45559","sourceNwkAddr":6540,"target":{"ieeeAddr":"0x000b57fffec6a5b2","networkAddress":40369},"targetIeeeAddr":"0x000b57fffec6a5b2"},{"depth":2,"linkquality":130,"lqi":130,"relationship":1,"routes":[],"source":{"ieeeAddr":"0x0017880104e45521","networkAddress":6538},"sourceIeeeAddr":"0x0017880104e45521","sourceNwkAddr":6538,"target":{"ieeeAddr":"0x0017880104e45559","networkAddress":6540},"targetIeeeAddr":"0x0017880104e45559"}],"nodes":[{"definition":null,"failed":[],"friendlyName":"Coordinator","ieeeAddr":"0x00124b00120144ae","lastSeen":1000,"modelID":null,"networkAddress":0,"type":"Coordinator"},{"definition":{"description":"TRADFRI LED bulb E26/E27 980 lumen, dimmable, white spectrum, opal white","model":"LED1545G12","supports":"light (state, brightness, color_temp, color_temp_startup), effect, power_on_behavior, linkquality","vendor":"IKEA"},"failed":[],"friendlyName":"bulb","ieeeAddr":"0x000b57fffec6a5b2","lastSeen":1000,"modelID":"TRADFRI bulb E27 WS opal 980lm","networkAddress":40369,"type":"Router"},{"definition":{"description":"Hue Go","model":"7146060PH","supports":"light (state, brightness, color_temp, color_temp_startup, color_xy, color_hs), effect, linkquality","vendor":"Philips"},"failed":[],"friendlyName":"bulb_color","ieeeAddr":"0x000b57fffec6a5b3","lastSeen":1000,"modelID":"LLC020","networkAddress":40399,"type":"Router"},{"definition":{"description":"Aqara double key wireless wall switch (2016 model)","model":"WXKG02LM_rev1","supports":"battery, action, voltage, power_outage_count, linkquality","vendor":"Xiaomi"},"friendlyName":"button_double_key","ieeeAddr":"0x0017880104e45521","lastSeen":1000,"modelID":"lumi.sensor_86sw2.es1","networkAddress":6538,"type":"EndDevice"},{"definition":null,"failed":["lqi","routingTable"],"friendlyName":"0x0017880104e45525","ieeeAddr":"0x0017880104e45525","lastSeen":1000,"manufacturerName":"Boef","modelID":"notSupportedModelID","networkAddress":6536,"type":"Router"},{"definition":{"description":"[CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/)","model":"CC2530.ROUTER","supports":"led, linkquality","vendor":"Custom devices (DiY)"},"failed":[],"friendlyName":"cc2530_router","ieeeAddr":"0x0017880104e45559","lastSeen":1000,"modelID":"lumi.router","networkAddress":6540,"type":"Router"},{"definition":{"description":"external","model":"external_converter_device","supports":"linkquality","vendor":"external"},"friendlyName":"0x0017880104e45511","ieeeAddr":"0x0017880104e45511","lastSeen":1000,"modelID":"external_converter_device","networkAddress":1114,"type":"EndDevice"}]}},"status":"ok"};
const actual = JSON.parse(call[1]);
expect(actual).toStrictEqual(expected);
});
+4 -2
View File
@@ -48,6 +48,8 @@ describe('On event', () => {
expect(call[0]).toBe('start')
expect(call[1]).toStrictEqual({})
expect(call[2]).toBe(device);
expect(call[3]).toStrictEqual(settings.getDevice(device.ieeeAddr));
expect(call[4]).toStrictEqual({});
});
it('Should call with stop event', async () => {
@@ -66,7 +68,7 @@ describe('On event', () => {
await zigbeeHerdsman.events.deviceAnnounce({device});
await flushPromises();
expect(mockOnEvent).toHaveBeenCalledTimes(1);
expect(mockOnEvent).toHaveBeenCalledWith('deviceAnnounce', {device}, device, settings.getDevice(device.ieeeAddr));
expect(mockOnEvent).toHaveBeenCalledWith('deviceAnnounce', {device}, device, settings.getDevice(device.ieeeAddr), {});
});
it('Should call index onEvent with zigbee event', async () => {
@@ -74,6 +76,6 @@ describe('On event', () => {
await zigbeeHerdsman.events.deviceAnnounce({device});
await flushPromises();
expect(zigbeeHerdsmanConverters.onEvent).toHaveBeenCalledTimes(1);
expect(zigbeeHerdsmanConverters.onEvent).toHaveBeenCalledWith('deviceAnnounce', {device}, device);
expect(zigbeeHerdsmanConverters.onEvent).toHaveBeenCalledWith('deviceAnnounce', {device}, device, settings.getDevice(device.ieeeAddr), {});
});
});
+4 -1
View File
@@ -1,3 +1,5 @@
const path = require('path');
const data = require('./stub/data');
const logger = require('./stub/logger');
const zigbeeHerdsman = require('./stub/zigbeeHerdsman');
@@ -11,6 +13,7 @@ const zigbeeOTA = require('zigbee-herdsman-converters/lib/ota/zigbeeOTA');
const spyUseIndexOverride = jest.spyOn(zigbeeOTA, 'useIndexOverride');
describe('OTA update', () => {
let controller;
@@ -468,7 +471,7 @@ describe('OTA update', () => {
it('Set zigbee_ota_override_index_location', async () => {
settings.set(['ota', 'zigbee_ota_override_index_location'], 'local.index.json');
await resetExtension();
expect(spyUseIndexOverride).toHaveBeenCalledWith(data.mockDir + '/local.index.json');
expect(spyUseIndexOverride).toHaveBeenCalledWith(path.join(data.mockDir, 'local.index.json'));
spyUseIndexOverride.mockClear();
settings.set(['ota', 'zigbee_ota_override_index_location'], 'http://my.site/index.json');
+4 -4
View File
@@ -919,11 +919,11 @@ describe('Publish', () => {
expect(endpoint.command).toHaveBeenCalledTimes(3);
expect(endpoint.command.mock.calls[0]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 50, transtime: 0}, {}]);
expect(endpoint.command.mock.calls[1]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 0, transtime: 0}, {}]);
expect(endpoint.command.mock.calls[2]).toEqual(["genOnOff", "on", {}, {}]);
expect(endpoint.command.mock.calls[2]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 50, transtime: 0}, {}]);
expect(MQTT.publish).toHaveBeenCalledTimes(3);
expect(MQTT.publish.mock.calls[0]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'ON', brightness: 50}), {"qos": 0, "retain": false}, expect.any(Function)]);
expect(MQTT.publish.mock.calls[1]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'OFF', brightness: 0}), {"qos": 0, "retain": false}, expect.any(Function)]);
expect(MQTT.publish.mock.calls[2]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'ON', brightness: 1}), {"qos": 0, "retain": false}, expect.any(Function)]);
expect(MQTT.publish.mock.calls[2]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'ON', brightness: 50}), {"qos": 0, "retain": false}, expect.any(Function)]);
});
it('Should turn device off when brightness 0 is send with transition', async () => {
@@ -938,11 +938,11 @@ describe('Publish', () => {
expect(endpoint.command).toHaveBeenCalledTimes(3);
expect(endpoint.command.mock.calls[0]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 50, transtime: 0}, {}]);
expect(endpoint.command.mock.calls[1]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 0, transtime: 30}, {}]);
expect(endpoint.command.mock.calls[2]).toEqual(["genOnOff", "on", {}, {}]);
expect(endpoint.command.mock.calls[2]).toEqual(["genLevelCtrl", "moveToLevelWithOnOff", {level: 50, transtime: 0}, {}]);
expect(MQTT.publish).toHaveBeenCalledTimes(3);
expect(MQTT.publish.mock.calls[0]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'ON', brightness: 50}), {"qos": 0, "retain": false}, expect.any(Function)]);
expect(MQTT.publish.mock.calls[1]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'OFF', brightness: 0}), {"qos": 0, "retain": false}, expect.any(Function)]);
expect(MQTT.publish.mock.calls[2]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'ON', brightness: 1}), {"qos": 0, "retain": false}, expect.any(Function)]);
expect(MQTT.publish.mock.calls[2]).toEqual(["zigbee2mqtt/bulb_color", stringify({state: 'ON', brightness: 50}), {"qos": 0, "retain": false}, expect.any(Function)]);
});
it('Should allow to set color via hue and saturation', async () => {
+6 -6
View File
@@ -84,7 +84,7 @@ describe('Receive', () => {
await zigbeeHerdsman.events.message({data: {currentPositionLiftPercentage: 90, currentPositionTiltPercentage: 80}, cluster: 'closuresWindowCovering', device, endpoint: device.getEndpoint(1), type: 'attributeReport', linkquality: 10});
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/J1_cover', stringify({position: 10, tilt: 20}), {retain: false, qos: 0}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/J1_cover', stringify({position: 10, tilt: 20, state: 'OPEN'}), {retain: false, qos: 0}, expect.any(Function));
// Inverted
MQTT.publish.mockClear();
@@ -92,7 +92,7 @@ describe('Receive', () => {
await zigbeeHerdsman.events.message({data: {currentPositionLiftPercentage: 90, currentPositionTiltPercentage: 80}, cluster: 'closuresWindowCovering', device, endpoint: device.getEndpoint(1), type: 'attributeReport', linkquality: 10});
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/J1_cover', stringify({position: 90, tilt: 80}), {retain: false, qos: 0}, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/J1_cover', stringify({position: 90, tilt: 80, state: 'OPEN'}), {retain: false, qos: 0}, expect.any(Function));
});
it('Should allow to disable the legacy integration', async () => {
@@ -242,15 +242,15 @@ describe('Receive', () => {
expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 1, "retain": false});
});
it('Should handle a zigbee message with voltage 3010', async () => {
it('Should handle a zigbee message with voltage 2990', async () => {
const device = zigbeeHerdsman.devices.WXKG02LM_rev1;
const data = {'65281': {'1': 3010}}
const data = {'65281': {'1': 2990}}
const payload = {data, cluster: 'genBasic', device, endpoint: device.getEndpoint(1), type: 'attributeReport', linkquality: 10};
await zigbeeHerdsman.events.message(payload);
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/button_double_key');
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({battery: 100, voltage: 3010});
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({battery: 93, voltage: 2990});
expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false});
});
@@ -262,7 +262,7 @@ describe('Receive', () => {
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/occupancy_sensor');
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({'battery': 100, 'illuminance': 381, "illuminance_lux": 381, 'voltage': 3045, 'temperature': 19});
expect(JSON.parse(MQTT.publish.mock.calls[0][1])).toStrictEqual({'battery': 100, 'illuminance': 381, "illuminance_lux": 381, 'voltage': 3045, 'device_temperature': 19, 'power_outage_count': 34});
expect(MQTT.publish.mock.calls[0][2]).toStrictEqual({"qos": 0, "retain": false});
});
+49 -3
View File
@@ -39,6 +39,7 @@ describe('Settings', () => {
beforeEach(() => {
remove(configurationFile);
remove(secretFile);
remove(devicesFile);
remove(groupsFile);
clearEnvironmentVariables();
@@ -69,6 +70,7 @@ describe('Settings', () => {
process.env['ZIGBEE2MQTT_CONFIG_ADVANCED_OUTPUT'] = 'csvtest';
process.env['ZIGBEE2MQTT_CONFIG_MAP_OPTIONS_GRAPHVIZ_COLORS_FILL'] = '{"enddevice": "#ff0000", "coordinator": "#00ff00", "router": "#0000ff"}';
process.env['ZIGBEE2MQTT_CONFIG_MQTT_BASE_TOPIC'] = 'testtopic';
process.env['ZIGBEE2MQTT_CONFIG_ADVANCED_NETWORK_KEY'] = 'GENERATE';
write(configurationFile, {});
const s = settings.get();
@@ -80,6 +82,7 @@ describe('Settings', () => {
expected.advanced.output = 'csvtest';
expected.map_options.graphviz.colors.fill = {enddevice: '#ff0000', coordinator: '#00ff00', router: '#0000ff'};
expected.mqtt.base_topic = 'testtopic';
expected.advanced.network_key = 'GENERATE';
expect(s).toStrictEqual(expected);
});
@@ -171,6 +174,49 @@ describe('Settings', () => {
expect(read(secretFile)).toStrictEqual({...contentSecret, username: 'test123', network_key: [1,2,3,4]});
});
it('Should read ALL secrets form a separate file', () => {
const contentConfiguration = {
mqtt: {
server: '!secret server',
user: '!secret username',
password: '!secret password',
},
advanced: {
network_key: '!secret network_key',
}
};
const contentSecret = {
server: 'my.mqtt.server',
username: 'mysecretusername',
password: 'mysecretpassword',
network_key: [1,2,3],
};
write(secretFile, contentSecret, false);
write(configurationFile, contentConfiguration);
const expected = {
base_topic: 'zigbee2mqtt',
include_device_information: false,
force_disable_retain: false,
password: "mysecretpassword",
server: "my.mqtt.server",
user: "mysecretusername",
};
expect(settings.get().mqtt).toStrictEqual(expected);
expect(settings.get().advanced.network_key).toStrictEqual([1,2,3]);
settings.testing.write();
expect(read(configurationFile)).toStrictEqual(contentConfiguration);
expect(read(secretFile)).toStrictEqual(contentSecret);
settings.set(['mqtt', 'server'], 'not.secret.server');
expect(read(configurationFile)).toStrictEqual(contentConfiguration);
expect(read(secretFile)).toStrictEqual({...contentSecret, server: 'not.secret.server'});
});
it('Should read devices form a separate file', () => {
const contentConfiguration = {
devices: 'devices.yaml',
@@ -747,15 +793,15 @@ describe('Settings', () => {
expect(settings.validate()).toEqual(expect.arrayContaining([error]));
});
it('Configuration friendly name cannot contain null char', async () => {
it('Configuration friendly name cannot contain control char', async () => {
write(configurationFile, {
...minimalConfig,
devices: {'0x0017880104e45519': {friendly_name: 'blaa/blaa' + String.fromCharCode(0), retain: false}},
devices: {'0x0017880104e45519': {friendly_name: 'blaa/blaa\u009f', retain: false}},
});
settings.reRead();
const error = `friendly_name is not allowed to contain null char`;
const error = `friendly_name is not allowed to contain control char`;
expect(settings.validate()).toEqual(expect.arrayContaining([error]));
});
+3
View File
@@ -243,6 +243,9 @@ const defaultState = {
"0x0017880104e45517": {
"brightness": 255
},
"1": {
'state': 'ON',
}
}
function getDefaultState() {
+1
View File
@@ -12,6 +12,7 @@ const callTransports = (level, message) => {
}
const mock = {
init: jest.fn(),
info: jest.fn().mockImplementation((msg) => callTransports('info', msg)),
warn: jest.fn().mockImplementation((msg) => callTransports('warn', msg)),
error: jest.fn().mockImplementation((msg) => callTransports('error', msg)),
+6 -1
View File
@@ -27,7 +27,11 @@ const clusters = {
'lightingColorCtrl': 768,
'closuresWindowCovering': 258,
'hvacThermostat': 513,
'msIlluminanceMeasurement': 1024,
'msTemperatureMeasurement': 1026,
'msRelativeHumidity': 1029,
'msSoilMoisture': 1032,
'msCO2': 1037
}
class Endpoint {
@@ -188,7 +192,7 @@ const devices = {
'MKS-CM-W5': new Device('Router', '0x90fd9ffffe4b64ac', 33901, 4476, [new Endpoint(1, [0,4,3,5,10,258,13,19,6,1,1030,8,768,1027,1029,1026], [0,3,4,6,8,5], '0x90fd9ffffe4b64aa', [], {})], true, "Mains (single phase)", "qnazj70", false),
'GL-S-007ZS': new Device('Router', '0x0017880104e45526', 6540,4151, [new Endpoint(1, [0], [], '0x0017880104e45526')], true, "Mains (single phase)", 'GL-S-007ZS'),
'U202DST600ZB': new Device('Router', '0x0017880104e43559', 6540,4151, [new Endpoint(10, [0, 6], [], '0x0017880104e43559'), new Endpoint(11, [0, 6], [], '0x0017880104e43559')], true, "Mains (single phase)", 'U202DST600ZB'),
'3157100': new Device('Router', '0x0017880104e44559', 6542,4151, [new Endpoint(1, [], [], '0x0017880104e44559')], true, "Mains (single phase)", '3157100'),
'3157100': new Device('Router', '0x0017880104e44559', 6542,4151, [new Endpoint(1, [], [], '0x0017880104e44559')], true, "Mains (single phase)", '3157100', false, 'Centralite'),
'J1': new Device('Router', '0x0017880104a44559', 6543,4151, [new Endpoint(1, [], [], '0x0017880104a44559')], true, "Mains (single phase)", 'J1 (5502)'),
'TS0601_thermostat': TS0601_thermostat,
'external_converter_device': new Device('EndDevice', '0x0017880104e45511', 1114, 'external', [new Endpoint(1, [], [], '0x0017880104e45511')], false, null, 'external_converter_device' ),
@@ -207,6 +211,7 @@ const mock = {
touchlinkScan: jest.fn(),
touchlinkIdentify: jest.fn(),
start: jest.fn(),
backup: jest.fn(),
isStopping: jest.fn(),
permitJoin: jest.fn(),
getCoordinatorVersion: jest.fn().mockReturnValue({type: 'z-Stack', meta: {version: 1, revision: 20190425}}),
-1
View File
@@ -18,7 +18,6 @@ echo "Creating backup of configuration..."
cp -R data data-backup
echo "Updating..."
git checkout HEAD -- npm-shrinkwrap.json
git pull
echo "Installing dependencies..."