zigbee-herdsman-converters 14.0.408 → 14.0.412

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.
@@ -616,6 +616,25 @@ const converters = {
616
616
  return result;
617
617
  },
618
618
  },
619
+ meter_identification: {
620
+ cluster: 'haMeterIdentification',
621
+ type: ['readResponse'],
622
+ convert: (model, msg, publish, options, meta) => {
623
+ const result = {};
624
+ const elements = [
625
+ /* 0x000A*/ 'softwareRevision',
626
+ /* 0x000D*/ 'availablePower',
627
+ /* 0x000E*/ 'powerThreshold',
628
+ ];
629
+ for (const at of elements) {
630
+ const atSnake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
631
+ if (msg.data[at]) {
632
+ result[atSnake] = msg.data[at];
633
+ }
634
+ }
635
+ return result;
636
+ },
637
+ },
619
638
  metering: {
620
639
  /**
621
640
  * When using this converter also add the following to the configure method of the device:
@@ -2395,6 +2414,26 @@ const converters = {
2395
2414
  }
2396
2415
  },
2397
2416
  },
2417
+ moes_switch: {
2418
+ cluster: 'manuSpecificTuya',
2419
+ type: ['commandDataResponse', 'commandDataReport'],
2420
+ convert: (model, msg, publish, options, meta) => {
2421
+ const dpValue = tuya.firstDpValue(msg, meta, 'moes_switch');
2422
+ const dp = dpValue.dp;
2423
+ const value = tuya.getDataValue(dpValue);
2424
+
2425
+ switch (dp) {
2426
+ case tuya.dataPoints.moesSwitchPowerOnBehavior:
2427
+ return {power_on_behavior: tuya.moesSwitch.powerOnBehavior[value]};
2428
+ case tuya.dataPoints.moesSwitchIndicateLight:
2429
+ return {indicate_light: tuya.moesSwitch.indicateLight[value]};
2430
+ default:
2431
+ meta.logger.warn(`fromZigbee:moes_switch: NOT RECOGNIZED DP #${
2432
+ dp} with data ${JSON.stringify(dpValue)}`);
2433
+ break;
2434
+ }
2435
+ },
2436
+ },
2398
2437
  eurotronic_thermostat: {
2399
2438
  cluster: 'hvacThermostat',
2400
2439
  type: ['attributeReport', 'readResponse'],
@@ -5020,27 +5059,28 @@ const converters = {
5020
5059
  }
5021
5060
  },
5022
5061
  },
5023
- legrand_device_mode: {
5062
+ legrand_cluster_fc01: {
5024
5063
  cluster: 'manuSpecificLegrandDevices',
5025
5064
  type: ['readResponse'],
5026
5065
  convert: (model, msg, publish, options, meta) => {
5027
5066
  const payload = {};
5028
- const option0 = msg.data['0'];
5029
- // Beware that mode depends on device type
5030
- // contactor
5031
- if (option0 === 0x0003) payload.device_mode = 'switch';
5032
- else if (option0 === 0x0004) payload.device_mode = 'auto';
5033
- // dimmer
5034
- else if (option0 === 0x0101) payload.device_mode = 'dimmer_on';
5035
- else if (option0 === 0x0100) payload.device_mode = 'dimmer_off';
5036
- // pilot wire
5037
- else if (option0 === 0x0002) payload.device_mode = 'pilot_on';
5038
- else if (option0 === 0x0001) payload.device_mode = 'pilot_off';
5039
- // unknown case
5040
- else {
5041
- meta.logger.warn(`device_mode ${option0} not recognized, please fix me`);
5042
- payload.device_mode = 'unknown';
5067
+
5068
+ if (msg.data.hasOwnProperty('0')) {
5069
+ const option0 = msg.data['0'];
5070
+
5071
+ if (option0 === 0x0001) payload.device_mode = 'pilot_off';
5072
+ else if (option0 === 0x0002) payload.device_mode = 'pilot_on';
5073
+ else if (option0 === 0x0003) payload.device_mode = 'switch';
5074
+ else if (option0 === 0x0004) payload.device_mode = 'auto';
5075
+ else if (option0 === 0x0100) payload.device_mode = 'dimmer_off';
5076
+ else if (option0 === 0x0101) payload.device_mode = 'dimmer_on';
5077
+ else {
5078
+ meta.logger.warn(`device_mode ${option0} not recognized, please fix me`);
5079
+ payload.device_mode = 'unknown';
5080
+ }
5043
5081
  }
5082
+ if (msg.data.hasOwnProperty('1')) payload.permanent_led = msg.data['1'] === 0x00 ? 'OFF' : 'ON';
5083
+ if (msg.data.hasOwnProperty('2')) payload.led_when_on = msg.data['2'] === 0x00 ? 'OFF' : 'ON';
5044
5084
  return payload;
5045
5085
  },
5046
5086
  },
@@ -5168,8 +5208,16 @@ const converters = {
5168
5208
  aqara_opple: {
5169
5209
  cluster: 'aqaraOpple',
5170
5210
  type: ['attributeReport', 'readResponse'],
5171
- options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
5172
- exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual')],
5211
+ options: (definition) => {
5212
+ const result = [];
5213
+ if (definition.exposes.find((e) => e.name === 'temperature')) {
5214
+ result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
5215
+ }
5216
+ if (definition.exposes.find((e) => e.name === 'illuminance')) {
5217
+ result.push(exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual'));
5218
+ }
5219
+ return result;
5220
+ },
5173
5221
  convert: (model, msg, publish, options, meta) => {
5174
5222
  const payload = {};
5175
5223
  if (msg.data.hasOwnProperty('247')) {
@@ -5315,8 +5363,9 @@ const converters = {
5315
5363
  payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
5316
5364
  5: 'left_leave', 6: 'approach', 7: 'away', 255: null}[value];
5317
5365
  }
5318
- } else if (index ===103) payload.monitoring_mode = value === 1 ? 'left_right' : 'undirected'; // RTCZCGQ11LM
5319
- else if (index === 105) {
5366
+ } else if (index === 103) {
5367
+ if (['RTCZCGQ11LM'].includes(model.model)) payload.monitoring_mode = value === 1 ? 'left_right' : 'undirected';
5368
+ } else if (index === 105) {
5320
5369
  if (['RTCGQ13LM'].includes(model.model)) {
5321
5370
  payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
5322
5371
  } else if (['RTCZCGQ11LM'].includes(model.model)) {
@@ -2211,7 +2211,7 @@ const converters = {
2211
2211
  key: ['led_disabled_night'],
2212
2212
  convertSet: async (entity, key, value, meta) => {
2213
2213
  if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
2214
- 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
2214
+ 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01'].includes(meta.mapped.model)) {
2215
2215
  await entity.write('aqaraOpple', {0x0203: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
2216
2216
  } else if (['ZNCZ11LM'].includes(meta.mapped.model)) {
2217
2217
  const payload = value ?
@@ -2226,7 +2226,7 @@ const converters = {
2226
2226
  },
2227
2227
  convertGet: async (entity, key, meta) => {
2228
2228
  if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
2229
- 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM'].includes(meta.mapped.model)) {
2229
+ 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01'].includes(meta.mapped.model)) {
2230
2230
  await entity.read('aqaraOpple', [0x0203], manufacturerOptions.xiaomi);
2231
2231
  } else {
2232
2232
  throw new Error('Not supported');
@@ -2417,12 +2417,6 @@ const converters = {
2417
2417
  await entity.read('genAnalogOutput', [0x0055]);
2418
2418
  },
2419
2419
  },
2420
- xiaomi_curtain_acn002_status: {
2421
- key: ['motor_state'],
2422
- convertGet: async (entity, key, meta) => {
2423
- await entity.read('genMultistateOutput', [0x0055]);
2424
- },
2425
- },
2426
2420
  ledvance_commands: {
2427
2421
  /* deprectated osram_*/
2428
2422
  key: ['set_transition', 'remember_state', 'osram_set_transition', 'osram_remember_state'],
@@ -3212,6 +3206,30 @@ const converters = {
3212
3206
  await entity.read('genOnOff', ['moesStartUpOnOff']);
3213
3207
  },
3214
3208
  },
3209
+ moes_switch: {
3210
+ key: ['power_on_behavior', 'indicate_light'],
3211
+ convertSet: async (entity, key, value, meta) => {
3212
+ switch (key) {
3213
+ case 'power_on_behavior':
3214
+ await tuya.sendDataPointEnum(
3215
+ entity,
3216
+ tuya.dataPoints.moesSwitchPowerOnBehavior,
3217
+ utils.getKey(tuya.moesSwitch.powerOnBehavior, value),
3218
+ );
3219
+ break;
3220
+ case 'indicate_light':
3221
+ await tuya.sendDataPointValue(
3222
+ entity,
3223
+ tuya.dataPoints.moesSwitchIndicateLight,
3224
+ utils.getKey(tuya.moesSwitch.indicateLight, value),
3225
+ );
3226
+ break;
3227
+ default:
3228
+ meta.logger.warn(`toZigbee.moes_switch: Unhandled Key ${key}`);
3229
+ break;
3230
+ }
3231
+ },
3232
+ },
3215
3233
  moes_thermostat_sensor: {
3216
3234
  key: ['sensor'],
3217
3235
  convertSet: async (entity, key, value, meta) => {
@@ -4505,6 +4523,10 @@ const converters = {
4505
4523
  const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
4506
4524
  const payload = {1: {value: enableLedIfOn, type: 16}};
4507
4525
  await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
4526
+ return {state: {'permanent_led': value}};
4527
+ },
4528
+ convertGet: async (entity, key, meta) => {
4529
+ await entity.read('manuSpecificLegrandDevices', [0x0001], manufacturerOptions.legrand);
4508
4530
  },
4509
4531
  },
4510
4532
  legrand_settingEnableLedIfOn: {
@@ -4516,15 +4538,10 @@ const converters = {
4516
4538
  const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
4517
4539
  const payload = {2: {value: enableLedIfOn, type: 16}};
4518
4540
  await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
4541
+ return {state: {'led_when_on': value}};
4519
4542
  },
4520
- },
4521
- legrand_settingEnableDimmer: {
4522
- key: ['dimmer_enabled'],
4523
- convertSet: async (entity, key, value, meta) => {
4524
- // enable the dimmer, requires a recent firmware on the device
4525
- const enableDimmer = value === 'ON' || (value === 'OFF' ? false : !!value);
4526
- const payload = {0: {value: enableDimmer ? 0x0101 : 0x0100, type: 9}};
4527
- await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
4543
+ convertGet: async (entity, key, meta) => {
4544
+ await entity.read('manuSpecificLegrandDevices', [0x0002], manufacturerOptions.legrand);
4528
4545
  },
4529
4546
  },
4530
4547
  legrand_deviceMode: {
@@ -12,12 +12,12 @@ module.exports = [
12
12
  model: 'K4003C/L4003C/N4003C/NT4003C',
13
13
  vendor: 'BTicino',
14
14
  description: 'Light switch with neutral',
15
- fromZigbee: [fz.identify, fz.on_off, fz.K4003C_binary_input],
15
+ fromZigbee: [fz.identify, fz.on_off, fz.K4003C_binary_input, fz.legrand_cluster_fc01],
16
16
  toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn, tz.legrand_identify],
17
17
  exposes: [
18
18
  e.switch(), e.action(['identify', 'on', 'off']),
19
- exposes.binary('permanent_led', ea.STATE_SET, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
20
- exposes.binary('led_when_on', ea.STATE_SET, 'ON', 'OFF').withDescription('Enables the LED when the light is on'),
19
+ exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
20
+ exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on'),
21
21
  ],
22
22
  configure: async (device, coordinatorEndpoint, logger) => {
23
23
  const endpoint = device.getEndpoint(1);
@@ -30,17 +30,17 @@ module.exports = [
30
30
  vendor: 'BTicino',
31
31
  description: 'Dimmer switch with neutral',
32
32
  extend: extend.light_onoff_brightness({noConfigure: true}),
33
- fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration],
33
+ fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
34
34
  toZigbee: [tz.light_onoff_brightness, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn,
35
- tz.legrand_settingEnableDimmer, tz.legrand_identify, tz.ballast_config],
35
+ tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
36
36
  exposes: [e.light_brightness(),
37
37
  exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
38
38
  .withDescription('Specifies the minimum brightness value'),
39
39
  exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
40
40
  .withDescription('Specifies the maximum brightness value'),
41
- exposes.binary('dimmer_enabled', ea.STATE_SET, 'ON', 'OFF').withDescription('Allow the device to change brightness'),
42
- exposes.binary('permanent_led', ea.STATE_SET, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
43
- exposes.binary('led_when_on', ea.STATE_SET, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
41
+ exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
42
+ exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
43
+ exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
44
44
  configure: async (device, coordinatorEndpoint, logger) => {
45
45
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
46
46
  const endpoint = device.getEndpoint(1);
@@ -76,10 +76,10 @@ module.exports = [
76
76
  description: 'DIN power consumption module (same as Legrand 412015)',
77
77
  vendor: 'BTicino',
78
78
  extend: extend.switch(),
79
- fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_device_mode, fz.ignore_basic_report, fz.ignore_genOta],
79
+ fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
80
80
  toZigbee: [tz.legrand_deviceMode, tz.on_off, tz.legrand_identify, tz.electrical_measurement_power],
81
81
  exposes: [exposes.switch().withState('state', true, 'On/off (works only if device is in "switch" mode)'),
82
- e.power().withAccess(ea.STATE_GET), exposes.enum( 'device_mode', ea.ALL, ['switch', 'auto'])
82
+ e.power().withAccess(ea.STATE_GET), exposes.enum('device_mode', ea.ALL, ['switch', 'auto'])
83
83
  .withDescription('switch: allow on/off, auto will use wired action via C1/C2 on contactor for example with HC/HP')],
84
84
  configure: async (device, coordinatorEndpoint, logger) => {
85
85
  const endpoint = device.getEndpoint(1);
@@ -62,7 +62,7 @@ const gledoptoExtend = {
62
62
  }),
63
63
  };
64
64
 
65
- const configureReadModelID = async (device, coordinatorEndpoint, logger) => {
65
+ const configureReadModelID = async (device) => {
66
66
  // https://github.com/Koenkk/zigbee-herdsman-converters/issues/3016#issuecomment-1027726604
67
67
  const endpoint = device.endpoints[0];
68
68
  await endpoint.read('genBasic', ['modelId']);
@@ -122,8 +122,11 @@ module.exports = [
122
122
  vendor: 'Gledopto',
123
123
  ota: ota.zigbeeOTA,
124
124
  description: 'Zigbee LED Controller WW/CW (pro)',
125
- extend: gledoptoExtend.light_onoff_brightness_colortemp(),
126
- configure: configureReadModelID,
125
+ extend: gledoptoExtend.light_onoff_brightness_colortemp({noConfigure: true}),
126
+ configure: async (device, coordinatorEndpoint, logger) => {
127
+ await extend.light_onoff_brightness_colortemp().configure(device, coordinatorEndpoint, logger);
128
+ await configureReadModelID(device);
129
+ },
127
130
  },
128
131
  {
129
132
  fingerprint: [
@@ -186,8 +189,11 @@ module.exports = [
186
189
  vendor: 'Gledopto',
187
190
  ota: ota.zigbeeOTA,
188
191
  description: 'Zigbee LED Controller RGBW (pro)',
189
- extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
190
- configure: configureReadModelID,
192
+ extend: gledoptoExtend.light_onoff_brightness_colortemp_color({noConfigure: true}),
193
+ configure: async (device, coordinatorEndpoint, logger) => {
194
+ await extend.light_onoff_brightness_colortemp_color().configure(device, coordinatorEndpoint, logger);
195
+ await configureReadModelID(device);
196
+ },
191
197
  },
192
198
  {
193
199
  fingerprint: [
@@ -245,8 +251,11 @@ module.exports = [
245
251
  vendor: 'Gledopto',
246
252
  ota: ota.zigbeeOTA,
247
253
  description: 'Zigbee LED Controller RGB (pro)',
248
- extend: gledoptoExtend.light_onoff_brightness_color(),
249
- configure: configureReadModelID,
254
+ extend: gledoptoExtend.light_onoff_brightness_color({noConfigure: true}),
255
+ configure: async (device, coordinatorEndpoint, logger) => {
256
+ await extend.light_onoff_brightness_color().configure(device, coordinatorEndpoint, logger);
257
+ await configureReadModelID(device);
258
+ },
250
259
  },
251
260
  {
252
261
  zigbeeModel: ['GL-C-008P'],
@@ -254,9 +263,12 @@ module.exports = [
254
263
  vendor: 'Gledopto',
255
264
  ota: ota.zigbeeOTA,
256
265
  description: 'Zigbee LED Controller RGB+CCT (pro)',
257
- extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
266
+ extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495], noConfigure: true}),
258
267
  meta: {disableDefaultResponse: true},
259
- configure: configureReadModelID,
268
+ configure: async (device, coordinatorEndpoint, logger) => {
269
+ await extend.light_onoff_brightness_colortemp_color().configure(device, coordinatorEndpoint, logger);
270
+ await configureReadModelID(device);
271
+ },
260
272
  },
261
273
  {
262
274
  zigbeeModel: ['GL-C-009'],
@@ -277,8 +289,11 @@ module.exports = [
277
289
  vendor: 'Gledopto',
278
290
  ota: ota.zigbeeOTA,
279
291
  description: 'Zigbee LED Controller W (pro)',
280
- extend: gledoptoExtend.light_onoff_brightness(),
281
- configure: configureReadModelID,
292
+ extend: gledoptoExtend.light_onoff_brightness({noConfigure: true}),
293
+ configure: async (device, coordinatorEndpoint, logger) => {
294
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
295
+ await configureReadModelID(device);
296
+ },
282
297
  },
283
298
  {
284
299
  zigbeeModel: ['GL-C-009S'],
package/devices/jasco.js CHANGED
@@ -1,8 +1,10 @@
1
+ const fz = require('../converters/fromZigbee');
1
2
  const reporting = require('../lib/reporting');
2
3
  const extend = require('../lib/extend');
3
4
  const exposes = require('../lib/exposes');
4
5
  const e = exposes.presets;
5
6
 
7
+
6
8
  module.exports = [
7
9
  {
8
10
  zigbeeModel: ['35938'],
@@ -32,4 +34,20 @@ module.exports = [
32
34
  await reporting.instantaneousDemand(endpoint);
33
35
  },
34
36
  },
37
+ {
38
+ zigbeeModel: ['43095'],
39
+ model: '43095',
40
+ vendor: 'Jasco Products',
41
+ description: 'Zigbee smart plug-in switch with energy metering',
42
+ fromZigbee: [fz.command_on_state, fz.command_off_state, fz.metering],
43
+ extend: extend.switch(),
44
+ exposes: [e.switch(), e.power(), e.energy()],
45
+ configure: async (device, coordinatorEndpoint, logger) => {
46
+ const endpoint1 = device.getEndpoint(1);
47
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['genOnOff', 'seMetering']);
48
+ await reporting.onOff(endpoint1);
49
+ await reporting.instantaneousDemand(endpoint1);
50
+ await reporting.readMeteringMultiplierDivisor(endpoint1);
51
+ },
52
+ },
35
53
  ];
@@ -36,10 +36,10 @@ module.exports = [
36
36
  description: 'Legrand (or Bticino) DIN contactor module',
37
37
  vendor: 'Legrand',
38
38
  extend: extend.switch(),
39
- fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_device_mode, fz.ignore_basic_report, fz.ignore_genOta],
39
+ fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
40
40
  toZigbee: [tz.legrand_deviceMode, tz.on_off, tz.legrand_identify, tz.electrical_measurement_power],
41
41
  exposes: [exposes.switch().withState('state', true, 'On/off (works only if device is in "switch" mode)'),
42
- e.power().withAccess(ea.STATE_GET), exposes.enum( 'device_mode', ea.ALL, ['switch', 'auto'])
42
+ e.power().withAccess(ea.STATE_GET), exposes.enum('device_mode', ea.ALL, ['switch', 'auto'])
43
43
  .withDescription('switch: allow on/off, auto will use wired action via C1/C2 on contactor for example with HC/HP')],
44
44
  configure: async (device, coordinatorEndpoint, logger) => {
45
45
  const endpoint = device.getEndpoint(1);
@@ -56,10 +56,10 @@ module.exports = [
56
56
  description: 'Legrand (or Bticino) DIN smart relay for light control (note: Legrand 412170 may be similar to Bticino FC80RC)',
57
57
  vendor: 'Legrand',
58
58
  extend: extend.switch(),
59
- fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_device_mode, fz.ignore_basic_report, fz.ignore_genOta],
59
+ fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
60
60
  toZigbee: [tz.legrand_deviceMode, tz.on_off, tz.legrand_identify, tz.electrical_measurement_power],
61
61
  exposes: [exposes.switch().withState('state', true, 'On/off (works only if device is in "switch" mode)'),
62
- e.power().withAccess(ea.STATE_GET), exposes.enum( 'device_mode', ea.ALL, ['switch', 'auto'])
62
+ e.power().withAccess(ea.STATE_GET), exposes.enum('device_mode', ea.ALL, ['switch', 'auto'])
63
63
  .withDescription('switch: allow on/off, auto will use wired action via C1/C2 on teleruptor with buttons')],
64
64
  configure: async (device, coordinatorEndpoint, logger) => {
65
65
  const endpoint = device.getEndpoint(1);
@@ -171,20 +171,19 @@ module.exports = [
171
171
  zigbeeModel: [' Dimmer switch w/o neutral\u0000\u0000\u0000\u0000\u0000'],
172
172
  model: '067771',
173
173
  vendor: 'Legrand',
174
- // led blink RED when battery is low
175
174
  description: 'Wired switch without neutral',
176
175
  extend: extend.light_onoff_brightness({noConfigure: true}),
177
- fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration],
176
+ fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
178
177
  toZigbee: [tz.light_onoff_brightness, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn,
179
- tz.legrand_settingEnableDimmer, tz.legrand_identify, tz.ballast_config],
178
+ tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
180
179
  exposes: [e.light_brightness(),
181
180
  exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
182
181
  .withDescription('Specifies the minimum brightness value'),
183
182
  exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
184
183
  .withDescription('Specifies the maximum brightness value'),
185
- exposes.binary('dimmer_enabled', ea.STATE_SET, 'ON', 'OFF').withDescription('Allow the device to change brightness'),
186
- exposes.binary('permanent_led', ea.STATE_SET, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
187
- exposes.binary('led_when_on', ea.STATE_SET, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
184
+ exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
185
+ exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
186
+ exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
188
187
  configure: async (device, coordinatorEndpoint, logger) => {
189
188
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
190
189
  const endpoint = device.getEndpoint(1);
@@ -306,9 +305,9 @@ module.exports = [
306
305
  model: '064882',
307
306
  vendor: 'Legrand',
308
307
  description: 'Cable outlet with pilot wire and consumption measurement',
309
- fromZigbee: [fz.legrand_device_mode, fz.legrand_cable_outlet_mode, fz.on_off, fz.electrical_measurement],
308
+ fromZigbee: [fz.legrand_cluster_fc01, fz.legrand_cable_outlet_mode, fz.on_off, fz.electrical_measurement],
310
309
  toZigbee: [tz.legrand_deviceMode, tz.legrand_cableOutletMode, tz.on_off, tz.electrical_measurement_power],
311
- exposes: [exposes.enum('device_mode', ea.ALL, ['pilot_off', 'pilot_on']),
310
+ exposes: [exposes.binary('device_mode', ea.ALL, 'pilot_on', 'pilot_off'),
312
311
  exposes.enum('cable_outlet_mode', ea.ALL, ['comfort', 'comfort-1', 'comfort-2', 'eco', 'frost_protection', 'off']),
313
312
  exposes.switch().withState('state', true, 'Works only when the pilot wire is deactivated'),
314
313
  e.power().withAccess(ea.STATE_GET)],
@@ -320,4 +319,26 @@ module.exports = [
320
319
  await reporting.activePower(endpoint);
321
320
  },
322
321
  },
322
+ {
323
+ zigbeeModel: [' NLIS - Double light switch\u0000\u0000\u0000\u0000'],
324
+ model: '067772',
325
+ vendor: 'Legrand',
326
+ description: 'Double wired switch with neutral',
327
+ fromZigbee: [fz.on_off, fz.legrand_cluster_fc01],
328
+ toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn],
329
+ exposes: [e.switch().withEndpoint('left'),
330
+ e.switch().withEndpoint('right'),
331
+ exposes.binary('permanent_led', ea.ALL, 'ON', 'OFF').withDescription('Enable or disable the permanent blue LED'),
332
+ exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
333
+ meta: {multiEndpoint: true},
334
+ configure: async (device, coordinatorEndpoint, logger) => {
335
+ const endpointLeft = device.getEndpoint(1);
336
+ await reporting.bind(endpointLeft, coordinatorEndpoint, ['genOnOff']);
337
+ const endpointRight = device.getEndpoint(2);
338
+ await reporting.bind(endpointRight, coordinatorEndpoint, ['genOnOff']);
339
+ },
340
+ endpoint: (device) => {
341
+ return {left: 1, right: 2};
342
+ },
343
+ },
323
344
  ];