zigbee-herdsman-converters 14.0.322 → 14.0.326

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.
@@ -1425,11 +1425,11 @@ const converters = {
1425
1425
  const invert = model.meta && model.meta.coverInverted ? !options.invert_cover : options.invert_cover;
1426
1426
  if (msg.data.hasOwnProperty('currentPositionLiftPercentage') && msg.data['currentPositionLiftPercentage'] <= 100) {
1427
1427
  const value = msg.data['currentPositionLiftPercentage'];
1428
- result.position = invert ? value : 100 - value;
1428
+ result[postfixWithEndpointName('position', msg, model)] = invert ? value : 100 - value;
1429
1429
  }
1430
1430
  if (msg.data.hasOwnProperty('currentPositionTiltPercentage') && msg.data['currentPositionTiltPercentage'] <= 100) {
1431
1431
  const value = msg.data['currentPositionTiltPercentage'];
1432
- result.tilt = invert ? value : 100 - value;
1432
+ result[postfixWithEndpointName('tilt', msg, model)] = invert ? value : 100 - value;
1433
1433
  }
1434
1434
  return result;
1435
1435
  },
@@ -1969,7 +1969,7 @@ const converters = {
1969
1969
  convertSet: async (entity, key, value, meta) => {
1970
1970
  if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
1971
1971
  'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG31LM', 'QBCZ15LM', 'QBKG20LM', 'QBKG38LM',
1972
- 'QBKG34LM', 'QBCZ14LM', 'QBKG19LM'].includes(meta.mapped.model)) {
1972
+ 'QBKG34LM', 'QBCZ14LM', 'QBKG19LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
1973
1973
  await entity.write('aqaraOpple', {0x0201: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
1974
1974
  } else if (['ZNCZ02LM', 'QBCZ11LM'].includes(meta.mapped.model)) {
1975
1975
  const payload = value ?
@@ -1992,7 +1992,7 @@ const converters = {
1992
1992
  convertGet: async (entity, key, meta) => {
1993
1993
  if (['ZNCZ04LM', 'QBKG25LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM', 'QBKG39LM', 'QBKG41LM', 'ZNCZ15LM',
1994
1994
  'WS-EUK02', 'WS-EUK01', 'QBKG31LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG20LM', 'QBKG34LM', 'QBKG19LM',
1995
- 'QBKG38LM'].includes(meta.mapped.model)) {
1995
+ 'QBKG38LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
1996
1996
  await entity.read('aqaraOpple', [0x0201]);
1997
1997
  } else if (['ZNCZ02LM', 'QBCZ11LM', 'ZNCZ11LM'].includes(meta.mapped.model)) {
1998
1998
  await entity.read('aqaraOpple', [0xFFF0]);
@@ -466,6 +466,20 @@ module.exports = [
466
466
  description: 'Zigbee 12W Downlight RGB+CCT (pro)',
467
467
  extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
468
468
  },
469
+ {
470
+ zigbeeModel: ['GL-D-006P'],
471
+ model: 'GL-D-006P',
472
+ vendor: 'Gledopto',
473
+ description: 'Zigbee 6W anti-glare downlight RGB+CCT (pro)',
474
+ extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
475
+ },
476
+ {
477
+ zigbeeModel: ['GL-D-007P'],
478
+ model: 'GL-D-007P',
479
+ vendor: 'Gledopto',
480
+ description: 'Zigbee 12W anti-glare downlight RGB+CCT (pro)',
481
+ extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
482
+ },
469
483
  {
470
484
  zigbeeModel: ['GL-FL-004TZ'],
471
485
  model: 'GL-FL-004TZ',
package/devices/ikea.js CHANGED
@@ -760,7 +760,7 @@ module.exports = [
760
760
  extend: tradfriExtend.light_onoff_brightness_colortemp_color(),
761
761
  },
762
762
  {
763
- zigbeeModel: ['TRADFRI bulb E14 CWS 470lm'],
763
+ zigbeeModel: ['TRADFRI bulb E14 CWS 470lm', 'TRADFRI bulb E12 CWS 450lm'],
764
764
  model: 'LED1925G6',
765
765
  vendor: 'IKEA',
766
766
  description: 'TRADFRI LED bulb E14 470 lumen, opal, dimmable, white spectrum, color spectrum',
package/devices/lidl.js CHANGED
@@ -6,6 +6,356 @@ const extend = require('../lib/extend');
6
6
  const e = exposes.presets;
7
7
  const ea = exposes.access;
8
8
  const tuya = require('../lib/tuya');
9
+ const globalStore = require('../lib/store');
10
+
11
+ const tuyaLocal = {
12
+ dataPoints: {
13
+ zsHeatingSetpoint: 16,
14
+ zsChildLock: 40,
15
+ zsTempCalibration: 104,
16
+ zsLocalTemp: 24,
17
+ zsBatteryVoltage: 35,
18
+ zsComfortTemp: 101,
19
+ zsEcoTemp: 102,
20
+ zsHeatingSetpointAuto: 105,
21
+ zsOpenwindowTemp: 116,
22
+ zsOpenwindowTime: 117,
23
+ zsErrorStatus: 45,
24
+ zsMode: 2,
25
+ zsAwaySetting: 103,
26
+ zsBinaryOne: 106,
27
+ zsBinaryTwo: 107,
28
+ zsScheduleMonday: 109,
29
+ zsScheduleTuesday: 110,
30
+ zsScheduleWednesday: 111,
31
+ zsScheduleThursday: 112,
32
+ zsScheduleFriday: 113,
33
+ zsScheduleSaturday: 114,
34
+ zsScheduleSunday: 115,
35
+ },
36
+ };
37
+
38
+ const fzLocal = {
39
+ zs_thermostat: {
40
+ cluster: 'manuSpecificTuya',
41
+ type: ['commandGetData', 'commandSetDataResponse'],
42
+ convert: (model, msg, publish, options, meta) => {
43
+ const dp = msg.data.dp;
44
+ const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
45
+ const ret = {};
46
+ const daysMap = {1: 'monday', 2: 'tuesday', 3: 'wednesday', 4: 'thursday', 5: 'friday', 6: 'saturday', 7: 'sunday'};
47
+ const day = daysMap[value[0]];
48
+
49
+ switch (dp) {
50
+ case tuyaLocal.dataPoints.zsChildLock:
51
+ return {child_lock: value ? 'LOCK' : 'UNLOCK'};
52
+
53
+ case tuyaLocal.dataPoints.zsHeatingSetpoint:
54
+ if (value==0) ret.system_mode='off';
55
+ if (value==60) {
56
+ ret.system_mode='heat';
57
+ ret.preset = 'boost';
58
+ }
59
+
60
+ ret.current_heating_setpoint= (value / 2).toFixed(1);
61
+ if (value>0 && value<60) globalStore.putValue(msg.endpoint, 'current_heating_setpoint', ret.current_heating_setpoint);
62
+ return ret;
63
+ case tuyaLocal.dataPoints.zsHeatingSetpointAuto:
64
+ return {current_heating_setpoint_auto: (value / 2).toFixed(1)};
65
+
66
+ case tuyaLocal.dataPoints.zsOpenwindowTemp:
67
+ return {detectwindow_temperature: (value / 2).toFixed(1)};
68
+
69
+ case tuyaLocal.dataPoints.zsOpenwindowTime:
70
+ return {detectwindow_timeminute: value};
71
+
72
+ case tuyaLocal.dataPoints.zsLocalTemp:
73
+ return {local_temperature: (value / 10).toFixed(1)};
74
+
75
+ case tuyaLocal.dataPoints.zsBatteryVoltage:
76
+ return {voltage: Math.round(value * 10)};
77
+
78
+ case tuyaLocal.dataPoints.zsTempCalibration:
79
+ return {local_temperature_calibration: value > 55 ?
80
+ ((value - 0x100000000)/10).toFixed(1): (value/ 10).toFixed(1)};
81
+
82
+ case tuyaLocal.dataPoints.zsBinaryOne:
83
+ return {binary_one: value ? 'ON' : 'OFF'};
84
+
85
+ case tuyaLocal.dataPoints.zsBinaryTwo:
86
+ return {binary_two: value ? 'ON' : 'OFF'};
87
+
88
+ case tuyaLocal.dataPoints.zsComfortTemp:
89
+ return {comfort_temperature: (value / 2).toFixed(1)};
90
+
91
+ case tuyaLocal.dataPoints.zsEcoTemp:
92
+ return {eco_temperature: (value / 2).toFixed(1)};
93
+
94
+ case tuyaLocal.dataPoints.zsAwayTemp:
95
+ return {away_preset_temperature: (value / 2).toFixed(1)};
96
+
97
+ case tuyaLocal.dataPoints.zsMode:
98
+ switch (value) {
99
+ case 1: // manual
100
+ return {system_mode: 'heat', away_mode: 'OFF', preset: 'manual'};
101
+ case 2: // away
102
+ return {system_mode: 'auto', away_mode: 'ON', preset: 'holiday'};
103
+ case 0: // auto
104
+ return {system_mode: 'auto', away_mode: 'OFF', preset: 'schedule'};
105
+ default:
106
+ meta.logger.warn('zigbee-herdsman-converters:zsThermostat: ' +
107
+ `preset ${value} is not recognized.`);
108
+ break;
109
+ }
110
+ break;
111
+ case tuyaLocal.dataPoints.zsScheduleMonday:
112
+ case tuyaLocal.dataPoints.zsScheduleTuesday:
113
+ case tuyaLocal.dataPoints.zsScheduleWednesday:
114
+ case tuyaLocal.dataPoints.zsScheduleThursday:
115
+ case tuyaLocal.dataPoints.zsScheduleFriday:
116
+ case tuyaLocal.dataPoints.zsScheduleSaturday:
117
+ case tuyaLocal.dataPoints.zsScheduleSunday:
118
+ for (let i = 1; i <= 9; i++) {
119
+ const tempId = ((i-1) * 2) +1;
120
+ const timeId = ((i-1) * 2) +2;
121
+ ret[`${day}_temp_${i}`] = (value[tempId] / 2).toFixed(1);
122
+ if (i!=9) {
123
+ ret[`${day}_hour_${i}`] = Math.floor(value[timeId] / 4).toString().padStart(2, '0');
124
+ ret[`${day}_minute_${i}`] = ((value[timeId] % 4) *15).toString().padStart(2, '0');
125
+ }
126
+ }
127
+ return ret;
128
+ case tuyaLocal.dataPoints.zsAwaySetting:
129
+ ret.away_preset_year = value[0];
130
+ ret.away_preset_month = value[1];
131
+ ret.away_preset_day = value[2];
132
+ ret.away_preset_hour = value[3];
133
+ ret.away_preset_minute = value[4];
134
+ ret.away_preset_temperature = (value[5] / 2).toFixed(1);
135
+ ret.away_preset_days = (value[6]<<8)+value[7];
136
+ return ret;
137
+ default:
138
+ meta.logger.warn(`zigbee-herdsman-converters:zsThermostat: Unrecognized DP #${dp} with data ${JSON.stringify(msg.data)}`);
139
+ }
140
+ },
141
+ },
142
+ };
143
+ const tzLocal = {
144
+ zs_thermostat_child_lock: {
145
+ key: ['child_lock'],
146
+ convertSet: async (entity, key, value, meta) => {
147
+ await tuya.sendDataPointBool(entity, tuyaLocal.dataPoints.zsChildLock, value === 'LOCK');
148
+ },
149
+ },
150
+ zs_thermostat_binary_one: {
151
+ key: ['binary_one'],
152
+ convertSet: async (entity, key, value, meta) => {
153
+ await tuya.sendDataPointBool(entity, tuyaLocal.dataPoints.zsBinaryOne, value === 'ON');
154
+ },
155
+ },
156
+ zs_thermostat_binary_two: {
157
+ key: ['binary_two'],
158
+ convertSet: async (entity, key, value, meta) => {
159
+ await tuya.sendDataPointBool(entity, tuyaLocal.dataPoints.zsBinaryTwo, value === 'ON');
160
+ },
161
+ },
162
+ zs_thermostat_current_heating_setpoint: {
163
+ key: ['current_heating_setpoint'],
164
+ convertSet: async (entity, key, value, meta) => {
165
+ let temp = Math.round(value * 2);
166
+ if (temp<=0) temp = 1;
167
+ if (temp>=60) temp = 59;
168
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsHeatingSetpoint, temp);
169
+ },
170
+ },
171
+ zs_thermostat_current_heating_setpoint_auto: {
172
+ key: ['current_heating_setpoint_auto'],
173
+ convertSet: async (entity, key, value, meta) => {
174
+ let temp = Math.round(value * 2);
175
+ if (temp<=0) temp = 1;
176
+ if (temp>=60) temp = 59;
177
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsHeatingSetpointAuto, temp);
178
+ },
179
+ },
180
+ zs_thermostat_comfort_temp: {
181
+ key: ['comfort_temperature'],
182
+ convertSet: async (entity, key, value, meta) => {
183
+ meta.logger.debug(JSON.stringify(entity));
184
+ const temp = Math.round(value * 2);
185
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsComfortTemp, temp);
186
+ },
187
+ },
188
+ zs_thermostat_openwindow_temp: {
189
+ key: ['detectwindow_temperature'],
190
+ convertSet: async (entity, key, value, meta) => {
191
+ let temp = Math.round(value * 2);
192
+ if (temp<=0) temp = 1;
193
+ if (temp>=60) temp = 59;
194
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsOpenwindowTemp, temp);
195
+ },
196
+ },
197
+ zs_thermostat_openwindow_time: {
198
+ key: ['detectwindow_timeminute'],
199
+ convertSet: async (entity, key, value, meta) => {
200
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsOpenwindowTime, value);
201
+ },
202
+ },
203
+ zs_thermostat_eco_temp: {
204
+ key: ['eco_temperature'],
205
+ convertSet: async (entity, key, value, meta) => {
206
+ const temp = Math.round(value * 2);
207
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsEcoTemp, temp);
208
+ },
209
+ },
210
+ zs_thermostat_preset_mode: {
211
+ key: ['preset'],
212
+ convertSet: async (entity, key, value, meta) => {
213
+ const lookup = {'schedule': 0, 'manual': 1, 'holiday': 2};
214
+ if (value == 'boost') {
215
+ await tuya.sendDataPointEnum(entity, tuyaLocal.dataPoints.zsMode, lookup['manual']);
216
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsHeatingSetpoint, 60);
217
+ } else {
218
+ await tuya.sendDataPointEnum(entity, tuyaLocal.dataPoints.zsMode, lookup[value]);
219
+ if (value == 'manual') {
220
+ const temp = globalStore.getValue(entity, 'current_heating_setpoint');
221
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsHeatingSetpoint, temp ? Math.round(temp * 2) : 43 );
222
+ }
223
+ }
224
+ },
225
+ },
226
+ zs_thermostat_system_mode: {
227
+ key: ['system_mode'],
228
+ convertSet: async (entity, key, value, meta) => {
229
+ if (value == 'off') {
230
+ await tuya.sendDataPointEnum(entity, tuyaLocal.dataPoints.zsMode, 1);
231
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsHeatingSetpoint, 0);
232
+ } else if (value == 'auto') {
233
+ await tuya.sendDataPointEnum(entity, tuyaLocal.dataPoints.zsMode, 0);
234
+ } else if (value == 'heat') {
235
+ // manual
236
+ const temp = globalStore.getValue(entity, 'current_heating_setpoint');
237
+ await tuya.sendDataPointEnum(entity, tuyaLocal.dataPoints.zsMode, 1);
238
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsHeatingSetpoint, temp ? Math.round(temp * 2) : 43 );
239
+ }
240
+ },
241
+ },
242
+ zs_thermostat_local_temperature_calibration: {
243
+ key: ['local_temperature_calibration'],
244
+ convertSet: async (entity, key, value, meta) => {
245
+ if (value > 0) value = value*10;
246
+ if (value < 0) value = value*10 + 0x100000000;
247
+ await tuya.sendDataPointValue(entity, tuyaLocal.dataPoints.zsTempCalibration, value);
248
+ },
249
+ },
250
+ zs_thermostat_away_setting: {
251
+ key: ['away_setting'],
252
+ convertSet: async (entity, key, value, meta) => {
253
+ const result = [];
254
+ const daysInMonth = new Date(2000+result[0], result[1], 0).getDate();
255
+
256
+ for (const attrName of ['away_preset_year',
257
+ 'away_preset_month',
258
+ 'away_preset_day',
259
+ 'away_preset_hour',
260
+ 'away_preset_minute',
261
+ 'away_preset_temperature',
262
+ 'away_preset_days']) {
263
+ let v = 0;
264
+ if (value.hasOwnProperty(attrName)) {
265
+ v = value[attrName];
266
+ } else if (meta.state.hasOwnProperty(attrName)) {
267
+ v = meta.state[attrName];
268
+ }
269
+ switch (attrName) {
270
+ case 'away_preset_year':
271
+ if (v<17 || v>99) v = 17;
272
+ result.push(Math.round(v));
273
+ break;
274
+ case 'away_preset_month':
275
+ if (v<1 || v>12) v = 1;
276
+ result.push(Math.round(v));
277
+ break;
278
+ case 'away_preset_day':
279
+ if (v<1) {
280
+ v = 1;
281
+ } else if (v>daysInMonth) {
282
+ v = daysInMonth;
283
+ }
284
+ result.push(Math.round(v));
285
+ break;
286
+ case 'away_preset_hour':
287
+ if (v<0 || v>23) v = 0;
288
+ result.push(Math.round(v));
289
+ break;
290
+ case 'away_preset_minute':
291
+ if (v<0 || v>59) v = 0;
292
+ result.push(Math.round(v));
293
+ break;
294
+ case 'away_preset_temperature':
295
+ if (v<0.5 || v>29.5) v = 17;
296
+ result.push(Math.round(v * 2));
297
+ break;
298
+ case 'away_preset_days':
299
+ if (v<1 || v>9999) v = 1;
300
+ result.push((v & 0xff00)>>8);
301
+ result.push((v & 0x00ff));
302
+ break;
303
+ }
304
+ }
305
+
306
+ await tuya.sendDataPointRaw(entity, tuyaLocal.dataPoints.zsAwaySetting, result);
307
+ },
308
+ },
309
+ zs_thermostat_local_schedule: {
310
+ key: ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'],
311
+ convertSet: async (entity, key, value, meta) => {
312
+ const daysMap = {'monday': 1, 'tuesday': 2, 'wednesday': 3, 'thursday': 4, 'friday': 5, 'saturday': 6, 'sunday': 7};
313
+ const day = daysMap[key];
314
+ const results = [];
315
+ results.push(day);
316
+ for (let i = 1; i <= 9; i++) {
317
+ // temperature
318
+ const attrName = `${key}_temp_${i}`;
319
+ let v = 17;
320
+ if (value.hasOwnProperty(attrName)) {
321
+ v = value[attrName];
322
+ } else if (meta.state.hasOwnProperty(attrName)) {
323
+ v = meta.state[attrName];
324
+ }
325
+ if (v<0.5 || v>29.5) v = 17;
326
+ results.push(Math.round(v * 2));
327
+ if (i!=9) {
328
+ // hour
329
+ let attrName = `${key}_hour_${i}`;
330
+ let h = 0;
331
+ if (value.hasOwnProperty(attrName)) {
332
+ h = value[attrName];
333
+ } else if (meta.state.hasOwnProperty(attrName)) {
334
+ h = meta.state[attrName];
335
+ }
336
+ // minute
337
+ attrName = `${key}_minute_${i}`;
338
+ let m = 0;
339
+ if (value.hasOwnProperty(attrName)) {
340
+ m = value[attrName];
341
+ } else if (meta.state.hasOwnProperty(attrName)) {
342
+ m = meta.state[attrName];
343
+ }
344
+ let rt = h*4 + m/15;
345
+ if (rt<1) {
346
+ rt =1;
347
+ } else if (rt>96) {
348
+ rt = 96;
349
+ }
350
+ results.push(Math.round(rt));
351
+ }
352
+ }
353
+ if (value > 0) value = value*10;
354
+ if (value < 0) value = value*10 + 0x100000000;
355
+ await tuya.sendDataPointRaw(entity, (109+day-1), results);
356
+ },
357
+ },
358
+ };
9
359
 
10
360
  module.exports = [
11
361
  {
@@ -301,4 +651,57 @@ module.exports = [
301
651
  await reporting.onOff(endpoint);
302
652
  },
303
653
  },
654
+ {
655
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'}],
656
+ model: '368308_2010',
657
+ vendor: 'Lidl',
658
+ description: 'Silvercrest rdiator valve with thermostat',
659
+ fromZigbee: [fz.ignore_tuya_set_time, fzLocal.zs_thermostat, fz.tuya_data_point_dump],
660
+ toZigbee: [tzLocal.zs_thermostat_current_heating_setpoint, tzLocal.zs_thermostat_child_lock,
661
+ tzLocal.zs_thermostat_comfort_temp, tzLocal.zs_thermostat_eco_temp, tzLocal.zs_thermostat_preset_mode,
662
+ tzLocal.zs_thermostat_system_mode, tzLocal.zs_thermostat_local_temperature_calibration,
663
+ tzLocal.zs_thermostat_current_heating_setpoint_auto, tzLocal.zs_thermostat_openwindow_time,
664
+ tzLocal.zs_thermostat_openwindow_temp, tzLocal.zs_thermostat_binary_one, tzLocal.zs_thermostat_binary_two,
665
+ tzLocal.zs_thermostat_away_setting, tzLocal.zs_thermostat_local_schedule],
666
+ onEvent: tuya.onEventSetLocalTime,
667
+ configure: async (device, coordinatorEndpoint, logger) => {
668
+ const endpoint = device.getEndpoint(1);
669
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic']);
670
+ },
671
+ exposes: [
672
+ e.child_lock(), e.comfort_temperature(), e.eco_temperature(), e.battery_voltage(),
673
+ exposes.numeric('current_heating_setpoint_auto', ea.STATE_SET).withValueMin(0.5).withValueMax(29.5)
674
+ .withValueStep(0.5).withUnit('°C').withDescription('Temperature setpoint automatic'),
675
+ exposes.climate().withSetpoint('current_heating_setpoint', 0.5, 29.5, 0.5, ea.STATE_SET)
676
+ .withLocalTemperature(ea.STATE).withLocalTemperatureCalibration(-20, 20, 1, ea.STATE_SET)
677
+ .withSystemMode(['off', 'heat', 'auto'], ea.STATE_SET)
678
+ .withPreset(['schedule', 'manual', 'holiday', 'boost']),
679
+ exposes.numeric('detectwindow_temperature', ea.STATE_SET).withUnit('°C').withDescription('Open window detection temperature'),
680
+ exposes.numeric('detectwindow_timeminute', ea.STATE_SET).withUnit('min').withDescription('Open window time in minute'),
681
+ exposes.binary('binary_one', ea.STATE_SET, 'ON', 'OFF').withDescription('Unknown binary one'),
682
+ exposes.binary('binary_two', ea.STATE_SET, 'ON', 'OFF').withDescription('Unknown binary two'),
683
+ exposes.binary('away_mode', ea.STATE, 'ON', 'OFF').withDescription('Away mode'),
684
+ exposes.composite('away_setting', 'away_setting').withFeature(e.away_preset_days()).setAccess('away_preset_days', ea.ALL)
685
+ .withFeature(e.away_preset_temperature()).setAccess('away_preset_temperature', ea.ALL)
686
+ .withFeature(exposes.numeric('away_preset_year', ea.ALL).withUnit('year').withDescription('Start away year 20xx'))
687
+ .withFeature(exposes.numeric('away_preset_month', ea.ALL).withUnit('month').withDescription('Start away month'))
688
+ .withFeature(exposes.numeric('away_preset_day', ea.ALL).withUnit('day').withDescription('Start away day'))
689
+ .withFeature(exposes.numeric('away_preset_hour', ea.ALL).withUnit('hour').withDescription('Start away hours'))
690
+ .withFeature(exposes.numeric('away_preset_minute', ea.ALL).withUnit('min').withDescription('Start away minutes')),
691
+ ...['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'].map((day) => {
692
+ const expose = exposes.composite(day, day);
693
+ [1, 2, 3, 4, 5, 6, 7, 8, 9].forEach((i) => {
694
+ expose.withFeature(exposes.numeric(`${day}_temp_${i}`, ea.ALL).withValueMin(0.5)
695
+ .withValueMax(29.5).withValueStep(0.5).withUnit('°C').withDescription(`Temperature ${i}`));
696
+ expose.withFeature(exposes.enum(`${day}_hour_${i}`, ea.STATE_SET,
697
+ ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09',
698
+ '10', '11', '12', '13', '14', '15', '16', '17', '18', '19',
699
+ '20', '21', '22', '23', '24']).withDescription(`Hour TO for temp ${i}`));
700
+ expose.withFeature(exposes.enum(`${day}_minute_${i}`, ea.STATE_SET, ['00', '15', '30', '45'])
701
+ .withDescription(`Minute TO for temp ${i}`));
702
+ });
703
+ return expose;
704
+ }),
705
+ ],
706
+ },
304
707
  ];
@@ -39,6 +39,6 @@ module.exports = [
39
39
  model: 'FUT038Z',
40
40
  description: 'RGBW LED controller',
41
41
  vendor: 'Miboxer',
42
- extend: extend.light_onoff_brightness_colortemp({disableColorTempStartup: true, colorTempRange: [153, 500]}),
42
+ extend: extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}),
43
43
  },
44
44
  ];
package/devices/osram.js CHANGED
@@ -30,6 +30,14 @@ module.exports = [
30
30
  extend: extend.ledvance.light_onoff_brightness_colortemp_color(),
31
31
  ota: ota.ledvance,
32
32
  },
33
+ {
34
+ zigbeeModel: ['LIGHTIFY RT RGBW'],
35
+ model: '73741_LIGHTIFY',
36
+ vendor: 'OSRAM',
37
+ description: 'LIGHTIFY RT5/6 LED',
38
+ extend: extend.ledvance.light_onoff_brightness_colortemp_color(),
39
+ ota: ota.ledvance,
40
+ },
33
41
  {
34
42
  zigbeeModel: ['Classic A60 RGBW'],
35
43
  model: 'AA69697',
@@ -38,6 +38,15 @@ module.exports = [
38
38
  extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
39
39
  ota: ota.zigbeeOTA,
40
40
  },
41
+ {
42
+ zigbeeModel: ['929003054301'],
43
+ model: '929003054301',
44
+ vendor: 'Philips',
45
+ description: 'Hue White Ambiance Cher Pendant',
46
+ meta: {turnsOffAtBrightness1: true},
47
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
48
+ ota: ota.zigbeeOTA,
49
+ },
41
50
  {
42
51
  zigbeeModel: ['5063131P7'],
43
52
  model: '5063131P7',
@@ -726,6 +735,15 @@ module.exports = [
726
735
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
727
736
  ota: ota.zigbeeOTA,
728
737
  },
738
+ {
739
+ zigbeeModel: ['LCA006'],
740
+ model: '9290024689',
741
+ vendor: 'Philips',
742
+ description: 'Hue white and color ambiance B22 1100lm',
743
+ meta: {turnsOffAtBrightness1: true},
744
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
745
+ ota: ota.zigbeeOTA,
746
+ },
729
747
  {
730
748
  zigbeeModel: ['LCA008'],
731
749
  model: '929002471601',
@@ -1067,6 +1085,15 @@ module.exports = [
1067
1085
  extend: hueExtend.light_onoff_brightness_colortemp_color(),
1068
1086
  ota: ota.zigbeeOTA,
1069
1087
  },
1088
+ {
1089
+ zigbeeModel: ['4090231P9'],
1090
+ model: '4090231P9',
1091
+ vendor: 'Philips',
1092
+ description: 'Hue Liane',
1093
+ meta: {turnsOffAtBrightness1: true},
1094
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1095
+ ota: ota.zigbeeOTA,
1096
+ },
1070
1097
  {
1071
1098
  zigbeeModel: ['LTC001'],
1072
1099
  model: '3261030P7',
@@ -1237,6 +1264,15 @@ module.exports = [
1237
1264
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
1238
1265
  ota: ota.zigbeeOTA,
1239
1266
  },
1267
+ {
1268
+ zigbeeModel: ['929003099101'],
1269
+ model: '929003099101',
1270
+ vendor: 'Philips',
1271
+ description: 'Hue white ambiance Aurelle rectangle panel light',
1272
+ meta: {turnsOffAtBrightness1: true},
1273
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
1274
+ ota: ota.zigbeeOTA,
1275
+ },
1240
1276
  {
1241
1277
  zigbeeModel: ['LTC016'],
1242
1278
  model: '3216431P5',
@@ -1417,6 +1453,15 @@ module.exports = [
1417
1453
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1418
1454
  ota: ota.zigbeeOTA,
1419
1455
  },
1456
+ {
1457
+ zigbeeModel: ['LCT020'],
1458
+ model: '4080148P7',
1459
+ vendor: 'Philips',
1460
+ description: 'Hue Signe table light',
1461
+ meta: {turnsOffAtBrightness1: true},
1462
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1463
+ ota: ota.zigbeeOTA,
1464
+ },
1420
1465
  {
1421
1466
  zigbeeModel: ['4080148P9'],
1422
1467
  model: '4080148P9',
@@ -1780,6 +1825,39 @@ module.exports = [
1780
1825
  },
1781
1826
  ota: ota.zigbeeOTA,
1782
1827
  },
1828
+ {
1829
+ zigbeeModel: ['SML003'],
1830
+ model: '9290030675',
1831
+ vendor: 'Philips',
1832
+ description: 'Hue motion sensor',
1833
+ fromZigbee: [fz.battery, fz.occupancy, fz.temperature, fz.occupancy_timeout, fz.illuminance,
1834
+ fz.hue_motion_sensitivity, fz.hue_motion_led_indication],
1835
+ exposes: [e.temperature(), e.occupancy(), e.battery(), e.illuminance_lux(), e.illuminance(),
1836
+ exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']),
1837
+ exposes.binary('led_indication', ea.ALL, true, false).withDescription('Blink green LED on motion detection'),
1838
+ exposes.numeric('occupancy_timeout', ea.ALL).withUnit('second').withValueMin(0).withValueMax(65535)],
1839
+ toZigbee: [tz.occupancy_timeout, tz.hue_motion_sensitivity, tz.hue_motion_led_indication],
1840
+ endpoint: (device) => {
1841
+ return {
1842
+ 'default': 2, // default
1843
+ 'ep1': 1,
1844
+ 'ep2': 2, // e.g. for write to msOccupancySensing
1845
+ };
1846
+ },
1847
+ configure: async (device, coordinatorEndpoint, logger) => {
1848
+ const endpoint = device.getEndpoint(2);
1849
+ const binds = ['genPowerCfg', 'msIlluminanceMeasurement', 'msTemperatureMeasurement', 'msOccupancySensing'];
1850
+ await reporting.bind(endpoint, coordinatorEndpoint, binds);
1851
+ await reporting.batteryPercentageRemaining(endpoint);
1852
+ await reporting.occupancy(endpoint);
1853
+ await reporting.temperature(endpoint);
1854
+ await reporting.illuminance(endpoint);
1855
+ // read occupancy_timeout and motion_sensitivity
1856
+ await endpoint.read('msOccupancySensing', ['pirOToUDelay']);
1857
+ await endpoint.read('msOccupancySensing', [48], {manufacturerCode: 4107});
1858
+ },
1859
+ ota: ota.zigbeeOTA,
1860
+ },
1783
1861
  {
1784
1862
  zigbeeModel: ['LOM001'],
1785
1863
  model: '929002240401',
@@ -2323,4 +2401,22 @@ module.exports = [
2323
2401
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2324
2402
  ota: ota.zigbeeOTA,
2325
2403
  },
2404
+ {
2405
+ zigbeeModel: ['LTA005'],
2406
+ model: '8719514392830',
2407
+ vendor: 'Philips',
2408
+ description: 'Hue White Ambiance E27 filament screw globe',
2409
+ meta: {turnsOffAtBrightness1: true},
2410
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [222, 454]}),
2411
+ ota: ota.zigbeeOTA,
2412
+ },
2413
+ {
2414
+ zigbeeModel: ['LWE007'],
2415
+ model: '9290030211',
2416
+ vendor: 'Philips',
2417
+ description: 'Hue white Candle bulb E14 bluetooth',
2418
+ meta: {turnsOffAtBrightness1: true},
2419
+ extend: hueExtend.light_onoff_brightness(),
2420
+ ota: ota.zigbeeOTA,
2421
+ },
2326
2422
  ];
@@ -85,4 +85,16 @@ module.exports = [
85
85
  meta: {battery: {dontDividePercentage: true}},
86
86
  exposes: [e.contact(), e.battery_low(), e.battery(), e.battery_voltage()],
87
87
  },
88
+ {
89
+ zigbeeModel: ['3RSP019BZ'],
90
+ model: '3RSP019BZ',
91
+ vendor: 'Third Reality',
92
+ description: 'Zigbee / BLE smart plug',
93
+ extend: extend.switch(),
94
+ configure: async (device, coordinatorEndpoint, logger) => {
95
+ const endpoint = device.getEndpoint(1);
96
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
97
+ await reporting.onOff(endpoint);
98
+ },
99
+ },
88
100
  ];