zigbee-herdsman-converters 14.0.629 → 14.0.631

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.
@@ -785,6 +785,20 @@ const converters = {
785
785
  }
786
786
  },
787
787
  },
788
+ on_off_force_multiendpoint: {
789
+ cluster: 'genOnOff',
790
+ type: ['attributeReport', 'readResponse'],
791
+ convert: (model, msg, publish, options, meta) => {
792
+ // This converted is need instead of `fz.on_off` when no meta: {multiEndpoint: true} can be defined for this device
793
+ // but it is needed for the `state`. E.g. when a switch has 3 channels (state_l1, state_l2, state_l3) but
794
+ // has combined power measurements (power, energy))
795
+ if (msg.data.hasOwnProperty('onOff')) {
796
+ const endpointName = model.hasOwnProperty('endpoint') ?
797
+ utils.getKey(model.endpoint(meta.device), msg.endpoint.ID) : msg.endpoint.ID;
798
+ return {[`state_${endpointName}`]: msg.data['onOff'] === 1 ? 'ON' : 'OFF'};
799
+ }
800
+ },
801
+ },
788
802
  on_off_skip_duplicate_transaction: {
789
803
  cluster: 'genOnOff',
790
804
  type: ['attributeReport', 'readResponse'],
@@ -79,6 +79,13 @@ const batteryRotaryDimmer = (...endpointsIds) => ({
79
79
  });
80
80
 
81
81
  module.exports = [
82
+ {
83
+ zigbeeModel: ['TWBulb51AU'],
84
+ model: 'AU-A1GSZ9CX',
85
+ vendor: 'Aurora',
86
+ description: 'AOne GLS lamp 9w tunable dimmable 2200-5000K',
87
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [200, 454]}),
88
+ },
82
89
  {
83
90
  zigbeeModel: ['RGBCXStrip50AU'],
84
91
  model: 'AU-A1ZBSCRGBCX',
@@ -37,7 +37,7 @@ module.exports = [
37
37
  .withDescription('Thermostat Orientation. This is important for the PID in how it assesses temperature. ' +
38
38
  '`false` Horizontal or `true` Vertical'),
39
39
  exposes.binary('viewing_direction', ea.ALL, true, false)
40
- .withDescription('Viewing/Display Direction. `false` Horizontal or `true` Vertical'),
40
+ .withDescription('Viewing/display direction, `false` normal or `true` upside-down'),
41
41
  exposes.binary('heat_available', ea.ALL, true, false)
42
42
  .withDescription('Not clear how this affects operation. However, it would appear that the device does not execute any ' +
43
43
  'motor functions if this is set to false. This may be a means to conserve battery during periods that the heating ' +
@@ -290,16 +290,20 @@ module.exports = [
290
290
  model: 'MOSZB-140',
291
291
  vendor: 'Develco',
292
292
  description: 'Motion sensor',
293
- fromZigbee: [fz.temperature, fz.illuminance, fz.ias_occupancy_alarm_1],
293
+ fromZigbee: [fz.temperature, fz.illuminance, fz.ias_occupancy_alarm_1, fz.battery],
294
294
  toZigbee: [],
295
- exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.temperature(), e.illuminance_lux()],
295
+ exposes: [e.occupancy(), e.battery(), e.battery_low(), e.tamper(), e.temperature(), e.illuminance_lux()],
296
+ meta: {battery: {voltageToPercentage: '3V_2500'}},
296
297
  configure: async (device, coordinatorEndpoint, logger) => {
297
- const endpoint1 = device.getEndpoint(38);
298
- await reporting.bind(endpoint1, coordinatorEndpoint, ['msTemperatureMeasurement']);
299
- await reporting.temperature(endpoint1);
300
- const endpoint2 = device.getEndpoint(39);
301
- await reporting.bind(endpoint2, coordinatorEndpoint, ['msIlluminanceMeasurement']);
302
- await reporting.illuminance(endpoint2);
298
+ const endpoint1 = device.getEndpoint(35);
299
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['genPowerCfg']);
300
+ await reporting.batteryVoltage(endpoint1, {min: constants.repInterval.HOUR, max: 43200, change: 100});
301
+ const endpoint2 = device.getEndpoint(38);
302
+ await reporting.bind(endpoint2, coordinatorEndpoint, ['msTemperatureMeasurement']);
303
+ await reporting.temperature(endpoint2);
304
+ const endpoint3 = device.getEndpoint(39);
305
+ await reporting.bind(endpoint3, coordinatorEndpoint, ['msIlluminanceMeasurement']);
306
+ await reporting.illuminance(endpoint3);
303
307
  },
304
308
  },
305
309
  {
@@ -2,6 +2,7 @@ const exposes = require('../lib/exposes');
2
2
  const globalStore = require('../lib/store');
3
3
  const ota = require('../lib/ota');
4
4
  const extend = require('../lib/extend');
5
+ const reporting = require('../lib/reporting');
5
6
  const utils = require('../lib/utils');
6
7
  const tz = require('../converters/toZigbee');
7
8
  const e = exposes.presets;
@@ -600,6 +601,21 @@ module.exports = [
600
601
  description: 'Zigbee 10W Floodlight RGB+CCT (pro)',
601
602
  extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
602
603
  },
604
+ {
605
+ zigbeeModel: ['GL-C-004P'],
606
+ model: 'GL-C-004P',
607
+ vendor: 'Gledopto',
608
+ description: 'Zigbee LED Strip Light Kit',
609
+ extend: gledoptoExtend.light_onoff_brightness_colortemp({noConfigure: true, colorTempRange: [158, 495]}),
610
+ configure: async (device, coordinatorEndpoint, logger) => {
611
+ await extend.light_onoff_brightness_colortemp().configure(device, coordinatorEndpoint, logger);
612
+ const endpoint = device.getEndpoint(11);
613
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingColorCtrl']);
614
+ await reporting.onOff(endpoint);
615
+ await reporting.brightness(endpoint);
616
+ await reporting.colorTemperature(endpoint);
617
+ },
618
+ },
603
619
  {
604
620
  zigbeeModel: ['GL-FL-001P'],
605
621
  model: 'GL-FL-001P',
package/devices/immax.js CHANGED
@@ -53,6 +53,13 @@ module.exports = [
53
53
  description: 'Neo SMART LED strip RGB + CCT, color, dimmable, Zigbee 3.0',
54
54
  extend: extend.light_onoff_brightness_colortemp_color(),
55
55
  },
56
+ {
57
+ fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_pwauw3g2'}],
58
+ model: '07743L',
59
+ vendor: 'Immax',
60
+ description: 'Neo Smart LED E27 11W RGB + CCT, color, dimmable, Zigbee 3.0',
61
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
62
+ },
56
63
  {
57
64
  zigbeeModel: ['Keyfob-ZB3.0'],
58
65
  model: '07046L',
package/devices/insta.js CHANGED
@@ -83,7 +83,7 @@ module.exports = [
83
83
  {ID: 242, profileID: 41440, deviceID: 97},
84
84
  ]},
85
85
  ],
86
- zigbeeModel: ['57004000'],
86
+ zigbeeModel: ['NEXENTRO Pushbutton Interface', '57004000'],
87
87
  model: '57004000',
88
88
  vendor: 'Insta',
89
89
  description: 'Pushbutton Interface 2-gang 230V',
package/devices/lellki.js CHANGED
@@ -133,14 +133,16 @@ module.exports = [
133
133
  description: 'Power cord 4 sockets EU (with power monitoring)',
134
134
  vendor: 'LELLKI',
135
135
  extend: extend.switch(),
136
- fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory],
136
+ fromZigbee: [fz.on_off_force_multiendpoint, fz.electrical_measurement, fz.metering, fz.ignore_basic_report,
137
+ fz.tuya_switch_power_outage_memory],
137
138
  toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
138
139
  configure: async (device, coordinatorEndpoint, logger) => {
139
140
  const endpoint = device.getEndpoint(1);
140
141
  await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
141
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
142
- await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
143
- await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
142
+ for (const ep of [1, 2, 3]) {
143
+ await reporting.bind(device.getEndpoint(ep), coordinatorEndpoint, ['genOnOff']);
144
+ await reporting.onOff(device.getEndpoint(ep));
145
+ }
144
146
  endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
145
147
  endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
146
148
  device.save();
@@ -14,6 +14,14 @@ module.exports = [
14
14
  extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 556]}),
15
15
  toZigbee: extend.light_onoff_brightness_colortemp_color().toZigbee.concat([tz.tint_scene]),
16
16
  },
17
+ {
18
+ zigbeeModel: ['Retro Bulb Gold XXL white+ambiance'],
19
+ model: '404065',
20
+ vendor: 'Müller Licht',
21
+ description: 'tint LED-Globe Retro Gold XXL E27',
22
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 555]}),
23
+ toZigbee: extend.light_onoff_brightness_colortemp().toZigbee.concat([tz.tint_scene]),
24
+ },
17
25
  {
18
26
  zigbeeModel: ['ZBT-DIMLight-A4700001'],
19
27
  model: '404023',
package/devices/niko.js CHANGED
@@ -131,6 +131,29 @@ module.exports = [
131
131
  exposes.binary('led_enable', ea.ALL, true, false).withDescription('Enable LED'),
132
132
  ],
133
133
  },
134
+ {
135
+ zigbeeModel: ['Smart plug Zigbee SE'],
136
+ model: '552-80698',
137
+ vendor: 'Niko',
138
+ description: 'Smart plug with side earthing pin',
139
+ fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.power_on_behavior],
140
+ toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power, tz.currentsummdelivered],
141
+ configure: async (device, coordinatorEndpoint, logger) => {
142
+ const endpoint = device.getEndpoint(1);
143
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
144
+ await reporting.onOff(endpoint);
145
+ // only activePower seems to be support, although compliance document states otherwise
146
+ await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
147
+ await reporting.activePower(endpoint);
148
+ await reporting.readMeteringMultiplierDivisor(endpoint);
149
+ await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
150
+ },
151
+ exposes: [
152
+ e.switch(), e.power().withAccess(ea.STATE_GET), e.energy().withAccess(ea.STATE_GET),
153
+ exposes.enum('power_on_behavior', ea.ALL, ['off', 'previous', 'on'])
154
+ .withDescription('Controls the behaviour when the device is powered on'),
155
+ ],
156
+ },
134
157
  {
135
158
  zigbeeModel: ['Smart plug Zigbee PE'],
136
159
  model: '552-80699',
@@ -2701,6 +2701,13 @@ module.exports = [
2701
2701
  description: 'Akari downlight',
2702
2702
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2703
2703
  },
2704
+ {
2705
+ zigbeeModel: ['LCD005'],
2706
+ model: '9290031345',
2707
+ vendor: 'Philips',
2708
+ description: 'Hue white and color ambiance 4" retrofit recessed downlight',
2709
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2710
+ },
2704
2711
  {
2705
2712
  zigbeeModel: ['LCD006'],
2706
2713
  model: '9290031346',
package/devices/rtx.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const fz = require('../converters/fromZigbee');
2
2
  const tz = require('../converters/toZigbee');
3
3
  const exposes = require('../lib/exposes');
4
+ const tuya = require('../lib/tuya');
4
5
  const e = exposes.presets;
5
6
  const ea = exposes.access;
6
7
 
@@ -14,7 +15,8 @@ module.exports = [
14
15
  model: 'ZVG1',
15
16
  vendor: 'RTX',
16
17
  description: 'Zigbee smart water valve',
17
- fromZigbee: [fz.ZVG1, fz.ignore_tuya_set_time, fz.ignore_basic_report],
18
+ onEvent: tuya.onEventSetLocalTime,
19
+ fromZigbee: [fz.ZVG1, fz.ignore_basic_report],
18
20
  toZigbee: [tz.tuya_switch_state, tz.ZVG1_weather_delay, tz.ZVG1_timer, tz.ZVG1_cycle_timer, tz.ZVG1_normal_schedule_timer],
19
21
  exposes: [e.switch().setAccess('state', ea.STATE_SET), e.battery(),
20
22
  exposes.enum('weather_delay', ea.STATE_SET, ['disabled', '24h', '48h', '72h']),
@@ -59,7 +59,7 @@ const fzLocal = {
59
59
 
60
60
  const tzLocal = {
61
61
  CSM300_SETUP: {
62
- key: ['rf_pairing_on', 'counting_freeze', 'tof_init', 'led_state', 'rf_state', 'transation', 'fast_in', 'fast_out'],
62
+ key: ['rf_pairing_on', 'counting_freeze', 'tof_init', 'led_state', 'rf_state', 'transaction', 'fast_in', 'fast_out'],
63
63
  convertSet: async (entity, key, value, meta) => {
64
64
  let payload = null;
65
65
  const endpoint = meta.device.endpoints.find((e) => e.supportsInputCluster('genAnalogInput'));
@@ -91,7 +91,7 @@ const tzLocal = {
91
91
  payload = {'presentValue': 89};
92
92
  }
93
93
  break;
94
- case 'transation':
94
+ case 'transaction':
95
95
  if (value === '0ms') {
96
96
  payload = {'presentValue': 90};
97
97
  } else if (value === '200ms') {
@@ -216,8 +216,8 @@ module.exports = [
216
216
  exposes.enum('tof_init', ea.SET, ['initial']).withDescription('ToF sensor initial'),
217
217
  exposes.binary('led_state', ea.SET, 'enable', 'disable').withDescription('Indicate LED enable/disable, default : enable'),
218
218
  exposes.binary('rf_state', ea.SET, 'enable', 'disable').withDescription('RF function enable/disable, default : disable'),
219
- exposes.enum('transation', ea.SET, ['0ms', '200ms', '400ms', '600ms', '800ms', '1,000ms'])
220
- .withDescription('Transation interval, default : 400ms'),
219
+ exposes.enum('transaction', ea.SET, ['0ms', '200ms', '400ms', '600ms', '800ms', '1,000ms'])
220
+ .withDescription('Transaction interval, default : 400ms'),
221
221
  exposes.binary('fast_in', ea.SET, 'enable', 'disable')
222
222
  .withDescription('Fast process enable/disable when people 0 to 1. default : enable'),
223
223
  exposes.binary('fast_out', ea.SET, 'enable', 'disable')
package/devices/siglis.js CHANGED
@@ -41,18 +41,26 @@ const zifgredFromZigbeeButtonEvent = {
41
41
  };
42
42
 
43
43
  const coverAndLightToZigbee = {
44
- key: ['state', 'brightness', 'brightness_percent', 'on_time'],
44
+ key: ['state', 'brightness', 'brightness_percent', 'on_time', 'position', 'tilt'],
45
45
  options: [exposes.options.transition()],
46
46
  convertSet: async (entity, key, value, meta) => {
47
- const isCover = (typeof value === 'string' && ['open', 'close', 'stop'].includes(value.toLowerCase()));
47
+ const isCover = entity.ID === 0x0b || entity.ID === 0x0c;
48
48
  if (isCover) {
49
- return tz.cover_state.convertSet(entity, key, value, meta);
49
+ if (key === 'state') {
50
+ return tz.cover_state.convertSet(entity, key, value, meta);
51
+ } else if (key === 'position' || key === 'tilt') {
52
+ return tz.cover_position_tilt.convertSet(entity, key, value, meta);
53
+ }
50
54
  } else {
51
- return tz.light_onoff_brightness.convertSet(entity, key, value, meta);
55
+ if (key === 'state' || key === 'brightness' || key === 'brightness_percent' || key === 'on_time') {
56
+ return tz.light_onoff_brightness.convertSet(entity, key, value, meta);
57
+ }
52
58
  }
53
59
  },
54
60
  convertGet: async (entity, key, meta) => {
55
- if (key === 'brightness') {
61
+ if (key === 'state' && (entity.ID === 0x0b || entity.ID === 0x0c)) {
62
+ await tz.cover_position_tilt.convertGet(entity, 'position', meta);
63
+ } else if (key === 'brightness') {
56
64
  await entity.read('genLevelCtrl', ['currentLevel']);
57
65
  } else if (key === 'state') {
58
66
  await tz.on_off.convertGet(entity, key, meta);
@@ -68,7 +76,7 @@ const buttonEventExposes = e.action([
68
76
  ]);
69
77
 
70
78
  function checkOption(device, options, key) {
71
- if (options.hasOwnProperty(key)) {
79
+ if (options != null && options.hasOwnProperty(key)) {
72
80
  if (options[key] === 'true') {
73
81
  return true;
74
82
  } else if (options[key] === 'false') {
@@ -80,16 +88,22 @@ function checkOption(device, options, key) {
80
88
  }
81
89
 
82
90
  function checkMetaOption(device, key) {
83
- const enabled = device.meta[key];
84
- if (enabled === undefined) {
85
- return false;
86
- } else {
87
- return !!enabled;
91
+ if (device != null) {
92
+ const enabled = device.meta[key];
93
+ if (enabled === undefined) {
94
+ return false;
95
+ } else {
96
+ return !!enabled;
97
+ }
88
98
  }
99
+
100
+ return false;
89
101
  }
90
102
 
91
103
  function setMetaOption(device, key, enabled) {
92
- device.meta[key] = enabled;
104
+ if (device != null && key != null) {
105
+ device.meta[key] = enabled;
106
+ }
93
107
  }
94
108
 
95
109
  module.exports = [
@@ -114,21 +128,19 @@ module.exports = [
114
128
  expose.push(buttonEventExposes);
115
129
  expose.push(e.linkquality());
116
130
 
117
- if (device != null && options != null) {
118
- if (checkOption(device, options, 'front_surface_enabled')) {
119
- expose.push(e.light_brightness_colorxy().withEndpoint('l1'));
120
- }
131
+ if (checkOption(device, options, 'front_surface_enabled')) {
132
+ expose.push(e.light_brightness_colorxy().withEndpoint('l1'));
133
+ }
121
134
 
122
- if (checkOption(device, options, 'relay_enabled')) {
123
- expose.push(e.switch().withEndpoint('l2'));
124
- }
135
+ if (checkOption(device, options, 'relay_enabled')) {
136
+ expose.push(e.switch().withEndpoint('l2'));
137
+ }
125
138
 
126
- if (checkOption(device, options, 'dimmer_enabled')) {
127
- if (checkOption(device, options, 'dimmer_dimming_enabled')) {
128
- expose.push(e.light_brightness().withEndpoint('l3'));
129
- } else {
130
- expose.push(e.switch().withEndpoint('l3'));
131
- }
139
+ if (checkOption(device, options, 'dimmer_enabled')) {
140
+ if (checkOption(device, options, 'dimmer_dimming_enabled')) {
141
+ expose.push(e.light_brightness().withEndpoint('l3'));
142
+ } else {
143
+ expose.push(e.switch().withEndpoint('l3'));
132
144
  }
133
145
  }
134
146
 
@@ -238,65 +250,63 @@ module.exports = [
238
250
  expose.push(buttonEventExposes);
239
251
  expose.push(e.linkquality());
240
252
 
241
- if (device != null && options != null) {
242
- if (checkOption(device, options, 'front_surface_enabled')) {
243
- expose.push(e.light_brightness_colorxy().withEndpoint('l1'));
244
- }
253
+ if (checkOption(device, options, 'front_surface_enabled')) {
254
+ expose.push(e.light_brightness_colorxy().withEndpoint('l1'));
255
+ }
245
256
 
246
- if (checkOption(device, options, 'dimmer_1_enabled')) {
247
- if (checkOption(device, options, 'dimmer_1_dimming_enabled')) {
248
- expose.push(e.light_brightness().withEndpoint('l2'));
249
- } else {
250
- expose.push(e.switch().withEndpoint('l2'));
251
- }
257
+ if (checkOption(device, options, 'dimmer_1_enabled')) {
258
+ if (checkOption(device, options, 'dimmer_1_dimming_enabled')) {
259
+ expose.push(e.light_brightness().withEndpoint('l2'));
260
+ } else {
261
+ expose.push(e.switch().withEndpoint('l2'));
252
262
  }
263
+ }
253
264
 
254
- if (checkOption(device, options, 'dimmer_2_enabled')) {
255
- if (checkOption(device, options, 'dimmer_2_dimming_enabled')) {
256
- expose.push(e.light_brightness().withEndpoint('l3'));
257
- } else {
258
- expose.push(e.switch().withEndpoint('l3'));
259
- }
265
+ if (checkOption(device, options, 'dimmer_2_enabled')) {
266
+ if (checkOption(device, options, 'dimmer_2_dimming_enabled')) {
267
+ expose.push(e.light_brightness().withEndpoint('l3'));
268
+ } else {
269
+ expose.push(e.switch().withEndpoint('l3'));
260
270
  }
271
+ }
261
272
 
262
- if (checkOption(device, options, 'dimmer_3_enabled')) {
263
- if (checkOption(device, options, 'dimmer_3_dimming_enabled')) {
264
- expose.push(e.light_brightness().withEndpoint('l4'));
265
- } else {
266
- expose.push(e.switch().withEndpoint('l4'));
267
- }
273
+ if (checkOption(device, options, 'dimmer_3_enabled')) {
274
+ if (checkOption(device, options, 'dimmer_3_dimming_enabled')) {
275
+ expose.push(e.light_brightness().withEndpoint('l4'));
276
+ } else {
277
+ expose.push(e.switch().withEndpoint('l4'));
268
278
  }
279
+ }
269
280
 
270
- if (checkOption(device, options, 'dimmer_4_enabled')) {
271
- if (checkOption(device, options, 'dimmer_4_dimming_enabled')) {
272
- expose.push(e.light_brightness().withEndpoint('l5'));
273
- } else {
274
- expose.push(e.switch().withEndpoint('l5'));
275
- }
281
+ if (checkOption(device, options, 'dimmer_4_enabled')) {
282
+ if (checkOption(device, options, 'dimmer_4_dimming_enabled')) {
283
+ expose.push(e.light_brightness().withEndpoint('l5'));
284
+ } else {
285
+ expose.push(e.switch().withEndpoint('l5'));
276
286
  }
287
+ }
277
288
 
278
- if (checkOption(device, options, 'cover_1_enabled')) {
279
- if (checkOption(device, options, 'cover_1_tilt_enabled')) {
280
- expose.push(exposes.cover()
281
- .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
282
- .withPosition().withTilt().withEndpoint('l6'));
283
- } else {
284
- expose.push(exposes.cover()
285
- .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
286
- .withPosition().withEndpoint('l6'));
287
- }
289
+ if (checkOption(device, options, 'cover_1_enabled')) {
290
+ if (checkOption(device, options, 'cover_1_tilt_enabled')) {
291
+ expose.push(exposes.cover()
292
+ .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
293
+ .withPosition().withTilt().withEndpoint('l6'));
294
+ } else {
295
+ expose.push(exposes.cover()
296
+ .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
297
+ .withPosition().withEndpoint('l6'));
288
298
  }
299
+ }
289
300
 
290
- if (checkOption(device, options, 'cover_2_enabled')) {
291
- if (checkOption(device, options, 'cover_2_tilt_enabled')) {
292
- expose.push(exposes.cover()
293
- .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
294
- .withPosition().withTilt().withEndpoint('l7'));
295
- } else {
296
- expose.push(exposes.cover()
297
- .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
298
- .withPosition().withEndpoint('l7'));
299
- }
301
+ if (checkOption(device, options, 'cover_2_enabled')) {
302
+ if (checkOption(device, options, 'cover_2_tilt_enabled')) {
303
+ expose.push(exposes.cover()
304
+ .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
305
+ .withPosition().withTilt().withEndpoint('l7'));
306
+ } else {
307
+ expose.push(exposes.cover()
308
+ .setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
309
+ .withPosition().withEndpoint('l7'));
300
310
  }
301
311
  }
302
312
 
@@ -311,9 +321,6 @@ module.exports = [
311
321
  fz.power_on_behavior,
312
322
  fz.ignore_basic_report,
313
323
  fz.cover_position_tilt,
314
- fz.command_cover_open,
315
- fz.command_cover_close,
316
- fz.command_cover_stop,
317
324
  ],
318
325
  toZigbee: [
319
326
  tz.light_color,
@@ -327,7 +334,6 @@ module.exports = [
327
334
  tz.light_hue_saturation_step,
328
335
  tz.light_color_options,
329
336
  tz.light_color_mode,
330
- tz.cover_position_tilt,
331
337
  coverAndLightToZigbee,
332
338
  ],
333
339
  meta: {multiEndpoint: true},
package/devices/tuya.js CHANGED
@@ -21,7 +21,7 @@ const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak',
21
21
  '_TZ3000_1h2x4akh', '_TZ3000_9vo5icau', '_TZ3000_cehuw1lw', '_TZ3000_ko6v90pg', '_TZ3000_f1bapcit', '_TZ3000_cjrngdr3',
22
22
  '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_idrffznf', '_TZ3000_okaz9tjs', '_TZ3210_q7oryllx',
23
23
  '_TZ3000_ss98ec5d', '_TZ3000_gznh2xla', '_TZ3000_hdopuwv6', '_TZ3000_gvn91tmx', '_TZ3000_dksbtrzs', '_TZ3000_b28wrpvx',
24
- '_TZ3000_aim0ztek', '_TZ3000_mlswgkc3', '_TZ3000_7dndcnnb'];
24
+ '_TZ3000_aim0ztek', '_TZ3000_mlswgkc3', '_TZ3000_7dndcnnb', '_TZ3000_waho4jtj'];
25
25
 
26
26
  const tzLocal = {
27
27
  SA12IZL_silence_siren: {
@@ -1044,6 +1044,22 @@ module.exports = [
1044
1044
  await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
1045
1045
  },
1046
1046
  },
1047
+ {
1048
+ fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3040_msl6wxk9'}],
1049
+ model: '40ZH-O',
1050
+ vendor: 'TuYa',
1051
+ description: 'Motion sensor',
1052
+ fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ZM35HQ_attr, fzLocal.ZM35HQ_battery],
1053
+ toZigbee: [tz.ZM35HQ_attr],
1054
+ exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery(),
1055
+ exposes.enum('sensitivity', ea.ALL, ['low', 'medium', 'high']).withDescription('PIR sensor sensitivity'),
1056
+ exposes.enum('keep_time', ea.ALL, [30, 60, 120]).withDescription('PIR keep time in seconds'),
1057
+ ],
1058
+ configure: async (device, coordinatorEndpoint, logger) => {
1059
+ const endpoint = device.getEndpoint(1);
1060
+ await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
1061
+ },
1062
+ },
1047
1063
  {
1048
1064
  fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3000_mcxw5ehu'}],
1049
1065
  model: 'IH012-RT01',
@@ -1143,6 +1159,7 @@ module.exports = [
1143
1159
  {vendor: 'Earda', model: 'EDM-1ZBA-EU'},
1144
1160
  {vendor: 'Mercator Ikuü', model: 'SSWD01'},
1145
1161
  {vendor: 'Moes', model: 'ZS-USD'},
1162
+ {vendor: 'Moes', model: 'EDM-1ZBB-EU'},
1146
1163
  ],
1147
1164
  },
1148
1165
  {
@@ -1368,6 +1385,7 @@ module.exports = [
1368
1385
  {modelID: 'TS0502B', manufacturerName: '_TZ3210_ijsj2evj'},
1369
1386
  {modelID: 'TS0502B', manufacturerName: '_TZ3210_pgq2qvyv'},
1370
1387
  {modelID: 'TS0502B', manufacturerName: '_TZ3210_nvaik6gk'},
1388
+ {modelID: 'TS0502B', manufacturerName: '_TZB210_rkgngb5o'},
1371
1389
  {modelID: 'TS0502B', manufacturerName: '_TZ3000_armwcncd'},
1372
1390
  {modelID: 'TS0502B', manufacturerName: '_TZ3210_2p6wbry3'},
1373
1391
  {modelID: 'TS0502B', manufacturerName: '_TZB210_nfzrlz29'},
@@ -1913,6 +1931,7 @@ module.exports = [
1913
1931
  {modelID: 'TS0601', manufacturerName: '_TZE200_husqqvux'}, /* model: 'TSL-TRV-TV01ZG', vendor: 'Tesla Smart' */
1914
1932
  {modelID: 'TS0601', manufacturerName: '_TZE200_lllliz3p'}, /* model: 'TV02-Zigbee', vendor: 'TuYa' */
1915
1933
  {modelID: 'TS0601', manufacturerName: '_TZE200_mudxchsu'}, /* model: 'TV05-ZG curve', vendor: 'TuYa' */
1934
+ {modelID: 'TS0601', manufacturerName: '_TZE200_7yoranx2'}, /* model: 'TV01-ZB', vendor: 'Moes' */
1916
1935
  ],
1917
1936
  model: 'TV02-Zigbee',
1918
1937
  vendor: 'TuYa',
@@ -3173,7 +3192,7 @@ module.exports = [
3173
3192
  exposes: [e.temperature(), e.humidity(), e.battery()],
3174
3193
  },
3175
3194
  {
3176
- fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_3towulqd'}],
3195
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_3towulqd'}, {modelID: 'TS0601', manufacturerName: '_TZE200_1ibpyhdc'}],
3177
3196
  model: 'ZG-204ZL',
3178
3197
  vendor: 'TuYa',
3179
3198
  description: 'Luminance motion sensor',
package/lib/reporting.js CHANGED
@@ -86,6 +86,10 @@ module.exports = {
86
86
  const p = payload('currentLevel', 0, repInterval.HOUR, 1, overrides);
87
87
  await endpoint.configureReporting('genLevelCtrl', p);
88
88
  },
89
+ colorTemperature: async (endpoint, overrides) => {
90
+ const p = payload('colorTemperature', 0, repInterval.HOUR, 1, overrides);
91
+ await endpoint.configureReporting('lightingColorCtrl', p);
92
+ },
89
93
  occupancy: async (endpoint, overrides) => {
90
94
  const p = payload('occupancy', 0, repInterval.HOUR, 0, overrides);
91
95
  await endpoint.configureReporting('msOccupancySensing', p);
package/lib/tuya.js CHANGED
@@ -125,12 +125,12 @@ function convertRawToCycleTimer(value) {
125
125
  timernr = value[1];
126
126
  timeractive = value[2];
127
127
  if (value[3] > 0) {
128
- weekdays = (value[3] & 0x40 ? 'Mo' : '') +
129
- (value[3] & 0x20 ? 'Tu' : '') +
130
- (value[3] & 0x10 ? 'We' : '') +
131
- (value[3] & 0x08 ? 'Th' : '') +
132
- (value[3] & 0x04 ? 'Fr' : '') +
133
- (value[3] & 0x02 ? 'Sa' : '') +
128
+ weekdays = (value[3] & 0x40 ? 'Sa' : '') +
129
+ (value[3] & 0x20 ? 'Fr' : '') +
130
+ (value[3] & 0x10 ? 'Th' : '') +
131
+ (value[3] & 0x08 ? 'We' : '') +
132
+ (value[3] & 0x04 ? 'Tu' : '') +
133
+ (value[3] & 0x02 ? 'Mo' : '') +
134
134
  (value[3] & 0x01 ? 'Su' : '');
135
135
  } else {
136
136
  weekdays = 'once';
@@ -165,12 +165,12 @@ function convertRawToTimer(value) {
165
165
  starttime = String(parseInt(minsincemidnight / 60)).padStart(2, '0') + ':' + String(minsincemidnight % 60).padStart(2, '0');
166
166
  duration = value[4] * 256 + value[5];
167
167
  if (value[6] > 0) {
168
- weekdays = (value[6] & 0x40 ? 'Mo' : '') +
169
- (value[6] & 0x20 ? 'Tu' : '') +
170
- (value[6] & 0x10 ? 'We' : '') +
171
- (value[6] & 0x08 ? 'Th' : '') +
172
- (value[6] & 0x04 ? 'Fr' : '') +
173
- (value[6] & 0x02 ? 'Sa' : '') +
168
+ weekdays = (value[6] & 0x40 ? 'Sa' : '') +
169
+ (value[6] & 0x20 ? 'Fr' : '') +
170
+ (value[6] & 0x10 ? 'Th' : '') +
171
+ (value[6] & 0x08 ? 'We' : '') +
172
+ (value[6] & 0x04 ? 'Tu' : '') +
173
+ (value[6] & 0x02 ? 'Mo' : '') +
174
174
  (value[6] & 0x01 ? 'Su' : '');
175
175
  } else {
176
176
  weekdays = 'once';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.629",
3
+ "version": "14.0.631",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -38,7 +38,7 @@
38
38
  "buffer-crc32": "^0.2.13",
39
39
  "https-proxy-agent": "^5.0.1",
40
40
  "tar-stream": "^2.2.0",
41
- "zigbee-herdsman": "^0.14.55"
41
+ "zigbee-herdsman": "^0.14.59"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",