matterbridge-zigbee2mqtt 2.4.5-dev.1 → 2.4.5-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 +1 -1
- package/dist/entity.js +30 -17
- package/dist/platform.js +3 -2
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,7 +12,7 @@ All notable changes to this project will be documented in this file.
|
|
|
12
12
|
|
|
13
13
|
### Fixed
|
|
14
14
|
|
|
15
|
-
- [endpoint]: Fix thermostat bug.
|
|
15
|
+
- [endpoint]: Fix thermostat bug (thanks https://github.com/robvanoostenrijk).
|
|
16
16
|
|
|
17
17
|
<a href="https://www.buymeacoffee.com/luligugithub">
|
|
18
18
|
<img src="./yellow-button.png" alt="Buy me a coffee" width="120">
|
package/dist/entity.js
CHANGED
|
@@ -135,6 +135,12 @@ export class ZigbeeEntity extends EventEmitter {
|
|
|
135
135
|
this.updateAttributeIfChanged(this.bridgedDevice, undefined, WindowCovering.Cluster.id, 'targetPositionLiftPercent100ths', position);
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
+
if (key === 'current_heating_setpoint' && 'system_mode' in payload && payload['system_mode'] === 'heat' && isValidNumber(value)) {
|
|
139
|
+
this.updateAttributeIfChanged(this.bridgedDevice, undefined, Thermostat.Cluster.id, 'occupiedHeatingSetpoint', value * 100);
|
|
140
|
+
}
|
|
141
|
+
if (key === 'current_heating_setpoint' && 'system_mode' in payload && payload['system_mode'] === 'cool' && isValidNumber(value)) {
|
|
142
|
+
this.updateAttributeIfChanged(this.bridgedDevice, undefined, Thermostat.Cluster.id, 'occupiedCoolingSetpoint', value * 100);
|
|
143
|
+
}
|
|
138
144
|
if (key === 'color_temp' && 'color_mode' in payload && payload['color_mode'] === 'color_temp') {
|
|
139
145
|
this.updateAttributeIfChanged(this.bridgedDevice, undefined, ColorControl.Cluster.id, 'colorMode', ColorControl.ColorMode.ColorTemperatureMireds);
|
|
140
146
|
this.updateAttributeIfChanged(this.bridgedDevice, undefined, ColorControl.Cluster.id, 'colorTemperatureMireds', Math.max(147, Math.min(500, typeof value === 'number' ? value : 0)));
|
|
@@ -173,12 +179,18 @@ export class ZigbeeEntity extends EventEmitter {
|
|
|
173
179
|
});
|
|
174
180
|
}
|
|
175
181
|
destroy() {
|
|
182
|
+
this.removeAllListeners();
|
|
176
183
|
if (this.colorTimeout)
|
|
177
184
|
clearTimeout(this.colorTimeout);
|
|
178
185
|
this.colorTimeout = undefined;
|
|
179
186
|
if (this.thermostatTimeout)
|
|
180
187
|
clearTimeout(this.thermostatTimeout);
|
|
181
188
|
this.thermostatTimeout = undefined;
|
|
189
|
+
this.device = undefined;
|
|
190
|
+
this.group = undefined;
|
|
191
|
+
this.bridgedDevice = undefined;
|
|
192
|
+
this.mutableDevice.clear();
|
|
193
|
+
this.propertyMap.clear();
|
|
182
194
|
}
|
|
183
195
|
addBridgedDeviceBasicInformation() {
|
|
184
196
|
if (!this.bridgedDevice)
|
|
@@ -431,6 +443,7 @@ export class ZigbeeGroup extends ZigbeeEntity {
|
|
|
431
443
|
zigbeeGroup.bridgedDevice.addRequiredClusterServers();
|
|
432
444
|
if (!zigbeeGroup.bridgedDevice || !zigbeeGroup.verifyMutableDevice(zigbeeGroup.bridgedDevice))
|
|
433
445
|
return zigbeeGroup;
|
|
446
|
+
zigbeeGroup.mutableDevice.clear();
|
|
434
447
|
zigbeeGroup.logPropertyMap();
|
|
435
448
|
if (isSwitch || isLight) {
|
|
436
449
|
if (isSwitch && !isLight)
|
|
@@ -559,7 +572,7 @@ export class ZigbeeGroup extends ZigbeeEntity {
|
|
|
559
572
|
zigbeeGroup.bridgedDevice.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', (newValue, oldValue) => {
|
|
560
573
|
zigbeeGroup.bridgedDevice?.log.info(`Thermostat occupiedCoolingSetpoint changed from ${oldValue / 100} to ${newValue / 100}`);
|
|
561
574
|
zigbeeGroup.bridgedDevice?.log.info(`Setting thermostat occupiedCoolingSetpoint to ${newValue / 100}`);
|
|
562
|
-
zigbeeGroup.publishCommand('CurrentCoolingSetpoint', group.friendly_name, {
|
|
575
|
+
zigbeeGroup.publishCommand('CurrentCoolingSetpoint', group.friendly_name, { current_heating_setpoint: Math.round(newValue / 100) });
|
|
563
576
|
zigbeeGroup.publishCommand('OccupiedCoolingSetpoint', group.friendly_name, { occupied_cooling_setpoint: Math.round(newValue / 100) });
|
|
564
577
|
zigbeeGroup.noUpdate = true;
|
|
565
578
|
zigbeeGroup.thermostatTimeout = setTimeout(() => {
|
|
@@ -588,10 +601,11 @@ export const z2ms = [
|
|
|
588
601
|
{ type: 'cover', name: 'position', property: 'position', deviceType: coverDevice, cluster: WindowCovering.Cluster.id, attribute: 'currentPositionLiftPercent100ths' },
|
|
589
602
|
{ type: 'lock', name: 'state', property: 'state', deviceType: doorLockDevice, cluster: DoorLock.Cluster.id, attribute: 'lockState', converter: (value) => { return value === 'LOCK' ? DoorLock.LockState.Locked : DoorLock.LockState.Unlocked; } },
|
|
590
603
|
{ type: 'climate', name: 'local_temperature', property: 'local_temperature', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'localTemperature', converter: (value) => { return Math.max(-5000, Math.min(5000, value * 100)); } },
|
|
591
|
-
{ type: 'climate', name: 'current_heating_setpoint', property: 'current_heating_setpoint', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'occupiedHeatingSetpoint'
|
|
592
|
-
{ type: 'climate', name: 'current_cooling_setpoint', property: 'current_cooling_setpoint', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'occupiedCoolingSetpoint', converter: (value) => { return Math.max(-5000, Math.min(5000, value * 100)); } },
|
|
604
|
+
{ type: 'climate', name: 'current_heating_setpoint', property: 'current_heating_setpoint', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'occupiedHeatingSetpoint' },
|
|
593
605
|
{ type: 'climate', name: 'occupied_heating_setpoint', property: 'occupied_heating_setpoint', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'occupiedHeatingSetpoint', converter: (value) => { return Math.max(-5000, Math.min(5000, value * 100)); } },
|
|
594
606
|
{ type: 'climate', name: 'occupied_cooling_setpoint', property: 'occupied_cooling_setpoint', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'occupiedCoolingSetpoint', converter: (value) => { return Math.max(-5000, Math.min(5000, value * 100)); } },
|
|
607
|
+
{ type: 'climate', name: 'unoccupied_heating_setpoint', property: 'unoccupied_heating_setpoint', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'occupiedHeatingSetpoint', converter: (value) => { return Math.max(-5000, Math.min(5000, value * 100)); } },
|
|
608
|
+
{ type: 'climate', name: 'unoccupied_cooling_setpoint', property: 'unoccupied_cooling_setpoint', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'occupiedCoolingSetpoint', converter: (value) => { return Math.max(-5000, Math.min(5000, value * 100)); } },
|
|
595
609
|
{ type: 'climate', name: 'running_state', property: 'running_state', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'thermostatRunningMode', valueLookup: ['idle', '', '', 'cool', 'heat'] },
|
|
596
610
|
{ type: 'climate', name: 'system_mode', property: 'system_mode', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'systemMode', valueLookup: ['off', 'auto', '', 'cool', 'heat'] },
|
|
597
611
|
{ type: '', name: 'min_temperature_limit', property: 'min_temperature_limit', deviceType: thermostatDevice, cluster: Thermostat.Cluster.id, attribute: 'minHeatSetpointLimit', converter: (value) => { return Math.max(-5000, Math.min(5000, value * 100)); } },
|
|
@@ -920,25 +934,28 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
920
934
|
}
|
|
921
935
|
}
|
|
922
936
|
if (mainEndpoint.clusterServersIds.includes(Thermostat.Cluster.id)) {
|
|
923
|
-
const
|
|
924
|
-
const
|
|
937
|
+
const system_mode = zigbeeDevice.propertyMap.get('system_mode');
|
|
938
|
+
const system_mode_values = system_mode?.values;
|
|
939
|
+
const heat = zigbeeDevice.propertyMap.get('occupied_heating_setpoint') || zigbeeDevice.propertyMap.get('unoccupied_heating_setpoint');
|
|
940
|
+
const cool = zigbeeDevice.propertyMap.get('occupied_cooling_setpoint') || zigbeeDevice.propertyMap.get('unoccupied_cooling_setpoint');
|
|
925
941
|
const minHeating = heat && heat.value_min !== undefined && !isNaN(heat.value_min) ? heat.value_min : 0;
|
|
926
942
|
const maxHeating = heat && heat.value_max !== undefined && !isNaN(heat.value_max) ? heat.value_max : 50;
|
|
927
943
|
const minCooling = cool && cool.value_min !== undefined && !isNaN(cool.value_min) ? cool.value_min : 0;
|
|
928
944
|
const maxCooling = cool && cool.value_max !== undefined && !isNaN(cool.value_max) ? cool.value_max : 50;
|
|
929
|
-
zigbeeDevice.log.debug(`Configuring device ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} Thermostat cluster with heating ${CYAN}${heat ? 'supported' : 'not supported'}${db} cooling ${CYAN}${cool ? 'supported' : 'not supported'}${db} ` +
|
|
945
|
+
zigbeeDevice.log.debug(`Configuring device ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} Thermostat cluster with heating ${CYAN}${heat ? 'supported' : '(un)occupied not supported'}${db} cooling ${CYAN}${cool ? 'supported' : '(un)occupied not supported'}${db} ` +
|
|
946
|
+
`system_mode ${CYAN}${system_mode_values ?? 'not supported'}${db} ` +
|
|
930
947
|
`minHeating ${CYAN}${minHeating}${db} maxHeating ${CYAN}${maxHeating}${db} minCooling ${CYAN}${minCooling}${db} maxCooling ${CYAN}${maxCooling}${db}`);
|
|
931
|
-
if (heat && !cool) {
|
|
948
|
+
if ((heat && !cool) || (!system_mode_values?.includes('auto') && system_mode_values?.includes('heat'))) {
|
|
932
949
|
zigbeeDevice.propertyMap.delete('running_state');
|
|
933
950
|
zigbeeDevice.bridgedDevice.createDefaultHeatingThermostatClusterServer(undefined, undefined, minHeating, maxHeating);
|
|
934
951
|
mainEndpoint.clusterServersIds.splice(mainEndpoint.clusterServersIds.indexOf(Thermostat.Cluster.id), 1);
|
|
935
952
|
}
|
|
936
|
-
else if (!heat && cool) {
|
|
953
|
+
else if ((!heat && cool) || (!system_mode_values?.includes('auto') && system_mode_values?.includes('cool'))) {
|
|
937
954
|
zigbeeDevice.propertyMap.delete('running_state');
|
|
938
955
|
zigbeeDevice.bridgedDevice.createDefaultCoolingThermostatClusterServer(undefined, undefined, minCooling, maxCooling);
|
|
939
956
|
mainEndpoint.clusterServersIds.splice(mainEndpoint.clusterServersIds.indexOf(Thermostat.Cluster.id), 1);
|
|
940
957
|
}
|
|
941
|
-
else
|
|
958
|
+
else {
|
|
942
959
|
zigbeeDevice.bridgedDevice.createDefaultThermostatClusterServer(undefined, undefined, undefined, undefined, minHeating, maxHeating, minCooling, maxCooling);
|
|
943
960
|
mainEndpoint.clusterServersIds.splice(mainEndpoint.clusterServersIds.indexOf(Thermostat.Cluster.id), 1);
|
|
944
961
|
}
|
|
@@ -1169,23 +1186,19 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
1169
1186
|
const setpoint = Math.round(t / 100 + request.amount / 10);
|
|
1170
1187
|
if (zigbeeDevice.propertyMap.has('current_heating_setpoint')) {
|
|
1171
1188
|
zigbeeDevice.publishCommand('OccupiedHeatingSetpoint', device.friendly_name, { current_heating_setpoint: setpoint });
|
|
1172
|
-
zigbeeDevice.log.debug('Command setpointRaiseLower sent:', debugStringify({ current_heating_setpoint: setpoint }));
|
|
1173
1189
|
}
|
|
1174
1190
|
else if (zigbeeDevice.propertyMap.has('occupied_heating_setpoint')) {
|
|
1175
1191
|
zigbeeDevice.publishCommand('OccupiedHeatingSetpoint', device.friendly_name, { occupied_heating_setpoint: setpoint });
|
|
1176
|
-
zigbeeDevice.log.debug('Command setpointRaiseLower sent:', debugStringify({ occupied_heating_setpoint: setpoint }));
|
|
1177
1192
|
}
|
|
1178
1193
|
}
|
|
1179
1194
|
if (request.mode === Thermostat.SetpointRaiseLowerMode.Cool || request.mode === Thermostat.SetpointRaiseLowerMode.Both) {
|
|
1180
1195
|
const t = zigbeeDevice.bridgedDevice?.getAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', zigbeeDevice.log);
|
|
1181
1196
|
const setpoint = Math.round(t / 100 + request.amount / 10);
|
|
1182
|
-
if (zigbeeDevice.propertyMap.has('
|
|
1183
|
-
zigbeeDevice.publishCommand('OccupiedCoolingSetpoint', device.friendly_name, {
|
|
1184
|
-
zigbeeDevice.log.debug('Command setpointRaiseLower sent:', debugStringify({ current_cooling_setpoint: setpoint }));
|
|
1197
|
+
if (zigbeeDevice.propertyMap.has('current_heating_setpoint')) {
|
|
1198
|
+
zigbeeDevice.publishCommand('OccupiedCoolingSetpoint', device.friendly_name, { current_heating_setpoint: setpoint });
|
|
1185
1199
|
}
|
|
1186
1200
|
else if (zigbeeDevice.propertyMap.has('occupied_cooling_setpoint')) {
|
|
1187
1201
|
zigbeeDevice.publishCommand('OccupiedCoolingSetpoint', device.friendly_name, { occupied_cooling_setpoint: setpoint });
|
|
1188
|
-
zigbeeDevice.log.debug('Command setpointRaiseLower sent:', debugStringify({ occupied_cooling_setpoint: setpoint }));
|
|
1189
1202
|
}
|
|
1190
1203
|
}
|
|
1191
1204
|
});
|
|
@@ -1213,8 +1226,8 @@ export class ZigbeeDevice extends ZigbeeEntity {
|
|
|
1213
1226
|
if (zigbeeDevice.bridgedDevice.hasAttributeServer(ThermostatCluster.id, 'occupiedCoolingSetpoint'))
|
|
1214
1227
|
zigbeeDevice.bridgedDevice.subscribeAttribute(ThermostatCluster.id, 'occupiedCoolingSetpoint', async (value) => {
|
|
1215
1228
|
zigbeeDevice.log.debug(`Subscribe occupiedCoolingSetpoint called for ${zigbeeDevice.ien}${device.friendly_name}${rs}${db} with:`, value);
|
|
1216
|
-
if (zigbeeDevice.propertyMap.has('
|
|
1217
|
-
zigbeeDevice.publishCommand('OccupiedCoolingSetpoint', device.friendly_name, {
|
|
1229
|
+
if (zigbeeDevice.propertyMap.has('current_heating_setpoint'))
|
|
1230
|
+
zigbeeDevice.publishCommand('OccupiedCoolingSetpoint', device.friendly_name, { current_heating_setpoint: Math.round(value / 100) });
|
|
1218
1231
|
else if (zigbeeDevice.propertyMap.has('occupied_cooling_setpoint'))
|
|
1219
1232
|
zigbeeDevice.publishCommand('OccupiedCoolingSetpoint', device.friendly_name, { occupied_cooling_setpoint: Math.round(value / 100) });
|
|
1220
1233
|
zigbeeDevice.noUpdate = true;
|
package/dist/platform.js
CHANGED
|
@@ -223,7 +223,7 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
223
223
|
this.z2m.on('device_interview', async (friendly_name, ieee_address, status, supported) => {
|
|
224
224
|
this.log.info(`zigbee2MQTT sent device_interview device: ${friendly_name} ieee_address: ${ieee_address} status: ${status} supported: ${supported}`);
|
|
225
225
|
if (status === 'successful' && supported) {
|
|
226
|
-
if (!this.
|
|
226
|
+
if (!this.validateDevice(friendly_name))
|
|
227
227
|
return;
|
|
228
228
|
this.log.info(`Registering device: ${friendly_name}`);
|
|
229
229
|
const bridgedDevice = this.z2mBridgeDevices?.find((device) => device.friendly_name === friendly_name);
|
|
@@ -243,7 +243,7 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
243
243
|
});
|
|
244
244
|
this.z2m.on('group_add', async (friendly_name, id, status) => {
|
|
245
245
|
this.log.info(`zigbee2MQTT sent group_add friendly_name: ${friendly_name} id ${id} status ${status}`);
|
|
246
|
-
if (!this.
|
|
246
|
+
if (!this.validateDevice(friendly_name))
|
|
247
247
|
return;
|
|
248
248
|
this.log.info(`Registering group: ${friendly_name}`);
|
|
249
249
|
const bridgedGroup = this.z2mBridgeGroups?.find((group) => group.friendly_name === friendly_name);
|
|
@@ -479,6 +479,7 @@ export class ZigbeePlatform extends MatterbridgeDynamicPlatform {
|
|
|
479
479
|
if (entity) {
|
|
480
480
|
this.log.info(`Removing device: ${friendly_name}`);
|
|
481
481
|
await this.unregisterDevice(entity.bridgedDevice);
|
|
482
|
+
entity.destroy();
|
|
482
483
|
this.zigbeeEntities = this.zigbeeEntities.filter((entity) => entity.entityName !== friendly_name);
|
|
483
484
|
this.bridgedDevices = this.bridgedDevices.filter((device) => device.deviceName !== friendly_name);
|
|
484
485
|
}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "matterbridge-zigbee2mqtt",
|
|
3
|
-
"version": "2.4.5-dev.
|
|
3
|
+
"version": "2.4.5-dev.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "matterbridge-zigbee2mqtt",
|
|
9
|
-
"version": "2.4.5-dev.
|
|
9
|
+
"version": "2.4.5-dev.3",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"moment": "2.30.1",
|