matterbridge-zigbee2mqtt 2.5.0-dev.2 → 2.5.0-dev.3
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 +5 -2
- package/README.md +8 -0
- package/dist/entity.js +11 -0
- package/dist/platform.js +19 -12
- package/dist/zigbee2mqtt.js +10 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -19,7 +19,7 @@ New device types:
|
|
|
19
19
|
|
|
20
20
|
If your controller has issues detecting the new device type, blacklist these devices, restart, wait 5 minutes, remove the blacklist and restart again. This will create a new endpoint on the controller.
|
|
21
21
|
|
|
22
|
-
## [2.5.0] - 2025-05-
|
|
22
|
+
## [2.5.0] - 2025-05-23
|
|
23
23
|
|
|
24
24
|
### Added
|
|
25
25
|
|
|
@@ -27,7 +27,10 @@ If your controller has issues detecting the new device type, blacklist these dev
|
|
|
27
27
|
- [waterLeak]: Added waterLeakDetector device type for zigbee property "water_leak". Default to false (i.e. no alarm) since is not possible to get the property.
|
|
28
28
|
- [rainSensor]: Added rainSensor device type for zigbee property "rain". Default to false (i.e. no alarm) since is not possible to get the property.
|
|
29
29
|
- [smokeSensor]: Added smokeSensor device type for zigbee property "smoke". Default to false (i.e. no alarm) since is not possible to get the property.
|
|
30
|
-
- [colorTemp]: Added conversion from color temperature to rgb for the devices that
|
|
30
|
+
- [colorTemp]: Added conversion from color temperature to rgb for the rgb devices that don't support color temperature.
|
|
31
|
+
- [battery]: Set batChargeLevel to warning if battery is less than 40% and the device doesn't expose battery_low.
|
|
32
|
+
- [battery]: Set batChargeLevel to critical if battery is less than 20% and the device doesn't expose battery_low.
|
|
33
|
+
- [retain]: Send retained mqtt states at startup if z2m has retain enabled.
|
|
31
34
|
|
|
32
35
|
### Changed
|
|
33
36
|
|
package/README.md
CHANGED
|
@@ -224,6 +224,14 @@ The latest release also supports all clusters in the multi endpoints devices (e.
|
|
|
224
224
|
|
|
225
225
|
Since the Matter support in the available ecosystems (controllers) is sometimes limited and, when available, only covers Matter 1.1 specifications, some z2m devices cannot be exposed properly or cannot be exposed at all.
|
|
226
226
|
|
|
227
|
+
## Availability
|
|
228
|
+
|
|
229
|
+
If the availability is enabled in zigbee2mqtt settings, it is exposed.
|
|
230
|
+
|
|
231
|
+
## Retain
|
|
232
|
+
|
|
233
|
+
If the retain option is enabled in zigbee2mqtt settings or device setting, at restart all retained states are updated.
|
|
234
|
+
|
|
227
235
|
## Unsupported devices
|
|
228
236
|
|
|
229
237
|
If one of your devices is not supported out of the box, open an issue and we will try to support it if possible.
|
package/dist/entity.js
CHANGED
|
@@ -86,6 +86,17 @@ export class ZigbeeEntity extends EventEmitter {
|
|
|
86
86
|
return;
|
|
87
87
|
if (key === 'voltage' && this.isDevice && this.device?.power_source === 'Battery')
|
|
88
88
|
key = 'battery_voltage';
|
|
89
|
+
if (key === 'battery' && !('battery_low' in payload) && isValidNumber(value, 0, 100) && this.isDevice && this.device?.power_source === 'Battery') {
|
|
90
|
+
if (value < 20) {
|
|
91
|
+
this.updateAttributeIfChanged(this.bridgedDevice, undefined, PowerSource.Cluster.id, 'batChargeLevel', PowerSource.BatChargeLevel.Critical);
|
|
92
|
+
}
|
|
93
|
+
else if (value < 40) {
|
|
94
|
+
this.updateAttributeIfChanged(this.bridgedDevice, undefined, PowerSource.Cluster.id, 'batChargeLevel', PowerSource.BatChargeLevel.Warning);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.updateAttributeIfChanged(this.bridgedDevice, undefined, PowerSource.Cluster.id, 'batChargeLevel', PowerSource.BatChargeLevel.Ok);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
89
100
|
const propertyMap = this.propertyMap.get(key);
|
|
90
101
|
if (propertyMap) {
|
|
91
102
|
this.log.debug(`Payload entry ${CYAN}${key}${db} => name: ${CYAN}${propertyMap.name}${db} type: ${CYAN}${propertyMap.type === '' ? 'generic' : propertyMap.type}${db} ` +
|
package/dist/platform.js
CHANGED
|
@@ -34,7 +34,8 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
34
34
|
z2mBridgeInfo;
|
|
35
35
|
z2mBridgeDevices;
|
|
36
36
|
z2mBridgeGroups;
|
|
37
|
-
|
|
37
|
+
z2mEntityAvailability = new Map();
|
|
38
|
+
z2mEntityPayload = new Map();
|
|
38
39
|
availabilityTimer;
|
|
39
40
|
constructor(matterbridge, log, config) {
|
|
40
41
|
super(matterbridge, log, config);
|
|
@@ -194,11 +195,14 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
194
195
|
}
|
|
195
196
|
});
|
|
196
197
|
this.z2m.on('availability', (device, available) => {
|
|
197
|
-
this.
|
|
198
|
+
this.z2mEntityAvailability.set(device, available);
|
|
198
199
|
if (available)
|
|
199
|
-
this.log.info(`zigbee2MQTT
|
|
200
|
+
this.log.info(`zigbee2MQTT entity ${device} is ${available ? 'online' : 'offline'}`);
|
|
200
201
|
else
|
|
201
|
-
this.log.warn(`zigbee2MQTT
|
|
202
|
+
this.log.warn(`zigbee2MQTT entity ${device} is ${available ? 'online' : 'offline'}`);
|
|
203
|
+
});
|
|
204
|
+
this.z2m.on('message', (device, payload) => {
|
|
205
|
+
this.z2mEntityPayload.set(device, payload);
|
|
202
206
|
});
|
|
203
207
|
this.z2m.on('permit_join', async (device, time, status) => {
|
|
204
208
|
this.log.info(`zigbee2MQTT sent permit_join device: ${device} time: ${time} status: ${status}`);
|
|
@@ -334,10 +338,6 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
334
338
|
await super.onConfigure();
|
|
335
339
|
this.log.info(`Requesting update for ${this.zigbeeEntities.length} zigbee entities.`);
|
|
336
340
|
for (const bridgedEntity of this.zigbeeEntities) {
|
|
337
|
-
if (bridgedEntity.isDevice && bridgedEntity.device)
|
|
338
|
-
await this.requestDeviceUpdate(bridgedEntity.device);
|
|
339
|
-
if (bridgedEntity.isGroup && bridgedEntity.group)
|
|
340
|
-
await this.requestGroupUpdate(bridgedEntity.group);
|
|
341
341
|
await bridgedEntity.configure();
|
|
342
342
|
if (bridgedEntity.isRouter && bridgedEntity.bridgedDevice) {
|
|
343
343
|
this.log.info(`Configuring router ${bridgedEntity.bridgedDevice?.deviceName}.`);
|
|
@@ -352,15 +352,22 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
352
352
|
bridgedEntity.bridgedDevice?.triggerEvent(DoorLock.Cluster.id, 'lockOperation', { lockOperationType: DoorLock.LockOperationType.Lock, operationSource: DoorLock.OperationSource.Manual, userIndex: null, fabricIndex: null, sourceNode: null }, this.log);
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
|
+
if (bridgedEntity.isDevice && bridgedEntity.device)
|
|
356
|
+
await this.requestDeviceUpdate(bridgedEntity.device);
|
|
357
|
+
if (bridgedEntity.isGroup && bridgedEntity.group)
|
|
358
|
+
await this.requestGroupUpdate(bridgedEntity.group);
|
|
355
359
|
}
|
|
356
360
|
this.availabilityTimer = setTimeout(() => {
|
|
357
|
-
for (const [
|
|
361
|
+
for (const [entity, available] of this.z2mEntityAvailability) {
|
|
358
362
|
if (available)
|
|
359
|
-
this.z2m.emit('ONLINE-' +
|
|
363
|
+
this.z2m.emit('ONLINE-' + entity);
|
|
360
364
|
else
|
|
361
|
-
this.z2m.emit('OFFLINE-' +
|
|
365
|
+
this.z2m.emit('OFFLINE-' + entity);
|
|
366
|
+
}
|
|
367
|
+
for (const [entity, payload] of this.z2mEntityPayload) {
|
|
368
|
+
this.z2m.emit('MESSAGE-' + entity, payload);
|
|
362
369
|
}
|
|
363
|
-
},
|
|
370
|
+
}, 10 * 1000).unref();
|
|
364
371
|
if (this.config.injectPayloads) {
|
|
365
372
|
this.injectTimer = setInterval(() => {
|
|
366
373
|
const data = this.z2m.readConfig(path.join(this.matterbridge.matterbridgeDirectory, this.config.injectPayloads));
|
package/dist/zigbee2mqtt.js
CHANGED
|
@@ -70,6 +70,8 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
70
70
|
await mkdir(dataPath, { recursive: true });
|
|
71
71
|
this.mqttDataPath = dataPath;
|
|
72
72
|
this.log.debug(`Data directory ${this.mqttDataPath} created successfully.`);
|
|
73
|
+
const filePath = path.join(this.mqttDataPath, 'bridge-payloads.txt');
|
|
74
|
+
fs.unlinkSync(filePath);
|
|
73
75
|
}
|
|
74
76
|
catch (e) {
|
|
75
77
|
const error = e;
|
|
@@ -80,6 +82,13 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
80
82
|
this.log.error('Error creating data directory:', error);
|
|
81
83
|
}
|
|
82
84
|
}
|
|
85
|
+
try {
|
|
86
|
+
const filePath = path.join(this.mqttDataPath, 'bridge-payloads.txt');
|
|
87
|
+
fs.unlinkSync(filePath);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
this.log.debug(`Error deleting bridge-payloads.txt: ${error}`);
|
|
91
|
+
}
|
|
83
92
|
}
|
|
84
93
|
getUrl() {
|
|
85
94
|
return 'mqtt://' + this.mqttHost + ':' + this.mqttPort.toString();
|
|
@@ -613,6 +622,7 @@ export class Zigbee2MQTT extends EventEmitter {
|
|
|
613
622
|
else if (service === 'set') {
|
|
614
623
|
}
|
|
615
624
|
else if (service === undefined) {
|
|
625
|
+
this.emit('message', entity, data);
|
|
616
626
|
this.emit('MESSAGE-' + entity, data);
|
|
617
627
|
}
|
|
618
628
|
else {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-zigbee2mqtt",
|
|
3
|
-
"version": "2.5.0-dev.
|
|
3
|
+
"version": "2.5.0-dev.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge-zigbee2mqtt",
|
|
9
|
-
"version": "2.5.0-dev.
|
|
9
|
+
"version": "2.5.0-dev.3",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"moment": "2.30.1",
|