zigbee-herdsman-converters 14.0.628 → 14.0.630
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.
- package/converters/fromZigbee.js +14 -0
- package/converters/toZigbee.js +5 -1
- package/devices/aurora_lighting.js +7 -0
- package/devices/ctm.js +1 -10
- package/devices/envilar.js +1 -1
- package/devices/heiman.js +22 -0
- package/devices/insta.js +1 -1
- package/devices/lellki.js +6 -4
- package/devices/leviton.js +29 -0
- package/devices/niko.js +23 -0
- package/devices/philips.js +21 -0
- package/devices/siglis.js +311 -127
- package/devices/xiaomi.js +1 -2
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -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'],
|
package/converters/toZigbee.js
CHANGED
|
@@ -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) => {
|
|
@@ -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',
|
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
|
|
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);
|
package/devices/envilar.js
CHANGED
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',
|
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.
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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();
|
package/devices/leviton.js
CHANGED
|
@@ -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
|
];
|
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',
|
package/devices/philips.js
CHANGED
|
@@ -2312,6 +2312,13 @@ module.exports = [
|
|
|
2312
2312
|
description: 'Hue white filament Edison ST72 E27 LED',
|
|
2313
2313
|
extend: hueExtend.light_onoff_brightness(),
|
|
2314
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
|
+
},
|
|
2315
2322
|
{
|
|
2316
2323
|
zigbeeModel: ['HML004'],
|
|
2317
2324
|
model: '3115331PH',
|
|
@@ -2694,6 +2701,13 @@ module.exports = [
|
|
|
2694
2701
|
description: 'Akari downlight',
|
|
2695
2702
|
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2696
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
|
+
},
|
|
2697
2711
|
{
|
|
2698
2712
|
zigbeeModel: ['LCD006'],
|
|
2699
2713
|
model: '9290031346',
|
|
@@ -2785,4 +2799,11 @@ module.exports = [
|
|
|
2785
2799
|
description: 'Hue White ambiance Runner spot white (1 spot)',
|
|
2786
2800
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2787
2801
|
},
|
|
2802
|
+
{
|
|
2803
|
+
zigbeeModel: ['915005998101'],
|
|
2804
|
+
model: '915005998101',
|
|
2805
|
+
vendor: 'Philips',
|
|
2806
|
+
description: 'Hue white ambiance ceiling black Enrave',
|
|
2807
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2808
|
+
},
|
|
2788
2809
|
];
|
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
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
const actionLookup = {
|
|
20
|
+
0: 'release',
|
|
21
|
+
1: 'single',
|
|
22
|
+
2: 'double',
|
|
23
|
+
3: 'hold',
|
|
24
|
+
};
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
36
|
-
|
|
33
|
+
const buttonName = buttonLookup[button];
|
|
34
|
+
const typeName = actionLookup[type];
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
'
|
|
76
|
-
|
|
77
|
-
'
|
|
78
|
-
|
|
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
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
'
|
|
156
|
-
|
|
157
|
-
'
|
|
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
|
-
|
|
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
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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/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', '
|
|
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.
|
|
3
|
+
"version": "14.0.630",
|
|
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.
|
|
41
|
+
"zigbee-herdsman": "^0.14.59"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|