zigbee-herdsman-converters 14.0.383 → 14.0.387

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.
@@ -5177,7 +5177,9 @@ const converters = {
5177
5177
  payload.voltage = value;
5178
5178
  payload.battery = batteryVoltageToPercentage(value, '3V_2100');
5179
5179
  } else if (index === 3) payload.temperature = calibrateAndPrecisionRoundOptions(value, options, 'temperature'); // 0x03
5180
- else if (index === 100) {
5180
+ else if (index === 5) {
5181
+ if (['JT-BZ-01AQ/A'].includes(model.model)) payload.power_outage_count = value;
5182
+ } else if (index === 100) {
5181
5183
  if (['QBKG19LM', 'QBKG20LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
5182
5184
  const mapping = model.model === 'QBCZ15LM' ? 'relay' : 'left';
5183
5185
  payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
@@ -5198,15 +5200,37 @@ const converters = {
5198
5200
  } else if (index === 150) payload.voltage = precisionRound(value * 0.1, 1); // 0x96
5199
5201
  else if (index === 151) payload.current = precisionRound(value * 0.001, 4); // 0x97
5200
5202
  else if (index === 152) payload.power = precisionRound(value, 2); // 0x98
5203
+ else if (index === 159) payload.gas_sensitivity = {1: '15%LEL', 2: '10%LEL'}[value]; // JT-BZ-01AQ/A
5204
+ else if (index === 160) payload.gas = value === 1; // JT-BZ-01AQ/A
5205
+ else if (index === 161) payload.gas_density = value; // JT-BZ-01AQ/A
5206
+ else if (index === 162) payload.test = value === 1; // JT-BZ-01AQ/A
5207
+ else if (index === 163) payload.mute = value === 1; // JT-BZ-01AQ/A
5208
+ else if (index === 164) payload.state = value === 1 ? 'preparation' : 'work'; // JT-BZ-01AQ/A
5209
+ else if (index === 166) payload.linkage_alarm = value === 1; // JT-BZ-01AQ/A
5201
5210
  else if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: unknown index ${index} with value ${value}`);
5202
5211
  }
5203
5212
  }
5204
5213
 
5205
5214
  if (msg.data.hasOwnProperty('0')) payload.detection_period = msg.data['0'];
5215
+ if (msg.data.hasOwnProperty('2')) {
5216
+ if (['JT-BZ-01AQ/A'].includes(model.model)) payload.power_outage_count = msg.data['2'];
5217
+ }
5206
5218
  if (msg.data.hasOwnProperty('4')) payload.mode_switch = {4: 'anti_flicker_mode', 1: 'quick_mode'}[msg.data['4']];
5207
5219
  if (msg.data.hasOwnProperty('10')) payload.switch_type = {1: 'toggle', 2: 'momentary'}[msg.data['10']];
5208
5220
  if (msg.data.hasOwnProperty('258')) payload.detection_interval = msg.data['258'];
5209
- if (msg.data.hasOwnProperty('268')) payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[msg.data['268']];
5221
+ if (msg.data.hasOwnProperty('268')) {
5222
+ if (['RTCGQ13LM'].includes(model.model)) {
5223
+ payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[msg.data['268']];
5224
+ } else if (['JT-BZ-01AQ/A'].includes(model.model)) {
5225
+ payload.gas_sensitivity = {1: '15%LEL', 2: '10%LEL'}[msg.data['268']];
5226
+ }
5227
+ }
5228
+ if (msg.data.hasOwnProperty('294')) payload.mute = msg.data['294'] === 1; // JT-BZ-01AQ/A
5229
+ if (msg.data.hasOwnProperty('295')) payload.test = msg.data['295'] === 1; // JT-BZ-01AQ/A
5230
+ if (msg.data.hasOwnProperty('313')) payload.state = msg.data['313'] === 1 ? 'preparation' : 'work'; // JT-BZ-01AQ/A
5231
+ if (msg.data.hasOwnProperty('314')) payload.gas = msg.data['314'] === 1; // JT-BZ-01AQ/A
5232
+ if (msg.data.hasOwnProperty('315')) payload.gas_density = msg.data['315']; // JT-BZ-01AQ/A
5233
+ if (msg.data.hasOwnProperty('331')) payload.linkage_alarm = msg.data['331'] === 1; // JT-BZ-01AQ/A
5210
5234
  if (msg.data.hasOwnProperty('512')) {
5211
5235
  if (['ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM'].includes(model.model)) {
5212
5236
  payload.button_lock = msg.data['512'] === 1 ? 'OFF' : 'ON';
@@ -7956,6 +7980,81 @@ const converters = {
7956
7980
  return {action};
7957
7981
  },
7958
7982
  },
7983
+ ZMAM02: {
7984
+ cluster: 'manuSpecificTuya',
7985
+ type: ['commandDataResponse', 'commandDataReport', 'commandSetDataresponse'],
7986
+ convert: (model, msg, publish, options, meta) => {
7987
+ const result = {};
7988
+ // let value = tuya.getDataValue(dpValue);
7989
+ // let result = null;
7990
+ for (const dpValue of msg.data.dpValues) {
7991
+ const value = tuya.getDataValue(dpValue);
7992
+ switch (dpValue.dp) {
7993
+ case tuya.dataPoints.AM02Control:
7994
+ result.control = tuya.ZMAM02.AM02Control[value];
7995
+ break;
7996
+ case tuya.dataPoints.AM02PercentControl:
7997
+ result.percent_control = value;
7998
+ break;
7999
+ case tuya.dataPoints.AM02ControlBackMode:
8000
+ result.control_back_mode = tuya.ZMAM02.AM02Direction[value];
8001
+ break;
8002
+ case tuya.dataPoints.AM02MotorWorkingMode:
8003
+ switch (value) {
8004
+ case 0: // continuous 1
8005
+ result.motor_working_mode = 'continuous';
8006
+ break;
8007
+ case 1: // intermittently
8008
+ result.motor_working_mode = 'intermittently';
8009
+ break;
8010
+ default:
8011
+ meta.logger.warn('zigbee-herdsman-converters:ZM_AM_02: ' +
8012
+ `Mode ${value} is not recognized.`);
8013
+ break;
8014
+ }
8015
+ break;
8016
+ case tuya.dataPoints.AM02Border:
8017
+ switch (value) {
8018
+ case 0: // up
8019
+ result.border = 'up';
8020
+ break;
8021
+ case 1: // down
8022
+ result.border = 'down';
8023
+ break;
8024
+ case 2: // down_delete
8025
+ result.border = 'down_delete';
8026
+ break;
8027
+ default:
8028
+ meta.logger.warn('zigbee-herdsman-converters:ZM_AM_02: ' +
8029
+ `Mode ${value} is not recognized.`);
8030
+ break;
8031
+ }
8032
+ break;
8033
+ case tuya.dataPoints.AM02PercentState:
8034
+ result.percent_state = value;
8035
+ break;
8036
+ case tuya.dataPoints.AM02Mode:
8037
+ switch (value) {
8038
+ case 0: // morning
8039
+ result.mode = 'morning';
8040
+ break;
8041
+ case 1: // night
8042
+ result.mode = 'night';
8043
+ break;
8044
+ default:
8045
+ meta.logger.warn('zigbee-herdsman-converters:ZM_AM_02: ' +
8046
+ `Mode ${value} is not recognized.`);
8047
+ break;
8048
+ }
8049
+ break;
8050
+ default:
8051
+ meta.logger.warn(`fromZigbee.Zemismart Shader Konverter (Zm_AM02): NOT RECOGNIZED ` +
8052
+ `DP #${dpValue.dp} with data ${JSON.stringify(dpValue)}`);
8053
+ }
8054
+ }
8055
+ return result;
8056
+ },
8057
+ },
7959
8058
  // #endregion
7960
8059
 
7961
8060
  // #region Ignore converters (these message dont need parsing).
@@ -2419,6 +2419,72 @@ const converters = {
2419
2419
  await entity.write('ssIasZone', {0xFFF1: {value: 0x03010000, type: 0x23}}, options);
2420
2420
  },
2421
2421
  },
2422
+ JTBZ01AQA_gas: {
2423
+ key: ['gas'],
2424
+ convertGet: async (entity, key, meta) => {
2425
+ await entity.read('aqaraOpple', [0x013a], manufacturerOptions.xiaomi);
2426
+ },
2427
+ },
2428
+ JTBZ01AQA_gas_density: {
2429
+ key: ['gas_density'],
2430
+ convertGet: async (entity, key, meta) => {
2431
+ await entity.read('aqaraOpple', [0x013b], manufacturerOptions.xiaomi);
2432
+ },
2433
+ },
2434
+ JTBZ01AQA_gas_sensitivity: {
2435
+ key: ['gas_sensitivity'],
2436
+ convertSet: async (entity, key, value, meta) => {
2437
+ value = value.toLowerCase();
2438
+ const lookup = {'15%lel': 1, '10%lel': 2};
2439
+ await entity.write('aqaraOpple', {0x010c: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
2440
+ return {state: {gas_sensitivity: value}};
2441
+ },
2442
+ convertGet: async (entity, key, meta) => {
2443
+ await entity.read('aqaraOpple', [0x010c], manufacturerOptions.xiaomi);
2444
+ },
2445
+ },
2446
+ JTBZ01AQA_selftest: {
2447
+ key: ['selftest'],
2448
+ convertSet: async (entity, key, value, meta) => {
2449
+ await entity.write('aqaraOpple', {0x0127: {value: true, type: 0x10}}, manufacturerOptions.xiaomi);
2450
+ },
2451
+ },
2452
+ JTBZ01AQA_mute_buzzer: {
2453
+ key: ['mute_buzzer'],
2454
+ convertSet: async (entity, key, value, meta) => {
2455
+ await entity.write('aqaraOpple', {0x013f: {value: 15360, type: 0x23}}, manufacturerOptions.xiaomi);
2456
+ await entity.write('aqaraOpple', {0x0126: {value: 1, type: 0x20}}, manufacturerOptions.xiaomi);
2457
+ },
2458
+ },
2459
+ JTBZ01AQA_mute: {
2460
+ key: ['mute'],
2461
+ convertGet: async (entity, key, meta) => {
2462
+ await entity.read('aqaraOpple', [0x0126], manufacturerOptions.xiaomi);
2463
+ },
2464
+ },
2465
+ JTBZ01AQA_linkage_alarm: {
2466
+ key: ['linkage_alarm'],
2467
+ convertSet: async (entity, key, value, meta) => {
2468
+ const lookup = {true: 1, false: 0};
2469
+ await entity.write('aqaraOpple', {0x014b: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
2470
+ return {state: {linkage_alarm: value}};
2471
+ },
2472
+ convertGet: async (entity, key, meta) => {
2473
+ await entity.read('aqaraOpple', [0x014b], manufacturerOptions.xiaomi);
2474
+ },
2475
+ },
2476
+ JTBZ01AQA_state: {
2477
+ key: ['state'],
2478
+ convertGet: async (entity, key, meta) => {
2479
+ await entity.read('aqaraOpple', [0x0139], manufacturerOptions.xiaomi);
2480
+ },
2481
+ },
2482
+ aqara_power_outage_count: {
2483
+ key: ['power_outage_count'],
2484
+ convertGet: async (entity, key, meta) => {
2485
+ await entity.read('aqaraOpple', [0x0002], manufacturerOptions.xiaomi);
2486
+ },
2487
+ },
2422
2488
  LLKZMK11LM_interlock: {
2423
2489
  key: ['interlock'],
2424
2490
  convertSet: async (entity, key, value, meta) => {
@@ -6592,6 +6658,33 @@ const converters = {
6592
6658
  }
6593
6659
  },
6594
6660
  },
6661
+ ZMAM02: {
6662
+ key: ['control', 'percent_control', 'mode', 'control_back_mode', 'border', 'motor_working_mode'],
6663
+ convertSet: async (entity, key, value, meta) => {
6664
+ switch (key) {
6665
+ case 'control':
6666
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.AM02Control, utils.getKey(tuya.ZMAM02.AM02Control, value));
6667
+ break;
6668
+ case 'percent_control':
6669
+ await tuya.sendDataPointValue(entity, tuya.dataPoints.AM02PercentState, value);
6670
+ break;
6671
+ case 'mode':
6672
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.AM02Mode, utils.getKey(tuya.ZMAM02.AM02Mode, value));
6673
+ break;
6674
+ case 'control_back_mode':
6675
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.AM02ControlBackMode, utils.getKey(tuya.ZMAM02.AM02Direction, value));
6676
+ break;
6677
+ case 'border':
6678
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.AM02Border, utils.getKey(tuya.ZMAM02.AM02Border, value));
6679
+ break;
6680
+ case 'motor_working_mode':
6681
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.AM02MotorWorkingMode, utils.getKey(tuya.ZMAM02.AM02MotorMode, value));
6682
+ break;
6683
+ default: // Unknown Key
6684
+ meta.logger.warn(`toZigbee.ZMAM02: Unhandled Key ${key}`);
6685
+ }
6686
+ },
6687
+ },
6595
6688
  // #endregion
6596
6689
 
6597
6690
  // #region Ignore converters
package/devices/cleode.js CHANGED
@@ -1,8 +1,7 @@
1
1
  const exposes = require('../lib/exposes');
2
- const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
- const tz = require('../converters/toZigbee');
4
2
  const reporting = require('../lib/reporting');
5
3
  const e = exposes.presets;
4
+ const extend = require('../lib/extend');
6
5
 
7
6
  module.exports = [
8
7
  {
@@ -10,9 +9,7 @@ module.exports = [
10
9
  model: 'ZPLUG_Boost',
11
10
  vendor: 'CLEODE',
12
11
  description: 'ZPlug boost',
13
- meta: {multiEndpoint: true},
14
- fromZigbee: [fz.on_off],
15
- toZigbee: [tz.on_off],
12
+ extend: extend.switch(),
16
13
  exposes: [e.switch(), e.power()],
17
14
  configure: async (device, coordinatorEndpoint, logger) => {
18
15
  const endpoint = device.getEndpoint(1);
package/devices/ikea.js CHANGED
@@ -252,7 +252,7 @@ module.exports = [
252
252
  extend: tradfriExtend.light_onoff_brightness_colortemp(),
253
253
  },
254
254
  {
255
- zigbeeModel: ['TRADFRI bulb E27 WS clear 950lm', 'TRADFRI bulb E26 WS clear 950lm'],
255
+ zigbeeModel: ['TRADFRI bulb E27 WS clear 950lm', 'TRADFRI bulb E26 WS clear 950lm', 'TRADFRI bulb E27 WS\uFFFDclear 950lm'],
256
256
  model: 'LED1546G12',
257
257
  vendor: 'IKEA',
258
258
  description: 'TRADFRI LED bulb E26/E27 950 lumen, dimmable, white spectrum, clear',
@@ -91,7 +91,7 @@ module.exports = [
91
91
  zigbeeModel: ['LEDVANCE DIM'],
92
92
  model: '4058075208421',
93
93
  vendor: 'LEDVANCE',
94
- description: 'SMART+ candle E14 tunable white',
94
+ description: 'SMART+ candle E14 dimmable white',
95
95
  extend: extend.ledvance.light_onoff_brightness(),
96
96
  ota: ota.ledvance,
97
97
  },
@@ -4,6 +4,7 @@ const tz = require('../converters/toZigbee');
4
4
  const e = exposes.presets;
5
5
  const ea = exposes.access;
6
6
  const extend = require('../lib/extend');
7
+ const tuya = require('../lib/tuya');
7
8
 
8
9
  module.exports = [
9
10
  {
@@ -21,11 +22,13 @@ module.exports = [
21
22
  ],
22
23
  },
23
24
  {
24
- fingerprint: [{modelID: 'TS0501B', manufacturerName: '_TZ3210_dxroobu3'}],
25
+ fingerprint: [{modelID: 'TS0501B', manufacturerName: '_TZ3210_dxroobu3'},
26
+ {modelID: 'TS0501B', manufacturerName: '_TZ3210_dbilpfqk'}],
25
27
  model: 'FUT036Z',
26
28
  description: 'Single color LED controller',
27
29
  vendor: 'Miboxer',
28
30
  extend: extend.light_onoff_brightness(),
31
+ onEvent: tuya.onEventSetTime,
29
32
  },
30
33
  {
31
34
  fingerprint: [{modelID: 'TS0502B', manufacturerName: '_TZ3210_frm6149r'}],
package/devices/moes.js CHANGED
@@ -9,6 +9,27 @@ const e = exposes.presets;
9
9
  const ea = exposes.access;
10
10
 
11
11
  module.exports = [
12
+ {
13
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cymsnfvf'}],
14
+ model: 'ZP-LZ-FR2U',
15
+ vendor: 'Moes',
16
+ description: 'Zigbee 3.0 dual USB wireless socket plug',
17
+ fromZigbee: [fz.on_off, fz.tuya_switch_power_outage_memory],
18
+ toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
19
+ exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'),
20
+ exposes.enum('power_outage_memory', ea.STATE_SET, ['on', 'off', 'restore'])
21
+ .withDescription('Recover state after power outage')],
22
+ endpoint: (device) => {
23
+ return {'l1': 1, 'l2': 2};
24
+ },
25
+ meta: {multiEndpoint: true},
26
+ configure: async (device, coordinatorEndpoint, logger) => {
27
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
28
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
29
+ await reporting.onOff(device.getEndpoint(1));
30
+ await reporting.onOff(device.getEndpoint(2));
31
+ },
32
+ },
12
33
  {
13
34
  fingerprint: [{modelID: 'TS0121', manufacturerName: '_TYZB01_iuepbmpv'}, {modelID: 'TS011F', manufacturerName: '_TZ3000_zmy1waw6'},
14
35
  {modelID: 'TS011F', manufacturerName: '_TZ3000_bkfe0bab'}],
@@ -1543,6 +1543,15 @@ module.exports = [
1543
1543
  extend: hueExtend.light_onoff_brightness_colortemp_color(),
1544
1544
  ota: ota.zigbeeOTA,
1545
1545
  },
1546
+ {
1547
+ zigbeeModel: ['LCF003', '4080248P7'],
1548
+ model: '4080248P7',
1549
+ vendor: 'Philips',
1550
+ description: 'Hue Signe floor light',
1551
+ meta: {turnsOffAtBrightness1: true},
1552
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1553
+ ota: ota.zigbeeOTA,
1554
+ },
1546
1555
  {
1547
1556
  zigbeeModel: ['4080248U9'],
1548
1557
  model: '4080248U9',
package/devices/tuya.js CHANGED
@@ -845,7 +845,6 @@ module.exports = [
845
845
  {modelID: 'TS0601', manufacturerName: '_TZE200_fzo2pocs'},
846
846
  {modelID: 'TS0601', manufacturerName: '_TZE200_5sbebbzs'},
847
847
  {modelID: 'TS0601', manufacturerName: '_TZE200_zuz7f94z'},
848
- {modelID: 'TS0601', manufacturerName: '_TZE200_iossyxra'},
849
848
  ],
850
849
  model: 'TS0601_cover',
851
850
  vendor: 'TuYa',
@@ -1127,7 +1126,6 @@ module.exports = [
1127
1126
  {
1128
1127
  fingerprint: [
1129
1128
  {modelID: 'TS011F', manufacturerName: '_TZ3000_hyfvrar3'},
1130
- {modelID: 'TS011F', manufacturerName: '_TZ3000_cymsnfvf'},
1131
1129
  {modelID: 'TS011F', manufacturerName: '_TZ3000_bfn1w0mm'}],
1132
1130
  model: 'TS011F_plug_2',
1133
1131
  description: 'Smart plug (without power monitoring)',
package/devices/xiaomi.js CHANGED
@@ -81,11 +81,11 @@ module.exports = [
81
81
  model: 'ZNLDP12LM',
82
82
  vendor: 'Xiaomi',
83
83
  description: 'Aqara smart LED bulb',
84
- toZigbee: xiaomiExtend.light_onoff_brightness_colortemp().toZigbee.concat([
84
+ toZigbee: xiaomiExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}).toZigbee.concat([
85
85
  tz.xiaomi_light_power_outage_memory]),
86
- fromZigbee: xiaomiExtend.light_onoff_brightness_colortemp().fromZigbee,
86
+ fromZigbee: xiaomiExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}).fromZigbee,
87
87
  // power_on_behavior 'toggle' does not seem to be supported
88
- exposes: xiaomiExtend.light_onoff_brightness_colortemp().exposes.concat([
88
+ exposes: xiaomiExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}).exposes.concat([
89
89
  e.power_outage_memory().withAccess(ea.STATE_SET)]),
90
90
  ota: ota.zigbeeOTA,
91
91
  },
@@ -1133,6 +1133,41 @@ module.exports = [
1133
1133
  exposes.numeric('gas_density', ea.STATE), exposes.enum('selftest', ea.SET, ['']),
1134
1134
  ],
1135
1135
  },
1136
+ {
1137
+ zigbeeModel: ['lumi.sensor_gas.acn02'],
1138
+ model: 'JT-BZ-01AQ/A',
1139
+ vendor: 'Xiaomi',
1140
+ description: 'Aqara smart natural gas detector',
1141
+ fromZigbee: [fz.aqara_opple],
1142
+ toZigbee: [tz.JTBZ01AQA_gas, tz.JTBZ01AQA_gas_density, tz.JTBZ01AQA_gas_sensitivity, tz.JTBZ01AQA_selftest,
1143
+ tz.JTBZ01AQA_mute_buzzer, tz.JTBZ01AQA_mute, tz.JTBZ01AQA_linkage_alarm, tz.JTBZ01AQA_state, tz.aqara_power_outage_count],
1144
+ exposes: [e.gas().withAccess(ea.STATE_GET),
1145
+ exposes.numeric('gas_density', ea.STATE_GET).withUnit('%LEL').withDescription('Value of gas concentration'),
1146
+ exposes.enum('gas_sensitivity', ea.ALL, ['10%LEL', '15%LEL']).withDescription('Gas concentration value at which ' +
1147
+ 'an alarm is triggered ("10%LEL" is more sensitive than "15%LEL")'),
1148
+ exposes.enum('selftest', ea.SET, ['Test']).withDescription('Starts the self-test process (checking the indicator ' +
1149
+ 'light and buzzer work properly)'),
1150
+ exposes.binary('test', ea.STATE, true, false).withDescription('Self-test in progress'),
1151
+ exposes.enum('mute_buzzer', ea.SET, ['Mute']).withDescription('Mute the buzzer for 10 minutes (buzzer cannot be ' +
1152
+ 'pre-muted, because this function only works when the alarm is triggered)'),
1153
+ exposes.binary('mute', ea.STATE_GET, true, false).withDescription('Buzzer muted'),
1154
+ exposes.switch().withState('linkage_alarm', true, 'After being turned on, one of the devices triggers the ' +
1155
+ 'natural gas leakage alarm, and other devices with linkage turned on', ea.ALL, true, false),
1156
+ exposes.binary('state', ea.STATE_GET, 'preparation', 'work').withDescription('"Preparation" or "work" ' +
1157
+ '(measurement of the gas concentration value and triggering of an alarm are only performed in the "work" state)'),
1158
+ exposes.numeric('power_outage_count', ea.STATE_GET).withDescription('Number of power outages (since last pairing)')],
1159
+ configure: async (device, coordinatorEndpoint, logger) => {
1160
+ const endpoint = device.getEndpoint(1);
1161
+ await endpoint.read('aqaraOpple', [0x013a], {manufacturerCode: 0x115f});
1162
+ await endpoint.read('aqaraOpple', [0x013b], {manufacturerCode: 0x115f});
1163
+ await endpoint.read('aqaraOpple', [0x0126], {manufacturerCode: 0x115f});
1164
+ await endpoint.read('aqaraOpple', [0x0139], {manufacturerCode: 0x115f});
1165
+ await endpoint.read('aqaraOpple', [0x010c], {manufacturerCode: 0x115f});
1166
+ await endpoint.read('aqaraOpple', [0x014b], {manufacturerCode: 0x115f});
1167
+ await endpoint.read('aqaraOpple', [0x0002], {manufacturerCode: 0x115f});
1168
+ },
1169
+ ota: ota.zigbeeOTA,
1170
+ },
1136
1171
  {
1137
1172
  zigbeeModel: ['lumi.lock.v1'],
1138
1173
  model: 'A6121',
@@ -124,4 +124,26 @@ module.exports = [
124
124
  await reporting.onOff(device.getEndpoint(2));
125
125
  },
126
126
  },
127
+ {
128
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_iossyxra'}],
129
+ model: 'ZM-AM02',
130
+ vendor: 'Zemismart',
131
+ description: 'Zigbee/RF curtain converter',
132
+ fromZigbee: [fz.ZMAM02],
133
+ toZigbee: [tz.ZMAM02],
134
+ exposes: [exposes.enum('motor_working_mode', ea.STATE_SET, Object.values(tuya.ZMAM02.AM02MotorMode)),
135
+ exposes.enum('control', ea.STATE_SET, Object.values(tuya.ZMAM02.AM02Control)),
136
+ exposes.numeric('percent_state', ea.STATE).withValueMin(0).withValueMax(100).withValueStep(1).withUnit('%'),
137
+ exposes.enum('mode', ea.STATE_SET, Object.values(tuya.ZMAM02.AM02Mode)),
138
+ exposes.enum('control_back_mode', ea.STATE_SET, Object.values(tuya.ZMAM02.AM02Direction)),
139
+ exposes.enum('border', ea.STATE_SET, Object.values(tuya.ZMAM02.AM02Border)),
140
+ // ---------------------------------------------------------------------------------
141
+ // DP exists, but not used at the moment
142
+ // exposes.numeric('percent_control', ea.STATE_SET).withValueMin(0).withValueMax(100).withValueStep(1).withUnit('%'),
143
+ // exposes.enum('work_state', ea.STATE, Object.values(tuya.ZMAM02.AM02WorkState)),
144
+ // exposes.numeric('countdown_left', ea.STATE).withUnit('s'),
145
+ // exposes.numeric('time_total', ea.STATE).withUnit('ms'),
146
+ // exposes.enum('situation_set', ea.STATE, Object.values(tuya.ZMAM02.AM02Situation)),
147
+ ],
148
+ },
127
149
  ];
package/lib/tuya.js CHANGED
@@ -537,6 +537,20 @@ const dataPoints = {
537
537
  evanellLocalTemp: 5,
538
538
  evanellBattery: 6,
539
539
  evanellChildLock: 8,
540
+ // ZMAM02 Zemismart RF Courtain Converter
541
+ AM02Control: 1,
542
+ AM02PercentControl: 2,
543
+ AM02PercentState: 3,
544
+ AM02Mode: 4,
545
+ AM02ControlBackMode: 5,
546
+ AM02WorkState: 7,
547
+ AM02CountdownLeft: 9,
548
+ AM02TimeTotal: 10,
549
+ AM02SituationSet: 11,
550
+ AM02Fault: 12,
551
+ AM02Border: 16,
552
+ AM02MotorWorkingMode: 20,
553
+ AM02AddRemoter: 101,
540
554
  };
541
555
 
542
556
  const thermostatWeekFormat = {
@@ -650,6 +664,40 @@ const tvThermostatPreset = {
650
664
  1: 'manual',
651
665
  3: 'holiday',
652
666
  };
667
+ // Zemismart ZM_AM02 Roller Shade Converter
668
+ const ZMAM02 = {
669
+ AM02Mode: {
670
+ 0: 'morning',
671
+ 1: 'night',
672
+ },
673
+ AM02Control: {
674
+ 0: 'open',
675
+ 1: 'stop',
676
+ 2: 'close',
677
+ 3: 'continue',
678
+ },
679
+ AM02Direction: {
680
+ 0: 'forward',
681
+ 1: 'back',
682
+ },
683
+ AM02WorkState: {
684
+ 0: 'opening',
685
+ 1: 'closing',
686
+ },
687
+ AM02Border: {
688
+ 0: 'up',
689
+ 1: 'down',
690
+ 2: 'down_delete',
691
+ },
692
+ AM02Situation: {
693
+ 0: 'fully_open',
694
+ 1: 'fully_close',
695
+ },
696
+ AM02MotorMode: {
697
+ 0: 'continuous',
698
+ 1: 'intermittently',
699
+ },
700
+ };
653
701
 
654
702
  // Return `seq` - transaction ID for handling concrete response
655
703
  async function sendDataPoints(entity, dpValues, cmd, seq=undefined) {
@@ -800,4 +848,5 @@ module.exports = {
800
848
  tvThermostatMode,
801
849
  tvThermostatPreset,
802
850
  tuyaRadar,
851
+ ZMAM02,
803
852
  };