zigbee-herdsman-converters 14.0.388 → 14.0.392

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.
@@ -1860,6 +1860,36 @@ const converters = {
1860
1860
  }
1861
1861
  },
1862
1862
  },
1863
+ tuya_illuminance_sensor: {
1864
+ cluster: `manuSpecificTuya`,
1865
+ type: [`commandDataReport`, `commandDataResponse`],
1866
+ options: [exposes.options.precision('illuminance_lux'),
1867
+ exposes.options.calibration('illuminance_lux', 'percentual')],
1868
+ convert: (() => {
1869
+ const brightnessState = {
1870
+ 0: 'low',
1871
+ 1: 'middle',
1872
+ 2: 'high',
1873
+ 3: 'strong',
1874
+ };
1875
+ return (model, msg, publish, options, meta) => {
1876
+ const dpValue = tuya.firstDpValue(msg, meta, `tuya_illuminance_sensor`);
1877
+ const dp = dpValue.dp;
1878
+ const value = tuya.getDataValue(dpValue);
1879
+ switch (dp) {
1880
+ case tuya.dataPoints.state:
1881
+ return {brightness_state: brightnessState[value]};
1882
+ case tuya.dataPoints.tIlluminanceLux:
1883
+ return {illuminance_lux: calibrateAndPrecisionRoundOptions(value, options, 'illuminance_lux')};
1884
+ default:
1885
+ meta.logger.warn(
1886
+ `zigbee-herdsman-converters:tuya_illuminance_sensor: NOT RECOGNIZED ` +
1887
+ `DP #${dp} with data ${JSON.stringify(dpValue)}`,
1888
+ );
1889
+ }
1890
+ };
1891
+ })(),
1892
+ },
1863
1893
  ts0201_temperature_humidity_alarm: {
1864
1894
  cluster: 'manuSpecificTuya_2',
1865
1895
  type: ['attributeReport', 'readResponse'],
@@ -2468,6 +2498,29 @@ const converters = {
2468
2498
  }
2469
2499
  },
2470
2500
  },
2501
+ neo_alarm: {
2502
+ cluster: 'manuSpecificTuya',
2503
+ type: ['commandDataReport', 'commandDataResponse'],
2504
+ convert: (model, msg, publish, options, meta) => {
2505
+ const dp = msg.data.dp;
2506
+ const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
2507
+
2508
+ switch (dp) {
2509
+ case tuya.dataPoints.neoAOAlarm: // 0x13 [TRUE,FALSE]
2510
+ return {alarm: value};
2511
+ case tuya.dataPoints.neoAODuration: // 0x7 [0,0,0,10] duration alarm in second
2512
+ return {duration: value};
2513
+ case tuya.dataPoints.neoAOBattPerc: // 0x15 [0,0,0,100] battery percentage
2514
+ return {battpercentage: value};
2515
+ case tuya.dataPoints.neoAOMelody: // 0x21 [5] Melody
2516
+ return {melody: value};
2517
+ case tuya.dataPoints.neoAOVolume: // 0x5 [0]/[1]/[2] Volume 0-max, 2-low
2518
+ return {volume: {2: 'low', 1: 'medium', 0: 'high'}[value]};
2519
+ default: // Unknown code
2520
+ meta.logger.warn(`Unhandled DP #${dp}: ${JSON.stringify(msg.data)}`);
2521
+ }
2522
+ },
2523
+ },
2471
2524
  terncy_contact: {
2472
2525
  cluster: 'genBinaryInput',
2473
2526
  type: 'attributeReport',
@@ -4362,6 +4415,14 @@ const converters = {
4362
4415
  convert: (model, msg, publis, options, meta) => {
4363
4416
  // Don't use in production!
4364
4417
  // Used in: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_tuya_devices.html
4418
+ const getType = (datatype) => {
4419
+ const entry = Object.entries(tuya.dataTypes).find(([typeName, typeId]) => typeId === datatype);
4420
+ return (entry ? entry[0] : 'unknown');
4421
+ };
4422
+ const getAllDpIds = (dp) => {
4423
+ const entries = Object.entries(tuya.dataPoints).filter(([dpName, dpId]) => dpId === dp);
4424
+ return entries.map(([dpName, dpId]) => dpName);
4425
+ };
4365
4426
  const getHex = (value) => {
4366
4427
  let hex = value.toString(16);
4367
4428
  if (hex.length < 2) {
@@ -4372,6 +4433,11 @@ const converters = {
4372
4433
  const now = Date.now().toString();
4373
4434
  let dataStr = '';
4374
4435
  for (const [i, dpValue] of msg.data.dpValues.entries()) {
4436
+ const value = tuya.getDataValue(dpValue);
4437
+ meta.logger.info(`zigbee-herdsman-converters:tuya_data_point_dump: Received DP #${
4438
+ dpValue.dp} from ${meta.device.ieeeAddr} with raw data '${JSON.stringify(dpValue)}': type='${msg.type}', datatype='${
4439
+ getType(dpValue.datatype)}', value='${value}', known DP# usage: ${JSON.stringify(getAllDpIds(dpValue.dp))}`);
4440
+
4375
4441
  dataStr +=
4376
4442
  now + ' ' +
4377
4443
  meta.device.ieeeAddr + ' ' +
@@ -5225,6 +5291,7 @@ const converters = {
5225
5291
  payload.gas_sensitivity = {1: '15%LEL', 2: '10%LEL'}[msg.data['268']];
5226
5292
  }
5227
5293
  }
5294
+ if (msg.data.hasOwnProperty('293')) payload.click_mode = {1: 'fast', 2: 'multi'}[msg.data['293']];
5228
5295
  if (msg.data.hasOwnProperty('294')) payload.mute = msg.data['294'] === 1; // JT-BZ-01AQ/A
5229
5296
  if (msg.data.hasOwnProperty('295')) payload.test = msg.data['295'] === 1; // JT-BZ-01AQ/A
5230
5297
  if (msg.data.hasOwnProperty('313')) payload.state = msg.data['313'] === 1 ? 'preparation' : 'work'; // JT-BZ-01AQ/A
@@ -7651,7 +7718,7 @@ const converters = {
7651
7718
  result = {tumble_switch: {false: 'OFF', true: 'ON'}[value]};
7652
7719
  break;
7653
7720
  case tuya.dataPoints.trsfFallDownStatus:
7654
- result = {fall_down_status: {0: false, 1: true}[value]};
7721
+ result = {fall_down_status: tuya.tuyaRadar.fallDown[value]};
7655
7722
  break;
7656
7723
  case tuya.dataPoints.trsfStaticDwellAlarm:
7657
7724
  result = {static_dwell_alarm: value};
@@ -1270,7 +1270,7 @@ const converters = {
1270
1270
  convertSet: async (entity, key, value, meta) => {
1271
1271
  let result;
1272
1272
  if (meta.options.thermostat_unit === 'fahrenheit') {
1273
- result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1273
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1274
1274
  } else {
1275
1275
  result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1276
1276
  }
@@ -1287,7 +1287,7 @@ const converters = {
1287
1287
  convertSet: async (entity, key, value, meta) => {
1288
1288
  let result;
1289
1289
  if (meta.options.thermostat_unit === 'fahrenheit') {
1290
- result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1290
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1291
1291
  } else {
1292
1292
  result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1293
1293
  }
@@ -1304,7 +1304,7 @@ const converters = {
1304
1304
  convertSet: async (entity, key, value, meta) => {
1305
1305
  let result;
1306
1306
  if (meta.options.thermostat_unit === 'fahrenheit') {
1307
- result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1307
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1308
1308
  } else {
1309
1309
  result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1310
1310
  }
@@ -1321,7 +1321,7 @@ const converters = {
1321
1321
  convertSet: async (entity, key, value, meta) => {
1322
1322
  let result;
1323
1323
  if (meta.options.thermostat_unit === 'fahrenheit') {
1324
- result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1324
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1325
1325
  } else {
1326
1326
  result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1327
1327
  }
@@ -1356,7 +1356,7 @@ const converters = {
1356
1356
  convertSet: async (entity, key, value, meta) => {
1357
1357
  let result;
1358
1358
  if (meta.options.thermostat_unit === 'fahrenheit') {
1359
- result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1359
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1360
1360
  } else {
1361
1361
  result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1362
1362
  }
@@ -1372,7 +1372,7 @@ const converters = {
1372
1372
  convertSet: async (entity, key, value, meta) => {
1373
1373
  let result;
1374
1374
  if (meta.options.thermostat_unit === 'fahrenheit') {
1375
- result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1375
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1376
1376
  } else {
1377
1377
  result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1378
1378
  }
@@ -5074,6 +5074,32 @@ const converters = {
5074
5074
  }
5075
5075
  },
5076
5076
  },
5077
+ neo_alarm: {
5078
+ key: [
5079
+ 'alarm', 'melody', 'volume', 'duration',
5080
+ ],
5081
+ convertSet: async (entity, key, value, meta) => {
5082
+ switch (key) {
5083
+ case 'alarm':
5084
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.neoAOAlarm, value);
5085
+ break;
5086
+ case 'melody':
5087
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.neoAOMelody, parseInt(value, 10));
5088
+ break;
5089
+ case 'volume':
5090
+ await tuya.sendDataPointEnum(
5091
+ entity,
5092
+ tuya.dataPoints.neoAOVolume,
5093
+ {'low': 2, 'medium': 1, 'high': 0}[value]);
5094
+ break;
5095
+ case 'duration':
5096
+ await tuya.sendDataPointValue(entity, tuya.dataPoints.neoAODuration, value);
5097
+ break;
5098
+ default: // Unknown key
5099
+ throw new Error(`Unhandled key ${key}`);
5100
+ }
5101
+ },
5102
+ },
5077
5103
  nous_lcd_temperature_humidity_sensor: {
5078
5104
  key: ['min_temperature', 'max_temperature', 'temperature_sensitivity', 'temperature_unit_convert'],
5079
5105
  convertSet: async (entity, key, value, meta) => {
@@ -6548,6 +6574,9 @@ const converters = {
6548
6574
  await entity.write('aqaraOpple', {0x0125: {value: lookupState[value], type: 0x20}}, manufacturerOptions.xiaomi);
6549
6575
  return {state: {click_mode: value}};
6550
6576
  },
6577
+ convertGet: async (entity, key, meta) => {
6578
+ await entity.read('aqaraOpple', [0x125], manufacturerOptions.xiaomi);
6579
+ },
6551
6580
  },
6552
6581
  tuya_light_wz5: {
6553
6582
  key: ['color', 'color_temp', 'brightness', 'white_brightness'],
@@ -100,4 +100,17 @@ module.exports = [
100
100
  await reporting.onOff(endpoint);
101
101
  },
102
102
  },
103
+ {
104
+ zigbeeModel: ['43096'],
105
+ model: '43096',
106
+ vendor: 'Enbrighten',
107
+ description: 'Zigbee plug-in smart dimmer with dual controlled outlets',
108
+ extend: extend.light_onoff_brightness({noConfigure: true}),
109
+ configure: async (device, coordinatorEndpoint, logger) => {
110
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
111
+ const endpoint = device.getEndpoint(1);
112
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
113
+ await reporting.onOff(endpoint);
114
+ },
115
+ },
103
116
  ];
package/devices/ikea.js CHANGED
@@ -64,6 +64,12 @@ const tradfriExtend = {
64
64
  ota: ota.tradfri,
65
65
  onEvent: bulbOnEvent,
66
66
  }),
67
+ light_onoff_brightness_color: (options = {}) => ({
68
+ ...extend.light_onoff_brightness_color(options),
69
+ exposes: extend.light_onoff_brightness_color(options).exposes.concat(e.power_on_behavior()),
70
+ ota: ota.tradfri,
71
+ onEvent: bulbOnEvent,
72
+ }),
67
73
  };
68
74
 
69
75
  const manufacturerOptions = {manufacturerCode: herdsman.Zcl.ManufacturerCode.IKEA_OF_SWEDEN};
@@ -369,7 +375,7 @@ module.exports = [
369
375
  model: 'LED1624G9',
370
376
  vendor: 'IKEA',
371
377
  description: 'TRADFRI LED bulb E14/E26/E27 600 lumen, dimmable, color, opal white',
372
- extend: tradfriExtend.light_onoff_brightness_colortemp_color({colorTempRange: [250, 454]}),
378
+ extend: tradfriExtend.light_onoff_brightness_color(),
373
379
  meta: {supportsHueAndSaturation: false},
374
380
  },
375
381
  {
package/devices/lg.js ADDED
@@ -0,0 +1,18 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ zigbeeModel: ['B1027EB0Z01'],
6
+ model: 'B1027EB0Z01',
7
+ vendor: 'LG Electronics',
8
+ description: 'Smart bulb 1',
9
+ extend: extend.light_onoff_brightness(),
10
+ },
11
+ {
12
+ zigbeeModel: ['B1027EB0Z02'],
13
+ model: 'B1027EB0Z02',
14
+ vendor: 'LG Electronics',
15
+ description: 'Smart bulb 2',
16
+ extend: extend.light_onoff_brightness(),
17
+ },
18
+ ];
package/devices/lidl.js CHANGED
@@ -485,6 +485,17 @@ module.exports = [
485
485
  device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
486
486
  },
487
487
  },
488
+ {
489
+ fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_r0xgkft5'}],
490
+ model: '14156506L',
491
+ vendor: 'Lidl',
492
+ description: 'Livarno Lux smart LED mood light',
493
+ ...extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}),
494
+ meta: {applyRedFix: true, enhancedHue: false},
495
+ configure: async (device, coordinatorEndpoint, logger) => {
496
+ device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
497
+ },
498
+ },
488
499
  {
489
500
  fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3000_quqaeew6'}],
490
501
  model: 'HG07834A',
package/devices/neo.js CHANGED
@@ -34,6 +34,29 @@ module.exports = [
34
34
  await endpoint.command('manuSpecificTuya', 'mcuVersionRequest', {'seq': 0x0002});
35
35
  },
36
36
  },
37
+ {
38
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_t1blo2bj'}],
39
+ zigbeeModel: ['1blo2bj'],
40
+ model: 'NAS-AB02B2',
41
+ vendor: 'Neo',
42
+ description: 'Alarm',
43
+ fromZigbee: [fz.neo_alarm, fz.ignore_basic_report],
44
+ toZigbee: [tz.neo_alarm],
45
+ exposes: [
46
+ e.battery_low(),
47
+ exposes.binary('alarm', ea.STATE_SET, true, false),
48
+ exposes.enum('melody', ea.STATE_SET, Array.from(Array(18).keys()).map((x)=>(x+1).toString())),
49
+ exposes.numeric('duration', ea.STATE_SET).withUnit('second').withValueMin(0).withValueMax(1800),
50
+ exposes.enum('volume', ea.STATE_SET, ['low', 'medium', 'high']),
51
+ exposes.numeric('battpercentage', ea.STATE).withUnit('%'),
52
+ ],
53
+ onEvent: tuya.onEventSetLocalTime,
54
+ configure: async (device, coordinatorEndpoint, logger) => {
55
+ const endpoint = device.getEndpoint(1);
56
+ await endpoint.command('manuSpecificTuya', 'dataQuery', {});
57
+ await endpoint.command('manuSpecificTuya', 'mcuVersionRequest', {'seq': 0x0002});
58
+ },
59
+ },
37
60
  {
38
61
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7hfcudw5'}],
39
62
  model: 'NAS-PD07',
@@ -66,7 +66,7 @@ module.exports = [
66
66
  ota: ota.zigbeeOTA,
67
67
  },
68
68
  {
69
- zigbeeModel: ['915005996401'],
69
+ zigbeeModel: ['915005996401', '915005996501'],
70
70
  model: '915005996401',
71
71
  vendor: 'Philips',
72
72
  description: 'Hue white ambiance ceiling light Enrave S with Bluetooth',
@@ -494,6 +494,15 @@ module.exports = [
494
494
  extend: hueExtend.light_onoff_brightness(),
495
495
  ota: ota.zigbeeOTA,
496
496
  },
497
+ {
498
+ zigbeeModel: ['1746630V7'],
499
+ model: '1746630V7',
500
+ vendor: 'Philips',
501
+ description: 'Amarant linear outdoor light',
502
+ meta: {turnsOffAtBrightness1: true},
503
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
504
+ ota: ota.zigbeeOTA,
505
+ },
497
506
  {
498
507
  zigbeeModel: ['LCC001'],
499
508
  model: '4090531P7',
@@ -1194,12 +1203,12 @@ module.exports = [
1194
1203
  ota: ota.zigbeeOTA,
1195
1204
  },
1196
1205
  {
1197
- zigbeeModel: ['3261031P6'],
1206
+ zigbeeModel: ['3261031P6', '929003055001'],
1198
1207
  model: '3261031P6',
1199
1208
  vendor: 'Philips',
1200
1209
  description: 'Hue Being white',
1201
1210
  meta: {turnsOffAtBrightness1: true},
1202
- extend: hueExtend.light_onoff_brightness_colortemp(),
1211
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
1203
1212
  ota: ota.zigbeeOTA,
1204
1213
  },
1205
1214
  {
@@ -2619,4 +2628,21 @@ module.exports = [
2619
2628
  extend: hueExtend.light_onoff_brightness(),
2620
2629
  ota: ota.zigbeeOTA,
2621
2630
  },
2631
+ {
2632
+ zigbeeModel: ['915005997501'],
2633
+ model: '915005997501',
2634
+ vendor: 'Philips',
2635
+ description: 'Hue Bluetooth white & color ambiance ceiling lamp Infuse large',
2636
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2637
+ ota: ota.zigbeeOTA,
2638
+ },
2639
+ {
2640
+ zigbeeModel: ['929003045001_01', '929003045001_02', '929003045001_03'],
2641
+ model: '9290019533',
2642
+ vendor: 'Philips',
2643
+ description: 'Hue white ambiance GU10 with Bluetooth',
2644
+ meta: {turnsOffAtBrightness1: true},
2645
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2646
+ ota: ota.zigbeeOTA,
2647
+ },
2622
2648
  ];
@@ -37,6 +37,22 @@ module.exports = [
37
37
  endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 1000000, multiplier: 1});
38
38
  },
39
39
  },
40
+ {
41
+ zigbeeModel: ['SZ-ESW02'],
42
+ model: 'SZ-ESW02',
43
+ vendor: 'Sercomm',
44
+ description: 'Telstra smart plug 2',
45
+ fromZigbee: [fz.on_off, fz.metering],
46
+ exposes: [e.switch(), e.power()],
47
+ toZigbee: [tz.on_off],
48
+ configure: async (device, coordinatorEndpoint, logger) => {
49
+ const endpoint = device.getEndpoint(1);
50
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
51
+ await reporting.onOff(endpoint);
52
+ await reporting.instantaneousDemand(endpoint);
53
+ endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 1000000, multiplier: 1});
54
+ },
55
+ },
40
56
  {
41
57
  zigbeeModel: ['XHS2-SE'],
42
58
  model: 'XHS2-SE',
package/devices/tuya.js CHANGED
@@ -839,6 +839,7 @@ module.exports = [
839
839
  {modelID: 'TS0601', manufacturerName: '_TZE200_sbordckq'},
840
840
  {modelID: 'TS0601', manufacturerName: '_TZE200_fctwhugx'},
841
841
  {modelID: 'TS0601', manufacturerName: '_TZE200_zah67ekd'},
842
+ {modelID: 'TS0601', manufacturerName: '_TZE200_hsgrhjpf'},
842
843
  // Window pushers:
843
844
  {modelID: 'TS0601', manufacturerName: '_TZE200_g5wdnuow'},
844
845
  // Tubular motors:
@@ -926,6 +927,7 @@ module.exports = [
926
927
  {modelID: 'TS0601', manufacturerName: '_TZE200_hue3yfsn'}, /* model: 'TV02-Zigbee', vendor: 'TuYa' */
927
928
  {modelID: 'TS0601', manufacturerName: '_TZE200_e9ba97vf'}, /* model: 'TV01-ZB', vendor: 'Moes' */
928
929
  {modelID: 'TS0601', manufacturerName: '_TZE200_husqqvux'}, /* model: 'TSL-TRV-TV01ZG', vendor: 'Tesla Smart' */
930
+ {modelID: 'TS0601', manufacturerName: '_TZE200_lllliz3p'}, /* model: 'TV02-Zigbee', vendor: 'TuYa' */
929
931
  ],
930
932
  model: 'TV02-Zigbee',
931
933
  vendor: 'TuYa',
@@ -1754,7 +1756,8 @@ module.exports = [
1754
1756
  .withDescription('fall sensitivity of the radar'),
1755
1757
  exposes.numeric('tumble_alarm_time', ea.STATE_SET).withValueMin(1).withValueMax(5).withValueStep(1)
1756
1758
  .withUnit('min').withDescription('tumble alarm time'),
1757
- exposes.binary('fall_down_status', ea.STATE).withDescription('fall down status'),
1759
+ exposes.enum('fall_down_status', ea.STATE, Object.values(tuya.tuyaRadar.fallDown))
1760
+ .withDescription('fall down status'),
1758
1761
  exposes.text('static_dwell_alarm', ea.STATE).withDescription('static dwell alarm'),
1759
1762
  ],
1760
1763
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -1901,4 +1904,13 @@ module.exports = [
1901
1904
  toZigbee: [],
1902
1905
  exposes: [e.contact(), e.battery(), e.vibration()],
1903
1906
  },
1907
+ {
1908
+ fingerprint: [{modelID: `TS0601`, manufacturerName: `_TZE200_yi4jtqq1`}],
1909
+ model: `XFY-CGQ-ZIGB`,
1910
+ vendor: `TuYa`,
1911
+ description: `Illuminance sensor`,
1912
+ fromZigbee: [fz.tuya_illuminance_sensor],
1913
+ toZigbee: [],
1914
+ exposes: [e.illuminance_lux(), e.brightness_state()],
1915
+ },
1904
1916
  ];
@@ -0,0 +1,12 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_dn5higyl'}],
6
+ model: 'TH008L10RGBCCT',
7
+ vendor: 'UR Lighting',
8
+ description: '10W RGB+CCT downlight',
9
+ meta: {applyRedFix: true, enhancedHue: false},
10
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
11
+ },
12
+ ];
package/devices/xiaomi.js CHANGED
@@ -1837,7 +1837,7 @@ module.exports = [
1837
1837
  fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple],
1838
1838
  toZigbee: [tz.xiaomi_switch_click_mode],
1839
1839
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'hold']),
1840
- exposes.enum('click_mode', ea.SET, ['fast', 'multi'])
1840
+ exposes.enum('click_mode', ea.ALL, ['fast', 'multi'])
1841
1841
  .withDescription('Click mode, fast: only supports single click which will be send immediately after clicking.' +
1842
1842
  'multi: supports more events like double and hold')],
1843
1843
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -1853,7 +1853,7 @@ module.exports = [
1853
1853
  exposes: [e.battery(), e.battery_voltage(),
1854
1854
  e.action(['single_left', 'single_right', 'single_both', 'double_left', 'double_right', 'hold_left', 'hold_right']),
1855
1855
  // eslint-disable-next-line max-len
1856
- exposes.enum('click_mode', ea.SET, ['fast', 'multi']).withDescription('Click mode, fast: only supports single click which will be send immediately after clicking, multi: supports more events like double and hold'),
1856
+ exposes.enum('click_mode', ea.ALL, ['fast', 'multi']).withDescription('Click mode, fast: only supports single click which will be send immediately after clicking, multi: supports more events like double and hold'),
1857
1857
  ],
1858
1858
  fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple],
1859
1859
  toZigbee: [tz.xiaomi_switch_click_mode],
@@ -1864,4 +1864,23 @@ module.exports = [
1864
1864
  await endpoint1.write('aqaraOpple', {0x0125: {value: 0x02, type: 0x20}}, {manufacturerCode: 0x115f});
1865
1865
  },
1866
1866
  },
1867
+ {
1868
+ zigbeeModel: ['lumi.remote.b18ac1'],
1869
+ model: 'WXKG14LM',
1870
+ vendor: 'Xiaomi',
1871
+ description: 'Aqara wireless remote switch H1 (single rocker)',
1872
+ fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple],
1873
+ toZigbee: [tz.xiaomi_switch_click_mode, tz.aqara_opple_operation_mode],
1874
+ exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'hold']),
1875
+ exposes.enum('click_mode', ea.ALL, ['fast', 'multi'])
1876
+ .withDescription('Click mode, fast: only supports single click which will be send immediately after clicking.' +
1877
+ 'multi: supports more events like double and hold'),
1878
+ exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
1879
+ .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
1880
+ configure: async (device, coordinatorEndpoint, logger) => {
1881
+ const endpoint1 = device.getEndpoint(1);
1882
+ await endpoint1.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
1883
+ await endpoint1.read('aqaraOpple', [0x0125], {manufacturerCode: 0x115f});
1884
+ },
1885
+ },
1867
1886
  ];
package/lib/exposes.js CHANGED
@@ -543,6 +543,7 @@ module.exports = {
543
543
  humidity: () => new Numeric('humidity', access.STATE).withUnit('%').withDescription('Measured relative humidity'),
544
544
  illuminance: () => new Numeric('illuminance', access.STATE).withDescription('Raw measured illuminance'),
545
545
  illuminance_lux: () => new Numeric('illuminance_lux', access.STATE).withUnit('lx').withDescription('Measured illuminance in lux'),
546
+ brightness_state: () => new Enum('brightness_state', access.STATE, ['low', 'middle', 'high', 'strong']).withDescription('Brightness state'),
546
547
  keypad_lockout: () => new Enum('keypad_lockout', access.ALL, ['unlock', 'lock1', 'lock2']).withDescription('Enables/disables physical input on the device'),
547
548
  led_disabled_night: () => new Binary('led_disabled_night', access.ALL, true, false).withDescription('Enable/disable the LED at night'),
548
549
  light_brightness: () => new Light().withBrightness(),
package/lib/ota/common.js CHANGED
@@ -385,9 +385,18 @@ async function updateToLatest(device, logger, onProgress, getNewImage, getImageM
385
385
 
386
386
  endpoint.commandResponse('genOta', 'upgradeEndResponse', payload).then(
387
387
  () => {
388
- logger.debug(`Update succeeded`);
388
+ logger.debug(`Update succeeded, waiting for device announce`);
389
389
  onProgress(100, null);
390
- resolve();
390
+
391
+ let timer = null;
392
+ const cb = () => {
393
+ logger.debug('Got device announce or timed out, call resolve');
394
+ clearInterval(timer);
395
+ device.removeListener('deviceAnnounce', cb);
396
+ resolve();
397
+ };
398
+ timer = setTimeout(cb, 120 * 1000); // timeout after 2 minutes
399
+ device.once('deviceAnnounce', cb);
391
400
  },
392
401
  (e) => {
393
402
  const message = `Upgrade end reponse failed (${e.message})`;
package/lib/tuya.js CHANGED
@@ -314,6 +314,12 @@ const dataPoints = {
314
314
  neoHumidityAlarm: 114,
315
315
  neoUnknown3: 115,
316
316
  neoVolume: 116,
317
+ // Neo AlarmOnly
318
+ neoAOBattPerc: 15,
319
+ neoAOMelody: 21,
320
+ neoAODuration: 7,
321
+ neoAOAlarm: 13,
322
+ neoAOVolume: 5,
317
323
  // Saswell TRV
318
324
  saswellHeating: 3,
319
325
  saswellWindowDetection: 8,
@@ -537,6 +543,7 @@ const dataPoints = {
537
543
  // TUYA / HUMIDITY/ILLUMINANCE/TEMPERATURE SENSOR
538
544
  thitBatteryPercentage: 3,
539
545
  thitIlluminanceLux: 7,
546
+ tIlluminanceLux: 2,
540
547
  thitHumidity: 9,
541
548
  thitTemperature: 8,
542
549
  // TUYA SMART VIBRATION SENSOR
@@ -643,6 +650,11 @@ const tuyaRadar = {
643
650
  1: 'moving_forward',
644
651
  2: 'moving_backward',
645
652
  },
653
+ fallDown: {
654
+ 0: 'none',
655
+ 1: 'maybe_fall',
656
+ 2: 'fall',
657
+ },
646
658
  };
647
659
 
648
660
  // Motion sensor lookups
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.388",
3
+ "version": "14.0.392",
4
4
  "lockfileVersion": 1,
5
5
  "requires": true,
6
6
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.388",
3
+ "version": "14.0.392",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [