Compare commits

..
62 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
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
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
27 changed files with 1187 additions and 2146 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
@@ -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
+3 -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,16 +118,16 @@ async function handleQuit() {
}
}
if (require.main === module) {
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);
module.exports = { start };
module.exports = {start};
}
+2
View File
@@ -163,6 +163,8 @@ export 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 => {
+38 -10
View File
@@ -245,9 +245,7 @@ export default class HomeAssistant extends Extension {
discoveryEntry.discovery_payload.mode_state_topic = true;
discoveryEntry.discovery_payload.mode_state_template = `{{ value_json.${mode.property} }}`;
discoveryEntry.discovery_payload.modes = mode.values;
if (mode.access & ACCESS_SET) {
discoveryEntry.discovery_payload.mode_command_topic = true;
}
discoveryEntry.discovery_payload.mode_command_topic = true;
}
const state = firstExpose.features.find((f) => f.name === 'running_state');
@@ -556,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'},
};
/**
@@ -617,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'},
@@ -669,10 +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_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'},
@@ -853,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 = {
@@ -1073,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) {
@@ -1190,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;
}
@@ -1245,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`;
}
@@ -1436,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 {
+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;
}
+5 -1
View File
@@ -359,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, flatten, arrayUnique,
getAllFiles, filterProperties, flatten, arrayUnique, clone,
};
+1012 -2074
View File
File diff suppressed because it is too large Load Diff
+19 -20
View File
@@ -1,6 +1,6 @@
{
"name": "zigbee2mqtt",
"version": "1.28.2",
"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.26.0",
"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",
@@ -59,33 +58,33 @@
"winston": "^3.8.2",
"winston-syslog": "^2.7.0",
"winston-transport": "^4.5.0",
"ws": "^8.10.0",
"zigbee-herdsman": "0.14.68",
"zigbee-herdsman-converters": "14.0.657-hotfix.0",
"zigbee2mqtt-frontend": "0.6.114"
"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.6",
"@babel/plugin-proposal-decorators": "^7.20.0",
"@babel/preset-env": "^7.19.4",
"@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.2.0",
"@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.41.0",
"@typescript-eslint/parser": "^5.41.0",
"babel-jest": "^29.2.2",
"eslint": "^8.26.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.1.3",
"jest": "^29.2.2",
"eslint-plugin-jest": "^27.1.6",
"jest": "^29.3.1",
"tmp": "^0.2.1",
"typescript": "^4.8.4"
"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();
+10 -9
View File
@@ -779,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",
@@ -955,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),
);
@@ -971,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),
);
@@ -987,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),
);
@@ -1075,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)
);
@@ -1105,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)
);
@@ -1387,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",
+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
@@ -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',