zigbee-herdsman-converters 15.0.3 → 15.0.5
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/toZigbee.js +28 -1
- package/devices/ikea.js +1 -26
- package/devices/iris.js +2 -2
- package/devices/ledvance.js +16 -0
- package/devices/legrand.js +1 -0
- package/devices/lidl.js +6 -0
- package/devices/lonsonho.js +1 -1
- package/devices/moes.js +1 -1
- package/devices/philips.js +16 -2
- package/devices/sinope.js +29 -22
- package/devices/sunricher.js +9 -0
- package/devices/tuya.js +19 -9
- package/devices/visonic.js +7 -2
- package/lib/tuya.js +31 -5
- package/package.json +1 -1
package/converters/toZigbee.js
CHANGED
|
@@ -760,6 +760,31 @@ const converters = {
|
|
|
760
760
|
}
|
|
761
761
|
},
|
|
762
762
|
},
|
|
763
|
+
light_color_and_colortemp_via_color: {
|
|
764
|
+
key: ['color', 'color_temp', 'color_temp_percent'],
|
|
765
|
+
options: [exposes.options.color_sync(), exposes.options.transition()],
|
|
766
|
+
convertSet: async (entity, key, value, meta) => {
|
|
767
|
+
if (key == 'color') {
|
|
768
|
+
const result = await converters.light_color.convertSet(entity, key, value, meta);
|
|
769
|
+
return result;
|
|
770
|
+
} else if (key == 'color_temp' || key == 'color_temp_percent') {
|
|
771
|
+
const xy = libColor.ColorXY.fromMireds(value);
|
|
772
|
+
const payload = {
|
|
773
|
+
transtime: utils.getTransition(entity, key, meta).time,
|
|
774
|
+
colorx: utils.mapNumberRange(xy.x, 0, 1, 0, 65535),
|
|
775
|
+
colory: utils.mapNumberRange(xy.y, 0, 1, 0, 65535),
|
|
776
|
+
};
|
|
777
|
+
await entity.command('lightingColorCtrl', 'moveToColor', payload, utils.getOptions(meta.mapped, entity));
|
|
778
|
+
return {
|
|
779
|
+
state: libColor.syncColorState({'color_mode': constants.colorMode[2], 'color_temp': value}, meta.state,
|
|
780
|
+
entity, meta.options, meta.logger), readAfterWriteTime: payload.transtime * 100,
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
},
|
|
784
|
+
convertGet: async (entity, key, meta) => {
|
|
785
|
+
await entity.read('lightingColorCtrl', light.readColorAttributes(entity, meta));
|
|
786
|
+
},
|
|
787
|
+
},
|
|
763
788
|
light_hue_saturation_step: {
|
|
764
789
|
key: ['hue_step', 'saturation_step'],
|
|
765
790
|
options: [exposes.options.transition()],
|
|
@@ -5516,7 +5541,9 @@ const converters = {
|
|
|
5516
5541
|
extensionfieldsets.push({'clstId': 8, 'len': 1, 'extField': [val]});
|
|
5517
5542
|
state['brightness'] = val;
|
|
5518
5543
|
} else if (attribute === 'position') {
|
|
5519
|
-
|
|
5544
|
+
const invert = utils.getMetaValue(entity, meta.mapped, 'coverInverted', 'allEqual', false) ?
|
|
5545
|
+
!meta.options.invert_cover : meta.options.invert_cover;
|
|
5546
|
+
extensionfieldsets.push({'clstId': 258, 'len': 1, 'extField': [invert ? 100 - val : val]});
|
|
5520
5547
|
state['position'] = val;
|
|
5521
5548
|
} else if (attribute === 'color_temp') {
|
|
5522
5549
|
/*
|
package/devices/ikea.js
CHANGED
|
@@ -6,7 +6,6 @@ const constants = require('../lib/constants');
|
|
|
6
6
|
const reporting = require('../lib/reporting');
|
|
7
7
|
const {repInterval} = require('../lib/constants');
|
|
8
8
|
const utils = require('../lib/utils');
|
|
9
|
-
const libColor = require('../lib/color');
|
|
10
9
|
const extend = require('../lib/extend');
|
|
11
10
|
const globalStore = require('../lib/store');
|
|
12
11
|
const e = exposes.presets;
|
|
@@ -73,30 +72,6 @@ const configureRemote = async (device, coordinatorEndpoint, logger) => {
|
|
|
73
72
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
74
73
|
};
|
|
75
74
|
|
|
76
|
-
const tzLocal = {
|
|
77
|
-
LED1624G9_color_colortemp: {
|
|
78
|
-
...tz.light_color_colortemp,
|
|
79
|
-
convertSet: async (entity, key, value, meta) => {
|
|
80
|
-
if (key == 'color') {
|
|
81
|
-
const result = await tz.light_color.convertSet(entity, key, value, meta);
|
|
82
|
-
return result;
|
|
83
|
-
} else if (key == 'color_temp' || key == 'color_temp_percent') {
|
|
84
|
-
const xy = libColor.ColorXY.fromMireds(value);
|
|
85
|
-
const payload = {
|
|
86
|
-
transtime: utils.getTransition(entity, key, meta).time,
|
|
87
|
-
colorx: utils.mapNumberRange(xy.x, 0, 1, 0, 65535),
|
|
88
|
-
colory: utils.mapNumberRange(xy.y, 0, 1, 0, 65535),
|
|
89
|
-
};
|
|
90
|
-
await entity.command('lightingColorCtrl', 'moveToColor', payload, utils.getOptions(meta.mapped, entity));
|
|
91
|
-
return {
|
|
92
|
-
state: libColor.syncColorState({'color_mode': constants.colorMode[2], 'color_temp': value}, meta.state,
|
|
93
|
-
entity, meta.options, meta.logger), readAfterWriteTime: payload.transtime * 100,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
75
|
const fzLocal = {
|
|
101
76
|
// The STYRBAR sends an on +- 500ms after the arrow release. We don't want to send the ON action in this case.
|
|
102
77
|
// https://github.com/Koenkk/zigbee2mqtt/issues/13335
|
|
@@ -490,7 +465,7 @@ module.exports = [
|
|
|
490
465
|
toZigbee: utils.replaceInArray(
|
|
491
466
|
tradfriExtend.light_onoff_brightness_colortemp_color().toZigbee,
|
|
492
467
|
[tz.light_color_colortemp],
|
|
493
|
-
[
|
|
468
|
+
[tz.light_color_and_colortemp_via_color],
|
|
494
469
|
),
|
|
495
470
|
meta: {supportsHueAndSaturation: false},
|
|
496
471
|
},
|
package/devices/iris.js
CHANGED
|
@@ -58,7 +58,7 @@ module.exports = [
|
|
|
58
58
|
await reporting.temperature(endpoint);
|
|
59
59
|
await reporting.batteryVoltage(endpoint);
|
|
60
60
|
},
|
|
61
|
-
exposes: [e.occupancy(), e.battery_low(), e.
|
|
61
|
+
exposes: [e.occupancy(), e.battery_low(), e.temperature(), e.battery()],
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
zigbeeModel: ['3320-L'],
|
|
@@ -74,7 +74,7 @@ module.exports = [
|
|
|
74
74
|
await reporting.temperature(endpoint);
|
|
75
75
|
await reporting.batteryVoltage(endpoint);
|
|
76
76
|
},
|
|
77
|
-
exposes: [e.contact(), e.battery_low(), e.
|
|
77
|
+
exposes: [e.contact(), e.battery_low(), e.temperature(), e.battery()],
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
zigbeeModel: ['3450-L', '3450-L2'],
|
package/devices/ledvance.js
CHANGED
|
@@ -251,6 +251,22 @@ module.exports = [
|
|
|
251
251
|
extend: extend.ledvance.light_onoff_brightness(),
|
|
252
252
|
ota: ota.ledvance,
|
|
253
253
|
},
|
|
254
|
+
{
|
|
255
|
+
zigbeeModel: ['FLEX RGBW T'],
|
|
256
|
+
model: '4058075729384',
|
|
257
|
+
vendor: 'LEDVANCE',
|
|
258
|
+
description: 'SMART+ Indoor Flex multicolor RGBW',
|
|
259
|
+
extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 526]}),
|
|
260
|
+
ota: ota.ledvance,
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
zigbeeModel: ['OUTDOOR FLEX RGBW T'],
|
|
264
|
+
model: '4058075729360',
|
|
265
|
+
vendor: 'LEDVANCE',
|
|
266
|
+
description: 'SMART+ Outdoor Flex multicolor RGBW',
|
|
267
|
+
extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 526]}),
|
|
268
|
+
ota: ota.ledvance,
|
|
269
|
+
},
|
|
254
270
|
{
|
|
255
271
|
zigbeeModel: ['GLOBE60 FIL DIM T'],
|
|
256
272
|
model: '4058075729247',
|
package/devices/legrand.js
CHANGED
|
@@ -368,6 +368,7 @@ module.exports = [
|
|
|
368
368
|
model: '064882',
|
|
369
369
|
vendor: 'Legrand',
|
|
370
370
|
description: 'Cable outlet with pilot wire and consumption measurement',
|
|
371
|
+
ota: ota.zigbeeOTA,
|
|
371
372
|
fromZigbee: [fz.legrand_cluster_fc01, fz.legrand_cable_outlet_mode, fz.on_off, fz.electrical_measurement, fz.power_on_behavior],
|
|
372
373
|
toZigbee: [tz.legrand_deviceMode, tz.legrand_cableOutletMode, tz.on_off, tz.electrical_measurement_power, tz.power_on_behavior],
|
|
373
374
|
exposes: [exposes.binary('device_mode', ea.ALL, 'pilot_on', 'pilot_off'),
|
package/devices/lidl.js
CHANGED
|
@@ -8,6 +8,7 @@ const ea = exposes.access;
|
|
|
8
8
|
const tuya = require('../lib/tuya');
|
|
9
9
|
const globalStore = require('../lib/store');
|
|
10
10
|
const ota = require('../lib/ota');
|
|
11
|
+
const utils = require('../lib/utils');
|
|
11
12
|
|
|
12
13
|
const tuyaLocal = {
|
|
13
14
|
dataPoints: {
|
|
@@ -542,6 +543,11 @@ module.exports = [
|
|
|
542
543
|
vendor: 'Lidl',
|
|
543
544
|
description: 'Livarno smart LED ceiling light',
|
|
544
545
|
...extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}),
|
|
546
|
+
toZigbee: utils.replaceInArray(
|
|
547
|
+
extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}).toZigbee,
|
|
548
|
+
[tz.light_color_colortemp],
|
|
549
|
+
[tz.light_color_and_colortemp_via_color],
|
|
550
|
+
),
|
|
545
551
|
meta: {applyRedFix: true, enhancedHue: false},
|
|
546
552
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
547
553
|
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
package/devices/lonsonho.js
CHANGED
|
@@ -25,7 +25,7 @@ module.exports = [
|
|
|
25
25
|
model: '11830304',
|
|
26
26
|
vendor: 'Lonsonho',
|
|
27
27
|
description: 'Curtain switch',
|
|
28
|
-
fromZigbee: [fz.cover_position_tilt, tuya.fz.
|
|
28
|
+
fromZigbee: [fz.cover_position_tilt, tuya.fz.backlight_mode_low_medium_high, fz.tuya_cover_options],
|
|
29
29
|
toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.tuya_cover_calibration, tz.tuya_cover_reversal,
|
|
30
30
|
tuya.tz.backlight_indicator_mode],
|
|
31
31
|
meta: {coverInverted: true},
|
package/devices/moes.js
CHANGED
|
@@ -399,7 +399,7 @@ module.exports = [
|
|
|
399
399
|
model: 'ZS-EUB_1gang',
|
|
400
400
|
vendor: 'Moes',
|
|
401
401
|
description: 'Wall light switch (1 gang)',
|
|
402
|
-
extend: tuya.extend.switch({
|
|
402
|
+
extend: tuya.extend.switch({backlightModeLowMediumHigh: true, switchType: true}),
|
|
403
403
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
404
404
|
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
405
405
|
device.powerSource = 'Mains (single phase)';
|
package/devices/philips.js
CHANGED
|
@@ -810,6 +810,13 @@ module.exports = [
|
|
|
810
810
|
description: 'Hue Filament Standard A60/E27 bluetooth',
|
|
811
811
|
extend: hueExtend.light_onoff_brightness(),
|
|
812
812
|
},
|
|
813
|
+
{
|
|
814
|
+
zigbeeModel: ['LWA021'],
|
|
815
|
+
model: '9290030514',
|
|
816
|
+
vendor: 'Philips',
|
|
817
|
+
description: 'Hue Filament Standard A60/E27 bluetooth',
|
|
818
|
+
extend: hueExtend.light_onoff_brightness(),
|
|
819
|
+
},
|
|
813
820
|
{
|
|
814
821
|
zigbeeModel: ['LCB001'],
|
|
815
822
|
model: '548727',
|
|
@@ -1430,7 +1437,7 @@ module.exports = [
|
|
|
1430
1437
|
zigbeeModel: ['3261331P6', '929003055301'],
|
|
1431
1438
|
model: '3261331P6',
|
|
1432
1439
|
vendor: 'Philips',
|
|
1433
|
-
description: 'Hue white ambiance Still',
|
|
1440
|
+
description: 'Hue white ambiance Still (white)',
|
|
1434
1441
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
1435
1442
|
},
|
|
1436
1443
|
{
|
|
@@ -1447,11 +1454,18 @@ module.exports = [
|
|
|
1447
1454
|
description: 'Hue white ambiance Still',
|
|
1448
1455
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
1449
1456
|
},
|
|
1457
|
+
{
|
|
1458
|
+
zigbeeModel: ['929003055401'],
|
|
1459
|
+
model: '929003055401',
|
|
1460
|
+
vendor: 'Philips',
|
|
1461
|
+
description: 'Hue white ambiance Still (aluminium)',
|
|
1462
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
1463
|
+
},
|
|
1450
1464
|
{
|
|
1451
1465
|
zigbeeModel: ['929003055501'],
|
|
1452
1466
|
model: '929003055501',
|
|
1453
1467
|
vendor: 'Philips',
|
|
1454
|
-
description: 'Hue white ambiance Still',
|
|
1468
|
+
description: 'Hue white ambiance Still (black)',
|
|
1455
1469
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
1456
1470
|
},
|
|
1457
1471
|
{
|
package/devices/sinope.js
CHANGED
|
@@ -8,6 +8,7 @@ const extend = require('../lib/extend');
|
|
|
8
8
|
const e = exposes.presets;
|
|
9
9
|
const ea = exposes.access;
|
|
10
10
|
|
|
11
|
+
const manuSinope = {manufacturerCode: 0x119C};
|
|
11
12
|
const fzLocal = {
|
|
12
13
|
sinope_thermostat: {
|
|
13
14
|
cluster: 'hvacThermostat',
|
|
@@ -123,11 +124,11 @@ const tzLocal = {
|
|
|
123
124
|
convertSet: async (entity, key, value, meta) => {
|
|
124
125
|
const sinopeOccupancy = {0: 'unoccupied', 1: 'occupied'};
|
|
125
126
|
const SinopeOccupancy = utils.getKey(sinopeOccupancy, value, value, Number);
|
|
126
|
-
await entity.write('hvacThermostat', {SinopeOccupancy},
|
|
127
|
+
await entity.write('hvacThermostat', {SinopeOccupancy}, manuSinope);
|
|
127
128
|
return {state: {'thermostat_occupancy': value}};
|
|
128
129
|
},
|
|
129
130
|
convertGet: async (entity, key, meta) => {
|
|
130
|
-
await entity.read('hvacThermostat', ['SinopeOccupancy'],
|
|
131
|
+
await entity.read('hvacThermostat', ['SinopeOccupancy'], manuSinope);
|
|
131
132
|
},
|
|
132
133
|
},
|
|
133
134
|
sinope_thermostat_backlight_autodim_param: {
|
|
@@ -135,11 +136,11 @@ const tzLocal = {
|
|
|
135
136
|
convertSet: async (entity, key, value, meta) => {
|
|
136
137
|
const sinopeBacklightParam = {0: 'on_demand', 1: 'sensing'};
|
|
137
138
|
const SinopeBacklight = utils.getKey(sinopeBacklightParam, value, value, Number);
|
|
138
|
-
await entity.write('hvacThermostat', {SinopeBacklight},
|
|
139
|
+
await entity.write('hvacThermostat', {SinopeBacklight}, manuSinope);
|
|
139
140
|
return {state: {'backlight_auto_dim': value}};
|
|
140
141
|
},
|
|
141
142
|
convertGet: async (entity, key, meta) => {
|
|
142
|
-
await entity.read('hvacThermostat', ['SinopeBacklight'],
|
|
143
|
+
await entity.read('hvacThermostat', ['SinopeBacklight'], manuSinope);
|
|
143
144
|
},
|
|
144
145
|
},
|
|
145
146
|
sinope_thermostat_main_cycle_output: {
|
|
@@ -147,11 +148,11 @@ const tzLocal = {
|
|
|
147
148
|
key: ['main_cycle_output'],
|
|
148
149
|
convertSet: async (entity, key, value, meta) => {
|
|
149
150
|
const lookup = {'15_sec': 15, '5_min': 300, '10_min': 600, '15_min': 900, '20_min': 1200, '30_min': 1800};
|
|
150
|
-
await entity.write('hvacThermostat', {SinopeMainCycleOutput: lookup[value]},
|
|
151
|
+
await entity.write('hvacThermostat', {SinopeMainCycleOutput: lookup[value]}, manuSinope);
|
|
151
152
|
return {state: {'main_cycle_output': value}};
|
|
152
153
|
},
|
|
153
154
|
convertGet: async (entity, key, meta) => {
|
|
154
|
-
await entity.read('hvacThermostat', ['SinopeMainCycleOutput'],
|
|
155
|
+
await entity.read('hvacThermostat', ['SinopeMainCycleOutput'], manuSinope);
|
|
155
156
|
},
|
|
156
157
|
},
|
|
157
158
|
sinope_thermostat_aux_cycle_output: {
|
|
@@ -170,22 +171,22 @@ const tzLocal = {
|
|
|
170
171
|
key: ['enable_outdoor_temperature'],
|
|
171
172
|
convertSet: async (entity, key, value, meta) => {
|
|
172
173
|
if (value.toLowerCase() == 'on') {
|
|
173
|
-
await entity.write('manuSpecificSinope', {outdoorTempToDisplayTimeout: 10800});
|
|
174
|
+
await entity.write('manuSpecificSinope', {outdoorTempToDisplayTimeout: 10800}, manuSinope);
|
|
174
175
|
} else if (value.toLowerCase() == 'off') {
|
|
175
176
|
// set timer to 12 sec in order to disable outdoor temperature
|
|
176
|
-
await entity.write('manuSpecificSinope', {outdoorTempToDisplayTimeout: 12});
|
|
177
|
+
await entity.write('manuSpecificSinope', {outdoorTempToDisplayTimeout: 12}, manuSinope);
|
|
177
178
|
}
|
|
178
179
|
return {readAfterWriteTime: 250, state: {enable_outdoor_temperature: value}};
|
|
179
180
|
},
|
|
180
181
|
convertGet: async (entity, key, meta) => {
|
|
181
|
-
await entity.read('manuSpecificSinope', ['outdoorTempToDisplayTimeout']);
|
|
182
|
+
await entity.read('manuSpecificSinope', ['outdoorTempToDisplayTimeout'], manuSinope);
|
|
182
183
|
},
|
|
183
184
|
},
|
|
184
185
|
sinope_thermostat_outdoor_temperature: {
|
|
185
186
|
key: ['thermostat_outdoor_temperature'],
|
|
186
187
|
convertSet: async (entity, key, value, meta) => {
|
|
187
188
|
if (value > -100 && value < 100) {
|
|
188
|
-
await entity.write('manuSpecificSinope', {outdoorTempToDisplay: value * 100});
|
|
189
|
+
await entity.write('manuSpecificSinope', {outdoorTempToDisplay: value * 100}, manuSinope);
|
|
189
190
|
}
|
|
190
191
|
},
|
|
191
192
|
},
|
|
@@ -197,9 +198,9 @@ const tzLocal = {
|
|
|
197
198
|
const thermostatTimeSec = thermostatDate.getTime() / 1000;
|
|
198
199
|
const thermostatTimezoneOffsetSec = thermostatDate.getTimezoneOffset() * 60;
|
|
199
200
|
const currentTimeToDisplay = Math.round(thermostatTimeSec - thermostatTimezoneOffsetSec - 946684800);
|
|
200
|
-
await entity.write('manuSpecificSinope', {currentTimeToDisplay});
|
|
201
|
+
await entity.write('manuSpecificSinope', {currentTimeToDisplay}, manuSinope);
|
|
201
202
|
} else if (value !== '') {
|
|
202
|
-
await entity.write('manuSpecificSinope', {currentTimeToDisplay: value});
|
|
203
|
+
await entity.write('manuSpecificSinope', {currentTimeToDisplay: value}, manuSinope);
|
|
203
204
|
}
|
|
204
205
|
},
|
|
205
206
|
},
|
|
@@ -287,12 +288,12 @@ const tzLocal = {
|
|
|
287
288
|
const lookup = {'24h': 0, '12h': 1};
|
|
288
289
|
value = value.toLowerCase();
|
|
289
290
|
if (lookup.hasOwnProperty(value)) {
|
|
290
|
-
await entity.write('manuSpecificSinope', {timeFormatToDisplay: lookup[value]});
|
|
291
|
+
await entity.write('manuSpecificSinope', {timeFormatToDisplay: lookup[value]}, manuSinope);
|
|
291
292
|
return {readAfterWriteTime: 250, state: {time_format: value}};
|
|
292
293
|
}
|
|
293
294
|
},
|
|
294
295
|
convertGet: async (entity, key, meta) => {
|
|
295
|
-
await entity.read('manuSpecificSinope', ['timeFormatToDisplay']);
|
|
296
|
+
await entity.read('manuSpecificSinope', ['timeFormatToDisplay'], manuSinope);
|
|
296
297
|
},
|
|
297
298
|
},
|
|
298
299
|
sinope_connected_load: {
|
|
@@ -428,6 +429,10 @@ module.exports = [
|
|
|
428
429
|
await reporting.thermostatTemperature(endpoint);
|
|
429
430
|
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
430
431
|
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
432
|
+
|
|
433
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
434
|
+
await endpoint.configureReporting('msTemperatureMeasurement', [{
|
|
435
|
+
attribute: 'tolerance', minimumReportInterval: 1, maximumReportInterval: 0xFFFF, reportableChange: 1}]);
|
|
431
436
|
try {
|
|
432
437
|
await reporting.thermostatSystemMode(endpoint);
|
|
433
438
|
} catch (error) {/* Not all support this */}
|
|
@@ -446,8 +451,6 @@ module.exports = [
|
|
|
446
451
|
}
|
|
447
452
|
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
448
453
|
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
449
|
-
|
|
450
|
-
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
451
454
|
},
|
|
452
455
|
},
|
|
453
456
|
{
|
|
@@ -492,6 +495,10 @@ module.exports = [
|
|
|
492
495
|
await reporting.thermostatTemperature(endpoint);
|
|
493
496
|
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
494
497
|
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
498
|
+
|
|
499
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
500
|
+
await endpoint.configureReporting('msTemperatureMeasurement', [{
|
|
501
|
+
attribute: 'tolerance', minimumReportInterval: 1, maximumReportInterval: 0xFFFF, reportableChange: 1}]);
|
|
495
502
|
try {
|
|
496
503
|
await reporting.thermostatSystemMode(endpoint);
|
|
497
504
|
} catch (error) {/* Not all support this */}
|
|
@@ -510,8 +517,6 @@ module.exports = [
|
|
|
510
517
|
}
|
|
511
518
|
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
512
519
|
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
513
|
-
|
|
514
|
-
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
515
520
|
},
|
|
516
521
|
},
|
|
517
522
|
{
|
|
@@ -557,22 +562,24 @@ module.exports = [
|
|
|
557
562
|
const thermostatTimeSec = thermostatDate.getTime() / 1000;
|
|
558
563
|
const thermostatTimezoneOffsetSec = thermostatDate.getTimezoneOffset() * 60;
|
|
559
564
|
const currentTimeToDisplay = Math.round(thermostatTimeSec - thermostatTimezoneOffsetSec - 946684800);
|
|
560
|
-
await endpoint.write('manuSpecificSinope', {currentTimeToDisplay},
|
|
561
|
-
await endpoint.write('manuSpecificSinope', {'secondScreenBehavior': 0},
|
|
565
|
+
await endpoint.write('manuSpecificSinope', {currentTimeToDisplay}, manuSinope);
|
|
566
|
+
await endpoint.write('manuSpecificSinope', {'secondScreenBehavior': 0}, manuSinope); // Mode auto
|
|
562
567
|
|
|
563
568
|
await reporting.thermostatTemperature(endpoint);
|
|
564
569
|
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
565
570
|
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
566
571
|
await reporting.thermostatSystemMode(endpoint);
|
|
567
572
|
|
|
573
|
+
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
574
|
+
await endpoint.configureReporting('msTemperatureMeasurement', [{
|
|
575
|
+
attribute: 'tolerance', minimumReportInterval: 1, maximumReportInterval: 0xFFFF, reportableChange: 1}]);
|
|
576
|
+
|
|
568
577
|
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
569
578
|
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
|
|
570
579
|
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
571
580
|
await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 1: 1W
|
|
572
581
|
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 100}); // divider 1000: 0.1Arms
|
|
573
582
|
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 5}); // divider 10: 0.5Vrms
|
|
574
|
-
|
|
575
|
-
await reporting.temperature(endpoint, {min: 1, max: 0xFFFF}); // Disable default reporting
|
|
576
583
|
try {
|
|
577
584
|
await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
|
|
578
585
|
} catch (error) {/* Do nothing */} // Not enought space but shall pass
|
package/devices/sunricher.js
CHANGED
|
@@ -603,4 +603,13 @@ module.exports = [
|
|
|
603
603
|
await endpoint.read('hvacThermostat', [0x2001, 0x2002], options);
|
|
604
604
|
},
|
|
605
605
|
},
|
|
606
|
+
{
|
|
607
|
+
fingerprint: [{modelID: 'TERNCY-DC01', manufacturer: 'Sunricher'}],
|
|
608
|
+
model: 'SR-ZG9010A',
|
|
609
|
+
vendor: 'Sunricher',
|
|
610
|
+
description: 'Door windows sensor',
|
|
611
|
+
fromZigbee: [fz.U02I007C01_contact, fz.battery],
|
|
612
|
+
toZigbee: [],
|
|
613
|
+
exposes: [e.contact(), e.battery()],
|
|
614
|
+
},
|
|
606
615
|
];
|
package/devices/tuya.js
CHANGED
|
@@ -931,7 +931,7 @@ module.exports = [
|
|
|
931
931
|
model: 'TS011F_2_gang_wall',
|
|
932
932
|
vendor: 'TuYa',
|
|
933
933
|
description: '2 gang wall outlet',
|
|
934
|
-
extend: tuya.extend.switch({
|
|
934
|
+
extend: tuya.extend.switch({backlightModeLowMediumHigh: true, childLock: true, endpoints: ['l1', 'l2']}),
|
|
935
935
|
whiteLabel: [{vendor: 'ClickSmart+', model: 'CMA30036'}],
|
|
936
936
|
endpoint: (device) => {
|
|
937
937
|
return {'l1': 1, 'l2': 2};
|
|
@@ -1026,6 +1026,17 @@ module.exports = [
|
|
|
1026
1026
|
vendor: 'TuYa',
|
|
1027
1027
|
extend: extend.light_onoff_brightness({disablePowerOnBehavior: true}),
|
|
1028
1028
|
},
|
|
1029
|
+
{
|
|
1030
|
+
fingerprint: tuya.fingerprint('TS0202', ['_TYZB01_vwqnz1sn']),
|
|
1031
|
+
model: 'TS0202_3',
|
|
1032
|
+
vendor: 'TuYa',
|
|
1033
|
+
description: 'Motion detector with illuminance',
|
|
1034
|
+
fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_occupancy_alarm_1_report, fz.illuminance],
|
|
1035
|
+
toZigbee: [],
|
|
1036
|
+
onEvent: tuya.onEventSetTime,
|
|
1037
|
+
configure: tuya.configureMagicPacket,
|
|
1038
|
+
exposes: [e.occupancy(), e.battery_low(), e.battery(), e.tamper(), e.illuminance_lux()],
|
|
1039
|
+
},
|
|
1029
1040
|
{
|
|
1030
1041
|
fingerprint: tuya.fingerprint('TS0202', ['_TZ3210_cwamkvua']),
|
|
1031
1042
|
model: 'TS0202_2',
|
|
@@ -1069,7 +1080,6 @@ module.exports = [
|
|
|
1069
1080
|
{
|
|
1070
1081
|
fingerprint: [{modelID: 'TS0202', manufacturerName: '_TYZB01_dr6sduka'},
|
|
1071
1082
|
{modelID: 'TS0202', manufacturerName: '_TYZB01_ef5xlc9q'},
|
|
1072
|
-
{modelID: 'TS0202', manufacturerName: '_TYZB01_vwqnz1sn'},
|
|
1073
1083
|
{modelID: 'TS0202', manufacturerName: '_TYZB01_2b8f6cio'},
|
|
1074
1084
|
{modelID: 'TS0202', manufacturerName: '_TYZB01_71kfvvma'},
|
|
1075
1085
|
{modelID: 'TS0202', manufacturerName: '_TZE200_bq5c8xfe'},
|
|
@@ -1379,7 +1389,7 @@ module.exports = [
|
|
|
1379
1389
|
model: 'TS130F',
|
|
1380
1390
|
vendor: 'TuYa',
|
|
1381
1391
|
description: 'Curtain/blind switch',
|
|
1382
|
-
fromZigbee: [fz.cover_position_tilt, tuya.fz.
|
|
1392
|
+
fromZigbee: [fz.cover_position_tilt, tuya.fz.backlight_mode_low_medium_high, fz.tuya_cover_options],
|
|
1383
1393
|
toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.tuya_cover_calibration, tz.tuya_cover_reversal,
|
|
1384
1394
|
tuya.tz.backlight_indicator_mode],
|
|
1385
1395
|
meta: {coverInverted: true},
|
|
@@ -1666,7 +1676,7 @@ module.exports = [
|
|
|
1666
1676
|
model: 'TS011F_2_gang_2_usb_wall',
|
|
1667
1677
|
vendor: 'TuYa',
|
|
1668
1678
|
description: '2 gang 2 usb wall outlet',
|
|
1669
|
-
extend: tuya.extend.switch({
|
|
1679
|
+
extend: tuya.extend.switch({backlightModeLowMediumHigh: true, endpoints: ['l1', 'l2', 'l3', 'l4']}),
|
|
1670
1680
|
endpoint: () => {
|
|
1671
1681
|
return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4};
|
|
1672
1682
|
},
|
|
@@ -2501,7 +2511,8 @@ module.exports = [
|
|
|
2501
2511
|
},
|
|
2502
2512
|
{
|
|
2503
2513
|
zigbeeModel: ['5p1vj8r'],
|
|
2504
|
-
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_t5p1vj8r', '_TZE200_uebojraa', '_TZE200_vzekyi4c', '_TZE200_yh7aoahi'
|
|
2514
|
+
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_t5p1vj8r', '_TZE200_uebojraa', '_TZE200_vzekyi4c', '_TZE200_yh7aoahi',
|
|
2515
|
+
'_TZE200_dnz6yvl2']),
|
|
2505
2516
|
model: 'TS0601_smoke',
|
|
2506
2517
|
vendor: 'TuYa',
|
|
2507
2518
|
description: 'Smoke sensor',
|
|
@@ -2755,8 +2766,7 @@ module.exports = [
|
|
|
2755
2766
|
description: 'Smart light switch - 2 gang',
|
|
2756
2767
|
whiteLabel: [{vendor: 'Vrey', model: 'VR-X712U-0013'}, {vendor: 'TUYATEC', model: 'GDKES-02TZXD'},
|
|
2757
2768
|
{vendor: 'Earda', model: 'ESW-2ZAA-EU'}],
|
|
2758
|
-
extend: tuya.extend.switch(),
|
|
2759
|
-
exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right')],
|
|
2769
|
+
extend: tuya.extend.switch({backlightModeOffNormalInverted: true, endpoints: ['left', 'right']}),
|
|
2760
2770
|
endpoint: (device) => {
|
|
2761
2771
|
return {'left': 1, 'right': 2};
|
|
2762
2772
|
},
|
|
@@ -2795,7 +2805,7 @@ module.exports = [
|
|
|
2795
2805
|
model: 'TS0013',
|
|
2796
2806
|
vendor: 'TuYa',
|
|
2797
2807
|
description: 'Smart light switch - 3 gang without neutral wire',
|
|
2798
|
-
extend: tuya.extend.switch({
|
|
2808
|
+
extend: tuya.extend.switch({backlightModeLowMediumHigh: true, endpoints: ['left', 'center', 'right']}),
|
|
2799
2809
|
endpoint: (device) => {
|
|
2800
2810
|
return {'left': 1, 'center': 2, 'right': 3};
|
|
2801
2811
|
},
|
|
@@ -2846,7 +2856,7 @@ module.exports = [
|
|
|
2846
2856
|
model: 'TS0014',
|
|
2847
2857
|
vendor: 'TuYa',
|
|
2848
2858
|
description: 'Smart light switch - 4 gang without neutral wire',
|
|
2849
|
-
extend: tuya.extend.switch({
|
|
2859
|
+
extend: tuya.extend.switch({backlightModeLowMediumHigh: true, endpoints: ['l1', 'l2', 'l3', 'l4']}),
|
|
2850
2860
|
endpoint: (device) => {
|
|
2851
2861
|
return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4};
|
|
2852
2862
|
},
|
package/devices/visonic.js
CHANGED
|
@@ -36,9 +36,14 @@ module.exports = [
|
|
|
36
36
|
model: 'MCT-350 SMA',
|
|
37
37
|
vendor: 'Visonic',
|
|
38
38
|
description: 'Magnetic door & window contact sensor',
|
|
39
|
-
fromZigbee: [fz.ias_contact_alarm_1],
|
|
39
|
+
fromZigbee: [fz.ias_contact_alarm_1, fz.temperature],
|
|
40
40
|
toZigbee: [],
|
|
41
|
-
|
|
41
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
42
|
+
const endpoint = device.getEndpoint(1);
|
|
43
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement']);
|
|
44
|
+
await reporting.temperature(endpoint);
|
|
45
|
+
},
|
|
46
|
+
exposes: [e.contact(), e.battery_low(), e.tamper(), e.temperature()],
|
|
42
47
|
},
|
|
43
48
|
{
|
|
44
49
|
zigbeeModel: ['MCT-340 E'],
|
package/lib/tuya.js
CHANGED
|
@@ -1158,7 +1158,10 @@ const tuyaExposes = {
|
|
|
1158
1158
|
powerFactorWithPhase: (phase) => exposes.numeric(`power_factor_${phase}`, ea.STATE).withUnit('%')
|
|
1159
1159
|
.withDescription(`Instantaneous measured power factor (phase ${phase.toUpperCase()})`),
|
|
1160
1160
|
switchType: () => exposes.enum('switch_type', ea.ALL, ['toggle', 'state', 'momentary']).withDescription('Type of the switch'),
|
|
1161
|
-
|
|
1161
|
+
backlightModeLowMediumHigh: () => exposes.enum('backlight_mode', ea.ALL, ['low', 'medium', 'high'])
|
|
1162
|
+
.withDescription('Intensity of the backlight'),
|
|
1163
|
+
backlightModeOffNormalInverted: () => exposes.enum('backlight_mode', ea.ALL, ['off', 'normal', 'inverted'])
|
|
1164
|
+
.withDescription('Mode of the backlight'),
|
|
1162
1165
|
indicatorMode: () => exposes.enum('indicator_mode', ea.ALL, ['off', 'off/on', 'on/off', 'on']).withDescription('LED indicator mode'),
|
|
1163
1166
|
powerOutageMemory: () => exposes.enum('power_outage_memory', ea.ALL, ['on', 'off', 'restore'])
|
|
1164
1167
|
.withDescription('Recover state after power outage'),
|
|
@@ -1546,7 +1549,8 @@ const tuyaTz = {
|
|
|
1546
1549
|
backlight_indicator_mode: {
|
|
1547
1550
|
key: ['backlight_mode', 'indicator_mode'],
|
|
1548
1551
|
convertSet: async (entity, key, value, meta) => {
|
|
1549
|
-
const lookup = key === 'backlight_mode' ? {'low': 0, 'medium': 1, 'high': 2
|
|
1552
|
+
const lookup = key === 'backlight_mode' ? {'low': 0, 'medium': 1, 'high': 2, 'off': 0, 'normal': 1, 'inverted': 2} :
|
|
1553
|
+
{'off': 0, 'off/on': 1, 'on/off': 2, 'on': 3};
|
|
1550
1554
|
value = value.toLowerCase();
|
|
1551
1555
|
utils.validateValue(value, Object.keys(lookup));
|
|
1552
1556
|
await entity.write('genOnOff', {tuyaBacklightMode: lookup[value]});
|
|
@@ -1644,7 +1648,7 @@ const tuyaFz = {
|
|
|
1644
1648
|
}
|
|
1645
1649
|
},
|
|
1646
1650
|
},
|
|
1647
|
-
|
|
1651
|
+
backlight_mode_low_medium_high: {
|
|
1648
1652
|
cluster: 'genOnOff',
|
|
1649
1653
|
type: ['attributeReport', 'readResponse'],
|
|
1650
1654
|
convert: (model, msg, publish, options, meta) => {
|
|
@@ -1655,6 +1659,17 @@ const tuyaFz = {
|
|
|
1655
1659
|
}
|
|
1656
1660
|
},
|
|
1657
1661
|
},
|
|
1662
|
+
backlight_mode_off_normal_inverted: {
|
|
1663
|
+
cluster: 'genOnOff',
|
|
1664
|
+
type: ['attributeReport', 'readResponse'],
|
|
1665
|
+
convert: (model, msg, publish, options, meta) => {
|
|
1666
|
+
if (msg.data.hasOwnProperty('tuyaBacklightMode')) {
|
|
1667
|
+
const value = msg.data['tuyaBacklightMode'];
|
|
1668
|
+
const backlightLookup = {0: 'off', 1: 'normal', 2: 'inverted'};
|
|
1669
|
+
return {backlight_mode: backlightLookup[value]};
|
|
1670
|
+
}
|
|
1671
|
+
},
|
|
1672
|
+
},
|
|
1658
1673
|
indicator_mode: {
|
|
1659
1674
|
cluster: 'genOnOff',
|
|
1660
1675
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -1747,8 +1762,19 @@ const tuyaExtend = {
|
|
|
1747
1762
|
toZigbee.push(tuyaTz.switch_type);
|
|
1748
1763
|
exposes.push(tuyaExposes.switchType());
|
|
1749
1764
|
}
|
|
1750
|
-
if (options.
|
|
1751
|
-
|
|
1765
|
+
if (options.backlightModeLowMediumHigh || options.backlightModeOffNormalInverted || options.indicatorMode) {
|
|
1766
|
+
if (options.backlightModeLowMediumHigh) {
|
|
1767
|
+
fromZigbee.push(tuyaFz.backlight_mode_low_medium_high);
|
|
1768
|
+
exposes.push(tuyaExposes.backlightModeLowMediumHigh());
|
|
1769
|
+
}
|
|
1770
|
+
if (options.backlightModeOffNormalInverted) {
|
|
1771
|
+
fromZigbee.push(tuyaFz.backlight_mode_off_normal_inverted);
|
|
1772
|
+
exposes.push(tuyaExposes.backlightModeOffNormalInverted());
|
|
1773
|
+
}
|
|
1774
|
+
if (options.indicatorMode) {
|
|
1775
|
+
fromZigbee.push(tuyaFz.indicator_mode);
|
|
1776
|
+
exposes.push(tuyaExposes.indicatorMode());
|
|
1777
|
+
}
|
|
1752
1778
|
toZigbee.push(tuyaTz.backlight_indicator_mode);
|
|
1753
1779
|
exposes.push(options.backlightMode ? tuyaExposes.backlightMode() : tuyaExposes.indicatorMode());
|
|
1754
1780
|
}
|