matterbridge-zigbee2mqtt 2.6.0 → 2.7.0-dev-20250711-6299fe0
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 +25 -0
- package/README.md +8 -6
- package/dist/entity.js +289 -144
- package/dist/index.js +0 -1
- package/dist/platform.js +10 -30
- package/dist/zigbee2mqtt.js +5 -0
- package/npm-shrinkwrap.json +44 -32
- package/package.json +5 -5
- package/CODEOWNERS +0 -1
- package/tsconfig.jest.json +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -21,6 +21,31 @@ New device types:
|
|
|
21
21
|
|
|
22
22
|
If your controller has issues detecting the new device type, blacklist these devices, restart, wait 5 minutes that the controller removes them, remove the blacklist and restart again. This will create a new endpoint on the controller and the controllers will likely remove and recreate all the devices so make a backup of configurations (i.e. room assignements) and automations on the controller.
|
|
23
23
|
|
|
24
|
+
## [2.7.0] - 2025-07-10
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- [entity]: Added the ability to cache commands on a single light device or group. They will be executed in once. This helps to execute global controller scenes in large setups.
|
|
29
|
+
- [composed]: Added the ability to send commands on subenpoint also for ColorControl cluster.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- [package]: Updated dependencies.
|
|
34
|
+
- [package]: Updated package to Automator v. 2.0.2.
|
|
35
|
+
- [DevContainer]: Added support for the [**Matterbridge Plugin Dev Container**](https://github.com/Luligu/matterbridge/blob/dev/README-DEV.md#matterbridge-plugin-dev-container) with optimized named volumes for `matterbridge` and `node_modules`.
|
|
36
|
+
- [GitHub]: Added GitHub issue templates for bug reports and feature requests.
|
|
37
|
+
- [ESLint]: Refactored the flat config.
|
|
38
|
+
- [ESLint]: Added the plugins `eslint-plugin-promise`, `eslint-plugin-jsdoc`, and `@vitest/eslint-plugin`.
|
|
39
|
+
- [Jest]: Refactored the flat config.
|
|
40
|
+
- [Vitest]: Added Vitest for TypeScript project testing. It will replace Jest, which does not work correctly with ESM module mocks.
|
|
41
|
+
- [JSDoc]: Added missing JSDoc comments, including `@param` and `@returns` tags.
|
|
42
|
+
- [CodeQL]: Added CodeQL badge in the readme.
|
|
43
|
+
- [Codecov]: Added Codecov badge in the readme.
|
|
44
|
+
|
|
45
|
+
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
46
|
+
<img src="bmc-button.svg" alt="Buy me a coffee" width="80">
|
|
47
|
+
</a>
|
|
48
|
+
|
|
24
49
|
## [2.6.0] - 2025-06-07
|
|
25
50
|
|
|
26
51
|
### Added
|
package/README.md
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
[](https://hub.docker.com/r/luligu/matterbridge)
|
|
6
6
|
[](https://hub.docker.com/r/luligu/matterbridge)
|
|
7
7
|

|
|
8
|
+

|
|
9
|
+
[](https://codecov.io/gh/Luligu/matterbridge-zigbee2mqtt)
|
|
8
10
|
|
|
9
11
|
[](https://www.npmjs.com/package/matterbridge)
|
|
10
12
|
[](https://www.npmjs.com/package/matter-history)
|
|
@@ -13,7 +15,7 @@
|
|
|
13
15
|
|
|
14
16
|
---
|
|
15
17
|
|
|
16
|
-
Matterbridge zigbee2mqtt is a matterbridge production-level plugin that expose all zigbee2mqtt devices and groups to Matter.
|
|
18
|
+
Matterbridge zigbee2mqtt is a matterbridge production-level plugin that expose all zigbee2mqtt devices and groups to Matter. Scenes are supported too.
|
|
17
19
|
|
|
18
20
|
No hub or dedicated hardware needed.
|
|
19
21
|
|
|
@@ -37,7 +39,7 @@ on Windows:
|
|
|
37
39
|
npm install -g matterbridge --omit=dev
|
|
38
40
|
```
|
|
39
41
|
|
|
40
|
-
on Linux (you need the necessary permissions):
|
|
42
|
+
on Linux and macOS (you need the necessary permissions):
|
|
41
43
|
|
|
42
44
|
```
|
|
43
45
|
sudo npm install -g matterbridge --omit=dev
|
|
@@ -67,7 +69,7 @@ npm install -g matterbridge-zigbee2mqtt --omit=dev
|
|
|
67
69
|
matterbridge -add matterbridge-zigbee2mqtt
|
|
68
70
|
```
|
|
69
71
|
|
|
70
|
-
On linux:
|
|
72
|
+
On linux and macOS:
|
|
71
73
|
|
|
72
74
|
```
|
|
73
75
|
cd ~/Matterbridge
|
|
@@ -92,10 +94,10 @@ cd matterbridge-zigbee2mqtt
|
|
|
92
94
|
npm ci
|
|
93
95
|
npm run dev:link
|
|
94
96
|
npm run build
|
|
95
|
-
matterbridge -add
|
|
97
|
+
matterbridge -add .
|
|
96
98
|
```
|
|
97
99
|
|
|
98
|
-
On linux:
|
|
100
|
+
On linux and macOS:
|
|
99
101
|
|
|
100
102
|
```
|
|
101
103
|
cd ~/Matterbridge
|
|
@@ -104,7 +106,7 @@ cd matterbridge-zigbee2mqtt
|
|
|
104
106
|
npm ci
|
|
105
107
|
npm run dev:link
|
|
106
108
|
npm run build
|
|
107
|
-
matterbridge -add
|
|
109
|
+
matterbridge -add .
|
|
108
110
|
```
|
|
109
111
|
|
|
110
112
|
Then start Matterbridge
|
package/dist/entity.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import EventEmitter from 'node:events';
|
|
1
2
|
import { airQualitySensor, colorTemperatureSwitch, dimmableSwitch, onOffSwitch, powerSource, bridgedNode, electricalSensor, onOffLight, dimmableLight, colorTemperatureLight, onOffOutlet, coverDevice, thermostatDevice, MatterbridgeEndpoint, dimmableOutlet, doorLockDevice, occupancySensor, lightSensor, contactSensor, temperatureSensor, humiditySensor, pressureSensor, genericSwitch, waterLeakDetector, rainSensor, smokeCoAlarm, extendedColorLight, } from 'matterbridge';
|
|
2
3
|
import { AnsiLogger, gn, dn, ign, idn, rs, db, debugStringify, hk, zb, or, nf, CYAN, er, YELLOW } from 'matterbridge/logger';
|
|
3
|
-
import { deepCopy, deepEqual, isValidNumber, kelvinToRGB, miredToKelvin } from 'matterbridge/utils';
|
|
4
|
+
import { deepCopy, deepEqual, isValidNumber, isValidObject, kelvinToRGB, miredToKelvin } from 'matterbridge/utils';
|
|
4
5
|
import * as color from 'matterbridge/utils';
|
|
5
6
|
import { SwitchesTag, NumberTag } from 'matterbridge/matter';
|
|
6
7
|
import { getClusterNameById, ClusterId } from 'matterbridge/matter/types';
|
|
7
8
|
import { ElectricalEnergyMeasurement, ElectricalPowerMeasurement, OnOffCluster, LevelControlCluster, WindowCoveringCluster, DoorLockCluster, BridgedDeviceBasicInformation, OnOff, LevelControl, ColorControl, ColorControlCluster, TemperatureMeasurement, BooleanState, RelativeHumidityMeasurement, PressureMeasurement, OccupancySensing, IlluminanceMeasurement, PowerSource, WindowCovering, DoorLock, ThermostatCluster, Thermostat, AirQuality, TotalVolatileOrganicCompoundsConcentrationMeasurement, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, FormaldehydeConcentrationMeasurement, Pm1ConcentrationMeasurement, Pm25ConcentrationMeasurement, Pm10ConcentrationMeasurement, SmokeCoAlarm, } from 'matterbridge/matter/clusters';
|
|
8
|
-
import EventEmitter from 'node:events';
|
|
9
9
|
export class ZigbeeEntity extends EventEmitter {
|
|
10
10
|
log;
|
|
11
11
|
serial = '';
|
|
@@ -26,7 +26,7 @@ export class ZigbeeEntity extends EventEmitter {
|
|
|
26
26
|
transition = false;
|
|
27
27
|
propertyMap = new Map();
|
|
28
28
|
mutableDevice = new Map();
|
|
29
|
-
|
|
29
|
+
lightTimeout = undefined;
|
|
30
30
|
thermostatTimeout = undefined;
|
|
31
31
|
thermostatSystemModeLookup = ['off', 'auto', '', 'cool', 'heat', '', '', 'fan_only'];
|
|
32
32
|
composedType = '';
|
|
@@ -50,11 +50,17 @@ export class ZigbeeEntity extends EventEmitter {
|
|
|
50
50
|
this.en = gn;
|
|
51
51
|
this.ien = ign;
|
|
52
52
|
}
|
|
53
|
-
this.log = new AnsiLogger({
|
|
53
|
+
this.log = new AnsiLogger({
|
|
54
|
+
logName: this.entityName,
|
|
55
|
+
logTimestampFormat: 4,
|
|
56
|
+
logLevel: platform.debugEnabled ? "debug" : platform.log.logLevel,
|
|
57
|
+
});
|
|
54
58
|
this.log.debug(`Created MatterEntity: ${this.entityName}`);
|
|
55
59
|
this.platform.z2m.on('MESSAGE-' + this.entityName, (payload) => {
|
|
56
60
|
const now = Date.now();
|
|
57
|
-
if (now - this.lastSeen < 1000 * 60 &&
|
|
61
|
+
if (now - this.lastSeen < 1000 * 60 &&
|
|
62
|
+
deepEqual(this.lastPayload, payload, ['linkquality', 'last_seen', ...this.ignoreFeatures]) &&
|
|
63
|
+
!Object.prototype.hasOwnProperty.call(this.lastPayload, 'action')) {
|
|
58
64
|
this.log.debug(`Skipping not changed ${platform.z2mDevicesRegistered ? 'MQTT message' : 'State update'} for accessory ${this.entityName}`);
|
|
59
65
|
return;
|
|
60
66
|
}
|
|
@@ -200,9 +206,9 @@ export class ZigbeeEntity extends EventEmitter {
|
|
|
200
206
|
}
|
|
201
207
|
destroy() {
|
|
202
208
|
this.removeAllListeners();
|
|
203
|
-
if (this.
|
|
204
|
-
clearTimeout(this.
|
|
205
|
-
this.
|
|
209
|
+
if (this.lightTimeout)
|
|
210
|
+
clearTimeout(this.lightTimeout);
|
|
211
|
+
this.lightTimeout = undefined;
|
|
206
212
|
if (this.thermostatTimeout)
|
|
207
213
|
clearTimeout(this.thermostatTimeout);
|
|
208
214
|
this.thermostatTimeout = undefined;
|
|
@@ -466,7 +472,7 @@ export class ZigbeeGroup extends ZigbeeEntity {
|
|
|
466
472
|
platform.setSelectDeviceEntity(`group-${group.id}`, 'scenes', 'Scenes', 'component');
|
|
467
473
|
platform.registerVirtualDevice(`${platform.config.scenesPrefix ? group.friendly_name + ' ' : ''}${scene.name}`, async () => {
|
|
468
474
|
zigbeeGroup.log.info(`Triggered scene "${scene.name}" id ${scene.id} from group ${group.friendly_name}`);
|
|
469
|
-
zigbeeGroup.publishCommand('scene_recall', group.friendly_name, {
|
|
475
|
+
zigbeeGroup.publishCommand('scene_recall', group.friendly_name, { scene_recall: scene.id });
|
|
470
476
|
});
|
|
471
477
|
});
|
|
472
478
|
}
|
|
@@ -477,6 +483,25 @@ export class ZigbeeGroup extends ZigbeeEntity {
|
|
|
477
483
|
return zigbeeGroup;
|
|
478
484
|
zigbeeGroup.mutableDevice.clear();
|
|
479
485
|
zigbeeGroup.logPropertyMap();
|
|
486
|
+
let lastRequestedHue = -1;
|
|
487
|
+
let lastRequestedSaturation = -1;
|
|
488
|
+
let nextPayload = {};
|
|
489
|
+
function cachePublishLight(command = 'cachedPublishLight') {
|
|
490
|
+
clearTimeout(zigbeeGroup.lightTimeout);
|
|
491
|
+
zigbeeGroup.lightTimeout = setTimeout(() => {
|
|
492
|
+
clearTimeout(zigbeeGroup.lightTimeout);
|
|
493
|
+
zigbeeGroup.lightTimeout = undefined;
|
|
494
|
+
if (lastRequestedHue >= 0 && lastRequestedSaturation >= 0) {
|
|
495
|
+
const rgb = color.hslColorToRgbColor((lastRequestedHue / 254) * 360, (lastRequestedSaturation / 254) * 100, 50);
|
|
496
|
+
nextPayload['color'] = { r: rgb.r, g: rgb.g, b: rgb.b };
|
|
497
|
+
}
|
|
498
|
+
if (isValidObject(nextPayload, 1))
|
|
499
|
+
zigbeeGroup.publishCommand(command, group.friendly_name, nextPayload);
|
|
500
|
+
nextPayload = {};
|
|
501
|
+
lastRequestedHue = -1;
|
|
502
|
+
lastRequestedSaturation = -1;
|
|
503
|
+
}, 100);
|
|
504
|
+
}
|
|
480
505
|
if (isSwitch || isLight) {
|
|
481
506
|
if (isSwitch && !isLight)
|
|
482
507
|
await zigbeeGroup.bridgedDevice.addFixedLabel('type', 'switch');
|
|
@@ -487,71 +512,87 @@ export class ZigbeeGroup extends ZigbeeEntity {
|
|
|
487
512
|
});
|
|
488
513
|
zigbeeGroup.bridgedDevice.addCommandHandler('on', async () => {
|
|
489
514
|
zigbeeGroup.log.debug(`Command on called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db}`);
|
|
490
|
-
|
|
515
|
+
nextPayload['state'] = 'ON';
|
|
516
|
+
cachePublishLight();
|
|
491
517
|
});
|
|
492
518
|
zigbeeGroup.bridgedDevice.addCommandHandler('off', async () => {
|
|
493
519
|
zigbeeGroup.log.debug(`Command off called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db}`);
|
|
494
|
-
|
|
520
|
+
nextPayload['state'] = 'OFF';
|
|
521
|
+
cachePublishLight();
|
|
495
522
|
});
|
|
496
523
|
zigbeeGroup.bridgedDevice.addCommandHandler('toggle', async () => {
|
|
497
524
|
zigbeeGroup.log.debug(`Command toggle called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db}`);
|
|
498
|
-
|
|
525
|
+
nextPayload['state'] = 'TOGGLE';
|
|
526
|
+
cachePublishLight();
|
|
499
527
|
});
|
|
500
528
|
}
|
|
501
529
|
if (isLight) {
|
|
502
530
|
if (useBrightness) {
|
|
503
|
-
zigbeeGroup.bridgedDevice.addCommandHandler('moveToLevel', async (
|
|
504
|
-
zigbeeGroup.log.debug(`Command moveToLevel called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${level}`);
|
|
505
|
-
|
|
531
|
+
zigbeeGroup.bridgedDevice.addCommandHandler('moveToLevel', async (data) => {
|
|
532
|
+
zigbeeGroup.log.debug(`Command moveToLevel called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${data.request.level}`);
|
|
533
|
+
nextPayload['state'] = 'ON';
|
|
534
|
+
nextPayload['brightness'] = data.request.level;
|
|
535
|
+
if (zigbeeGroup.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
536
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
537
|
+
cachePublishLight();
|
|
506
538
|
});
|
|
507
|
-
zigbeeGroup.bridgedDevice.addCommandHandler('moveToLevelWithOnOff', async (
|
|
508
|
-
zigbeeGroup.log.debug(`Command moveToLevelWithOnOff called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${level}`);
|
|
509
|
-
|
|
539
|
+
zigbeeGroup.bridgedDevice.addCommandHandler('moveToLevelWithOnOff', async (data) => {
|
|
540
|
+
zigbeeGroup.log.debug(`Command moveToLevelWithOnOff called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${data.request.level}`);
|
|
541
|
+
nextPayload['state'] = 'ON';
|
|
542
|
+
nextPayload['brightness'] = data.request.level;
|
|
543
|
+
if (zigbeeGroup.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
544
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
545
|
+
cachePublishLight();
|
|
510
546
|
});
|
|
511
547
|
}
|
|
512
548
|
if (useColorTemperature) {
|
|
513
|
-
zigbeeGroup.bridgedDevice.addCommandHandler('moveToColorTemperature', async (
|
|
514
|
-
zigbeeGroup.log.debug(`Command moveToColorTemperature called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${request.colorTemperatureMireds}`);
|
|
549
|
+
zigbeeGroup.bridgedDevice.addCommandHandler('moveToColorTemperature', async (data) => {
|
|
550
|
+
zigbeeGroup.log.debug(`Command moveToColorTemperature called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${data.request.colorTemperatureMireds}`);
|
|
515
551
|
await zigbeeGroup.bridgedDevice?.setAttribute(ColorControl.Cluster.id, 'colorMode', ColorControl.ColorMode.ColorTemperatureMireds);
|
|
516
|
-
|
|
552
|
+
nextPayload['state'] = 'ON';
|
|
553
|
+
nextPayload['color_temp'] = data.request.colorTemperatureMireds;
|
|
554
|
+
if (zigbeeGroup.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
555
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
556
|
+
cachePublishLight();
|
|
517
557
|
});
|
|
518
558
|
}
|
|
519
559
|
if (useColor) {
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
zigbeeGroup.bridgedDevice.addCommandHandler('moveToHue', async ({ request: request }) => {
|
|
523
|
-
zigbeeGroup.log.debug(`Command moveToHue called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${request.hue}`);
|
|
560
|
+
zigbeeGroup.bridgedDevice.addCommandHandler('moveToHue', async (data) => {
|
|
561
|
+
zigbeeGroup.log.debug(`Command moveToHue called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${data.request.hue}`);
|
|
524
562
|
await zigbeeGroup.bridgedDevice?.setAttribute(ColorControl.Cluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}, 500);
|
|
563
|
+
nextPayload['state'] = 'ON';
|
|
564
|
+
lastRequestedHue = data.request.hue;
|
|
565
|
+
if (zigbeeGroup.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
566
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
567
|
+
cachePublishLight();
|
|
531
568
|
});
|
|
532
|
-
zigbeeGroup.bridgedDevice.addCommandHandler('moveToSaturation', async (
|
|
533
|
-
zigbeeGroup.log.debug(`Command moveToSaturation called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${request.saturation}`);
|
|
569
|
+
zigbeeGroup.bridgedDevice.addCommandHandler('moveToSaturation', async (data) => {
|
|
570
|
+
zigbeeGroup.log.debug(`Command moveToSaturation called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${data.request.saturation}`);
|
|
534
571
|
await zigbeeGroup.bridgedDevice?.setAttribute(ColorControl.Cluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
}, 500);
|
|
572
|
+
nextPayload['state'] = 'ON';
|
|
573
|
+
lastRequestedSaturation = data.request.saturation;
|
|
574
|
+
if (zigbeeGroup.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
575
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
576
|
+
cachePublishLight();
|
|
541
577
|
});
|
|
542
|
-
zigbeeGroup.bridgedDevice.addCommandHandler('moveToHueAndSaturation', async (
|
|
543
|
-
zigbeeGroup.log.debug(`Command moveToHueAndSaturation called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${request.hue}-${request.saturation}`);
|
|
578
|
+
zigbeeGroup.bridgedDevice.addCommandHandler('moveToHueAndSaturation', async (data) => {
|
|
579
|
+
zigbeeGroup.log.debug(`Command moveToHueAndSaturation called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: ${data.request.hue}-${data.request.saturation}`);
|
|
544
580
|
await zigbeeGroup.bridgedDevice?.setAttribute(ColorControl.Cluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation);
|
|
545
|
-
|
|
546
|
-
|
|
581
|
+
nextPayload['state'] = 'ON';
|
|
582
|
+
const rgb = color.hslColorToRgbColor((data.request.hue / 254) * 360, (data.request.saturation / 254) * 100, 50);
|
|
583
|
+
nextPayload['color'] = { r: rgb.r, g: rgb.g, b: rgb.b };
|
|
584
|
+
if (zigbeeGroup.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
585
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
586
|
+
cachePublishLight();
|
|
547
587
|
});
|
|
548
|
-
zigbeeGroup.bridgedDevice.addCommandHandler('moveToColor', async (
|
|
549
|
-
zigbeeGroup.log.debug(`Command moveToColor called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: X: ${request.colorX} Y: ${request.colorY}`);
|
|
588
|
+
zigbeeGroup.bridgedDevice.addCommandHandler('moveToColor', async (data) => {
|
|
589
|
+
zigbeeGroup.log.debug(`Command moveToColor called for ${zigbeeGroup.ien}${group.friendly_name}${rs}${db} request: X: ${data.request.colorX} Y: ${data.request.colorY}`);
|
|
550
590
|
await zigbeeGroup.bridgedDevice?.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentXAndCurrentY, zigbeeGroup.log);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
591
|
+
nextPayload['state'] = 'ON';
|
|
592
|
+
nextPayload['color'] = { x: data.request.colorX / 65536, y: data.request.colorY / 65536 };
|
|
593
|
+
if (zigbeeGroup.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
594
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
595
|
+
cachePublishLight();
|
|
555
596
|
});
|
|
556
597
|
}
|
|
557
598
|
}
|
|
@@ -693,7 +734,9 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
693
734
|
if (zigbeeDevice.platform.postfix !== '') {
|
|
694
735
|
zigbeeDevice.serial = `${zigbeeDevice.serial}-${zigbeeDevice.platform.postfix}`.slice(0, 32);
|
|
695
736
|
}
|
|
696
|
-
if (device.friendly_name === 'Coordinator' ||
|
|
737
|
+
if (device.friendly_name === 'Coordinator' ||
|
|
738
|
+
(device.model_id === 'ti.router' && device.manufacturer === 'TexasInstruments') ||
|
|
739
|
+
(device.model_id.startsWith('SLZB-') && device.manufacturer === 'SMLIGHT')) {
|
|
697
740
|
zigbeeDevice.isRouter = true;
|
|
698
741
|
platform.setSelectDevice(device.ieee_address, device.friendly_name, 'wifi');
|
|
699
742
|
zigbeeDevice.bridgedDevice = new MatterbridgeEndpoint([doorLockDevice, bridgedNode, powerSource], { uniqueStorageKey: device.friendly_name }, zigbeeDevice.log.logLevel === "debug");
|
|
@@ -724,7 +767,7 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
724
767
|
platform.setSelectDeviceEntity(device.ieee_address, 'scenes', 'Scenes', 'component');
|
|
725
768
|
platform.registerVirtualDevice(`${platform.config.scenesPrefix ? device.friendly_name + ' ' : ''}${scene.name}`, async () => {
|
|
726
769
|
zigbeeDevice.log.info(`Triggered scene "${scene.name}" id ${scene.id} from device ${device.friendly_name}`);
|
|
727
|
-
zigbeeDevice.publishCommand('scene_recall', device.friendly_name, {
|
|
770
|
+
zigbeeDevice.publishCommand('scene_recall', device.friendly_name, { scene_recall: scene.id });
|
|
728
771
|
});
|
|
729
772
|
});
|
|
730
773
|
});
|
|
@@ -902,7 +945,14 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
902
945
|
}
|
|
903
946
|
const tagList = [];
|
|
904
947
|
tagList.push({ mfgCode: null, namespaceId: SwitchesTag.Custom.namespaceId, tag: SwitchesTag.Custom.tag, label: 'switch_' + count });
|
|
905
|
-
zigbeeDevice.mutableDevice.set('switch_' + count, {
|
|
948
|
+
zigbeeDevice.mutableDevice.set('switch_' + count, {
|
|
949
|
+
tagList,
|
|
950
|
+
deviceTypes: [genericSwitch],
|
|
951
|
+
clusterServersIds: [...genericSwitch.requiredServerClusters],
|
|
952
|
+
clusterServersOptions: [],
|
|
953
|
+
clusterClientsIds: [],
|
|
954
|
+
clusterClientsOptions: [],
|
|
955
|
+
});
|
|
906
956
|
}
|
|
907
957
|
else {
|
|
908
958
|
for (let i = 0; i < zigbeeDevice.actions.length; i += 3) {
|
|
@@ -914,7 +964,14 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
914
964
|
}
|
|
915
965
|
const tagList = [];
|
|
916
966
|
tagList.push({ mfgCode: null, namespaceId: SwitchesTag.Custom.namespaceId, tag: SwitchesTag.Custom.tag, label: 'switch_' + count });
|
|
917
|
-
zigbeeDevice.mutableDevice.set('switch_' + count, {
|
|
967
|
+
zigbeeDevice.mutableDevice.set('switch_' + count, {
|
|
968
|
+
tagList,
|
|
969
|
+
deviceTypes: [genericSwitch],
|
|
970
|
+
clusterServersIds: [...genericSwitch.requiredServerClusters],
|
|
971
|
+
clusterServersOptions: [],
|
|
972
|
+
clusterClientsIds: [],
|
|
973
|
+
clusterClientsOptions: [],
|
|
974
|
+
});
|
|
918
975
|
count++;
|
|
919
976
|
}
|
|
920
977
|
}
|
|
@@ -928,7 +985,14 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
928
985
|
zigbeeDevice.propertyMap.set('battery_voltage', { name: 'battery_voltage', type: '', endpoint: '' });
|
|
929
986
|
}
|
|
930
987
|
if (!zigbeeDevice.mutableDevice.has(''))
|
|
931
|
-
zigbeeDevice.mutableDevice.set('', {
|
|
988
|
+
zigbeeDevice.mutableDevice.set('', {
|
|
989
|
+
tagList: [],
|
|
990
|
+
deviceTypes: [bridgedNode, powerSource],
|
|
991
|
+
clusterServersIds: [],
|
|
992
|
+
clusterServersOptions: [],
|
|
993
|
+
clusterClientsIds: [],
|
|
994
|
+
clusterClientsOptions: [],
|
|
995
|
+
});
|
|
932
996
|
const mainEndpoint = zigbeeDevice.mutableDevice.get('');
|
|
933
997
|
if (!mainEndpoint)
|
|
934
998
|
return zigbeeDevice;
|
|
@@ -987,7 +1051,8 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
987
1051
|
zigbeeDevice.log.debug(`Device ${zigbeeDevice.ien}${zigbeeDevice.device?.friendly_name}${rs}${db} endpoint: ${ign}${endpoint === '' ? 'main' : endpoint}${rs}${db} => ` +
|
|
988
1052
|
`${nf}tagList: ${debugStringify(device.tagList)} deviceTypes: ${debugStringify(device.deviceTypes)} clusterServersIds: ${debugStringify(device.clusterServersIds)}`);
|
|
989
1053
|
}
|
|
990
|
-
if ((mainEndpoint.deviceTypes.find((dt) => dt.code === waterLeakDetector.code) || mainEndpoint.deviceTypes.find((dt) => dt.code === rainSensor.code)) &&
|
|
1054
|
+
if ((mainEndpoint.deviceTypes.find((dt) => dt.code === waterLeakDetector.code) || mainEndpoint.deviceTypes.find((dt) => dt.code === rainSensor.code)) &&
|
|
1055
|
+
mainEndpoint.clusterServersIds.includes(BooleanState.Cluster.id)) {
|
|
991
1056
|
zigbeeDevice.log.debug(`Configuring device ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} BooleanStateCluster cluster with`);
|
|
992
1057
|
zigbeeDevice.bridgedDevice.createDefaultBooleanStateClusterServer(false);
|
|
993
1058
|
mainEndpoint.clusterServersIds.splice(mainEndpoint.clusterServersIds.indexOf(BooleanState.Cluster.id), 1);
|
|
@@ -1054,146 +1119,226 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
1054
1119
|
return zigbeeDevice;
|
|
1055
1120
|
zigbeeDevice.mutableDevice.clear();
|
|
1056
1121
|
zigbeeDevice.logPropertyMap();
|
|
1122
|
+
let lastRequestedHue = -1;
|
|
1123
|
+
let lastRequestedSaturation = -1;
|
|
1124
|
+
let nextPayload = {};
|
|
1125
|
+
function cachePublishLight(command = 'cachedPublishLight') {
|
|
1126
|
+
clearTimeout(zigbeeDevice.lightTimeout);
|
|
1127
|
+
zigbeeDevice.lightTimeout = setTimeout(() => {
|
|
1128
|
+
clearTimeout(zigbeeDevice.lightTimeout);
|
|
1129
|
+
zigbeeDevice.lightTimeout = undefined;
|
|
1130
|
+
if (lastRequestedHue >= 0 && lastRequestedSaturation >= 0) {
|
|
1131
|
+
const rgb = color.hslColorToRgbColor((lastRequestedHue / 254) * 360, (lastRequestedSaturation / 254) * 100, 50);
|
|
1132
|
+
nextPayload['color'] = { r: rgb.r, g: rgb.g, b: rgb.b };
|
|
1133
|
+
}
|
|
1134
|
+
if (isValidObject(nextPayload, 1))
|
|
1135
|
+
zigbeeDevice.publishCommand(command, device.friendly_name, nextPayload);
|
|
1136
|
+
nextPayload = {};
|
|
1137
|
+
lastRequestedHue = -1;
|
|
1138
|
+
lastRequestedSaturation = -1;
|
|
1139
|
+
}, 100);
|
|
1140
|
+
}
|
|
1057
1141
|
zigbeeDevice.bridgedDevice.addCommandHandler('identify', async (data) => {
|
|
1058
|
-
zigbeeDevice.log.debug(`Command identify called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber} request identifyTime:${data.request.identifyTime} `);
|
|
1142
|
+
zigbeeDevice.log.debug(`Command identify called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request identifyTime:${data.request.identifyTime} `);
|
|
1059
1143
|
});
|
|
1060
1144
|
if (zigbeeDevice.bridgedDevice.hasClusterServer(OnOffCluster.id) || zigbeeDevice.hasEndpoints) {
|
|
1061
1145
|
for (const child of zigbeeDevice.bridgedDevice.getChildEndpoints()) {
|
|
1062
1146
|
if (child.hasClusterServer(OnOffCluster)) {
|
|
1063
1147
|
child.addCommandHandler('on', async (data) => {
|
|
1064
|
-
zigbeeDevice.log.debug(`Command on called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber}`);
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
zigbeeDevice.publishCommand('on', device.friendly_name, payload);
|
|
1148
|
+
zigbeeDevice.log.debug(`Command on called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber}`);
|
|
1149
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1150
|
+
cachePublishLight();
|
|
1068
1151
|
});
|
|
1069
1152
|
child.addCommandHandler('off', async (data) => {
|
|
1070
|
-
zigbeeDevice.log.debug(`Command off called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber}`);
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
zigbeeDevice.publishCommand('off', device.friendly_name, payload);
|
|
1153
|
+
zigbeeDevice.log.debug(`Command off called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber}`);
|
|
1154
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'OFF';
|
|
1155
|
+
cachePublishLight();
|
|
1074
1156
|
});
|
|
1075
1157
|
child.addCommandHandler('toggle', async (data) => {
|
|
1076
|
-
zigbeeDevice.log.debug(`Command toggle called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber}`);
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
zigbeeDevice.publishCommand('toggle', device.friendly_name, payload);
|
|
1158
|
+
zigbeeDevice.log.debug(`Command toggle called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber}`);
|
|
1159
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'TOGGLE';
|
|
1160
|
+
cachePublishLight();
|
|
1080
1161
|
});
|
|
1081
1162
|
}
|
|
1082
1163
|
}
|
|
1083
1164
|
zigbeeDevice.bridgedDevice.addCommandHandler('on', async (data) => {
|
|
1084
|
-
zigbeeDevice.log.debug(`Command on called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber}`);
|
|
1085
|
-
|
|
1165
|
+
zigbeeDevice.log.debug(`Command on called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber}`);
|
|
1166
|
+
nextPayload['state'] = 'ON';
|
|
1167
|
+
cachePublishLight();
|
|
1086
1168
|
});
|
|
1087
1169
|
zigbeeDevice.bridgedDevice.addCommandHandler('off', async (data) => {
|
|
1088
|
-
zigbeeDevice.log.debug(`Command off called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber}`);
|
|
1089
|
-
|
|
1170
|
+
zigbeeDevice.log.debug(`Command off called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber}`);
|
|
1171
|
+
nextPayload['state'] = 'OFF';
|
|
1172
|
+
cachePublishLight();
|
|
1090
1173
|
});
|
|
1091
1174
|
zigbeeDevice.bridgedDevice.addCommandHandler('toggle', async (data) => {
|
|
1092
|
-
zigbeeDevice.log.debug(`Command toggle called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber}`);
|
|
1093
|
-
|
|
1175
|
+
zigbeeDevice.log.debug(`Command toggle called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber}`);
|
|
1176
|
+
nextPayload['state'] = 'TOGGLE';
|
|
1177
|
+
cachePublishLight();
|
|
1094
1178
|
});
|
|
1095
1179
|
}
|
|
1096
1180
|
if (zigbeeDevice.bridgedDevice.hasClusterServer(LevelControlCluster.id) || zigbeeDevice.hasEndpoints) {
|
|
1097
1181
|
for (const child of zigbeeDevice.bridgedDevice.getChildEndpoints()) {
|
|
1098
1182
|
if (child.hasClusterServer(LevelControlCluster)) {
|
|
1099
1183
|
child.addCommandHandler('moveToLevel', async (data) => {
|
|
1100
|
-
zigbeeDevice.log.debug(`Command moveToLevel called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1101
|
-
|
|
1102
|
-
|
|
1184
|
+
zigbeeDevice.log.debug(`Command moveToLevel called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1185
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1186
|
+
nextPayload['brightness_' + data.endpoint.uniqueStorageKey] = data.request.level;
|
|
1103
1187
|
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1104
|
-
|
|
1105
|
-
|
|
1188
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1189
|
+
cachePublishLight();
|
|
1106
1190
|
});
|
|
1107
1191
|
child.addCommandHandler('moveToLevelWithOnOff', async (data) => {
|
|
1108
|
-
zigbeeDevice.log.debug(`Command moveToLevelWithOnOff called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1109
|
-
|
|
1110
|
-
|
|
1192
|
+
zigbeeDevice.log.debug(`Command moveToLevelWithOnOff called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1193
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1194
|
+
nextPayload['brightness_' + data.endpoint.uniqueStorageKey] = data.request.level;
|
|
1111
1195
|
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1112
|
-
|
|
1113
|
-
|
|
1196
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1197
|
+
cachePublishLight();
|
|
1114
1198
|
});
|
|
1115
1199
|
}
|
|
1116
1200
|
}
|
|
1117
1201
|
zigbeeDevice.bridgedDevice.addCommandHandler('moveToLevel', async (data) => {
|
|
1118
|
-
zigbeeDevice.log.debug(`Command moveToLevel called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1119
|
-
|
|
1202
|
+
zigbeeDevice.log.debug(`Command moveToLevel called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1203
|
+
nextPayload['state'] = 'ON';
|
|
1204
|
+
nextPayload['brightness'] = data.request.level;
|
|
1120
1205
|
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1121
|
-
|
|
1122
|
-
|
|
1206
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1207
|
+
cachePublishLight();
|
|
1123
1208
|
});
|
|
1124
1209
|
zigbeeDevice.bridgedDevice.addCommandHandler('moveToLevelWithOnOff', async (data) => {
|
|
1125
|
-
zigbeeDevice.log.debug(`Command moveToLevelWithOnOff called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1126
|
-
|
|
1210
|
+
zigbeeDevice.log.debug(`Command moveToLevelWithOnOff called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.level} transition: ${data.request.transitionTime}`);
|
|
1211
|
+
nextPayload['state'] = 'ON';
|
|
1212
|
+
nextPayload['brightness'] = data.request.level;
|
|
1127
1213
|
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1128
|
-
|
|
1129
|
-
|
|
1214
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1215
|
+
cachePublishLight();
|
|
1130
1216
|
});
|
|
1131
1217
|
}
|
|
1132
|
-
if (zigbeeDevice.bridgedDevice.hasAttributeServer(ColorControlCluster.id, 'colorTemperatureMireds')) {
|
|
1133
|
-
zigbeeDevice.bridgedDevice.
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1218
|
+
if (zigbeeDevice.bridgedDevice.hasAttributeServer(ColorControlCluster.id, 'colorTemperatureMireds') || zigbeeDevice.hasEndpoints) {
|
|
1219
|
+
for (const child of zigbeeDevice.bridgedDevice.getChildEndpoints()) {
|
|
1220
|
+
if (child.hasAttributeServer(ColorControlCluster.id, 'colorTemperatureMireds')) {
|
|
1221
|
+
child.addCommandHandler('moveToColorTemperature', async (data) => {
|
|
1222
|
+
zigbeeDevice.log.debug(`Command moveToColorTemperature called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.colorTemperatureMireds} transition: ${data.request.transitionTime}`);
|
|
1223
|
+
await child.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.ColorTemperatureMireds, zigbeeDevice.log);
|
|
1224
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1225
|
+
if (zigbeeDevice.propertyMap.get('color_temp')) {
|
|
1226
|
+
nextPayload['color_temp_' + data.endpoint.uniqueStorageKey] = data.request.colorTemperatureMireds;
|
|
1227
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1228
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1229
|
+
cachePublishLight();
|
|
1230
|
+
}
|
|
1231
|
+
else {
|
|
1232
|
+
const rgb = kelvinToRGB(miredToKelvin(data.request.colorTemperatureMireds));
|
|
1233
|
+
nextPayload['color_' + data.endpoint.uniqueStorageKey] = { r: rgb.r, g: rgb.g, b: rgb.b };
|
|
1234
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1235
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1236
|
+
cachePublishLight();
|
|
1237
|
+
zigbeeDevice.log.info(`Command moveToColorTemperature called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${nf} but color_temp property is not available. Converting ${data.request.colorTemperatureMireds} to RGB ${debugStringify(rgb)}.`);
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
zigbeeDevice.bridgedDevice.addCommandHandler('moveToColorTemperature', async (data) => {
|
|
1243
|
+
zigbeeDevice.log.debug(`Command moveToColorTemperature called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.colorTemperatureMireds} transition: ${data.request.transitionTime}`);
|
|
1244
|
+
await data.endpoint?.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.ColorTemperatureMireds, zigbeeDevice.log);
|
|
1245
|
+
nextPayload['state'] = 'ON';
|
|
1137
1246
|
if (zigbeeDevice.propertyMap.get('color_temp')) {
|
|
1138
|
-
|
|
1247
|
+
nextPayload['color_temp'] = data.request.colorTemperatureMireds;
|
|
1248
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1249
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1250
|
+
cachePublishLight();
|
|
1139
1251
|
}
|
|
1140
1252
|
else {
|
|
1141
|
-
const rgb = kelvinToRGB(miredToKelvin(request.colorTemperatureMireds));
|
|
1142
|
-
|
|
1143
|
-
zigbeeDevice.
|
|
1253
|
+
const rgb = kelvinToRGB(miredToKelvin(data.request.colorTemperatureMireds));
|
|
1254
|
+
nextPayload['color'] = { r: rgb.r, g: rgb.g, b: rgb.b };
|
|
1255
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1256
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1257
|
+
cachePublishLight();
|
|
1258
|
+
zigbeeDevice.log.info(`Command moveToColorTemperature called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${nf} but color_temp property is not available. Converting ${data.request.colorTemperatureMireds} to RGB ${debugStringify(rgb)}.`);
|
|
1144
1259
|
}
|
|
1145
|
-
if (zigbeeDevice.transition && request.transitionTime && request.transitionTime / 10 >= 1)
|
|
1146
|
-
payload['transition'] = Math.round(request.transitionTime / 10);
|
|
1147
|
-
zigbeeDevice.publishCommand('moveToColorTemperature', device.friendly_name, payload);
|
|
1148
1260
|
});
|
|
1149
1261
|
}
|
|
1150
|
-
if (zigbeeDevice.bridgedDevice.hasAttributeServer(ColorControlCluster.id, 'currentX')) {
|
|
1151
|
-
zigbeeDevice.bridgedDevice.
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1262
|
+
if (zigbeeDevice.bridgedDevice.hasAttributeServer(ColorControlCluster.id, 'currentX') || zigbeeDevice.hasEndpoints) {
|
|
1263
|
+
for (const child of zigbeeDevice.bridgedDevice.getChildEndpoints()) {
|
|
1264
|
+
if (child.hasAttributeServer(ColorControlCluster.id, 'currentX')) {
|
|
1265
|
+
child.addCommandHandler('moveToColor', async (data) => {
|
|
1266
|
+
zigbeeDevice.log.debug(`Command moveToColor called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: X: ${data.request.colorX} Y: ${data.request.colorY} transition: ${data.request.transitionTime}`);
|
|
1267
|
+
await child.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentXAndCurrentY, zigbeeDevice.log);
|
|
1268
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1269
|
+
nextPayload['color_' + data.endpoint.uniqueStorageKey] = { x: data.request.colorX / 65536, y: data.request.colorY / 65536 };
|
|
1270
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1271
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1272
|
+
cachePublishLight();
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
zigbeeDevice.bridgedDevice.addCommandHandler('moveToColor', async (data) => {
|
|
1277
|
+
zigbeeDevice.log.debug(`Command moveToColor called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: X: ${data.request.colorX} Y: ${data.request.colorY} transition: ${data.request.transitionTime}`);
|
|
1278
|
+
await data.endpoint?.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentXAndCurrentY, zigbeeDevice.log);
|
|
1279
|
+
nextPayload['state'] = 'ON';
|
|
1280
|
+
nextPayload['color'] = { x: data.request.colorX / 65536, y: data.request.colorY / 65536 };
|
|
1281
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1282
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1283
|
+
cachePublishLight();
|
|
1158
1284
|
});
|
|
1159
1285
|
}
|
|
1160
|
-
if (zigbeeDevice.bridgedDevice.hasAttributeServer(ColorControlCluster.id, 'currentHue')) {
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1286
|
+
if (zigbeeDevice.bridgedDevice.hasAttributeServer(ColorControlCluster.id, 'currentHue') || zigbeeDevice.hasEndpoints) {
|
|
1287
|
+
for (const child of zigbeeDevice.bridgedDevice.getChildEndpoints()) {
|
|
1288
|
+
if (child.hasAttributeServer(ColorControlCluster.id, 'currentHue')) {
|
|
1289
|
+
child.addCommandHandler('moveToHue', async (data) => {
|
|
1290
|
+
zigbeeDevice.log.debug(`Command moveToHue called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.hue} transition: ${data.request.transitionTime}`);
|
|
1291
|
+
await child.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation, zigbeeDevice.log);
|
|
1292
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1293
|
+
lastRequestedHue = data.request.hue;
|
|
1294
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1295
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1296
|
+
cachePublishLight();
|
|
1297
|
+
});
|
|
1298
|
+
child.addCommandHandler('moveToSaturation', async (data) => {
|
|
1299
|
+
zigbeeDevice.log.debug(`Command moveToSaturation called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.saturation} transition: ${data.request.transitionTime}`);
|
|
1300
|
+
await child.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation, zigbeeDevice.log);
|
|
1301
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1302
|
+
lastRequestedSaturation = data.request.saturation;
|
|
1303
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1304
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1305
|
+
cachePublishLight();
|
|
1306
|
+
});
|
|
1307
|
+
child.addCommandHandler('moveToHueAndSaturation', async (data) => {
|
|
1308
|
+
zigbeeDevice.log.debug(`Command moveToHueAndSaturation called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.hue}-${data.request.saturation} transition: ${data.request.transitionTime}`);
|
|
1309
|
+
await child.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation, zigbeeDevice.log);
|
|
1310
|
+
nextPayload['state_' + data.endpoint.uniqueStorageKey] = 'ON';
|
|
1311
|
+
const rgb = color.hslColorToRgbColor((data.request.hue / 254) * 360, (data.request.saturation / 254) * 100, 50);
|
|
1312
|
+
nextPayload['color_' + data.endpoint.uniqueStorageKey] = { r: rgb.r, g: rgb.g, b: rgb.b };
|
|
1313
|
+
cachePublishLight();
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
zigbeeDevice.bridgedDevice.addCommandHandler('moveToHue', async (data) => {
|
|
1318
|
+
zigbeeDevice.log.debug(`Command moveToHue called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.hue} transition: ${data.request.transitionTime}`);
|
|
1165
1319
|
await zigbeeDevice.bridgedDevice?.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation, zigbeeDevice.log);
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
if (zigbeeDevice.transition && request.transitionTime && request.transitionTime / 10 >= 1)
|
|
1172
|
-
payload['transition'] = Math.round(request.transitionTime / 10);
|
|
1173
|
-
zigbeeDevice.publishCommand('moveToHue', device.friendly_name, payload);
|
|
1174
|
-
}, 500);
|
|
1320
|
+
nextPayload['state'] = 'ON';
|
|
1321
|
+
lastRequestedHue = data.request.hue;
|
|
1322
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1323
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1324
|
+
cachePublishLight();
|
|
1175
1325
|
});
|
|
1176
|
-
zigbeeDevice.bridgedDevice.addCommandHandler('moveToSaturation', async (
|
|
1177
|
-
zigbeeDevice.log.debug(`Command moveToSaturation called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} request: ${request.saturation}`);
|
|
1326
|
+
zigbeeDevice.bridgedDevice.addCommandHandler('moveToSaturation', async (data) => {
|
|
1327
|
+
zigbeeDevice.log.debug(`Command moveToSaturation called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.saturation} transition: ${data.request.transitionTime}`);
|
|
1178
1328
|
await zigbeeDevice.bridgedDevice?.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation, zigbeeDevice.log);
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
if (zigbeeDevice.transition && request.transitionTime && request.transitionTime / 10 >= 1)
|
|
1185
|
-
payload['transition'] = Math.round(request.transitionTime / 10);
|
|
1186
|
-
zigbeeDevice.publishCommand('moveToSaturation', device.friendly_name, payload);
|
|
1187
|
-
}, 500);
|
|
1329
|
+
nextPayload['state'] = 'ON';
|
|
1330
|
+
lastRequestedSaturation = data.request.saturation;
|
|
1331
|
+
if (zigbeeDevice.transition && data.request.transitionTime && data.request.transitionTime / 10 >= 1)
|
|
1332
|
+
nextPayload['transition'] = Math.round(data.request.transitionTime / 10);
|
|
1333
|
+
cachePublishLight();
|
|
1188
1334
|
});
|
|
1189
|
-
zigbeeDevice.bridgedDevice.addCommandHandler('moveToHueAndSaturation', async (
|
|
1190
|
-
zigbeeDevice.log.debug(`Command moveToHueAndSaturation called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} request: ${request.hue}-${request.saturation}`);
|
|
1335
|
+
zigbeeDevice.bridgedDevice.addCommandHandler('moveToHueAndSaturation', async (data) => {
|
|
1336
|
+
zigbeeDevice.log.debug(`Command moveToHueAndSaturation called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} endpoint: ${data.endpoint?.maybeId}:${data.endpoint?.maybeNumber} request: ${data.request.hue}-${data.request.saturation} transition: ${data.request.transitionTime}`);
|
|
1191
1337
|
await zigbeeDevice.bridgedDevice?.setAttribute(ColorControlCluster.id, 'colorMode', ColorControl.ColorMode.CurrentHueAndCurrentSaturation, zigbeeDevice.log);
|
|
1192
|
-
|
|
1193
|
-
const
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
zigbeeDevice.publishCommand('moveToHueAndSaturation', device.friendly_name, payload);
|
|
1338
|
+
nextPayload['state'] = 'ON';
|
|
1339
|
+
const rgb = color.hslColorToRgbColor((data.request.hue / 254) * 360, (data.request.saturation / 254) * 100, 50);
|
|
1340
|
+
nextPayload['color'] = { r: rgb.r, g: rgb.g, b: rgb.b };
|
|
1341
|
+
cachePublishLight();
|
|
1197
1342
|
});
|
|
1198
1343
|
}
|
|
1199
1344
|
if (zigbeeDevice.bridgedDevice.hasClusterServer(WindowCoveringCluster.id)) {
|
package/dist/index.js
CHANGED
package/dist/platform.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import { addVirtualDevice, MatterbridgeDynamicPlatform } from 'matterbridge';
|
|
2
3
|
import { dn, gn, db, wr, zb, payloadStringify, rs, debugStringify, CYAN, er, nf } from 'matterbridge/logger';
|
|
3
4
|
import { isValidNumber, isValidString, waiter } from 'matterbridge/utils';
|
|
4
5
|
import { BridgedDeviceBasicInformation, DoorLock } from 'matterbridge/matter/clusters';
|
|
5
|
-
import path from 'node:path';
|
|
6
6
|
import { ZigbeeDevice, ZigbeeGroup } from './entity.js';
|
|
7
7
|
import { Zigbee2MQTT } from './zigbee2mqtt.js';
|
|
8
8
|
export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
9
|
-
publishCallBack = undefined;
|
|
10
|
-
permitJoinCallBack = undefined;
|
|
11
9
|
bridgedDevices = [];
|
|
12
10
|
zigbeeEntities = [];
|
|
13
|
-
injectTimer;
|
|
14
11
|
namePostfix = 1;
|
|
12
|
+
injectTimer;
|
|
15
13
|
mqttHost = 'mqtt://localhost';
|
|
16
14
|
mqttPort = 1883;
|
|
17
15
|
mqttTopic = 'zigbee2mqtt';
|
|
@@ -337,20 +335,20 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
337
335
|
}
|
|
338
336
|
async onConfigure() {
|
|
339
337
|
await super.onConfigure();
|
|
340
|
-
this.log.info(`
|
|
338
|
+
this.log.info(`Configuring ${this.zigbeeEntities.length} zigbee entities.`);
|
|
341
339
|
for (const bridgedEntity of this.zigbeeEntities) {
|
|
342
340
|
await bridgedEntity.configure();
|
|
343
341
|
if (bridgedEntity.isRouter && bridgedEntity.bridgedDevice) {
|
|
344
|
-
this.log.info(`Configuring router ${bridgedEntity.bridgedDevice
|
|
342
|
+
this.log.info(`Configuring router ${bridgedEntity.bridgedDevice.deviceName}.`);
|
|
345
343
|
if (this.z2mBridgeInfo?.permit_join) {
|
|
346
|
-
bridgedEntity.bridgedDevice
|
|
344
|
+
bridgedEntity.bridgedDevice.setAttribute(DoorLock.Cluster.id, 'lockState', DoorLock.LockState.Unlocked, this.log);
|
|
347
345
|
if (bridgedEntity.bridgedDevice.maybeNumber)
|
|
348
|
-
bridgedEntity.bridgedDevice
|
|
346
|
+
bridgedEntity.bridgedDevice.triggerEvent(DoorLock.Cluster.id, 'lockOperation', { lockOperationType: DoorLock.LockOperationType.Unlock, operationSource: DoorLock.OperationSource.Manual, userIndex: null, fabricIndex: null, sourceNode: null }, this.log);
|
|
349
347
|
}
|
|
350
348
|
else {
|
|
351
|
-
bridgedEntity.bridgedDevice
|
|
349
|
+
bridgedEntity.bridgedDevice.setAttribute(DoorLock.Cluster.id, 'lockState', DoorLock.LockState.Locked, this.log);
|
|
352
350
|
if (bridgedEntity.bridgedDevice.maybeNumber)
|
|
353
|
-
bridgedEntity.bridgedDevice
|
|
351
|
+
bridgedEntity.bridgedDevice.triggerEvent(DoorLock.Cluster.id, 'lockOperation', { lockOperationType: DoorLock.LockOperationType.Lock, operationSource: DoorLock.OperationSource.Manual, userIndex: null, fabricIndex: null, sourceNode: null }, this.log);
|
|
354
352
|
}
|
|
355
353
|
}
|
|
356
354
|
if (bridgedEntity.isDevice && bridgedEntity.device)
|
|
@@ -398,7 +396,6 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
398
396
|
await super.onShutdown(reason);
|
|
399
397
|
this.z2m.removeAllListeners();
|
|
400
398
|
this.z2m.stop();
|
|
401
|
-
this.publishCallBack = undefined;
|
|
402
399
|
this.log.debug('Shutting down zigbee2mqtt platform: ' + reason);
|
|
403
400
|
for (const entity of this.zigbeeEntities) {
|
|
404
401
|
entity.destroy();
|
|
@@ -413,26 +410,9 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
413
410
|
await this.unregisterAllDevices();
|
|
414
411
|
this.log.info(`Shutdown zigbee2mqtt dynamic platform v${this.version}`);
|
|
415
412
|
}
|
|
416
|
-
setPublishCallBack(onPublish) {
|
|
417
|
-
this.publishCallBack = onPublish;
|
|
418
|
-
}
|
|
419
|
-
setPermitJoinCallBack(onPermitJoin) {
|
|
420
|
-
this.permitJoinCallBack = onPermitJoin;
|
|
421
|
-
}
|
|
422
413
|
async publish(topic, subTopic, message) {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
await this.publishCallBack(topic, subTopic, message);
|
|
426
|
-
if (this.permitJoinCallBack && topic.startsWith('bridge/request'))
|
|
427
|
-
await this.permitJoinCallBack('', message === '{"value":true}');
|
|
428
|
-
}
|
|
429
|
-
else {
|
|
430
|
-
await this.z2m.publish(this.z2m.mqttTopic + '/' + topic + (subTopic === '' ? '' : '/' + subTopic), message);
|
|
431
|
-
this.log.info(`MQTT publish topic: ${CYAN}${this.z2m.mqttTopic + '/' + topic + (subTopic === '' ? '' : '/' + subTopic)}${nf} payload: ${CYAN}${message}${nf}`);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
emit(eventName, data) {
|
|
435
|
-
this.z2m.emit(eventName, data);
|
|
414
|
+
this.log.info(`MQTT publish topic: ${CYAN}${this.z2m.mqttTopic + '/' + topic + (subTopic === '' ? '' : '/' + subTopic)}${nf} payload: ${CYAN}${message}${nf}`);
|
|
415
|
+
await this.z2m.publish(this.z2m.mqttTopic + '/' + topic + (subTopic === '' ? '' : '/' + subTopic), message);
|
|
436
416
|
}
|
|
437
417
|
async requestDeviceUpdate(device) {
|
|
438
418
|
this.log.debug(`Requesting update for ${device.friendly_name} model_id: ${device.model_id} manufacturer: ${device.manufacturer}`);
|
package/dist/zigbee2mqtt.js
CHANGED
|
@@ -205,6 +205,7 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
205
205
|
this.log.error('Error publishing keepalive MQTT message:', error);
|
|
206
206
|
}
|
|
207
207
|
}, (this.options.keepalive ?? 60) * 1000).unref();
|
|
208
|
+
return;
|
|
208
209
|
})
|
|
209
210
|
.catch((error) => {
|
|
210
211
|
this.log.error(`Error connecting to ${this.getUrl()}: ${error.message}`);
|
|
@@ -231,6 +232,7 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
231
232
|
this.mqttIsEnding = false;
|
|
232
233
|
this.mqttClient = undefined;
|
|
233
234
|
this.log.debug('Connection closed');
|
|
235
|
+
return;
|
|
234
236
|
})
|
|
235
237
|
.catch((error) => {
|
|
236
238
|
this.log.error(`Error closing connection: ${error.message}`);
|
|
@@ -245,6 +247,7 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
245
247
|
.then(() => {
|
|
246
248
|
this.log.debug(`Subscribe success on topic: ${topic}`);
|
|
247
249
|
this.emit('mqtt_subscribed');
|
|
250
|
+
return;
|
|
248
251
|
})
|
|
249
252
|
.catch((error) => {
|
|
250
253
|
this.log.error(`Subscribe error: ${error} on topic: ${topic}`);
|
|
@@ -325,6 +328,7 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
325
328
|
writeFile(`${filePath}.json`, JSON.stringify(jsonData, null, 2))
|
|
326
329
|
.then(() => {
|
|
327
330
|
this.log.debug(`Successfully wrote to ${filePath}.json`);
|
|
331
|
+
return;
|
|
328
332
|
})
|
|
329
333
|
.catch((error) => {
|
|
330
334
|
this.log.error(`Error writing to ${filePath}.json:`, error);
|
|
@@ -335,6 +339,7 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
335
339
|
writeFile(`${filePath}`, data)
|
|
336
340
|
.then(() => {
|
|
337
341
|
this.log.debug(`Successfully wrote to ${filePath}`);
|
|
342
|
+
return;
|
|
338
343
|
})
|
|
339
344
|
.catch((error) => {
|
|
340
345
|
this.log.error(`Error writing to ${filePath}:`, error);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-zigbee2mqtt",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0-dev-20250711-6299fe0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge-zigbee2mqtt",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.7.0-dev-20250711-6299fe0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"moment": "2.30.1",
|
|
13
|
-
"mqtt": "5.13.
|
|
14
|
-
"node-ansi-logger": "3.
|
|
15
|
-
"node-persist-manager": "
|
|
13
|
+
"mqtt": "5.13.2",
|
|
14
|
+
"node-ansi-logger": "3.1.1",
|
|
15
|
+
"node-persist-manager": "2.0.0"
|
|
16
16
|
},
|
|
17
17
|
"engines": {
|
|
18
|
-
"node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0"
|
|
18
|
+
"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"
|
|
19
19
|
},
|
|
20
20
|
"funding": {
|
|
21
21
|
"type": "buymeacoffee",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"node_modules/@types/node": {
|
|
35
|
-
"version": "
|
|
36
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-
|
|
37
|
-
"integrity": "sha512-
|
|
35
|
+
"version": "24.0.12",
|
|
36
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.12.tgz",
|
|
37
|
+
"integrity": "sha512-LtOrbvDf5ndC9Xi+4QZjVL0woFymF/xSTKZKPgrrl7H7XoeDvnD+E2IclKVDyaK9UM756W/3BXqSU+JEHopA9g==",
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"undici-types": "~
|
|
40
|
+
"undici-types": "~7.8.0"
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"node_modules/@types/readable-stream": {
|
|
@@ -49,6 +49,15 @@
|
|
|
49
49
|
"@types/node": "*"
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
|
+
"node_modules/@types/ws": {
|
|
53
|
+
"version": "8.18.1",
|
|
54
|
+
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
|
|
55
|
+
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"@types/node": "*"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
52
61
|
"node_modules/abort-controller": {
|
|
53
62
|
"version": "3.0.0",
|
|
54
63
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
|
@@ -286,11 +295,13 @@
|
|
|
286
295
|
}
|
|
287
296
|
},
|
|
288
297
|
"node_modules/mqtt": {
|
|
289
|
-
"version": "5.13.
|
|
290
|
-
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.13.
|
|
291
|
-
"integrity": "sha512-
|
|
298
|
+
"version": "5.13.2",
|
|
299
|
+
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.13.2.tgz",
|
|
300
|
+
"integrity": "sha512-21E15qjFMNEddowGtLiMw4wXfzZxd3Iv+q+zC+tJSmY0flEreNgov+8SKrYcapA+pjClaqj+IgJW0jsJsHkmVQ==",
|
|
292
301
|
"license": "MIT",
|
|
293
302
|
"dependencies": {
|
|
303
|
+
"@types/readable-stream": "^4.0.18",
|
|
304
|
+
"@types/ws": "^8.18.1",
|
|
294
305
|
"commist": "^3.2.0",
|
|
295
306
|
"concat-stream": "^2.0.0",
|
|
296
307
|
"debug": "^4.4.0",
|
|
@@ -339,12 +350,13 @@
|
|
|
339
350
|
"license": "MIT"
|
|
340
351
|
},
|
|
341
352
|
"node_modules/node-ansi-logger": {
|
|
342
|
-
"version": "3.
|
|
343
|
-
"resolved": "https://registry.npmjs.org/node-ansi-logger/-/node-ansi-logger-3.
|
|
344
|
-
"integrity": "sha512-
|
|
345
|
-
"
|
|
353
|
+
"version": "3.1.1",
|
|
354
|
+
"resolved": "https://registry.npmjs.org/node-ansi-logger/-/node-ansi-logger-3.1.1.tgz",
|
|
355
|
+
"integrity": "sha512-tFeCSxwiRg5XaNda5nC27alzraZP76nLtUk1JDZqb9byhW4WYaSGL7/lmxFHEI16gypQDMEYljuF+wcG+cPPHw==",
|
|
356
|
+
"hasShrinkwrap": true,
|
|
357
|
+
"license": "Apache-2.0",
|
|
346
358
|
"engines": {
|
|
347
|
-
"node": ">=18.0.0"
|
|
359
|
+
"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"
|
|
348
360
|
},
|
|
349
361
|
"funding": {
|
|
350
362
|
"type": "buymeacoffee",
|
|
@@ -364,15 +376,15 @@
|
|
|
364
376
|
}
|
|
365
377
|
},
|
|
366
378
|
"node_modules/node-persist-manager": {
|
|
367
|
-
"version": "
|
|
368
|
-
"resolved": "https://registry.npmjs.org/node-persist-manager/-/node-persist-manager-
|
|
369
|
-
"integrity": "sha512-
|
|
379
|
+
"version": "2.0.0",
|
|
380
|
+
"resolved": "https://registry.npmjs.org/node-persist-manager/-/node-persist-manager-2.0.0.tgz",
|
|
381
|
+
"integrity": "sha512-jpgOqCCn4ZEnIr4WcvqkyyGmmLJarV6aUyBlDQdG1G84X9UUmOmI1W2OZtc9K0z375CYWhjtGEXaY7GXNiEOfA==",
|
|
370
382
|
"license": "MIT",
|
|
371
383
|
"dependencies": {
|
|
372
|
-
"node-persist": "
|
|
384
|
+
"node-persist": "4.0.4"
|
|
373
385
|
},
|
|
374
386
|
"engines": {
|
|
375
|
-
"node": ">=18.0.0"
|
|
387
|
+
"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"
|
|
376
388
|
},
|
|
377
389
|
"funding": {
|
|
378
390
|
"type": "buymeacoffee",
|
|
@@ -472,9 +484,9 @@
|
|
|
472
484
|
}
|
|
473
485
|
},
|
|
474
486
|
"node_modules/socks": {
|
|
475
|
-
"version": "2.8.
|
|
476
|
-
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.
|
|
477
|
-
"integrity": "sha512-
|
|
487
|
+
"version": "2.8.5",
|
|
488
|
+
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz",
|
|
489
|
+
"integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==",
|
|
478
490
|
"license": "MIT",
|
|
479
491
|
"dependencies": {
|
|
480
492
|
"ip-address": "^9.0.5",
|
|
@@ -522,9 +534,9 @@
|
|
|
522
534
|
"license": "MIT"
|
|
523
535
|
},
|
|
524
536
|
"node_modules/undici-types": {
|
|
525
|
-
"version": "
|
|
526
|
-
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-
|
|
527
|
-
"integrity": "sha512-
|
|
537
|
+
"version": "7.8.0",
|
|
538
|
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
|
|
539
|
+
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
|
|
528
540
|
"license": "MIT"
|
|
529
541
|
},
|
|
530
542
|
"node_modules/util-deprecate": {
|
|
@@ -568,9 +580,9 @@
|
|
|
568
580
|
}
|
|
569
581
|
},
|
|
570
582
|
"node_modules/ws": {
|
|
571
|
-
"version": "8.18.
|
|
572
|
-
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.
|
|
573
|
-
"integrity": "sha512-
|
|
583
|
+
"version": "8.18.3",
|
|
584
|
+
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
|
|
585
|
+
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
|
|
574
586
|
"license": "MIT",
|
|
575
587
|
"engines": {
|
|
576
588
|
"node": ">=10.0.0"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-zigbee2mqtt",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0-dev-20250711-6299fe0",
|
|
4
4
|
"description": "Matterbridge zigbee2mqtt plugin",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"zigbee2mqtt"
|
|
39
39
|
],
|
|
40
40
|
"engines": {
|
|
41
|
-
"node": ">=18.0.0 <19.0.0 || >=20.0.0 <21.0.0 || >=22.0.0"
|
|
41
|
+
"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"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"moment": "2.30.1",
|
|
45
|
-
"mqtt": "5.13.
|
|
46
|
-
"node-ansi-logger": "3.
|
|
47
|
-
"node-persist-manager": "
|
|
45
|
+
"mqtt": "5.13.2",
|
|
46
|
+
"node-ansi-logger": "3.1.1",
|
|
47
|
+
"node-persist-manager": "2.0.0"
|
|
48
48
|
}
|
|
49
49
|
}
|
package/CODEOWNERS
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@Luligu
|