zigbee-herdsman-converters 14.0.332 → 14.0.336
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 +30 -3
- package/converters/toZigbee.js +12 -8
- package/devices/casaia.js +18 -0
- package/devices/danfoss.js +2 -2
- package/devices/develco.js +3 -0
- package/devices/hive.js +2 -2
- package/devices/icasa.js +1 -0
- package/devices/ikea.js +4 -2
- package/devices/immax.js +19 -0
- package/devices/leedarson.js +1 -1
- package/devices/lidl.js +1 -1
- package/devices/moes.js +2 -1
- package/devices/owon.js +19 -0
- package/devices/perenio.js +15 -0
- package/devices/philips.js +9 -0
- package/devices/popp.js +2 -2
- package/devices/shinasystem.js +17 -0
- package/devices/tuya.js +33 -15
- package/devices/xiaomi.js +15 -0
- package/lib/color.js +9 -3
- package/lib/tuya.js +6 -0
- package/npm-shrinkwrap.json +577 -620
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -596,7 +596,7 @@ const converters = {
|
|
|
596
596
|
// handle color property sync
|
|
597
597
|
// NOTE: this should the last thing we do, as we need to have processed all attributes,
|
|
598
598
|
// we use assign here so we do not lose other attributes.
|
|
599
|
-
return Object.assign(result, libColor.syncColorState(result, meta.state, options));
|
|
599
|
+
return Object.assign(result, libColor.syncColorState(result, meta.state, msg.endpoint, options, meta.logger));
|
|
600
600
|
},
|
|
601
601
|
},
|
|
602
602
|
metering_datek: {
|
|
@@ -668,6 +668,10 @@ const converters = {
|
|
|
668
668
|
constants.develcoInterfaceMode[msg.data['develcoInterfaceMode']] :
|
|
669
669
|
msg.data['develcoInterfaceMode'];
|
|
670
670
|
}
|
|
671
|
+
if (msg.data.hasOwnProperty('status')) {
|
|
672
|
+
result['battery_low'] = (msg.data.status & 2) > 0;
|
|
673
|
+
result['check_meter'] = (msg.data.status & 1) > 0;
|
|
674
|
+
}
|
|
671
675
|
|
|
672
676
|
return result;
|
|
673
677
|
},
|
|
@@ -1753,6 +1757,29 @@ const converters = {
|
|
|
1753
1757
|
}
|
|
1754
1758
|
},
|
|
1755
1759
|
},
|
|
1760
|
+
tuya_illuminance_temperature_humidity_sensor: {
|
|
1761
|
+
cluster: 'manuSpecificTuya',
|
|
1762
|
+
type: ['commandSetDataResponse', 'commandGetData'],
|
|
1763
|
+
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
|
|
1764
|
+
exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
|
|
1765
|
+
convert: (model, msg, publish, options, meta) => {
|
|
1766
|
+
const dp = msg.data.dp;
|
|
1767
|
+
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
1768
|
+
switch (dp) {
|
|
1769
|
+
case tuya.dataPoints.thitTemperature:
|
|
1770
|
+
return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
|
|
1771
|
+
case tuya.dataPoints.thitHumidity:
|
|
1772
|
+
return {humidity: calibrateAndPrecisionRoundOptions(value, options, 'humidity')};
|
|
1773
|
+
case tuya.dataPoints.thitBatteryPercentage:
|
|
1774
|
+
return {battery: value};
|
|
1775
|
+
case tuya.dataPoints.thitIlluminanceLux:
|
|
1776
|
+
return {illuminance_lux: value};
|
|
1777
|
+
default:
|
|
1778
|
+
meta.logger.warn(`zigbee-herdsman-converters:tuya_illuminance_temperature_humidity_sensor: NOT RECOGNIZED ` +
|
|
1779
|
+
`DP #${dp} with data ${JSON.stringify(msg.data)}`);
|
|
1780
|
+
}
|
|
1781
|
+
},
|
|
1782
|
+
},
|
|
1756
1783
|
ts0201_temperature_humidity_alarm: {
|
|
1757
1784
|
cluster: 'manuSpecificTuya_2',
|
|
1758
1785
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -1958,7 +1985,7 @@ const converters = {
|
|
|
1958
1985
|
result.color.s = result.color.saturation;
|
|
1959
1986
|
}
|
|
1960
1987
|
|
|
1961
|
-
return Object.assign(result, libColor.syncColorState(result, meta.state, options));
|
|
1988
|
+
return Object.assign(result, libColor.syncColorState(result, meta.state, msg.endpoint, options, meta.logger));
|
|
1962
1989
|
},
|
|
1963
1990
|
},
|
|
1964
1991
|
tuya_cover: {
|
|
@@ -2444,7 +2471,7 @@ const converters = {
|
|
|
2444
2471
|
buttonMapping = {1: '1', 2: '2'};
|
|
2445
2472
|
} else if (model.model === 'TS0043') {
|
|
2446
2473
|
buttonMapping = {1: '1', 2: '2', 3: '3'};
|
|
2447
|
-
} else if (['TS0044', 'YSR-MINI-Z'].includes(model.model)) {
|
|
2474
|
+
} else if (['TS0044', 'YSR-MINI-Z', 'TS004F'].includes(model.model)) {
|
|
2448
2475
|
buttonMapping = {1: '1', 2: '2', 3: '3', 4: '4'};
|
|
2449
2476
|
}
|
|
2450
2477
|
const button = buttonMapping ? `${buttonMapping[msg.endpoint.ID]}_` : '';
|
package/converters/toZigbee.js
CHANGED
|
@@ -913,8 +913,8 @@ const converters = {
|
|
|
913
913
|
const payload = {colortemp: value, transtime: utils.getTransition(entity, key, meta).time};
|
|
914
914
|
await entity.command('lightingColorCtrl', 'moveToColorTemp', payload, utils.getOptions(meta.mapped, entity));
|
|
915
915
|
return {
|
|
916
|
-
state: libColor.syncColorState({'color_mode': constants.colorMode[2], 'color_temp': value}, meta.state,
|
|
917
|
-
|
|
916
|
+
state: libColor.syncColorState({'color_mode': constants.colorMode[2], 'color_temp': value}, meta.state,
|
|
917
|
+
entity, meta.options, meta.logger), readAfterWriteTime: payload.transtime * 100,
|
|
918
918
|
};
|
|
919
919
|
},
|
|
920
920
|
convertGet: async (entity, key, meta) => {
|
|
@@ -1030,7 +1030,8 @@ const converters = {
|
|
|
1030
1030
|
}
|
|
1031
1031
|
|
|
1032
1032
|
await entity.command('lightingColorCtrl', command, zclData, utils.getOptions(meta.mapped, entity));
|
|
1033
|
-
return {state: libColor.syncColorState(newState, meta.state, meta.options
|
|
1033
|
+
return {state: libColor.syncColorState(newState, meta.state, entity, meta.options, meta.logger),
|
|
1034
|
+
readAfterWriteTime: zclData.transtime * 100};
|
|
1034
1035
|
},
|
|
1035
1036
|
convertGet: async (entity, key, meta) => {
|
|
1036
1037
|
await entity.read('lightingColorCtrl', light.readColorAttributes(entity, meta));
|
|
@@ -3023,7 +3024,8 @@ const converters = {
|
|
|
3023
3024
|
color_temp: meta.message.color_temp,
|
|
3024
3025
|
};
|
|
3025
3026
|
|
|
3026
|
-
return {state: libColor.syncColorState(newState, meta.state, meta.options
|
|
3027
|
+
return {state: libColor.syncColorState(newState, meta.state, entity, meta.options, meta.logger),
|
|
3028
|
+
readAfterWriteTime: zclData.transtime * 100};
|
|
3027
3029
|
}
|
|
3028
3030
|
|
|
3029
3031
|
if (key === 'color_temp') {
|
|
@@ -3040,7 +3042,8 @@ const converters = {
|
|
|
3040
3042
|
color_temp: value,
|
|
3041
3043
|
};
|
|
3042
3044
|
|
|
3043
|
-
return {state: libColor.syncColorState(newState, meta.state, meta.options
|
|
3045
|
+
return {state: libColor.syncColorState(newState, meta.state, entity, meta.options, meta.logger),
|
|
3046
|
+
readAfterWriteTime: zclData.transtime * 100};
|
|
3044
3047
|
}
|
|
3045
3048
|
|
|
3046
3049
|
const zclData = {
|
|
@@ -3104,7 +3107,8 @@ const converters = {
|
|
|
3104
3107
|
color_mode: constants.colorMode[0],
|
|
3105
3108
|
};
|
|
3106
3109
|
|
|
3107
|
-
return {state: libColor.syncColorState(newState, meta.state, meta.options
|
|
3110
|
+
return {state: libColor.syncColorState(newState, meta.state, entity, meta.options, meta.logger),
|
|
3111
|
+
readAfterWriteTime: zclData.transtime * 100};
|
|
3108
3112
|
},
|
|
3109
3113
|
convertGet: async (entity, key, meta) => {
|
|
3110
3114
|
await entity.read('lightingColorCtrl', [
|
|
@@ -5063,7 +5067,7 @@ const converters = {
|
|
|
5063
5067
|
recalledState = addColorMode(recalledState);
|
|
5064
5068
|
}
|
|
5065
5069
|
|
|
5066
|
-
Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, meta.options));
|
|
5070
|
+
Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, entity, meta.options, meta.logger));
|
|
5067
5071
|
membersState[member.getDevice().ieeeAddr] = recalledState;
|
|
5068
5072
|
} else {
|
|
5069
5073
|
meta.logger.warn(`Unknown scene was recalled for ${member.getDevice().ieeeAddr}, can't restore state.`);
|
|
@@ -5080,7 +5084,7 @@ const converters = {
|
|
|
5080
5084
|
recalledState = addColorMode(recalledState);
|
|
5081
5085
|
}
|
|
5082
5086
|
|
|
5083
|
-
Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, meta.options));
|
|
5087
|
+
Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, entity, meta.options, meta.logger));
|
|
5084
5088
|
meta.logger.info('Successfully recalled scene');
|
|
5085
5089
|
return {state: recalledState};
|
|
5086
5090
|
} else {
|
package/devices/casaia.js
CHANGED
|
@@ -2,6 +2,7 @@ const exposes = require('../lib/exposes');
|
|
|
2
2
|
const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
|
|
3
3
|
const reporting = require('../lib/reporting');
|
|
4
4
|
const e = exposes.presets;
|
|
5
|
+
const tz = require('../converters/toZigbee');
|
|
5
6
|
|
|
6
7
|
module.exports = [
|
|
7
8
|
{
|
|
@@ -22,4 +23,21 @@ module.exports = [
|
|
|
22
23
|
},
|
|
23
24
|
exposes: [e.temperature(), e.battery_low(), e.battery()],
|
|
24
25
|
},
|
|
26
|
+
{
|
|
27
|
+
zigbeeModel: ['CCB432'],
|
|
28
|
+
model: 'CCB432',
|
|
29
|
+
vendor: 'CASAIA',
|
|
30
|
+
description: 'Rail-Din relay and energy meter',
|
|
31
|
+
fromZigbee: [fz.electrical_measurement, fz.metering, fz.on_off],
|
|
32
|
+
toZigbee: [tz.on_off],
|
|
33
|
+
exposes: [e.switch(), e.power(), e.energy()],
|
|
34
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
35
|
+
const endpoint = device.getEndpoint(1);
|
|
36
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
37
|
+
await reporting.onOff(endpoint);
|
|
38
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
39
|
+
await reporting.instantaneousDemand(endpoint);
|
|
40
|
+
await reporting.currentSummDelivered(endpoint);
|
|
41
|
+
},
|
|
42
|
+
},
|
|
25
43
|
];
|
package/devices/danfoss.js
CHANGED
|
@@ -42,8 +42,8 @@ module.exports = [
|
|
|
42
42
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
|
|
43
43
|
.withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
|
|
44
44
|
exposes.numeric('external_measured_room_sensor', ea.ALL)
|
|
45
|
-
.withDescription('Set at maximum 3 hours interval but not more often than every 30 minutes
|
|
46
|
-
'
|
|
45
|
+
.withDescription('Set at maximum 3 hours interval but not more often than every 30 minutes and 0.1 ' +
|
|
46
|
+
'degrees difference. Resets every 3hours to standard. e.g. 21C = 2100 (-8000=undefined).'),
|
|
47
47
|
exposes.numeric('window_open_internal', ea.STATE_GET).withValueMin(0).withValueMax(4)
|
|
48
48
|
.withDescription('0=Quarantine, 1=Windows are closed, 2=Hold - Windows are maybe about to open, ' +
|
|
49
49
|
'3=Open window detected, 4=In window open state from external but detected closed locally'),
|
package/devices/develco.js
CHANGED
|
@@ -311,6 +311,7 @@ module.exports = [
|
|
|
311
311
|
exposes: [
|
|
312
312
|
e.power(),
|
|
313
313
|
e.energy(),
|
|
314
|
+
e.battery_low(),
|
|
314
315
|
exposes.numeric('pulse_configuration', ea.ALL).withValueMin(0).withValueMax(65535)
|
|
315
316
|
.withDescription('Pulses per kwh. Default 1000 imp/kWh. Range 0 to 65535'),
|
|
316
317
|
exposes.enum('interface_mode', ea.ALL,
|
|
@@ -318,6 +319,8 @@ module.exports = [
|
|
|
318
319
|
.withDescription('Operating mode/probe'),
|
|
319
320
|
exposes.numeric('current_summation', ea.SET)
|
|
320
321
|
.withDescription('Current summation value sent to the display. e.g. 570 = 0,570 kWh'),
|
|
322
|
+
exposes.binary('check_meter', ea.STATE, true, false)
|
|
323
|
+
.withDescription('Is true if communication problem with meter is experienced'),
|
|
321
324
|
],
|
|
322
325
|
},
|
|
323
326
|
{
|
package/devices/hive.js
CHANGED
|
@@ -183,8 +183,8 @@ module.exports = [
|
|
|
183
183
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
|
|
184
184
|
.withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
|
|
185
185
|
exposes.numeric('external_measured_room_sensor', ea.ALL)
|
|
186
|
-
.withDescription('Set at maximum 3 hours interval but not more often than every 30 minutes
|
|
187
|
-
'
|
|
186
|
+
.withDescription('Set at maximum 3 hours interval but not more often than every 30 minutes and 0.1 ' +
|
|
187
|
+
'degrees difference. Resets every 3hours to standard. e.g. 21C = 2100 (-8000=undefined).'),
|
|
188
188
|
exposes.numeric('window_open_internal', ea.STATE_GET).withValueMin(0).withValueMax(4)
|
|
189
189
|
.withDescription('0=Quarantine, 1=Windows are closed, 2=Hold - Windows are maybe about to open, ' +
|
|
190
190
|
'3=Open window detected, 4=In window open state from external but detected closed locally'),
|
package/devices/icasa.js
CHANGED
|
@@ -81,6 +81,7 @@ module.exports = [
|
|
|
81
81
|
model: 'ICZB-RM11S',
|
|
82
82
|
vendor: 'iCasa',
|
|
83
83
|
description: 'Zigbee 3.0 remote control',
|
|
84
|
+
meta: {battery: {dontDividePercentage: true}},
|
|
84
85
|
fromZigbee: [fz.command_recall, fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
|
|
85
86
|
exposes: [e.battery(), e.action(['recall_*', 'on', 'off', 'brightness_stop', 'brightness_move_up', 'brightness_move_down'])],
|
|
86
87
|
toZigbee: [],
|
package/devices/ikea.js
CHANGED
|
@@ -146,10 +146,12 @@ const ikea = {
|
|
|
146
146
|
convertSet: async (entity, key, value, meta) => {
|
|
147
147
|
if (key == 'fan_state' && value.toLowerCase() == 'on') {
|
|
148
148
|
value = getMetaValue(entity, meta.mapped, 'fanStateOn', 'allEqual', 'on');
|
|
149
|
+
} else {
|
|
150
|
+
value = value.toString().toLowerCase();
|
|
149
151
|
}
|
|
150
152
|
|
|
151
153
|
let fanMode;
|
|
152
|
-
switch (value
|
|
154
|
+
switch (value) {
|
|
153
155
|
case 'off':
|
|
154
156
|
fanMode = 0;
|
|
155
157
|
break;
|
|
@@ -161,7 +163,7 @@ const ikea = {
|
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
await entity.write('manuSpecificIkeaAirPurifier', {'fanMode': fanMode}, manufacturerOptions.ikea);
|
|
164
|
-
return {state: {fan_mode: value
|
|
166
|
+
return {state: {fan_mode: value, fan_state: value === 'off' ? 'OFF' : 'ON'}};
|
|
165
167
|
},
|
|
166
168
|
convertGet: async (entity, key, meta) => {
|
|
167
169
|
await entity.read('manuSpecificIkeaAirPurifier', ['fanMode']);
|
package/devices/immax.js
CHANGED
|
@@ -140,4 +140,23 @@ module.exports = [
|
|
|
140
140
|
description: 'Neo RECUADRO SMART, color temp, dimmable, Zigbee 3.0',
|
|
141
141
|
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
|
|
142
142
|
},
|
|
143
|
+
{
|
|
144
|
+
fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3210_jijr1sss'}],
|
|
145
|
+
model: '07502L',
|
|
146
|
+
vendor: 'Immax',
|
|
147
|
+
description: '4 in 1 multi sensor',
|
|
148
|
+
fromZigbee: [fz.battery, fz.ignore_basic_report, fz.illuminance, fz.ZB003X, fz.ZB003X_attr, fz.ZB003X_occupancy],
|
|
149
|
+
toZigbee: [tz.ZB003X],
|
|
150
|
+
exposes: [e.occupancy(), e.tamper(), e.battery(), e.illuminance(), e.illuminance_lux().withUnit('lx'), e.temperature(),
|
|
151
|
+
e.humidity(), exposes.numeric('reporting_time', ea.STATE_SET).withDescription('Reporting interval in minutes'),
|
|
152
|
+
exposes.numeric('temperature_calibration', ea.STATE_SET).withDescription('Temperature calibration'),
|
|
153
|
+
exposes.numeric('humidity_calibration', ea.STATE_SET).withDescription('Humidity calibration'),
|
|
154
|
+
exposes.numeric('illuminance_calibration', ea.STATE_SET).withDescription('Illuminance calibration'),
|
|
155
|
+
exposes.binary('pir_enable', ea.STATE_SET, true, false).withDescription('Enable PIR sensor'),
|
|
156
|
+
exposes.binary('led_enable', ea.STATE_SET, true, false).withDescription('Enabled LED'),
|
|
157
|
+
exposes.binary('reporting_enable', ea.STATE_SET, true, false).withDescription('Enabled reporting'),
|
|
158
|
+
exposes.enum('sensitivity', ea.STATE_SET, ['low', 'medium', 'high']).withDescription('PIR sensor sensitivity'),
|
|
159
|
+
// eslint-disable-next-line
|
|
160
|
+
exposes.enum('keep_time', ea.STATE_SET, ['0', '30', '60', '120', '240']).withDescription('PIR keep time in seconds')],
|
|
161
|
+
},
|
|
143
162
|
];
|
package/devices/leedarson.js
CHANGED
|
@@ -85,7 +85,7 @@ module.exports = [
|
|
|
85
85
|
extend: extend.light_onoff_brightness_colortemp(),
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
|
-
|
|
88
|
+
fingerprint: [{modelID: 'ZHA-PIRSensor', manufacturerName: 'Leedarson'}],
|
|
89
89
|
model: '5AA-SS-ZA-H0',
|
|
90
90
|
vendor: 'Leedarson',
|
|
91
91
|
description: 'Motion sensor',
|
package/devices/lidl.js
CHANGED
|
@@ -655,7 +655,7 @@ module.exports = [
|
|
|
655
655
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'}],
|
|
656
656
|
model: '368308_2010',
|
|
657
657
|
vendor: 'Lidl',
|
|
658
|
-
description: 'Silvercrest
|
|
658
|
+
description: 'Silvercrest radiator valve with thermostat',
|
|
659
659
|
fromZigbee: [fz.ignore_tuya_set_time, fzLocal.zs_thermostat, fz.tuya_data_point_dump],
|
|
660
660
|
toZigbee: [tzLocal.zs_thermostat_current_heating_setpoint, tzLocal.zs_thermostat_child_lock,
|
|
661
661
|
tzLocal.zs_thermostat_comfort_temp, tzLocal.zs_thermostat_eco_temp, tzLocal.zs_thermostat_preset_mode,
|
package/devices/moes.js
CHANGED
|
@@ -76,7 +76,8 @@ module.exports = [
|
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_aoclfnxz'},
|
|
79
|
-
{modelID: 'TS0601', manufacturerName: '_TZE200_ztvwu4nk'}
|
|
79
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_ztvwu4nk'},
|
|
80
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_u9bfwha0'}],
|
|
80
81
|
model: 'BHT-002-GCLZB',
|
|
81
82
|
vendor: 'Moes',
|
|
82
83
|
description: 'Moes BHT series Thermostat',
|
package/devices/owon.js
CHANGED
|
@@ -83,4 +83,23 @@ module.exports = [
|
|
|
83
83
|
await reporting.thermostatAcLouverPosition(endpoint);
|
|
84
84
|
},
|
|
85
85
|
},
|
|
86
|
+
{
|
|
87
|
+
zigbeeModel: ['THS317'],
|
|
88
|
+
model: 'THS317',
|
|
89
|
+
vendor: 'OWON',
|
|
90
|
+
description: 'Temperature and humidity sensor',
|
|
91
|
+
fromZigbee: [fz.temperature, fz.humidity, fz.battery],
|
|
92
|
+
toZigbee: [],
|
|
93
|
+
exposes: [e.battery(), e.temperature(), e.humidity()],
|
|
94
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
95
|
+
const endpoint = device.getEndpoint(2);
|
|
96
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'msRelativeHumidity', 'genPowerCfg']);
|
|
97
|
+
await reporting.temperature(endpoint);
|
|
98
|
+
await reporting.humidity(endpoint);
|
|
99
|
+
await reporting.batteryVoltage(endpoint);
|
|
100
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
101
|
+
device.powerSource = 'Battery';
|
|
102
|
+
device.save();
|
|
103
|
+
},
|
|
104
|
+
},
|
|
86
105
|
];
|
package/devices/perenio.js
CHANGED
|
@@ -33,4 +33,19 @@ module.exports = [
|
|
|
33
33
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
|
+
{
|
|
37
|
+
fingerprint: [{modelID: 'ZHA-PirSensor', manufacturerName: 'LDS'}],
|
|
38
|
+
model: 'PECMS01',
|
|
39
|
+
vendor: 'Perenio',
|
|
40
|
+
description: 'Motion sensor',
|
|
41
|
+
fromZigbee: [fz.battery, fz.ias_occupancy_alarm_1],
|
|
42
|
+
toZigbee: [],
|
|
43
|
+
meta: {battery: {dontDividePercentage: true}},
|
|
44
|
+
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery()],
|
|
45
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
46
|
+
const endpoint = device.getEndpoint(1);
|
|
47
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
48
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
49
|
+
},
|
|
50
|
+
},
|
|
36
51
|
];
|
package/devices/philips.js
CHANGED
|
@@ -2244,6 +2244,15 @@ module.exports = [
|
|
|
2244
2244
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2245
2245
|
ota: ota.zigbeeOTA,
|
|
2246
2246
|
},
|
|
2247
|
+
{
|
|
2248
|
+
zigbeeModel: ['5047230P6', '5047230P6'],
|
|
2249
|
+
model: '5047230P6',
|
|
2250
|
+
vendor: 'Philips',
|
|
2251
|
+
description: 'Hue White ambiance Buckram double spotlight',
|
|
2252
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2253
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2254
|
+
ota: ota.zigbeeOTA,
|
|
2255
|
+
},
|
|
2247
2256
|
{
|
|
2248
2257
|
zigbeeModel: ['5047430P6'],
|
|
2249
2258
|
model: '5047430P6',
|
package/devices/popp.js
CHANGED
|
@@ -42,8 +42,8 @@ module.exports = [
|
|
|
42
42
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
|
|
43
43
|
.withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
|
|
44
44
|
exposes.numeric('external_measured_room_sensor', ea.ALL)
|
|
45
|
-
.withDescription('Set at maximum 3 hours interval but not more often than every 30 minutes
|
|
46
|
-
'
|
|
45
|
+
.withDescription('Set at maximum 3 hours interval but not more often than every 30 minutes and 0.1 ' +
|
|
46
|
+
'degrees difference. Resets every 3hours to standard. e.g. 21C = 2100 (-8000=undefined).'),
|
|
47
47
|
exposes.numeric('window_open_internal', ea.STATE_GET).withValueMin(0).withValueMax(4)
|
|
48
48
|
.withDescription('0=Quarantine, 1=Windows are closed, 2=Hold - Windows are maybe about to open, ' +
|
|
49
49
|
'3=Open window detected, 4=In window open state from external but detected closed locally'),
|
package/devices/shinasystem.js
CHANGED
|
@@ -282,4 +282,21 @@ module.exports = [
|
|
|
282
282
|
await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
|
|
283
283
|
},
|
|
284
284
|
},
|
|
285
|
+
{
|
|
286
|
+
zigbeeModel: ['PMM-300Z1'],
|
|
287
|
+
model: 'PMM-300Z1',
|
|
288
|
+
vendor: 'ShinaSystem',
|
|
289
|
+
description: 'SiHAS energy monitor',
|
|
290
|
+
fromZigbee: [fz.electrical_measurement, fz.metering],
|
|
291
|
+
toZigbee: [tz.electrical_measurement_power],
|
|
292
|
+
exposes: [e.power().withAccess(ea.STATE_GET), e.energy()],
|
|
293
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
294
|
+
const endpoint = device.getEndpoint(1);
|
|
295
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['haElectricalMeasurement', 'seMetering']);
|
|
296
|
+
await reporting.activePower(endpoint, {min: 1, max: 600, change: 5});
|
|
297
|
+
await reporting.instantaneousDemand(endpoint, {min: 1, max: 600, change: 1});
|
|
298
|
+
endpoint.saveClusterAttributeKeyValue('seMetering', {multiplier: 1, divisor: 1000});
|
|
299
|
+
await reporting.currentSummDelivered(endpoint, {min: 1, max: 600, change: 5});
|
|
300
|
+
},
|
|
301
|
+
},
|
|
285
302
|
];
|
package/devices/tuya.js
CHANGED
|
@@ -36,6 +36,15 @@ module.exports = [
|
|
|
36
36
|
toZigbee: [],
|
|
37
37
|
exposes: [e.temperature(), e.humidity(), e.battery()],
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_vzqtvljm'}],
|
|
41
|
+
model: 'TS0601_illuminance_temperature_humidity_sensor',
|
|
42
|
+
vendor: 'TuYa',
|
|
43
|
+
description: 'Illuminance, temperature & humidity sensor',
|
|
44
|
+
fromZigbee: [fz.tuya_illuminance_temperature_humidity_sensor],
|
|
45
|
+
toZigbee: [],
|
|
46
|
+
exposes: [e.temperature(), e.humidity(), e.illuminance_lux(), e.battery()],
|
|
47
|
+
},
|
|
39
48
|
{
|
|
40
49
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_8ygsuhe1'},
|
|
41
50
|
{modelID: 'TS0601', manufacturerName: '_TZE200_yvx5lh6k'}, {modelID: 'TS0601', manufacturerName: '_TZE200_ryfmq5rl'}],
|
|
@@ -115,8 +124,8 @@ module.exports = [
|
|
|
115
124
|
model: 'TS0505B',
|
|
116
125
|
vendor: 'TuYa',
|
|
117
126
|
description: 'Zigbee RGB+CCT light',
|
|
118
|
-
whiteLabel: [{vendor: 'Mercator
|
|
119
|
-
{vendor: 'TuYa', model: 'A5C-21F7-01'}, {vendor: 'Mercator
|
|
127
|
+
whiteLabel: [{vendor: 'Mercator Ikuü', model: 'SMD4106W-RGB-ZB'},
|
|
128
|
+
{vendor: 'TuYa', model: 'A5C-21F7-01'}, {vendor: 'Mercator Ikuü', model: 'S9E27LED9W-RGB-Z'}],
|
|
120
129
|
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
121
130
|
meta: {applyRedFix: true, enhancedHue: false},
|
|
122
131
|
},
|
|
@@ -241,7 +250,7 @@ module.exports = [
|
|
|
241
250
|
{vendor: 'Earda', model: 'EDM-1ZAA-EU'},
|
|
242
251
|
{vendor: 'Earda', model: 'EDM-1ZAB-EU'},
|
|
243
252
|
{vendor: 'Earda', model: 'EDM-1ZBA-EU'},
|
|
244
|
-
{vendor: 'Mercator
|
|
253
|
+
{vendor: 'Mercator Ikuü', model: 'SSWD01'},
|
|
245
254
|
],
|
|
246
255
|
},
|
|
247
256
|
{
|
|
@@ -437,7 +446,7 @@ module.exports = [
|
|
|
437
446
|
model: 'TS0502B',
|
|
438
447
|
vendor: 'TuYa',
|
|
439
448
|
description: 'Light controller',
|
|
440
|
-
whiteLabel: [{vendor: 'Mercator
|
|
449
|
+
whiteLabel: [{vendor: 'Mercator Ikuü', model: 'SMI7040', description: 'Ford Batten Light'}],
|
|
441
450
|
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
|
|
442
451
|
},
|
|
443
452
|
{
|
|
@@ -545,16 +554,24 @@ module.exports = [
|
|
|
545
554
|
model: 'TS004F',
|
|
546
555
|
vendor: 'TuYa',
|
|
547
556
|
description: 'Wireless switch with 4 buttons',
|
|
548
|
-
exposes: [e.battery(), e.action(
|
|
549
|
-
|
|
550
|
-
fromZigbee: [fz.battery, fz.
|
|
551
|
-
toZigbee: [],
|
|
557
|
+
exposes: [e.battery(), e.action(['1_single', '1_double', '1_hold', '2_single', '2_double', '2_hold',
|
|
558
|
+
'3_single', '3_double', '3_hold', '4_single', '4_double', '4_hold'])],
|
|
559
|
+
fromZigbee: [fz.battery, fz.tuya_on_off_action],
|
|
560
|
+
toZigbee: [tz.tuya_operation_mode],
|
|
552
561
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
553
562
|
const endpoint = device.getEndpoint(1);
|
|
554
|
-
await
|
|
563
|
+
await endpoint.read('genBasic', [0x0004, 0x000, 0x0001, 0x0005, 0x0007, 0xfffe]);
|
|
564
|
+
await endpoint.write('genOnOff', {'tuyaOperationMode': 1});
|
|
565
|
+
await endpoint.read('genOnOff', ['tuyaOperationMode']);
|
|
555
566
|
try {
|
|
556
|
-
await
|
|
557
|
-
} catch (
|
|
567
|
+
await endpoint.read(0xE001, [0xD011]);
|
|
568
|
+
} catch (err) {/* do nothing */}
|
|
569
|
+
await endpoint.read('genPowerCfg', ['batteryVoltage', 'batteryPercentageRemaining']);
|
|
570
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
571
|
+
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
572
|
+
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
573
|
+
await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
|
|
574
|
+
await reporting.bind(device.getEndpoint(4), coordinatorEndpoint, ['genOnOff']);
|
|
558
575
|
},
|
|
559
576
|
},
|
|
560
577
|
{
|
|
@@ -1185,7 +1202,7 @@ module.exports = [
|
|
|
1185
1202
|
{vendor: 'Vrey', model: 'VR-X712U-0013'},
|
|
1186
1203
|
{vendor: 'TUYATEC', model: 'GDKES-01TZXD'},
|
|
1187
1204
|
{vendor: 'Lonsonho', model: 'QS-Zigbee-S05-L', description: '1 gang smart switch module without neutral wire'},
|
|
1188
|
-
{vendor: 'Mercator
|
|
1205
|
+
{vendor: 'Mercator Ikuü', model: 'SSW01'},
|
|
1189
1206
|
],
|
|
1190
1207
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1191
1208
|
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
@@ -1318,7 +1335,7 @@ module.exports = [
|
|
|
1318
1335
|
{
|
|
1319
1336
|
fingerprint: [{modelID: 'TS0014', manufacturerName: '_TZ3000_jr2atpww'}, {modelID: 'TS0014', manufacturerName: '_TYZB01_dvakyzhd'},
|
|
1320
1337
|
{modelID: 'TS0014', manufacturerName: '_TZ3210_w3hl6rao'}, {modelID: 'TS0014', manufacturerName: '_TYZB01_bagt1e4o'},
|
|
1321
|
-
{modelID: 'TS0014', manufacturerName: '_TZ3000_r0pmi2p3'}],
|
|
1338
|
+
{modelID: 'TS0014', manufacturerName: '_TZ3000_r0pmi2p3'}, {modelID: 'TS0014', manufacturerName: '_TZ3000_fxjdcikv'}],
|
|
1322
1339
|
model: 'TS0014',
|
|
1323
1340
|
vendor: 'TuYa',
|
|
1324
1341
|
description: 'Smart light switch - 4 gang without neutral wire',
|
|
@@ -1329,7 +1346,7 @@ module.exports = [
|
|
|
1329
1346
|
return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4};
|
|
1330
1347
|
},
|
|
1331
1348
|
whiteLabel: [{vendor: 'TUYATEC', model: 'GDKES-04TZXD'}, {vendor: 'Vizo', model: 'VZ-222S'},
|
|
1332
|
-
{vendor: 'MakeGood', model: 'MG-ZG04W/B/G'}],
|
|
1349
|
+
{vendor: 'MakeGood', model: 'MG-ZG04W/B/G'}, {vendor: 'Mercator Ikuü', model: 'SSW04'}],
|
|
1333
1350
|
meta: {multiEndpoint: true},
|
|
1334
1351
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1335
1352
|
try {
|
|
@@ -1517,7 +1534,8 @@ module.exports = [
|
|
|
1517
1534
|
exposes: [e.battery(), e.illuminance(), e.illuminance_lux()],
|
|
1518
1535
|
},
|
|
1519
1536
|
{
|
|
1520
|
-
fingerprint: [{modelID: 'TS0210', manufacturerName: '_TYZB01_3zv6oleo'}
|
|
1537
|
+
fingerprint: [{modelID: 'TS0210', manufacturerName: '_TYZB01_3zv6oleo'},
|
|
1538
|
+
{modelID: 'TS0210', manufacturerName: '_TYZB01_j9xxahcl'}],
|
|
1521
1539
|
model: 'TS0210',
|
|
1522
1540
|
vendor: 'TuYa',
|
|
1523
1541
|
description: 'Vibration sensor',
|
package/devices/xiaomi.js
CHANGED
|
@@ -1772,6 +1772,21 @@ module.exports = [
|
|
|
1772
1772
|
await endpoint1.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
|
|
1773
1773
|
},
|
|
1774
1774
|
},
|
|
1775
|
+
{
|
|
1776
|
+
zigbeeModel: ['lumi.remote.acn003'],
|
|
1777
|
+
model: 'WXKG16LM',
|
|
1778
|
+
vendor: 'Xiaomi',
|
|
1779
|
+
description: 'Aqara wireless remote switch E1 (single rocker)',
|
|
1780
|
+
fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple],
|
|
1781
|
+
toZigbee: [tz.xiaomi_switch_click_mode],
|
|
1782
|
+
exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'hold']),
|
|
1783
|
+
exposes.enum('click_mode', ea.SET, ['fast', 'multi'])
|
|
1784
|
+
.withDescription('Click mode, fast: only supports single click which will be send immediately after clicking.' +
|
|
1785
|
+
'multi: supports more events like double and hold')],
|
|
1786
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1787
|
+
await device.getEndpoint(1).write('aqaraOpple', {0x0125: {value: 0x02, type: 0x20}}, {manufacturerCode: 0x115f});
|
|
1788
|
+
},
|
|
1789
|
+
},
|
|
1775
1790
|
{
|
|
1776
1791
|
zigbeeModel: ['lumi.remote.acn004'],
|
|
1777
1792
|
model: 'WXKG17LM',
|
package/lib/color.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const kelvinToXyLookup = require('./kelvinToXy');
|
|
2
2
|
const {precisionRound} = require('./utils');
|
|
3
|
+
const {findColorTempRange, clampColorTemp} = require('./light');
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Color represented in HSV space
|
|
@@ -637,14 +638,17 @@ class Color {
|
|
|
637
638
|
* NOTE: behavior can be disable by setting the 'color_sync' device/group option
|
|
638
639
|
* @param {Object} newState state with only the changed attributes set
|
|
639
640
|
* @param {Object} oldState state from the cache with all the old attributes set
|
|
641
|
+
* @param {Object} endpoint with lightingColorCtrl cluster
|
|
640
642
|
* @param {Object} options meta.options for the device or group
|
|
643
|
+
* @param {Object} logger used for logging
|
|
641
644
|
* @return {Object} state with color, color_temp, and color_mode set and syncronized from newState's attributes
|
|
642
645
|
* (other attributes are not included make sure to merge yourself)
|
|
643
646
|
*/
|
|
644
|
-
function syncColorState(newState, oldState, options) {
|
|
647
|
+
function syncColorState(newState, oldState, endpoint, options, logger) {
|
|
645
648
|
const colorTargets = [];
|
|
646
649
|
const colorSync = (options && options.hasOwnProperty('color_sync')) ? options.color_sync : true;
|
|
647
650
|
const result = {};
|
|
651
|
+
const [colorTempMin, colorTempMax] = findColorTempRange(endpoint, logger);
|
|
648
652
|
|
|
649
653
|
// check if color sync is enabled
|
|
650
654
|
if (!colorSync) {
|
|
@@ -704,7 +708,8 @@ function syncColorState(newState, oldState, options) {
|
|
|
704
708
|
if (result.color.hasOwnProperty('hue') && result.color.hasOwnProperty('saturation')) {
|
|
705
709
|
const hsv = new ColorHSV(result.color.hue, result.color.saturation);
|
|
706
710
|
if (colorTargets.includes('color_temp')) {
|
|
707
|
-
result.color_temp = precisionRound(hsv.toMireds(), 0)
|
|
711
|
+
result.color_temp = clampColorTemp(precisionRound(hsv.toMireds(), 0),
|
|
712
|
+
colorTempMin, colorTempMax, logger);
|
|
708
713
|
}
|
|
709
714
|
if (colorTargets.includes('xy')) {
|
|
710
715
|
Object.assign(result.color, hsv.toXY().rounded(4).toObject());
|
|
@@ -726,7 +731,8 @@ function syncColorState(newState, oldState, options) {
|
|
|
726
731
|
if (result.color.hasOwnProperty('x') && result.color.hasOwnProperty('y')) {
|
|
727
732
|
const xy = new ColorXY(result.color.x, result.color.y);
|
|
728
733
|
if (colorTargets.includes('color_temp')) {
|
|
729
|
-
result.color_temp = precisionRound(xy.toMireds(), 0)
|
|
734
|
+
result.color_temp = clampColorTemp(precisionRound(xy.toMireds(), 0),
|
|
735
|
+
colorTempMin, colorTempMax, logger);
|
|
730
736
|
}
|
|
731
737
|
if (colorTargets.includes('hs')) {
|
|
732
738
|
Object.assign(result.color, xy.toHSV().rounded(0).toObject(false, false));
|
package/lib/tuya.js
CHANGED
|
@@ -471,6 +471,12 @@ const dataPoints = {
|
|
|
471
471
|
hochTotalReverseActivePower: 117,
|
|
472
472
|
hochHistoricalVoltage: 118,
|
|
473
473
|
hochHistoricalCurrent: 119,
|
|
474
|
+
|
|
475
|
+
// TUYA / HUMIDITY/ILLUMINANCE/TEMPERATURE SENSOR
|
|
476
|
+
thitBatteryPercentage: 3,
|
|
477
|
+
thitIlluminanceLux: 7,
|
|
478
|
+
thitHumidity: 9,
|
|
479
|
+
thitTemperature: 8,
|
|
474
480
|
};
|
|
475
481
|
|
|
476
482
|
const thermostatWeekFormat = {
|