zigbee-herdsman-converters 14.0.340 → 14.0.344
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 +36 -56
- package/converters/toZigbee.js +10 -10
- package/devices/custom_devices_diy.js +21 -0
- package/devices/ewelink.js +15 -0
- package/devices/heiman.js +4 -2
- package/devices/ikea.js +19 -52
- package/devices/lidl.js +1 -1
- package/devices/neo.js +3 -3
- package/devices/nue_3a.js +13 -1
- package/devices/osram.js +2 -2
- package/devices/philips.js +19 -1
- package/devices/sonoff.js +1 -1
- package/devices/tuya.js +25 -9
- package/lib/exposes.js +1 -1
- package/lib/legacy.js +1 -1
- package/lib/tuya.js +48 -44
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -1644,7 +1644,7 @@ const converters = {
|
|
|
1644
1644
|
},
|
|
1645
1645
|
moes_105_dimmer: {
|
|
1646
1646
|
cluster: 'manuSpecificTuya',
|
|
1647
|
-
type: ['
|
|
1647
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
1648
1648
|
convert: (model, msg, publish, options, meta) => {
|
|
1649
1649
|
const multiEndpoint = model.meta && model.meta.multiEndpoint;
|
|
1650
1650
|
const dp = msg.data.dp;
|
|
@@ -1738,7 +1738,7 @@ const converters = {
|
|
|
1738
1738
|
},
|
|
1739
1739
|
tuya_temperature_humidity_sensor: {
|
|
1740
1740
|
cluster: 'manuSpecificTuya',
|
|
1741
|
-
type: ['
|
|
1741
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
1742
1742
|
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
|
|
1743
1743
|
exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
|
|
1744
1744
|
convert: (model, msg, publish, options, meta) => {
|
|
@@ -1759,7 +1759,7 @@ const converters = {
|
|
|
1759
1759
|
},
|
|
1760
1760
|
tuya_illuminance_temperature_humidity_sensor: {
|
|
1761
1761
|
cluster: 'manuSpecificTuya',
|
|
1762
|
-
type: ['
|
|
1762
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
1763
1763
|
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
|
|
1764
1764
|
exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
|
|
1765
1765
|
convert: (model, msg, publish, options, meta) => {
|
|
@@ -1811,7 +1811,7 @@ const converters = {
|
|
|
1811
1811
|
},
|
|
1812
1812
|
tuya_thermostat_weekly_schedule: {
|
|
1813
1813
|
cluster: 'manuSpecificTuya',
|
|
1814
|
-
type: ['
|
|
1814
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
1815
1815
|
convert: (model, msg, publish, options, meta) => {
|
|
1816
1816
|
const dp = msg.data.dp;
|
|
1817
1817
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -1860,7 +1860,7 @@ const converters = {
|
|
|
1860
1860
|
},
|
|
1861
1861
|
hy_thermostat: {
|
|
1862
1862
|
cluster: 'manuSpecificTuya',
|
|
1863
|
-
type: ['
|
|
1863
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
1864
1864
|
convert: (model, msg, publish, options, meta) => {
|
|
1865
1865
|
const dp = msg.data.dp;
|
|
1866
1866
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -1990,7 +1990,7 @@ const converters = {
|
|
|
1990
1990
|
},
|
|
1991
1991
|
tuya_cover: {
|
|
1992
1992
|
cluster: 'manuSpecificTuya',
|
|
1993
|
-
type: ['
|
|
1993
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
1994
1994
|
options: [exposes.options.invert_cover()],
|
|
1995
1995
|
convert: (model, msg, publish, options, meta) => {
|
|
1996
1996
|
// Protocol description
|
|
@@ -2313,7 +2313,7 @@ const converters = {
|
|
|
2313
2313
|
},
|
|
2314
2314
|
neo_nas_pd07: {
|
|
2315
2315
|
cluster: 'manuSpecificTuya',
|
|
2316
|
-
type: ['
|
|
2316
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
2317
2317
|
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
|
|
2318
2318
|
exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
|
|
2319
2319
|
convert: (model, msg, publish, options, meta) => {
|
|
@@ -2339,7 +2339,7 @@ const converters = {
|
|
|
2339
2339
|
},
|
|
2340
2340
|
neo_t_h_alarm: {
|
|
2341
2341
|
cluster: 'manuSpecificTuya',
|
|
2342
|
-
type: ['
|
|
2342
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
2343
2343
|
convert: (model, msg, publish, options, meta) => {
|
|
2344
2344
|
const dp = msg.data.dp;
|
|
2345
2345
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -2484,7 +2484,7 @@ const converters = {
|
|
|
2484
2484
|
},
|
|
2485
2485
|
tuya_water_leak: {
|
|
2486
2486
|
cluster: 'manuSpecificTuya',
|
|
2487
|
-
type: '
|
|
2487
|
+
type: 'commandDataReport',
|
|
2488
2488
|
convert: (model, msg, publish, options, meta) => {
|
|
2489
2489
|
if (msg.data.dp === tuya.dataPoints.waterLeak) {
|
|
2490
2490
|
return {water_leak: tuya.getDataValue(msg.data.datatype, msg.data.data)};
|
|
@@ -2727,25 +2727,6 @@ const converters = {
|
|
|
2727
2727
|
}
|
|
2728
2728
|
},
|
|
2729
2729
|
},
|
|
2730
|
-
hy_set_time_request: {
|
|
2731
|
-
cluster: 'manuSpecificTuya',
|
|
2732
|
-
type: ['commandSetTimeRequest'],
|
|
2733
|
-
convert: async (model, msg, publish, options, meta) => {
|
|
2734
|
-
const OneJanuary2000 = new Date('January 01, 2000 00:00:00 UTC+00:00').getTime();
|
|
2735
|
-
const currentTime = new Date().getTime();
|
|
2736
|
-
const utcTime = Math.round((currentTime - OneJanuary2000) / 1000);
|
|
2737
|
-
const localTime = Math.round(currentTime / 1000) - (new Date()).getTimezoneOffset() * 60;
|
|
2738
|
-
const endpoint = msg.endpoint;
|
|
2739
|
-
const payload = {
|
|
2740
|
-
payloadSize: 8,
|
|
2741
|
-
payload: [
|
|
2742
|
-
...tuya.convertDecimalValueTo4ByteHexArray(utcTime),
|
|
2743
|
-
...tuya.convertDecimalValueTo4ByteHexArray(localTime),
|
|
2744
|
-
],
|
|
2745
|
-
};
|
|
2746
|
-
await endpoint.command('manuSpecificTuya', 'setTime', payload, {});
|
|
2747
|
-
},
|
|
2748
|
-
},
|
|
2749
2730
|
ptvo_switch_uart: {
|
|
2750
2731
|
cluster: 'genMultistateValue',
|
|
2751
2732
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -2867,7 +2848,7 @@ const converters = {
|
|
|
2867
2848
|
},
|
|
2868
2849
|
silvercrest_smart_led_string: {
|
|
2869
2850
|
cluster: 'manuSpecificTuya',
|
|
2870
|
-
type: ['
|
|
2851
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
2871
2852
|
convert: (model, msg, publish, options, meta) => {
|
|
2872
2853
|
const dp = msg.data.dp;
|
|
2873
2854
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -3487,7 +3468,7 @@ const converters = {
|
|
|
3487
3468
|
},
|
|
3488
3469
|
moes_thermostat: {
|
|
3489
3470
|
cluster: 'manuSpecificTuya',
|
|
3490
|
-
type: ['
|
|
3471
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
3491
3472
|
convert: (model, msg, publish, options, meta) => {
|
|
3492
3473
|
const dp = msg.data.dp;
|
|
3493
3474
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -3560,7 +3541,7 @@ const converters = {
|
|
|
3560
3541
|
},
|
|
3561
3542
|
moesS_thermostat: {
|
|
3562
3543
|
cluster: 'manuSpecificTuya',
|
|
3563
|
-
type: ['
|
|
3544
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
3564
3545
|
convert: (model, msg, publish, options, meta) => {
|
|
3565
3546
|
const dp = msg.data.dp; // First we get the data point ID
|
|
3566
3547
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -3620,7 +3601,7 @@ const converters = {
|
|
|
3620
3601
|
},
|
|
3621
3602
|
tvtwo_thermostat: {
|
|
3622
3603
|
cluster: 'manuSpecificTuya',
|
|
3623
|
-
type: ['
|
|
3604
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
3624
3605
|
convert: (model, msg, publish, options, meta) => {
|
|
3625
3606
|
const dp = msg.data.dp;
|
|
3626
3607
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -3771,7 +3752,7 @@ const converters = {
|
|
|
3771
3752
|
},
|
|
3772
3753
|
haozee_thermostat: {
|
|
3773
3754
|
cluster: 'manuSpecificTuya',
|
|
3774
|
-
type: ['
|
|
3755
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
3775
3756
|
convert: (model, msg, publish, options, meta) => {
|
|
3776
3757
|
const dp = msg.data.dp; // First we get the data point ID
|
|
3777
3758
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -3886,7 +3867,7 @@ const converters = {
|
|
|
3886
3867
|
},
|
|
3887
3868
|
tuya_air_quality: {
|
|
3888
3869
|
cluster: 'manuSpecificTuya',
|
|
3889
|
-
type: ['
|
|
3870
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
3890
3871
|
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
|
|
3891
3872
|
exposes.options.precision('humidity'), exposes.options.calibration('humidity'),
|
|
3892
3873
|
exposes.options.precision('co2'), exposes.options.calibration('co2'),
|
|
@@ -3915,7 +3896,7 @@ const converters = {
|
|
|
3915
3896
|
},
|
|
3916
3897
|
saswell_thermostat: {
|
|
3917
3898
|
cluster: 'manuSpecificTuya',
|
|
3918
|
-
type: ['
|
|
3899
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
3919
3900
|
convert: (model, msg, publish, options, meta) => {
|
|
3920
3901
|
const dp = msg.data.dp;
|
|
3921
3902
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -4036,7 +4017,7 @@ const converters = {
|
|
|
4036
4017
|
},
|
|
4037
4018
|
etop_thermostat: {
|
|
4038
4019
|
cluster: 'manuSpecificTuya',
|
|
4039
|
-
type: ['
|
|
4020
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
4040
4021
|
convert: (model, msg, publish, options, meta) => {
|
|
4041
4022
|
const dp = msg.data.dp;
|
|
4042
4023
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -4085,7 +4066,7 @@ const converters = {
|
|
|
4085
4066
|
},
|
|
4086
4067
|
tuya_thermostat: {
|
|
4087
4068
|
cluster: 'manuSpecificTuya',
|
|
4088
|
-
type: ['
|
|
4069
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
4089
4070
|
convert: (model, msg, publish, options, meta) => {
|
|
4090
4071
|
const dp = msg.data.dp;
|
|
4091
4072
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -4191,7 +4172,7 @@ const converters = {
|
|
|
4191
4172
|
},
|
|
4192
4173
|
tuya_dimmer: {
|
|
4193
4174
|
cluster: 'manuSpecificTuya',
|
|
4194
|
-
type: ['
|
|
4175
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
4195
4176
|
convert: (model, msg, publish, options, meta) => {
|
|
4196
4177
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
4197
4178
|
if (msg.data.dp === tuya.dataPoints.state) {
|
|
@@ -4208,7 +4189,7 @@ const converters = {
|
|
|
4208
4189
|
},
|
|
4209
4190
|
tuya_data_point_dump: {
|
|
4210
4191
|
cluster: 'manuSpecificTuya',
|
|
4211
|
-
type: ['
|
|
4192
|
+
type: ['commandDataResponse', 'commandDataReport', 'commandActiveStatusReport'],
|
|
4212
4193
|
convert: (model, msg, publis, options, meta) => {
|
|
4213
4194
|
// Don't use in production!
|
|
4214
4195
|
// Used in: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_tuya_devices.html
|
|
@@ -4222,8 +4203,7 @@ const converters = {
|
|
|
4222
4203
|
let dataStr =
|
|
4223
4204
|
Date.now().toString() + ' ' +
|
|
4224
4205
|
meta.device.ieeeAddr + ' ' +
|
|
4225
|
-
getHex(msg.data.
|
|
4226
|
-
getHex(msg.data.transid) + ' ' +
|
|
4206
|
+
getHex(msg.data.seq) + ' ' +
|
|
4227
4207
|
getHex(msg.data.dp) + ' ' +
|
|
4228
4208
|
getHex(msg.data.datatype) + ' ' +
|
|
4229
4209
|
getHex(msg.data.fn);
|
|
@@ -4274,7 +4254,7 @@ const converters = {
|
|
|
4274
4254
|
},
|
|
4275
4255
|
blitzwolf_occupancy_with_timeout: {
|
|
4276
4256
|
cluster: 'manuSpecificTuya',
|
|
4277
|
-
type: '
|
|
4257
|
+
type: 'commandDataResponse',
|
|
4278
4258
|
convert: (model, msg, publish, options, meta) => {
|
|
4279
4259
|
msg.data.occupancy = msg.data.dp === tuya.dataPoints.occupancy ? 1 : 0;
|
|
4280
4260
|
return converters.occupancy_with_timeout.convert(model, msg, publish, options, meta);
|
|
@@ -4568,7 +4548,7 @@ const converters = {
|
|
|
4568
4548
|
},
|
|
4569
4549
|
frankever_valve: {
|
|
4570
4550
|
cluster: 'manuSpecificTuya',
|
|
4571
|
-
type: ['
|
|
4551
|
+
type: ['commandDataResponse', 'commandDataReport', 'commandActiveStatusReport'],
|
|
4572
4552
|
convert: (model, msg, publish, options, meta) => {
|
|
4573
4553
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
4574
4554
|
const dp = msg.data.dp;
|
|
@@ -4591,7 +4571,7 @@ const converters = {
|
|
|
4591
4571
|
},
|
|
4592
4572
|
tuya_smoke: {
|
|
4593
4573
|
cluster: 'manuSpecificTuya',
|
|
4594
|
-
type: ['
|
|
4574
|
+
type: ['commandDataResponse'],
|
|
4595
4575
|
convert: (model, msg, publish, options, meta) => {
|
|
4596
4576
|
const dp = msg.data.dp;
|
|
4597
4577
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -4605,7 +4585,7 @@ const converters = {
|
|
|
4605
4585
|
},
|
|
4606
4586
|
tuya_woox_smoke: {
|
|
4607
4587
|
cluster: 'manuSpecificTuya',
|
|
4608
|
-
type: ['
|
|
4588
|
+
type: ['commandDataResponse'],
|
|
4609
4589
|
convert: (model, msg, publish, options, meta) => {
|
|
4610
4590
|
const dp = msg.data.dp;
|
|
4611
4591
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -4623,7 +4603,7 @@ const converters = {
|
|
|
4623
4603
|
},
|
|
4624
4604
|
tuya_switch: {
|
|
4625
4605
|
cluster: 'manuSpecificTuya',
|
|
4626
|
-
type: ['
|
|
4606
|
+
type: ['commandDataReport', 'commandDataResponse', 'commandActiveStatusReport'],
|
|
4627
4607
|
convert: (model, msg, publish, options, meta) => {
|
|
4628
4608
|
const multiEndpoint = model.meta && model.meta.multiEndpoint;
|
|
4629
4609
|
const dp = msg.data.dp;
|
|
@@ -4643,7 +4623,7 @@ const converters = {
|
|
|
4643
4623
|
},
|
|
4644
4624
|
tuya_dinrail_switch: {
|
|
4645
4625
|
cluster: 'manuSpecificTuya',
|
|
4646
|
-
type: ['
|
|
4626
|
+
type: ['commandDataReport', 'commandDataResponse', 'commandActiveStatusReport'],
|
|
4647
4627
|
convert: (model, msg, publish, options, meta) => {
|
|
4648
4628
|
const dp = msg.data.dp;
|
|
4649
4629
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -5997,7 +5977,7 @@ const converters = {
|
|
|
5997
5977
|
},
|
|
5998
5978
|
javis_microwave_sensor: {
|
|
5999
5979
|
cluster: 'manuSpecificTuya',
|
|
6000
|
-
type: ['
|
|
5980
|
+
type: ['commandDataReport', 'commandDataResponse'],
|
|
6001
5981
|
convert: (model, msg, publish, options, meta) => {
|
|
6002
5982
|
const dp = msg.data.dp;
|
|
6003
5983
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -6204,7 +6184,7 @@ const converters = {
|
|
|
6204
6184
|
},
|
|
6205
6185
|
ZVG1: {
|
|
6206
6186
|
cluster: 'manuSpecificTuya',
|
|
6207
|
-
type: '
|
|
6187
|
+
type: 'commandDataResponse',
|
|
6208
6188
|
convert: (model, msg, publish, options, meta) => {
|
|
6209
6189
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
6210
6190
|
const dp = msg.data.dp;
|
|
@@ -6768,7 +6748,7 @@ const converters = {
|
|
|
6768
6748
|
},
|
|
6769
6749
|
SLUXZB: {
|
|
6770
6750
|
cluster: 'manuSpecificTuya',
|
|
6771
|
-
type: ['
|
|
6751
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
6772
6752
|
convert: (model, msg, publish, options, meta) => {
|
|
6773
6753
|
const dp = msg.data.dp;
|
|
6774
6754
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -6851,7 +6831,7 @@ const converters = {
|
|
|
6851
6831
|
},
|
|
6852
6832
|
tuya_gas: {
|
|
6853
6833
|
cluster: 'manuSpecificTuya',
|
|
6854
|
-
type: ['
|
|
6834
|
+
type: ['commandDataResponse'],
|
|
6855
6835
|
convert: (model, msg, publish, options, meta) => {
|
|
6856
6836
|
const dp = msg.data.dp;
|
|
6857
6837
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -7221,7 +7201,7 @@ const converters = {
|
|
|
7221
7201
|
},
|
|
7222
7202
|
tuya_motion_sensor: {
|
|
7223
7203
|
cluster: 'manuSpecificTuya',
|
|
7224
|
-
type: ['
|
|
7204
|
+
type: ['commandDataResponse'],
|
|
7225
7205
|
convert: (model, msg, publish, options, meta) => {
|
|
7226
7206
|
const dp = msg.data.dp;
|
|
7227
7207
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -7269,7 +7249,7 @@ const converters = {
|
|
|
7269
7249
|
},
|
|
7270
7250
|
tuya_radar_sensor: {
|
|
7271
7251
|
cluster: 'manuSpecificTuya',
|
|
7272
|
-
type: ['
|
|
7252
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
7273
7253
|
convert: (model, msg, publish, options, meta) => {
|
|
7274
7254
|
const dp = msg.data.dp;
|
|
7275
7255
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -7293,7 +7273,7 @@ const converters = {
|
|
|
7293
7273
|
},
|
|
7294
7274
|
moes_thermostat_tv: {
|
|
7295
7275
|
cluster: 'manuSpecificTuya',
|
|
7296
|
-
type: ['
|
|
7276
|
+
type: ['commandDataResponse', 'commandDataReport', 'raw'],
|
|
7297
7277
|
convert: (model, msg, publish, options, meta) => {
|
|
7298
7278
|
const dp = msg.data.dp;
|
|
7299
7279
|
let value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -7402,7 +7382,7 @@ const converters = {
|
|
|
7402
7382
|
},
|
|
7403
7383
|
hoch_din: {
|
|
7404
7384
|
cluster: 'manuSpecificTuya',
|
|
7405
|
-
type: ['
|
|
7385
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
7406
7386
|
convert: (model, msg, publish, options, meta) => {
|
|
7407
7387
|
const dp = msg.data.dp;
|
|
7408
7388
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
@@ -7703,7 +7683,7 @@ const converters = {
|
|
|
7703
7683
|
},
|
|
7704
7684
|
ignore_tuya_set_time: {
|
|
7705
7685
|
cluster: 'manuSpecificTuya',
|
|
7706
|
-
type: ['
|
|
7686
|
+
type: ['commandMcuSyncTime'],
|
|
7707
7687
|
convert: (model, msg, publish, options, meta) => null,
|
|
7708
7688
|
},
|
|
7709
7689
|
// #endregion
|
package/converters/toZigbee.js
CHANGED
|
@@ -3155,7 +3155,7 @@ const converters = {
|
|
|
3155
3155
|
key: ['state'],
|
|
3156
3156
|
convertSet: async (entity, key, value, meta) => {
|
|
3157
3157
|
// Always use same transid as tuya_dimmer_level (https://github.com/Koenkk/zigbee2mqtt/issues/6366)
|
|
3158
|
-
await tuya.sendDataPointBool(entity, tuya.dataPoints.state, value === 'ON', '
|
|
3158
|
+
await tuya.sendDataPointBool(entity, tuya.dataPoints.state, value === 'ON', 'dataRequest', 1);
|
|
3159
3159
|
},
|
|
3160
3160
|
},
|
|
3161
3161
|
tuya_dimmer_level: {
|
|
@@ -3194,7 +3194,7 @@ const converters = {
|
|
|
3194
3194
|
}
|
|
3195
3195
|
}
|
|
3196
3196
|
// Always use same transid as tuya_dimmer_state (https://github.com/Koenkk/zigbee2mqtt/issues/6366)
|
|
3197
|
-
await tuya.sendDataPointValue(entity, dp, newValue, '
|
|
3197
|
+
await tuya.sendDataPointValue(entity, dp, newValue, 'dataRequest', 1);
|
|
3198
3198
|
},
|
|
3199
3199
|
},
|
|
3200
3200
|
tuya_switch_state: {
|
|
@@ -3239,7 +3239,7 @@ const converters = {
|
|
|
3239
3239
|
convertSet: async (entity, key, value, meta) => {
|
|
3240
3240
|
// input to multiple of 10 with max value of 100
|
|
3241
3241
|
const thresh = Math.abs(Math.min(10 * (Math.floor(value / 10)), 100));
|
|
3242
|
-
await tuya.sendDataPointValue(entity, tuya.dataPoints.frankEverTreshold, thresh, '
|
|
3242
|
+
await tuya.sendDataPointValue(entity, tuya.dataPoints.frankEverTreshold, thresh, 'dataRequest', 1);
|
|
3243
3243
|
return {state: {threshold: value}};
|
|
3244
3244
|
},
|
|
3245
3245
|
},
|
|
@@ -3249,7 +3249,7 @@ const converters = {
|
|
|
3249
3249
|
// input in minutes with maximum of 600 minutes (equals 10 hours)
|
|
3250
3250
|
const timer = 60 * Math.abs(Math.min(value, 600));
|
|
3251
3251
|
// sendTuyaDataPoint* functions take care of converting the data to proper format
|
|
3252
|
-
await tuya.sendDataPointValue(entity, tuya.dataPoints.frankEverTimer, timer, '
|
|
3252
|
+
await tuya.sendDataPointValue(entity, tuya.dataPoints.frankEverTimer, timer, 'dataRequest', 1);
|
|
3253
3253
|
return {state: {timer: value}};
|
|
3254
3254
|
},
|
|
3255
3255
|
},
|
|
@@ -3318,7 +3318,7 @@ const converters = {
|
|
|
3318
3318
|
// input in minutes with maximum of 600 minutes (equals 10 hours)
|
|
3319
3319
|
const timer = 60 * Math.abs(Math.min(value, 600));
|
|
3320
3320
|
// sendTuyaDataPoint* functions take care of converting the data to proper format
|
|
3321
|
-
await tuya.sendDataPointValue(entity, 11, timer, '
|
|
3321
|
+
await tuya.sendDataPointValue(entity, 11, timer, 'dataRequest', 1);
|
|
3322
3322
|
return {state: {timer: value}};
|
|
3323
3323
|
},
|
|
3324
3324
|
},
|
|
@@ -3328,7 +3328,7 @@ const converters = {
|
|
|
3328
3328
|
let timerState = 2;
|
|
3329
3329
|
if (value === 'disabled') timerState = 0;
|
|
3330
3330
|
else if (value === 'active') timerState = 1;
|
|
3331
|
-
await tuya.sendDataPointValue(entity, 11, timerState, '
|
|
3331
|
+
await tuya.sendDataPointValue(entity, 11, timerState, 'dataRequest', 1);
|
|
3332
3332
|
return {state: {timer_state: value}};
|
|
3333
3333
|
},
|
|
3334
3334
|
},
|
|
@@ -6110,18 +6110,18 @@ const converters = {
|
|
|
6110
6110
|
|
|
6111
6111
|
switch (key) {
|
|
6112
6112
|
case 'state':
|
|
6113
|
-
await tuya.sendDataPointBool(entity, stateKeyId, value === 'ON', '
|
|
6113
|
+
await tuya.sendDataPointBool(entity, stateKeyId, value === 'ON', 'dataRequest', 1);
|
|
6114
6114
|
break;
|
|
6115
6115
|
|
|
6116
6116
|
case 'brightness':
|
|
6117
6117
|
if (value >= 0 && value <= 254) {
|
|
6118
6118
|
const newValue = utils.mapNumberRange(value, 0, 254, 0, 1000);
|
|
6119
6119
|
if (newValue === 0) {
|
|
6120
|
-
await tuya.sendDataPointBool(entity, stateKeyId, false, '
|
|
6120
|
+
await tuya.sendDataPointBool(entity, stateKeyId, false, 'dataRequest', 1);
|
|
6121
6121
|
} else {
|
|
6122
|
-
await tuya.sendDataPointBool(entity, stateKeyId, true, '
|
|
6122
|
+
await tuya.sendDataPointBool(entity, stateKeyId, true, 'dataRequest', 1);
|
|
6123
6123
|
}
|
|
6124
|
-
await tuya.sendDataPointValue(entity, brightnessKeyId, newValue, '
|
|
6124
|
+
await tuya.sendDataPointValue(entity, brightnessKeyId, newValue, 'dataRequest', 1);
|
|
6125
6125
|
break;
|
|
6126
6126
|
} else {
|
|
6127
6127
|
throw new Error('Dimmer brightness is out of range 0..254');
|
|
@@ -269,4 +269,25 @@ module.exports = [
|
|
|
269
269
|
},
|
|
270
270
|
exposes: [e.soil_moisture(), e.battery()],
|
|
271
271
|
},
|
|
272
|
+
{
|
|
273
|
+
zigbeeModel: ['EFEKTA_eON213wz'],
|
|
274
|
+
model: 'EFEKTA_eON213wz',
|
|
275
|
+
vendor: 'Custom devices (DiY)',
|
|
276
|
+
description: '[Mini weather station, digital barometer, forecast, charts, temperature, humidity](http://efektalab.com/eON213wz)',
|
|
277
|
+
fromZigbee: [fz.temperature, fz.humidity, fz.pressure, fz.battery],
|
|
278
|
+
toZigbee: [tz.factory_reset],
|
|
279
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
280
|
+
const endpoint = device.getEndpoint(1);
|
|
281
|
+
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
282
|
+
'genPowerCfg', 'msTemperatureMeasurement', 'msRelativeHumidity', 'msPressureMeasurement']);
|
|
283
|
+
const overides = {min: 0, max: 21600, change: 0};
|
|
284
|
+
await reporting.batteryVoltage(endpoint, overides);
|
|
285
|
+
await reporting.batteryPercentageRemaining(endpoint, overides);
|
|
286
|
+
await reporting.temperature(endpoint, overides);
|
|
287
|
+
await reporting.humidity(endpoint, overides);
|
|
288
|
+
await reporting.pressureExtended(endpoint, overides);
|
|
289
|
+
await endpoint.read('msPressureMeasurement', ['scale']);
|
|
290
|
+
},
|
|
291
|
+
exposes: [e.battery(), e.temperature(), e.humidity(), e.pressure()],
|
|
292
|
+
},
|
|
272
293
|
];
|
package/devices/ewelink.js
CHANGED
|
@@ -20,6 +20,21 @@ module.exports = [
|
|
|
20
20
|
device.skipDefaultResponse = true;
|
|
21
21
|
},
|
|
22
22
|
},
|
|
23
|
+
{
|
|
24
|
+
zigbeeModel: ['SWITCH-ZR02'],
|
|
25
|
+
model: 'SWITCH-ZR02',
|
|
26
|
+
vendor: 'eWeLink',
|
|
27
|
+
description: 'Zigbee smart switch',
|
|
28
|
+
extend: extend.switch(),
|
|
29
|
+
fromZigbee: [fz.on_off_skip_duplicate_transaction],
|
|
30
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
31
|
+
const endpoint = device.getEndpoint(1);
|
|
32
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
33
|
+
},
|
|
34
|
+
onEvent: async (type, data, device) => {
|
|
35
|
+
device.skipDefaultResponse = true;
|
|
36
|
+
},
|
|
37
|
+
},
|
|
23
38
|
{
|
|
24
39
|
zigbeeModel: ['ZB-SW01'],
|
|
25
40
|
model: 'ZB-SW01',
|
package/devices/heiman.js
CHANGED
|
@@ -73,6 +73,7 @@ module.exports = [
|
|
|
73
73
|
globalStore.clearValue(device, 'interval');
|
|
74
74
|
} else if (!globalStore.hasValue(device, 'interval')) {
|
|
75
75
|
const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 60;
|
|
76
|
+
if (seconds === -1) return;
|
|
76
77
|
const interval = setInterval(async () => {
|
|
77
78
|
try {
|
|
78
79
|
await endpoint.read('haElectricalMeasurement', ['rmsVoltage', 'rmsCurrent', 'activePower']);
|
|
@@ -85,7 +86,8 @@ module.exports = [
|
|
|
85
86
|
},
|
|
86
87
|
{
|
|
87
88
|
zigbeeModel: ['SMOK_V16', 'SMOK_V15', 'b5db59bfd81e4f1f95dc57fdbba17931', '98293058552c49f38ad0748541ee96ba', 'SMOK_YDLV10',
|
|
88
|
-
'FB56-SMF02HM1.4', 'SmokeSensor-N-3.0', '319fa36e7384414a9ea62cba8f6e7626', 'c3442b4ac59b4ba1a83119d938f283ab'
|
|
89
|
+
'FB56-SMF02HM1.4', 'SmokeSensor-N-3.0', '319fa36e7384414a9ea62cba8f6e7626', 'c3442b4ac59b4ba1a83119d938f283ab',
|
|
90
|
+
'SmokeSensor-EF-3.0'],
|
|
89
91
|
model: 'HS1SA',
|
|
90
92
|
vendor: 'HEIMAN',
|
|
91
93
|
description: 'Smoke detector',
|
|
@@ -99,7 +101,7 @@ module.exports = [
|
|
|
99
101
|
exposes: [e.smoke(), e.battery_low(), e.battery()],
|
|
100
102
|
},
|
|
101
103
|
{
|
|
102
|
-
zigbeeModel: ['SmokeSensor-N', 'SmokeSensor-
|
|
104
|
+
zigbeeModel: ['SmokeSensor-N', 'SmokeSensor-EM'],
|
|
103
105
|
model: 'HS3SA',
|
|
104
106
|
vendor: 'HEIMAN',
|
|
105
107
|
description: 'Smoke detector',
|
package/devices/ikea.js
CHANGED
|
@@ -32,6 +32,19 @@ const bulbOnEvent = async (type, data, device) => {
|
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
const configureRemote = async (device, coordinatorEndpoint, logger) => {
|
|
36
|
+
// Firmware 2.3.75 >= only supports binding to endpoint, before only to group
|
|
37
|
+
// - https://github.com/Koenkk/zigbee2mqtt/issues/2772#issuecomment-577389281
|
|
38
|
+
// - https://github.com/Koenkk/zigbee2mqtt/issues/7716
|
|
39
|
+
const endpoint = device.getEndpoint(1);
|
|
40
|
+
const version = device.softwareBuildID.split('.').map((n) => Number(n));
|
|
41
|
+
const bindTarget = version[0] > 2 || (version[0] == 2 && version[1] > 3) || (version[0] == 2 && version[1] == 3 && version[2] >= 75) ?
|
|
42
|
+
coordinatorEndpoint : constants.defaultBindGroup;
|
|
43
|
+
await endpoint.bind('genOnOff', bindTarget);
|
|
44
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
45
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
46
|
+
};
|
|
47
|
+
|
|
35
48
|
const tradfriExtend = {
|
|
36
49
|
light_onoff_brightness: (options = {}) => ({
|
|
37
50
|
...extend.light_onoff_brightness(options),
|
|
@@ -518,14 +531,7 @@ module.exports = [
|
|
|
518
531
|
toZigbee: [],
|
|
519
532
|
ota: ota.tradfri,
|
|
520
533
|
meta: {battery: {dontDividePercentage: true}},
|
|
521
|
-
configure:
|
|
522
|
-
const endpoint = device.getEndpoint(1);
|
|
523
|
-
// See explanation in E1743, only applies to E1810 (for E1524 it has no effect)
|
|
524
|
-
// https://github.com/Koenkk/zigbee2mqtt/issues/2772#issuecomment-577389281
|
|
525
|
-
await endpoint.bind('genOnOff', constants.defaultBindGroup);
|
|
526
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
527
|
-
await reporting.batteryPercentageRemaining(endpoint);
|
|
528
|
-
},
|
|
534
|
+
configure: configureRemote,
|
|
529
535
|
},
|
|
530
536
|
{
|
|
531
537
|
zigbeeModel: ['Remote Control N2'],
|
|
@@ -540,12 +546,7 @@ module.exports = [
|
|
|
540
546
|
toZigbee: [],
|
|
541
547
|
ota: ota.tradfri,
|
|
542
548
|
meta: {battery: {dontDividePercentage: true}},
|
|
543
|
-
configure:
|
|
544
|
-
const endpoint = device.getEndpoint(1);
|
|
545
|
-
await endpoint.bind('genOnOff', constants.defaultBindGroup);
|
|
546
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
547
|
-
await reporting.batteryPercentageRemaining(endpoint);
|
|
548
|
-
},
|
|
549
|
+
configure: configureRemote,
|
|
549
550
|
},
|
|
550
551
|
{
|
|
551
552
|
zigbeeModel: ['TRADFRI on/off switch'],
|
|
@@ -558,16 +559,7 @@ module.exports = [
|
|
|
558
559
|
toZigbee: [],
|
|
559
560
|
ota: ota.tradfri,
|
|
560
561
|
meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
|
|
561
|
-
configure:
|
|
562
|
-
const endpoint = device.getEndpoint(1);
|
|
563
|
-
// By default this device controls group 0, some devices are by default in
|
|
564
|
-
// group 0 causing the remote to control them.
|
|
565
|
-
// By binding it to a random group, e.g. 901, it will send the commands to group 901 instead of 0
|
|
566
|
-
// https://github.com/Koenkk/zigbee2mqtt/issues/2772#issuecomment-577389281
|
|
567
|
-
await endpoint.bind('genOnOff', constants.defaultBindGroup);
|
|
568
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
569
|
-
await reporting.batteryPercentageRemaining(endpoint);
|
|
570
|
-
},
|
|
562
|
+
configure: configureRemote,
|
|
571
563
|
},
|
|
572
564
|
{
|
|
573
565
|
zigbeeModel: ['KNYCKLAN Open/Close remote'],
|
|
@@ -579,16 +571,7 @@ module.exports = [
|
|
|
579
571
|
toZigbee: [],
|
|
580
572
|
ota: ota.tradfri,
|
|
581
573
|
meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
|
|
582
|
-
configure:
|
|
583
|
-
const endpoint = device.getEndpoint(1);
|
|
584
|
-
// By default this device controls group 0, some devices are by default in
|
|
585
|
-
// group 0 causing the remote to control them.
|
|
586
|
-
// By binding it to a random group, e.g. 901, it will send the commands to group 901 instead of 0
|
|
587
|
-
// https://github.com/Koenkk/zigbee2mqtt/issues/2772#issuecomment-577389281
|
|
588
|
-
await endpoint.bind('genOnOff', constants.defaultBindGroup);
|
|
589
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
590
|
-
await reporting.batteryPercentageRemaining(endpoint);
|
|
591
|
-
},
|
|
574
|
+
configure: configureRemote,
|
|
592
575
|
},
|
|
593
576
|
{
|
|
594
577
|
zigbeeModel: ['KNYCKLAN receiver'],
|
|
@@ -613,14 +596,7 @@ module.exports = [
|
|
|
613
596
|
toZigbee: [],
|
|
614
597
|
ota: ota.tradfri,
|
|
615
598
|
meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
|
|
616
|
-
configure:
|
|
617
|
-
const endpoint = device.getEndpoint(1);
|
|
618
|
-
// By default this device controls group 0, some devices are by default in
|
|
619
|
-
// group 0 causing the remote to control them.
|
|
620
|
-
// By binding it to a random group, e.g. 901, it will send the commands to group 901 instead of 0
|
|
621
|
-
await reporting.bind(endpoint, constants.defaultBindGroup, ['genPowerCfg']);
|
|
622
|
-
await reporting.batteryPercentageRemaining(endpoint);
|
|
623
|
-
},
|
|
599
|
+
configure: configureRemote,
|
|
624
600
|
},
|
|
625
601
|
{
|
|
626
602
|
zigbeeModel: ['SYMFONISK Sound Controller'],
|
|
@@ -722,16 +698,7 @@ module.exports = [
|
|
|
722
698
|
toZigbee: [],
|
|
723
699
|
meta: {battery: {dontDividePercentage: true}},
|
|
724
700
|
ota: ota.tradfri,
|
|
725
|
-
configure:
|
|
726
|
-
const endpoint = device.getEndpoint(1);
|
|
727
|
-
// By default this device controls group 0, some devices are by default in
|
|
728
|
-
// group 0 causing the remote to control them.
|
|
729
|
-
// By binding it to a random group, e.g. 901, it will send the commands to group 901 instead of 0
|
|
730
|
-
// https://github.com/Koenkk/zigbee2mqtt/issues/2772#issuecomment-577389281
|
|
731
|
-
await endpoint.bind('genOnOff', constants.defaultBindGroup);
|
|
732
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
733
|
-
await reporting.batteryPercentageRemaining(endpoint);
|
|
734
|
-
},
|
|
701
|
+
configure: configureRemote,
|
|
735
702
|
},
|
|
736
703
|
{
|
|
737
704
|
zigbeeModel: ['GUNNARP panel round'],
|
package/devices/lidl.js
CHANGED
|
@@ -38,7 +38,7 @@ const tuyaLocal = {
|
|
|
38
38
|
const fzLocal = {
|
|
39
39
|
zs_thermostat: {
|
|
40
40
|
cluster: 'manuSpecificTuya',
|
|
41
|
-
type: ['
|
|
41
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
42
42
|
convert: (model, msg, publish, options, meta) => {
|
|
43
43
|
const dp = msg.data.dp;
|
|
44
44
|
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
package/devices/neo.js
CHANGED
|
@@ -30,8 +30,8 @@ module.exports = [
|
|
|
30
30
|
onEvent: tuya.onEventSetLocalTime,
|
|
31
31
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
32
32
|
const endpoint = device.getEndpoint(1);
|
|
33
|
-
await endpoint.command('manuSpecificTuya', '
|
|
34
|
-
await endpoint.command('manuSpecificTuya', '
|
|
33
|
+
await endpoint.command('manuSpecificTuya', 'dataQuery', {});
|
|
34
|
+
await endpoint.command('manuSpecificTuya', 'mcuVersionRequest', {'seq': 0x0002});
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
{
|
|
@@ -41,7 +41,7 @@ module.exports = [
|
|
|
41
41
|
description: 'Motion, temperature & humidity sensor',
|
|
42
42
|
fromZigbee: [fz.neo_nas_pd07],
|
|
43
43
|
toZigbee: [],
|
|
44
|
-
onEvent: tuya.
|
|
44
|
+
onEvent: tuya.onEventSetTime,
|
|
45
45
|
exposes: [e.occupancy(), e.humidity(), e.temperature(), e.tamper(), e.battery_low(),
|
|
46
46
|
exposes.enum('power_type', ea.STATE, ['battery_full', 'battery_high', 'battery_medium', 'battery_low', 'usb'])],
|
|
47
47
|
},
|
package/devices/nue_3a.js
CHANGED
|
@@ -157,7 +157,7 @@ module.exports = [
|
|
|
157
157
|
},
|
|
158
158
|
},
|
|
159
159
|
{
|
|
160
|
-
zigbeeModel: ['FNB56-ZSW02LX2.0'
|
|
160
|
+
zigbeeModel: ['FNB56-ZSW02LX2.0'],
|
|
161
161
|
model: 'HGZB-42',
|
|
162
162
|
vendor: 'Nue / 3A',
|
|
163
163
|
description: 'Smart light switch - 2 gang v2.0',
|
|
@@ -282,4 +282,16 @@ module.exports = [
|
|
|
282
282
|
description: '9W RGB LED downlight',
|
|
283
283
|
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
|
|
284
284
|
},
|
|
285
|
+
{
|
|
286
|
+
zigbeeModel: ['LXN-2S27LX1.0'],
|
|
287
|
+
model: 'NUE-AUWZO2',
|
|
288
|
+
vendor: 'Nue / 3A',
|
|
289
|
+
description: 'Smart Zigbee double power point',
|
|
290
|
+
extend: extend.switch(),
|
|
291
|
+
exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right')],
|
|
292
|
+
meta: {multiEndpoint: true},
|
|
293
|
+
endpoint: (device) => {
|
|
294
|
+
return {left: 1, right: 2};
|
|
295
|
+
},
|
|
296
|
+
},
|
|
285
297
|
];
|
package/devices/osram.js
CHANGED
|
@@ -261,8 +261,8 @@ module.exports = [
|
|
|
261
261
|
model: 'AC0363900NJ',
|
|
262
262
|
vendor: 'OSRAM',
|
|
263
263
|
description: 'Smart+ mini gardenpole RGBW',
|
|
264
|
-
extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153,
|
|
265
|
-
exposes: [e.light_brightness_colortemp_colorhs([153,
|
|
264
|
+
extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370], disableColorTempStartup: true}),
|
|
265
|
+
exposes: [e.light_brightness_colortemp_colorhs([153, 370]).removeFeature('color_temp_startup'), e.effect()],
|
|
266
266
|
ota: ota.ledvance,
|
|
267
267
|
},
|
|
268
268
|
{
|
package/devices/philips.js
CHANGED
|
@@ -368,6 +368,15 @@ module.exports = [
|
|
|
368
368
|
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
369
369
|
ota: ota.zigbeeOTA,
|
|
370
370
|
},
|
|
371
|
+
{
|
|
372
|
+
zigbeeModel: ['1743730P7'],
|
|
373
|
+
model: '1743730P7',
|
|
374
|
+
vendor: 'Philips',
|
|
375
|
+
description: 'Hue Calla outdoor',
|
|
376
|
+
meta: {turnsOffAtBrightness1: true},
|
|
377
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
378
|
+
ota: ota.zigbeeOTA,
|
|
379
|
+
},
|
|
371
380
|
{
|
|
372
381
|
zigbeeModel: ['1744130P7'],
|
|
373
382
|
model: '1744130P7',
|
|
@@ -404,6 +413,15 @@ module.exports = [
|
|
|
404
413
|
extend: hueExtend.light_onoff_brightness_colortemp_color(),
|
|
405
414
|
ota: ota.zigbeeOTA,
|
|
406
415
|
},
|
|
416
|
+
{
|
|
417
|
+
zigbeeModel: ['1743430P7'],
|
|
418
|
+
model: '1743430P7',
|
|
419
|
+
vendor: 'Philips',
|
|
420
|
+
description: 'Hue Impress outdoor Pedestal',
|
|
421
|
+
meta: {turnsOffAtBrightness1: true},
|
|
422
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
423
|
+
ota: ota.zigbeeOTA,
|
|
424
|
+
},
|
|
407
425
|
{
|
|
408
426
|
zigbeeModel: ['1740193P0'],
|
|
409
427
|
model: '1740193P0',
|
|
@@ -834,7 +852,7 @@ module.exports = [
|
|
|
834
852
|
ota: ota.zigbeeOTA,
|
|
835
853
|
},
|
|
836
854
|
{
|
|
837
|
-
zigbeeModel: ['LCT024', '440400982841'],
|
|
855
|
+
zigbeeModel: ['LCT024', '440400982841', '440400982842'],
|
|
838
856
|
model: '915005733701',
|
|
839
857
|
vendor: 'Philips',
|
|
840
858
|
description: 'Hue White and color ambiance Play Lightbar',
|
package/devices/sonoff.js
CHANGED
|
@@ -104,7 +104,7 @@ module.exports = [
|
|
|
104
104
|
const endpoint = device.getEndpoint(1);
|
|
105
105
|
const bindClusters = ['msTemperatureMeasurement', 'msRelativeHumidity', 'genPowerCfg'];
|
|
106
106
|
await reporting.bind(endpoint, coordinatorEndpoint, bindClusters);
|
|
107
|
-
await reporting.temperature(endpoint, {min: 5, max: constants.repInterval.MINUTES_30, change:
|
|
107
|
+
await reporting.temperature(endpoint, {min: 5, max: constants.repInterval.MINUTES_30, change: 20});
|
|
108
108
|
await reporting.humidity(endpoint);
|
|
109
109
|
await reporting.batteryVoltage(endpoint);
|
|
110
110
|
await reporting.batteryPercentageRemaining(endpoint);
|
package/devices/tuya.js
CHANGED
|
@@ -122,6 +122,7 @@ module.exports = [
|
|
|
122
122
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_x2fqbdun'},
|
|
123
123
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_589kq4ul'},
|
|
124
124
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_1mtktxdk'},
|
|
125
|
+
{modelID: 'TS0505B', manufacturerName: '_TZ3210_0rn9qhnu'},
|
|
125
126
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_bicjqpg4'},
|
|
126
127
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_cmaky9gq'},
|
|
127
128
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_tza2vjxx'}],
|
|
@@ -988,6 +989,7 @@ module.exports = [
|
|
|
988
989
|
globalStore.clearValue(device, 'interval');
|
|
989
990
|
} else if (!globalStore.hasValue(device, 'interval')) {
|
|
990
991
|
const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 60;
|
|
992
|
+
if (seconds === -1) return;
|
|
991
993
|
const interval = setInterval(async () => {
|
|
992
994
|
try {
|
|
993
995
|
await endpoint.read('haElectricalMeasurement', ['rmsVoltage', 'rmsCurrent', 'activePower']);
|
|
@@ -1005,13 +1007,17 @@ module.exports = [
|
|
|
1005
1007
|
extend: extend.switch(),
|
|
1006
1008
|
},
|
|
1007
1009
|
{
|
|
1008
|
-
fingerprint: [
|
|
1010
|
+
fingerprint: [
|
|
1011
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_5f43h46b'},
|
|
1012
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7'},
|
|
1013
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak'},
|
|
1009
1014
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_ew3ldmgx'},
|
|
1010
|
-
{modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato'},
|
|
1011
|
-
{modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm'},
|
|
1012
1015
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_jvzvulen'},
|
|
1016
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm'},
|
|
1017
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_nfnmi125'},
|
|
1018
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato'},
|
|
1013
1019
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_w0qqde0g'},
|
|
1014
|
-
|
|
1020
|
+
],
|
|
1015
1021
|
model: 'TS011F_plug_1',
|
|
1016
1022
|
description: 'Smart plug (with power monitoring)',
|
|
1017
1023
|
vendor: 'TuYa',
|
|
@@ -1051,14 +1057,22 @@ module.exports = [
|
|
|
1051
1057
|
},
|
|
1052
1058
|
{
|
|
1053
1059
|
fingerprint: [
|
|
1054
|
-
{modelID: 'TS011F', manufacturerName: '
|
|
1055
|
-
{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 69},
|
|
1060
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_5f43h46b', applicationVersion: 68},
|
|
1056
1061
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_5f43h46b', applicationVersion: 69},
|
|
1057
|
-
{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak', applicationVersion: 68},
|
|
1058
1062
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 68},
|
|
1059
|
-
{modelID: 'TS011F', manufacturerName: '
|
|
1063
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 69},
|
|
1064
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_ew3ldmgx', applicationVersion: 68},
|
|
1065
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_ew3ldmgx', applicationVersion: 69},
|
|
1066
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_jvzvulen', applicationVersion: 68},
|
|
1067
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_jvzvulen', applicationVersion: 69},
|
|
1068
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm', applicationVersion: 68},
|
|
1069
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm', applicationVersion: 69},
|
|
1070
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_nfnmi125', applicationVersion: 68},
|
|
1071
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_nfnmi125', applicationVersion: 69},
|
|
1072
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato', applicationVersion: 68},
|
|
1060
1073
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato', applicationVersion: 69},
|
|
1061
1074
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_w0qqde0g', applicationVersion: 68},
|
|
1075
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_w0qqde0g', applicationVersion: 69},
|
|
1062
1076
|
],
|
|
1063
1077
|
model: 'TS011F_plug_3',
|
|
1064
1078
|
description: 'Smart plug (with power monitoring by polling)',
|
|
@@ -1084,6 +1098,7 @@ module.exports = [
|
|
|
1084
1098
|
globalStore.clearValue(device, 'interval');
|
|
1085
1099
|
} else if (!globalStore.hasValue(device, 'interval')) {
|
|
1086
1100
|
const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 60;
|
|
1101
|
+
if (seconds === -1) return;
|
|
1087
1102
|
const interval = setInterval(async () => {
|
|
1088
1103
|
try {
|
|
1089
1104
|
await endpoint.read('haElectricalMeasurement', ['rmsVoltage', 'rmsCurrent', 'activePower']);
|
|
@@ -1536,8 +1551,9 @@ module.exports = [
|
|
|
1536
1551
|
model: 'HY08WE',
|
|
1537
1552
|
vendor: 'TuYa',
|
|
1538
1553
|
description: 'Wall-mount thermostat',
|
|
1539
|
-
fromZigbee: [fz.hy_thermostat, fz.ignore_basic_report
|
|
1554
|
+
fromZigbee: [fz.hy_thermostat, fz.ignore_basic_report],
|
|
1540
1555
|
toZigbee: [tz.hy_thermostat],
|
|
1556
|
+
onEvent: tuya.onEventSetTime,
|
|
1541
1557
|
exposes: [exposes.climate().withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET)
|
|
1542
1558
|
.withLocalTemperature(ea.STATE)
|
|
1543
1559
|
.withSystemMode(['off', 'auto', 'heat'], ea.STATE_SET).withRunningState(['idle', 'heat'], ea.STATE)],
|
package/lib/exposes.js
CHANGED
|
@@ -495,7 +495,7 @@ module.exports = {
|
|
|
495
495
|
no_position_support: () => new Binary('no_position_support', access.SET, true, false).withDescription('Set to true when your device only reports position 0, 100 and 50 (in this case your device has an older firmware) (default false).'),
|
|
496
496
|
transition: () => new Numeric(`transition`, access.SET).withValueMin(0).withDescription('Controls the transition time (in seconds) of on/off, brightness, color temperature (if applicable) and color (if applicable) changes. Defaults to `0` (no transition).'),
|
|
497
497
|
legacy: () => new Binary(`legacy`, access.SET, true, false).withDescription(`Set to false to disable the legacy integration (highly recommended), will change structure of the published payload (default true).`),
|
|
498
|
-
measurement_poll_interval: () => new Numeric(`measurement_poll_interval`, access.SET).withValueMin(
|
|
498
|
+
measurement_poll_interval: () => new Numeric(`measurement_poll_interval`, access.SET).withValueMin(-1).withDescription(`This device does not support reporting electric measurements so it is polled instead. The default poll interval is 60 seconds, set to -1 to disable.`),
|
|
499
499
|
illuminance_below_threshold_check: () => new Binary(`illuminance_below_threshold_check`, access.SET, true, false).withDescription(`Set to false to also send messages when illuminance is above threshold in night mode (default true).`),
|
|
500
500
|
},
|
|
501
501
|
presets: {
|
package/lib/legacy.js
CHANGED
|
@@ -2045,7 +2045,7 @@ const fromZigbee = {
|
|
|
2045
2045
|
},
|
|
2046
2046
|
tuya_thermostat_weekly_schedule: {
|
|
2047
2047
|
cluster: 'manuSpecificTuya',
|
|
2048
|
-
type: ['
|
|
2048
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
2049
2049
|
options: [exposes.options.legacy()],
|
|
2050
2050
|
convert: (model, msg, publish, options, meta) => {
|
|
2051
2051
|
if (!isLegacyEnabled(options)) {
|
package/lib/tuya.js
CHANGED
|
@@ -63,19 +63,19 @@ function convertDecimalValueTo2ByteHexArray(value) {
|
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
async function onEventSetTime(type, data, device) {
|
|
66
|
-
|
|
66
|
+
// FIXME: Need to join onEventSetTime/onEventSetLocalTime to one command
|
|
67
|
+
|
|
68
|
+
if (data.type === 'commandMcuSyncTime' && data.cluster === 'manuSpecificTuya') {
|
|
67
69
|
try {
|
|
68
70
|
const utcTime = Math.round(((new Date()).getTime() - constants.OneJanuary2000) / 1000);
|
|
69
71
|
const localTime = utcTime - (new Date()).getTimezoneOffset() * 60;
|
|
70
72
|
const endpoint = device.getEndpoint(1);
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
};
|
|
78
|
-
await endpoint.command('manuSpecificTuya', 'setTime', payload, {});
|
|
73
|
+
|
|
74
|
+
await endpoint.command('manuSpecificTuya', 'mcuSyncTime', {
|
|
75
|
+
'seq': 8, // FIXME: Seems that need to set same seq as in request
|
|
76
|
+
'utc': utcTime,
|
|
77
|
+
'local': localTime,
|
|
78
|
+
});
|
|
79
79
|
} catch (error) {
|
|
80
80
|
// endpoint.command can throw an error which needs to
|
|
81
81
|
// be caught or the zigbee-herdsman may crash
|
|
@@ -87,24 +87,28 @@ async function onEventSetTime(type, data, device) {
|
|
|
87
87
|
// set UTC and Local Time as total number of seconds from 00: 00: 00 on January 01, 1970
|
|
88
88
|
// force to update every device time every hour due to very poor clock
|
|
89
89
|
async function onEventSetLocalTime(type, data, device) {
|
|
90
|
+
// FIXME: What actually nextLocalTimeUpdate/forceTimeUpdate do?
|
|
91
|
+
// I did not find any timers or something else where it was used.
|
|
92
|
+
// Actually, there are two ways to set time on TuYa MCU devices:
|
|
93
|
+
// 1. Respond to the `commandMcuSyncTime` event
|
|
94
|
+
// 2. Just send `mcuSyncTime` anytime (by 1-hour timer or something else)
|
|
95
|
+
|
|
90
96
|
const nextLocalTimeUpdate = globalStore.getValue(device, 'nextLocalTimeUpdate');
|
|
91
97
|
const forceTimeUpdate = nextLocalTimeUpdate == null || nextLocalTimeUpdate < new Date().getTime();
|
|
92
98
|
|
|
93
|
-
if ((data.type === '
|
|
99
|
+
if ((data.type === 'commandMcuSyncTime' && data.cluster === 'manuSpecificTuya') || forceTimeUpdate) {
|
|
94
100
|
globalStore.putValue(device, 'nextLocalTimeUpdate', new Date().getTime() + 3600 * 1000);
|
|
95
101
|
|
|
96
102
|
try {
|
|
97
103
|
const utcTime = Math.round(((new Date()).getTime()) / 1000);
|
|
98
104
|
const localTime = utcTime - (new Date()).getTimezoneOffset() * 60;
|
|
99
105
|
const endpoint = device.getEndpoint(1);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
};
|
|
107
|
-
await endpoint.command('manuSpecificTuya', 'setTime', payload, {});
|
|
106
|
+
|
|
107
|
+
await endpoint.command('manuSpecificTuya', 'mcuSyncTime', {
|
|
108
|
+
'seq': 8, // FIXME: Seems that need to set same seq as in request
|
|
109
|
+
'utc': utcTime,
|
|
110
|
+
'local': localTime,
|
|
111
|
+
});
|
|
108
112
|
} catch (error) {
|
|
109
113
|
// endpoint.command can throw an error which needs to
|
|
110
114
|
// be caught or the zigbee-herdsman may crash
|
|
@@ -573,24 +577,23 @@ const tvThermostatPreset = {
|
|
|
573
577
|
3: 'holiday',
|
|
574
578
|
};
|
|
575
579
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
+
// Return `seq` - transaction ID for handling concrete response
|
|
581
|
+
async function sendDataPoint(entity, datatype, dp, data, cmd, seq=undefined) {
|
|
582
|
+
if (seq === undefined) {
|
|
583
|
+
if (sendDataPoint.seq === undefined) {
|
|
584
|
+
sendDataPoint.seq = 0;
|
|
580
585
|
} else {
|
|
581
|
-
sendDataPoint.
|
|
582
|
-
sendDataPoint.
|
|
586
|
+
sendDataPoint.seq++;
|
|
587
|
+
sendDataPoint.seq %= 0xFFFF;
|
|
583
588
|
}
|
|
584
|
-
|
|
585
|
-
transid = sendDataPoint.transId;
|
|
589
|
+
seq = sendDataPoint.seq;
|
|
586
590
|
}
|
|
587
591
|
|
|
588
592
|
await entity.command(
|
|
589
593
|
'manuSpecificTuya',
|
|
590
|
-
cmd || '
|
|
594
|
+
cmd || 'dataRequest',
|
|
591
595
|
{
|
|
592
|
-
|
|
593
|
-
transid,
|
|
596
|
+
seq,
|
|
594
597
|
dp: dp,
|
|
595
598
|
datatype: datatype,
|
|
596
599
|
length_hi: (data.length >> 8) & 0xFF,
|
|
@@ -599,60 +602,61 @@ async function sendDataPoint(entity, datatype, dp, data, cmd, transid) {
|
|
|
599
602
|
},
|
|
600
603
|
{disableDefaultResponse: true},
|
|
601
604
|
);
|
|
605
|
+
return seq;
|
|
602
606
|
}
|
|
603
607
|
|
|
604
|
-
async function sendDataPointValue(entity, dp, value, cmd,
|
|
605
|
-
await sendDataPoint(
|
|
608
|
+
async function sendDataPointValue(entity, dp, value, cmd, seq=undefined) {
|
|
609
|
+
return await sendDataPoint(
|
|
606
610
|
entity,
|
|
607
611
|
dataTypes.value,
|
|
608
612
|
dp,
|
|
609
613
|
convertDecimalValueTo4ByteHexArray(value),
|
|
610
614
|
cmd,
|
|
611
|
-
|
|
615
|
+
seq,
|
|
612
616
|
);
|
|
613
617
|
}
|
|
614
618
|
|
|
615
|
-
async function sendDataPointBool(entity, dp, value, cmd,
|
|
616
|
-
await sendDataPoint(
|
|
619
|
+
async function sendDataPointBool(entity, dp, value, cmd, seq=undefined) {
|
|
620
|
+
return await sendDataPoint(
|
|
617
621
|
entity,
|
|
618
622
|
dataTypes.bool,
|
|
619
623
|
dp,
|
|
620
624
|
[value ? 1 : 0],
|
|
621
625
|
cmd,
|
|
622
|
-
|
|
626
|
+
seq,
|
|
623
627
|
);
|
|
624
628
|
}
|
|
625
629
|
|
|
626
|
-
async function sendDataPointEnum(entity, dp, value, cmd,
|
|
627
|
-
await sendDataPoint(
|
|
630
|
+
async function sendDataPointEnum(entity, dp, value, cmd, seq=undefined) {
|
|
631
|
+
return await sendDataPoint(
|
|
628
632
|
entity,
|
|
629
633
|
dataTypes.enum,
|
|
630
634
|
dp,
|
|
631
635
|
[value],
|
|
632
636
|
cmd,
|
|
633
|
-
|
|
637
|
+
seq,
|
|
634
638
|
);
|
|
635
639
|
}
|
|
636
640
|
|
|
637
|
-
async function sendDataPointRaw(entity, dp, value, cmd,
|
|
638
|
-
await sendDataPoint(
|
|
641
|
+
async function sendDataPointRaw(entity, dp, value, cmd, seq=undefined) {
|
|
642
|
+
return await sendDataPoint(
|
|
639
643
|
entity,
|
|
640
644
|
dataTypes.raw,
|
|
641
645
|
dp,
|
|
642
646
|
value,
|
|
643
647
|
cmd,
|
|
644
|
-
|
|
648
|
+
seq,
|
|
645
649
|
);
|
|
646
650
|
}
|
|
647
651
|
|
|
648
|
-
async function sendDataPointBitmap(entity, dp, value, cmd,
|
|
649
|
-
await sendDataPoint(
|
|
652
|
+
async function sendDataPointBitmap(entity, dp, value, cmd, seq=undefined) {
|
|
653
|
+
return await sendDataPoint(
|
|
650
654
|
entity,
|
|
651
655
|
dataTypes.bitmap,
|
|
652
656
|
dp,
|
|
653
657
|
value,
|
|
654
658
|
cmd,
|
|
655
|
-
|
|
659
|
+
seq,
|
|
656
660
|
);
|
|
657
661
|
}
|
|
658
662
|
|
package/npm-shrinkwrap.json
CHANGED