zigbee-herdsman-converters 15.0.61 → 15.0.63
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 +14 -2
- package/converters/toZigbee.js +56 -29
- package/devices/aurora_lighting.js +7 -0
- package/devices/lidl.js +2 -2
- package/devices/namron.js +1 -1
- package/devices/philips.js +14 -0
- package/devices/seastar_intelligence.js +5 -0
- package/devices/sonoff.js +1 -1
- package/devices/tuya.js +2 -2
- package/devices/xiaomi.js +5 -0
- package/lib/constants.js +1 -0
- package/lib/exposes.js +1 -1
- package/lib/ota/zigbeeOTA.js +15 -1
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -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
|
};
|
|
@@ -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',
|
package/converters/toZigbee.js
CHANGED
|
@@ -1222,24 +1222,69 @@ const converters = {
|
|
|
1222
1222
|
key: ['weekly_schedule'],
|
|
1223
1223
|
convertSet: async (entity, key, value, meta) => {
|
|
1224
1224
|
const payload = {
|
|
1225
|
-
numoftrans: value.numoftrans,
|
|
1226
1225
|
dayofweek: value.dayofweek,
|
|
1227
|
-
mode: value.mode,
|
|
1228
1226
|
transitions: value.transitions,
|
|
1229
1227
|
};
|
|
1230
1228
|
|
|
1229
|
+
if (Array.isArray(payload.transitions)) {
|
|
1230
|
+
// calculate numoftrans
|
|
1231
|
+
if (typeof value.numoftrans !== 'undefined') {
|
|
1232
|
+
meta.logger.warn(`weekly_schedule: igonoring provided numoftrans value (${JSON.stringify(value.numoftrans)}),\
|
|
1233
|
+
this is now calculated automatically`);
|
|
1234
|
+
}
|
|
1235
|
+
payload.numoftrans = payload.transitions.length;
|
|
1231
1236
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1237
|
+
// mode is calculated below
|
|
1238
|
+
if (typeof value.mode !== 'undefined') {
|
|
1239
|
+
meta.logger.warn(
|
|
1240
|
+
`weekly_schedule: igonoring provided mode value (${JSON.stringify(value.mode)}),\
|
|
1241
|
+
this is now calculated automatically`);
|
|
1242
|
+
}
|
|
1243
|
+
payload.mode = [];
|
|
1244
|
+
|
|
1245
|
+
// transform transition payload values if needed
|
|
1246
|
+
for (const elem of payload.transitions) {
|
|
1247
|
+
// update payload.mode if needed
|
|
1248
|
+
if (elem.hasOwnProperty('heatSetpoint') && !payload.mode.includes('heat')) {
|
|
1249
|
+
payload.mode.push('heat');
|
|
1250
|
+
}
|
|
1251
|
+
if (elem.hasOwnProperty('coolSetpoint') && !payload.mode.includes('cool')) {
|
|
1252
|
+
payload.mode.push('cool');
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
// transform setpoint values if numeric
|
|
1256
|
+
if (typeof elem['heatSetpoint'] === 'number') {
|
|
1257
|
+
elem['heatSetpoint'] = Math.round(elem['heatSetpoint'] * 100);
|
|
1258
|
+
}
|
|
1259
|
+
if (typeof elem['coolSetpoint'] === 'number') {
|
|
1260
|
+
elem['coolSetpoint'] = Math.round(elem['coolSetpoint'] * 100);
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
// accept 24h time notation (e.g. 19:30)
|
|
1264
|
+
if (typeof elem['transitionTime'] === 'string') {
|
|
1265
|
+
const time = elem['transitionTime'].split(':');
|
|
1266
|
+
if ((time.length != 2) || isNaN(time[0]) || isNaN(time[1])) {
|
|
1267
|
+
meta.logger.warn(
|
|
1268
|
+
`weekly_schedule: expected 24h time notation (e.g. 19:30) but got '${elem['transitionTime']}'!`,
|
|
1269
|
+
);
|
|
1270
|
+
} else {
|
|
1271
|
+
elem['transitionTime'] = ((parseInt(time[0]) * 60) + parseInt(time[1]));
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1240
1274
|
}
|
|
1241
|
-
|
|
1275
|
+
} else {
|
|
1276
|
+
meta.logger.error('weekly_schedule: transitions is not an array!');
|
|
1277
|
+
return;
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
// map array of desired modes to bitmask
|
|
1281
|
+
let mode = 0;
|
|
1282
|
+
for (let m of payload.mode) {
|
|
1283
|
+
// lookup mode bit
|
|
1284
|
+
m = utils.getKey(constants.thermostatScheduleMode, m.toLowerCase(), m, Number);
|
|
1285
|
+
mode |= (1 << m);
|
|
1242
1286
|
}
|
|
1287
|
+
payload.mode = mode;
|
|
1243
1288
|
|
|
1244
1289
|
// map array of days to desired dayofweek bitmask
|
|
1245
1290
|
if (typeof payload.dayofweek === 'string') payload.dayofweek = [payload.dayofweek];
|
|
@@ -1253,24 +1298,6 @@ const converters = {
|
|
|
1253
1298
|
payload.dayofweek = dayofweek;
|
|
1254
1299
|
}
|
|
1255
1300
|
|
|
1256
|
-
for (const elem of payload['transitions']) {
|
|
1257
|
-
if (typeof elem['heatSetpoint'] === 'number') {
|
|
1258
|
-
elem['heatSetpoint'] = Math.round(elem['heatSetpoint'] * 100);
|
|
1259
|
-
}
|
|
1260
|
-
if (typeof elem['coolSetpoint'] === 'number') {
|
|
1261
|
-
elem['coolSetpoint'] = Math.round(elem['coolSetpoint'] * 100);
|
|
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
|
-
}
|
|
1273
|
-
}
|
|
1274
1301
|
await entity.command('hvacThermostat', 'setWeeklySchedule', payload, utils.getOptions(meta.mapped, entity));
|
|
1275
1302
|
},
|
|
1276
1303
|
convertGet: async (entity, key, meta) => {
|
|
@@ -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/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/namron.js
CHANGED
|
@@ -452,7 +452,7 @@ module.exports = [
|
|
|
452
452
|
const time = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000 + ((new Date())
|
|
453
453
|
.getTimezoneOffset() * -1) * 60);
|
|
454
454
|
const values = {time: time};
|
|
455
|
-
endpoint.write('genTime', values);
|
|
455
|
+
await endpoint.write('genTime', values);
|
|
456
456
|
} catch (error) {/* Do nothing*/}
|
|
457
457
|
}, hours24);
|
|
458
458
|
globalStore.putValue(device, 'time', interval);
|
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',
|
|
@@ -1781,6 +1788,13 @@ module.exports = [
|
|
|
1781
1788
|
description: 'Hue Centura',
|
|
1782
1789
|
extend: philips.extend.light_onoff_brightness_colortemp_color(),
|
|
1783
1790
|
},
|
|
1791
|
+
{
|
|
1792
|
+
zigbeeModel: ['LWV007'],
|
|
1793
|
+
model: '9290030523',
|
|
1794
|
+
vendor: 'Philips',
|
|
1795
|
+
description: 'Hue white filament Edison ST72 LED',
|
|
1796
|
+
extend: philips.extend.light_onoff_brightness(),
|
|
1797
|
+
},
|
|
1784
1798
|
{
|
|
1785
1799
|
zigbeeModel: ['5055148P7'],
|
|
1786
1800
|
model: '5055148P7',
|
|
@@ -7,5 +7,10 @@ module.exports = [
|
|
|
7
7
|
vendor: 'Fischer & Honsel',
|
|
8
8
|
description: 'LED Tischleuchte Beta Zig',
|
|
9
9
|
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
|
|
10
|
+
endpoint: (device) => {
|
|
11
|
+
// https://github.com/Koenkk/zigbee-herdsman-converters/issues/5463
|
|
12
|
+
const endpoint = device.endpoints.find((e) => e.inputClusters.includes(6)).ID;
|
|
13
|
+
return {'default': endpoint};
|
|
14
|
+
},
|
|
10
15
|
},
|
|
11
16
|
];
|
package/devices/sonoff.js
CHANGED
|
@@ -216,7 +216,7 @@ module.exports = [
|
|
|
216
216
|
model: 'S40ZBTPB',
|
|
217
217
|
vendor: 'SONOFF',
|
|
218
218
|
description: '15A Zigbee smart plug',
|
|
219
|
-
extend: extend.switch(),
|
|
219
|
+
extend: extend.switch({disablePowerOnBehavior: true}),
|
|
220
220
|
fromZigbee: [fz.on_off_skip_duplicate_transaction],
|
|
221
221
|
ota: ota.zigbeeOTA,
|
|
222
222
|
configure: async (device, coordinatorEndpoint, logger) => {
|
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',
|
|
@@ -3415,7 +3415,7 @@ module.exports = [
|
|
|
3415
3415
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, tuya.fz.power_outage_memory,
|
|
3416
3416
|
fz.tuya_relay_din_led_indicator],
|
|
3417
3417
|
toZigbee: [tz.on_off, tuya.tz.power_on_behavior, tz.tuya_relay_din_led_indicator],
|
|
3418
|
-
whiteLabel: [{vendor: 'MatSee Plus', model: 'ATMS1602Z'}],
|
|
3418
|
+
whiteLabel: [{vendor: 'MatSee Plus', model: 'ATMS1602Z'}, {vendor: 'Tongou', model: 'TO-Q-SY1-JZT'}],
|
|
3419
3419
|
ota: ota.zigbeeOTA,
|
|
3420
3420
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
3421
3421
|
const endpoint = device.getEndpoint(1);
|
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
|
package/lib/constants.js
CHANGED
package/lib/exposes.js
CHANGED
|
@@ -626,7 +626,7 @@ module.exports = {
|
|
|
626
626
|
power_outage_memory: () => new Binary('power_outage_memory', access.ALL, true, false).withDescription('Enable/disable the power outage memory, this recovers the on/off mode after power failure'),
|
|
627
627
|
presence: () => new Binary('presence', access.STATE, true, false).withDescription('Indicates whether the device detected presence'),
|
|
628
628
|
pressure: () => new Numeric('pressure', access.STATE).withUnit('hPa').withDescription('The measured atmospheric pressure'),
|
|
629
|
-
programming_operation_mode: () => new Enum('programming_operation_mode', access.ALL, ['setpoint', 'schedule', 'eco']).withDescription('Controls how programming affects the thermostat. Possible values: setpoint (only use specified setpoint), schedule (follow programmed setpoint schedule). Changing this value does not clear programmed schedules.'),
|
|
629
|
+
programming_operation_mode: () => new Enum('programming_operation_mode', access.ALL, ['setpoint', 'schedule', 'schedule_with_preheat', 'eco']).withDescription('Controls how programming affects the thermostat. Possible values: setpoint (only use specified setpoint), schedule (follow programmed setpoint schedule), schedule_with_preheat (follow programmed setpoint schedule with pre-heating). Changing this value does not clear programmed schedules.'),
|
|
630
630
|
smoke: () => new Binary('smoke', access.STATE, true, false).withDescription('Indicates whether the device detected smoke'),
|
|
631
631
|
soil_moisture: () => new Numeric('soil_moisture', access.STATE).withUnit('%').withDescription('Measured soil moisture value'),
|
|
632
632
|
sos: () => new Binary('sos', access.STATE, true, false).withDescription('SOS alarm'),
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.63",
|
|
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": "*",
|