zigbee-herdsman-converters 14.0.317 → 14.0.321
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 +67 -23
- package/converters/toZigbee.js +94 -5
- package/devices/centralite.js +20 -0
- package/devices/elko.js +12 -1
- package/devices/ikea.js +31 -5
- package/devices/innr.js +24 -0
- package/devices/jethome.js +48 -0
- package/devices/keen_home.js +1 -1
- package/devices/leedarson.js +39 -0
- package/devices/moes.js +5 -6
- package/devices/philips.js +11 -2
- package/devices/tuya.js +13 -6
- package/devices/xiaomi.js +17 -1
- package/npm-shrinkwrap.json +167 -154
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -1574,6 +1574,10 @@ const converters = {
|
|
|
1574
1574
|
const result = {};
|
|
1575
1575
|
const data = msg.data;
|
|
1576
1576
|
|
|
1577
|
+
if (data.hasOwnProperty(0x0401)) { // Load
|
|
1578
|
+
result.load = data[0x0401];
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1577
1581
|
if (data.hasOwnProperty(0x0402)) { // Display text
|
|
1578
1582
|
result.display_text = data[0x0402];
|
|
1579
1583
|
}
|
|
@@ -3551,24 +3555,6 @@ const converters = {
|
|
|
3551
3555
|
return {child_lock: value ? 'LOCK' : 'UNLOCK'};
|
|
3552
3556
|
case tuya.dataPoints.moesSbattery:
|
|
3553
3557
|
return {battery: value};
|
|
3554
|
-
case tuya.dataPoints.moesSschedule:
|
|
3555
|
-
return {
|
|
3556
|
-
program_weekday:
|
|
3557
|
-
{weekday: ' ' + value[0] + 'h:' + value[1] + 'm ' + value[2]/2 + '°C' +
|
|
3558
|
-
', ' + value[3] + 'h:' + value[4] + 'm ' + value[5]/2 + '°C' +
|
|
3559
|
-
', ' + value[6] + 'h:' + value[7] + 'm ' + value[8]/2 + '°C' +
|
|
3560
|
-
', ' + value[9] + 'h:' + value[10] + 'm ' + value[11]/2 + '°C '},
|
|
3561
|
-
program_saturday:
|
|
3562
|
-
{saturday: '' + value[12] + 'h:' + value[13] + 'm ' + value[14]/2 + '°C' +
|
|
3563
|
-
', ' + value[15] + 'h:' + value[16] + 'm ' + value[17]/2 + '°C' +
|
|
3564
|
-
', ' + value[18] + 'h:' + value[19] + 'm ' + value[20]/2 + '°C' +
|
|
3565
|
-
', ' + value[21] + 'h:' + value[22] + 'm ' + value[23]/2 + '°C '},
|
|
3566
|
-
program_sunday:
|
|
3567
|
-
{sunday: ' ' + value[24] + 'h:' + value[25] + 'm ' + value[26]/2 + '°C' +
|
|
3568
|
-
', ' + value[27] + 'h:' + value[28] + 'm ' + value[29]/2 + '°C' +
|
|
3569
|
-
', ' + value[30] + 'h:' + value[31] + 'm ' + value[32]/2 + '°C' +
|
|
3570
|
-
', ' + value[33] + 'h:' + value[34] + 'm ' + value[35]/2 + '°C '},
|
|
3571
|
-
};
|
|
3572
3558
|
case tuya.dataPoints.moesSboostHeatingCountdownTimeSet:
|
|
3573
3559
|
return {boost_heating_countdown_time_set: (value)};
|
|
3574
3560
|
case tuya.dataPoints.moesSvalvePosition:
|
|
@@ -3583,6 +3569,18 @@ const converters = {
|
|
|
3583
3569
|
return {max_temperature: value};
|
|
3584
3570
|
case tuya.dataPoints.moesSminTempSet:
|
|
3585
3571
|
return {min_temperature: value};
|
|
3572
|
+
case tuya.dataPoints.moesSschedule: {
|
|
3573
|
+
const items = [];
|
|
3574
|
+
const pMode = [];
|
|
3575
|
+
for (let i = 0; i < 12; i++) {
|
|
3576
|
+
const item = {h: value[i*3], m: value[i*3+1], temp: value[i*3+2] / 2};
|
|
3577
|
+
items[i] = item;
|
|
3578
|
+
pMode[i] = item['h'].toString().padStart(2, '0') + ':' +
|
|
3579
|
+
item['m'].toString().padStart(2, '0') + '/' +
|
|
3580
|
+
item['temp'] + '°C';
|
|
3581
|
+
}
|
|
3582
|
+
return {programming_mode: pMode.join(' ')};
|
|
3583
|
+
}
|
|
3586
3584
|
default:
|
|
3587
3585
|
meta.logger.warn(`zigbee-herdsman-converters:moesS_thermostat: NOT RECOGNIZED DP #${
|
|
3588
3586
|
dp} with data ${JSON.stringify(msg.data)}`);
|
|
@@ -4295,14 +4293,16 @@ const converters = {
|
|
|
4295
4293
|
}
|
|
4296
4294
|
},
|
|
4297
4295
|
},
|
|
4298
|
-
|
|
4299
|
-
cluster: '
|
|
4296
|
+
ikea_air_purifier: {
|
|
4297
|
+
cluster: 'manuSpecificIkeaAirPurifier',
|
|
4300
4298
|
type: ['attributeReport', 'readResponse'],
|
|
4301
4299
|
options: [exposes.options.precision('pm25'), exposes.options.calibration('pm25')],
|
|
4302
4300
|
convert: (model, msg, publish, options, meta) => {
|
|
4303
|
-
|
|
4304
|
-
|
|
4301
|
+
const state = {};
|
|
4302
|
+
|
|
4303
|
+
if (msg.data.hasOwnProperty('particulateMatter25Measurement')) {
|
|
4305
4304
|
const pm25Property = postfixWithEndpointName('pm25', msg, model);
|
|
4305
|
+
let pm25 = parseFloat(msg.data['particulateMatter25Measurement']);
|
|
4306
4306
|
|
|
4307
4307
|
// Air Quality Scale (ikea app):
|
|
4308
4308
|
// 0-35=Good, 35-80=OK, 80+=Not Good
|
|
@@ -4318,8 +4318,52 @@ const converters = {
|
|
|
4318
4318
|
airQuality = 'unknown';
|
|
4319
4319
|
}
|
|
4320
4320
|
|
|
4321
|
-
|
|
4321
|
+
// calibrate and round pm25 unless invalid
|
|
4322
|
+
pm25 = (pm25 == 65535) ? -1 : calibrateAndPrecisionRoundOptions(pm25, options, 'pm25');
|
|
4323
|
+
|
|
4324
|
+
state[pm25Property] = calibrateAndPrecisionRoundOptions(pm25, options, 'pm25');
|
|
4325
|
+
state[airQualityProperty] = airQuality;
|
|
4326
|
+
}
|
|
4327
|
+
|
|
4328
|
+
if (msg.data.hasOwnProperty('filterRunTime')) {
|
|
4329
|
+
// Filter needs to be replaced after 6 months
|
|
4330
|
+
state['replace_filter'] = (parseInt(msg.data['filterRunTime']) >= 259200);
|
|
4331
|
+
}
|
|
4332
|
+
|
|
4333
|
+
if (msg.data.hasOwnProperty('controlPanelLight')) {
|
|
4334
|
+
state['led_enable'] = (msg.data['controlPanelLight'] == 0);
|
|
4335
|
+
}
|
|
4336
|
+
|
|
4337
|
+
if (msg.data.hasOwnProperty('childLock')) {
|
|
4338
|
+
state['child_lock'] = (msg.data['childLock'] > 0 ? 'LOCK' : 'UNLOCK');
|
|
4339
|
+
}
|
|
4340
|
+
|
|
4341
|
+
if (msg.data.hasOwnProperty('fanSpeed')) {
|
|
4342
|
+
let fanSpeed = msg.data['fanSpeed'];
|
|
4343
|
+
if (fanSpeed >= 10) {
|
|
4344
|
+
fanSpeed = (((fanSpeed - 5) * 2) / 10);
|
|
4345
|
+
} else {
|
|
4346
|
+
fanSpeed = 0;
|
|
4347
|
+
}
|
|
4348
|
+
|
|
4349
|
+
state['fan_speed'] = fanSpeed;
|
|
4322
4350
|
}
|
|
4351
|
+
|
|
4352
|
+
if (msg.data.hasOwnProperty('fanMode')) {
|
|
4353
|
+
let fanMode = msg.data['fanMode'];
|
|
4354
|
+
if (fanMode >= 10) {
|
|
4355
|
+
fanMode = (((fanMode - 5) * 2) / 10).toString();
|
|
4356
|
+
} else if (fanMode == 1) {
|
|
4357
|
+
fanMode = 'auto';
|
|
4358
|
+
} else {
|
|
4359
|
+
fanMode = 'off';
|
|
4360
|
+
}
|
|
4361
|
+
|
|
4362
|
+
state['fan_mode'] = fanMode;
|
|
4363
|
+
state['fan_state'] = (fanMode === 'off' ? 'OFF' : 'ON');
|
|
4364
|
+
}
|
|
4365
|
+
|
|
4366
|
+
return state;
|
|
4323
4367
|
},
|
|
4324
4368
|
},
|
|
4325
4369
|
E1524_E1810_levelctrl: {
|
package/converters/toZigbee.js
CHANGED
|
@@ -17,6 +17,7 @@ const manufacturerOptions = {
|
|
|
17
17
|
danfoss: {manufacturerCode: herdsman.Zcl.ManufacturerCode.DANFOSS},
|
|
18
18
|
develco: {manufacturerCode: herdsman.Zcl.ManufacturerCode.DEVELCO},
|
|
19
19
|
hue: {manufacturerCode: herdsman.Zcl.ManufacturerCode.PHILIPS},
|
|
20
|
+
ikea: {manufacturerCode: herdsman.Zcl.ManufacturerCode.IKEA_OF_SWEDEN},
|
|
20
21
|
sinope: {manufacturerCode: herdsman.Zcl.ManufacturerCode.SINOPE_TECH},
|
|
21
22
|
/*
|
|
22
23
|
* Ubisys doesn't accept a manufacturerCode on some commands
|
|
@@ -329,7 +330,7 @@ const converters = {
|
|
|
329
330
|
|
|
330
331
|
let info;
|
|
331
332
|
// https://github.com/Koenkk/zigbee2mqtt/issues/8310 some devices require the info to be reversed.
|
|
332
|
-
if (['SIRZB-110', 'SRAC-23B-ZBSR', 'AV2010/29A'].includes(meta.mapped.model)) {
|
|
333
|
+
if (['SIRZB-110', 'SRAC-23B-ZBSR', 'AV2010/29A', 'AV2010/24A'].includes(meta.mapped.model)) {
|
|
333
334
|
info = (mode[values.mode]) + ((values.strobe ? 1 : 0) << 4) + (level[values.level] << 6);
|
|
334
335
|
} else {
|
|
335
336
|
info = (mode[values.mode] << 4) + ((values.strobe ? 1 : 0) << 2) + (level[values.level]);
|
|
@@ -1378,6 +1379,16 @@ const converters = {
|
|
|
1378
1379
|
// #endregion
|
|
1379
1380
|
|
|
1380
1381
|
// #region Non-generic converters
|
|
1382
|
+
elko_load: {
|
|
1383
|
+
key: ['load'],
|
|
1384
|
+
convertSet: async (entity, key, value, meta) => {
|
|
1385
|
+
await entity.write('hvacThermostat', {'elkoLoad': value});
|
|
1386
|
+
return {state: {load: value}};
|
|
1387
|
+
},
|
|
1388
|
+
convertGet: async (entity, key, meta) => {
|
|
1389
|
+
await entity.read('hvacThermostat', ['elkoLoad']);
|
|
1390
|
+
},
|
|
1391
|
+
},
|
|
1381
1392
|
elko_display_text: {
|
|
1382
1393
|
key: ['display_text'],
|
|
1383
1394
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -1911,10 +1922,69 @@ const converters = {
|
|
|
1911
1922
|
await entity.read('genBasic', [0x0033], manufacturerOptions.hue);
|
|
1912
1923
|
},
|
|
1913
1924
|
},
|
|
1914
|
-
|
|
1925
|
+
ikea_air_purifier_fan_mode: {
|
|
1926
|
+
key: ['fan_mode', 'fan_state'],
|
|
1927
|
+
convertSet: async (entity, key, value, meta) => {
|
|
1928
|
+
if (key == 'fan_state' && value.toLowerCase() == 'on') {
|
|
1929
|
+
value = utils.getMetaValue(entity, meta.mapped, 'fanStateOn', 'allEqual', 'on');
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
let fanMode;
|
|
1933
|
+
switch (value.toLowerCase()) {
|
|
1934
|
+
case 'off':
|
|
1935
|
+
fanMode = 0;
|
|
1936
|
+
break;
|
|
1937
|
+
case 'auto':
|
|
1938
|
+
fanMode = 1;
|
|
1939
|
+
break;
|
|
1940
|
+
default:
|
|
1941
|
+
fanMode = parseInt(((parseInt(value) / 2.0) * 10) + 5);
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
await entity.write('manuSpecificIkeaAirPurifier', {'fanMode': fanMode}, manufacturerOptions.ikea);
|
|
1945
|
+
return {state: {fan_mode: value.toLowerCase(), fan_state: value.toLowerCase() === 'off' ? 'OFF' : 'ON'}};
|
|
1946
|
+
},
|
|
1947
|
+
convertGet: async (entity, key, meta) => {
|
|
1948
|
+
await entity.read('manuSpecificIkeaAirPurifier', ['fanMode']);
|
|
1949
|
+
},
|
|
1950
|
+
},
|
|
1951
|
+
ikea_air_purifier_fan_speed: {
|
|
1952
|
+
key: ['fan_speed'],
|
|
1953
|
+
convertGet: async (entity, key, meta) => {
|
|
1954
|
+
await entity.read('manuSpecificIkeaAirPurifier', ['fanSpeed']);
|
|
1955
|
+
},
|
|
1956
|
+
},
|
|
1957
|
+
ikea_air_purifier_pm25: {
|
|
1915
1958
|
key: ['pm25', 'air_quality'],
|
|
1916
1959
|
convertGet: async (entity, key, meta) => {
|
|
1917
|
-
await entity.read('
|
|
1960
|
+
await entity.read('manuSpecificIkeaAirPurifier', ['particulateMatter25Measurement']);
|
|
1961
|
+
},
|
|
1962
|
+
},
|
|
1963
|
+
ikea_air_purifier_replace_filter: {
|
|
1964
|
+
key: ['replace_filter'],
|
|
1965
|
+
convertGet: async (entity, key, meta) => {
|
|
1966
|
+
await entity.read('manuSpecificIkeaAirPurifier', ['filterRunTime']);
|
|
1967
|
+
},
|
|
1968
|
+
},
|
|
1969
|
+
ikea_air_purifier_child_lock: {
|
|
1970
|
+
key: ['child_lock'],
|
|
1971
|
+
convertSet: async (entity, key, value, meta) => {
|
|
1972
|
+
await entity.write('manuSpecificIkeaAirPurifier', {'childLock': ((value.toLowerCase() === 'lock') ? 1 : 0)},
|
|
1973
|
+
manufacturerOptions.ikea);
|
|
1974
|
+
return {state: {child_lock: ((value.toLowerCase() === 'lock') ? 'LOCK' : 'UNLOCK')}};
|
|
1975
|
+
},
|
|
1976
|
+
convertGet: async (entity, key, meta) => {
|
|
1977
|
+
await entity.read('manuSpecificIkeaAirPurifier', ['childLock']);
|
|
1978
|
+
},
|
|
1979
|
+
},
|
|
1980
|
+
ikea_air_purifier_led_enable: {
|
|
1981
|
+
key: ['led_enable'],
|
|
1982
|
+
convertSet: async (entity, key, value, meta) => {
|
|
1983
|
+
await entity.write('manuSpecificIkeaAirPurifier', {'controlPanelLight': ((value) ? 0 : 1)}, manufacturerOptions.ikea);
|
|
1984
|
+
return {state: {led_enable: ((value) ? true : false)}};
|
|
1985
|
+
},
|
|
1986
|
+
convertGet: async (entity, key, meta) => {
|
|
1987
|
+
await entity.read('manuSpecificIkeaAirPurifier', ['controlPanelLight']);
|
|
1918
1988
|
},
|
|
1919
1989
|
},
|
|
1920
1990
|
RTCGQ13LM_motion_sensitivity: {
|
|
@@ -1962,7 +2032,7 @@ const converters = {
|
|
|
1962
2032
|
xiaomi_switch_power_outage_memory: {
|
|
1963
2033
|
key: ['power_outage_memory'],
|
|
1964
2034
|
convertSet: async (entity, key, value, meta) => {
|
|
1965
|
-
if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
|
|
2035
|
+
if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
|
|
1966
2036
|
'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG31LM', 'QBCZ15LM', 'QBKG20LM', 'QBKG38LM',
|
|
1967
2037
|
'QBKG34LM', 'QBCZ14LM', 'QBKG19LM'].includes(meta.mapped.model)) {
|
|
1968
2038
|
await entity.write('aqaraOpple', {0x0201: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
@@ -1985,7 +2055,7 @@ const converters = {
|
|
|
1985
2055
|
return {state: {power_outage_memory: value}};
|
|
1986
2056
|
},
|
|
1987
2057
|
convertGet: async (entity, key, meta) => {
|
|
1988
|
-
if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
|
|
2058
|
+
if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
|
|
1989
2059
|
'WS-EUK02', 'WS-EUK01', 'QBKG31LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG20LM', 'QBKG34LM', 'QBKG19LM',
|
|
1990
2060
|
'QBKG38LM'].includes(meta.mapped.model)) {
|
|
1991
2061
|
await entity.read('aqaraOpple', [0x0201]);
|
|
@@ -2770,6 +2840,25 @@ const converters = {
|
|
|
2770
2840
|
await tuya.sendDataPointValue(entity, tuya.dataPoints.moesSminTempSet, temp);
|
|
2771
2841
|
},
|
|
2772
2842
|
},
|
|
2843
|
+
moesS_thermostat_schedule_programming: {
|
|
2844
|
+
key: ['programming_mode'],
|
|
2845
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2846
|
+
const payload = [];
|
|
2847
|
+
const items = value.split(' ');
|
|
2848
|
+
for (let i = 0; i < 12; i++) {
|
|
2849
|
+
const hourTemperature = items[i].split('/');
|
|
2850
|
+
const hourMinute = hourTemperature[0].split(':', 2);
|
|
2851
|
+
const h = parseInt(hourMinute[0]);
|
|
2852
|
+
const m = parseInt(hourMinute[1]);
|
|
2853
|
+
const temp = parseInt(hourTemperature[1]);
|
|
2854
|
+
if (h < 0 || h >= 24 || m < 0 || m >= 60 || temp < 5 || temp >= 35) {
|
|
2855
|
+
throw new Error('Invalid hour, minute or temperature of:' + items[i]);
|
|
2856
|
+
}
|
|
2857
|
+
payload[i*3] = h; payload[i*3+1] = m; payload[i*3+2] = temp * 2;
|
|
2858
|
+
}
|
|
2859
|
+
return tuya.sendDataPointRaw(entity, tuya.dataPoints.moesSschedule, payload);
|
|
2860
|
+
},
|
|
2861
|
+
},
|
|
2773
2862
|
tvtwo_thermostat: {
|
|
2774
2863
|
key: [
|
|
2775
2864
|
'window_detection', 'frost_protection', 'child_lock',
|
package/devices/centralite.js
CHANGED
|
@@ -26,6 +26,26 @@ module.exports = [
|
|
|
26
26
|
await reporting.activePower(endpoint);
|
|
27
27
|
},
|
|
28
28
|
},
|
|
29
|
+
{
|
|
30
|
+
zigbeeModel: ['4256050-ZHAC'],
|
|
31
|
+
model: '4256050-ZHAC',
|
|
32
|
+
vendor: 'Centralite',
|
|
33
|
+
description: '3-Series smart dimming outlet',
|
|
34
|
+
fromZigbee: [fz.restorable_brightness, fz.on_off, fz.electrical_measurement],
|
|
35
|
+
toZigbee: [tz.light_onoff_restorable_brightness],
|
|
36
|
+
exposes: [e.light_brightness(), e.power(), e.voltage(), e.current()],
|
|
37
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
38
|
+
const endpoint = device.getEndpoint(1);
|
|
39
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'haElectricalMeasurement']);
|
|
40
|
+
await reporting.onOff(endpoint);
|
|
41
|
+
// 4256050-ZHAC doesn't support reading 'acVoltageMultiplier' or 'acVoltageDivisor'
|
|
42
|
+
await endpoint.read('haElectricalMeasurement', ['acCurrentMultiplier', 'acCurrentDivisor']);
|
|
43
|
+
await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
|
|
44
|
+
await reporting.rmsVoltage(endpoint, {change: 2}); // Voltage reports in V
|
|
45
|
+
await reporting.rmsCurrent(endpoint, {change: 10}); // Current reports in mA
|
|
46
|
+
await reporting.activePower(endpoint, {change: 2}); // Power reports in 0.1W
|
|
47
|
+
},
|
|
48
|
+
},
|
|
29
49
|
{
|
|
30
50
|
zigbeeModel: ['4257050-ZHAC'],
|
|
31
51
|
model: '4257050-ZHAC',
|
package/devices/elko.js
CHANGED
|
@@ -27,11 +27,15 @@ module.exports = [
|
|
|
27
27
|
vendor: 'ELKO',
|
|
28
28
|
description: 'ESH Plus Super TR RF PH',
|
|
29
29
|
fromZigbee: [fz.elko_thermostat, fz.thermostat],
|
|
30
|
-
toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_heating_setpoint,
|
|
30
|
+
toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_heating_setpoint, tz.elko_load,
|
|
31
31
|
tz.elko_display_text, tz.elko_power_status, tz.elko_external_temp, tz.elko_mean_power, tz.elko_child_lock, tz.elko_frost_guard,
|
|
32
32
|
tz.elko_relay_state, tz.elko_sensor_mode, tz.elko_local_temperature_calibration, tz.elko_max_floor_temp,
|
|
33
33
|
tz.elko_regulator_mode, tz.elko_regulator_time, tz.elko_night_switching],
|
|
34
34
|
exposes: [exposes.text('display_text', ea.ALL).withDescription('Displayed text on thermostat display (zone). Max 14 characters'),
|
|
35
|
+
exposes.numeric('load', ea.ALL).withUnit('W')
|
|
36
|
+
.withDescription('Load in W when heating is on (between 0-2000 W). The thermostat uses the value as input to the ' +
|
|
37
|
+
'mean_power calculation.')
|
|
38
|
+
.withValueMin(0).withValueMax(2000),
|
|
35
39
|
exposes.binary('regulator_mode', ea.ALL, 'regulator', 'thermostat')
|
|
36
40
|
.withDescription('Device in regulator or thermostat mode.'),
|
|
37
41
|
exposes.numeric('regulator_time', ea.ALL).withUnit('min')
|
|
@@ -69,6 +73,13 @@ module.exports = [
|
|
|
69
73
|
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
70
74
|
|
|
71
75
|
// ELKO attributes
|
|
76
|
+
// Load value
|
|
77
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
78
|
+
attribute: 'elkoLoad',
|
|
79
|
+
minimumReportInterval: 0,
|
|
80
|
+
maximumReportInterval: constants.repInterval.HOUR,
|
|
81
|
+
reportableChange: null,
|
|
82
|
+
}]);
|
|
72
83
|
// Power status
|
|
73
84
|
await endpoint.configureReporting('hvacThermostat', [{
|
|
74
85
|
attribute: 'elkoPowerStatus',
|
package/devices/ikea.js
CHANGED
|
@@ -4,6 +4,7 @@ const tz = require('../converters/toZigbee');
|
|
|
4
4
|
const ota = require('../lib/ota');
|
|
5
5
|
const constants = require('../lib/constants');
|
|
6
6
|
const reporting = require('../lib/reporting');
|
|
7
|
+
const {repInterval} = require('../lib/constants');
|
|
7
8
|
const extend = require('../lib/extend');
|
|
8
9
|
const e = exposes.presets;
|
|
9
10
|
const ea = exposes.access;
|
|
@@ -626,19 +627,44 @@ module.exports = [
|
|
|
626
627
|
vendor: 'IKEA',
|
|
627
628
|
description: 'STARKVIND air purifier',
|
|
628
629
|
exposes: [
|
|
629
|
-
e.fan().withModes(['off', '
|
|
630
|
+
e.fan().withModes(['off', 'auto', '1', '2', '3', '4', '5', '6', '7', '8', '9']),
|
|
631
|
+
exposes.numeric('fan_speed', exposes.access.STATE_GET).withValueMin(0).withValueMax(9)
|
|
632
|
+
.withDescription('Current fan speed'),
|
|
630
633
|
e.pm25().withAccess(ea.STATE_GET),
|
|
631
634
|
exposes.enum('air_quality', ea.STATE_GET, [
|
|
632
635
|
'good', 'ok', 'not_good', 'unknown',
|
|
633
636
|
]).withDescription('Measured air quality'),
|
|
637
|
+
exposes.binary('led_enable', ea.ALL, true, false).withDescription('Enabled LED'),
|
|
638
|
+
exposes.binary('child_lock', ea.ALL, 'LOCK', 'UNLOCK').withDescription('Enables/disables physical input on the device'),
|
|
639
|
+
exposes.binary('replace_filter', ea.STATE_GET, true, false)
|
|
640
|
+
.withDescription('Filter is older than 6 months and needs replacing'),
|
|
634
641
|
],
|
|
635
642
|
meta: {fanStateOn: 'auto'},
|
|
636
|
-
fromZigbee: [fz.
|
|
637
|
-
toZigbee: [
|
|
643
|
+
fromZigbee: [fz.ikea_air_purifier],
|
|
644
|
+
toZigbee: [
|
|
645
|
+
tz.ikea_air_purifier_fan_mode, tz.ikea_air_purifier_fan_speed,
|
|
646
|
+
tz.ikea_air_purifier_pm25, tz.ikea_air_purifier_child_lock, tz.ikea_air_purifier_led_enable,
|
|
647
|
+
tz.ikea_air_purifier_replace_filter,
|
|
648
|
+
],
|
|
638
649
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
650
|
+
const options = {manufacturerCode: 0x117c};
|
|
639
651
|
const endpoint = device.getEndpoint(1);
|
|
640
|
-
|
|
641
|
-
await reporting.
|
|
652
|
+
|
|
653
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['manuSpecificIkeaAirPurifier']);
|
|
654
|
+
await endpoint.configureReporting('manuSpecificIkeaAirPurifier', [{attribute: 'particulateMatter25Measurement',
|
|
655
|
+
minimumReportInterval: repInterval.MINUTE, maximumReportInterval: repInterval.HOUR, reportableChange: 1}],
|
|
656
|
+
options);
|
|
657
|
+
await endpoint.configureReporting('manuSpecificIkeaAirPurifier', [{attribute: 'filterRunTime',
|
|
658
|
+
minimumReportInterval: repInterval.HOUR, maximumReportInterval: repInterval.HOUR, reportableChange: 0}],
|
|
659
|
+
options);
|
|
660
|
+
await endpoint.configureReporting('manuSpecificIkeaAirPurifier', [{attribute: 'fanMode',
|
|
661
|
+
minimumReportInterval: 0, maximumReportInterval: repInterval.HOUR, reportableChange: 1}],
|
|
662
|
+
options);
|
|
663
|
+
await endpoint.configureReporting('manuSpecificIkeaAirPurifier', [{attribute: 'fanSpeed',
|
|
664
|
+
minimumReportInterval: 0, maximumReportInterval: repInterval.HOUR, reportableChange: 1}],
|
|
665
|
+
options);
|
|
666
|
+
|
|
667
|
+
await endpoint.read('manuSpecificIkeaAirPurifier', ['controlPanelLight', 'childLock', 'filterRunTime']);
|
|
642
668
|
},
|
|
643
669
|
},
|
|
644
670
|
{
|
package/devices/innr.js
CHANGED
|
@@ -477,6 +477,30 @@ module.exports = [
|
|
|
477
477
|
await reporting.onOff(endpoint);
|
|
478
478
|
},
|
|
479
479
|
},
|
|
480
|
+
{
|
|
481
|
+
zigbeeModel: ['SP 234'],
|
|
482
|
+
model: 'SP 234',
|
|
483
|
+
vendor: 'Innr',
|
|
484
|
+
description: 'Smart plug',
|
|
485
|
+
fromZigbee: [fz.electrical_measurement, fz.on_off, fz.ignore_genLevelCtrl_report, fz.metering],
|
|
486
|
+
toZigbee: [tz.on_off],
|
|
487
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
488
|
+
const endpoint = device.getEndpoint(1);
|
|
489
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
490
|
+
await reporting.onOff(endpoint);
|
|
491
|
+
// Gives UNSUPPORTED_ATTRIBUTE on reporting.readEletricalMeasurementMultiplierDivisors.
|
|
492
|
+
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {
|
|
493
|
+
acCurrentDivisor: 1000,
|
|
494
|
+
acCurrentMultiplier: 1,
|
|
495
|
+
});
|
|
496
|
+
await reporting.activePower(endpoint);
|
|
497
|
+
await reporting.rmsCurrent(endpoint);
|
|
498
|
+
await reporting.rmsVoltage(endpoint);
|
|
499
|
+
// Gives UNSUPPORTED_ATTRIBUTE on reporting.readMeteringMultiplierDivisor.
|
|
500
|
+
endpoint.saveClusterAttributeKeyValue('seMetering', {multiplier: 1, divisor: 100});
|
|
501
|
+
},
|
|
502
|
+
exposes: [e.power(), e.current(), e.voltage().withAccess(ea.STATE), e.switch(), e.energy()],
|
|
503
|
+
},
|
|
480
504
|
{
|
|
481
505
|
zigbeeModel: ['OFL 120 C'],
|
|
482
506
|
model: 'OFL 120 C',
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const exposes = require('../lib/exposes');
|
|
2
|
+
const fz = require('../converters/fromZigbee');
|
|
3
|
+
const reporting = require('../lib/reporting');
|
|
4
|
+
const utils = require('../lib/utils');
|
|
5
|
+
const e = exposes.presets;
|
|
6
|
+
|
|
7
|
+
const jetHome = {
|
|
8
|
+
fz: {
|
|
9
|
+
multiStateAction: {
|
|
10
|
+
cluster: 'genMultistateInput',
|
|
11
|
+
type: ['attributeReport', 'readResponse'],
|
|
12
|
+
convert: (model, msg, publish, options, meta) => {
|
|
13
|
+
const actionLookup = {0: 'release', 1: 'single', 2: 'double', 3: 'triple', 4: 'hold'};
|
|
14
|
+
const value = msg.data['presentValue'];
|
|
15
|
+
const action = actionLookup[value];
|
|
16
|
+
return {action: utils.postfixWithEndpointName(action, msg, model)};
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
module.exports = [
|
|
23
|
+
{
|
|
24
|
+
fingerprint: [{modelID: 'WS7', manufacturerName: 'JetHome'}],
|
|
25
|
+
model: 'WS7',
|
|
26
|
+
vendor: 'JetHome',
|
|
27
|
+
description: '3-ch battery discrete input module',
|
|
28
|
+
fromZigbee: [fz.battery, jetHome.fz.multiStateAction],
|
|
29
|
+
toZigbee: [],
|
|
30
|
+
exposes: [
|
|
31
|
+
e.battery(), e.battery_voltage(), e.action(
|
|
32
|
+
['release_in1', 'single_in1', 'double_in1', 'hold_in1',
|
|
33
|
+
'release_in2', 'single_in2', 'double_in2', 'hold_in2',
|
|
34
|
+
'release_in3', 'single_in3', 'double_in3', 'hold_in3'])],
|
|
35
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
36
|
+
const endpoint = device.getEndpoint(1);
|
|
37
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
38
|
+
await reporting.batteryVoltage(endpoint);
|
|
39
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
40
|
+
},
|
|
41
|
+
meta: {multiEndpoint: true},
|
|
42
|
+
endpoint: (device) => {
|
|
43
|
+
return {
|
|
44
|
+
'in1': 1, 'in2': 2, 'in3': 3,
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
];
|
package/devices/keen_home.js
CHANGED
|
@@ -41,7 +41,7 @@ module.exports = [
|
|
|
41
41
|
exposes: [e.cover_position().setAccess('state', ea.ALL), e.temperature(), e.battery(), e.pressure()],
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
|
-
zigbeeModel: ['SV02-410-MP-1.3', 'SV02-610-MP-1.3', 'SV02-612-MP-1.3', 'SV02-410-MP-1.0'],
|
|
44
|
+
zigbeeModel: ['SV02-410-MP-1.3', 'SV02-412-MP-1.3', 'SV02-610-MP-1.3', 'SV02-612-MP-1.3', 'SV02-410-MP-1.0'],
|
|
45
45
|
model: 'SV02',
|
|
46
46
|
vendor: 'Keen Home',
|
|
47
47
|
description: 'Smart vent',
|
package/devices/leedarson.js
CHANGED
|
@@ -5,6 +5,27 @@ const extend = require('../lib/extend');
|
|
|
5
5
|
const e = exposes.presets;
|
|
6
6
|
|
|
7
7
|
module.exports = [
|
|
8
|
+
{
|
|
9
|
+
zigbeeModel: ['ZBT-DIMLight-GLS0800'],
|
|
10
|
+
model: 'ZBT-DIMLight-GLS0800',
|
|
11
|
+
vendor: 'Leedarson',
|
|
12
|
+
description: 'LED E27 warm white',
|
|
13
|
+
extend: extend.light_onoff_brightness(),
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
zigbeeModel: ['ZBT-CCTLight-GLS0904'],
|
|
17
|
+
model: 'ZBT-CCTLight-GLS0904',
|
|
18
|
+
vendor: 'Leedarson',
|
|
19
|
+
description: 'LED E27 tunable white',
|
|
20
|
+
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
zigbeeModel: ['ZBT-CCTLight-Candle0904'],
|
|
24
|
+
model: 'ZBT-CCTLight-Candle0904',
|
|
25
|
+
vendor: 'Leedarson',
|
|
26
|
+
description: 'LED E14 tunable white',
|
|
27
|
+
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
|
|
28
|
+
},
|
|
8
29
|
{
|
|
9
30
|
zigbeeModel: ['LED_GU10_OWDT'],
|
|
10
31
|
model: 'ZM350STW1TCF',
|
|
@@ -72,4 +93,22 @@ module.exports = [
|
|
|
72
93
|
toZigbee: [],
|
|
73
94
|
exposes: [e.occupancy(), e.illuminance(), e.illuminance_lux()],
|
|
74
95
|
},
|
|
96
|
+
{
|
|
97
|
+
zigbeeModel: ['ZB-SMART-PIRTH-V1'],
|
|
98
|
+
model: '7A-SS-ZABC-H0',
|
|
99
|
+
vendor: 'Leedarson',
|
|
100
|
+
description: '4-in-1-Sensor',
|
|
101
|
+
fromZigbee: [fz.battery, fz.ias_occupancy_alarm_1, fz.illuminance, fz.temperature, fz.humidity, fz.ignore_occupancy_report],
|
|
102
|
+
toZigbee: [],
|
|
103
|
+
exposes: [e.battery(), e.occupancy(), e.temperature(), e.illuminance(), e.illuminance_lux(), e.humidity()],
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
zigbeeModel: ['ZB-MotionSensor-S0000'],
|
|
107
|
+
model: '8A-SS-BA-H0',
|
|
108
|
+
vendor: 'Leedarson',
|
|
109
|
+
description: 'Motion Sensor',
|
|
110
|
+
fromZigbee: [fz.battery, fz.ias_occupancy_alarm_1, fz.ignore_occupancy_report],
|
|
111
|
+
toZigbee: [],
|
|
112
|
+
exposes: [e.battery(), e.occupancy()],
|
|
113
|
+
},
|
|
75
114
|
];
|
package/devices/moes.js
CHANGED
|
@@ -202,7 +202,8 @@ module.exports = [
|
|
|
202
202
|
tz.moesS_thermostat_boost_heating_countdown, tz.moesS_thermostat_system_mode,
|
|
203
203
|
tz.moesS_thermostat_boost_heating, tz.moesS_thermostat_boostHeatingCountdownTimeSet,
|
|
204
204
|
tz.moesS_thermostat_eco_temperature, tz.moesS_thermostat_max_temperature,
|
|
205
|
-
tz.moesS_thermostat_min_temperature, tz.moesS_thermostat_moesSecoMode
|
|
205
|
+
tz.moesS_thermostat_min_temperature, tz.moesS_thermostat_moesSecoMode,
|
|
206
|
+
tz.moesS_thermostat_schedule_programming],
|
|
206
207
|
exposes: [
|
|
207
208
|
e.battery(), e.child_lock(), e.eco_mode(), e.eco_temperature(), e.max_temperature(), e.min_temperature(),
|
|
208
209
|
e.position(), e.window_detection(),
|
|
@@ -218,11 +219,9 @@ module.exports = [
|
|
|
218
219
|
'to 15 degrees Celsius. After 10 days, the device will automatically switch to programming mode. ' +
|
|
219
220
|
'TEMPORARY MANUAL MODE - In this mode, ☝ icon will flash. At this time, the device executes the manually set ' +
|
|
220
221
|
'temperature and returns to the weekly programming mode in the next time period. '),
|
|
221
|
-
exposes.
|
|
222
|
-
'the device executes a preset week programming temperature time and temperature. '
|
|
223
|
-
|
|
224
|
-
.withFeature(exposes.text('program_saturday', ea.STATE))
|
|
225
|
-
.withFeature(exposes.text('program_sunday', ea.STATE)),
|
|
222
|
+
exposes.text('programming_mode', ea.STATE_SET).withDescription('PROGRAMMING MODE ⏱ - In this mode, ' +
|
|
223
|
+
'the device executes a preset week programming temperature time and temperature. ' +
|
|
224
|
+
'You can set up to 4 stages of temperature every for WEEKDAY ➀➁➂➃➄, SATURDAY ➅ and SUNDAY ➆.'),
|
|
226
225
|
exposes.binary('boost_heating', ea.STATE_SET, 'ON', 'OFF').withDescription('Boost Heating: press and hold "+" for 3 seconds, ' +
|
|
227
226
|
'the device will enter the boost heating mode, and the ▷╵◁ will flash. The countdown will be displayed in the APP'),
|
|
228
227
|
exposes.numeric('boost_heating_countdown', ea.STATE_SET).withUnit('min').withDescription('Countdown in minutes'),
|
package/devices/philips.js
CHANGED
|
@@ -441,7 +441,7 @@ module.exports = [
|
|
|
441
441
|
ota: ota.zigbeeOTA,
|
|
442
442
|
},
|
|
443
443
|
{
|
|
444
|
-
zigbeeModel: ['LWA003'],
|
|
444
|
+
zigbeeModel: ['LWA003', 'LWW002'],
|
|
445
445
|
model: '9290022268',
|
|
446
446
|
vendor: 'Philips',
|
|
447
447
|
description: 'Hue White A19 bulb with Bluetooth',
|
|
@@ -1936,6 +1936,15 @@ module.exports = [
|
|
|
1936
1936
|
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
1937
1937
|
ota: ota.zigbeeOTA,
|
|
1938
1938
|
},
|
|
1939
|
+
{
|
|
1940
|
+
zigbeeModel: ['1741730V7'],
|
|
1941
|
+
model: '1741730V7',
|
|
1942
|
+
vendor: 'Philips',
|
|
1943
|
+
description: 'Hue Lily outdoor spot light',
|
|
1944
|
+
meta: {turnsOffAtBrightness1: true},
|
|
1945
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
1946
|
+
ota: ota.zigbeeOTA,
|
|
1947
|
+
},
|
|
1939
1948
|
{
|
|
1940
1949
|
zigbeeModel: ['1746730V7'],
|
|
1941
1950
|
model: '1746730V7',
|
|
@@ -2095,7 +2104,7 @@ module.exports = [
|
|
|
2095
2104
|
vendor: 'Philips',
|
|
2096
2105
|
description: 'Hue Play gradient lightstrip 65',
|
|
2097
2106
|
meta: {turnsOffAtBrightness1: true},
|
|
2098
|
-
extend: hueExtend.
|
|
2107
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2099
2108
|
ota: ota.zigbeeOTA,
|
|
2100
2109
|
},
|
|
2101
2110
|
{
|
package/devices/tuya.js
CHANGED
|
@@ -140,7 +140,9 @@ module.exports = [
|
|
|
140
140
|
},
|
|
141
141
|
{
|
|
142
142
|
fingerprint: [{modelID: 'TS0501B', manufacturerName: '_TZ3000_4whigl8i'},
|
|
143
|
-
{modelID: 'TS0501B', manufacturerName: '_TZ3210_4whigl8i'},
|
|
143
|
+
{modelID: 'TS0501B', manufacturerName: '_TZ3210_4whigl8i'},
|
|
144
|
+
{modelID: 'TS0501B', manufacturerName: '_TZ3210_9q49basr'},
|
|
145
|
+
{modelID: 'TS0501B', manufacturerName: '_TZ3210_grnwgegn'}],
|
|
144
146
|
model: 'TS0501B',
|
|
145
147
|
description: 'Zigbee light',
|
|
146
148
|
vendor: 'TuYa',
|
|
@@ -974,7 +976,8 @@ module.exports = [
|
|
|
974
976
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato'},
|
|
975
977
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm'},
|
|
976
978
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_jvzvulen'},
|
|
977
|
-
{modelID: 'TS011F', manufacturerName: '_TZ3000_w0qqde0g'}
|
|
979
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_w0qqde0g'},
|
|
980
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_nfnmi125'}],
|
|
978
981
|
model: 'TS011F_plug_1',
|
|
979
982
|
description: 'Smart plug (with power monitoring)',
|
|
980
983
|
vendor: 'TuYa',
|
|
@@ -1011,11 +1014,15 @@ module.exports = [
|
|
|
1011
1014
|
.withDescription('Recover state after power outage')],
|
|
1012
1015
|
},
|
|
1013
1016
|
{
|
|
1014
|
-
fingerprint: [
|
|
1015
|
-
{modelID: 'TS011F', manufacturerName: '
|
|
1017
|
+
fingerprint: [
|
|
1018
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak'},
|
|
1019
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 69},
|
|
1020
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_5f43h46b'},
|
|
1021
|
+
],
|
|
1016
1022
|
model: 'TS011F_plug_3',
|
|
1017
1023
|
description: 'Smart plug (with power monitoring by polling)',
|
|
1018
1024
|
vendor: 'TuYa',
|
|
1025
|
+
whiteLabel: [{vendor: 'VIKEFON', model: 'TS011F'}],
|
|
1019
1026
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory],
|
|
1020
1027
|
toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
|
|
1021
1028
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -1182,7 +1189,7 @@ module.exports = [
|
|
|
1182
1189
|
},
|
|
1183
1190
|
},
|
|
1184
1191
|
{
|
|
1185
|
-
fingerprint: [{modelID: 'TS0011', manufacturerName: '
|
|
1192
|
+
fingerprint: [{modelID: 'TS0011', manufacturerName: '_TZ3000_ji4araar'}],
|
|
1186
1193
|
model: 'TS0011_switch_module',
|
|
1187
1194
|
vendor: 'TuYa',
|
|
1188
1195
|
description: '1 gang switch module - (without neutral)',
|
|
@@ -1271,7 +1278,7 @@ module.exports = [
|
|
|
1271
1278
|
},
|
|
1272
1279
|
},
|
|
1273
1280
|
{
|
|
1274
|
-
fingerprint: [{modelID: 'TS0013', manufacturerName: '
|
|
1281
|
+
fingerprint: [{modelID: 'TS0013', manufacturerName: '_TZ3000_ypgri8yz'}],
|
|
1275
1282
|
model: 'TS0013_switch_module',
|
|
1276
1283
|
vendor: 'TuYa',
|
|
1277
1284
|
description: '3 gang switch module - (without neutral)',
|