zigbee-herdsman-converters 14.0.366 → 14.0.367

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.
@@ -1690,10 +1690,11 @@ const converters = {
1690
1690
  type: ['commandDataResponse', 'commandDataReport'],
1691
1691
  convert: (model, msg, publish, options, meta) => {
1692
1692
  const multiEndpoint = model.meta && model.meta.multiEndpoint;
1693
- const dp = msg.data.dp;
1694
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
1693
+ const dpValue = tuya.firstDpValue(msg, meta, 'moes_105_dimmer');
1694
+ const dp = dpValue.dp;
1695
+ const value = tuya.getDataValue(dpValue);
1695
1696
 
1696
- meta.logger.debug(`from moes_105_dimmer, msg.data.dp=[${dp}], msg.data.datatype=[${msg.data.datatype}], value=[${value}]`);
1697
+ meta.logger.debug(`from moes_105_dimmer, dp=[${dp}], datatype=[${dpValue.datatype}], value=[${value}]`);
1697
1698
 
1698
1699
  const state = value ? 'ON': 'OFF';
1699
1700
  const brightness = mapNumberRange(value, 0, 1000, 0, 254);
@@ -1709,7 +1710,7 @@ const converters = {
1709
1710
  return {brightness_l2: brightness};
1710
1711
  default:
1711
1712
  meta.logger.debug(`zigbee-herdsman-converters:moes_105_dimmer:` +
1712
- `NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(msg.data)}`);
1713
+ `NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(dpValue)}`);
1713
1714
  }
1714
1715
  },
1715
1716
  },
@@ -1785,8 +1786,9 @@ const converters = {
1785
1786
  options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
1786
1787
  exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
1787
1788
  convert: (model, msg, publish, options, meta) => {
1788
- const dp = msg.data.dp;
1789
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
1789
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_temperature_humidity_sensor');
1790
+ const dp = dpValue.dp;
1791
+ const value = tuya.getDataValue(dpValue);
1790
1792
  switch (dp) {
1791
1793
  case 1:
1792
1794
  return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
@@ -1796,7 +1798,7 @@ const converters = {
1796
1798
  return {battery: value};
1797
1799
  default:
1798
1800
  meta.logger.warn(`zigbee-herdsman-converters:maa_tuya_temp_sensor: NOT RECOGNIZED ` +
1799
- `DP #${dp} with data ${JSON.stringify(msg.data)}`);
1801
+ `DP #${dp} with data ${JSON.stringify(dpValue)}`);
1800
1802
  }
1801
1803
  },
1802
1804
  },
@@ -1806,8 +1808,9 @@ const converters = {
1806
1808
  options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
1807
1809
  exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
1808
1810
  convert: (model, msg, publish, options, meta) => {
1809
- const dp = msg.data.dp;
1810
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
1811
+ const dpValue = tuya.firstDpValue(msg, meta, 'nous_lcd_temperature_humidity_sensor');
1812
+ const dp = dpValue.dp;
1813
+ const value = tuya.getDataValue(dpValue);
1811
1814
  switch (dp) {
1812
1815
  case tuya.dataPoints.nousTemperature:
1813
1816
  return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
@@ -1827,7 +1830,7 @@ const converters = {
1827
1830
  return {temperature_sensitivity: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
1828
1831
  default:
1829
1832
  meta.logger.warn(`zigbee-herdsman-converters:nous_lcd_temperature_humidity_sensor: NOT RECOGNIZED ` +
1830
- `DP #${dp} with data ${JSON.stringify(msg.data)}`);
1833
+ `DP #${dp} with data ${JSON.stringify(dpValue)}`);
1831
1834
  }
1832
1835
  },
1833
1836
  },
@@ -1837,8 +1840,9 @@ const converters = {
1837
1840
  options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
1838
1841
  exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
1839
1842
  convert: (model, msg, publish, options, meta) => {
1840
- const dp = msg.data.dp;
1841
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
1843
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_illuminance_temperature_humidity_sensor');
1844
+ const dp = dpValue.dp;
1845
+ const value = tuya.getDataValue(dpValue);
1842
1846
  switch (dp) {
1843
1847
  case tuya.dataPoints.thitTemperature:
1844
1848
  return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
@@ -1850,7 +1854,7 @@ const converters = {
1850
1854
  return {illuminance_lux: value};
1851
1855
  default:
1852
1856
  meta.logger.warn(`zigbee-herdsman-converters:tuya_illuminance_temperature_humidity_sensor: NOT RECOGNIZED ` +
1853
- `DP #${dp} with data ${JSON.stringify(msg.data)}`);
1857
+ `DP #${dp} with data ${JSON.stringify(dpValue)}`);
1854
1858
  }
1855
1859
  },
1856
1860
  },
@@ -1887,8 +1891,9 @@ const converters = {
1887
1891
  cluster: 'manuSpecificTuya',
1888
1892
  type: ['commandDataResponse', 'commandDataReport'],
1889
1893
  convert: (model, msg, publish, options, meta) => {
1890
- const dp = msg.data.dp;
1891
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
1894
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_thermostat_weekly_schedule');
1895
+ const dp = dpValue.dp;
1896
+ const value = tuya.getDataValue(dpValue);
1892
1897
 
1893
1898
  const thermostatMeta = getMetaValue(msg.endpoint, model, 'thermostat');
1894
1899
  const firstDayDpId = thermostatMeta.weeklyScheduleFirstDayDpId;
@@ -1936,8 +1941,9 @@ const converters = {
1936
1941
  cluster: 'manuSpecificTuya',
1937
1942
  type: ['commandDataReport', 'commandDataResponse'],
1938
1943
  convert: (model, msg, publish, options, meta) => {
1939
- const dp = msg.data.dp;
1940
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
1944
+ const dpValue = tuya.firstDpValue(msg, meta, 'hy_thermostat');
1945
+ const dp = dpValue.dp;
1946
+ const value = tuya.getDataValue(dpValue);
1941
1947
 
1942
1948
  switch (dp) {
1943
1949
  case tuya.dataPoints.hyWorkdaySchedule1: // schedule for workdays [5,9,12,8,0,15,10,0,15]
@@ -2010,7 +2016,7 @@ const converters = {
2010
2016
  return {alarm: (value > 0) ? true : false};
2011
2017
  default: // The purpose of the codes 17 & 19 are still unknown
2012
2018
  meta.logger.warn(`zigbee-herdsman-converters:hy_thermostat: Unrecognized DP #${
2013
- dp} with data ${JSON.stringify(msg.data)}`);
2019
+ dp} with data ${JSON.stringify(dpValue)}`);
2014
2020
  }
2015
2021
  },
2016
2022
  },
@@ -2070,8 +2076,9 @@ const converters = {
2070
2076
  // Protocol description
2071
2077
  // https://github.com/Koenkk/zigbee-herdsman-converters/issues/1159#issuecomment-614659802
2072
2078
 
2073
- const dp = msg.data.dp;
2074
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
2079
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_cover');
2080
+ const dp = dpValue.dp;
2081
+ const value = tuya.getDataValue(dpValue);
2075
2082
 
2076
2083
  switch (dp) {
2077
2084
  case tuya.dataPoints.coverPosition: // Started moving to position (triggered from Zigbee)
@@ -2097,7 +2104,7 @@ const converters = {
2097
2104
  break;
2098
2105
  default: // Unknown code
2099
2106
  meta.logger.warn(`TuYa_cover_control: Unhandled DP #${dp} for ${meta.device.manufacturerName}:
2100
- ${JSON.stringify(msg.data)}`);
2107
+ ${JSON.stringify(dpValue)}`);
2101
2108
  }
2102
2109
  },
2103
2110
  },
@@ -2391,8 +2398,9 @@ const converters = {
2391
2398
  options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
2392
2399
  exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
2393
2400
  convert: (model, msg, publish, options, meta) => {
2394
- const dp = msg.data.dp;
2395
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
2401
+ const dpValue = tuya.firstDpValue(msg, meta, 'neo_nas_pd07');
2402
+ const dp = dpValue.dp;
2403
+ const value = tuya.getDataValue(dpValue);
2396
2404
 
2397
2405
  if (dp === 101) return {occupancy: value > 0 ? true : false};
2398
2406
  else if (dp === 102) {
@@ -2407,7 +2415,7 @@ const converters = {
2407
2415
  } else if (dp === 105) {
2408
2416
  return {humidity: calibrateAndPrecisionRoundOptions(value, options, 'humidity')};
2409
2417
  } else {
2410
- meta.logger.warn(`zigbee-herdsman-converters:NEO-PD07: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(msg.data)}`);
2418
+ meta.logger.warn(`zigbee-herdsman-converters:NEO-PD07: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(dpValue)}`);
2411
2419
  }
2412
2420
  },
2413
2421
  },
@@ -2415,8 +2423,9 @@ const converters = {
2415
2423
  cluster: 'manuSpecificTuya',
2416
2424
  type: ['commandDataReport', 'commandDataResponse'],
2417
2425
  convert: (model, msg, publish, options, meta) => {
2418
- const dp = msg.data.dp;
2419
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
2426
+ const dpValue = tuya.firstDpValue(msg, meta, 'neo_t_h_alarm');
2427
+ const dp = dpValue.dp;
2428
+ const value = tuya.getDataValue(dpValue);
2420
2429
 
2421
2430
  switch (dp) {
2422
2431
  case tuya.dataPoints.neoAlarm:
@@ -2453,7 +2462,7 @@ const converters = {
2453
2462
  case tuya.dataPoints.neoVolume: // 0x0474 [0]/[1]/[2] Volume 0-max, 2-low
2454
2463
  return {volume: {2: 'low', 1: 'medium', 0: 'high'}[value]};
2455
2464
  default: // Unknown code
2456
- meta.logger.warn(`Unhandled DP #${dp}: ${JSON.stringify(msg.data)}`);
2465
+ meta.logger.warn(`Unhandled DP #${dp}: ${JSON.stringify(dpValue)}`);
2457
2466
  }
2458
2467
  },
2459
2468
  },
@@ -2560,8 +2569,9 @@ const converters = {
2560
2569
  cluster: 'manuSpecificTuya',
2561
2570
  type: 'commandDataReport',
2562
2571
  convert: (model, msg, publish, options, meta) => {
2563
- if (msg.data.dp === tuya.dataPoints.waterLeak) {
2564
- return {water_leak: tuya.getDataValue(msg.data.datatype, msg.data.data)};
2572
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_water_leak');
2573
+ if (dpValue.dp === tuya.dataPoints.waterLeak) {
2574
+ return {water_leak: tuya.getDataValue(dpValue)};
2565
2575
  }
2566
2576
  },
2567
2577
  },
@@ -2924,8 +2934,9 @@ const converters = {
2924
2934
  cluster: 'manuSpecificTuya',
2925
2935
  type: ['commandDataResponse', 'commandDataReport'],
2926
2936
  convert: (model, msg, publish, options, meta) => {
2927
- const dp = msg.data.dp;
2928
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
2937
+ const dpValue = tuya.firstDpValue(msg, meta, 'silvercrest_smart_led_string');
2938
+ const dp = dpValue.dp;
2939
+ const value = tuya.getDataValue(dpValue);
2929
2940
  const result = {};
2930
2941
 
2931
2942
  if (dp === tuya.dataPoints.silvercrestChangeMode) {
@@ -3547,8 +3558,9 @@ const converters = {
3547
3558
  cluster: 'manuSpecificTuya',
3548
3559
  type: ['commandDataResponse', 'commandDataReport'],
3549
3560
  convert: (model, msg, publish, options, meta) => {
3550
- const dp = msg.data.dp;
3551
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
3561
+ const dpValue = tuya.firstDpValue(msg, meta, 'moes_thermostat');
3562
+ const dp = dpValue.dp;
3563
+ const value = tuya.getDataValue(dpValue);
3552
3564
  let temperature;
3553
3565
  /* See tuyaThermostat above for message structure comment */
3554
3566
  switch (dp) {
@@ -3612,7 +3624,7 @@ const converters = {
3612
3624
  }
3613
3625
  default: // DataPoint 17 is unknown
3614
3626
  meta.logger.warn(`zigbee-herdsman-converters:Moes BHT-002: Unrecognized DP #${
3615
- dp} with data ${JSON.stringify(msg.data)}`);
3627
+ dp} with data ${JSON.stringify(dpValue)}`);
3616
3628
  }
3617
3629
  },
3618
3630
  },
@@ -3620,8 +3632,9 @@ const converters = {
3620
3632
  cluster: 'manuSpecificTuya',
3621
3633
  type: ['commandDataResponse', 'commandDataReport'],
3622
3634
  convert: (model, msg, publish, options, meta) => {
3623
- const dp = msg.data.dp; // First we get the data point ID
3624
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
3635
+ const dpValue = tuya.firstDpValue(msg, meta, 'moesS_thermostat');
3636
+ const dp = dpValue.dp; // First we get the data point ID
3637
+ const value = tuya.getDataValue(dpValue);
3625
3638
  const presetLookup = {0: 'programming', 1: 'manual', 2: 'temporary_manual', 3: 'holiday'};
3626
3639
  switch (dp) {
3627
3640
  case tuya.dataPoints.moesSsystemMode:
@@ -3672,7 +3685,7 @@ const converters = {
3672
3685
  }
3673
3686
  default:
3674
3687
  meta.logger.warn(`zigbee-herdsman-converters:moesS_thermostat: NOT RECOGNIZED DP #${
3675
- dp} with data ${JSON.stringify(msg.data)}`);
3688
+ dp} with data ${JSON.stringify(dpValue)}`);
3676
3689
  }
3677
3690
  },
3678
3691
  },
@@ -3680,8 +3693,9 @@ const converters = {
3680
3693
  cluster: 'manuSpecificTuya',
3681
3694
  type: ['commandDataResponse', 'commandDataReport'],
3682
3695
  convert: (model, msg, publish, options, meta) => {
3683
- const dp = msg.data.dp;
3684
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
3696
+ const dpValue = tuya.firstDpValue(msg, meta, 'tvtwo_thermostat');
3697
+ const dp = dpValue.dp;
3698
+ const value = tuya.getDataValue(dpValue);
3685
3699
  const presetLookup = {0: 'auto', 1: 'manual', 2: 'holiday'};
3686
3700
  switch (dp) {
3687
3701
  case tuya.dataPoints.tvMode:
@@ -3823,7 +3837,7 @@ const converters = {
3823
3837
 
3824
3838
  default:
3825
3839
  meta.logger.warn(`zigbee-herdsman-converters:tvtwo_thermostat: NOT RECOGNIZED DP #${
3826
- dp} with data ${JSON.stringify(msg.data)}`);
3840
+ dp} with data ${JSON.stringify(dpValue)}`);
3827
3841
  }
3828
3842
  },
3829
3843
  },
@@ -3831,8 +3845,9 @@ const converters = {
3831
3845
  cluster: 'manuSpecificTuya',
3832
3846
  type: ['commandDataResponse', 'commandDataReport'],
3833
3847
  convert: (model, msg, publish, options, meta) => {
3834
- const dp = msg.data.dp; // First we get the data point ID
3835
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
3848
+ const dpValue = tuya.firstDpValue(msg, meta, 'haozee_thermostat');
3849
+ const dp = dpValue.dp; // First we get the data point ID
3850
+ const value = tuya.getDataValue(dpValue);
3836
3851
  const presetLookup = {0: 'auto', 1: 'manual', 2: 'off', 3: 'on'};
3837
3852
  switch (dp) {
3838
3853
  case tuya.dataPoints.haozeeSystemMode:
@@ -3938,7 +3953,7 @@ const converters = {
3938
3953
  break;
3939
3954
  default:
3940
3955
  meta.logger.warn(`zigbee-herdsman-converters:haozee: NOT RECOGNIZED DP #${
3941
- dp} with data ${JSON.stringify(msg.data)}`);
3956
+ dp} with data ${JSON.stringify(dpValue)}`);
3942
3957
  }
3943
3958
  },
3944
3959
  },
@@ -3951,8 +3966,9 @@ const converters = {
3951
3966
  exposes.options.precision('voc'), exposes.options.calibration('voc'),
3952
3967
  exposes.options.precision('formaldehyd'), exposes.options.calibration('formaldehyd')],
3953
3968
  convert: (model, msg, publish, options, meta) => {
3954
- const dp = msg.data.dp;
3955
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
3969
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_air_quality');
3970
+ const dp = dpValue.dp;
3971
+ const value = tuya.getDataValue(dpValue);
3956
3972
  switch (dp) {
3957
3973
  case tuya.dataPoints.tuyaSabTemp:
3958
3974
  return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
@@ -3967,7 +3983,7 @@ const converters = {
3967
3983
  return {formaldehyd: calibrateAndPrecisionRoundOptions(value, options, 'formaldehyd')};
3968
3984
  default:
3969
3985
  meta.logger.warn(`zigbee-herdsman-converters:TuyaSmartAirBox: Unrecognized DP #${
3970
- dp} with data ${JSON.stringify(msg.data)}`);
3986
+ dp} with data ${JSON.stringify(dpValue)}`);
3971
3987
  }
3972
3988
  },
3973
3989
  },
@@ -3975,8 +3991,9 @@ const converters = {
3975
3991
  cluster: 'manuSpecificTuya',
3976
3992
  type: ['commandDataResponse', 'commandDataReport'],
3977
3993
  convert: (model, msg, publish, options, meta) => {
3978
- const dp = msg.data.dp;
3979
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
3994
+ const dpValue = tuya.firstDpValue(msg, meta, 'saswell_thermostat');
3995
+ const dp = dpValue.dp;
3996
+ const value = tuya.getDataValue(dpValue);
3980
3997
 
3981
3998
  switch (dp) {
3982
3999
  case tuya.dataPoints.saswellHeating:
@@ -4091,7 +4108,7 @@ const converters = {
4091
4108
  return {anti_scaling: value ? 'ON' : 'OFF'};
4092
4109
  default:
4093
4110
  meta.logger.warn(`zigbee-herdsman-converters:SaswellThermostat: Unrecognized DP #${
4094
- dp} with data ${JSON.stringify(msg.data)}`);
4111
+ dp} with data ${JSON.stringify(dpValue)}`);
4095
4112
  }
4096
4113
  },
4097
4114
  },
@@ -4099,8 +4116,9 @@ const converters = {
4099
4116
  cluster: 'manuSpecificTuya',
4100
4117
  type: ['commandDataResponse', 'commandDataReport'],
4101
4118
  convert: (model, msg, publish, options, meta) => {
4102
- const dp = msg.data.dp;
4103
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4119
+ const dpValue = tuya.firstDpValue(msg, meta, 'etop_thermostat');
4120
+ const dp = dpValue.dp;
4121
+ const value = tuya.getDataValue(dpValue);
4104
4122
 
4105
4123
  if (dp >= 101 && dp <=107) return; // handled by tuya_thermostat_weekly_schedule
4106
4124
 
@@ -4140,7 +4158,7 @@ const converters = {
4140
4158
  return {running_state: value ? 'heat' : 'idle'};
4141
4159
  default:
4142
4160
  meta.logger.warn(`zigbee-herdsman-converters:eTopThermostat: Unrecognized DP #${
4143
- dp} with data ${JSON.stringify(msg.data)}`);
4161
+ dp} with data ${JSON.stringify(dpValue)}`);
4144
4162
  }
4145
4163
  },
4146
4164
  },
@@ -4148,8 +4166,9 @@ const converters = {
4148
4166
  cluster: 'manuSpecificTuya',
4149
4167
  type: ['commandDataResponse', 'commandDataReport'],
4150
4168
  convert: (model, msg, publish, options, meta) => {
4151
- const dp = msg.data.dp;
4152
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4169
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_thermostat');
4170
+ const dp = dpValue.dp;
4171
+ const value = tuya.getDataValue(dpValue);
4153
4172
 
4154
4173
  switch (dp) {
4155
4174
  case tuya.dataPoints.windowDetection:
@@ -4246,7 +4265,7 @@ const converters = {
4246
4265
  return {week: tuya.thermostatWeekFormat[value]};
4247
4266
  default: // The purpose of the dps 17 & 19 is still unknown
4248
4267
  console.log(`zigbee-herdsman-converters:tuyaThermostat: Unrecognized DP #${
4249
- dp} with data ${JSON.stringify(msg.data)}`);
4268
+ dp} with data ${JSON.stringify(dpValue)}`);
4250
4269
  }
4251
4270
  },
4252
4271
  },
@@ -4254,12 +4273,13 @@ const converters = {
4254
4273
  cluster: 'manuSpecificTuya',
4255
4274
  type: ['commandDataResponse', 'commandDataReport'],
4256
4275
  convert: (model, msg, publish, options, meta) => {
4257
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4258
- if (msg.data.dp === tuya.dataPoints.state) {
4276
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_dimmer');
4277
+ const value = tuya.getDataValue(dpValue);
4278
+ if (dpValue.dp === tuya.dataPoints.state) {
4259
4279
  return {state: value ? 'ON': 'OFF'};
4260
4280
  } else if (meta.device.manufacturerName === '_TZE200_swaamsoy') {
4261
4281
  // https://github.com/Koenkk/zigbee-herdsman-converters/pull/3004
4262
- if (msg.data.dp === 2) {
4282
+ if (dpValue.dp === 2) {
4263
4283
  return {brightness: mapNumberRange(value, 10, 1000, 0, 254)};
4264
4284
  }
4265
4285
  } else { // TODO: Unknown dp, assumed value type
@@ -4280,18 +4300,22 @@ const converters = {
4280
4300
  }
4281
4301
  return hex;
4282
4302
  };
4283
- let dataStr =
4284
- Date.now().toString() + ' ' +
4285
- meta.device.ieeeAddr + ' ' +
4286
- getHex(msg.data.seq) + ' ' +
4287
- getHex(msg.data.dp) + ' ' +
4288
- getHex(msg.data.datatype) + ' ' +
4289
- getHex(msg.data.fn);
4290
-
4291
- msg.data.data.forEach((elem) => {
4292
- dataStr += ' ' + getHex(elem);
4293
- });
4294
- dataStr += '\n';
4303
+ const now = Date.now().toString();
4304
+ let dataStr = '';
4305
+ for (const [i, dpValue] of msg.data.dpValues.entries()) {
4306
+ dataStr +=
4307
+ now + ' ' +
4308
+ meta.device.ieeeAddr + ' ' +
4309
+ getHex(msg.data.seq) + ' ' +
4310
+ getHex(i) + ' ' +
4311
+ getHex(dpValue.dp) + ' ' +
4312
+ getHex(dpValue.datatype);
4313
+
4314
+ dpValue.data.forEach((elem) => {
4315
+ dataStr += ' ' + getHex(elem);
4316
+ });
4317
+ dataStr += '\n';
4318
+ }
4295
4319
  const fs = require('fs');
4296
4320
  fs.appendFile('data/tuya.dump.txt', dataStr, (err) => {
4297
4321
  if (err) throw err;
@@ -4336,7 +4360,8 @@ const converters = {
4336
4360
  cluster: 'manuSpecificTuya',
4337
4361
  type: 'commandDataResponse',
4338
4362
  convert: (model, msg, publish, options, meta) => {
4339
- msg.data.occupancy = msg.data.dp === tuya.dataPoints.occupancy ? 1 : 0;
4363
+ const dpValue = tuya.firstDpValue(msg, meta, 'blitzwolf_occupancy_with_timeout');
4364
+ msg.data.occupancy = dpValue.dp === tuya.dataPoints.occupancy ? 1 : 0;
4340
4365
  return converters.occupancy_with_timeout.convert(model, msg, publish, options, meta);
4341
4366
  },
4342
4367
  },
@@ -4633,8 +4658,9 @@ const converters = {
4633
4658
  cluster: 'manuSpecificTuya',
4634
4659
  type: ['commandDataResponse', 'commandDataReport', 'commandActiveStatusReport'],
4635
4660
  convert: (model, msg, publish, options, meta) => {
4636
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4637
- const dp = msg.data.dp;
4661
+ const dpValue = tuya.firstDpValue(msg, meta, 'frankever_valve');
4662
+ const value = tuya.getDataValue(dpValue);
4663
+ const dp = dpValue.dp;
4638
4664
  switch (dp) {
4639
4665
  case tuya.dataPoints.state: {
4640
4666
  return {state: value ? 'ON': 'OFF'};
@@ -4647,7 +4673,7 @@ const converters = {
4647
4673
  }
4648
4674
  default: {
4649
4675
  meta.logger.warn(`zigbee-herdsman-converters:FrankeverValve: NOT RECOGNIZED DP ` +
4650
- `#${dp} with data ${JSON.stringify(msg.data)}`);
4676
+ `#${dp} with data ${JSON.stringify(dpValue)}`);
4651
4677
  }
4652
4678
  }
4653
4679
  },
@@ -4656,13 +4682,14 @@ const converters = {
4656
4682
  cluster: 'manuSpecificTuya',
4657
4683
  type: ['commandDataResponse'],
4658
4684
  convert: (model, msg, publish, options, meta) => {
4659
- const dp = msg.data.dp;
4660
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4685
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_smoke');
4686
+ const dp = dpValue.dp;
4687
+ const value = tuya.getDataValue(dpValue);
4661
4688
  switch (dp) {
4662
4689
  case tuya.dataPoints.state:
4663
4690
  return {smoke: value === 0};
4664
4691
  default:
4665
- meta.logger.warn(`zigbee-herdsman-converters:tuya_smoke: Unrecognized DP #${ dp} with data ${JSON.stringify(msg.data)}`);
4692
+ meta.logger.warn(`zigbee-herdsman-converters:tuya_smoke: Unrecognized DP #${ dp} with data ${JSON.stringify(dpValue)}`);
4666
4693
  }
4667
4694
  },
4668
4695
  },
@@ -4670,8 +4697,9 @@ const converters = {
4670
4697
  cluster: 'manuSpecificTuya',
4671
4698
  type: ['commandDataResponse'],
4672
4699
  convert: (model, msg, publish, options, meta) => {
4673
- const dp = msg.data.dp;
4674
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4700
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_woox_smoke');
4701
+ const dp = dpValue.dp;
4702
+ const value = tuya.getDataValue(dpValue);
4675
4703
  switch (dp) {
4676
4704
  case tuya.dataPoints.wooxBattery:
4677
4705
  return {battery_low: value === 0};
@@ -4680,7 +4708,7 @@ const converters = {
4680
4708
  case tuya.dataPoints.wooxSmokeTest:
4681
4709
  return {smoke: value};
4682
4710
  default:
4683
- meta.logger.warn(`zigbee-herdsman-converters:tuya_smoke: Unrecognized DP #${ dp} with data ${JSON.stringify(msg.data)}`);
4711
+ meta.logger.warn(`zigbee-herdsman-converters:tuya_smoke: Unrecognized DP #${ dp} with data ${JSON.stringify(dpValue)}`);
4684
4712
  }
4685
4713
  },
4686
4714
  },
@@ -4689,8 +4717,9 @@ const converters = {
4689
4717
  type: ['commandDataReport', 'commandDataResponse', 'commandActiveStatusReport'],
4690
4718
  convert: (model, msg, publish, options, meta) => {
4691
4719
  const multiEndpoint = model.meta && model.meta.multiEndpoint;
4692
- const dp = msg.data.dp;
4693
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4720
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_switch');
4721
+ const dp = dpValue.dp;
4722
+ const value = tuya.getDataValue(dpValue);
4694
4723
  const state = value ? 'ON' : 'OFF';
4695
4724
  if (multiEndpoint) {
4696
4725
  const lookup = {1: 'l1', 2: 'l2', 3: 'l3', 4: 'l4'};
@@ -4708,8 +4737,9 @@ const converters = {
4708
4737
  cluster: 'manuSpecificTuya',
4709
4738
  type: ['commandDataReport', 'commandDataResponse', 'commandActiveStatusReport'],
4710
4739
  convert: (model, msg, publish, options, meta) => {
4711
- const dp = msg.data.dp;
4712
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
4740
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_dinrail_switch');
4741
+ const dp = dpValue.dp;
4742
+ const value = tuya.getDataValue(dpValue);
4713
4743
  const state = value ? 'ON' : 'OFF';
4714
4744
 
4715
4745
  switch (dp) {
@@ -4725,7 +4755,7 @@ const converters = {
4725
4755
  return {voltage: value/10};
4726
4756
  default:
4727
4757
  meta.logger.warn(`zigbee-herdsman-converters:TuyaDinRailSwitch: NOT RECOGNIZED DP ` +
4728
- `#${dp} with data ${JSON.stringify(msg.data)}`);
4758
+ `#${dp} with data ${JSON.stringify(dpValue)}`);
4729
4759
  }
4730
4760
 
4731
4761
  return null;
@@ -4985,6 +5015,11 @@ const converters = {
4985
5015
  value = data.readUInt16LE(i+2);
4986
5016
  i += 3;
4987
5017
  break;
5018
+ case 34:
5019
+ // 0x22 Zcl24BitUint
5020
+ value = data.readUIntLE(i+2, 3);
5021
+ i += 4;
5022
+ break;
4988
5023
  case 35:
4989
5024
  // 0x23 Zcl32BitUint
4990
5025
  value = data.readUInt32LE(i+2);
@@ -4992,9 +5027,19 @@ const converters = {
4992
5027
  break;
4993
5028
  case 36:
4994
5029
  // 0x24 Zcl40BitUint
4995
- value = [data.readUInt32LE(i+2), data.readUInt8(i+6)];
5030
+ value = data.readUIntLE(i+2, 5);
4996
5031
  i += 6;
4997
5032
  break;
5033
+ case 37:
5034
+ // 0x25 Zcl48BitUint
5035
+ value = data.readUIntLE(i+2, 6);
5036
+ i += 7;
5037
+ break;
5038
+ case 38:
5039
+ // 0x26 Zcl56BitUint
5040
+ value = data.readUIntLE(i+2, 7);
5041
+ i += 8;
5042
+ break;
4998
5043
  case 39:
4999
5044
  // 0x27 Zcl64BitUint
5000
5045
  value = data.readBigUInt64BE(i+2);
@@ -5010,11 +5055,31 @@ const converters = {
5010
5055
  value = data.readInt16LE(i+2);
5011
5056
  i += 3;
5012
5057
  break;
5058
+ case 42:
5059
+ // 0x2A Zcl24BitInt
5060
+ value = data.readIntLE(i+2, 3);
5061
+ i += 4;
5062
+ break;
5013
5063
  case 43:
5014
5064
  // 0x2B Zcl32BitInt
5015
5065
  value = data.readInt32LE(i+2);
5016
5066
  i += 5;
5017
5067
  break;
5068
+ case 44:
5069
+ // 0x2C Zcl40BitInt
5070
+ value = data.readIntLE(i+2, 5);
5071
+ i += 6;
5072
+ break;
5073
+ case 45:
5074
+ // 0x2D Zcl48BitInt
5075
+ value = data.readIntLE(i+2, 6);
5076
+ i += 7;
5077
+ break;
5078
+ case 46:
5079
+ // 0x2E Zcl56BitInt
5080
+ value = data.readIntLE(i+2, 7);
5081
+ i += 8;
5082
+ break;
5018
5083
  case 47:
5019
5084
  // 0x2F Zcl64BitInt
5020
5085
  value = data.readBigInt64BE(i+2);
@@ -6072,8 +6137,9 @@ const converters = {
6072
6137
  cluster: 'manuSpecificTuya',
6073
6138
  type: ['commandDataReport', 'commandDataResponse'],
6074
6139
  convert: (model, msg, publish, options, meta) => {
6075
- const dp = msg.data.dp;
6076
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
6140
+ const dpValue = tuya.firstDpValue(msg, meta, 'javis_microwave_sensor');
6141
+ const dp = dpValue.dp;
6142
+ const value = tuya.getDataValue(dpValue);
6077
6143
  const lookup = {
6078
6144
  0: 'no_motion',
6079
6145
  1: 'big_motion',
@@ -6135,7 +6201,7 @@ const converters = {
6135
6201
  }
6136
6202
  default:
6137
6203
  meta.logger.warn(`zigbee-herdsman-converters:javis_microwave_sensor: NOT RECOGNIZED ` +
6138
- `DP #${dp} with data ${JSON.stringify(msg.data)}`);
6204
+ `DP #${dp} with data ${JSON.stringify(dpValue)}`);
6139
6205
  }
6140
6206
  },
6141
6207
  },
@@ -6279,8 +6345,9 @@ const converters = {
6279
6345
  cluster: 'manuSpecificTuya',
6280
6346
  type: 'commandDataResponse',
6281
6347
  convert: (model, msg, publish, options, meta) => {
6282
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
6283
- const dp = msg.data.dp;
6348
+ const dpValue = tuya.firstDpValue(msg, meta, 'ZVG1');
6349
+ const value = tuya.getDataValue(dpValue);
6350
+ const dp = dpValue.dp;
6284
6351
  switch (dp) {
6285
6352
  case tuya.dataPoints.state: {
6286
6353
  return {state: value ? 'ON': 'OFF'};
@@ -6307,7 +6374,7 @@ const converters = {
6307
6374
  }
6308
6375
  default: {
6309
6376
  meta.logger.warn(`zigbee-herdsman-converters:RTXZVG1Valve: NOT RECOGNIZED DP ` +
6310
- `#${dp} with data ${JSON.stringify(msg.data)}`);
6377
+ `#${dp} with data ${JSON.stringify(dpValue)}`);
6311
6378
  }
6312
6379
  }
6313
6380
  },
@@ -6843,8 +6910,9 @@ const converters = {
6843
6910
  cluster: 'manuSpecificTuya',
6844
6911
  type: ['commandDataResponse', 'commandDataReport'],
6845
6912
  convert: (model, msg, publish, options, meta) => {
6846
- const dp = msg.data.dp;
6847
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
6913
+ const dpValue = tuya.firstDpValue(msg, meta, 'SLUXZB');
6914
+ const dp = dpValue.dp;
6915
+ const value = tuya.getDataValue(dpValue);
6848
6916
  switch (dp) {
6849
6917
  case 2:
6850
6918
  return {illuminance_lux: value.toFixed(0)};
@@ -6853,7 +6921,7 @@ const converters = {
6853
6921
  case 1:
6854
6922
  return {battery_low: value.toFixed(1)};
6855
6923
  default:
6856
- meta.logger.warn(`s_lux_zb_illuminance: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(msg.data)}`);
6924
+ meta.logger.warn(`s_lux_zb_illuminance: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(dpValue)}`);
6857
6925
  }
6858
6926
  },
6859
6927
  },
@@ -6863,8 +6931,9 @@ const converters = {
6863
6931
  options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
6864
6932
  exposes.options.precision('humidity'), exposes.options.calibration('humidity')],
6865
6933
  convert: (model, msg, publish, options, meta) => {
6866
- const dp = msg.data.dp;
6867
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
6934
+ const dpValue = tuya.firstDpValue(msg, meta, 'ZB003X');
6935
+ const dp = dpValue.dp;
6936
+ const value = tuya.getDataValue(dpValue);
6868
6937
 
6869
6938
  switch (dp) {
6870
6939
  case tuya.dataPoints.fantemTemp:
@@ -6893,7 +6962,7 @@ const converters = {
6893
6962
  return {reporting_enable: value};
6894
6963
  default:
6895
6964
  meta.logger.warn(`zigbee-herdsman-converters:FantemZB003X: Unrecognized DP #${
6896
- dp} with data ${JSON.stringify(msg.data)}`);
6965
+ dp} with data ${JSON.stringify(dpValue)}`);
6897
6966
  }
6898
6967
  },
6899
6968
  },
@@ -6926,15 +6995,16 @@ const converters = {
6926
6995
  cluster: 'manuSpecificTuya',
6927
6996
  type: ['commandDataResponse'],
6928
6997
  convert: (model, msg, publish, options, meta) => {
6929
- const dp = msg.data.dp;
6930
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
6998
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_gas');
6999
+ const dp = dpValue.dp;
7000
+ const value = tuya.getDataValue(dpValue);
6931
7001
 
6932
7002
  switch (dp) {
6933
7003
  case tuya.dataPoints.state:
6934
7004
  return {gas: value === 0 ? true : false};
6935
7005
  default:
6936
7006
  meta.logger.warn(`zigbee-herdsman-converters:tuya_gas: Unrecognized DP #${
6937
- dp} with data ${JSON.stringify(msg.data)}`);
7007
+ dp} with data ${JSON.stringify(dpValue)}`);
6938
7008
  }
6939
7009
  },
6940
7010
  },
@@ -6942,15 +7012,16 @@ const converters = {
6942
7012
  cluster: 'manuSpecificTuya',
6943
7013
  type: ['commandActiveStatusReport'],
6944
7014
  convert: (model, msg, publish, options, meta) => {
6945
- const dp = msg.data.dp;
6946
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
7015
+ const dpValue = tuya.firstDpValue(msg, meta, 'woox_R7060');
7016
+ const dp = dpValue.dp;
7017
+ const value = tuya.getDataValue(dpValue);
6947
7018
 
6948
7019
  switch (dp) {
6949
7020
  case tuya.dataPoints.wooxSwitch:
6950
7021
  return {state: value === 2 ? 'OFF' : 'ON'};
6951
7022
  default:
6952
7023
  meta.logger.warn(`zigbee-herdsman-converters:WooxR7060: Unrecognized DP #${
6953
- dp} with data ${JSON.stringify(msg.data)}`);
7024
+ dp} with data ${JSON.stringify(dpValue)}`);
6954
7025
  }
6955
7026
  },
6956
7027
  },
@@ -7296,8 +7367,9 @@ const converters = {
7296
7367
  cluster: 'manuSpecificTuya',
7297
7368
  type: ['commandDataResponse'],
7298
7369
  convert: (model, msg, publish, options, meta) => {
7299
- const dp = msg.data.dp;
7300
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
7370
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_motion_sensor');
7371
+ const dp = dpValue.dp;
7372
+ const value = tuya.getDataValue(dpValue);
7301
7373
  let result = null;
7302
7374
  switch (dp) {
7303
7375
  case tuya.dataPoints.state:
@@ -7334,7 +7406,7 @@ const converters = {
7334
7406
  result = {luminance_level: value};
7335
7407
  break;
7336
7408
  default:
7337
- meta.logger.warn(`fromZigbee.tuya_motion_sensor: NOT RECOGNIZED DP ${dp} with data ${JSON.stringify(msg.data)}`);
7409
+ meta.logger.warn(`fromZigbee.tuya_motion_sensor: NOT RECOGNIZED DP ${dp} with data ${JSON.stringify(dpValue)}`);
7338
7410
  }
7339
7411
 
7340
7412
  return result;
@@ -7344,8 +7416,9 @@ const converters = {
7344
7416
  cluster: 'manuSpecificTuya',
7345
7417
  type: ['commandDataResponse', 'commandDataReport'],
7346
7418
  convert: (model, msg, publish, options, meta) => {
7347
- const dp = msg.data.dp;
7348
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
7419
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_radar_sensor');
7420
+ const dp = dpValue.dp;
7421
+ const value = tuya.getDataValue(dpValue);
7349
7422
  switch (dp) {
7350
7423
  case tuya.dataPoints.trsPresenceState:
7351
7424
  return {presence: {0: false, 1: true}[value]};
@@ -7368,8 +7441,9 @@ const converters = {
7368
7441
  cluster: 'manuSpecificTuya',
7369
7442
  type: ['commandDataResponse', 'commandDataReport', 'raw'],
7370
7443
  convert: (model, msg, publish, options, meta) => {
7371
- const dp = msg.data.dp;
7372
- let value = tuya.getDataValue(msg.data.datatype, msg.data.data);
7444
+ const dpValue = tuya.firstDpValue(msg, meta, 'moes_thermostat_tv');
7445
+ const dp = dpValue.dp;
7446
+ let value = tuya.getDataValue(dpValue);
7373
7447
  let result = null;
7374
7448
  switch (dp) {
7375
7449
  case tuya.dataPoints.tvMode:
@@ -7443,7 +7517,7 @@ const converters = {
7443
7517
  }
7444
7518
  break;
7445
7519
  default:
7446
- meta.logger.warn(`fromZigbee.moes_thermostat_tv: NOT RECOGNIZED DP ${dp} with data ${JSON.stringify(msg.data)}`);
7520
+ meta.logger.warn(`fromZigbee.moes_thermostat_tv: NOT RECOGNIZED DP ${dp} with data ${JSON.stringify(dpValue)}`);
7447
7521
  }
7448
7522
 
7449
7523
  return result;
@@ -7477,10 +7551,11 @@ const converters = {
7477
7551
  cluster: 'manuSpecificTuya',
7478
7552
  type: ['commandDataResponse', 'commandDataReport'],
7479
7553
  convert: (model, msg, publish, options, meta) => {
7480
- const dp = msg.data.dp;
7481
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
7554
+ const dpValue = tuya.firstDpValue(msg, meta, 'hoch_din');
7555
+ const dp = dpValue.dp;
7556
+ const value = tuya.getDataValue(dpValue);
7482
7557
  const result = {};
7483
- meta.logger.debug(`from hoch_din, msg.data.dp=[${dp}], msg.data.datatype=[${msg.data.datatype}], value=[${value}]`);
7558
+ meta.logger.debug(`from hoch_din, dp=[${dp}], datatype=[${dpValue.datatype}], value=[${value}]`);
7484
7559
 
7485
7560
  if (dp === tuya.dataPoints.state) {
7486
7561
  result.state = value ? 'ON' : 'OFF';
@@ -5462,7 +5462,7 @@ const converters = {
5462
5462
  }
5463
5463
  }
5464
5464
 
5465
- await tuya.sendDataPoint(entity, tuya.dataTypes.string, tuya.dataPoints.silvercrestSetEffect, data);
5465
+ await tuya.sendDataPointStringBuffer(entity, tuya.dataPoints.silvercrestSetEffect, data);
5466
5466
  } else if (key === 'brightness') {
5467
5467
  await tuya.sendDataPointEnum(entity, tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white);
5468
5468
  // It expects 2 leading zero's.
@@ -5472,7 +5472,10 @@ const converters = {
5472
5472
  const scaled = utils.mapNumberRange(value, 0, 255, 0, 1000);
5473
5473
  data = data.concat(tuya.convertDecimalValueTo2ByteHexArray(scaled));
5474
5474
 
5475
- await tuya.sendDataPoint(entity, tuya.dataTypes.value, tuya.dataPoints.silvercrestSetBrightness, data);
5475
+ await tuya.sendDataPoint(
5476
+ entity,
5477
+ {dp: tuya.dataPoints.silvercrestSetBrightness, datatype: tuya.dataTypes.value, data: data},
5478
+ );
5476
5479
  } else if (key === 'color') {
5477
5480
  await tuya.sendDataPointEnum(entity, tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.color);
5478
5481
 
@@ -5544,7 +5547,7 @@ const converters = {
5544
5547
  data = data.concat(tuya.convertStringToHexArray(hsb.s));
5545
5548
  data = data.concat(tuya.convertStringToHexArray(hsb.b));
5546
5549
 
5547
- await tuya.sendDataPoint(entity, tuya.dataTypes.string, tuya.dataPoints.silvercrestSetColor, data);
5550
+ await tuya.sendDataPointStringBuffer(entity, tuya.dataPoints.silvercrestSetColor, data);
5548
5551
  }
5549
5552
  },
5550
5553
  },
package/devices/lidl.js CHANGED
@@ -40,8 +40,9 @@ const fzLocal = {
40
40
  cluster: 'manuSpecificTuya',
41
41
  type: ['commandDataResponse', 'commandDataReport'],
42
42
  convert: (model, msg, publish, options, meta) => {
43
- const dp = msg.data.dp;
44
- const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
43
+ const dpValue = tuya.firstDpValue(msg, meta, 'zs_thermostat');
44
+ const dp = dpValue.dp;
45
+ const value = tuya.getDataValue(dpValue);
45
46
  const ret = {};
46
47
  const daysMap = {1: 'monday', 2: 'tuesday', 3: 'wednesday', 4: 'thursday', 5: 'friday', 6: 'saturday', 7: 'sunday'};
47
48
  const day = daysMap[value[0]];
@@ -135,7 +136,7 @@ const fzLocal = {
135
136
  ret.away_preset_days = (value[6]<<8)+value[7];
136
137
  return ret;
137
138
  default:
138
- meta.logger.warn(`zigbee-herdsman-converters:zsThermostat: Unrecognized DP #${dp} with data ${JSON.stringify(msg.data)}`);
139
+ meta.logger.warn(`zigbee-herdsman-converters:zsThermostat: Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`);
139
140
  }
140
141
  },
141
142
  },
package/devices/nodon.js CHANGED
@@ -2,8 +2,23 @@ const exposes = require('../lib/exposes');
2
2
  const reporting = require('../lib/reporting');
3
3
  const extend = require('../lib/extend');
4
4
  const e = exposes.presets;
5
+ const tz = require('../converters/toZigbee');
6
+ const fz = require('../converters/fromZigbee');
5
7
 
6
8
  module.exports = [
9
+ {
10
+ zigbeeModel: ['SIN-4-RS-20'],
11
+ model: 'SIN-4-RS-20',
12
+ vendor: 'NodOn',
13
+ description: 'Roller shutter controller',
14
+ fromZigbee: [fz.cover_position_tilt],
15
+ toZigbee: [tz.cover_state, tz.cover_position_tilt],
16
+ configure: async (device, coordinatorEndpoint, logger) => {
17
+ const endpoint = device.getEndpoint(1);
18
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'closuresWindowCovering']);
19
+ },
20
+ exposes: [e.cover_position()],
21
+ },
7
22
  {
8
23
  zigbeeModel: ['SIN-4-1-20'],
9
24
  model: 'SIN-4-1-20',
package/devices/tuya.js CHANGED
@@ -183,7 +183,7 @@ module.exports = [
183
183
  },
184
184
  {
185
185
  fingerprint: [{modelID: 'TS0504B', manufacturerName: '_TZ3000_ukuvyhaa'},
186
- {modelID: 'TS0504B', manufacturerName: '_TZ3210_bfvybixd'}],
186
+ {modelID: 'TS0504B', manufacturerName: '_TZ3210_bfvybixd'}, {modelID: 'TS0504B', manufacturerName: '_TZ3210_sroezl0s'}],
187
187
  model: 'TS0504B',
188
188
  vendor: 'TuYa',
189
189
  description: 'Zigbee RGBW light',
@@ -1644,8 +1644,8 @@ module.exports = [
1644
1644
  exposes: [e.temperature(), e.humidity(), e.battery(), e.illuminance(), e.illuminance_lux(),
1645
1645
  exposes.numeric('alarm_temperature_max', ea.STATE).withUnit('°C').withDescription('Alarm temperature max'),
1646
1646
  exposes.numeric('alarm_temperature_min', ea.STATE).withUnit('°C').withDescription('Alarm temperature min'),
1647
- exposes.numeric('alarm_humidity_max', ea.STATE).withUnit('%').withDescription('Alarm huminity max'),
1648
- exposes.numeric('alarm_humidity_min', ea.STATE).withUnit('%').withDescription('Alarm huminity min'),
1647
+ exposes.numeric('alarm_humidity_max', ea.STATE).withUnit('%').withDescription('Alarm humidity max'),
1648
+ exposes.numeric('alarm_humidity_min', ea.STATE).withUnit('%').withDescription('Alarm humidity min'),
1649
1649
  exposes.enum('alarm_humidity', ea.STATE, ['below_min_humdity', 'over_humidity', 'off'])
1650
1650
  .withDescription('Alarm humidity status'),
1651
1651
  exposes.enum('alarm_temperature', ea.STATE, ['below_min_temperature', 'over_temperature', 'off'])
@@ -1692,7 +1692,7 @@ module.exports = [
1692
1692
  exposes.numeric('radar_sensitivity', ea.STATE_SET).withValueMin(0).withValueMax(10).withValueStep(1)
1693
1693
  .withDescription('sensitivity of the radar'),
1694
1694
  exposes.enum('radar_scene', ea.STATE_SET, ['default', 'area', 'toilet', 'bedroom', 'parlour', 'office', 'hotel'])
1695
- .withDescription('presets for sensivity for presence and movement'),
1695
+ .withDescription('presets for sensitivity for presence and movement'),
1696
1696
  ],
1697
1697
  },
1698
1698
  {
@@ -1797,7 +1797,7 @@ module.exports = [
1797
1797
  ],
1798
1798
  },
1799
1799
  {
1800
- fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_4fjiwweb'}],
1800
+ fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_4fjiwweb'}, {modelID: 'TS004F', manufacturerName: '_TZ3000_uri7ongn'}],
1801
1801
  model: 'ERS-10TZBVK-AA',
1802
1802
  vendor: 'TuYa',
1803
1803
  description: 'Smart knob',
package/devices/xiaomi.js CHANGED
@@ -47,7 +47,7 @@ module.exports = [
47
47
  description: 'Aqara E1 door & window contact sensor',
48
48
  fromZigbee: [fz.ias_contact_alarm_1, fz.aqara_opple],
49
49
  toZigbee: [],
50
- exposes: [e.contact(), e.battery(), e.temperature(), e.battery_voltage()],
50
+ exposes: [e.contact(), e.battery(), e.battery_voltage()],
51
51
  },
52
52
  {
53
53
  zigbeeModel: ['lumi.magnet.ac01'],
@@ -11,8 +11,9 @@ const fzLocal = {
11
11
  cluster: 'manuSpecificTuya',
12
12
  type: ['commandGetData', 'commandSetDataResponse'],
13
13
  convert: (model, msg, publish, options, meta) => {
14
- const button = msg.data.dp;
15
- const actionValue = tuya.getDataValue(msg.data.datatype, msg.data.data);
14
+ const dpValue = tuya.firstDpValue(msg, meta, 'ZMRM02');
15
+ const button = dpValue.dp;
16
+ const actionValue = tuya.getDataValue(dpValue);
16
17
  const lookup = {0: 'single', 1: 'double', 2: 'hold'};
17
18
  const action = lookup[actionValue];
18
19
  return {action: `button_${button}_${action}`};
package/lib/exposes.js CHANGED
@@ -557,9 +557,9 @@ module.exports = {
557
557
  linkquality: () => new Numeric('linkquality', access.STATE).withUnit('lqi').withDescription('Link quality (signal strength)').withValueMin(0).withValueMax(255),
558
558
  local_temperature: () => new Numeric('local_temperature', access.STATE_GET).withUnit('°C').withDescription('Current temperature measured on the device'),
559
559
  lock: () => new Lock().withState('state', 'LOCK', 'UNLOCK', 'State of the lock').withLockState('lock_state', 'Actual state of the lock'),
560
- max_temperature: () => new Numeric('max_temperature', access.STATE_SET).withUnit('°C').withDescription('Maximum temperature').withValueMin(15).withValueMax(35),
560
+ max_temperature: () => new Numeric('max_temperature', access.STATE_SET).withUnit('°C').withDescription('Maximum temperature').withValueMin(15).withValueMax(70),
561
561
  max_temperature_limit: () => new Numeric('max_temperature_limit', access.STATE_SET).withUnit('°C').withDescription('Maximum temperature limit').withValueMin(0).withValueMax(35),
562
- min_temperature: () => new Numeric('min_temperature', access.STATE_SET).withUnit('°C').withDescription('Minimum temperature').withValueMin(5).withValueMax(15),
562
+ min_temperature: () => new Numeric('min_temperature', access.STATE_SET).withUnit('°C').withDescription('Minimum temperature').withValueMin(1).withValueMax(15),
563
563
  noise: () => new Numeric('noise', access.STATE).withUnit('dBA').withDescription('The measured noise value'),
564
564
  noise_detected: () => new Binary('noise_detected', access.STATE, true, false).withDescription('Indicates whether the device detected noise'),
565
565
  occupancy: () => new Binary('occupancy', access.STATE, true, false).withDescription('Indicates whether the device detected occupancy'),
@@ -607,7 +607,7 @@ module.exports = {
607
607
  z_axis: () => new Numeric('z_axis', access.STATE).withDescription('Accelerometer Z value'),
608
608
  pincode: () => new Composite('pin_code', 'pin_code')
609
609
  .withFeature(new Numeric('user', access.SET).withDescription('User ID to set or clear the pincode for'))
610
- .withFeature(new Enum('user_type', access.SET, ['unrestricted', 'year_day_schedule', 'week_day_schedule', 'master', 'non_access']).withDescription('Type of user, unrestrictied: owner (default), (year|week)_day_schedule: user has ability to open lock based on specific time period, master: user has ability to both program and operate the door lock, non_access: user is recognized by the lock but does not have the ability to open the lock'))
610
+ .withFeature(new Enum('user_type', access.SET, ['unrestricted', 'year_day_schedule', 'week_day_schedule', 'master', 'non_access']).withDescription('Type of user, unrestricted: owner (default), (year|week)_day_schedule: user has ability to open lock based on specific time period, master: user has ability to both program and operate the door lock, non_access: user is recognized by the lock but does not have the ability to open the lock'))
611
611
  .withFeature(new Binary('user_enabled', access.SET, true, false).withDescription('Whether the user is enabled/disabled'))
612
612
  .withFeature(new Numeric('pin_code', access.SET).withDescription('Pincode to set, set pincode to null to clear')),
613
613
  squawk: () => new Composite('squawk', 'squawk')
package/lib/legacy.js CHANGED
@@ -2052,8 +2052,9 @@ const fromZigbee = {
2052
2052
  return fromZigbeeConverters.tuya_thermostat_weekly_schedule.convert(model, msg, publish, options, meta);
2053
2053
  }
2054
2054
 
2055
- const dp = msg.data.dp;
2056
- const value = tuyaGetDataValue(msg.data.datatype, msg.data.data);
2055
+ const dpValue = tuya.firstDpValue(msg, meta, 'tuya_thermostat_weekly_schedule');
2056
+ const dp = dpValue.dp;
2057
+ const value = tuyaGetDataValue(dpValue.datatype, dpValue.data);
2057
2058
 
2058
2059
  const thermostatMeta = getMetaValue(msg.endpoint, model, 'thermostat');
2059
2060
  const firstDayDpId = thermostatMeta.weeklyScheduleFirstDayDpId;
package/lib/tuya.js CHANGED
@@ -23,26 +23,38 @@ const convertMultiByteNumberPayloadToSingleDecimalNumber = (chunks) => {
23
23
  return value;
24
24
  };
25
25
 
26
- function getDataValue(dataType, data) {
27
- switch (dataType) {
26
+ function firstDpValue(msg, meta, converterName) {
27
+ const dpValues = msg.data.dpValues;
28
+ for (let index = 1; index < dpValues.length; index++) {
29
+ meta.logger.warn(`zigbee-herdsman-converters:${converterName}: Additional DP #${
30
+ dpValues[index].dp} with data ${JSON.stringify(dpValues[index])} will be ignored! ` +
31
+ 'Use a for loop in the fromZigbee converter (see ' +
32
+ 'https://www.zigbee2mqtt.io/advanced/support-new-devices/02_support_new_tuya_devices.html)');
33
+ }
34
+ return dpValues[0];
35
+ }
36
+
37
+
38
+ function getDataValue(dpValue) {
39
+ switch (dpValue.datatype) {
28
40
  case dataTypes.raw:
29
- return data;
41
+ return dpValue.data;
30
42
  case dataTypes.bool:
31
- return data[0] === 1;
43
+ return dpValue.data[0] === 1;
32
44
  case dataTypes.value:
33
- return convertMultiByteNumberPayloadToSingleDecimalNumber(data);
45
+ return convertMultiByteNumberPayloadToSingleDecimalNumber(dpValue.data);
34
46
  case dataTypes.string:
35
47
  // eslint-disable-next-line
36
48
  let dataString = '';
37
49
  // Don't use .map here, doesn't work: https://github.com/Koenkk/zigbee-herdsman-converters/pull/1799/files#r530377091
38
- for (let i = 0; i < data.length; ++i) {
39
- dataString += String.fromCharCode(data[i]);
50
+ for (let i = 0; i < dpValue.data.length; ++i) {
51
+ dataString += String.fromCharCode(dpValue.data[i]);
40
52
  }
41
53
  return dataString;
42
54
  case dataTypes.enum:
43
- return data[0];
55
+ return dpValue.data[0];
44
56
  case dataTypes.bitmap:
45
- return convertMultiByteNumberPayloadToSingleDecimalNumber(data);
57
+ return convertMultiByteNumberPayloadToSingleDecimalNumber(dpValue.data);
46
58
  }
47
59
  }
48
60
 
@@ -606,15 +618,15 @@ const tvThermostatPreset = {
606
618
  };
607
619
 
608
620
  // Return `seq` - transaction ID for handling concrete response
609
- async function sendDataPoint(entity, datatype, dp, data, cmd, seq=undefined) {
621
+ async function sendDataPoints(entity, dpValues, cmd, seq=undefined) {
610
622
  if (seq === undefined) {
611
- if (sendDataPoint.seq === undefined) {
612
- sendDataPoint.seq = 0;
623
+ if (sendDataPoints.seq === undefined) {
624
+ sendDataPoints.seq = 0;
613
625
  } else {
614
- sendDataPoint.seq++;
615
- sendDataPoint.seq %= 0xFFFF;
626
+ sendDataPoints.seq++;
627
+ sendDataPoints.seq %= 0xFFFF;
616
628
  }
617
- seq = sendDataPoint.seq;
629
+ seq = sendDataPoints.seq;
618
630
  }
619
631
 
620
632
  await entity.command(
@@ -622,67 +634,91 @@ async function sendDataPoint(entity, datatype, dp, data, cmd, seq=undefined) {
622
634
  cmd || 'dataRequest',
623
635
  {
624
636
  seq,
625
- dp: dp,
626
- datatype: datatype,
627
- length_hi: (data.length >> 8) & 0xFF,
628
- length_lo: data.length & 0xFF,
629
- data: data,
637
+ dpValues,
630
638
  },
631
639
  {disableDefaultResponse: true},
632
640
  );
633
641
  return seq;
634
642
  }
635
643
 
644
+ function dpValueFromIntValue(dp, value) {
645
+ return {dp, datatype: dataTypes.value, data: convertDecimalValueTo4ByteHexArray(value)};
646
+ }
647
+
648
+ function dpValueFromBool(dp, value) {
649
+ return {dp, datatype: dataTypes.bool, data: [value ? 1 : 0]};
650
+ }
651
+
652
+ function dpValueFromEnum(dp, value) {
653
+ return {dp, datatype: dataTypes.enum, data: [value]};
654
+ }
655
+
656
+ function dpValueFromStringBuffer(dp, stringBuffer) {
657
+ return {dp, datatype: dataTypes.string, data: stringBuffer};
658
+ }
659
+
660
+ function dpValueFromRaw(dp, rawBuffer) {
661
+ return {dp, datatype: dataTypes.raw, data: rawBuffer};
662
+ }
663
+
664
+ function dpValueFromBitmap(dp, bitmapBuffer) {
665
+ return {dp, datatype: dataTypes.bitmap, data: bitmapBuffer};
666
+ }
667
+
668
+ // Return `seq` - transaction ID for handling concrete response
669
+ async function sendDataPoint(entity, dpValue, cmd, seq=undefined) {
670
+ return await sendDataPoints(entity, [dpValue], cmd, seq);
671
+ }
672
+
636
673
  async function sendDataPointValue(entity, dp, value, cmd, seq=undefined) {
637
- return await sendDataPoint(
674
+ return await sendDataPoints(
638
675
  entity,
639
- dataTypes.value,
640
- dp,
641
- convertDecimalValueTo4ByteHexArray(value),
676
+ [dpValueFromIntValue(dp, value)],
642
677
  cmd,
643
678
  seq,
644
679
  );
645
680
  }
646
681
 
647
682
  async function sendDataPointBool(entity, dp, value, cmd, seq=undefined) {
648
- return await sendDataPoint(
683
+ return await sendDataPoints(
649
684
  entity,
650
- dataTypes.bool,
651
- dp,
652
- [value ? 1 : 0],
685
+ [dpValueFromBool(dp, value)],
653
686
  cmd,
654
687
  seq,
655
688
  );
656
689
  }
657
690
 
658
691
  async function sendDataPointEnum(entity, dp, value, cmd, seq=undefined) {
659
- return await sendDataPoint(
692
+ return await sendDataPoints(
660
693
  entity,
661
- dataTypes.enum,
662
- dp,
663
- [value],
694
+ [dpValueFromEnum(dp, value)],
664
695
  cmd,
665
696
  seq,
666
697
  );
667
698
  }
668
699
 
669
700
  async function sendDataPointRaw(entity, dp, value, cmd, seq=undefined) {
670
- return await sendDataPoint(
701
+ return await sendDataPoints(
671
702
  entity,
672
- dataTypes.raw,
673
- dp,
674
- value,
703
+ [dpValueFromRaw(dp, value)],
675
704
  cmd,
676
705
  seq,
677
706
  );
678
707
  }
679
708
 
680
709
  async function sendDataPointBitmap(entity, dp, value, cmd, seq=undefined) {
681
- return await sendDataPoint(
710
+ return await sendDataPoints(
711
+ entity,
712
+ [dpValueFromBitmap(dp, value)],
713
+ cmd,
714
+ seq,
715
+ );
716
+ }
717
+
718
+ async function sendDataPointStringBuffer(entity, dp, value, cmd, seq=undefined) {
719
+ return await sendDataPoints(
682
720
  entity,
683
- dataTypes.bitmap,
684
- dp,
685
- value,
721
+ [dpValueFromStringBuffer(dp, value)],
686
722
  cmd,
687
723
  seq,
688
724
  );
@@ -690,14 +726,23 @@ async function sendDataPointBitmap(entity, dp, value, cmd, seq=undefined) {
690
726
 
691
727
  module.exports = {
692
728
  sendDataPoint,
729
+ sendDataPoints,
693
730
  sendDataPointValue,
694
731
  sendDataPointBool,
695
732
  sendDataPointEnum,
696
733
  sendDataPointBitmap,
697
734
  sendDataPointRaw,
735
+ sendDataPointStringBuffer,
736
+ firstDpValue,
698
737
  getDataValue,
699
738
  dataTypes,
700
739
  dataPoints,
740
+ dpValueFromIntValue,
741
+ dpValueFromBool,
742
+ dpValueFromEnum,
743
+ dpValueFromStringBuffer,
744
+ dpValueFromRaw,
745
+ dpValueFromBitmap,
701
746
  convertDecimalValueTo4ByteHexArray,
702
747
  convertDecimalValueTo2ByteHexArray,
703
748
  onEventSetTime,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.366",
3
+ "version": "14.0.367",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
@@ -852,9 +852,9 @@
852
852
  "dev": true
853
853
  },
854
854
  "@types/node": {
855
- "version": "17.0.5",
856
- "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.5.tgz",
857
- "integrity": "sha512-w3mrvNXLeDYV1GKTZorGJQivK6XLCoGwpnyJFbJVK/aTBQUxOCaa/GlFAAN3OTDFcb7h5tiFG+YXCO2By+riZw==",
855
+ "version": "17.0.6",
856
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.6.tgz",
857
+ "integrity": "sha512-+XBAjfZmmivILUzO0HwBJoYkAyyySSLg5KCGBDFLomJo0sV6szvVLAf4ANZZ0pfWzgEds5KmGLG9D5hfEqOhaA==",
858
858
  "dev": true
859
859
  },
860
860
  "@types/prettier": {
@@ -1286,9 +1286,9 @@
1286
1286
  "dev": true
1287
1287
  },
1288
1288
  "caniuse-lite": {
1289
- "version": "1.0.30001294",
1290
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz",
1291
- "integrity": "sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g==",
1289
+ "version": "1.0.30001295",
1290
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001295.tgz",
1291
+ "integrity": "sha512-lSP16vcyC0FEy0R4ECc9duSPoKoZy+YkpGkue9G4D81OfPnliopaZrU10+qtPdT8PbGXad/PNx43TIQrOmJZSQ==",
1292
1292
  "dev": true
1293
1293
  },
1294
1294
  "chalk": {
@@ -1673,9 +1673,9 @@
1673
1673
  "dev": true
1674
1674
  },
1675
1675
  "eslint-plugin-jest": {
1676
- "version": "25.3.3",
1677
- "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.3.3.tgz",
1678
- "integrity": "sha512-qi7aduaU4/oWegWo0zH4kbJbx8+Be+ABTr72OnO68zTMcJeeSuyH1CduTGF4ATyNFgpE1zp0u10/gIhe+QDSfg==",
1676
+ "version": "25.3.4",
1677
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.3.4.tgz",
1678
+ "integrity": "sha512-CCnwG71wvabmwq/qkz0HWIqBHQxw6pXB1uqt24dxqJ9WB34pVg49bL1sjXphlJHgTMWGhBjN1PicdyxDxrfP5A==",
1679
1679
  "dev": true,
1680
1680
  "requires": {
1681
1681
  "@typescript-eslint/experimental-utils": "^5.0.0"
@@ -2723,9 +2723,9 @@
2723
2723
  },
2724
2724
  "dependencies": {
2725
2725
  "camelcase": {
2726
- "version": "6.2.1",
2727
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.1.tgz",
2728
- "integrity": "sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==",
2726
+ "version": "6.3.0",
2727
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
2728
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
2729
2729
  "dev": true
2730
2730
  }
2731
2731
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.366",
3
+ "version": "14.0.367",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [