zigbee-herdsman-converters 15.0.97 → 15.0.99
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/devices/develco.js +2 -1
- package/devices/lidl.js +0 -114
- package/devices/niko.js +20 -2
- package/devices/sinope.js +20 -12
- package/devices/tuya.js +297 -8
- package/lib/tuya.js +3 -0
- package/package.json +3 -3
package/devices/develco.js
CHANGED
|
@@ -292,7 +292,7 @@ module.exports = [
|
|
|
292
292
|
description: 'Power plug',
|
|
293
293
|
fromZigbee: [fz.on_off, develco.fz.electrical_measurement, develco.fz.metering],
|
|
294
294
|
toZigbee: [tz.on_off],
|
|
295
|
-
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy()],
|
|
295
|
+
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy(), e.ac_frequency()],
|
|
296
296
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
297
297
|
const endpoint = device.getEndpoint(2);
|
|
298
298
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
@@ -303,6 +303,7 @@ module.exports = [
|
|
|
303
303
|
await reporting.rmsVoltage(endpoint);
|
|
304
304
|
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
305
305
|
await reporting.currentSummDelivered(endpoint);
|
|
306
|
+
await reporting.acFrequency(endpoint);
|
|
306
307
|
},
|
|
307
308
|
endpoint: (device) => {
|
|
308
309
|
return {default: 2};
|
package/devices/lidl.js
CHANGED
|
@@ -7,9 +7,6 @@ const ea = exposes.access;
|
|
|
7
7
|
const tuya = require('../lib/tuya');
|
|
8
8
|
const globalStore = require('../lib/store');
|
|
9
9
|
const ota = require('../lib/ota');
|
|
10
|
-
const utils = require('../lib/utils');
|
|
11
|
-
const {ColorMode, colorModeLookup} = require('../lib/constants');
|
|
12
|
-
const libColor = require('../lib/color');
|
|
13
10
|
|
|
14
11
|
const tuyaLocal = {
|
|
15
12
|
dataPoints: {
|
|
@@ -145,105 +142,6 @@ const fzLocal = {
|
|
|
145
142
|
},
|
|
146
143
|
};
|
|
147
144
|
const tzLocal = {
|
|
148
|
-
led_control: {
|
|
149
|
-
key: ['brightness', 'color', 'color_temp', 'transition'],
|
|
150
|
-
options: [exposes.options.color_sync()],
|
|
151
|
-
convertSet: async (entity, _key, _value, meta) => {
|
|
152
|
-
const newState = {};
|
|
153
|
-
|
|
154
|
-
// The color mode encodes whether the light is using its white LEDs or its color LEDs
|
|
155
|
-
let colorMode = meta.state.color_mode ?? colorModeLookup[ColorMode.ColorTemp];
|
|
156
|
-
|
|
157
|
-
// Color mode switching is done by setting color temperature (switch to white LEDs) or setting color (switch
|
|
158
|
-
// to color LEDs)
|
|
159
|
-
if ('color_temp' in meta.message) colorMode = colorModeLookup[ColorMode.ColorTemp];
|
|
160
|
-
if ('color' in meta.message) colorMode = colorModeLookup[ColorMode.HS];
|
|
161
|
-
|
|
162
|
-
if (colorMode != meta.state.color_mode) {
|
|
163
|
-
newState.color_mode = colorMode;
|
|
164
|
-
|
|
165
|
-
// To switch between white mode and color mode, we have to send a special command:
|
|
166
|
-
const rgbMode = (colorMode == colorModeLookup[ColorMode.HS]);
|
|
167
|
-
await entity.command('lightingColorCtrl', 'tuyaRgbMode', {enable: rgbMode}, {}, {disableDefaultResponse: true});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// A transition time of 0 would be treated as about 1 second, probably some kind of fallback/default
|
|
171
|
-
// transition time, so for "no transition" we use 1 (tenth of a second).
|
|
172
|
-
const transtime = 'transition' in meta.message ? meta.message.transition * 10 : 1;
|
|
173
|
-
|
|
174
|
-
if (colorMode == colorModeLookup[ColorMode.ColorTemp]) {
|
|
175
|
-
if ('brightness' in meta.message) {
|
|
176
|
-
const zclData = {level: Number(meta.message.brightness), transtime};
|
|
177
|
-
await entity.command('genLevelCtrl', 'moveToLevel', zclData, utils.getOptions(meta.mapped, entity));
|
|
178
|
-
newState.brightness = meta.message.brightness;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if ('color_temp' in meta.message) {
|
|
182
|
-
const zclData = {colortemp: meta.message.color_temp, transtime: transtime};
|
|
183
|
-
await entity.command('lightingColorCtrl', 'moveToColorTemp', zclData, utils.getOptions(meta.mapped, entity));
|
|
184
|
-
newState.color_temp = meta.message.color_temp;
|
|
185
|
-
}
|
|
186
|
-
} else if (colorMode == colorModeLookup[ColorMode.HS]) {
|
|
187
|
-
if ('brightness' in meta.message || 'color' in meta.message) {
|
|
188
|
-
// We ignore the brightness of the color and instead use the overall brightness setting of the lamp
|
|
189
|
-
// for the brightness because I think that's the expected behavior and also because the color
|
|
190
|
-
// conversion below always returns 100 as brightness ("value") even for very dark colors, except
|
|
191
|
-
// when the color is completely black/zero.
|
|
192
|
-
|
|
193
|
-
// Load current state or defaults
|
|
194
|
-
const newSettings = {
|
|
195
|
-
brightness: meta.state.brightness ?? 254, // full brightness
|
|
196
|
-
hue: (meta.state.color ?? {}).hue ?? 0, // red
|
|
197
|
-
saturation: (meta.state.color ?? {}).saturation ?? 100, // full saturation
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
// Apply changes
|
|
201
|
-
if ('brightness' in meta.message) {
|
|
202
|
-
newSettings.brightness = meta.message.brightness;
|
|
203
|
-
newState.brightness = meta.message.brightness;
|
|
204
|
-
}
|
|
205
|
-
if ('color' in meta.message) {
|
|
206
|
-
// The Z2M UI sends `{ hex:'#xxxxxx' }`.
|
|
207
|
-
// Home Assistant sends `{ h: xxx, s: xxx }`.
|
|
208
|
-
// We convert the former into the latter.
|
|
209
|
-
const c = libColor.Color.fromConverterArg(meta.message.color);
|
|
210
|
-
if (c.isRGB()) {
|
|
211
|
-
// https://github.com/Koenkk/zigbee2mqtt/issues/13421#issuecomment-1426044963
|
|
212
|
-
c.hsv = c.rgb.gammaCorrected().toXY().toHSV();
|
|
213
|
-
}
|
|
214
|
-
const color = c.hsv;
|
|
215
|
-
|
|
216
|
-
newSettings.hue = color.hue;
|
|
217
|
-
newSettings.saturation = color.saturation;
|
|
218
|
-
|
|
219
|
-
newState.color = {
|
|
220
|
-
hue: color.hue,
|
|
221
|
-
saturation: color.saturation,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Convert to device specific format and send
|
|
226
|
-
const zclData = {
|
|
227
|
-
brightness: utils.mapNumberRange(newSettings.brightness, 0, 254, 0, 1000),
|
|
228
|
-
hue: newSettings.hue,
|
|
229
|
-
saturation: utils.mapNumberRange(newSettings.saturation, 0, 100, 0, 1000),
|
|
230
|
-
};
|
|
231
|
-
// This command doesn't support a transition time
|
|
232
|
-
await entity.command('lightingColorCtrl', 'tuyaMoveToHueAndSaturationBrightness2', zclData,
|
|
233
|
-
utils.getOptions(meta.mapped, entity));
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
// If we're in white mode, calculate a matching display color for the set color temperature. This also kind
|
|
238
|
-
// of works in the other direction.
|
|
239
|
-
Object.assign(newState, libColor.syncColorState(newState, meta.state, entity, meta.options, meta.logger));
|
|
240
|
-
|
|
241
|
-
return {state: newState};
|
|
242
|
-
},
|
|
243
|
-
convertGet: async (entity, key, meta) => {
|
|
244
|
-
await entity.read('lightingColorCtrl', ['currentHue', 'currentSaturation', 'currentLevel', 'tuyaRgbMode', 'colorTemperature']);
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
145
|
zs_thermostat_child_lock: {
|
|
248
146
|
key: ['child_lock'],
|
|
249
147
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -626,18 +524,6 @@ module.exports = [
|
|
|
626
524
|
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
|
627
525
|
},
|
|
628
526
|
},
|
|
629
|
-
{
|
|
630
|
-
fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_iystcadi'}],
|
|
631
|
-
model: '14149505L/14149506L_2',
|
|
632
|
-
vendor: 'Lidl',
|
|
633
|
-
description: 'Livarno Lux light bar RGB+CCT (black/white)',
|
|
634
|
-
toZigbee: [tz.on_off, tzLocal.led_control],
|
|
635
|
-
fromZigbee: [fz.on_off, fz.tuya_led_controller, fz.brightness, fz.ignore_basic_report],
|
|
636
|
-
exposes: [e.light_brightness_colortemp_colorhs([153, 500]).removeFeature('color_temp_startup')],
|
|
637
|
-
configure: async (device, coordinatorEndpoint, logger) => {
|
|
638
|
-
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
|
639
|
-
},
|
|
640
|
-
},
|
|
641
527
|
{
|
|
642
528
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_htnnfasr'}],
|
|
643
529
|
model: 'PSBZS A1',
|
package/devices/niko.js
CHANGED
|
@@ -34,14 +34,27 @@ const local = {
|
|
|
34
34
|
64: 'single',
|
|
35
35
|
32: 'hold',
|
|
36
36
|
48: 'release',
|
|
37
|
+
256: null,
|
|
38
|
+
1024: 'single_ext',
|
|
39
|
+
512: 'hold_ext',
|
|
40
|
+
768: 'release_ext',
|
|
37
41
|
} : {
|
|
38
42
|
16: null,
|
|
39
43
|
64: 'single_left',
|
|
40
44
|
32: 'hold_left',
|
|
41
45
|
48: 'release_left',
|
|
42
|
-
|
|
46
|
+
256: null,
|
|
47
|
+
1024: 'single_left_ext',
|
|
48
|
+
512: 'hold_left_ext',
|
|
49
|
+
768: 'release_left_ext',
|
|
50
|
+
4096: null,
|
|
51
|
+
16384: 'single_right',
|
|
43
52
|
8192: 'hold_right',
|
|
44
53
|
12288: 'release_right',
|
|
54
|
+
65536: null,
|
|
55
|
+
262144: 'single_right_ext',
|
|
56
|
+
131072: 'hold_right_ext',
|
|
57
|
+
196608: 'release_right_ext',
|
|
45
58
|
};
|
|
46
59
|
|
|
47
60
|
state['action'] = actionMap[msg.data.switchAction];
|
|
@@ -262,7 +275,10 @@ module.exports = [
|
|
|
262
275
|
},
|
|
263
276
|
exposes: [
|
|
264
277
|
e.switch(),
|
|
265
|
-
e.action([
|
|
278
|
+
e.action([
|
|
279
|
+
'single', 'hold', 'release',
|
|
280
|
+
'single_ext', 'hold_ext', 'release_ext',
|
|
281
|
+
]),
|
|
266
282
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']),
|
|
267
283
|
exposes.binary('led_enable', ea.ALL, true, false).withDescription('Enable LED'),
|
|
268
284
|
exposes.binary('led_state', ea.ALL, 'ON', 'OFF').withDescription('LED State'),
|
|
@@ -293,7 +309,9 @@ module.exports = [
|
|
|
293
309
|
e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'),
|
|
294
310
|
e.action([
|
|
295
311
|
'single_left', 'hold_left', 'release_left',
|
|
312
|
+
'single_left_ext', 'hold_left_ext', 'release_left_ext',
|
|
296
313
|
'single_right', 'hold_right', 'release_right',
|
|
314
|
+
'single_right_ext', 'hold_right_ext', 'release_right_ext',
|
|
297
315
|
]),
|
|
298
316
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']),
|
|
299
317
|
exposes.binary('led_enable', ea.ALL, true, false).withEndpoint('l1').withDescription('Enable LED'),
|
package/devices/sinope.js
CHANGED
|
@@ -370,7 +370,7 @@ const tzLocal = {
|
|
|
370
370
|
},
|
|
371
371
|
},
|
|
372
372
|
connected_load: {
|
|
373
|
-
// TH1400ZB
|
|
373
|
+
// TH1400ZB and SW2500ZB
|
|
374
374
|
key: ['connected_load'],
|
|
375
375
|
convertSet: async (entity, key, value, meta) => {
|
|
376
376
|
await entity.write('manuSpecificSinope', {connectedLoad: value});
|
|
@@ -413,7 +413,7 @@ const tzLocal = {
|
|
|
413
413
|
if (value >= 0 && value <= 100) {
|
|
414
414
|
await entity.write('manuSpecificSinope', {ledIntensityOn: value});
|
|
415
415
|
}
|
|
416
|
-
return {
|
|
416
|
+
return {state: {led_intensity_on: value}};
|
|
417
417
|
},
|
|
418
418
|
convertGet: async (entity, key, meta) => {
|
|
419
419
|
await entity.read('manuSpecificSinope', ['ledIntensityOn']);
|
|
@@ -426,7 +426,7 @@ const tzLocal = {
|
|
|
426
426
|
if (value >= 0 && value <= 100) {
|
|
427
427
|
await entity.write('manuSpecificSinope', {ledIntensityOff: value});
|
|
428
428
|
}
|
|
429
|
-
return {
|
|
429
|
+
return {state: {led_intensity_off: value}};
|
|
430
430
|
},
|
|
431
431
|
convertGet: async (entity, key, meta) => {
|
|
432
432
|
await entity.read('manuSpecificSinope', ['ledIntensityOff']);
|
|
@@ -476,13 +476,13 @@ const tzLocal = {
|
|
|
476
476
|
if (value >= 0 && value <= 10800) {
|
|
477
477
|
await entity.write('manuSpecificSinope', {dimmerTimmer: value});
|
|
478
478
|
}
|
|
479
|
-
return {
|
|
479
|
+
return {state: {timer_seconds: value}};
|
|
480
480
|
},
|
|
481
481
|
convertGet: async (entity, key, meta) => {
|
|
482
482
|
await entity.read('manuSpecificSinope', ['dimmerTimmer']);
|
|
483
483
|
},
|
|
484
484
|
},
|
|
485
|
-
|
|
485
|
+
keypad_lockout: {
|
|
486
486
|
// SW2500ZB
|
|
487
487
|
key: ['keypad_lockout'],
|
|
488
488
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -991,16 +991,16 @@ module.exports = [
|
|
|
991
991
|
model: 'SW2500ZB',
|
|
992
992
|
vendor: 'Sinopé',
|
|
993
993
|
description: 'Zigbee smart light switch',
|
|
994
|
-
fromZigbee: [fz.on_off,
|
|
994
|
+
fromZigbee: [fz.on_off, fzLocal.sinope, fz.metering],
|
|
995
995
|
toZigbee: [tz.on_off, tzLocal.timer_seconds, tzLocal.led_intensity_on, tzLocal.led_intensity_off,
|
|
996
|
-
tzLocal.led_color_on, tzLocal.led_color_off, tzLocal.
|
|
996
|
+
tzLocal.led_color_on, tzLocal.led_color_off, tzLocal.keypad_lockout, tzLocal.connected_load],
|
|
997
997
|
exposes: [e.switch(),
|
|
998
998
|
e.action(['up_single', 'up_double', 'up_hold', 'down_single', 'down_double', 'down_hold']),
|
|
999
|
-
exposes.numeric('timer_seconds', ea.ALL).withValueMin(0).withValueMax(10800)
|
|
999
|
+
exposes.numeric('timer_seconds', ea.ALL).withUnit('seconds').withValueMin(0).withValueMax(10800)
|
|
1000
1000
|
.withDescription('Automatically turn off load after x seconds'),
|
|
1001
|
-
exposes.numeric('led_intensity_on', ea.ALL).withValueMin(0).withValueMax(100)
|
|
1001
|
+
exposes.numeric('led_intensity_on', ea.ALL).withUnit('%').withValueMin(0).withValueMax(100)
|
|
1002
1002
|
.withDescription('Control status LED intensity when load ON'),
|
|
1003
|
-
exposes.numeric('led_intensity_off', ea.ALL).withValueMin(0).withValueMax(100)
|
|
1003
|
+
exposes.numeric('led_intensity_off', ea.ALL).withUnit('%').withValueMin(0).withValueMax(100)
|
|
1004
1004
|
.withDescription('Control status LED intensity when load OFF'),
|
|
1005
1005
|
exposes.composite('led_color_on', 'led_color_on', ea.SET)
|
|
1006
1006
|
.withFeature(exposes.numeric('r', ea.SET))
|
|
@@ -1013,12 +1013,20 @@ module.exports = [
|
|
|
1013
1013
|
.withFeature(exposes.numeric('b', ea.SET))
|
|
1014
1014
|
.withDescription('Control status LED color when load OFF'),
|
|
1015
1015
|
exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock'])
|
|
1016
|
-
.withDescription('Enables or disables the device’s buttons')
|
|
1016
|
+
.withDescription('Enables or disables the device’s buttons'),
|
|
1017
|
+
exposes.numeric('connected_load', ea.ALL)
|
|
1018
|
+
.withUnit('W').withValueMin(1).withValueMax(1800)
|
|
1019
|
+
.withDescription('Load connected in watt'),
|
|
1020
|
+
e.energy(),
|
|
1021
|
+
],
|
|
1017
1022
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1018
1023
|
const endpoint = device.getEndpoint(1);
|
|
1019
|
-
const binds = ['genOnOff'];
|
|
1024
|
+
const binds = ['genOnOff', 'manuSpecificSinope', 'seMetering'];
|
|
1020
1025
|
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1021
1026
|
await reporting.onOff(endpoint);
|
|
1027
|
+
try {
|
|
1028
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 300, change: [0, 10]});
|
|
1029
|
+
} catch (error) {/* Do nothing*/}
|
|
1022
1030
|
const payload = [{
|
|
1023
1031
|
attribute: 'actionReport',
|
|
1024
1032
|
minimumReportInterval: 0,
|
package/devices/tuya.js
CHANGED
|
@@ -14,8 +14,108 @@ const fzZosung = zosung.fzZosung;
|
|
|
14
14
|
const tzZosung = zosung.tzZosung;
|
|
15
15
|
const ez = zosung.presetsZosung;
|
|
16
16
|
const globalStore = require('../lib/store');
|
|
17
|
+
const {ColorMode, colorModeLookup} = require('../lib/constants');
|
|
17
18
|
|
|
18
19
|
const tzLocal = {
|
|
20
|
+
led_control: {
|
|
21
|
+
key: ['brightness', 'color', 'color_temp', 'transition'],
|
|
22
|
+
options: [exposes.options.color_sync()],
|
|
23
|
+
convertSet: async (entity, _key, _value, meta) => {
|
|
24
|
+
const newState = {};
|
|
25
|
+
|
|
26
|
+
// The color mode encodes whether the light is using its white LEDs or its color LEDs
|
|
27
|
+
let colorMode = meta.state.color_mode ?? colorModeLookup[ColorMode.ColorTemp];
|
|
28
|
+
|
|
29
|
+
// Color mode switching is done by setting color temperature (switch to white LEDs) or setting color (switch
|
|
30
|
+
// to color LEDs)
|
|
31
|
+
if ('color_temp' in meta.message) colorMode = colorModeLookup[ColorMode.ColorTemp];
|
|
32
|
+
if ('color' in meta.message) colorMode = colorModeLookup[ColorMode.HS];
|
|
33
|
+
|
|
34
|
+
if (colorMode != meta.state.color_mode) {
|
|
35
|
+
newState.color_mode = colorMode;
|
|
36
|
+
|
|
37
|
+
// To switch between white mode and color mode, we have to send a special command:
|
|
38
|
+
const rgbMode = (colorMode == colorModeLookup[ColorMode.HS]);
|
|
39
|
+
await entity.command('lightingColorCtrl', 'tuyaRgbMode', {enable: rgbMode}, {}, {disableDefaultResponse: true});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// A transition time of 0 would be treated as about 1 second, probably some kind of fallback/default
|
|
43
|
+
// transition time, so for "no transition" we use 1 (tenth of a second).
|
|
44
|
+
const transtime = 'transition' in meta.message ? meta.message.transition * 10 : 1;
|
|
45
|
+
|
|
46
|
+
if (colorMode == colorModeLookup[ColorMode.ColorTemp]) {
|
|
47
|
+
if ('brightness' in meta.message) {
|
|
48
|
+
const zclData = {level: Number(meta.message.brightness), transtime};
|
|
49
|
+
await entity.command('genLevelCtrl', 'moveToLevel', zclData, utils.getOptions(meta.mapped, entity));
|
|
50
|
+
newState.brightness = meta.message.brightness;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if ('color_temp' in meta.message) {
|
|
54
|
+
const zclData = {colortemp: meta.message.color_temp, transtime: transtime};
|
|
55
|
+
await entity.command('lightingColorCtrl', 'moveToColorTemp', zclData, utils.getOptions(meta.mapped, entity));
|
|
56
|
+
newState.color_temp = meta.message.color_temp;
|
|
57
|
+
}
|
|
58
|
+
} else if (colorMode == colorModeLookup[ColorMode.HS]) {
|
|
59
|
+
if ('brightness' in meta.message || 'color' in meta.message) {
|
|
60
|
+
// We ignore the brightness of the color and instead use the overall brightness setting of the lamp
|
|
61
|
+
// for the brightness because I think that's the expected behavior and also because the color
|
|
62
|
+
// conversion below always returns 100 as brightness ("value") even for very dark colors, except
|
|
63
|
+
// when the color is completely black/zero.
|
|
64
|
+
|
|
65
|
+
// Load current state or defaults
|
|
66
|
+
const newSettings = {
|
|
67
|
+
brightness: meta.state.brightness ?? 254, // full brightness
|
|
68
|
+
hue: (meta.state.color ?? {}).hue ?? 0, // red
|
|
69
|
+
saturation: (meta.state.color ?? {}).saturation ?? 100, // full saturation
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Apply changes
|
|
73
|
+
if ('brightness' in meta.message) {
|
|
74
|
+
newSettings.brightness = meta.message.brightness;
|
|
75
|
+
newState.brightness = meta.message.brightness;
|
|
76
|
+
}
|
|
77
|
+
if ('color' in meta.message) {
|
|
78
|
+
// The Z2M UI sends `{ hex:'#xxxxxx' }`.
|
|
79
|
+
// Home Assistant sends `{ h: xxx, s: xxx }`.
|
|
80
|
+
// We convert the former into the latter.
|
|
81
|
+
const c = libColor.Color.fromConverterArg(meta.message.color);
|
|
82
|
+
if (c.isRGB()) {
|
|
83
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/13421#issuecomment-1426044963
|
|
84
|
+
c.hsv = c.rgb.gammaCorrected().toXY().toHSV();
|
|
85
|
+
}
|
|
86
|
+
const color = c.hsv;
|
|
87
|
+
|
|
88
|
+
newSettings.hue = color.hue;
|
|
89
|
+
newSettings.saturation = color.saturation;
|
|
90
|
+
|
|
91
|
+
newState.color = {
|
|
92
|
+
hue: color.hue,
|
|
93
|
+
saturation: color.saturation,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Convert to device specific format and send
|
|
98
|
+
const zclData = {
|
|
99
|
+
brightness: utils.mapNumberRange(newSettings.brightness, 0, 254, 0, 1000),
|
|
100
|
+
hue: newSettings.hue,
|
|
101
|
+
saturation: utils.mapNumberRange(newSettings.saturation, 0, 100, 0, 1000),
|
|
102
|
+
};
|
|
103
|
+
// This command doesn't support a transition time
|
|
104
|
+
await entity.command('lightingColorCtrl', 'tuyaMoveToHueAndSaturationBrightness2', zclData,
|
|
105
|
+
utils.getOptions(meta.mapped, entity));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// If we're in white mode, calculate a matching display color for the set color temperature. This also kind
|
|
110
|
+
// of works in the other direction.
|
|
111
|
+
Object.assign(newState, libColor.syncColorState(newState, meta.state, entity, meta.options, meta.logger));
|
|
112
|
+
|
|
113
|
+
return {state: newState};
|
|
114
|
+
},
|
|
115
|
+
convertGet: async (entity, key, meta) => {
|
|
116
|
+
await entity.read('lightingColorCtrl', ['currentHue', 'currentSaturation', 'currentLevel', 'tuyaRgbMode', 'colorTemperature']);
|
|
117
|
+
},
|
|
118
|
+
},
|
|
19
119
|
TS110E_options: {
|
|
20
120
|
key: ['min_brightness', 'max_brightness', 'light_type', 'switch_type'],
|
|
21
121
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -338,6 +438,79 @@ const tzLocal = {
|
|
|
338
438
|
}
|
|
339
439
|
},
|
|
340
440
|
},
|
|
441
|
+
TS011F_threshold: {
|
|
442
|
+
key: [
|
|
443
|
+
'temperature_threshold', 'temperature_breaker', 'power_threshold', 'power_breaker',
|
|
444
|
+
'over_current_threshold', 'over_current_breaker', 'over_voltage_threshold', 'over_voltage_breaker',
|
|
445
|
+
'under_voltage_threshold', 'under_voltage_breaker',
|
|
446
|
+
],
|
|
447
|
+
convertSet: async (entity, key, value, meta) => {
|
|
448
|
+
switch (key) {
|
|
449
|
+
case 'temperature_threshold': {
|
|
450
|
+
const state = meta.state['temperature_breaker'];
|
|
451
|
+
const buf = Buffer.from([5, {'ON': 1, 'OFF': 0}[state], 0, value]);
|
|
452
|
+
await entity.command('manuSpecificTuya_3', 'setOptions2', {data: buf});
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
case 'temperature_breaker': {
|
|
456
|
+
const threshold = meta.state['temperature_threshold'];
|
|
457
|
+
const buf = Buffer.from([5, {'ON': 1, 'OFF': 0}[value], 0, threshold]);
|
|
458
|
+
await entity.command('manuSpecificTuya_3', 'setOptions2', {data: buf});
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
case 'power_threshold': {
|
|
462
|
+
const state = meta.state['power_breaker'];
|
|
463
|
+
const buf = Buffer.from([7, {'ON': 1, 'OFF': 0}[state], 0, value]);
|
|
464
|
+
await entity.command('manuSpecificTuya_3', 'setOptions2', {data: buf});
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
case 'power_breaker': {
|
|
468
|
+
const threshold = meta.state['power_threshold'];
|
|
469
|
+
const buf = Buffer.from([7, {'ON': 1, 'OFF': 0}[value], 0, threshold]);
|
|
470
|
+
await entity.command('manuSpecificTuya_3', 'setOptions2', {data: buf});
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
473
|
+
case 'over_current_threshold': {
|
|
474
|
+
const state = meta.state['over_current_breaker'];
|
|
475
|
+
const buf = Buffer.from([1, {'ON': 1, 'OFF': 0}[state], 0, value]);
|
|
476
|
+
await entity.command('manuSpecificTuya_3', 'setOptions3', {data: buf});
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
case 'over_current_breaker': {
|
|
480
|
+
const threshold = meta.state['over_current_threshold'];
|
|
481
|
+
const buf = Buffer.from([1, {'ON': 1, 'OFF': 0}[value], 0, threshold]);
|
|
482
|
+
await entity.command('manuSpecificTuya_3', 'setOptions3', {data: buf});
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
case 'over_voltage_threshold': {
|
|
486
|
+
const state = meta.state['over_voltage_breaker'];
|
|
487
|
+
const buf = Buffer.from([3, {'ON': 1, 'OFF': 0}[state], 0, value]);
|
|
488
|
+
await entity.command('manuSpecificTuya_3', 'setOptions3', {data: buf});
|
|
489
|
+
break;
|
|
490
|
+
}
|
|
491
|
+
case 'over_voltage_breaker': {
|
|
492
|
+
const threshold = meta.state['over_voltage_threshold'];
|
|
493
|
+
const buf = Buffer.from([3, {'ON': 1, 'OFF': 0}[value], 0, threshold]);
|
|
494
|
+
await entity.command('manuSpecificTuya_3', 'setOptions3', {data: buf});
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
case 'under_voltage_threshold': {
|
|
498
|
+
const state = meta.state['under_voltage_breaker'];
|
|
499
|
+
const buf = Buffer.from([4, {'ON': 1, 'OFF': 0}[state], 0, value]);
|
|
500
|
+
await entity.command('manuSpecificTuya_3', 'setOptions3', {data: buf});
|
|
501
|
+
break;
|
|
502
|
+
}
|
|
503
|
+
case 'under_voltage_breaker': {
|
|
504
|
+
const threshold = meta.state['under_voltage_threshold'];
|
|
505
|
+
const buf = Buffer.from([4, {'ON': 1, 'OFF': 0}[value], 0, threshold]);
|
|
506
|
+
await entity.command('manuSpecificTuya_3', 'setOptions3', {data: buf});
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
default: // Unknown key
|
|
510
|
+
meta.logger.warn(`Unhandled key ${key}`);
|
|
511
|
+
}
|
|
512
|
+
},
|
|
513
|
+
},
|
|
341
514
|
};
|
|
342
515
|
|
|
343
516
|
const fzLocal = {
|
|
@@ -739,6 +912,46 @@ const fzLocal = {
|
|
|
739
912
|
return result;
|
|
740
913
|
},
|
|
741
914
|
},
|
|
915
|
+
TS011F_threshold: {
|
|
916
|
+
cluster: 'manuSpecificTuya_3',
|
|
917
|
+
type: 'raw',
|
|
918
|
+
convert: (model, msg, publish, options, meta) => {
|
|
919
|
+
const splitToAttributes = (value) => {
|
|
920
|
+
const result = {};
|
|
921
|
+
const len = value.length;
|
|
922
|
+
let i = 0;
|
|
923
|
+
while (i < len) {
|
|
924
|
+
const key = value.readUInt8(i);
|
|
925
|
+
result[key] = [value.readUInt8(i+1), value.readUInt16BE(i+2)];
|
|
926
|
+
i += 4;
|
|
927
|
+
}
|
|
928
|
+
return result;
|
|
929
|
+
};
|
|
930
|
+
const lookup = {0: 'OFF', 1: 'ON'};
|
|
931
|
+
const command = msg.data[2];
|
|
932
|
+
const data = msg.data.slice(3);
|
|
933
|
+
if (command == 0xE6) {
|
|
934
|
+
const value = splitToAttributes(data);
|
|
935
|
+
return {
|
|
936
|
+
'temperature_threshold': value[0x05][1],
|
|
937
|
+
'temperature_breaker': lookup[value[0x05][0]],
|
|
938
|
+
'power_threshold': value[0x07][1],
|
|
939
|
+
'power_breaker': lookup[value[0x07][0]],
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
if (command == 0xE7) {
|
|
943
|
+
const value = splitToAttributes(data);
|
|
944
|
+
return {
|
|
945
|
+
'over_current_threshold': value[0x01][1],
|
|
946
|
+
'over_current_breaker': lookup[value[0x01][0]],
|
|
947
|
+
'over_voltage_threshold': value[0x03][1],
|
|
948
|
+
'over_voltage_breaker': lookup[value[0x03][0]],
|
|
949
|
+
'under_voltage_threshold': value[0x04][1],
|
|
950
|
+
'under_voltage_breaker': lookup[value[0x04][0]],
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
},
|
|
954
|
+
},
|
|
742
955
|
};
|
|
743
956
|
|
|
744
957
|
module.exports = [
|
|
@@ -1016,7 +1229,7 @@ module.exports = [
|
|
|
1016
1229
|
},
|
|
1017
1230
|
{
|
|
1018
1231
|
zigbeeModel: ['TS0505B'],
|
|
1019
|
-
model: '
|
|
1232
|
+
model: 'TS0505B_1',
|
|
1020
1233
|
vendor: 'TuYa',
|
|
1021
1234
|
description: 'Zigbee RGB+CCT light',
|
|
1022
1235
|
whiteLabel: [{vendor: 'Mercator Ikuü', model: 'SMD4106W-RGB-ZB'},
|
|
@@ -1055,6 +1268,22 @@ module.exports = [
|
|
|
1055
1268
|
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
|
1056
1269
|
},
|
|
1057
1270
|
},
|
|
1271
|
+
{
|
|
1272
|
+
fingerprint: tuya.fingerprint('TS0505B', ['_TZ3210_c0s1xloa', '_TZ3210_iystcadi']),
|
|
1273
|
+
model: 'TS0505B_2',
|
|
1274
|
+
vendor: 'TuYa',
|
|
1275
|
+
description: 'Zigbee RGB+CCT light',
|
|
1276
|
+
whiteLabel: [
|
|
1277
|
+
tuya.whitelabel('Lidl', '14149505L/14149506L_2', 'Livarno Lux light bar RGB+CCT (black/white)', ['_TZ3210_iystcadi']),
|
|
1278
|
+
tuya.whitelabel('Lidl', '399629_2110', 'Livarno Lux Ceiling Panel RGB+CCT', ['_TZ3210_c0s1xloa']),
|
|
1279
|
+
],
|
|
1280
|
+
toZigbee: [tz.on_off, tzLocal.led_control],
|
|
1281
|
+
fromZigbee: [fz.on_off, fz.tuya_led_controller, fz.brightness, fz.ignore_basic_report],
|
|
1282
|
+
exposes: [e.light_brightness_colortemp_colorhs([153, 500]).removeFeature('color_temp_startup')],
|
|
1283
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1284
|
+
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
|
1285
|
+
},
|
|
1286
|
+
},
|
|
1058
1287
|
{
|
|
1059
1288
|
zigbeeModel: ['TS0503B'],
|
|
1060
1289
|
model: 'TS0503B',
|
|
@@ -1175,13 +1404,15 @@ module.exports = [
|
|
|
1175
1404
|
{modelID: 'TS0202', manufacturerName: '_TZ3000_h4wnrtck'},
|
|
1176
1405
|
{modelID: 'TS0202', manufacturerName: '_TZ3000_sr0vaafi'},
|
|
1177
1406
|
{modelID: 'WHD02', manufacturerName: '_TZ3000_hktqahrq'},
|
|
1407
|
+
{modelID: 'TS0202', manufacturerName: '_TZ3040_wqmtjsyk'},
|
|
1178
1408
|
],
|
|
1179
1409
|
model: 'TS0202',
|
|
1180
1410
|
vendor: 'TuYa',
|
|
1181
1411
|
description: 'Motion sensor',
|
|
1182
1412
|
whiteLabel: [{vendor: 'Mercator Ikuü', model: 'SMA02P'},
|
|
1183
1413
|
{vendor: 'TuYa', model: 'TY-ZPR06'},
|
|
1184
|
-
{vendor: 'Tesla Smart', model: 'TS0202'}
|
|
1414
|
+
{vendor: 'Tesla Smart', model: 'TS0202'},
|
|
1415
|
+
tuya.whitelabel('MiBoxer', 'PIR1-ZB', 'PIR Sensor', ['_TZ3040_wqmtjsyk'])],
|
|
1185
1416
|
fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_occupancy_alarm_1_report],
|
|
1186
1417
|
toZigbee: [],
|
|
1187
1418
|
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
|
|
@@ -2128,11 +2359,14 @@ module.exports = [
|
|
|
2128
2359
|
},
|
|
2129
2360
|
{
|
|
2130
2361
|
fingerprint: tuya.fingerprint('TS0002', ['_TZ3000_01gpyda5', '_TZ3000_bvrlqyj7', '_TZ3000_7ed9cqgi',
|
|
2131
|
-
'_TZ3000_zmy4lslw', '_TZ3000_ruxexjfz']),
|
|
2362
|
+
'_TZ3000_zmy4lslw', '_TZ3000_ruxexjfz', '_TZ3000_4xfqlgqo']),
|
|
2132
2363
|
model: 'TS0002_switch_module',
|
|
2133
2364
|
vendor: 'TuYa',
|
|
2134
2365
|
description: '2 gang switch module',
|
|
2135
|
-
whiteLabel: [
|
|
2366
|
+
whiteLabel: [
|
|
2367
|
+
{vendor: 'OXT', model: 'SWTZ22'}, {vendor: 'Nous', model: 'L13Z'},
|
|
2368
|
+
tuya.whitelabel('pcblab.io', 'RR620ZB', '2 gang Zigbee switch module', ['_TZ3000_4xfqlgqo']),
|
|
2369
|
+
],
|
|
2136
2370
|
extend: tuya.extend.switch({switchType: true, endpoints: ['l1', 'l2']}),
|
|
2137
2371
|
endpoint: (device) => {
|
|
2138
2372
|
return {'l1': 1, 'l2': 2};
|
|
@@ -2411,8 +2645,8 @@ module.exports = [
|
|
|
2411
2645
|
exposes.enum('motor_direction', ea.STATE_SET, ['normal', 'reversed']).withDescription('Set the motor direction'),
|
|
2412
2646
|
exposes.numeric('motor_speed', ea.STATE_SET).withValueMin(0).withValueMax(255).withDescription('Motor speed').withUnit('rpm'),
|
|
2413
2647
|
exposes.enum('opening_mode', ea.STATE_SET, ['tilt', 'lift']).withDescription('Opening mode'),
|
|
2414
|
-
exposes.enum('set_upper_limit', ea.
|
|
2415
|
-
exposes.enum('set_bottom_limit', ea.
|
|
2648
|
+
exposes.enum('set_upper_limit', ea.STATE_SET, ['SET']).withDescription('Set the upper limit, to reset limits use factory_reset'),
|
|
2649
|
+
exposes.enum('set_bottom_limit', ea.STATE_SET, ['SET']).withDescription('Set the bottom limit, to reset limits use factory_reset'),
|
|
2416
2650
|
exposes.binary('factory_reset', ea.STATE_SET, true, false).withDescription('Factory reset the device'),
|
|
2417
2651
|
],
|
|
2418
2652
|
whiteLabel: [
|
|
@@ -3075,14 +3309,13 @@ module.exports = [
|
|
|
3075
3309
|
whiteLabel: [{vendor: 'Hiking', model: 'DDS238-2'}, {vendor: 'TuYa', model: 'RC-MCB'}],
|
|
3076
3310
|
},
|
|
3077
3311
|
{
|
|
3078
|
-
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lsanae15']),
|
|
3312
|
+
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lsanae15', '_TZE204_lsanae15']),
|
|
3079
3313
|
model: 'TS0601_din_2',
|
|
3080
3314
|
vendor: 'TuYa',
|
|
3081
3315
|
description: 'Zigbee DIN energy meter',
|
|
3082
3316
|
fromZigbee: [tuya.fz.datapoints],
|
|
3083
3317
|
toZigbee: [tuya.tz.datapoints],
|
|
3084
3318
|
configure: tuya.configureMagicPacket,
|
|
3085
|
-
whiteLabel: [{vendor: 'XOCA', model: 'DAC2161C'}],
|
|
3086
3319
|
exposes: [tuya.exposes.switch(), e.energy(), e.power(), e.voltage(), e.current(),
|
|
3087
3320
|
exposes.enum('fault', ea.STATE, ['clear', 'over_current_threshold', 'over_power_threshold',
|
|
3088
3321
|
'over_voltage threshold', 'wrong_frequency_threshold']).withDescription('Fault status of the device (clear = nothing)'),
|
|
@@ -3121,6 +3354,9 @@ module.exports = [
|
|
|
3121
3354
|
[24, null, null], // Forward Energy T4 - don't know what this
|
|
3122
3355
|
],
|
|
3123
3356
|
},
|
|
3357
|
+
whiteLabel: [
|
|
3358
|
+
tuya.whitelabel('MatSee Plus', 'DAC2161C', 'Smart Zigbee energy meter 80A din rail', ['_TZE200_lsanae15', '_TZE204_lsanae15']),
|
|
3359
|
+
],
|
|
3124
3360
|
},
|
|
3125
3361
|
{
|
|
3126
3362
|
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_rhblgy0z']),
|
|
@@ -4504,4 +4740,57 @@ module.exports = [
|
|
|
4504
4740
|
toZigbee: [],
|
|
4505
4741
|
configure: tuya.configureMagicPacket,
|
|
4506
4742
|
},
|
|
4743
|
+
{
|
|
4744
|
+
fingerprint: tuya.fingerprint('TS011F', ['_TZ3000_cayepv1a']),
|
|
4745
|
+
model: 'TS011F_with_threshold',
|
|
4746
|
+
description: 'Din rail switch with power monitoring and threshold settings',
|
|
4747
|
+
vendor: 'TuYa',
|
|
4748
|
+
ota: ota.zigbeeOTA,
|
|
4749
|
+
extend: tuya.extend.switch({
|
|
4750
|
+
electricalMeasurements: true, electricalMeasurementsFzConverter: fzLocal.TS011F_electrical_measurement,
|
|
4751
|
+
powerOutageMemory: true, indicatorMode: true,
|
|
4752
|
+
fromZigbee: [fz.temperature, fzLocal.TS011F_threshold],
|
|
4753
|
+
toZigbee: [tzLocal.TS011F_threshold],
|
|
4754
|
+
exposes: [
|
|
4755
|
+
e.temperature(),
|
|
4756
|
+
exposes.numeric('temperature_threshold', ea.STATE_SET).withValueMin(40).withValueMax(100).withValueStep(1).withUnit('*C')
|
|
4757
|
+
.withDescription('High temperature threshold'),
|
|
4758
|
+
exposes.binary('temperature_breaker', ea.STATE_SET, 'ON', 'OFF')
|
|
4759
|
+
.withDescription('High temperature breaker'),
|
|
4760
|
+
exposes.numeric('power_threshold', ea.STATE_SET).withValueMin(1).withValueMax(26).withValueStep(1).withUnit('kW')
|
|
4761
|
+
.withDescription('High power threshold'),
|
|
4762
|
+
exposes.binary('power_breaker', ea.STATE_SET, 'ON', 'OFF')
|
|
4763
|
+
.withDescription('High power breaker'),
|
|
4764
|
+
exposes.numeric('over_current_threshold', ea.STATE_SET).withValueMin(1).withValueMax(64).withValueStep(1).withUnit('A')
|
|
4765
|
+
.withDescription('Over-current threshold'),
|
|
4766
|
+
exposes.binary('over_current_breaker', ea.STATE_SET, 'ON', 'OFF')
|
|
4767
|
+
.withDescription('Over-current breaker'),
|
|
4768
|
+
exposes.numeric('over_voltage_threshold', ea.STATE_SET).withValueMin(220).withValueMax(260).withValueStep(1).withUnit('V')
|
|
4769
|
+
.withDescription('Over-voltage threshold'),
|
|
4770
|
+
exposes.binary('over_voltage_breaker', ea.STATE_SET, 'ON', 'OFF')
|
|
4771
|
+
.withDescription('Over-voltage breaker'),
|
|
4772
|
+
exposes.numeric('under_voltage_threshold', ea.STATE_SET).withValueMin(76).withValueMax(240).withValueStep(1).withUnit('V')
|
|
4773
|
+
.withDescription('Under-voltage threshold'),
|
|
4774
|
+
exposes.binary('under_voltage_breaker', ea.STATE_SET, 'ON', 'OFF')
|
|
4775
|
+
.withDescription('Under-voltage breaker'),
|
|
4776
|
+
],
|
|
4777
|
+
}),
|
|
4778
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
4779
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
4780
|
+
const endpoint = device.getEndpoint(1);
|
|
4781
|
+
endpoint.command('genBasic', 'tuyaSetup', {});
|
|
4782
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement']);
|
|
4783
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
4784
|
+
await reporting.rmsVoltage(endpoint, {change: 5});
|
|
4785
|
+
await reporting.rmsCurrent(endpoint, {change: 50});
|
|
4786
|
+
await reporting.activePower(endpoint, {change: 10});
|
|
4787
|
+
await reporting.currentSummDelivered(endpoint);
|
|
4788
|
+
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
|
|
4789
|
+
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
|
|
4790
|
+
device.save();
|
|
4791
|
+
},
|
|
4792
|
+
whiteLabel: [
|
|
4793
|
+
tuya.whitelabel('TONGOU', 'TO-Q-SY2-163JZT', 'Smart circuit breaker', ['_TZ3000_cayepv1a']),
|
|
4794
|
+
],
|
|
4795
|
+
},
|
|
4507
4796
|
];
|
package/lib/tuya.js
CHANGED
|
@@ -1932,6 +1932,9 @@ const tuyaExtend = {
|
|
|
1932
1932
|
toZigbee.push(tuyaTz.child_lock);
|
|
1933
1933
|
exposes.push(e.child_lock());
|
|
1934
1934
|
}
|
|
1935
|
+
if (options.fromZigbee) fromZigbee.push(...options.fromZigbee);
|
|
1936
|
+
if (options.toZigbee) toZigbee.push(...options.toZigbee);
|
|
1937
|
+
if (options.exposes) exposes.push(...options.exposes);
|
|
1935
1938
|
return {exposes, fromZigbee, toZigbee};
|
|
1936
1939
|
},
|
|
1937
1940
|
light_onoff_brightness_colortemp_color: (options={}) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.99",
|
|
4
4
|
"description": "Collection of device converters to be used with zigbee-herdsman",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/Koenkk/zigbee-herdsman-converters",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"axios": "^1.
|
|
37
|
+
"axios": "^1.4.0",
|
|
38
38
|
"buffer-crc32": "^0.2.13",
|
|
39
39
|
"https-proxy-agent": "^5.0.1",
|
|
40
40
|
"tar-stream": "^3.0.0",
|
|
41
|
-
"zigbee-herdsman": "^0.14.
|
|
41
|
+
"zigbee-herdsman": "^0.14.110"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|