zigbee-herdsman-converters 15.0.60 → 15.0.62
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/converters/fromZigbee.js +19 -7
- package/converters/toZigbee.js +39 -3
- package/devices/aurora_lighting.js +7 -0
- package/devices/develco.js +13 -7
- package/devices/ikea.js +18 -5
- package/devices/lidl.js +2 -2
- package/devices/lifecontrol.js +1 -1
- package/devices/osram.js +2 -2
- package/devices/philips.js +7 -0
- package/devices/salus_controls.js +6 -6
- package/devices/stelpro.js +1 -1
- package/devices/tuya.js +9 -8
- package/devices/xiaomi.js +7 -1
- package/lib/constants.js +8 -2
- package/lib/exposes.js +2 -1
- package/lib/ota/zigbeeOTA.js +15 -1
- package/lib/tuya.js +0 -1
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -158,7 +158,7 @@ const converters = {
|
|
|
158
158
|
const days = [];
|
|
159
159
|
for (let i = 0; i < 8; i++) {
|
|
160
160
|
if ((msg.data['dayofweek'] & 1<<i) > 0) {
|
|
161
|
-
days.push(constants.
|
|
161
|
+
days.push(constants.thermostatDayOfWeek[i]);
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
|
|
@@ -412,7 +412,7 @@ const converters = {
|
|
|
412
412
|
cluster: 'pm25Measurement',
|
|
413
413
|
type: ['attributeReport', 'readResponse'],
|
|
414
414
|
convert: (model, msg, publish, options, meta) => {
|
|
415
|
-
if (msg.data
|
|
415
|
+
if (msg.data.hasOwnProperty('measuredValue')) {
|
|
416
416
|
return {pm25: msg.data['measuredValue']};
|
|
417
417
|
}
|
|
418
418
|
},
|
|
@@ -1514,8 +1514,8 @@ const converters = {
|
|
|
1514
1514
|
const payload = {
|
|
1515
1515
|
action: postfixWithEndpointName(`color_move`, msg, model, meta),
|
|
1516
1516
|
action_color: {
|
|
1517
|
-
x: precisionRound(msg.data.colorx /
|
|
1518
|
-
y: precisionRound(msg.data.colory /
|
|
1517
|
+
x: precisionRound(msg.data.colorx / 65535, 3),
|
|
1518
|
+
y: precisionRound(msg.data.colory / 65535, 3),
|
|
1519
1519
|
},
|
|
1520
1520
|
action_transition_time: msg.data.transtime,
|
|
1521
1521
|
};
|
|
@@ -2191,7 +2191,7 @@ const converters = {
|
|
|
2191
2191
|
return {
|
|
2192
2192
|
// Same as in hvacThermostat:getWeeklyScheduleRsp hvacThermostat:setWeeklySchedule cluster format
|
|
2193
2193
|
weekly_schedule: {
|
|
2194
|
-
days: [constants.
|
|
2194
|
+
days: [constants.thermostatDayOfWeek[dayOfWeek]],
|
|
2195
2195
|
transitions: dataToTransitions(value, maxTransitions, dataOffset),
|
|
2196
2196
|
},
|
|
2197
2197
|
};
|
|
@@ -2886,6 +2886,18 @@ const converters = {
|
|
|
2886
2886
|
return {action: `${button}${clickMapping[msg.data[3]]}`};
|
|
2887
2887
|
},
|
|
2888
2888
|
},
|
|
2889
|
+
tuya_switch_scene: {
|
|
2890
|
+
cluster: 'genOnOff',
|
|
2891
|
+
type: 'raw',
|
|
2892
|
+
convert: (model, msg, publish, options, meta) => {
|
|
2893
|
+
if (hasAlreadyProcessedMessage(msg, model, msg.data[1])) return;
|
|
2894
|
+
// Since it is a non standard ZCL command, no default response is send from zigbee-herdsman
|
|
2895
|
+
// Send the defaultResponse here, otherwise the second button click delays.
|
|
2896
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/8149
|
|
2897
|
+
msg.endpoint.defaultResponse(0xfd, 0, 6, msg.data[1]).catch((error) => {});
|
|
2898
|
+
return {action: 'switch_scene', action_scene: msg.data[3]};
|
|
2899
|
+
},
|
|
2900
|
+
},
|
|
2889
2901
|
tuya_water_leak: {
|
|
2890
2902
|
cluster: 'manuSpecificTuya',
|
|
2891
2903
|
type: 'commandDataReport',
|
|
@@ -3533,8 +3545,8 @@ const converters = {
|
|
|
3533
3545
|
}
|
|
3534
3546
|
if (msg.data.hasOwnProperty('danfossDayOfWeek')) {
|
|
3535
3547
|
result[postfixWithEndpointName('day_of_week', msg, model, meta)] =
|
|
3536
|
-
constants.
|
|
3537
|
-
constants.
|
|
3548
|
+
constants.thermostatDayOfWeek.hasOwnProperty(msg.data['danfossDayOfWeek']) ?
|
|
3549
|
+
constants.thermostatDayOfWeek[msg.data['danfossDayOfWeek']] :
|
|
3538
3550
|
msg.data['danfossDayOfWeek'];
|
|
3539
3551
|
}
|
|
3540
3552
|
if (msg.data.hasOwnProperty('danfossTriggerTime')) {
|
package/converters/toZigbee.js
CHANGED
|
@@ -1227,13 +1227,49 @@ const converters = {
|
|
|
1227
1227
|
mode: value.mode,
|
|
1228
1228
|
transitions: value.transitions,
|
|
1229
1229
|
};
|
|
1230
|
+
|
|
1231
|
+
|
|
1232
|
+
// map array of desired modes to bitmask
|
|
1233
|
+
if (typeof payload.dayofweek === 'string') payload.dayofweek = [payload.dayofweek];
|
|
1234
|
+
if (Array.isArray(payload.dayofweek)) {
|
|
1235
|
+
let mode = 0;
|
|
1236
|
+
for (let m of payload.mode) {
|
|
1237
|
+
// lookup mode bit
|
|
1238
|
+
m = utils.getKey(constants.thermostatScheduleMode, m.toLowerCase(), m, Number);
|
|
1239
|
+
mode |= (1 << m);
|
|
1240
|
+
}
|
|
1241
|
+
payload.mode = mode;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
// map array of days to desired dayofweek bitmask
|
|
1245
|
+
if (typeof payload.dayofweek === 'string') payload.dayofweek = [payload.dayofweek];
|
|
1246
|
+
if (Array.isArray(payload.dayofweek)) {
|
|
1247
|
+
let dayofweek = 0;
|
|
1248
|
+
for (let d of payload.dayofweek) {
|
|
1249
|
+
// lookup dayofweek bit
|
|
1250
|
+
d = utils.getKey(constants.thermostatDayOfWeek, d.toLowerCase(), d, Number);
|
|
1251
|
+
dayofweek |= (1 << d);
|
|
1252
|
+
}
|
|
1253
|
+
payload.dayofweek = dayofweek;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1230
1256
|
for (const elem of payload['transitions']) {
|
|
1231
|
-
if (typeof elem['heatSetpoint']
|
|
1257
|
+
if (typeof elem['heatSetpoint'] === 'number') {
|
|
1232
1258
|
elem['heatSetpoint'] = Math.round(elem['heatSetpoint'] * 100);
|
|
1233
1259
|
}
|
|
1234
|
-
if (typeof elem['coolSetpoint']
|
|
1260
|
+
if (typeof elem['coolSetpoint'] === 'number') {
|
|
1235
1261
|
elem['coolSetpoint'] = Math.round(elem['coolSetpoint'] * 100);
|
|
1236
1262
|
}
|
|
1263
|
+
|
|
1264
|
+
// accept 24h time notation (e.g. 19:30)
|
|
1265
|
+
if (typeof elem['transitionTime'] === 'string') {
|
|
1266
|
+
const time = elem['transitionTime'].split(':');
|
|
1267
|
+
if ((time.length != 2) || isNaN(time[0]) || isNaN(time[1])) {
|
|
1268
|
+
meta.logger.warn(`weekly_schedule: expected 24h time notation (e.g. 19:30) but got '${elem['transitionTime']}'!`);
|
|
1269
|
+
} else {
|
|
1270
|
+
elem['transitionTime'] = ((parseInt(time[0]) * 60) + parseInt(time[1]));
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1237
1273
|
}
|
|
1238
1274
|
await entity.command('hvacThermostat', 'setWeeklySchedule', payload, utils.getOptions(meta.mapped, entity));
|
|
1239
1275
|
},
|
|
@@ -2904,7 +2940,7 @@ const converters = {
|
|
|
2904
2940
|
danfoss_day_of_week: {
|
|
2905
2941
|
key: ['day_of_week'],
|
|
2906
2942
|
convertSet: async (entity, key, value, meta) => {
|
|
2907
|
-
const payload = {'danfossDayOfWeek': utils.getKey(constants.
|
|
2943
|
+
const payload = {'danfossDayOfWeek': utils.getKey(constants.thermostatDayOfWeek, value, undefined, Number)};
|
|
2908
2944
|
await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
|
|
2909
2945
|
return {readAfterWriteTime: 200, state: {'day_of_week': value}};
|
|
2910
2946
|
},
|
|
@@ -115,6 +115,13 @@ module.exports = [
|
|
|
115
115
|
meta: {turnsOffAtBrightness1: true},
|
|
116
116
|
extend: extend.light_onoff_brightness(),
|
|
117
117
|
},
|
|
118
|
+
{
|
|
119
|
+
zigbeeModel: ['FWBulb51AU'],
|
|
120
|
+
model: 'AU-A1GSZ9B/27',
|
|
121
|
+
vendor: 'Aurora Lighting',
|
|
122
|
+
description: 'AOne 9W smart GLS B22',
|
|
123
|
+
extend: extend.light_onoff_brightness(),
|
|
124
|
+
},
|
|
118
125
|
{
|
|
119
126
|
zigbeeModel: ['FWGU10Bulb50AU', 'FWGU10Bulb01UK'],
|
|
120
127
|
model: 'AU-A1GUZB5/30',
|
package/devices/develco.js
CHANGED
|
@@ -135,22 +135,28 @@ const develco = {
|
|
|
135
135
|
type: ['attributeReport', 'readResponse'],
|
|
136
136
|
options: [exposes.options.precision('voc'), exposes.options.calibration('voc')],
|
|
137
137
|
convert: (model, msg, publish, options, meta) => {
|
|
138
|
-
|
|
138
|
+
// from Sensirion_Gas_Sensors_SGP3x_TVOC_Concept.pdf
|
|
139
|
+
// "The mean molar mass of this mixture is 110 g/mol and hence,
|
|
140
|
+
// 1 ppb TVOC corresponds to 4.5 μg/m3."
|
|
141
|
+
const vocPpb = parseFloat(msg.data['measuredValue']);
|
|
142
|
+
const voc = vocPpb * 4.5;
|
|
139
143
|
const vocProperty = utils.postfixWithEndpointName('voc', msg, model, meta);
|
|
140
144
|
|
|
145
|
+
// from aqszb-110-technical-manual-air-quality-sensor-04-08-20.pdf page 6, section 2.2 voc
|
|
146
|
+
// this contains a ppb to level mapping table.
|
|
141
147
|
let airQuality;
|
|
142
148
|
const airQualityProperty = utils.postfixWithEndpointName('air_quality', msg, model, meta);
|
|
143
|
-
if (
|
|
149
|
+
if (vocPpb <= 65) {
|
|
144
150
|
airQuality = 'excellent';
|
|
145
|
-
} else if (
|
|
151
|
+
} else if (vocPpb <= 220) {
|
|
146
152
|
airQuality = 'good';
|
|
147
|
-
} else if (
|
|
153
|
+
} else if (vocPpb <= 660) {
|
|
148
154
|
airQuality = 'moderate';
|
|
149
|
-
} else if (
|
|
155
|
+
} else if (vocPpb <= 2200) {
|
|
150
156
|
airQuality = 'poor';
|
|
151
|
-
} else if (
|
|
157
|
+
} else if (vocPpb <= 5500) {
|
|
152
158
|
airQuality = 'unhealthy';
|
|
153
|
-
} else if (
|
|
159
|
+
} else if (vocPpb > 5500) {
|
|
154
160
|
airQuality = 'out_of_range';
|
|
155
161
|
} else {
|
|
156
162
|
airQuality = 'unknown';
|
package/devices/ikea.js
CHANGED
|
@@ -181,6 +181,15 @@ const ikea = {
|
|
|
181
181
|
return state;
|
|
182
182
|
},
|
|
183
183
|
},
|
|
184
|
+
ikea_voc_index: {
|
|
185
|
+
cluster: 'msIkeaVocIndexMeasurement',
|
|
186
|
+
type: ['attributeReport', 'readResponse'],
|
|
187
|
+
convert: (model, msg, publish, options, meta) => {
|
|
188
|
+
if (msg.data.hasOwnProperty('measuredValue')) {
|
|
189
|
+
return {voc_index: msg.data['measuredValue']};
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
},
|
|
184
193
|
battery: {
|
|
185
194
|
cluster: 'genPowerCfg',
|
|
186
195
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -428,10 +437,10 @@ module.exports = [
|
|
|
428
437
|
extend: tradfriExtend.light_onoff_brightness_colortemp(),
|
|
429
438
|
},
|
|
430
439
|
{
|
|
431
|
-
zigbeeModel: ['TRADFRI bulb E14 WS globe 470lm'],
|
|
440
|
+
zigbeeModel: ['TRADFRI bulb E14 WS globe 470lm', 'TRADFRI bulb E12 WS globe 450lm'],
|
|
432
441
|
model: 'LED2101G4',
|
|
433
442
|
vendor: 'IKEA',
|
|
434
|
-
description: 'TRADFRI bulb E14 WS globe
|
|
443
|
+
description: 'TRADFRI bulb E12/E14 WS globe 450/470 lumen, dimmable, white spectrum, opal white',
|
|
435
444
|
extend: tradfriExtend.light_onoff_brightness_colortemp(),
|
|
436
445
|
},
|
|
437
446
|
{
|
|
@@ -1032,13 +1041,13 @@ module.exports = [
|
|
|
1032
1041
|
model: 'E2112',
|
|
1033
1042
|
vendor: 'IKEA',
|
|
1034
1043
|
description: 'Vindstyrka air quality and humidity sensor',
|
|
1035
|
-
fromZigbee: [fz.temperature, fz.humidity, fz.pm25],
|
|
1044
|
+
fromZigbee: [fz.temperature, fz.humidity, fz.pm25, ikea.fz.ikea_voc_index],
|
|
1036
1045
|
toZigbee: [],
|
|
1037
|
-
exposes: [e.temperature(), e.humidity(), e.pm25()],
|
|
1046
|
+
exposes: [e.temperature(), e.humidity(), e.pm25(), e.voc_index().withDescription('Sensirion VOC index')],
|
|
1038
1047
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1039
1048
|
const ep = device.getEndpoint(1);
|
|
1040
1049
|
await reporting.bind(ep, coordinatorEndpoint,
|
|
1041
|
-
['msTemperatureMeasurement', 'msRelativeHumidity', 'pm25Measurement']);
|
|
1050
|
+
['msTemperatureMeasurement', 'msRelativeHumidity', 'pm25Measurement', 'msIkeaVocIndexMeasurement']);
|
|
1042
1051
|
await ep.configureReporting('msTemperatureMeasurement', [{
|
|
1043
1052
|
attribute: 'measuredValue',
|
|
1044
1053
|
minimumReportInterval: 60, maximumReportInterval: 120,
|
|
@@ -1051,6 +1060,10 @@ module.exports = [
|
|
|
1051
1060
|
attribute: 'measuredValueIkea',
|
|
1052
1061
|
minimumReportInterval: 60, maximumReportInterval: 120, reportableChange: 2,
|
|
1053
1062
|
}]);
|
|
1063
|
+
await ep.configureReporting('msIkeaVocIndexMeasurement', [{
|
|
1064
|
+
attribute: 'measuredValue',
|
|
1065
|
+
minimumReportInterval: 60, maximumReportInterval: 120,
|
|
1066
|
+
}]);
|
|
1054
1067
|
},
|
|
1055
1068
|
},
|
|
1056
1069
|
];
|
package/devices/lidl.js
CHANGED
|
@@ -575,8 +575,8 @@ module.exports = [
|
|
|
575
575
|
vendor: 'Lidl',
|
|
576
576
|
description: 'Livarno Lux switch and dimming light remote control',
|
|
577
577
|
exposes: [e.action(['on', 'off', 'brightness_stop', 'brightness_step_up', 'brightness_step_down', 'brightness_move_up',
|
|
578
|
-
'brightness_move_down'])],
|
|
579
|
-
fromZigbee: [fz.command_on, fz.command_off, fz.command_step, fz.command_move, fz.command_stop],
|
|
578
|
+
'brightness_move_down', 'switch_scene'])],
|
|
579
|
+
fromZigbee: [fz.command_on, fz.command_off, fz.command_step, fz.command_move, fz.command_stop, fz.tuya_switch_scene],
|
|
580
580
|
toZigbee: [],
|
|
581
581
|
},
|
|
582
582
|
{
|
package/devices/lifecontrol.js
CHANGED
|
@@ -87,6 +87,6 @@ module.exports = [
|
|
|
87
87
|
fromZigbee: [fz.lifecontrolVoc, fz.battery],
|
|
88
88
|
toZigbee: [],
|
|
89
89
|
meta: {battery: {dontDividePercentage: true}},
|
|
90
|
-
exposes: [e.temperature(), e.humidity(), e.voc(), e.eco2(), e.battery()],
|
|
90
|
+
exposes: [e.temperature(), e.humidity(), e.voc().withUnit('ppb'), e.eco2(), e.battery()],
|
|
91
91
|
},
|
|
92
92
|
];
|
package/devices/osram.js
CHANGED
|
@@ -412,7 +412,7 @@ module.exports = [
|
|
|
412
412
|
model: '4062172044776_1',
|
|
413
413
|
vendor: 'OSRAM',
|
|
414
414
|
description: 'Zigbee 3.0 DALI CONV LI dimmer for DALI-based luminaires (only one device)',
|
|
415
|
-
extend: extend.ledvance.light_onoff_brightness(),
|
|
415
|
+
extend: extend.ledvance.light_onoff_brightness({disablePowerOnBehavior: true}),
|
|
416
416
|
ota: ota.zigbeeOTA,
|
|
417
417
|
},
|
|
418
418
|
{
|
|
@@ -425,7 +425,7 @@ module.exports = [
|
|
|
425
425
|
fz.command_toggle, fz.command_move, fz.command_stop],
|
|
426
426
|
extend: extend.ledvance.light_onoff_brightness({noConfigure: true}),
|
|
427
427
|
exposes: [e.action(['toggle', 'brightness_move_up', 'brightness_move_down', 'brightness_stop']),
|
|
428
|
-
...extend.ledvance.light_onoff_brightness({noConfigure: true}).exposes],
|
|
428
|
+
...extend.ledvance.light_onoff_brightness({noConfigure: true, disablePowerOnBehavior: true}).exposes],
|
|
429
429
|
ota: ota.zigbeeOTA,
|
|
430
430
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
431
431
|
await reporting.bind(device.getEndpoint(10), coordinatorEndpoint, ['genLevelCtrl', 'genOnOff']);
|
package/devices/philips.js
CHANGED
|
@@ -962,6 +962,13 @@ module.exports = [
|
|
|
962
962
|
description: 'Hue White and color ambiance Play Lightbar',
|
|
963
963
|
extend: philips.extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
964
964
|
},
|
|
965
|
+
{
|
|
966
|
+
zigbeeModel: ['915005988501'],
|
|
967
|
+
model: '915005988501',
|
|
968
|
+
vendor: 'Philips',
|
|
969
|
+
description: 'Play gradient light tube large',
|
|
970
|
+
extend: philips.extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
971
|
+
},
|
|
965
972
|
{
|
|
966
973
|
zigbeeModel: ['LTW011', 'LTB002'],
|
|
967
974
|
model: '464800',
|
|
@@ -108,19 +108,19 @@ module.exports = [
|
|
|
108
108
|
zigbeeModel: [
|
|
109
109
|
'SS909ZB',
|
|
110
110
|
'PS600',
|
|
111
|
-
'PS600\u0000\u0000 �\u0001 ��\u0000\u0000\t\u0001@\u0011�u\u0000\u0000\u0018&\n\u0005\u0000B',
|
|
112
|
-
'PS600\u0000\u0000 �\u0001 ��\u0000\u0000\t\u0001@\u0011�u\u0000\u0000\u0018\u0006\n\u0005\u0000',
|
|
113
|
-
'PS600\u0000\u0000 �\u0001 ��\u0000\u0000\t\u0001@\u0011�u\u0000\u0000\u0018\u0006\n\u0005\u0000B',
|
|
114
111
|
],
|
|
115
112
|
model: 'PS600',
|
|
116
113
|
vendor: 'Salus Controls',
|
|
117
114
|
description: 'Pipe temperature sensor',
|
|
118
|
-
fromZigbee: [fz.temperature],
|
|
115
|
+
fromZigbee: [fz.temperature, fz.battery],
|
|
119
116
|
toZigbee: [],
|
|
120
|
-
|
|
117
|
+
meta: {battery: {voltageToPercentage: '3V_2500'}},
|
|
118
|
+
exposes: [e.battery(), e.temperature()],
|
|
121
119
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
122
120
|
const endpoint = device.getEndpoint(9);
|
|
123
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement']);
|
|
121
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg']);
|
|
122
|
+
await reporting.temperature(endpoint);
|
|
123
|
+
await reporting.batteryVoltage(endpoint);
|
|
124
124
|
},
|
|
125
125
|
ota: ota.salus,
|
|
126
126
|
},
|
package/devices/stelpro.js
CHANGED
|
@@ -64,7 +64,7 @@ module.exports = [
|
|
|
64
64
|
tz.stelpro_thermostat_outdoor_temperature],
|
|
65
65
|
exposes: [e.local_temperature(), e.keypad_lockout(),
|
|
66
66
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 30, 0.5).withLocalTemperature()
|
|
67
|
-
.withSystemMode(['off', 'auto', 'heat']).withRunningState(['idle', 'heat'])],
|
|
67
|
+
.withSystemMode(['off', 'auto', 'heat']).withRunningState(['idle', 'heat']).withPiHeatingDemand()],
|
|
68
68
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
69
69
|
const endpoint = device.getEndpoint(25);
|
|
70
70
|
const binds = ['genBasic', 'genIdentify', 'genGroups', 'hvacThermostat', 'hvacUserInterfaceCfg', 'msTemperatureMeasurement'];
|
package/devices/tuya.js
CHANGED
|
@@ -1740,7 +1740,7 @@ module.exports = [
|
|
|
1740
1740
|
configure: tuya.configureMagicPacket,
|
|
1741
1741
|
},
|
|
1742
1742
|
{
|
|
1743
|
-
fingerprint:
|
|
1743
|
+
fingerprint: tuya.fingerprint('SM0201', ['_TYZB01_cbiezpds', '_TYZB01_zqvwka4k']),
|
|
1744
1744
|
model: 'SM0201',
|
|
1745
1745
|
vendor: 'TuYa',
|
|
1746
1746
|
description: 'Temperature & humidity sensor with LED screen',
|
|
@@ -2552,7 +2552,7 @@ module.exports = [
|
|
|
2552
2552
|
},
|
|
2553
2553
|
},
|
|
2554
2554
|
],
|
|
2555
|
-
[1, 'system_mode', tuya.valueConverterBasic.lookup({'auto': tuya.enum(1), 'off': tuya.enum(2), '
|
|
2555
|
+
[1, 'system_mode', tuya.valueConverterBasic.lookup({'auto': tuya.enum(1), 'off': tuya.enum(2), 'heat': tuya.enum(3)})],
|
|
2556
2556
|
[1, 'preset', tuya.valueConverterBasic.lookup(
|
|
2557
2557
|
{'auto': tuya.enum(0), 'manual': tuya.enum(1), 'off': tuya.enum(2), 'on': tuya.enum(3)})],
|
|
2558
2558
|
[2, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
|
|
@@ -2604,11 +2604,12 @@ module.exports = [
|
|
|
2604
2604
|
});
|
|
2605
2605
|
try {
|
|
2606
2606
|
await reporting.currentSummDelivered(endpoint);
|
|
2607
|
-
|
|
2607
|
+
await reporting.rmsVoltage(endpoint, {change: 5});
|
|
2608
|
+
await reporting.rmsCurrent(endpoint, {change: 50});
|
|
2609
|
+
await reporting.activePower(endpoint, {change: 10});
|
|
2610
|
+
} catch (error) {/* fails for some https://github.com/Koenkk/zigbee2mqtt/issues/11179
|
|
2611
|
+
and https://github.com/Koenkk/zigbee2mqtt/issues/16864 */}
|
|
2608
2612
|
await endpoint.read('genOnOff', ['onOff', 'moesStartUpOnOff', 'tuyaBacklightMode']);
|
|
2609
|
-
await reporting.rmsVoltage(endpoint, {change: 5});
|
|
2610
|
-
await reporting.rmsCurrent(endpoint, {change: 50});
|
|
2611
|
-
await reporting.activePower(endpoint, {change: 10});
|
|
2612
2613
|
},
|
|
2613
2614
|
options: [exposes.options.measurement_poll_interval()],
|
|
2614
2615
|
// This device doesn't support reporting correctly.
|
|
@@ -3414,7 +3415,7 @@ module.exports = [
|
|
|
3414
3415
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, tuya.fz.power_outage_memory,
|
|
3415
3416
|
fz.tuya_relay_din_led_indicator],
|
|
3416
3417
|
toZigbee: [tz.on_off, tuya.tz.power_on_behavior, tz.tuya_relay_din_led_indicator],
|
|
3417
|
-
whiteLabel: [{vendor: 'MatSee Plus', model: 'ATMS1602Z'}],
|
|
3418
|
+
whiteLabel: [{vendor: 'MatSee Plus', model: 'ATMS1602Z'}, {vendor: 'Tongou', model: 'TO-Q-SY1-JZT'}],
|
|
3418
3419
|
ota: ota.zigbeeOTA,
|
|
3419
3420
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
3420
3421
|
const endpoint = device.getEndpoint(1);
|
|
@@ -3571,7 +3572,7 @@ module.exports = [
|
|
|
3571
3572
|
tuyaDatapoints: [
|
|
3572
3573
|
[1, 'presence', tuya.valueConverter.trueFalse1],
|
|
3573
3574
|
[2, 'radar_sensitivity', tuya.valueConverter.raw],
|
|
3574
|
-
[102, 'occupancy', tuya.valueConverter.
|
|
3575
|
+
[102, 'occupancy', tuya.valueConverter.trueFalse1],
|
|
3575
3576
|
[103, 'illuminance_lux', tuya.valueConverter.raw],
|
|
3576
3577
|
[105, 'tumble_switch', tuya.valueConverter.plus1],
|
|
3577
3578
|
[106, 'tumble_alarm_time', tuya.valueConverter.raw],
|
package/devices/xiaomi.js
CHANGED
|
@@ -142,6 +142,11 @@ const fzLocal = {
|
|
|
142
142
|
result['schedule_settings'] = trv.stringifySchedule(schedule);
|
|
143
143
|
break;
|
|
144
144
|
}
|
|
145
|
+
case 0x00EE: {
|
|
146
|
+
meta.device.meta.aqaraFileVersion = value;
|
|
147
|
+
meta.device.save();
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
145
150
|
case 0xfff2:
|
|
146
151
|
case 0x00ff: // 4e:27:49:bb:24:b6:30:dd:74:de:53:76:89:44:c4:81
|
|
147
152
|
case 0x027c: // 0x00
|
|
@@ -2769,7 +2774,7 @@ module.exports = [
|
|
|
2769
2774
|
fromZigbee: [fz.xiaomi_tvoc, fz.battery, fz.temperature, fz.humidity, fz.aqara_opple],
|
|
2770
2775
|
toZigbee: [tzLocal.VOCKQJK11LM_display_unit],
|
|
2771
2776
|
meta: {battery: {voltageToPercentage: '3V_2850_3000'}},
|
|
2772
|
-
exposes: [e.temperature(), e.humidity(), e.voc(), e.device_temperature(), e.battery(), e.battery_voltage(),
|
|
2777
|
+
exposes: [e.temperature(), e.humidity(), e.voc().withUnit('ppb'), e.device_temperature(), e.battery(), e.battery_voltage(),
|
|
2773
2778
|
exposes.enum('display_unit', ea.ALL, ['mgm3_celsius', 'ppb_celsius', 'mgm3_fahrenheit', 'ppb_fahrenheit'])
|
|
2774
2779
|
.withDescription('Units to show on the display')],
|
|
2775
2780
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -2908,6 +2913,7 @@ module.exports = [
|
|
|
2908
2913
|
toZigbee: [],
|
|
2909
2914
|
meta: {battery: {voltageToPercentage: '3V_2850_3000'}},
|
|
2910
2915
|
exposes: [e.contact(), e.battery(), e.battery_voltage()],
|
|
2916
|
+
ota: ota.zigbeeOTA,
|
|
2911
2917
|
},
|
|
2912
2918
|
{
|
|
2913
2919
|
zigbeeModel: ['lumi.plug.sacn02'],
|
package/lib/constants.js
CHANGED
|
@@ -45,7 +45,7 @@ const thermostatRunningMode= {
|
|
|
45
45
|
4: 'heat',
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
const
|
|
48
|
+
const thermostatDayOfWeek = {
|
|
49
49
|
0: 'sunday',
|
|
50
50
|
1: 'monday',
|
|
51
51
|
2: 'tuesday',
|
|
@@ -83,6 +83,11 @@ const thermostatAcLouverPositions = {
|
|
|
83
83
|
5: 'three_quarters_open',
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
+
const thermostatScheduleMode = {
|
|
87
|
+
0: 'heat',
|
|
88
|
+
1: 'cool',
|
|
89
|
+
};
|
|
90
|
+
|
|
86
91
|
const fanMode = {
|
|
87
92
|
'off': 0,
|
|
88
93
|
'low': 1,
|
|
@@ -284,7 +289,8 @@ module.exports = {
|
|
|
284
289
|
thermostatRunningStates,
|
|
285
290
|
thermostatRunningMode,
|
|
286
291
|
thermostatAcLouverPositions,
|
|
287
|
-
|
|
292
|
+
thermostatScheduleMode,
|
|
293
|
+
thermostatDayOfWeek,
|
|
288
294
|
fanMode,
|
|
289
295
|
temperatureDisplayMode,
|
|
290
296
|
danfossAdaptionRunControl,
|
package/lib/exposes.js
CHANGED
|
@@ -642,7 +642,8 @@ module.exports = {
|
|
|
642
642
|
valve_state: () => new Binary('valve_state', access.STATE, 'OPEN', 'CLOSED').withDescription('Valve state if open or closed'),
|
|
643
643
|
valve_detection: () => new Switch().withState('valve_detection', true).setAccess('state', access.STATE_SET),
|
|
644
644
|
vibration: () => new Binary('vibration', access.STATE, true, false).withDescription('Indicates whether the device detected vibration'),
|
|
645
|
-
voc: () => new Numeric('voc', access.STATE).withUnit('
|
|
645
|
+
voc: () => new Numeric('voc', access.STATE).withUnit('µg/m³').withDescription('Measured VOC value'),
|
|
646
|
+
voc_index: () => new Numeric('voc_index', access.STATE).withDescription('VOC index'),
|
|
646
647
|
voltage: () => new Numeric('voltage', access.STATE).withUnit('V').withDescription('Measured electrical potential value'),
|
|
647
648
|
voltage_phase_b: () => new Numeric('voltage_phase_b', access.STATE).withUnit('V').withDescription('Measured electrical potential value on phase B'),
|
|
648
649
|
voltage_phase_c: () => new Numeric('voltage_phase_c', access.STATE).withUnit('V').withDescription('Measured electrical potential value on phase C'),
|
package/lib/ota/zigbeeOTA.js
CHANGED
|
@@ -122,12 +122,26 @@ async function getImageMeta(current, logger, device) {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
+
async function isNewImageAvailable(current, logger, device, getImageMeta) {
|
|
126
|
+
if (device.modelID === 'lumi.airrtc.agl001') {
|
|
127
|
+
// The current.fileVersion which comes from the device is wrong.
|
|
128
|
+
// Use the `aqaraFileVersion` which comes from the aqaraOpple.attributeReport instead.
|
|
129
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/16345#issuecomment-1454835056
|
|
130
|
+
if (!device.meta.aqaraFileVersion) {
|
|
131
|
+
throw new Error(`Did not receive a current fileVersion from 'lumi.airrtc.agl001' yet, please wait some hours and try again`);
|
|
132
|
+
}
|
|
133
|
+
current = {...current, fileVersion: device.meta.aqaraFileVersion};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return common.isNewImageAvailable(current, logger, device, getImageMeta);
|
|
137
|
+
}
|
|
138
|
+
|
|
125
139
|
/**
|
|
126
140
|
* Interface implementation
|
|
127
141
|
*/
|
|
128
142
|
|
|
129
143
|
async function isUpdateAvailable(device, logger, requestPayload=null) {
|
|
130
|
-
return common.isUpdateAvailable(device, logger,
|
|
144
|
+
return common.isUpdateAvailable(device, logger, isNewImageAvailable, requestPayload, getImageMeta);
|
|
131
145
|
}
|
|
132
146
|
|
|
133
147
|
async function updateToLatest(device, logger, onProgress) {
|
package/lib/tuya.js
CHANGED
|
@@ -1232,7 +1232,6 @@ const valueConverterBasic = {
|
|
|
1232
1232
|
const valueConverter = {
|
|
1233
1233
|
trueFalse0: valueConverterBasic.trueFalse(0),
|
|
1234
1234
|
trueFalse1: valueConverterBasic.trueFalse(1),
|
|
1235
|
-
trueFalse2: valueConverterBasic.trueFalse(2),
|
|
1236
1235
|
trueFalseEnum0: valueConverterBasic.trueFalse(new Enum(0)),
|
|
1237
1236
|
onOff: valueConverterBasic.lookup({'ON': true, 'OFF': false}),
|
|
1238
1237
|
powerOnBehavior: valueConverterBasic.lookup({'off': 0, 'on': 1, 'previous': 2}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.62",
|
|
4
4
|
"description": "Collection of device converters to be used with zigbee-herdsman",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"buffer-crc32": "^0.2.13",
|
|
39
39
|
"https-proxy-agent": "^5.0.1",
|
|
40
40
|
"tar-stream": "^3.0.0",
|
|
41
|
-
"zigbee-herdsman": "^0.14.
|
|
41
|
+
"zigbee-herdsman": "^0.14.97"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|