zigbee-herdsman-converters 14.0.497 → 14.0.500

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.
@@ -4294,7 +4294,6 @@ const converters = {
4294
4294
  const dpValue = tuya.firstDpValue(msg, meta, 'tuya_air_quality');
4295
4295
  const dp = dpValue.dp;
4296
4296
  const value = tuya.getDataValue(dpValue);
4297
- const swapPM25CO2 = ['_TZE200_ryfmq5rl', '_TZE200_dwcarsat'];
4298
4297
  switch (dp) {
4299
4298
  case tuya.dataPoints.tuyaSabTemp:
4300
4299
  return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
@@ -4302,15 +4301,17 @@ const converters = {
4302
4301
  return {humidity: calibrateAndPrecisionRoundOptions(value / 10, options, 'humidity')};
4303
4302
  // DP22: Smart Air Box: Formaldehyd, Smart Air Housekeeper: co2
4304
4303
  case tuya.dataPoints.tuyaSabFormaldehyd:
4305
- if (swapPM25CO2.includes(meta.device.manufacturerName)) {
4304
+ if (['_TZE200_dwcarsat', '_TZE200_ryfmq5rl'].includes(meta.device.manufacturerName)) {
4306
4305
  return {co2: calibrateAndPrecisionRoundOptions(value, options, 'co2')};
4307
4306
  } else {
4308
4307
  return {formaldehyd: calibrateAndPrecisionRoundOptions(value, options, 'formaldehyd')};
4309
4308
  }
4310
4309
  // DP2: Smart Air Box: co2, Smart Air Housekeeper: MP25
4311
4310
  case tuya.dataPoints.tuyaSabCO2:
4312
- if (swapPM25CO2.includes(meta.device.manufacturerName)) {
4311
+ if (meta.device.manufacturerName === '_TZE200_dwcarsat') {
4313
4312
  return {pm25: calibrateAndPrecisionRoundOptions(value, options, 'pm25')};
4313
+ } else if (meta.device.manufacturerName === '_TZE200_ryfmq5rl') {
4314
+ return {formaldehyd: calibrateAndPrecisionRoundOptions(value, options, 'formaldehyd')};
4314
4315
  } else {
4315
4316
  return {co2: calibrateAndPrecisionRoundOptions(value, options, 'co2')};
4316
4317
  }
@@ -4763,7 +4764,7 @@ const converters = {
4763
4764
  },
4764
4765
  tuya_data_point_dump: {
4765
4766
  cluster: 'manuSpecificTuya',
4766
- type: ['commandDataResponse', 'commandDataReport', 'commandActiveStatusReport'],
4767
+ type: ['commandDataResponse', 'commandDataReport', 'commandActiveStatusReport', 'commandActiveStatusReportAlt'],
4767
4768
  convert: (model, msg, publis, options, meta) => {
4768
4769
  // Don't use in production!
4769
4770
  // Used in: https://www.zigbee2mqtt.io/how_tos/how_to_support_new_tuya_devices.html
@@ -5871,19 +5872,9 @@ const converters = {
5871
5872
  return result;
5872
5873
  },
5873
5874
  },
5874
- xiaomi_curtain_acn002_position: {
5875
- cluster: 'genAnalogOutput',
5876
- type: ['attributeReport', 'readResponse'],
5877
- options: [exposes.options.invert_cover()],
5878
- convert: (model, msg, publish, options, meta) => {
5879
- let position = precisionRound(msg.data['presentValue'], 2);
5880
- position = options.invert_cover ? 100 - position : position;
5881
- return {position: position};
5882
- },
5883
- },
5884
5875
  xiaomi_curtain_acn002_status: {
5885
5876
  cluster: 'genMultistateOutput',
5886
- type: ['attributeReport', 'readResponse'],
5877
+ type: ['attributeReport'],
5887
5878
  convert: (model, msg, publish, options, meta) => {
5888
5879
  let running = false;
5889
5880
  const data = msg.data;
@@ -7326,22 +7317,34 @@ const converters = {
7326
7317
  },
7327
7318
  ZB006X_settings: {
7328
7319
  cluster: 'manuSpecificTuya',
7329
- type: ['commandDataResponse'],
7320
+ type: ['commandActiveStatusReport', 'commandActiveStatusReportAlt'],
7330
7321
  convert: (model, msg, publish, options, meta) => {
7331
7322
  const dpValue = tuya.firstDpValue(msg, meta, 'ZB006X_settings');
7332
7323
  const dp = dpValue.dp;
7333
7324
  const value = tuya.getDataValue(dpValue);
7334
- if (dp === 103) {
7335
- meta.logger.debug(`fromZigbee.ZB006X_settings: Found DP #${dp} with data ${JSON.stringify(dpValue)}`);
7336
- return {ext_switch_type: {0: 'unknown', 1: 'toggle_sw', 2: 'momentary_sw', 3: 'rotary_sw', 4: 'auto_config'}[value]};
7337
- } else if (dp === 105) {
7338
- meta.logger.debug(`fromZigbee.ZB006X_settings: Found DP #${dp} with data ${JSON.stringify(dpValue)}`);
7325
+ switch (dp) {
7326
+ case tuya.dataPoints.fantemPowerSupplyMode:
7327
+ return {power_supply_mode: {0: 'unknown', 1: 'no_neutral', 2: 'with_neutral'}[value]};
7328
+ case tuya.dataPoints.fantemExtSwitchType:
7329
+ return {ext_switch_type: {0: 'unknown', 1: 'toggle_sw', 2: 'momentary_sw', 3: 'rotary_sw',
7330
+ 4: 'auto_config'}[value]};
7331
+ case tuya.dataPoints.fantemLoadDetectionMode:
7339
7332
  return {load_detection_mode: {0: 'none', 1: 'first_power_on', 2: 'every_power_on'}[value]};
7340
- } else if (dp === 109) {
7341
- meta.logger.debug(`fromZigbee.ZB006X_settings: Found DP #${dp} with data ${JSON.stringify(dpValue)}`);
7342
- return {control_mode: {0: 'local', 1: 'remote', 2: 'both'}[value]};
7343
- } else {
7344
- meta.logger.warn(`fromZigbee.ZB006X_settings: Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`);
7333
+ case tuya.dataPoints.fantemExtSwitchStatus:
7334
+ return {ext_switch_status: value};
7335
+ case tuya.dataPoints.fantemControlMode:
7336
+ return {control_mode: {0: 'ext_switch', 1: 'remote', 2: 'both'}[value]};
7337
+ case 111:
7338
+ // Value 0 is received after each device power-on. No idea what it means.
7339
+ return;
7340
+ case tuya.dataPoints.fantemLoadType:
7341
+ // Not sure if 0 is 'resistive' and 2 is 'resistive_inductive'.
7342
+ // If you see 'unknown', pls. check with Tuya gateway and app and update with label shown in Tuya app.
7343
+ return {load_type: {0: 'unknown', 1: 'resistive_capacitive', 2: 'unknown', 3: 'detecting'}[value]};
7344
+ case tuya.dataPoints.fantemLoadDimmable:
7345
+ return {load_dimmable: {0: 'unknown', 1: 'dimmable', 2: 'not_dimmable'}[value]};
7346
+ default:
7347
+ meta.logger.warn(`fz.ZB006X_settings: Unhandled DP|Value [${dp}|${value}][${JSON.stringify(dpValue)}]`);
7345
7348
  }
7346
7349
  },
7347
7350
  },
@@ -792,7 +792,7 @@ const converters = {
792
792
  },
793
793
  },
794
794
  light_onoff_brightness: {
795
- key: ['state', 'brightness', 'brightness_percent'],
795
+ key: ['state', 'brightness', 'brightness_percent', 'on_time'],
796
796
  options: [exposes.options.transition()],
797
797
  convertSet: async (entity, key, value, meta) => {
798
798
  const {message} = meta;
@@ -2439,6 +2439,20 @@ const converters = {
2439
2439
  } else {
2440
2440
  await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped, entity));
2441
2441
  }
2442
+
2443
+ if (!['ZNCLDJ11LM', 'ZNJLBL01LM'].includes(meta.mapped.model)) {
2444
+ // The code below is originally added for ZNCLDJ11LM (Koenkk/zigbee2mqtt#4585).
2445
+ // However, in Koenkk/zigbee-herdsman-converters#4039 it was replaced by reading
2446
+ // directly from currentPositionLiftPercentage, so that device is excluded.
2447
+ // For ZNJLBL01LM, in Koenkk/zigbee-herdsman-converters#4163 the position is read
2448
+ // through onEvent each time the motor stops, so it becomes redundant, and the
2449
+ // device is excluded.
2450
+ // The code is left here to avoid breaking compatibility, ideally all devices using
2451
+ // this converter should be tested so the code can be adjusted/deleted.
2452
+
2453
+ // Xiaomi curtain does not send position update on stop, request this.
2454
+ await entity.read('genAnalogOutput', [0x0055]);
2455
+ }
2442
2456
  } else {
2443
2457
  const lookup = {'open': 100, 'close': 0, 'on': 100, 'off': 0};
2444
2458
 
@@ -6495,17 +6509,19 @@ const converters = {
6495
6509
  convertSet: async (entity, key, value, meta) => {
6496
6510
  switch (key) {
6497
6511
  case 'ext_switch_type':
6498
- await tuya.sendDataPointEnum(entity, 103, {'unknown': 0, 'toggle_sw': 1,
6499
- 'momentary_sw': 2, 'rotary_sw': 3, 'auto_config': 4}[value]);
6512
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.fantemExtSwitchType, {'unknown': 0, 'toggle_sw': 1,
6513
+ 'momentary_sw': 2, 'rotary_sw': 3, 'auto_config': 4}[value], 'sendData');
6500
6514
  break;
6501
6515
  case 'load_detection_mode':
6502
- await tuya.sendDataPointEnum(entity, 105, {'none': 0, 'first_power_on': 1, 'every_power_on': 2}[value]);
6516
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.fantemLoadDetectionMode, {'none': 0, 'first_power_on': 1,
6517
+ 'every_power_on': 2}[value], 'sendData');
6503
6518
  break;
6504
6519
  case 'control_mode':
6505
- await tuya.sendDataPointEnum(entity, 109, {'local': 0, 'remote': 1, 'both': 2}[value]);
6520
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.fantemControlMode, {'ext_switch': 0, 'remote': 1,
6521
+ 'both': 2}[value], 'sendData');
6506
6522
  break;
6507
6523
  default: // Unknown key
6508
- throw new Error(`toZigbee.ZB006X_settings: Unhandled key ${key}`);
6524
+ throw new Error(`tz.ZB006X_settings: Unhandled key ${key}`);
6509
6525
  }
6510
6526
  },
6511
6527
  },
package/devices/awox.js CHANGED
@@ -224,11 +224,30 @@ module.exports = [
224
224
  },
225
225
  ],
226
226
  },
227
+ {
228
+ type: 'Router', manufacturerName: 'AwoX', modelID: 'TLSR82xx', endpoints: [
229
+ {
230
+ ID: 1,
231
+ profileID: 260,
232
+ deviceID: 268,
233
+ inputClusters: [0, 3, 4, 5, 6, 8, 768, 4096, 64599, 10],
234
+ outputClusters: [6],
235
+ },
236
+ {ID: 242, profileID: 41440, deviceID: 97, inputClusters: [], outputClusters: [33]},
237
+ {
238
+ ID: 3,
239
+ profileID: 4751,
240
+ deviceID: 268,
241
+ inputClusters: [65360, 65361],
242
+ outputClusters: [65360, 65361],
243
+ },
244
+ ],
245
+ },
227
246
  ],
228
247
  model: '33957',
229
248
  vendor: 'AwoX',
230
249
  description: 'LED light with color temperature',
231
- extend: extend.light_onoff_brightness_colortemp(),
250
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
232
251
  },
233
252
  {
234
253
  fingerprint: [
@@ -45,7 +45,7 @@ module.exports = [
45
45
  .withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'),
46
46
  exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
47
47
  .withDescription('Values observed are `0` (manual), `1` (schedule) or `2` (externally)'),
48
- exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
48
+ exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 35, 0.5).withLocalTemperature().withPiHeatingDemand()
49
49
  .withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
50
50
  exposes.numeric('external_measured_room_sensor', ea.ALL)
51
51
  .withDescription('If `radiator_covered` is `true`: Set at maximum 30 minutes interval but not more often than every ' +
@@ -79,7 +79,8 @@ module.exports = [
79
79
  .withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
80
80
  .withValueMin(-8000).withValueMax(2000),
81
81
  exposes.numeric('load_estimate', ea.STATE_GET)
82
- .withDescription('Load estimate on this radiator'),
82
+ .withDescription('Load estimate on this radiator')
83
+ .withValueMin(-8000).withValueMax(3600),
83
84
  exposes.binary('preheat_status', ea.STATE_GET, true, false)
84
85
  .withDescription('Specific for pre-heat running in Zigbee Weekly Schedule mode'),
85
86
  exposes.enum('adaptation_run_status', ea.STATE_GET, ['none', 'in_progress', 'found', 'lost'])
package/devices/fantem.js CHANGED
@@ -5,6 +5,7 @@ const e = exposes.presets;
5
5
  const ea = exposes.access;
6
6
  const extend = require('../lib/extend');
7
7
  const reporting = require('../lib/reporting');
8
+ const tuya = require('../lib/tuya');
8
9
 
9
10
  module.exports = [
10
11
  {
@@ -13,21 +14,34 @@ module.exports = [
13
14
  vendor: 'Fantem',
14
15
  description: 'Smart dimmer module without neutral',
15
16
  extend: extend.light_onoff_brightness({noConfigure: true}),
16
- fromZigbee: [...extend.light_onoff_brightness({noConfigure: true}).fromZigbee, fz.command_on, fz.command_off,
17
- fz.command_move, fz.command_stop, fz.ZB006X_settings],
17
+ fromZigbee: [...extend.light_onoff_brightness({noConfigure: true}).fromZigbee,
18
+ fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.ZB006X_settings],
18
19
  toZigbee: [...extend.light_onoff_brightness({noConfigure: true}).toZigbee, tz.ZB006X_settings],
19
20
  exposes: [e.light_brightness(),
20
21
  e.action(['on', 'off', 'brightness_move_down', 'brightness_move_up', 'brightness_stop']),
22
+ exposes.enum('control_mode', ea.STATE_SET, ['ext_switch', 'remote', 'both']).withDescription('Control mode'),
21
23
  exposes.enum('ext_switch_type', ea.STATE_SET, ['unknown', 'toggle_sw', 'momentary_sw', 'rotary_sw', 'auto_config'])
22
24
  .withDescription('External switch type'),
25
+ exposes.numeric('ext_switch_status', ea.STATE).withDescription('External switch status')
26
+ .withValueMin(-10000).withValueMax(10000),
23
27
  exposes.enum('load_detection_mode', ea.STATE_SET, ['none', 'first_power_on', 'every_power_on'])
24
28
  .withDescription('Load detection mode'),
25
- exposes.enum('control_mode', ea.STATE_SET, ['local', 'remote', 'both']).withDescription('Control mode'),
29
+ // If you see load_type 'unknown', pls. check with Tuya gateway and app and update with label from Tuya app.
30
+ exposes.enum('load_type', ea.STATE, ['unknown', 'resistive_capacitive', 'unknown', 'detecting'])
31
+ .withDescription('Load type'),
32
+ exposes.enum('load_dimmable', ea.STATE, ['unknown', 'dimmable', 'not_dimmable'])
33
+ .withDescription('Load dimmable'),
34
+ exposes.enum('power_supply_mode', ea.STATE, ['unknown', 'no_neutral', 'with_neutral'])
35
+ .withDescription('Power supply mode'),
26
36
  ],
27
37
  meta: {disableActionGroup: true},
38
+ onEvent: tuya.onEventSetLocalTime,
28
39
  configure: async (device, coordinatorEndpoint, logger) => {
29
40
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
30
41
  const endpoint = device.getEndpoint(1);
42
+ // Enables reporting of physical state changes
43
+ // https://github.com/Koenkk/zigbee2mqtt/issues/9057#issuecomment-1007742130
44
+ await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
31
45
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
32
46
  await reporting.onOff(endpoint);
33
47
  },
@@ -1,4 +1,5 @@
1
1
  const exposes = require('../lib/exposes');
2
+ const fz = require('../converters/fromZigbee');
2
3
  const tz = require('../converters/toZigbee');
3
4
  const e = exposes.presets;
4
5
  const ea = exposes.access;
@@ -47,4 +48,28 @@ module.exports = [
47
48
  vendor: 'Miboxer',
48
49
  extend: extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}),
49
50
  },
51
+ {
52
+ fingerprint: [{manufacturerName: '_TZ3000_xwh1e22x'}],
53
+ model: 'FUT089Z',
54
+ vendor: 'MiBoxer',
55
+ description: 'RGB+CCT Remote',
56
+ fromZigbee: [fz.battery],
57
+ toZigbee: [],
58
+ exposes: [e.battery(), e.battery_voltage()],
59
+ configure: async (device, coordinatorEndpoint, logger) => {
60
+ const endpoint = device.getEndpoint(1);
61
+ await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
62
+ await endpoint.command('genGroups', 'miboxerSetZones', {zones: [
63
+ {zoneNum: 1, groupId: 101},
64
+ {zoneNum: 2, groupId: 102},
65
+ {zoneNum: 3, groupId: 103},
66
+ {zoneNum: 4, groupId: 104},
67
+ {zoneNum: 5, groupId: 105},
68
+ {zoneNum: 6, groupId: 106},
69
+ {zoneNum: 7, groupId: 107},
70
+ {zoneNum: 8, groupId: 108},
71
+ ]});
72
+ await endpoint.command('genBasic', 'tuyaSetup', {}, {disableDefaultResponse: true});
73
+ },
74
+ },
50
75
  ];
package/devices/nue_3a.js CHANGED
@@ -137,8 +137,12 @@ module.exports = [
137
137
  model: 'HGZB-04D / HGZB-4D-UK',
138
138
  vendor: 'Nue / 3A',
139
139
  description: 'Smart dimmer wall switch',
140
- extend: extend.light_onoff_brightness({disableEffect: true}),
140
+ extend: extend.light_onoff_brightness({disableEffect: true, noConfigure: true}),
141
141
  whiteLabel: [{vendor: 'Sunricher', model: 'SR-ZG9001K8-DIM'}],
142
+ configure: async (device, coordinatorEndpoint, logger) => {
143
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
144
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
145
+ },
142
146
  },
143
147
  {
144
148
  zigbeeModel: ['FB56+ZSW1HKJ1.7', 'FB56+ZSW1HKJ2.5', 'FB56+ZSW1HKJ2.7'],
@@ -108,6 +108,15 @@ module.exports = [
108
108
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
109
109
  ota: ota.zigbeeOTA,
110
110
  },
111
+ {
112
+ zigbeeModel: ['915005996801', '915005996901'],
113
+ model: '915005996901',
114
+ vendor: 'Philips',
115
+ description: 'Hue white ambiance ceiling light Enrave L with Bluetooth',
116
+ meta: {turnsOffAtBrightness1: true},
117
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
118
+ ota: ota.zigbeeOTA,
119
+ },
111
120
  {
112
121
  zigbeeModel: ['915005997001', '915005997101'],
113
122
  model: '915005997001',
package/devices/tuya.js CHANGED
@@ -167,7 +167,7 @@ module.exports = [
167
167
  description: 'Air quality sensor',
168
168
  fromZigbee: [fz.tuya_air_quality],
169
169
  toZigbee: [],
170
- exposes: [e.temperature(), e.humidity(), e.co2(), e.voc(), e.formaldehyd()],
170
+ exposes: [e.temperature(), e.humidity(), e.co2(), e.voc().withUnit('ppm'), e.formaldehyd()],
171
171
  },
172
172
  {
173
173
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_dwcarsat'}],
@@ -1086,7 +1086,6 @@ module.exports = [
1086
1086
  // Window pushers:
1087
1087
  {modelID: 'TS0601', manufacturerName: '_TZE200_g5wdnuow'},
1088
1088
  // Tubular motors:
1089
- {modelID: 'TS0601', manufacturerName: '_TZE200_fzo2pocs'},
1090
1089
  {modelID: 'TS0601', manufacturerName: '_TZE200_5sbebbzs'},
1091
1090
  {modelID: 'TS0601', manufacturerName: '_TZE200_zuz7f94z'},
1092
1091
  {modelID: 'TS0601', manufacturerName: '_TZE200_zyrdrmno'},
@@ -1107,7 +1106,6 @@ module.exports = [
1107
1106
  {vendor: 'Moes', model: 'AM43-0.45/40-ES-EB'},
1108
1107
  {vendor: 'Larkkey', model: 'ZSTY-SM-1SRZG-EU'},
1109
1108
  {vendor: 'Zemismart', model: 'ZM85EL-2Z', description: 'Roman Rod I type curtains track'},
1110
- {vendor: 'Zemismart', model: 'ZM25TQ', description: 'Tubular motor'},
1111
1109
  {vendor: 'Zemismart', model: 'AM43', description: 'Roller blind motor'},
1112
1110
  {vendor: 'Zemismart', model: 'M2805EGBZTN', description: 'Tubular motor'},
1113
1111
  {vendor: 'Zemismart', model: 'BCM500DS-TYZ', description: 'Curtain motor'},
package/devices/xiaomi.js CHANGED
@@ -1348,9 +1348,16 @@ module.exports = [
1348
1348
  model: 'ZNJLBL01LM',
1349
1349
  description: 'Aqara roller shade companion E1',
1350
1350
  vendor: 'Xiaomi',
1351
- fromZigbee: [fz.xiaomi_curtain_acn002_position, fz.xiaomi_curtain_acn002_status, fz.xiaomi_curtain_position_tilt,
1352
- fz.ignore_basic_report, fz.aqara_opple],
1351
+ fromZigbee: [fz.xiaomi_curtain_position, fz.xiaomi_curtain_acn002_status, fz.ignore_basic_report, fz.aqara_opple],
1353
1352
  toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_acn002_battery, tz.xiaomi_curtain_acn002_charging_status],
1353
+ onEvent: async (type, data, device) => {
1354
+ if (type === 'message' && data.type === 'attributeReport' && data.cluster === 'genMultistateOutput' &&
1355
+ data.data.hasOwnProperty('presentValue') && data.data['presentValue'] > 1) {
1356
+ // Try to read the position after the motor stops, the device occasionally report wrong data right after stopping
1357
+ // Might need to add delay, seems to be working without one but needs more tests.
1358
+ await device.getEndpoint(1).read('genAnalogOutput', ['presentValue']);
1359
+ }
1360
+ },
1354
1361
  exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery().withAccess(ea.STATE_GET),
1355
1362
  exposes.binary('charging_status', ea.STATE_GET, true, false)
1356
1363
  .withDescription('The current charging status.'),
@@ -154,4 +154,13 @@ module.exports = [
154
154
  // exposes.enum('situation_set', ea.STATE, Object.values(tuya.ZMAM02.AM02Situation)),
155
155
  ],
156
156
  },
157
+ {
158
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_fzo2pocs'}],
159
+ model: 'ZM25TQ',
160
+ vendor: 'Zemismart',
161
+ description: 'Tubular motor',
162
+ fromZigbee: [fz.tuya_cover, fz.ignore_basic_report],
163
+ toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options, tz.tuya_data_point_test],
164
+ exposes: [e.cover_position().setAccess('position', ea.STATE_SET)],
165
+ },
157
166
  ];
package/lib/exposes.js CHANGED
@@ -550,7 +550,7 @@ module.exports = {
550
550
  fan: () => new Fan(),
551
551
  flip_indicator_light: () => new Binary('flip_indicator_light', access.ALL, 'ON', 'OFF').withDescription('After turn on, the indicator light turns on while switch is off, and vice versa'),
552
552
  force: () => new Enum('force', access.STATE_SET, ['normal', 'open', 'close']).withDescription('Force the valve position'),
553
- formaldehyd: () => new Numeric('formaldehyd', access.STATE).withDescription('The measured formaldehyd value'),
553
+ formaldehyd: () => new Numeric('formaldehyd', access.STATE).withDescription('The measured formaldehyd value').withUnit('mg/m³'),
554
554
  gas: () => new Binary('gas', access.STATE, true, false).withDescription('Indicates whether the device detected gas'),
555
555
  hcho: () => new Numeric('hcho', access.STATE).withUnit('mg/m³').withDescription('Measured Hcho value'),
556
556
  holiday_temperature: () => new Numeric('holiday_temperature', access.STATE_SET).withUnit('°C').withDescription('Holiday temperature').withValueMin(0).withValueMax(30),
package/lib/tuya.js CHANGED
@@ -449,16 +449,23 @@ const dataPoints = {
449
449
  silvercrestSetColor: 5,
450
450
  silvercrestSetEffect: 6,
451
451
  // Fantem
452
+ fantemPowerSupplyMode: 101,
452
453
  fantemReportingTime: 102,
454
+ fantemExtSwitchType: 103,
453
455
  fantemTempCalibration: 104,
454
456
  fantemHumidityCalibration: 105,
457
+ fantemLoadDetectionMode: 105,
455
458
  fantemLuxCalibration: 106,
459
+ fantemExtSwitchStatus: 106,
456
460
  fantemTemp: 107,
457
461
  fantemHumidity: 108,
458
462
  fantemMotionEnable: 109,
463
+ fantemControlMode: 109,
459
464
  fantemBattery: 110,
460
465
  fantemLedEnable: 111,
461
466
  fantemReportingEnable: 112,
467
+ fantemLoadType: 112,
468
+ fantemLoadDimmable: 113,
462
469
  // Woox
463
470
  wooxSwitch: 102,
464
471
  wooxBattery: 14,
package/lib/xiaomi.js CHANGED
@@ -196,9 +196,10 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
196
196
  payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
197
197
  } else if (['WXKG14LM', 'WXKG16LM', 'WXKG17LM'].includes(model.model)) {
198
198
  payload.click_mode = {1: 'fast', 2: 'multi'}[value];
199
- } else if (['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM'].includes(model.model)) {
199
+ } else if (['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM', 'ZNMS12LM'].includes(model.model)) {
200
200
  // We don't know what the value means for these devices.
201
201
  // https://github.com/Koenkk/zigbee2mqtt/issues/11126
202
+ // https://github.com/Koenkk/zigbee2mqtt/issues/12279
202
203
  } else if (['WSDCGQ01LM', 'WSDCGQ11LM'].includes(model.model)) {
203
204
  // https://github.com/Koenkk/zigbee2mqtt/issues/798
204
205
  // Sometimes the sensor publishes non-realistic vales, filter these
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.497",
3
+ "version": "14.0.500",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [