zigbee-herdsman-converters 14.0.627 → 14.0.629

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.
@@ -8155,9 +8155,12 @@ const converters = {
8155
8155
  convert: (model, msg, publish, options, meta) => {
8156
8156
  const lookup = {'0': 'idle', '1': 'in', '2': 'out'};
8157
8157
  const value = precisionRound(parseFloat(msg.data['presentValue']), 1);
8158
+ const people = precisionRound(msg.data.presentValue, 0);
8158
8159
  let result = null;
8159
- result = {people: precisionRound(msg.data.presentValue, 0), status: lookup[value*10%10]};
8160
- return result;
8160
+ if (value <= 80) {
8161
+ result = {people: people, status: lookup[value*10%10]};
8162
+ return result;
8163
+ }
8161
8164
  },
8162
8165
  },
8163
8166
  sihas_action: {
@@ -582,7 +582,8 @@ const converters = {
582
582
  'ballast_physical_minimum_level',
583
583
  'ballast_physical_maximum_level',
584
584
  'ballast_minimum_level',
585
- 'ballast_maximum_level'],
585
+ 'ballast_maximum_level',
586
+ 'ballast_power_on_level'],
586
587
  // zcl attribute names are camel case, but we want to use snake case in the outside communication
587
588
  convertSet: async (entity, key, value, meta) => {
588
589
  if (key === 'ballast_config') {
@@ -599,6 +600,9 @@ const converters = {
599
600
  if (key === 'ballast_maximum_level') {
600
601
  await entity.write('lightingBallastCfg', {'maxLevel': value});
601
602
  }
603
+ if (key === 'ballast_power_on_level') {
604
+ await entity.write('lightingBallastCfg', {'powerOnLevel': value});
605
+ }
602
606
  converters.ballast_config.convertGet(entity, key, meta);
603
607
  },
604
608
  convertGet: async (entity, key, meta) => {
package/devices/ctm.js CHANGED
@@ -281,15 +281,6 @@ const fzLocal = {
281
281
 
282
282
 
283
283
  const tzLocal = {
284
- ballast_power_on_level: {
285
- key: ['ballast_power_on_level'],
286
- convertSet: async (entity, key, value, meta) => {
287
- await entity.write('lightingBallastCfg', {'powerOnLevel': value});
288
- },
289
- convertGet: async (entity, key, meta) => {
290
- await entity.read('lightingBallastCfg', ['powerOnLevel']);
291
- },
292
- },
293
284
  ctm_device_mode: {
294
285
  key: ['device_mode'],
295
286
  convertGet: async (entity, key, meta) => {
@@ -577,7 +568,7 @@ module.exports = [
577
568
  vendor: 'CTM Lyng',
578
569
  description: 'mTouch Dim OP, touch dimmer',
579
570
  fromZigbee: [fz.on_off, fz.brightness, fz.lighting_ballast_configuration],
580
- toZigbee: [tz.on_off, tz.light_onoff_brightness, tz.light_brightness_move, tz.ballast_config, tzLocal.ballast_power_on_level],
571
+ toZigbee: [tz.on_off, tz.light_onoff_brightness, tz.light_brightness_move, tz.ballast_config],
581
572
  meta: {disableDefaultResponse: true},
582
573
  configure: async (device, coordinatorEndpoint, logger) => {
583
574
  const endpoint = device.getEndpoint(1);
@@ -13,7 +13,7 @@ module.exports = [
13
13
  extend: extend.light_onoff_brightness(),
14
14
  },
15
15
  {
16
- zigbeeModel: ['ZG50CC-CCT-DRIVER'],
16
+ zigbeeModel: ['ZG50CC-CCT-DRIVER', 'HK-CCT'],
17
17
  model: 'ZG50CC-CCT-DRIVER',
18
18
  vendor: 'Envilar',
19
19
  description: 'Zigbee CCT LED driver',
package/devices/heiman.js CHANGED
@@ -444,6 +444,21 @@ module.exports = [
444
444
  await reporting.batteryPercentageRemaining(endpoint);
445
445
  },
446
446
  },
447
+ {
448
+ zigbeeModel: ['TempDimmerSw-EM-3.0'],
449
+ model: 'HS2WDSC-E',
450
+ vendor: 'HEIMAN',
451
+ description: 'Remote dimmer and temperature control',
452
+ fromZigbee: [fz.battery, fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.command_move_to_color,
453
+ fz.command_move_to_color_temp],
454
+ exposes: [e.battery(), e.action(['on', 'off', 'move', 'stop', 'color_move', 'color_temperature_move'])],
455
+ toZigbee: [],
456
+ configure: async (device, coordinatorEndpoint, logger) => {
457
+ const endpoint = device.getEndpoint(1);
458
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'genOnOff', 'genLevelCtrl', 'lightingColorCtrl']);
459
+ await reporting.batteryPercentageRemaining(endpoint, {min: constants.repInterval.MINUTES_5, max: constants.repInterval.HOUR});
460
+ },
461
+ },
447
462
  {
448
463
  fingerprint: [{modelID: 'ColorDimmerSw-EM-3.0', manufacturerName: 'HEIMAN'}],
449
464
  model: 'HS2WDSR-E',
@@ -667,6 +682,13 @@ module.exports = [
667
682
  exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('center'), e.switch().withEndpoint('right'),
668
683
  e.device_temperature()],
669
684
  },
685
+ {
686
+ zigbeeModel: ['TemperLight'],
687
+ model: 'HS2WDS',
688
+ vendor: 'HEIMAN',
689
+ description: 'LED 9W CCT E27',
690
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
691
+ },
670
692
  {
671
693
  zigbeeModel: ['CurtainMo-EF-3.0', 'CurtainMo-EF'],
672
694
  model: 'HS2CM-N-DC',
@@ -1,5 +1,7 @@
1
1
  const reporting = require('../lib/reporting');
2
2
  const extend = require('../lib/extend');
3
+ const exposes = require('../lib/exposes');
4
+ const e = exposes.presets;
3
5
 
4
6
  module.exports = [
5
7
  {
@@ -8,11 +10,20 @@ module.exports = [
8
10
  vendor: 'HZC Electric',
9
11
  description: 'Zigbee dual dimmer',
10
12
  extend: extend.light_onoff_brightness({noConfigure: true}),
13
+ exposes: [e.light_brightness().withEndpoint('l1'), e.light_brightness().withEndpoint('l2')],
11
14
  configure: async (device, coordinatorEndpoint, logger) => {
12
15
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
13
- const endpoint = device.getEndpoint(1);
14
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
15
- await reporting.onOff(endpoint);
16
+ const endpoint1 = device.getEndpoint(1);
17
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
18
+ await reporting.onOff(endpoint1);
19
+
20
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
21
+ const endpoint2 = device.getEndpoint(2);
22
+ await reporting.bind(endpoint2, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
23
+ await reporting.onOff(endpoint2);
24
+ },
25
+ endpoint: () => {
26
+ return {l1: 1, l2: 2};
16
27
  },
17
28
  },
18
29
  ];
@@ -3,6 +3,8 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
3
3
  const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
5
  const extend = require('../lib/extend');
6
+ const e = exposes.presets;
7
+ const ea = exposes.access;
6
8
 
7
9
  module.exports = [
8
10
  {
@@ -83,4 +85,31 @@ module.exports = [
83
85
  .withSetpoint('occupied_cooling_setpoint', 10, 30, 1)
84
86
  .withLocalTemperatureCalibration(-30, 30, 0.1).withPiHeatingDemand()],
85
87
  },
88
+ {
89
+ // Reference from a similar switch: https://gist.github.com/nebhead/dc5a0a827ec14eef6196ded4be6e2dd0
90
+ zigbeeModel: ['ZS057'],
91
+ model: 'ZS057-D0Z',
92
+ vendor: 'Leviton',
93
+ description: 'Wall switch, 0-10V dimmer, 120-277V, Lumina™ RF',
94
+ extend: extend.light_onoff_brightness({disableEffect: true, noConfigure: true}),
95
+ fromZigbee: [fz.brightness, fz.identify, fz.lighting_ballast_configuration, fz.level_config],
96
+ toZigbee: [tz.light_onoff_brightness, tz.ballast_config, tz.level_config],
97
+ exposes: [e.light_brightness(),
98
+ exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
99
+ .withDescription('Specifies the minimum brightness value'),
100
+ exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
101
+ .withDescription('Specifies the maximum brightness value'),
102
+ exposes.numeric('ballast_power_on_level', ea.ALL).withValueMin(1).withValueMax(254)
103
+ .withDescription('Specifies the initialisation light level. Can not be set lower than "ballast_minimum_level"'),
104
+ exposes.numeric('ballast_physical_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
105
+ .withDescription('Specifies the minimum light output the ballast can achieve.'),
106
+ exposes.numeric('ballast_physical_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
107
+ .withDescription('Specifies the maximum light output the ballast can achieve.')],
108
+ configure: async (device, coordinatorEndpoint, logger) => {
109
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
110
+ const endpoint = device.getEndpoint(1);
111
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'lightingBallastCfg']);
112
+ await reporting.onOff(endpoint);
113
+ },
114
+ },
86
115
  ];
@@ -609,6 +609,13 @@ module.exports = [
609
609
  description: 'Hue Calla outdoor',
610
610
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
611
611
  },
612
+ {
613
+ zigbeeModel: ['1741930V7'],
614
+ model: '1741930V7',
615
+ vendor: 'Philips',
616
+ description: 'Hue Calla outdoor',
617
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
618
+ },
612
619
  {
613
620
  zigbeeModel: ['1744130P7'],
614
621
  model: '1744130P7',
@@ -1815,7 +1822,9 @@ module.exports = [
1815
1822
  vendor: 'Philips',
1816
1823
  description: 'Hue wall switch module',
1817
1824
  fromZigbee: [fz.battery, fz.hue_wall_switch_device_mode, fz.hue_wall_switch],
1818
- exposes: [e.battery(), e.action(['left_press', 'left_press_release', 'right_press', 'right_press_release']),
1825
+ exposes: [
1826
+ e.battery(), e.action(['left_press', 'left_press_release', 'right_press', 'right_press_release',
1827
+ 'left_hold', 'left_hold_release', 'right_hold', 'right_hold_release']),
1819
1828
  exposes.enum('device_mode', ea.ALL, ['single_rocker', 'single_push_button', 'dual_rocker', 'dual_push_button'])],
1820
1829
  toZigbee: [tz.hue_wall_switch_device_mode],
1821
1830
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -2303,6 +2312,13 @@ module.exports = [
2303
2312
  description: 'Hue white filament Edison ST72 E27 LED',
2304
2313
  extend: hueExtend.light_onoff_brightness(),
2305
2314
  },
2315
+ {
2316
+ zigbeeModel: ['LWV004'],
2317
+ model: '8719514279193',
2318
+ vendor: 'Philips',
2319
+ description: 'Hue white filament Edison ST72 B22 LED',
2320
+ extend: hueExtend.light_onoff_brightness(),
2321
+ },
2306
2322
  {
2307
2323
  zigbeeModel: ['HML004'],
2308
2324
  model: '3115331PH',
@@ -2776,4 +2792,11 @@ module.exports = [
2776
2792
  description: 'Hue White ambiance Runner spot white (1 spot)',
2777
2793
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2778
2794
  },
2795
+ {
2796
+ zigbeeModel: ['915005998101'],
2797
+ model: '915005998101',
2798
+ vendor: 'Philips',
2799
+ description: 'Hue white ambiance ceiling black Enrave',
2800
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2801
+ },
2779
2802
  ];
@@ -19,6 +19,7 @@ module.exports = [
19
19
  {modelID: 'TS0601', manufacturerName: '_TZE200_zuhszj9s'},
20
20
  {modelID: 'TS0601', manufacturerName: '_TZE200_9gvruqf5'},
21
21
  {modelID: 'TS0601', manufacturerName: '_TZE200_zr9c0day'},
22
+ {modelID: 'TS0601', manufacturerName: '_TZE200_0dvm9mva'},
22
23
  ],
23
24
  model: 'SEA801-Zigbee/SEA802-Zigbee',
24
25
  vendor: 'Saswell',
package/devices/siglis.js CHANGED
@@ -1,44 +1,41 @@
1
+ /* eslint-disable linebreak-style */
1
2
  const fz = require('../converters/fromZigbee');
2
3
  const tz = require('../converters/toZigbee');
3
4
  const exposes = require('../lib/exposes');
4
5
  const reporting = require('../lib/reporting');
5
6
  const e = exposes.presets;
7
+ const ea = exposes.access;
6
8
 
7
9
 
8
- const siglisManufacturerCode = 0x129C;
9
10
  const zigfredEndpoint = 5;
10
11
 
11
- const zifgredFromZigbee = {
12
- cluster: 'manuSpecificSiglisZigfred',
13
- type: ['attributeReport'],
14
- convert: (model, msg, publish, options, meta) => {
15
- const buttonEvent = msg.data['buttonEvent'];
16
-
17
- if (buttonEvent != null) {
18
- const buttonLookup = {
19
- 0: 'button_1',
20
- 1: 'button_2',
21
- 2: 'button_3',
22
- 3: 'button_4',
23
- };
12
+ const buttonLookup = {
13
+ 0: 'button_1',
14
+ 1: 'button_2',
15
+ 2: 'button_3',
16
+ 3: 'button_4',
17
+ };
24
18
 
25
- const actionLookup = {
26
- 0: 'release',
27
- 1: 'single',
28
- 2: 'double',
29
- 3: 'hold',
30
- };
19
+ const actionLookup = {
20
+ 0: 'release',
21
+ 1: 'single',
22
+ 2: 'double',
23
+ 3: 'hold',
24
+ };
31
25
 
32
- const button = buttonEvent & 0xff;
33
- const state = (buttonEvent >> 8) & 0xff;
26
+ const zifgredFromZigbeeButtonEvent = {
27
+ cluster: 'manuSpecificSiglisZigfred',
28
+ type: ['commandSiglisZigfredButtonEvent'],
29
+ convert: (model, msg, publish, options, meta) => {
30
+ const button = msg.data.button;
31
+ const type = msg.data.type;
34
32
 
35
- const buttonName = buttonLookup[button];
36
- const stateName = actionLookup[state];
33
+ const buttonName = buttonLookup[button];
34
+ const typeName = actionLookup[type];
37
35
 
38
- if (buttonName && stateName) {
39
- const action = `${buttonName}_${stateName}`;
40
- return {action};
41
- }
36
+ if (buttonName && typeName) {
37
+ const action = `${buttonName}_${typeName}`;
38
+ return {action};
42
39
  }
43
40
  },
44
41
  };
@@ -63,6 +60,37 @@ const coverAndLightToZigbee = {
63
60
  },
64
61
  };
65
62
 
63
+ const buttonEventExposes = e.action([
64
+ 'button_1_single', 'button_1_double', 'button_1_hold', 'button_1_release',
65
+ 'button_2_single', 'button_2_double', 'button_2_hold', 'button_2_release',
66
+ 'button_3_single', 'button_3_double', 'button_3_hold', 'button_3_release',
67
+ 'button_4_single', 'button_4_double', 'button_4_hold', 'button_4_release',
68
+ ]);
69
+
70
+ function checkOption(device, options, key) {
71
+ if (options.hasOwnProperty(key)) {
72
+ if (options[key] === 'true') {
73
+ return true;
74
+ } else if (options[key] === 'false') {
75
+ return false;
76
+ }
77
+ }
78
+
79
+ return checkMetaOption(device, key);
80
+ }
81
+
82
+ function checkMetaOption(device, key) {
83
+ const enabled = device.meta[key];
84
+ if (enabled === undefined) {
85
+ return false;
86
+ } else {
87
+ return !!enabled;
88
+ }
89
+ }
90
+
91
+ function setMetaOption(device, key, enabled) {
92
+ device.meta[key] = enabled;
93
+ }
66
94
 
67
95
  module.exports = [
68
96
  {
@@ -70,15 +98,44 @@ module.exports = [
70
98
  model: 'ZFU-1D-CH',
71
99
  vendor: 'Siglis',
72
100
  description: 'zigfred uno smart in-wall switch',
73
- exposes: [e.light_brightness_colorxy().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.light_brightness().withEndpoint('l3'),
74
- e.action([
75
- 'button_1_single', 'button_1_double', 'button_1_hold', 'button_1_release',
76
- 'button_2_single', 'button_2_double', 'button_2_hold', 'button_2_release',
77
- 'button_3_single', 'button_3_double', 'button_3_hold', 'button_3_release',
78
- 'button_4_single', 'button_4_double', 'button_4_hold', 'button_4_release',
79
- ])],
101
+ options: [
102
+ exposes.enum(`front_surface_enabled`, ea.SET, ['auto', 'true', 'false'])
103
+ .withDescription('Front Surface LED enabled'),
104
+ exposes.enum(`relay_enabled`, ea.SET, ['auto', 'true', 'false'])
105
+ .withDescription('Relay enabled'),
106
+ exposes.enum(`dimmer_enabled`, ea.SET, ['auto', 'true', 'false'])
107
+ .withDescription('Dimmer enabled'),
108
+ exposes.enum(`dimmer_dimming_enabled`, ea.SET, ['auto', 'true', 'false'])
109
+ .withDescription('Dimmer dimmable'),
110
+ ],
111
+ exposes: (device, options) => {
112
+ const expose = [];
113
+
114
+ expose.push(buttonEventExposes);
115
+ expose.push(e.linkquality());
116
+
117
+ if (device != null && options != null) {
118
+ if (checkOption(device, options, 'front_surface_enabled')) {
119
+ expose.push(e.light_brightness_colorxy().withEndpoint('l1'));
120
+ }
121
+
122
+ if (checkOption(device, options, 'relay_enabled')) {
123
+ expose.push(e.switch().withEndpoint('l2'));
124
+ }
125
+
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
+ }
132
+ }
133
+ }
134
+
135
+ return expose;
136
+ },
80
137
  fromZigbee: [
81
- zifgredFromZigbee,
138
+ zifgredFromZigbeeButtonEvent,
82
139
  fz.color_colortemp,
83
140
  fz.on_off,
84
141
  fz.brightness,
@@ -108,31 +165,38 @@ module.exports = [
108
165
  'l3': 7,
109
166
  };
110
167
  },
111
- configure: async (device, coordinatorEndpoint, logger) => {
112
- const controlEp = device.getEndpoint(zigfredEndpoint);
113
- const relayEp = device.getEndpoint(6);
114
- const dimmerEp = device.getEndpoint(7);
115
-
116
- // Bind Control EP (LED)
117
- await reporting.bind(controlEp, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'manuSpecificSiglisZigfred']);
118
- await reporting.onOff(controlEp);
119
- await reporting.brightness(controlEp);
120
- const payload = [{
121
- attribute: 'buttonEvent',
122
- minimumReportInterval: 0,
123
- maximumReportInterval: 0,
124
- reportableChange: 0,
125
- }];
126
- await controlEp.configureReporting('manuSpecificSiglisZigfred', payload, {manufacturerCode: siglisManufacturerCode});
127
-
128
- // Bind Relay EP
129
- await reporting.bind(relayEp, coordinatorEndpoint, ['genOnOff']);
130
- await reporting.onOff(relayEp);
131
-
132
- // Bind Dimmer EP
133
- await reporting.bind(dimmerEp, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
134
- await reporting.onOff(dimmerEp);
135
- await reporting.brightness(dimmerEp);
168
+ configure: async (device, coordinatorEndpoint, logger, options) => {
169
+ if (device != null) {
170
+ const controlEp = device.getEndpoint(zigfredEndpoint);
171
+ const relayEp = device.getEndpoint(6);
172
+ const dimmerEp = device.getEndpoint(7);
173
+
174
+ // Bind Control EP (LED)
175
+ setMetaOption(device, 'front_surface_enabled', (await controlEp.read('genBasic', ['deviceEnabled'])).deviceEnabled);
176
+ if (checkMetaOption(device, 'front_surface_enabled')) {
177
+ await reporting.bind(controlEp, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'manuSpecificSiglisZigfred']);
178
+ await reporting.onOff(controlEp);
179
+ await reporting.brightness(controlEp);
180
+ }
181
+
182
+ // Bind Relay EP
183
+ setMetaOption(device, 'relay_enabled', (await relayEp.read('genBasic', ['deviceEnabled'])).deviceEnabled);
184
+ if (checkMetaOption(device, 'relay_enabled')) {
185
+ await reporting.bind(relayEp, coordinatorEndpoint, ['genOnOff']);
186
+ await reporting.onOff(relayEp);
187
+ }
188
+
189
+ // Bind Dimmer EP
190
+ setMetaOption(device, 'dimmer_enabled', (await dimmerEp.read('genBasic', ['deviceEnabled'])).deviceEnabled);
191
+ if (checkMetaOption(device, 'dimmer_enabled')) {
192
+ await reporting.bind(dimmerEp, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
193
+ await reporting.onOff(dimmerEp);
194
+ await reporting.brightness(dimmerEp);
195
+ }
196
+ setMetaOption(device, 'dimmer_dimming_enabled', true);
197
+
198
+ device.save();
199
+ }
136
200
  },
137
201
  },
138
202
  {
@@ -140,24 +204,106 @@ module.exports = [
140
204
  model: 'ZFP-1A-CH',
141
205
  vendor: 'Siglis',
142
206
  description: 'zigfred plus smart in-wall switch',
143
- exposes: [
144
- e.light_brightness_colorxy().withEndpoint('l1'),
145
- e.light_brightness().withEndpoint('l2'),
146
- e.light_brightness().withEndpoint('l3'),
147
- e.light_brightness().withEndpoint('l4'),
148
- e.light_brightness().withEndpoint('l5'),
149
- exposes.cover().setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
150
- .withPosition().withTilt().withEndpoint('l6'),
151
- exposes.cover().setAccess('state', exposes.access.STATE_SET | exposes.access.STATE_GET)
152
- .withPosition().withTilt().withEndpoint('l7'),
153
- e.action([
154
- 'button_1_single', 'button_1_double', 'button_1_hold', 'button_1_release',
155
- 'button_2_single', 'button_2_double', 'button_2_hold', 'button_2_release',
156
- 'button_3_single', 'button_3_double', 'button_3_hold', 'button_3_release',
157
- 'button_4_single', 'button_4_double', 'button_4_hold', 'button_4_release',
158
- ])],
207
+ options: [
208
+ exposes.enum(`front_surface_enabled`, ea.SET, ['auto', 'true', 'false'])
209
+ .withDescription('Front Surface LED enabled'),
210
+ exposes.enum(`dimmer_1_enabled`, ea.SET, ['auto', 'true', 'false'])
211
+ .withDescription('Dimmer 1 enabled'),
212
+ exposes.enum(`dimmer_1_dimming_enabled`, ea.SET, ['auto', 'true', 'false'])
213
+ .withDescription('Dimmer 1 dimmable'),
214
+ exposes.enum(`dimmer_2_enabled`, ea.SET, ['auto', 'true', 'false'])
215
+ .withDescription('Dimmer 2 enabled'),
216
+ exposes.enum(`dimmer_2_dimming_enabled`, ea.SET, ['auto', 'true', 'false'])
217
+ .withDescription('Dimmer 2 dimmable'),
218
+ exposes.enum(`dimmer_3_enabled`, ea.SET, ['auto', 'true', 'false'])
219
+ .withDescription('Dimmer 3 enabled'),
220
+ exposes.enum(`dimmer_3_dimming_enabled`, ea.SET, ['auto', 'true', 'false'])
221
+ .withDescription('Dimmer 3 dimmable'),
222
+ exposes.enum(`dimmer_4_enabled`, ea.SET, ['auto', 'true', 'false'])
223
+ .withDescription('Dimmer 4 enabled'),
224
+ exposes.enum(`dimmer_4_dimming_enabled`, ea.SET, ['auto', 'true', 'false'])
225
+ .withDescription('Dimmer 4 dimmable'),
226
+ exposes.enum(`cover_1_enabled`, ea.SET, ['auto', 'true', 'false'])
227
+ .withDescription('Cover 1 enabled'),
228
+ exposes.enum(`cover_1_tilt_enabled`, ea.SET, ['auto', 'true', 'false'])
229
+ .withDescription('Cover 1 tiltable'),
230
+ exposes.enum(`cover_2_enabled`, ea.SET, ['auto', 'true', 'false'])
231
+ .withDescription('Cover 2 enabled'),
232
+ exposes.enum(`cover_2_tilt_enabled`, ea.SET, ['auto', 'true', 'false'])
233
+ .withDescription('Cover 2 tiltable'),
234
+ ],
235
+ exposes: (device, options) => {
236
+ const expose = [];
237
+
238
+ expose.push(buttonEventExposes);
239
+ expose.push(e.linkquality());
240
+
241
+ if (device != null && options != null) {
242
+ if (checkOption(device, options, 'front_surface_enabled')) {
243
+ expose.push(e.light_brightness_colorxy().withEndpoint('l1'));
244
+ }
245
+
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
+ }
252
+ }
253
+
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
+ }
260
+ }
261
+
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
+ }
268
+ }
269
+
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
+ }
276
+ }
277
+
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
+ }
288
+ }
289
+
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
+ }
300
+ }
301
+ }
302
+
303
+ return expose;
304
+ },
159
305
  fromZigbee: [
160
- zifgredFromZigbee,
306
+ zifgredFromZigbeeButtonEvent,
161
307
  fz.color_colortemp,
162
308
  fz.on_off,
163
309
  fz.brightness,
@@ -196,55 +342,93 @@ module.exports = [
196
342
  'l7': 12,
197
343
  };
198
344
  },
199
- configure: async (device, coordinatorEndpoint, logger) => {
200
- // Bind Control EP (LED)
201
- const controlEp = device.getEndpoint(zigfredEndpoint);
202
- await reporting.bind(controlEp, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'manuSpecificSiglisZigfred']);
203
- await reporting.onOff(controlEp);
204
- await reporting.brightness(controlEp);
205
- const payload = [{
206
- attribute: 'buttonEvent',
207
- minimumReportInterval: 0,
208
- maximumReportInterval: 0,
209
- reportableChange: 0,
210
- }];
211
- await controlEp.configureReporting('manuSpecificSiglisZigfred', payload, {manufacturerCode: siglisManufacturerCode});
212
-
213
- // Bind Dimmer 1 EP
214
- const dimmer1Ep = device.getEndpoint(7);
215
- await reporting.bind(dimmer1Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
216
- await reporting.onOff(dimmer1Ep);
217
- await reporting.brightness(dimmer1Ep);
218
-
219
- // Bind Dimmer 2 EP
220
- const dimmer2Ep = device.getEndpoint(8);
221
- await reporting.bind(dimmer2Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
222
- await reporting.onOff(dimmer2Ep);
223
- await reporting.brightness(dimmer2Ep);
224
-
225
- // Bind Dimmer 3 EP
226
- const dimmer3Ep = device.getEndpoint(9);
227
- await reporting.bind(dimmer3Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
228
- await reporting.onOff(dimmer3Ep);
229
- await reporting.brightness(dimmer3Ep);
230
-
231
- // Bind Dimmer 4 EP
232
- const dimmer4Ep = device.getEndpoint(10);
233
- await reporting.bind(dimmer4Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
234
- await reporting.onOff(dimmer4Ep);
235
- await reporting.brightness(dimmer4Ep);
236
-
237
- // Bind Cover 1 EP
238
- const cover1Ep = device.getEndpoint(11);
239
- await reporting.bind(cover1Ep, coordinatorEndpoint, ['closuresWindowCovering']);
240
- await reporting.currentPositionLiftPercentage(cover1Ep);
241
- await reporting.currentPositionTiltPercentage(cover1Ep);
242
-
243
- // Bind Cover 2 EP
244
- const cover2Ep = device.getEndpoint(12);
245
- await reporting.bind(cover2Ep, coordinatorEndpoint, ['closuresWindowCovering']);
246
- await reporting.currentPositionLiftPercentage(cover2Ep);
247
- await reporting.currentPositionTiltPercentage(cover2Ep);
345
+ configure: async (device, coordinatorEndpoint, logger, options) => {
346
+ if (device != null) {
347
+ // Bind Control EP (LED)
348
+ const controlEp = device.getEndpoint(zigfredEndpoint);
349
+ setMetaOption(device, 'front_surface_enabled', (await controlEp.read('genBasic', ['deviceEnabled'])).deviceEnabled);
350
+ if (checkMetaOption(device, 'front_surface_enabled')) {
351
+ await reporting.bind(controlEp, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl', 'manuSpecificSiglisZigfred']);
352
+ await reporting.onOff(controlEp);
353
+ await reporting.brightness(controlEp);
354
+ }
355
+
356
+ // Bind Dimmer 1 EP
357
+ const dimmer1Ep = device.getEndpoint(7);
358
+ setMetaOption(device, 'dimmer_1_enabled', (await dimmer1Ep.read('genBasic', ['deviceEnabled'])).deviceEnabled);
359
+ if (checkMetaOption(device, 'dimmer_1_enabled')) {
360
+ await reporting.bind(dimmer1Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
361
+ await reporting.onOff(dimmer1Ep);
362
+ await reporting.brightness(dimmer1Ep);
363
+ }
364
+ setMetaOption(device, 'dimmer_1_dimming_enabled', true);
365
+
366
+ // Bind Dimmer 2 EP
367
+ const dimmer2Ep = device.getEndpoint(8);
368
+ setMetaOption(device, 'dimmer_2_enabled', (await dimmer2Ep.read('genBasic', ['deviceEnabled'])).deviceEnabled);
369
+ if (checkMetaOption(device, 'dimmer_2_enabled')) {
370
+ await reporting.bind(dimmer2Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
371
+ await reporting.onOff(dimmer2Ep);
372
+ await reporting.brightness(dimmer2Ep);
373
+ }
374
+ setMetaOption(device, 'dimmer_2_dimming_enabled', true);
375
+
376
+ // Bind Dimmer 3 EP
377
+ const dimmer3Ep = device.getEndpoint(9);
378
+ setMetaOption(device, 'dimmer_3_enabled', (await dimmer3Ep.read('genBasic', ['deviceEnabled'])).deviceEnabled);
379
+ if (checkMetaOption(device, 'dimmer_3_enabled')) {
380
+ await reporting.bind(dimmer3Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
381
+ await reporting.onOff(dimmer3Ep);
382
+ await reporting.brightness(dimmer3Ep);
383
+ }
384
+ setMetaOption(device, 'dimmer_3_dimming_enabled', true);
385
+
386
+ // Bind Dimmer 4 EP
387
+ const dimmer4Ep = device.getEndpoint(10);
388
+ setMetaOption(device, 'dimmer_4_enabled', (await dimmer4Ep.read('genBasic', ['deviceEnabled'])).deviceEnabled);
389
+ if (checkMetaOption(device, 'dimmer_4_enabled')) {
390
+ await reporting.bind(dimmer4Ep, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
391
+ await reporting.onOff(dimmer4Ep);
392
+ await reporting.brightness(dimmer4Ep);
393
+ }
394
+ setMetaOption(device, 'dimmer_4_dimming_enabled', true);
395
+
396
+ // Bind Cover 1 EP
397
+ const cover1Ep = device.getEndpoint(11);
398
+ setMetaOption(device, 'cover_1_enabled', (await cover1Ep.read('genBasic', ['deviceEnabled'])).deviceEnabled);
399
+ if (checkMetaOption(device, 'cover_1_enabled')) {
400
+ await reporting.bind(cover1Ep, coordinatorEndpoint, ['closuresWindowCovering']);
401
+ await reporting.currentPositionLiftPercentage(cover1Ep);
402
+ setMetaOption(
403
+ device,
404
+ 'cover_1_tilt_enabled',
405
+ (await cover1Ep.read('closuresWindowCovering', ['windowCoveringType'])).windowCoveringType === 0x08);
406
+ if (checkMetaOption(device, 'cover_1_tilt_enabled')) {
407
+ await reporting.currentPositionTiltPercentage(cover1Ep);
408
+ }
409
+ } else {
410
+ setMetaOption(device, 'cover_1_tilt_enabled', false);
411
+ }
412
+
413
+ // Bind Cover 2 EP
414
+ const cover2Ep = device.getEndpoint(12);
415
+ setMetaOption(device, 'cover_2_enabled', (await cover2Ep.read('genBasic', ['deviceEnabled'])).deviceEnabled);
416
+ if (checkMetaOption(device, 'cover_2_enabled')) {
417
+ await reporting.bind(cover2Ep, coordinatorEndpoint, ['closuresWindowCovering']);
418
+ await reporting.currentPositionLiftPercentage(cover2Ep);
419
+ setMetaOption(
420
+ device,
421
+ 'cover_2_tilt_enabled',
422
+ (await cover2Ep.read('closuresWindowCovering', ['windowCoveringType'])).windowCoveringType === 0x08);
423
+ if (checkMetaOption(device, 'cover_2_tilt_enabled')) {
424
+ await reporting.currentPositionTiltPercentage(cover2Ep);
425
+ }
426
+ } else {
427
+ setMetaOption(device, 'cover_2_tilt_enabled', false);
428
+ }
429
+
430
+ device.save();
431
+ }
248
432
  },
249
433
  },
250
434
  ];
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'];
24
+ '_TZ3000_aim0ztek', '_TZ3000_mlswgkc3', '_TZ3000_7dndcnnb'];
25
25
 
26
26
  const tzLocal = {
27
27
  SA12IZL_silence_siren: {
package/devices/xiaomi.js CHANGED
@@ -886,8 +886,7 @@ module.exports = [
886
886
  e.switch().withEndpoint('right'),
887
887
  e.power().withAccess(ea.STATE_GET),
888
888
  e.action([
889
- 'hold_left', 'single_left', 'double_left', 'release_left', 'hold_right', 'single_right',
890
- 'double_right', 'release_right', 'hold_both', 'single_both', 'double_both', 'release_both',
889
+ 'hold_left', 'single_left', 'double_left', 'single_right', 'double_right', 'single_both', 'double_both',
891
890
  ]),
892
891
  exposes.enum('operation_mode', ea.ALL, ['control_left_relay', 'decoupled'])
893
892
  .withDescription('Decoupled mode for left button')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.627",
3
+ "version": "14.0.629",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [