Compare commits

..
111 Commits
Author SHA1 Message Date
Koen Kanters e43c371d76 1.28.3 2022-12-01 17:35:02 +01:00
Koen Kanters a7e85a0bd9 Undev 2022-12-01 17:34:47 +01:00
Koen Kanters 7f6f6a69c7 Merge remote-tracking branch 'origin/master' into dev 2022-12-01 17:33:55 +01:00
github-actions[bot]andKoenkk 87667bdac7 Update zigbee-herdsman-converters to 14.0.680 (#15276)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-12-01 15:02:29 +00:00
github-actions[bot]andKoenkk bd8edd70bb Update zigbee-herdsman-converters to 14.0.679 (#15262)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-30 16:06:01 +00:00
github-actions[bot]andKoenkk 4a3e6b9561 Update zigbee-herdsman-converters to 14.0.678 (#15249)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-29 18:45:39 +00:00
Artem Draft f92134fc5f Disable by default update_available sensor in HA (#15237) 2022-11-29 19:18:33 +01:00
9dba2d7f11 Update zigbee-herdsman-converters to 14.0.677 (#15229)
* Update zigbee-herdsman-converters to 14.0.677

* Fix

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-11-28 18:49:34 +00:00
9289a26f11 Update dependencies (#15204)
* Update dependencies

* Fix diff

* fix

* update

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-11-27 14:52:47 +01:00
github-actions[bot]andKoenkk 17054627e9 Update zigbee-herdsman-converters to 14.0.676 (#15207)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-27 09:38:39 +00:00
github-actions[bot]andKoenkk 66c4ca072e Update zigbee-herdsman-converters to 14.0.675 (#15190)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-26 09:32:55 +00:00
github-actions[bot]andKoenkk 3b221d4fb0 Update zigbee-herdsman-converters to 14.0.674 (#15168)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-24 16:40:12 +00:00
github-actions[bot]andKoenkk 4464554f90 Update zigbee-herdsman to 0.14.76 (#15167)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-24 16:32:05 +00:00
b15cd433c4 Update zigbee-herdsman-converters to 14.0.673 (#15150)
* Update zigbee-herdsman-converters to 14.0.673

* Update homeassistant.test.js

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-11-23 17:56:32 +00:00
github-actions[bot]andKoenkk 4b5a03c6c5 Update zigbee-herdsman to 0.14.75 (#15149)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-23 16:10:46 +00:00
github-actions[bot]andKoenkk ca4badca4d Update zigbee-herdsman-converters to 14.0.672 (#15133)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-22 19:03:36 +00:00
DJTerentjevandAlex 1b3dd7540b Add polling when bounded for Trust and Gledopto (#15126)
* GitHub Workflows security hardening (#14799)

* build: harden update_frontend.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

* build: harden update_zhc.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

* build: harden ghcr_cleanup.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

* build: harden update_zh.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

Signed-off-by: Alex <aleksandrosansan@gmail.com>

* Add bound polling by manufacturerNames

Based on:
#7825

* Add bound polling by manufacturerNames

Based on:
#7825

Signed-off-by: Alex <aleksandrosansan@gmail.com>
Co-authored-by: Alex <aleksandrosansan@gmail.com>
2022-11-22 19:35:15 +01:00
Koen Kanters c7183ca080 Update external converter tester. 2022-11-22 19:16:25 +01:00
Koen Kanters 119531e9e2 Add external converter tester 2022-11-22 19:12:03 +01:00
85be7d28d5 Update zigbee-herdsman-converters to 14.0.671 (#15123)
* Update zigbee-herdsman-converters to 14.0.671

* Update homeassistant.ts

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-11-21 19:35:37 +00:00
github-actions[bot]andnurikk 6c147dae6c Update zigbee2mqtt-frontend to 0.6.119 (#15109)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-11-20 20:48:42 +00:00
github-actions[bot]andKoenkk 1fe138c34c Update zigbee-herdsman-converters to 14.0.670 (#15107)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-20 18:26:44 +00:00
github-actions[bot]andKoenkk 1258aee464 Update zigbee-herdsman to 0.14.74 (#15105)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-20 16:35:01 +00:00
github-actions[bot]andnurikk fbb0ed0e67 Update zigbee2mqtt-frontend to 0.6.118 (#15083)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-11-19 11:16:56 +00:00
github-actions[bot]andKoenkk 8510e99010 Update zigbee-herdsman-converters to 14.0.669 (#15053)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-17 17:07:37 +00:00
Koen Kanters 342955666a Fix 'dict object' has no attribute 'installed_version'. https://github.com/Koenkk/zigbee2mqtt/discussions/15039 2022-11-17 17:52:59 +01:00
github-actions[bot]andKoenkk 50cb421f64 Update zigbee-herdsman-converters to 14.0.668 (#15007)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-15 19:38:26 +00:00
github-actions[bot]andnurikk 16398b7810 Update zigbee2mqtt-frontend to 0.6.117 (#14995)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-11-15 11:36:57 +00:00
github-actions[bot]andKoenkk f3b5aee173 Update zigbee-herdsman-converters to 14.0.667 (#14983)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-14 20:16:38 +00:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> e8f85b35c1 Bump actions/dependency-review-action from 2 to 3 (#14978)
Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 2 to 3.
- [Release notes](https://github.com/actions/dependency-review-action/releases)
- [Commits](https://github.com/actions/dependency-review-action/compare/v2...v3)

---
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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-14 18:13:49 +01:00
github-actions[bot]andKoenkk dd8f13aa8d Update zigbee-herdsman to 0.14.73 (#14979)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-14 17:07:35 +00:00
dreed47 ced2ba7344 small clarification to the description for adding a user-defined device icon (#14960)
* small clarification to the description for adding a user-defined device icon

* small wording change
2022-11-14 17:49:18 +01:00
Jakub Jirutka a2f8534823 Allow to specify full file name in value reference '!' (#14955)
* Extract parsing of value reference '!' in settings into a function

* Allow to specify full file name in value reference '!'

This `network_key: '!secret network_key'` is really confusing because
it looks like a YAML tag named 'secret' and a value "network_key".
When we write `network_key: '!secret.yaml network_key'` instead, it's
a little clearer what's going on. Also, it's more consistent with file
references in 'devices' and 'groups'.
2022-11-13 15:17:59 +01:00
github-actions[bot]andKoenkk d05ef70901 Update zigbee-herdsman to 0.14.72 (#14958)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-13 09:26:45 +00:00
Jakub JirutkaandKoen Kanters 4bc0c3ed6b Use path.resolve instead of path.join in data.joinPath (#14953)
This allows specifying a path outside of the data directory using an
absolute path (e.g. /path/to/devices.yaml) or a path relative to the data
directory (e.g. devices.yaml, foo/devices.yaml, ../../devices.yaml, ...).
This change is backward compatible because file names and nested paths are
just a special case of a relative path.

Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-11-13 09:24:47 +01:00
Koen Kanters 489d1de756 Fix Cannot set properties of undefined (setting 'installed_version'). https://github.com/Koenkk/zigbee2mqtt/issues/14917 2022-11-13 09:21:27 +01:00
github-actions[bot]andKoenkk 499b993410 Update zigbee-herdsman to 0.14.71 (#14946)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-12 15:20:46 +00:00
github-actions[bot]andKoenkk 9f0b16291a Update zigbee-herdsman-converters to 14.0.666 (#14930)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-11 16:16:51 +00:00
github-actions[bot]andKoenkk 98a6a2dfe8 Update zigbee-herdsman-converters to 14.0.665 (#14916)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-10 17:05:54 +00:00
Koen Kanters fb14ba20ca Update Docker image to use node:18-alpine3.16 (#14915) 2022-11-10 17:48:17 +01:00
Koen Kanters b68b984de6 Log Zigbee2MQTT started! on startup. https://github.com/Koenkk/zigbee2mqtt/issues/14283 2022-11-10 17:45:48 +01:00
Koen Kanters 1d36dfd932 Support Home Assistant MQTT update #14748 (#14905) 2022-11-09 21:01:30 +01:00
github-actions[bot]andKoenkk 672da64913 Update zigbee-herdsman-converters to 14.0.664 (#14900)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-09 18:53:08 +00:00
github-actions[bot]andKoenkk cb29e164f8 Update zigbee-herdsman-converters to 14.0.663 (#14889)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-08 18:20:43 +00:00
Vincenzo Mantova 1e6a457190 more Home Assistant icons (#14865)
* add missing icons and classes for BRT-100-TRV (and possibly others)

* use high/low thermometer icons for max/min temperatures
2022-11-08 16:24:19 +01:00
github-actions[bot]andKoenkk cd22dafc89 Update zigbee-herdsman-converters to 14.0.662 (#14860)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-07 17:34:17 +00:00
github-actions[bot]andKoenkk 83d8a0e6a2 Update zigbee-herdsman to 0.14.70 (#14858)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-07 17:06:27 +00:00
Vincenzo Mantova e0b765ba88 Revert "Respect climate system_mode ACCESS_SET bit in Home Assistant (#14715)" (#14842)
This reverts commit 58c800181a.
2022-11-07 17:38:30 +01:00
5e2df18b75 Update zigbee-herdsman-converters to 14.0.661 (#14839)
* Update zigbee-herdsman-converters to 14.0.661

* Fix tests

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-11-06 14:42:08 +00:00
github-actions[bot]andKoenkk 9b48334e0e Update zigbee-herdsman to 0.14.69 (#14838)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-06 12:51:48 +00:00
github-actions[bot]andKoenkk c8ae15e92d Update dependencies (#14834)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-06 13:37:56 +01:00
John DoeandAinur Timerbaev f88ac154a2 Mark node v19 as supported (#14837)
* Mark node19 as supported

* Fix condition

* Fix tests

Co-authored-by: Ainur Timerbaev <ainur.timerbaev@superawesome.com>
2022-11-06 12:28:59 +00:00
Alex e66fe8534e GitHub Workflows security hardening (#14799)
* build: harden update_frontend.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

* build: harden update_zhc.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

* build: harden ghcr_cleanup.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

* build: harden update_zh.yml permissions

Signed-off-by: Alex <aleksandrosansan@gmail.com>

Signed-off-by: Alex <aleksandrosansan@gmail.com>
2022-11-05 14:21:55 +01:00
Jakub Jirutka c2e95bdb6a Remove core-js polyfills (#14788)
According to engines.node in package.json, the minimal supported version
of Node.js is 14.

* `Object.fromEntries()` is supported by Node.js since 12.0.0
* `Array.prototype.flat()` is supported by Node.js since 11.0.0

These polyfills were added in #9085, but the minimum supported Node.js
version has since been raised to 14.
2022-11-05 14:17:53 +01:00
github-actions[bot]andnurikk 7c5ef8a3d6 Update zigbee2mqtt-frontend to 0.6.115 (#14816)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-11-05 09:59:34 +00:00
Koen Kanters 4a2190f969 Add back fsevents 2022-11-04 19:35:14 +01:00
github-actions[bot]andKoenkk a3ed236524 Update dependencies (#14810)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-04 17:08:56 +01:00
Koen Kanters f4d8e6f4c5 Merge branch 'master' into dev 2022-11-04 17:05:54 +01:00
Koen Kanters 360a777a4e 1.28.2 2022-11-04 16:53:33 +01:00
Koen Kanters 5ed8b36cf2 Bump zigbee-herdsman-converters to 14.0.657-hotfix.0 2022-11-04 16:52:53 +01:00
github-actions[bot]andKoenkk 9540b6c182 Update zigbee-herdsman-converters to 14.0.660 (#14792)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-03 18:43:32 +00:00
Koen Kanters 31f002294e Update README.md 2022-11-02 22:00:25 +01:00
ecfc7e8906 Update zigbee-herdsman-converters to 14.0.659 (#14780)
* Update zigbee-herdsman-converters to 14.0.659

* Fix tests

Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
Co-authored-by: Koen Kanters <koenkanters94@gmail.com>
2022-11-02 20:56:54 +00:00
Koen Kanters 60bf855e74 Fix starting via cli.js. https://github.com/Koenkk/zigbee2mqtt/pull/14396 2022-11-02 20:01:06 +01:00
Koen Kanters c3f6e793fa Promote to dev 2022-11-01 19:59:25 +01:00
Koen Kanters 48117fddfa 1.28.1 2022-11-01 19:58:47 +01:00
Koen Kanters 7e70a5984f Undev 2022-11-01 19:58:44 +01:00
github-actions[bot]andKoenkk 4589c9f691 Update zigbee-herdsman-converters to 14.0.657 (#14753)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-01 18:51:21 +00:00
github-actions[bot]andKoenkk d81c15b5af Update zigbee-herdsman to 0.14.68 (#14754)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-01 16:44:28 +00:00
github-actions[bot]andKoenkk 043ae738d2 Update zigbee-herdsman to 0.14.67 (#14752)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-11-01 16:07:35 +00:00
github-actions[bot]andKoenkk 68184d669e Update zigbee-herdsman-converters to 14.0.655 (#14734)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-31 18:20:01 +00:00
github-actions[bot]andKoenkk fb3ee70c7a Update zigbee-herdsman-converters to 14.0.654 (#14727)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-30 19:07:00 +00:00
github-actions[bot]andKoenkk c5697e6c2b Update dependencies (#14718)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-30 19:23:11 +01:00
Vincenzo Mantova 58c800181a Respect climate system_mode ACCESS_SET bit in Home Assistant (#14715) 2022-10-30 19:16:32 +01:00
github-actions[bot]andKoenkk fd023268c5 Update zigbee-herdsman-converters to 14.0.652 (#14708)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-29 15:50:52 +00:00
github-actions[bot]andKoenkk 9dc93c7d27 Update zigbee-herdsman-converters to 14.0.651 (#14700)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-29 08:21:29 +00:00
Koen Kanters c943992e49 Fix 60de5b7676 2022-10-27 21:49:25 +02:00
github-actions[bot]andKoenkk dd9e92f81f Update zigbee-herdsman-converters to 14.0.650 (#14677)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-27 21:46:16 +02:00
Koen Kanters 60de5b7676 Respond with NO_IMAGE_AVAILABLE when device requests OTA. https://github.com/Koenkk/zigbee2mqtt/issues/13396 2022-10-27 20:39:44 +02:00
github-actions[bot]andKoenkk 6c0430b6e2 Update zigbee-herdsman-converters to 14.0.649 (#14660)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-26 16:57:24 +00:00
github-actions[bot]andKoenkk ddc4345f01 Update zigbee-herdsman-converters to 14.0.648 (#14633)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-24 17:49:52 +00:00
Koen Kanters 41053aa024 Set NODE_ENV to PRODUTION in Docker container. https://github.com/Koenkk/zigbee2mqtt/discussions/14625 2022-10-24 19:30:40 +02:00
github-actions[bot]andKoenkk 08ceae235e Update dependencies (#14602)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-23 09:09:56 +02:00
github-actions[bot]andKoenkk 599380dd63 Update zigbee-herdsman-converters to 14.0.647 (#14592)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-22 15:58:08 +00:00
github-actions[bot]andKoenkk a426ee1041 Update zigbee-herdsman-converters to 14.0.646 (#14576)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-21 14:44:53 +00:00
github-actions[bot]andKoenkk 939fdf0496 Update zigbee-herdsman-converters to 14.0.645 (#14553)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-19 15:59:22 +00:00
github-actions[bot]andKoenkk 3cffc2fdd8 Update zigbee-herdsman to 0.14.66 (#14549)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-19 15:26:35 +00:00
github-actions[bot]andKoenkk 22d2170d41 Update zigbee-herdsman-converters to 14.0.644 (#14540)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-18 18:16:04 +00:00
Vladyslav Pavlov 50a9de4e2b Expose step size of local_temperature_calibration Home Assistant sensor (#14502) 2022-10-18 17:59:32 +02:00
github-actions[bot]andKoenkk 2c12cbaf18 Update zigbee-herdsman to 0.14.65 (#14538)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-18 15:50:13 +00:00
github-actions[bot]andKoenkk ef6826f263 Update dependencies (#14503)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-18 17:38:26 +02:00
github-actions[bot]andKoenkk ceeaabafbc Update zigbee-herdsman-converters to 14.0.643 (#14458)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-12 19:47:13 +00:00
github-actions[bot]andKoenkk c49f5b157d Update zigbee-herdsman-converters to 14.0.642 (#14444)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-11 18:52:33 +00:00
github-actions[bot]andKoenkk 0a71e39253 Update zigbee-herdsman-converters to 14.0.641 (#14426)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-10 15:20:46 +00:00
github-actions[bot]andKoenkk 52a0f68c87 Update zigbee-herdsman-converters to 14.0.640 (#14416)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-09 18:19:11 +00:00
github-actions[bot]andKoenkk 457fc9da7c Update dependencies (#14411)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-09 09:01:32 +02:00
github-actions[bot]andKoenkk 5b39884c13 Update zigbee-herdsman-converters to 14.0.639 (#14403)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-08 12:18:16 +00:00
Matt 4d7b1a6c03 Allow Zigbee2MQTT to be installed as a module (#14396)
* Fix mnodule resolution

Allows the correct module path to be found if installed as a package

* Correct signature to avoid TS error

* Allow module to be included in another module

Only create hash ot auto-start if it is the main module, otherwise export the `start` function
2022-10-08 10:48:15 +02:00
Koen Kanters 50b5c67dde Support effects for Home Assistant light groups. #13438 2022-10-08 10:22:26 +02:00
Ben Windsor 005ada0237 Make temperature sensor selection for thermostats appear as a config item in HA (#14376) 2022-10-07 16:58:06 +02:00
github-actions[bot]andKoenkk e9b1080734 Update zigbee-herdsman-converters to 14.0.638 (#14374)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-06 16:12:23 +00:00
Ben Windsor 56cc1432e9 Mark min_temperature_limit as a config variable for HA (#14358) 2022-10-06 17:31:48 +02:00
github-actions[bot]andKoenkk e3dcc7b0a6 Update zigbee-herdsman-converters to 14.0.637 (#14353)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-05 19:08:45 +00:00
github-actions[bot]andKoenkk 37aea8df8f Update zigbee-herdsman to 0.14.64 (#14348)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-05 14:30:54 +00:00
github-actions[bot]andKoenkk f8d64b67ad Update zigbee-herdsman-converters to 14.0.636 (#14331)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-04 17:30:49 +00:00
github-actions[bot]andKoenkk 77fc3a9308 Update dependencies (#14279)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-04 19:26:54 +02:00
Ben Windsor db3730ea44 Expose value_step to home assistant if it has been set on a numeric type (#14313) 2022-10-04 18:02:35 +02:00
github-actions[bot]andnurikk 98ceaa04bb Update zigbee2mqtt-frontend to 0.6.114 (#14290)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-10-02 16:51:48 +00:00
github-actions[bot]andnurikk e3e4a0a440 Update zigbee2mqtt-frontend to 0.6.113 (#14271)
Co-authored-by: nurikk <nurikk@users.noreply.github.com>
2022-10-01 09:41:07 +00:00
github-actions[bot]andKoenkk 52150b7257 Update zigbee-herdsman to 0.14.63 (#14270)
Co-authored-by: Koenkk <Koenkk@users.noreply.github.com>
2022-10-01 08:53:48 +00:00
Koen Kanters 5727fe3a49 Dev 2022-10-01 09:40:35 +02:00
31 changed files with 1516 additions and 2468 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [14, 16, 18]
node: [14, 16, 18, 19]
runs-on: ${{ matrix.os }}
continue-on-error: true
steps:
+1 -1
View File
@@ -11,4 +11,4 @@ jobs:
- name: 'Checkout repository'
uses: actions/checkout@v3
- name: 'Dependency review'
uses: actions/dependency-review-action@v2
uses: actions/dependency-review-action@v3
+1
View File
@@ -3,6 +3,7 @@ on:
name: GHCR cleanup
permissions: {}
jobs:
build:
runs-on: ubuntu-latest
+5
View File
@@ -3,8 +3,13 @@ on:
repository_dispatch:
types: update_frontend
permissions: {}
jobs:
update_frontend:
permissions:
contents: write # to create branch (peter-evans/create-pull-request)
pull-requests: write # to create a PR (peter-evans/create-pull-request)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+5
View File
@@ -3,8 +3,13 @@ on:
repository_dispatch:
types: update_zh
permissions: {}
jobs:
update_zh:
permissions:
contents: write # to create branch (peter-evans/create-pull-request)
pull-requests: write # to create a PR (peter-evans/create-pull-request)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+5
View File
@@ -3,8 +3,13 @@ on:
repository_dispatch:
types: update_zhc
permissions: {}
jobs:
update_zhc:
permissions:
contents: write # to create branch (peter-evans/create-pull-request)
pull-requests: write # to create a PR (peter-evans/create-pull-request)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
+1 -1
View File
@@ -54,7 +54,7 @@ Zigbee2MQTT integrates well with (almost) every home automation solution because
### [Home Assistant](https://www.home-assistant.io/)
- [Home Assistant](https://www.home-assistant.io/hassio/): Using [the official addon](https://github.com/zigbee2mqtt/hassio-zigbee2mqtt)
- Generic install or Hassbian: Using instructions [here](https://www.zigbee2mqtt.io/guide/usage/integrations/home_assistant.html)
- Generic install: using instructions [here](https://www.zigbee2mqtt.io/guide/usage/integrations/home_assistant.html)
<img align="left" height="100px" width="100px" src="https://user-images.githubusercontent.com/2734836/47615848-b8dd8700-dabd-11e8-9d77-175002dd8987.png">
+3 -1
View File
@@ -1,4 +1,4 @@
FROM node:16-alpine3.15 as base
FROM node:18-alpine3.16 as base
WORKDIR /app
RUN apk add --no-cache tzdata eudev tini
@@ -28,5 +28,7 @@ RUN mkdir /app/data
ARG COMMIT
RUN echo "$COMMIT" > dist/.hash
ENV NODE_ENV production
ENTRYPOINT ["docker-entrypoint.sh"]
CMD [ "/sbin/tini", "--", "node", "index.js"]
+9 -5
View File
@@ -1,5 +1,3 @@
require('core-js/features/object/from-entries');
require('core-js/features/array/flat');
const semver = require('semver');
const engines = require('./package.json').engines;
const fs = require('fs');
@@ -120,10 +118,16 @@ async function handleQuit() {
}
}
if (process.argv.length === 3 && process.argv[2] === 'writehash') {
writeHash();
if (require.main === module || require.main.filename.endsWith(path.sep + 'cli.js')) {
if (process.argv.length === 3 && process.argv[2] === 'writehash') {
writeHash();
} else {
process.on('SIGINT', handleQuit);
process.on('SIGTERM', handleQuit);
start();
}
} else {
process.on('SIGINT', handleQuit);
process.on('SIGTERM', handleQuit);
start();
module.exports = {start};
}
+4 -2
View File
@@ -39,7 +39,7 @@ const AllExtensions = [
type ExtensionArgs = [Zigbee, MQTT, State, PublishEntityState, EventBus,
(enable: boolean, name: string) => Promise<void>, () => void, (extension: Extension) => Promise<void>];
class Controller {
export class Controller {
private eventBus: EventBus;
private zigbee: Zigbee;
private state: State;
@@ -49,7 +49,7 @@ class Controller {
private extensions: Extension[];
private extensionArgs: ExtensionArgs;
constructor(restartCallback: () => void, exitCallback: (code: number) => void) {
constructor(restartCallback: () => void, exitCallback: (code: number, restart: boolean) => void) {
logger.init();
this.eventBus = new EventBus( /* istanbul ignore next */ (error) => {
logger.error(`Error: ${error.message}`);
@@ -163,6 +163,8 @@ class Controller {
this.eventBus.onLastSeenChanged(this,
(data) => utils.publishLastSeen(data, settings.get(), false, this.publishEntityState));
logger.info(`Zigbee2MQTT started!`);
}
@bind async enableDisableExtension(enable: boolean, name: string): Promise<void> {
+16 -2
View File
@@ -68,7 +68,8 @@ const reportClusters: {[s: string]:
type PollOnMessage = {
cluster: {[s: string]: {type: string, data: KeyValue}[]}
read: {cluster: string, attributes: string[], attributesForEndpoint?: (endpoint: zh.Endpoint) => Promise<string[]>}
manufacturerIDs: number[]
manufacturerIDs: number[],
manufacturerNames: string [],
}[];
const pollOnMessage: PollOnMessage = [
@@ -102,6 +103,10 @@ const pollOnMessage: PollOnMessage = [
zigbeeHersdman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
zigbeeHersdman.Zcl.ManufacturerCode.TELINK,
],
manufacturerNames: [
'GLEDOPTO',
'Trust International B.V.\u0000',
],
},
{
cluster: {
@@ -133,6 +138,10 @@ const pollOnMessage: PollOnMessage = [
zigbeeHersdman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
zigbeeHersdman.Zcl.ManufacturerCode.TELINK,
],
manufacturerNames: [
'GLEDOPTO',
'Trust International B.V.\u0000',
],
},
{
cluster: {
@@ -160,6 +169,10 @@ const pollOnMessage: PollOnMessage = [
zigbeeHersdman.Zcl.ManufacturerCode.MUELLER_LICHT_INT,
zigbeeHersdman.Zcl.ManufacturerCode.TELINK,
],
manufacturerNames: [
'GLEDOPTO',
'Trust International B.V.\u0000',
],
},
];
@@ -456,7 +469,8 @@ export default class Bind extends Extension {
for (const endpoint of toPoll) {
for (const poll of polls) {
if (!poll.manufacturerIDs.includes(endpoint.getDevice().manufacturerID) ||
if ((!poll.manufacturerIDs.includes(endpoint.getDevice().manufacturerID) &&
!poll.manufacturerNames.includes(endpoint.getDevice().manufacturerName)) ||
!endpoint.supportsInputCluster(poll.read.cluster)) {
continue;
}
+3 -1
View File
@@ -162,7 +162,9 @@ export default class Bridge extends Extension {
};
cleanupDeleted(message.options, diff.deleted);
const newSettings = objectAssignDeep({}, diff.added, diff.updated, diff.deleted);
// objectAssignDeep requires object prototype which is missing from detailedDiff, therefore clone
const newSettings = objectAssignDeep({}, utils.clone(diff.added), utils.clone(diff.updated),
utils.clone(diff.deleted));
// deep-object-diff converts arrays to objects, set original array back here
const convertBackArray = (before: KeyValue, after: KeyValue): void => {
+55 -15
View File
@@ -111,7 +111,7 @@ export default class HomeAssistant extends Extension {
}
private exposeToConfig(exposes: zhc.DefinitionExpose[], entityType: 'device' | 'group',
definition?: zhc.Definition, definitionExposes?: zhc.DefinitionExpose[]): DiscoveryEntry[] {
allExposes: zhc.DefinitionExpose[], definition?: zhc.Definition): DiscoveryEntry[] {
// For groups an array of exposes (of the same type) is passed, this is to determine e.g. what features
// to use for a bulb (e.g. color_xy/color_temp)
assert(entityType === 'group' || exposes.length === 1, 'Multiple exposes for device not allowed');
@@ -171,10 +171,11 @@ export default class HomeAssistant extends Extension {
discoveryEntry.discovery_payload.min_mireds = min;
}
const effect = definitionExposes?.find((e) => e.type === 'enum' && e.name === 'effect');
if (effect) {
const effects = utils.arrayUnique(utils.flatten(
allExposes.filter((e) => e.type === 'enum' && e.name === 'effect').map((e) => e.values)));
if (effects.length) {
discoveryEntry.discovery_payload.effect = true;
discoveryEntry.discovery_payload.effect_list = effect.values;
discoveryEntry.discovery_payload.effect_list = effects;
}
discoveryEntries.push(discoveryEntry);
@@ -320,6 +321,9 @@ export default class HomeAssistant extends Extension {
if (tempCalibration.value_min != null) discoveryEntry.discovery_payload.min = tempCalibration.value_min;
if (tempCalibration.value_max != null) discoveryEntry.discovery_payload.max = tempCalibration.value_max;
if (tempCalibration.value_step != null) {
discoveryEntry.discovery_payload.step = tempCalibration.value_step;
}
discoveryEntries.push(discoveryEntry);
}
@@ -386,9 +390,9 @@ export default class HomeAssistant extends Extension {
?.features.find((f) => f.name === 'position');
const tilt = exposes.find((expose) => expose.features.find((e) => e.name === 'tilt'))
?.features.find((f) => f.name === 'tilt');
const motorState = definitionExposes?.find((e) => e.type === 'enum' && e.name === 'motor_state' &&
const motorState = allExposes?.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 running = allExposes?.find((e) => e.type === 'binary' && e.name === 'running');
const discoveryEntry: DiscoveryEntry = {
type: 'cover',
@@ -550,8 +554,10 @@ export default class HomeAssistant extends Extension {
tamper: {device_class: 'tamper'},
temperature_scale: {entity_category: 'config', icon: 'mdi:temperature-celsius'},
test: {entity_category: 'diagnostic', icon: 'mdi:test-tube'},
valve_state: {device_class: 'opening'},
vibration: {device_class: 'vibration'},
water_leak: {device_class: 'moisture'},
window: {device_class: 'window'},
};
/**
@@ -611,6 +617,8 @@ export default class HomeAssistant extends Extension {
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_heating_countdown: {device_class: 'duration'},
boost_heating_countdown_time_set: {entity_category: 'config', icon: 'mdi:timer'},
boost_time: {entity_category: 'config', icon: 'mdi:timer'},
calibration: {entity_category: 'config', icon: 'mdi:wrench-clock'},
calibration_time: {entity_category: 'config', icon: 'mdi:wrench-clock'},
@@ -663,9 +671,10 @@ export default class HomeAssistant extends Extension {
state_class: 'measurement',
},
local_temperature: {device_class: 'temperature', state_class: 'measurement'},
max_temperature: {entity_category: 'config', icon: 'mdi:thermometer'},
max_temperature_limit: {entity_category: 'config', icon: 'mdi:thermometer'},
min_temperature: {entity_category: 'config', icon: 'mdi:thermometer'},
max_temperature: {entity_category: 'config', icon: 'mdi:thermometer-high'},
max_temperature_limit: {entity_category: 'config', icon: 'mdi:thermometer-high'},
min_temperature_limit: {entity_category: 'config', icon: 'mdi:thermometer-low'},
min_temperature: {entity_category: 'config', icon: 'mdi:thermometer-low'},
measurement_poll_interval: {entity_category: 'config', icon: 'mdi:clock-out'},
occupancy_timeout: {entity_category: 'config', icon: 'mdi:timer'},
pm10: {device_class: 'pm10', state_class: 'measurement'},
@@ -756,6 +765,7 @@ export default class HomeAssistant extends Extension {
command_topic_prefix: endpoint,
command_topic_postfix: firstExpose.property,
...(firstExpose.unit && {unit_of_measurement: firstExpose.unit}),
...(firstExpose.value_step && {step: firstExpose.value_step}),
...lookup[firstExpose.name],
},
};
@@ -802,6 +812,7 @@ export default class HomeAssistant extends Extension {
sound_volume: {entity_category: 'config', icon: 'mdi:volume-high'},
status: {icon: 'mdi:state-machine'},
switch_type: {entity_category: 'config', icon: 'mdi:tune'},
temperature_sensor_select: {entity_category: 'config', icon: 'mdi:home-thermometer'},
thermostat_unit: {entity_category: 'config', icon: 'mdi:thermometer'},
volume: {entity_category: 'config', icon: 'mdi: volume-high'},
week: {entity_category: 'config', icon: 'mdi:calendar-clock'},
@@ -844,10 +855,11 @@ export default class HomeAssistant extends Extension {
},
});
}
} else if (firstExpose.type === 'text' || firstExpose.type === 'composite') {
} else if (firstExpose.type === 'text' || firstExpose.type === 'composite' || firstExpose.type === 'list') {
if (firstExpose.access & ACCESS_STATE) {
const lookup: {[s: string]: KeyValue} = {
action: {icon: 'mdi:gesture-double-tap'},
programming_mode: {icon: 'mdi:calendar-clock'},
};
const discoveryEntry: DiscoveryEntry = {
@@ -980,7 +992,7 @@ export default class HomeAssistant extends Extension {
if (isDevice) {
const exposes = entity.exposes(); // avoid calling it hundred of times/s
for (const expose of exposes) {
configs.push(...this.exposeToConfig([expose], 'device', entity.definition, exposes));
configs.push(...this.exposeToConfig([expose], 'device', exposes, entity.definition));
}
for (const mapping of legacyMapping) {
@@ -997,10 +1009,13 @@ export default class HomeAssistant extends Extension {
}
} else { // group
const exposesByType: {[s: string]: zhc.DefinitionExpose[]} = {};
const allExposes: zhc.DefinitionExpose[] = [];
entity.zh.members.map((e) => this.zigbee.resolveEntity(e.getDevice()) as Device)
.filter((d) => d.definition).forEach((device) => {
for (const expose of device.exposes().filter((e) => groupSupportedTypes.includes(e.type))) {
const exposes = device.exposes();
allExposes.push(...exposes);
for (const expose of exposes.filter((e) => groupSupportedTypes.includes(e.type))) {
let key = expose.type;
if (['switch', 'lock', 'cover'].includes(expose.type) && expose.endpoint) {
// A device can have multiple of these types which have to discovered seperately.
@@ -1015,7 +1030,7 @@ export default class HomeAssistant extends Extension {
});
configs = [].concat(...Object.values(exposesByType)
.map((exposes) => this.exposeToConfig(exposes, 'group')));
.map((exposes) => this.exposeToConfig(exposes, 'group', allExposes)));
}
if (isDevice && settings.get().advanced.last_seen !== 'disable') {
@@ -1061,12 +1076,29 @@ export default class HomeAssistant extends Extension {
payload_on: true,
payload_off: false,
value_template: `{{ value_json['update']['state'] == "available" }}`,
enabled_by_default: true,
enabled_by_default: false,
device_class: 'update',
entity_category: 'diagnostic',
},
};
configs.push(updateAvailableSensor);
const updateSensor: DiscoveryEntry = {
type: 'update',
object_id: 'update',
mockProperties: [{property: 'update', value: {state: null}}],
discovery_payload: {
entity_picture: 'https://github.com/Koenkk/zigbee2mqtt/raw/master/images/logo.png',
latest_version_topic: true,
state_topic: true,
device_class: 'firmware',
command_topic: `${settings.get().mqtt.base_topic}/bridge/request/device/ota_update/update`,
payload_install: `{"id": "${entity.ieeeAddr}"}`,
value_template: `{{ value_json['update']['installed_version'] }}`,
latest_version_template: `{% if value_json['update']['state'] == "available" %}{{ 'newer' }}` +
`{% else %}{{ value_json['update']['installed_version'] }}{% endif %}`,
},
};
configs.push(updateSensor);
}
if (isDevice && entity.options.hasOwnProperty('legacy') && !entity.options.legacy) {
@@ -1178,7 +1210,7 @@ export default class HomeAssistant extends Extension {
delete payload.command_topic_postfix;
const commandTopic = `${baseTopic}/${commandTopicPrefix}set${commandTopicPostfix}`;
if (payload.command_topic) {
if (payload.command_topic && typeof payload.command_topic !== 'string') {
payload.command_topic = commandTopic;
}
@@ -1233,6 +1265,10 @@ export default class HomeAssistant extends Extension {
payload.fan_mode_state_topic = stateTopic;
}
if (payload.latest_version_topic) {
payload.latest_version_topic = stateTopic;
}
if (payload.fan_mode_command_topic) {
payload.fan_mode_command_topic = `${baseTopic}/${commandTopicPrefix}set/fan_mode`;
}
@@ -1424,6 +1460,10 @@ export default class HomeAssistant extends Extension {
message.color.s = message.color.saturation;
}
}
if (entity.isDevice() && entity.definition?.ota && message.hasOwnProperty('update')) {
message['update']['installed_version'] = entity.zh.softwareBuildID || 'unknown';
}
}
private getEncodedBaseTopic(): string {
+2 -4
View File
@@ -112,13 +112,11 @@ export default class OTAUpdate extends Extension {
}
}
// Respond to the OTA request:
// - In case we don't support OTA: respond with NO_IMAGE_AVAILABLE (0x98) (so the client stops requesting OTAs)
// - In case we do support OTA: respond with ABORT (0x95) as we don't want to update now.
// Respond to the OTA request: respond with NO_IMAGE_AVAILABLE (0x98) (so the client stops requesting OTAs)
const endpoint = data.device.zh.endpoints.find((e) => e.supportsOutputCluster('genOta'));
if (endpoint) {
// Some devices send OTA requests without defining OTA cluster as input cluster.
await endpoint.commandResponse('genOta', 'queryNextImageResponse', {status: supportsOTA ? 0x95 : 0x98});
await endpoint.commandResponse('genOta', 'queryNextImageResponse', {status: 0x98});
}
}
+1 -1
View File
@@ -100,7 +100,7 @@ declare global {
interface DefinitionExpose {
type: string, name?: string, features?: DefinitionExposeFeature[],
endpoint?: string, values?: string[], value_off?: string, value_on?: string,
endpoint?: string, values?: string[], value_off?: string, value_on?: string, value_step?: number,
access: number, property: string, unit?: string,
value_min?: number, value_max?: number}
+1 -1
View File
@@ -14,7 +14,7 @@ function load(): void {
load();
function joinPath(file: string): string {
return path.join(dataPath, file);
return path.resolve(dataPath, file);
}
function getPath(): string {
+1 -1
View File
@@ -842,7 +842,7 @@
"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"
"description": "The user-defined device icon for the frontend. It can be a full URL link to an image (e.g. https://SOME.SITE/MODEL123.jpg) (you cannot use a path to a local file) or base64 encoded data URL (e.g. image/svg+xml;base64,PHN2ZyB3aW....R0aD)"
},
"homeassistant": {
"type": ["object", "null"],
+20 -9
View File
@@ -187,6 +187,20 @@ function loadSettingsWithDefaults(): void {
_settingsWithDefaults.whitelist && _settingsWithDefaults.passlist.push(..._settingsWithDefaults.whitelist);
}
function parseValueRef(text: string): {filename: string, key: string} | null {
const match = /!(.*) (.*)/g.exec(text);
if (match) {
let filename = match[1];
// This is mainly for backward compatibility.
if (!filename.endsWith('.yaml') && !filename.endsWith('.yml')) {
filename += '.yaml';
}
return {filename, key: match[2]};
} else {
return null;
}
}
function write(): void {
const settings = getInternalSettings();
const toWrite: KeyValue = objectAssignDeep({}, settings);
@@ -203,9 +217,9 @@ function write(): void {
['frontend', 'auth_token'],
]) {
if (actual[path[0]] && actual[path[0]][path[1]]) {
const match = /!(.*) (.*)/g.exec(actual[path[0]][path[1]]);
if (match) {
yaml.updateIfChanged(data.joinPath(`${match[1]}.yaml`), match[2], toWrite[path[0]][path[1]]);
const ref = parseValueRef(actual[path[0]][path[1]]);
if (ref) {
yaml.updateIfChanged(data.joinPath(ref.filename), ref.key, toWrite[path[0]][path[1]]);
toWrite[path[0]][path[1]] = actual[path[0]][path[1]];
}
}
@@ -314,12 +328,9 @@ function read(): Settings {
// Read !secret MQTT username and password if set
// eslint-disable-next-line
const interpetValue = (value: any): any => {
const re = /!(.*) (.*)/g;
const match = re.exec(value);
if (match) {
const file = data.joinPath(`${match[1]}.yaml`);
const key = match[2];
return yaml.read(file)[key];
const ref = parseValueRef(value);
if (ref) {
return yaml.read(data.joinPath(ref.filename))[ref.key];
} else {
return value;
}
+14 -2
View File
@@ -77,7 +77,7 @@ async function getZigbee2MQTTVersion(includeCommitHash=true): Promise<{commitHas
}
async function getDependencyVersion(depend: string): Promise<{version: string}> {
const packageJSON = await import(path.join(__dirname, '..', '..', 'node_modules', depend, 'package.json'));
const packageJSON = await import(path.join(require.resolve(depend), '..', '..', 'package.json'));
const version = packageJSON.version;
return {version};
}
@@ -314,6 +314,14 @@ function isEndpoint(obj: unknown): obj is zh.Endpoint {
return obj.constructor.name.toLowerCase() === 'endpoint';
}
function flatten<Type>(arr: Type[][]): Type[] {
return [].concat(...arr);
}
function arrayUnique<Type>(arr: Type[]): Type[] {
return [...new Set(arr)];
}
function isZHGroup(obj: unknown): obj is zh.Group {
return obj.constructor.name.toLowerCase() === 'group';
}
@@ -351,11 +359,15 @@ function filterProperties(filter: string[], data: KeyValue): void {
}
}
function clone(obj: KeyValue): KeyValue {
return JSON.parse(JSON.stringify(obj));
}
export default {
endpointNames, capitalize, getZigbee2MQTTVersion, getDependencyVersion, formatDate, objectHasProperties,
equalsPartial, getObjectProperty, getResponse, parseJSON, loadModuleFromText, loadModuleFromFile,
getExternalConvertersDefinitions, removeNullPropertiesFromObject, toNetworkAddressHex, toSnakeCase,
parseEntityID, isEndpoint, isZHGroup, hours, minutes, seconds, validateFriendlyName, sleep,
sanitizeImageParameter, isAvailabilityEnabledForEntity, publishLastSeen, availabilityPayload,
getAllFiles, filterProperties,
getAllFiles, filterProperties, flatten, arrayUnique, clone,
};
+1261 -2378
View File
File diff suppressed because it is too large Load Diff
+21 -22
View File
@@ -1,6 +1,6 @@
{
"name": "zigbee2mqtt",
"version": "1.28.0",
"version": "1.28.3",
"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": "^14 || ^16 || ^18"
"node": "^14 || ^16 || ^18 || ^19"
},
"keywords": [
"xiaomi",
@@ -35,12 +35,11 @@
},
"homepage": "https://koenkk.github.io/zigbee2mqtt",
"dependencies": {
"ajv": "^8.11.0",
"ajv": "^8.11.2",
"bind-decorator": "^1.0.11",
"connect-gzip-static": "2.1.1",
"core-js": "^3.25.2",
"debounce": "^1.2.1",
"deep-object-diff": "^1.1.7",
"deep-object-diff": "^1.1.9",
"fast-deep-equal": "^3.1.3",
"finalhandler": "^1.2.0",
"git-last-commit": "^1.0.1",
@@ -53,39 +52,39 @@
"mqtt": "4.3.7",
"object-assign-deep": "^0.4.0",
"rimraf": "^3.0.2",
"semver": "^7.3.7",
"semver": "^7.3.8",
"source-map-support": "^0.5.21",
"uri-js": "^4.4.1",
"winston": "^3.8.2",
"winston-syslog": "^2.6.0",
"winston-syslog": "^2.7.0",
"winston-transport": "^4.5.0",
"ws": "^8.9.0",
"zigbee-herdsman": "0.14.62",
"zigbee-herdsman-converters": "14.0.635",
"zigbee2mqtt-frontend": "0.6.112"
"ws": "^8.11.0",
"zigbee-herdsman": "0.14.76",
"zigbee-herdsman-converters": "14.0.680",
"zigbee2mqtt-frontend": "0.6.119"
},
"devDependencies": {
"@babel/core": "^7.19.1",
"@babel/plugin-proposal-decorators": "^7.19.1",
"@babel/preset-env": "^7.19.1",
"@babel/core": "^7.20.2",
"@babel/plugin-proposal-decorators": "^7.20.2",
"@babel/preset-env": "^7.20.2",
"@babel/preset-typescript": "^7.18.6",
"@types/debounce": "^1.2.1",
"@types/finalhandler": "^1.2.0",
"@types/humanize-duration": "^3.27.1",
"@types/jest": "^29.0.3",
"@types/jest": "^29.2.3",
"@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.38.0",
"@typescript-eslint/parser": "^5.38.0",
"babel-jest": "^29.0.3",
"eslint": "^8.24.0",
"@typescript-eslint/eslint-plugin": "^5.44.0",
"@typescript-eslint/parser": "^5.44.0",
"babel-jest": "^29.3.1",
"eslint": "^8.28.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-jest": "^27.0.4",
"jest": "^29.0.3",
"eslint-plugin-jest": "^27.1.6",
"jest": "^29.3.1",
"tmp": "^0.2.1",
"typescript": "^4.8.3"
"typescript": "^4.9.3"
},
"jest": {
"coverageThreshold": {
+22
View File
@@ -0,0 +1,22 @@
const assert = require('assert');
const vm = require('vm');
const fs = require('fs');
const path = require('path');
const filename = process.argv[2];
const moduleCode = fs.readFileSync(filename);
const moduleFakePath = path.join(__dirname, 'externally-loaded.js');
const sandbox = {
require: require,
module: {},
console,
setTimeout,
clearTimeout,
setInterval,
clearInterval,
setImmediate,
clearImmediate,
};
vm.runInNewContext(moduleCode, sandbox, moduleFakePath);
const converter = sandbox.module.exports;
assert(!converter.toZigbee.includes(undefined));
assert(!converter.fromZigbee.includes(undefined));
+2 -2
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -19,6 +19,7 @@ describe('Data', () => {
const actual = data.getPath();
expect(actual).toBe(expected);
expect(data.joinPath('test')).toStrictEqual(path.join(expected, 'test'));
expect(data.joinPath('/test')).toStrictEqual(path.resolve(expected, '/test'));
delete process.env.ZIGBEE2MQTT_DATA;
data.testingOnlyReload();
});
+6 -1
View File
@@ -84,7 +84,12 @@ describe('User extensions', () => {
MQTT.events.message('zigbee2mqtt/bridge/request/extension/save', stringify({"name": "foo.js", "code": extensionCode}));
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/bridge/response/extension/save', stringify({"data":{},"error":"Unexpected identifier","status":"error"}), { retain: false, qos: 0 }, expect.any(Function));
expect(MQTT.publish).toHaveBeenCalledWith('zigbee2mqtt/bridge/response/extension/save', expect.any(String), { retain: false, qos: 0 }, expect.any(Function));
const payload = JSON.parse(MQTT.publish.mock.calls[0][1]);
expect(payload).toEqual(
expect.objectContaining({"data":{},"status":"error"})
);
expect(payload.error).toMatch("Unexpected identifier");
});
it('Removes user extension', async () => {
+2 -2
View File
@@ -140,7 +140,7 @@ describe('Frontend', () => {
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb_color',
stringify({state: 'ON', linkquality: null, update_available: null, update: {state: null}}),
stringify({state: 'ON', power_on_behavior:null, linkquality: null, update_available: null, update: {state: null, installed_version: "unknown"}}),
{ retain: false, qos: 0 },
expect.any(Function)
);
@@ -151,7 +151,7 @@ describe('Frontend', () => {
// Received message on socket
expect(mockWSClient.implementation.send).toHaveBeenCalledTimes(1);
expect(mockWSClient.implementation.send).toHaveBeenCalledWith(stringify({topic: 'bulb_color', payload: {state: 'ON', linkquality: null, update_available: null, update: {state: null}}}));
expect(mockWSClient.implementation.send).toHaveBeenCalledWith(stringify({topic: 'bulb_color', payload: {state: 'ON', power_on_behavior:null, linkquality: null, update_available: null, update: {state: null, installed_version: "unknown"}}}));
// Shouldnt set when not ready
mockWSClient.implementation.send.mockClear();
+46 -9
View File
@@ -98,6 +98,15 @@ describe('HomeAssistant extension', () => {
"xy",
"color_temp"
],
"effect":true,
"effect_list":[
"blink",
"breathe",
"okay",
"channel_change",
"finish_effect",
"stop_effect"
],
"unique_id":"9_light_zigbee2mqtt"
};
@@ -770,7 +779,8 @@ describe('HomeAssistant extension', () => {
"boost",
"complex",
"comfort",
"eco"
"eco",
"away"
],
"preset_mode_value_template":"{{ value_json.preset }}",
"preset_mode_state_topic":"zigbee2mqtt/TS0601_thermostat",
@@ -946,7 +956,7 @@ describe('HomeAssistant extension', () => {
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb_color',
stringify({"color":{"hue": 0, "saturation": 100, "h": 0, "s": 100}, "color_mode": "hs", "linkquality": null, "state": null, "update_available": null, "update": {"state": null}}),
stringify({"color":{"hue": 0, "saturation": 100, "h": 0, "s": 100}, "color_mode": "hs", "linkquality": null, "state": null, "update_available": null, "power_on_behavior":null, "update": {"state": null, "installed_version": "unknown"}}),
{ retain: false, qos: 0 },
expect.any(Function),
);
@@ -962,7 +972,7 @@ describe('HomeAssistant extension', () => {
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb_color',
stringify({"color": {"x": 0.4576,"y": 0.41}, "color_mode": "xy", "linkquality": null,"state": null, "update_available": null, "update": {"state": null}}),
stringify({"color": {"x": 0.4576,"y": 0.41}, "color_mode": "xy", "linkquality": null,"state": null, "update_available": null, "power_on_behavior":null, "update": {"state": null, "installed_version": "unknown"}}),
{ retain: false, qos: 0 },
expect.any(Function),
);
@@ -978,7 +988,7 @@ describe('HomeAssistant extension', () => {
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb_color',
stringify({"linkquality": null,"state": "ON", "update_available": null, "update": {"state": null}}),
stringify({"linkquality": null,"state": "ON", "update_available": null, "power_on_behavior": null, "update": {"state": null, "installed_version": "unknown"}}),
{ retain: false, qos: 0 },
expect.any(Function),
);
@@ -1066,13 +1076,13 @@ describe('HomeAssistant extension', () => {
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb',
stringify({"state":"ON","brightness":50,"color_temp":370,"linkquality":99,"power_on_behavior":null, "update_available": null, "update": {"state": null}}),
stringify({"state":"ON","brightness":50,"color_temp":370,"linkquality":99,"power_on_behavior":null, "update_available": null, "update": {"state": null, "installed_version": "unknown"}}),
{ retain: true, qos: 0 },
expect.any(Function)
);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/remote',
stringify({"action":null,"action_duration":null,"battery":null,"brightness":255,"linkquality":null, "update_available": null, "update": {"state": null}}),
stringify({"action":null,"action_duration":null,"battery":null,"brightness":255,"linkquality":null, "update_available": null, "update": {"state": null, "installed_version": "unknown"}}),
{ retain: true, qos: 0 },
expect.any(Function)
);
@@ -1096,13 +1106,13 @@ describe('HomeAssistant extension', () => {
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb',
stringify({"state":"ON","brightness":50,"color_temp":370,"linkquality":99,"power_on_behavior":null, "update_available": null, "update": {"state": null}}),
stringify({"state":"ON","brightness":50,"color_temp":370,"linkquality":99,"power_on_behavior":null, "update_available": null, "update": {"state": null, "installed_version": "unknown"}}),
{ retain: true, qos: 0 },
expect.any(Function)
);
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/remote',
stringify({"action":null,"action_duration":null,"battery":null,"brightness":255,"linkquality":null, "update_available": null, "update": {"state": null}}),
stringify({"action":null,"action_duration":null,"battery":null,"brightness":255,"linkquality":null, "update_available": null, "update": {"state": null, "installed_version": "unknown"}}),
{ retain: true, qos: 0 },
expect.any(Function)
);
@@ -1306,6 +1316,15 @@ describe('HomeAssistant extension', () => {
"xy",
"color_temp"
],
"effect":true,
"effect_list":[
"blink",
"breathe",
"okay",
"channel_change",
"finish_effect",
"stop_effect"
],
"unique_id":"9_light_zigbee2mqtt"
};
@@ -1369,7 +1388,7 @@ describe('HomeAssistant extension', () => {
"payload_on":true,
"payload_off":false,
"value_template":`{{ value_json['update']['state'] == "available" }}`,
"enabled_by_default": true,
"enabled_by_default": false,
"state_topic":"zigbee2mqtt/bulb",
"json_attributes_topic":"zigbee2mqtt/bulb",
"name":"bulb update available",
@@ -1822,6 +1841,15 @@ describe('HomeAssistant extension', () => {
"xy",
"color_temp"
],
"effect":true,
"effect_list":[
"blink",
"breathe",
"okay",
"channel_change",
"finish_effect",
"stop_effect"
],
"unique_id":"9_light_zigbee2mqtt"
};
@@ -1858,6 +1886,15 @@ describe('HomeAssistant extension', () => {
"xy",
"color_temp"
],
"effect":true,
"effect_list":[
"blink",
"breathe",
"okay",
"channel_change",
"finish_effect",
"stop_effect"
],
"unique_id":"9_light_zigbee2mqtt"
};
+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, 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"}]};
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, power_on_behavior, 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, 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 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, power_on_behavior, 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);
});
+2 -2
View File
@@ -258,7 +258,7 @@ describe('OTA update', () => {
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(logger.info).toHaveBeenCalledWith(`Update available for 'bulb'`);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x95});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98});
// Should not request again when device asks again after a short time
await zigbeeHerdsman.events.message(payload);
@@ -313,7 +313,7 @@ describe('OTA update', () => {
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledTimes(1);
expect(mapped.ota.isUpdateAvailable).toHaveBeenCalledWith(device, logger, {"imageType": 12382});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledTimes(1);
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x95});
expect(device.endpoints[0].commandResponse).toHaveBeenCalledWith("genOta", "queryNextImageResponse", {"status": 0x98});
expect(MQTT.publish).toHaveBeenCalledWith(
'zigbee2mqtt/bulb',
stringify({"update_available":false,"update":{"state":"idle"}}),
+2 -2
View File
@@ -419,7 +419,7 @@ describe('Receive', () => {
const data = {instantaneousDemand:496,currentSummDelivered:[0,6648]}
const SP600_NEW = zigbeeHerdsman.devices.SP600_NEW;
await zigbeeHerdsman.events.message({data, cluster: 'seMetering', device: SP600_NEW, endpoint: SP600_NEW.getEndpoint(1), type: 'attributeReport', linkquality: 10});
await zigbeeHerdsman.events.message({data, cluster: 'seMetering', device: SP600_NEW, endpoint: SP600_NEW.getEndpoint(1), type: 'attributeReport', linkquality: 10, meta: {zclTransactionSequenceNumber: 1}});
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/SP600_NEW');
@@ -427,7 +427,7 @@ describe('Receive', () => {
MQTT.publish.mockClear();
const SP600_OLD = zigbeeHerdsman.devices.SP600_OLD;
await zigbeeHerdsman.events.message({data, cluster: 'seMetering', device: SP600_OLD, endpoint: SP600_OLD.getEndpoint(1), type: 'attributeReport', linkquality: 10});
await zigbeeHerdsman.events.message({data, cluster: 'seMetering', device: SP600_OLD, endpoint: SP600_OLD.getEndpoint(1), type: 'attributeReport', linkquality: 10, meta: {zclTransactionSequenceNumber: 2}});
await flushPromises();
expect(MQTT.publish).toHaveBeenCalledTimes(1);
expect(MQTT.publish.mock.calls[0][0]).toStrictEqual('zigbee2mqtt/SP600_OLD');
+1 -1
View File
@@ -199,7 +199,7 @@ describe('Settings', () => {
mqtt: {
server: '!secret server',
user: '!secret username',
password: '!secret password',
password: '!secret.yaml password',
},
advanced: {
network_key: '!secret network_key',