zigbee-herdsman-converters 14.0.411 → 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.
@@ -5059,27 +5059,28 @@ const converters = {
5059
5059
  }
5060
5060
  },
5061
5061
  },
5062
- legrand_device_mode: {
5062
+ legrand_cluster_fc01: {
5063
5063
  cluster: 'manuSpecificLegrandDevices',
5064
5064
  type: ['readResponse'],
5065
5065
  convert: (model, msg, publish, options, meta) => {
5066
5066
  const payload = {};
5067
- const option0 = msg.data['0'];
5068
- // Beware that mode depends on device type
5069
- // contactor
5070
- if (option0 === 0x0003) payload.device_mode = 'switch';
5071
- else if (option0 === 0x0004) payload.device_mode = 'auto';
5072
- // dimmer
5073
- else if (option0 === 0x0101) payload.device_mode = 'dimmer_on';
5074
- else if (option0 === 0x0100) payload.device_mode = 'dimmer_off';
5075
- // pilot wire
5076
- else if (option0 === 0x0002) payload.device_mode = 'pilot_on';
5077
- else if (option0 === 0x0001) payload.device_mode = 'pilot_off';
5078
- // unknown case
5079
- else {
5080
- meta.logger.warn(`device_mode ${option0} not recognized, please fix me`);
5081
- 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
+ }
5082
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';
5083
5084
  return payload;
5084
5085
  },
5085
5086
  },
@@ -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');
@@ -4523,6 +4523,10 @@ const converters = {
4523
4523
  const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
4524
4524
  const payload = {1: {value: enableLedIfOn, type: 16}};
4525
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);
4526
4530
  },
4527
4531
  },
4528
4532
  legrand_settingEnableLedIfOn: {
@@ -4534,15 +4538,10 @@ const converters = {
4534
4538
  const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
4535
4539
  const payload = {2: {value: enableLedIfOn, type: 16}};
4536
4540
  await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
4541
+ return {state: {'led_when_on': value}};
4537
4542
  },
4538
- },
4539
- legrand_settingEnableDimmer: {
4540
- key: ['dimmer_enabled'],
4541
- convertSet: async (entity, key, value, meta) => {
4542
- // enable the dimmer, requires a recent firmware on the device
4543
- const enableDimmer = value === 'ON' || (value === 'OFF' ? false : !!value);
4544
- const payload = {0: {value: enableDimmer ? 0x0101 : 0x0100, type: 9}};
4545
- await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
4543
+ convertGet: async (entity, key, meta) => {
4544
+ await entity.read('manuSpecificLegrandDevices', [0x0002], manufacturerOptions.legrand);
4546
4545
  },
4547
4546
  },
4548
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);
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
  ];
@@ -90,6 +90,15 @@ module.exports = [
90
90
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
91
91
  ota: ota.zigbeeOTA,
92
92
  },
93
+ {
94
+ zigbeeModel: ['915005996701'],
95
+ model: '915005996701',
96
+ vendor: 'Philips',
97
+ description: 'Hue white ambiance ceiling black Enrave M with Bluetooth',
98
+ meta: {turnsOffAtBrightness1: true},
99
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
100
+ ota: ota.zigbeeOTA,
101
+ },
93
102
  {
94
103
  zigbeeModel: ['929003054001'],
95
104
  model: '929003054001',
package/devices/xiaomi.js CHANGED
@@ -1473,7 +1473,7 @@ module.exports = [
1473
1473
  fromZigbee: [fz.on_off, fz.device_temperature, fz.aqara_opple, fz.ignore_metering, fz.ignore_electrical_measurement,
1474
1474
  fz.xiaomi_power],
1475
1475
  exposes: [e.switch(), e.energy(), e.power(), e.device_temperature(), e.power_outage_memory(), e.switch_type()],
1476
- toZigbee: [tz.xiaomi_switch_type, tz.on_off, tz.xiaomi_switch_power_outage_memory],
1476
+ toZigbee: [tz.xiaomi_switch_type, tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night],
1477
1477
  configure: async (device, coordinatorEndpoint, logger) => {
1478
1478
  const endpoint = device.getEndpoint(1);
1479
1479
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genDeviceTempCfg']);