matterbridge-zigbee2mqtt 3.0.6 → 3.0.7-dev-20260220-9c00050

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -26,6 +26,26 @@ If you like this project and find it useful, please consider giving it a star on
26
26
 
27
27
  <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="120"></a>
28
28
 
29
+ ## [3.0.7] - 2026-02-20
30
+
31
+ ### Added
32
+
33
+ - [docker]: Add an example of docker_compose.yml. You need to provide your own certificates.
34
+ - [mosquitto]: Add an example of mosquitto configuration for ws:// wss:// mqtt:// mqtts:// mqtt+unix://. You need to provide your own certificates.
35
+ - [transition]: Add transition to groups. Thanks Robin (https://github.com/Luligu/matterbridge-zigbee2mqtt/issues/147).
36
+ - [transition]: Support decimal transition. Thanks Robin (https://github.com/Luligu/matterbridge-zigbee2mqtt/issues/150).
37
+
38
+ ### Changed
39
+
40
+ - [package]: Update dependencies.
41
+ - [package]: Bump package to `automator` v.3.0.8.
42
+ - [package]: Bump `node-persist-manager` to v.2.0.1.
43
+ - [package]: Bump `eslint` to v.10.0.0.
44
+ - [package]: Bump `typescript-eslint` to v.8.56.0.
45
+ - [eslint]: Use minimatch in ignores.
46
+
47
+ <a href="https://www.buymeacoffee.com/luligugithub"><img src="https://matterbridge.io/assets/bmc-button.svg" alt="Buy me a coffee" width="80"></a>
48
+
29
49
  ## [3.0.6] - 2026-02-07
30
50
 
31
51
  ### Changed
package/dist/entity.js CHANGED
@@ -247,8 +247,8 @@ export class ZigbeeEntity extends EventEmitter {
247
247
  }
248
248
  if (payload)
249
249
  this.cachePayload = { ...this.cachePayload, ...payload };
250
- if (this.transition && transitionTime && transitionTime / 10 >= 1)
251
- this.cachePayload['transition'] = Math.round(transitionTime / 10);
250
+ if (this.transition && transitionTime && transitionTime / 10 >= 0)
251
+ this.cachePayload['transition'] = transitionTime / 10;
252
252
  clearTimeout(this.cachePublishTimeout);
253
253
  this.cachePublishTimeout = setTimeout(() => {
254
254
  clearTimeout(this.cachePublishTimeout);
@@ -603,6 +603,7 @@ export class ZigbeeGroup extends ZigbeeEntity {
603
603
  platform.setSelectDevice(`group-${group.id}`, group.friendly_name, 'wifi');
604
604
  let useState = false;
605
605
  let useBrightness = false;
606
+ let useTransition = false;
606
607
  let useColor = false;
607
608
  let useColorTemperature = false;
608
609
  let minColorTemperature = 140;
@@ -657,6 +658,9 @@ export class ZigbeeGroup extends ZigbeeEntity {
657
658
  zigbeeGroup.log.debug(`- generic type ${CYAN}${expose.type}${db} expose name ${CYAN}${expose.name}${db} property ${CYAN}${expose.property}${db}`);
658
659
  }
659
660
  });
661
+ device.definition?.options.forEach((option) => {
662
+ useTransition = useTransition === true || option.name === 'transition' ? true : false;
663
+ });
660
664
  });
661
665
  zigbeeGroup.log.debug(`Group ${gn}${group.friendly_name}${rs}${db} switch: ${CYAN}${isSwitch}${db} light: ${CYAN}${isLight}${db} cover: ${CYAN}${isCover}${db} thermostat: ${CYAN}${isThermostat}${db}`);
662
666
  zigbeeGroup.log.debug(`Group ${gn}${group.friendly_name}${rs}${db} state: ${CYAN}${useState}${db} brightness: ${CYAN}${useBrightness}${db} color: ${CYAN}${useColor}${db} color_temp: ${CYAN}${useColorTemperature}${db} min: ${CYAN}${minColorTemperature}${db} max: ${CYAN}${maxColorTemperature}${db}`);
@@ -675,6 +679,9 @@ export class ZigbeeGroup extends ZigbeeEntity {
675
679
  deviceType = dimmableLight;
676
680
  zigbeeGroup.propertyMap.set('brightness', { name: 'brightness', type: 'light', endpoint: '' });
677
681
  }
682
+ if (useTransition) {
683
+ zigbeeGroup.transition = true;
684
+ }
678
685
  if (useColorTemperature) {
679
686
  deviceType = colorTemperatureLight;
680
687
  zigbeeGroup.propertyMap.set('color_temp', { name: 'color_temp', type: 'light', endpoint: '' });
@@ -731,13 +738,6 @@ export class ZigbeeGroup extends ZigbeeEntity {
731
738
  zigbeeGroup.bridgedDevice.addCommandHandler('off', zigbeeGroup.offCommandHandler.bind(zigbeeGroup));
732
739
  zigbeeGroup.bridgedDevice.addCommandHandler('toggle', zigbeeGroup.toggleCommandHandler.bind(zigbeeGroup));
733
740
  }
734
- for (const child of zigbeeGroup.bridgedDevice.getChildEndpoints()) {
735
- if (child.hasClusterServer(OnOff.Cluster.id)) {
736
- child.addCommandHandler('on', zigbeeGroup.onCommandHandler.bind(zigbeeGroup));
737
- child.addCommandHandler('off', zigbeeGroup.offCommandHandler.bind(zigbeeGroup));
738
- child.addCommandHandler('toggle', zigbeeGroup.toggleCommandHandler.bind(zigbeeGroup));
739
- }
740
- }
741
741
  }
742
742
  if (isLight) {
743
743
  if (useBrightness) {
@@ -795,7 +795,7 @@ export class ZigbeeGroup extends ZigbeeEntity {
795
795
  zigbeeGroup.noUpdate = true;
796
796
  zigbeeGroup.thermostatTimeout = setTimeout(() => {
797
797
  zigbeeGroup.noUpdate = false;
798
- }, zigbeeGroup.thermostatTimeoutTime);
798
+ }, zigbeeGroup.thermostatTimeoutTime).unref();
799
799
  }
800
800
  }, zigbeeGroup.log);
801
801
  zigbeeGroup.bridgedDevice.subscribeAttribute(ThermostatCluster.id, 'occupiedHeatingSetpoint', (newValue, oldValue) => {
@@ -806,7 +806,7 @@ export class ZigbeeGroup extends ZigbeeEntity {
806
806
  zigbeeGroup.noUpdate = true;
807
807
  zigbeeGroup.thermostatTimeout = setTimeout(() => {
808
808
  zigbeeGroup.noUpdate = false;
809
- }, zigbeeGroup.thermostatTimeoutTime);
809
+ }, zigbeeGroup.thermostatTimeoutTime).unref();
810
810
  }, zigbeeGroup.log);
811
811
  zigbeeGroup.bridgedDevice.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', (newValue, oldValue) => {
812
812
  zigbeeGroup.bridgedDevice?.log.info(`Thermostat occupiedCoolingSetpoint changed from ${oldValue / 100} to ${newValue / 100}`);
@@ -816,7 +816,7 @@ export class ZigbeeGroup extends ZigbeeEntity {
816
816
  zigbeeGroup.noUpdate = true;
817
817
  zigbeeGroup.thermostatTimeout = setTimeout(() => {
818
818
  zigbeeGroup.noUpdate = false;
819
- }, zigbeeGroup.thermostatTimeoutTime);
819
+ }, zigbeeGroup.thermostatTimeoutTime).unref();
820
820
  }, zigbeeGroup.log);
821
821
  }
822
822
  return zigbeeGroup;
@@ -1407,7 +1407,7 @@ export class ZigbeeDevice extends ZigbeeEntity {
1407
1407
  zigbeeDevice.noUpdate = true;
1408
1408
  zigbeeDevice.thermostatTimeout = setTimeout(() => {
1409
1409
  zigbeeDevice.noUpdate = false;
1410
- }, zigbeeDevice.thermostatTimeoutTime);
1410
+ }, zigbeeDevice.thermostatTimeoutTime).unref();
1411
1411
  }
1412
1412
  }, zigbeeDevice.log);
1413
1413
  if (zigbeeDevice.bridgedDevice.hasAttributeServer(ThermostatCluster.id, 'occupiedHeatingSetpoint'))
@@ -1420,7 +1420,7 @@ export class ZigbeeDevice extends ZigbeeEntity {
1420
1420
  zigbeeDevice.noUpdate = true;
1421
1421
  zigbeeDevice.thermostatTimeout = setTimeout(() => {
1422
1422
  zigbeeDevice.noUpdate = false;
1423
- }, zigbeeDevice.thermostatTimeoutTime);
1423
+ }, zigbeeDevice.thermostatTimeoutTime).unref();
1424
1424
  }, zigbeeDevice.log);
1425
1425
  if (zigbeeDevice.bridgedDevice.hasAttributeServer(ThermostatCluster.id, 'occupiedCoolingSetpoint'))
1426
1426
  zigbeeDevice.bridgedDevice.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', (value) => {
@@ -1432,7 +1432,7 @@ export class ZigbeeDevice extends ZigbeeEntity {
1432
1432
  zigbeeDevice.noUpdate = true;
1433
1433
  zigbeeDevice.thermostatTimeout = setTimeout(() => {
1434
1434
  zigbeeDevice.noUpdate = false;
1435
- }, zigbeeDevice.thermostatTimeoutTime);
1435
+ }, zigbeeDevice.thermostatTimeoutTime).unref();
1436
1436
  }, zigbeeDevice.log);
1437
1437
  }
1438
1438
  return zigbeeDevice;
@@ -395,7 +395,7 @@ export class Zigbee2MQTT extends EventEmitter {
395
395
  messageHandler(topic, payload) {
396
396
  if (topic.startsWith(this.mqttTopic + '/bridge/state')) {
397
397
  const payloadString = payload.toString();
398
- let data = {};
398
+ let data;
399
399
  if (payloadString.startsWith('{') && payloadString.endsWith('}')) {
400
400
  data = this.tryJsonParse(payload.toString());
401
401
  }
@@ -564,7 +564,7 @@ export class Zigbee2MQTT extends EventEmitter {
564
564
  return;
565
565
  }
566
566
  const payloadString = payload.toString();
567
- let data = {};
567
+ let data;
568
568
  if (payloadString.startsWith('{') && payloadString.endsWith('}')) {
569
569
  data = this.tryJsonParse(payload.toString());
570
570
  }
@@ -597,7 +597,7 @@ export class Zigbee2MQTT extends EventEmitter {
597
597
  return;
598
598
  }
599
599
  const payloadString = payload.toString();
600
- let data = {};
600
+ let data;
601
601
  if (payloadString.startsWith('{') && payloadString.endsWith('}')) {
602
602
  data = this.tryJsonParse(payload.toString());
603
603
  }
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "matterbridge-zigbee2mqtt",
3
- "version": "3.0.6",
3
+ "version": "3.0.7-dev-20260220-9c00050",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "matterbridge-zigbee2mqtt",
9
- "version": "3.0.6",
9
+ "version": "3.0.7-dev-20260220-9c00050",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "moment": "2.30.1",
13
13
  "mqtt": "5.15.0",
14
14
  "node-ansi-logger": "3.2.0",
15
- "node-persist-manager": "2.0.0"
15
+ "node-persist-manager": "2.0.1"
16
16
  },
17
17
  "engines": {
18
18
  "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
@@ -32,12 +32,12 @@
32
32
  }
33
33
  },
34
34
  "node_modules/@types/node": {
35
- "version": "25.2.1",
36
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.1.tgz",
37
- "integrity": "sha512-CPrnr8voK8vC6eEtyRzvMpgp3VyVRhgclonE7qYi6P9sXwYb59ucfrnmFBTaP0yUi8Gk4yZg/LlTJULGxvTNsg==",
35
+ "version": "25.3.0",
36
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz",
37
+ "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==",
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
- "undici-types": "~7.16.0"
40
+ "undici-types": "~7.18.0"
41
41
  }
42
42
  },
43
43
  "node_modules/@types/readable-stream": {
@@ -365,45 +365,36 @@
365
365
  "url": "https://www.buymeacoffee.com/luligugithub"
366
366
  }
367
367
  },
368
- "node_modules/node-persist": {
369
- "version": "4.0.4",
370
- "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-4.0.4.tgz",
371
- "integrity": "sha512-8sPAz/7tw1mCCc8xBG4f0wi+flHkSSgQeX998iQ75Pu27evA6UUWCjSE7xnrYTg2q33oU5leJ061EKPDv6BocQ==",
372
- "license": "MIT",
373
- "dependencies": {
374
- "p-limit": "^3.1.0"
375
- },
376
- "engines": {
377
- "node": ">=10.12.0"
378
- }
379
- },
380
368
  "node_modules/node-persist-manager": {
381
- "version": "2.0.0",
382
- "resolved": "https://registry.npmjs.org/node-persist-manager/-/node-persist-manager-2.0.0.tgz",
383
- "integrity": "sha512-jpgOqCCn4ZEnIr4WcvqkyyGmmLJarV6aUyBlDQdG1G84X9UUmOmI1W2OZtc9K0z375CYWhjtGEXaY7GXNiEOfA==",
384
- "license": "MIT",
369
+ "version": "2.0.1",
370
+ "resolved": "https://registry.npmjs.org/node-persist-manager/-/node-persist-manager-2.0.1.tgz",
371
+ "integrity": "sha512-uCnZd8YZSaaYkxhFdOtzC4Q0uix+z5Cfnq5RbL43OKKFvU/6Ms/kZtXWF4CrlhIX9CBKAPUtV7pIUQy85nYc8g==",
372
+ "hasShrinkwrap": true,
373
+ "license": "Apache-2.0",
385
374
  "dependencies": {
386
375
  "node-persist": "4.0.4"
387
376
  },
388
377
  "engines": {
389
- "node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
378
+ "node": ">=20.0.0 <21.0.0 || >=22.0.0 <23.0.0 || >=24.0.0 <25.0.0"
390
379
  },
391
380
  "funding": {
392
381
  "type": "buymeacoffee",
393
382
  "url": "https://www.buymeacoffee.com/luligugithub"
394
383
  }
395
384
  },
396
- "node_modules/number-allocator": {
397
- "version": "1.0.14",
398
- "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
399
- "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
385
+ "node_modules/node-persist-manager/node_modules/node-persist": {
386
+ "version": "4.0.4",
387
+ "resolved": "https://registry.npmjs.org/node-persist/-/node-persist-4.0.4.tgz",
388
+ "integrity": "sha512-8sPAz/7tw1mCCc8xBG4f0wi+flHkSSgQeX998iQ75Pu27evA6UUWCjSE7xnrYTg2q33oU5leJ061EKPDv6BocQ==",
400
389
  "license": "MIT",
401
390
  "dependencies": {
402
- "debug": "^4.3.1",
403
- "js-sdsl": "4.3.0"
391
+ "p-limit": "^3.1.0"
392
+ },
393
+ "engines": {
394
+ "node": ">=10.12.0"
404
395
  }
405
396
  },
406
- "node_modules/p-limit": {
397
+ "node_modules/node-persist-manager/node_modules/p-limit": {
407
398
  "version": "3.1.0",
408
399
  "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
409
400
  "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
@@ -418,6 +409,28 @@
418
409
  "url": "https://github.com/sponsors/sindresorhus"
419
410
  }
420
411
  },
412
+ "node_modules/node-persist-manager/node_modules/yocto-queue": {
413
+ "version": "0.1.0",
414
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
415
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
416
+ "license": "MIT",
417
+ "engines": {
418
+ "node": ">=10"
419
+ },
420
+ "funding": {
421
+ "url": "https://github.com/sponsors/sindresorhus"
422
+ }
423
+ },
424
+ "node_modules/number-allocator": {
425
+ "version": "1.0.14",
426
+ "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz",
427
+ "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==",
428
+ "license": "MIT",
429
+ "dependencies": {
430
+ "debug": "^4.3.1",
431
+ "js-sdsl": "4.3.0"
432
+ }
433
+ },
421
434
  "node_modules/process": {
422
435
  "version": "0.11.10",
423
436
  "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
@@ -530,9 +543,9 @@
530
543
  "license": "MIT"
531
544
  },
532
545
  "node_modules/undici-types": {
533
- "version": "7.16.0",
534
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
535
- "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
546
+ "version": "7.18.2",
547
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
548
+ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
536
549
  "license": "MIT"
537
550
  },
538
551
  "node_modules/util-deprecate": {
@@ -608,18 +621,6 @@
608
621
  "optional": true
609
622
  }
610
623
  }
611
- },
612
- "node_modules/yocto-queue": {
613
- "version": "0.1.0",
614
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
615
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
616
- "license": "MIT",
617
- "engines": {
618
- "node": ">=10"
619
- },
620
- "funding": {
621
- "url": "https://github.com/sponsors/sindresorhus"
622
- }
623
624
  }
624
625
  }
625
626
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "matterbridge-zigbee2mqtt",
3
- "version": "3.0.6",
3
+ "version": "3.0.7-dev-20260220-9c00050",
4
4
  "description": "Matterbridge zigbee2mqtt plugin",
5
5
  "author": "https://github.com/Luligu",
6
6
  "license": "Apache-2.0",
@@ -68,6 +68,10 @@
68
68
  "moment": "2.30.1",
69
69
  "mqtt": "5.15.0",
70
70
  "node-ansi-logger": "3.2.0",
71
- "node-persist-manager": "2.0.0"
71
+ "node-persist-manager": "2.0.1"
72
+ },
73
+ "overrides": {
74
+ "eslint": "10.0.0",
75
+ "@eslint/js": "10.0.1"
72
76
  }
73
77
  }