zigbee-herdsman-converters 14.0.605 → 14.0.608

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.
@@ -1540,14 +1540,15 @@ const converters = {
1540
1540
  // HomeAssistant etc. work the other way round.
1541
1541
  // For zigbee-herdsman-converters: open = 100, close = 0
1542
1542
  // ubisys J1 will report 255 if lift or tilt positions are not known, so skip that.
1543
- const invert = model.meta && model.meta.coverInverted ? !options.invert_cover : options.invert_cover;
1543
+ const metaInvert = model.meta && model.meta.coverInverted;
1544
+ const invert = metaInvert ? !options.invert_cover : options.invert_cover;
1544
1545
  const coverStateFromTilt = model.meta && model.meta.coverStateFromTilt;
1545
1546
  if (msg.data.hasOwnProperty('currentPositionLiftPercentage') && msg.data['currentPositionLiftPercentage'] <= 100) {
1546
1547
  const value = msg.data['currentPositionLiftPercentage'];
1547
1548
  result[postfixWithEndpointName('position', msg, model, meta)] = invert ? value : 100 - value;
1548
1549
  if (!coverStateFromTilt) {
1549
1550
  result[postfixWithEndpointName('state', msg, model, meta)] =
1550
- invert ? (value === 100 ? 'CLOSE' : 'OPEN') : (value === 0 ? 'CLOSE' : 'OPEN');
1551
+ metaInvert ? (value === 0 ? 'CLOSE' : 'OPEN') : (value === 100 ? 'CLOSE' : 'OPEN');
1551
1552
  }
1552
1553
  }
1553
1554
  if (msg.data.hasOwnProperty('currentPositionTiltPercentage') && msg.data['currentPositionTiltPercentage'] <= 100) {
@@ -1555,7 +1556,7 @@ const converters = {
1555
1556
  result[postfixWithEndpointName('tilt', msg, model, meta)] = invert ? value : 100 - value;
1556
1557
  if (coverStateFromTilt) {
1557
1558
  result[postfixWithEndpointName('state', msg, model, meta)] =
1558
- invert ? (value === 100 ? 'OPEN' : 'CLOSE') : (value === 0 ? 'OPEN' : 'CLOSE');
1559
+ metaInvert ? (value === 100 ? 'OPEN' : 'CLOSE') : (value === 0 ? 'OPEN' : 'CLOSE');
1559
1560
  }
1560
1561
  }
1561
1562
  return result;
@@ -176,7 +176,7 @@ const converters = {
176
176
  if (!utils.isInRange(0, meta.mapped.meta.pinCodeCount - 1, user)) throw new Error('user must be in range for device');
177
177
 
178
178
  if (pinCode == null) {
179
- await entity.command('closuresDoorLock', 'clearPinCode', {'userid': user}, utils.getOptions(meta.mapped));
179
+ await entity.command('closuresDoorLock', 'clearPinCode', {'userid': user}, utils.getOptions(meta.mapped, entity));
180
180
  } else {
181
181
  if (isNaN(pinCode)) throw new Error('pinCode must be a number');
182
182
  const typeLookup = {'unrestricted': 0, 'year_day_schedule': 1, 'week_day_schedule': 2, 'master': 3, 'non_access': 4};
@@ -187,7 +187,7 @@ const converters = {
187
187
  'usertype': typeLookup[userType],
188
188
  'pincodevalue': pinCode.toString(),
189
189
  };
190
- await entity.command('closuresDoorLock', 'setPinCode', payload, utils.getOptions(meta.mapped));
190
+ await entity.command('closuresDoorLock', 'setPinCode', payload, utils.getOptions(meta.mapped, entity));
191
191
  }
192
192
  },
193
193
  convertGet: async (entity, key, meta) => {
@@ -235,7 +235,7 @@ const converters = {
235
235
  'userid': user,
236
236
  'userstatus': status,
237
237
  },
238
- utils.getOptions(meta.mapped),
238
+ utils.getOptions(meta.mapped, entity),
239
239
  );
240
240
  },
241
241
  convertGet: async (entity, key, meta) => {
@@ -3070,24 +3070,24 @@ const converters = {
3070
3070
 
3071
3071
  const oldPosition = meta.state.position;
3072
3072
  if (value == 100) {
3073
- await entity.command('closuresWindowCovering', 'upOpen', {}, utils.getOptions(meta.mapped));
3073
+ await entity.command('closuresWindowCovering', 'upOpen', {}, utils.getOptions(meta.mapped, entity));
3074
3074
  } else if (value == 0) {
3075
- await entity.command('closuresWindowCovering', 'downClose', {}, utils.getOptions(meta.mapped));
3075
+ await entity.command('closuresWindowCovering', 'downClose', {}, utils.getOptions(meta.mapped, entity));
3076
3076
  } else {
3077
3077
  if (oldPosition > value) {
3078
3078
  const delta = oldPosition - value;
3079
3079
  const mutiplicateur = meta.options.time_open / 100;
3080
3080
  const timeBeforeStop = delta * mutiplicateur;
3081
- await entity.command('closuresWindowCovering', 'downClose', {}, utils.getOptions(meta.mapped));
3081
+ await entity.command('closuresWindowCovering', 'downClose', {}, utils.getOptions(meta.mapped, entity));
3082
3082
  await sleepSeconds(timeBeforeStop);
3083
- await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped));
3083
+ await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped, entity));
3084
3084
  } else if (oldPosition < value) {
3085
3085
  const delta = value - oldPosition;
3086
3086
  const mutiplicateur = meta.options.time_close / 100;
3087
3087
  const timeBeforeStop = delta * mutiplicateur;
3088
- await entity.command('closuresWindowCovering', 'upOpen', {}, utils.getOptions(meta.mapped));
3088
+ await entity.command('closuresWindowCovering', 'upOpen', {}, utils.getOptions(meta.mapped, entity));
3089
3089
  await sleepSeconds(timeBeforeStop);
3090
- await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped));
3090
+ await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped, entity));
3091
3091
  }
3092
3092
  }
3093
3093
 
@@ -5545,7 +5545,7 @@ const converters = {
5545
5545
  scenename = value.name;
5546
5546
  }
5547
5547
 
5548
- const response = await entity.command('genScenes', 'store', {groupid, sceneid}, utils.getOptions(meta.mapped));
5548
+ const response = await entity.command('genScenes', 'store', {groupid, sceneid}, utils.getOptions(meta.mapped, entity));
5549
5549
 
5550
5550
  if (isGroup) {
5551
5551
  if (meta.membersState) {
@@ -5567,7 +5567,7 @@ const converters = {
5567
5567
  convertSet: async (entity, key, value, meta) => {
5568
5568
  const groupid = entity.constructor.name === 'Group' ? entity.groupID : 0;
5569
5569
  const sceneid = value;
5570
- await entity.command('genScenes', 'recall', {groupid, sceneid}, utils.getOptions(meta.mapped));
5570
+ await entity.command('genScenes', 'recall', {groupid, sceneid}, utils.getOptions(meta.mapped, entity));
5571
5571
 
5572
5572
  const addColorMode = (newState) => {
5573
5573
  if (newState.hasOwnProperty('color_temp')) {
@@ -5736,12 +5736,13 @@ const converters = {
5736
5736
  * We accept a SUCESS or NOT_FOUND as a result of the remove call.
5737
5737
  */
5738
5738
  const removeresp = await entity.command(
5739
- 'genScenes', 'remove', {groupid, sceneid}, utils.getOptions(meta.mapped),
5739
+ 'genScenes', 'remove', {groupid, sceneid}, utils.getOptions(meta.mapped, entity),
5740
5740
  );
5741
5741
 
5742
5742
  if (isGroup || (removeresp.status === 0 || removeresp.status == 133 || removeresp.status == 139)) {
5743
5743
  const response = await entity.command(
5744
- 'genScenes', 'add', {groupid, sceneid, scenename: '', transtime, extensionfieldsets}, utils.getOptions(meta.mapped),
5744
+ 'genScenes', 'add', {groupid, sceneid, scenename: '', transtime, extensionfieldsets},
5745
+ utils.getOptions(meta.mapped, entity),
5745
5746
  );
5746
5747
 
5747
5748
  if (isGroup) {
@@ -5768,7 +5769,7 @@ const converters = {
5768
5769
  const groupid = entity.constructor.name === 'Group' ? entity.groupID : 0;
5769
5770
  const sceneid = value;
5770
5771
  const response = await entity.command(
5771
- 'genScenes', 'remove', {groupid, sceneid}, utils.getOptions(meta.mapped),
5772
+ 'genScenes', 'remove', {groupid, sceneid}, utils.getOptions(meta.mapped, entity),
5772
5773
  );
5773
5774
  const isGroup = entity.constructor.name === 'Group';
5774
5775
  if (isGroup) {
@@ -5790,7 +5791,7 @@ const converters = {
5790
5791
  convertSet: async (entity, key, value, meta) => {
5791
5792
  const groupid = entity.constructor.name === 'Group' ? entity.groupID : 0;
5792
5793
  const response = await entity.command(
5793
- 'genScenes', 'removeAll', {groupid}, utils.getOptions(meta.mapped),
5794
+ 'genScenes', 'removeAll', {groupid}, utils.getOptions(meta.mapped, entity),
5794
5795
  );
5795
5796
  const isGroup = entity.constructor.name === 'Group';
5796
5797
  if (isGroup) {
@@ -0,0 +1,11 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_sln7ah6r'}],
6
+ model: 'Garza-Standard-A60',
7
+ vendor: 'Garza Smart',
8
+ description: 'Standard A60 bulb',
9
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
10
+ },
11
+ ];
package/devices/moes.js CHANGED
@@ -8,10 +8,78 @@ const extend = require('../lib/extend');
8
8
  const e = exposes.presets;
9
9
  const ea = exposes.access;
10
10
  const zosung = require('../lib/zosung');
11
+ const utils = require('../lib/utils');
11
12
  const fzZosung = zosung.fzZosung;
12
13
  const tzZosung = zosung.tzZosung;
13
14
  const ez = zosung.presetsZosung;
14
15
 
16
+ const fzLocal = {
17
+ ZSEUD: {
18
+ cluster: 'manuSpecificTuya',
19
+ type: ['commandDataResponse', 'commandDataReport'],
20
+ convert: async (model, msg, publish, options, meta) => {
21
+ const result = {};
22
+ for (const dpValue of msg.data.dpValues) {
23
+ const dp = dpValue.dp;
24
+ const value = tuya.getDataValue(dpValue);
25
+ switch (dp) {
26
+ case 1:
27
+ result.state_l1 = value ? 'ON' : 'OFF';
28
+ break;
29
+ case 2:
30
+ result.brightness_l1 = utils.mapNumberRange(value, 0, 1000, 0, 254);
31
+ break;
32
+ case 7:
33
+ result.state_l2 = value ? 'ON' : 'OFF';
34
+ break;
35
+ case 8:
36
+ result.brightness_l2 = utils.mapNumberRange(value, 0, 1000, 0, 254);
37
+ break;
38
+ default:
39
+ meta.logger.warn(`zigbee-herdsman-converters:ZSEUD: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(dpValue)}`);
40
+ }
41
+ }
42
+ return result;
43
+ },
44
+ },
45
+ };
46
+
47
+ const tzLocal = {
48
+ ZSEUD_state: {
49
+ key: ['state'],
50
+ convertSet: async (entity, key, value, meta) => {
51
+ const lookup = {l1: 1, l2: 7};
52
+ const dp = lookup[meta.endpoint_name];
53
+ await tuya.sendDataPointBool(entity, dp, value === 'ON');
54
+ },
55
+ },
56
+ ZSEUD_brightness: {
57
+ key: ['brightness'],
58
+ convertSet: async (entity, key, value, meta) => {
59
+ const lookup = {l1: 2, l2: 8};
60
+ const dp = lookup[meta.endpoint_name];
61
+
62
+ if (key == 'brightness') {
63
+ // upscale to 1000
64
+ if (value >= 0 && value <= 254) {
65
+ const newValue = utils.mapNumberRange(value, 0, 254, 0, 1000);
66
+ // Always use same transid as tuya_dimmer_state (https://github.com/Koenkk/zigbee2mqtt/issues/6366)
67
+ if (meta.state[`state_${meta.endpoint_name}`] === 'ON') {
68
+ await tuya.sendDataPointValue(entity, dp, newValue, 'dataRequest', 1);
69
+ } else {
70
+ await tuya.sendDataPoints(entity, [tuya.dpValueFromBool(dp-1, true), tuya.dpValueFromIntValue(dp, newValue)],
71
+ 'dataRequest', 1);
72
+ }
73
+ } else {
74
+ throw new Error('Dimmer brightness is out of range 0..254');
75
+ }
76
+ } else {
77
+ meta.logger.warn(`ZSEUD TZ unsupported key=${key} value=${value}`);
78
+ }
79
+ },
80
+ },
81
+ };
82
+
15
83
  module.exports = [
16
84
  {
17
85
  fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cymsnfvf'},
@@ -284,6 +352,24 @@ module.exports = [
284
352
  },
285
353
  exposes: [e.light_brightness().setAccess('state', ea.STATE_SET).setAccess('brightness', ea.STATE_SET)],
286
354
  },
355
+ {
356
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_fjjbhx9d'}],
357
+ model: 'ZS-EUD',
358
+ vendor: 'Moes',
359
+ description: '2 gang light dimmer switch',
360
+ fromZigbee: [fzLocal.ZSEUD, fz.ignore_basic_report],
361
+ toZigbee: [tzLocal.ZSEUD_brightness, tzLocal.ZSEUD_state],
362
+ meta: {turnsOffAtBrightness1: true, multiEndpoint: true},
363
+ configure: async (device, coordinatorEndpoint, logger) => {
364
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
365
+ if (device.getEndpoint(2)) await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
366
+ },
367
+ exposes: [e.light_brightness().withEndpoint('l1').setAccess('state', ea.STATE_SET).setAccess('brightness', ea.STATE_SET),
368
+ e.light_brightness().withEndpoint('l2').setAccess('state', ea.STATE_SET).setAccess('brightness', ea.STATE_SET)],
369
+ endpoint: (device) => {
370
+ return {'l1': 1, 'l2': 1};
371
+ },
372
+ },
287
373
  {
288
374
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_e3oitdyu'}],
289
375
  model: 'MS-105B',
@@ -0,0 +1,11 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_mcm6m1ma'}],
6
+ model: 'DL41-03-10-R-ZB',
7
+ vendor: 'Oz Smart Things',
8
+ description: 'Oz Smart RGBW Zigbee downlight 10w',
9
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
10
+ },
11
+ ];
package/devices/rtx.js CHANGED
@@ -76,4 +76,13 @@ module.exports = [
76
76
  'MoTu..= active weekdays ' +
77
77
  '1 = deactivate timer with 0)')],
78
78
  },
79
+ {
80
+ fingerprint: [{modelID: 'TS0202', manufacturerName: '_TZ3000_mwd3c2at'}],
81
+ model: 'ZMS4',
82
+ vendor: 'RTX',
83
+ description: 'Zigbee PIR sensor',
84
+ fromZigbee: [fz.ias_occupancy_alarm_1],
85
+ toZigbee: [],
86
+ exposes: [e.battery_low(), e.occupancy()],
87
+ },
79
88
  ];
@@ -16,7 +16,6 @@ module.exports = [
16
16
  {modelID: 'TS0601', manufacturerName: '_TZE200_c88teujp'},
17
17
  {modelID: 'TS0601', manufacturerName: '_TZE200_yw7cahqs'},
18
18
  {modelID: 'TS0601', manufacturerName: '_TZE200_azqp6ssj'},
19
- {modelID: 'TS0601', manufacturerName: '_TZE200_bvu2wnxz'},
20
19
  {modelID: 'TS0601', manufacturerName: '_TZE200_zuhszj9s'},
21
20
  {modelID: 'TS0601', manufacturerName: '_TZE200_9gvruqf5'},
22
21
  {modelID: 'TS0601', manufacturerName: '_TZE200_zr9c0day'},
package/devices/tuya.js CHANGED
@@ -26,13 +26,7 @@ const tzLocal = {
26
26
  hpsz: {
27
27
  key: ['led_state'],
28
28
  convertSet: async (entity, key, value, meta) => {
29
- switch (key) {
30
- case 'led_state': {
31
- const ledState = value.toUpperCase() === 'ON' ? true : false;
32
- await tuya.sendDataPointBool(entity, tuya.dataPoints.HPSZLEDState, ledState);
33
- return {led_state: value};
34
- }
35
- }
29
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.HPSZLEDState, value);
36
30
  },
37
31
  },
38
32
  TS0504B_color: {
@@ -302,7 +296,7 @@ const fzLocal = {
302
296
  result = {duration_of_absence: value};
303
297
  break;
304
298
  case tuya.dataPoints.HPSZLEDState:
305
- result = {state: value};
299
+ result = {led_state: value};
306
300
  break;
307
301
  default:
308
302
  meta.logger.warn(`zigbee-herdsman-converters:hpsz: NOT RECOGNIZED DP #${
@@ -631,7 +625,7 @@ module.exports = [
631
625
  fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
632
626
  toZigbee: [],
633
627
  exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
634
- whiteLabel: [{vendor: 'CR Smart Home', model: 'TS0203'}],
628
+ whiteLabel: [{vendor: 'CR Smart Home', model: 'TS0203'}, {vendor: 'TuYa', model: 'iH-F001'}],
635
629
  configure: async (device, coordinatorEndpoint, logger) => {
636
630
  try {
637
631
  const endpoint = device.getEndpoint(1);
@@ -892,7 +886,8 @@ module.exports = [
892
886
  {modelID: 'TS0501B', manufacturerName: '_TZ3210_nehayyhx'},
893
887
  {modelID: 'TS0501B', manufacturerName: '_TZ3210_wuheofsg'},
894
888
  {modelID: 'TS0501B', manufacturerName: '_TZ3210_e5t9bfdv'},
895
- {modelID: 'TS0501B', manufacturerName: '_TZ3210_19qb27da'}],
889
+ {modelID: 'TS0501B', manufacturerName: '_TZ3210_19qb27da'},
890
+ {modelID: 'TS0501B', manufacturerName: '_TZ3210_4zinq6io'}],
896
891
  model: 'TS0501B',
897
892
  description: 'Zigbee light',
898
893
  vendor: 'TuYa',
@@ -914,6 +909,7 @@ module.exports = [
914
909
  {modelID: 'TS0202', manufacturerName: '_TYZB01_ef5xlc9q'},
915
910
  {modelID: 'TS0202', manufacturerName: '_TYZB01_vwqnz1sn'},
916
911
  {modelID: 'TS0202', manufacturerName: '_TYZB01_2b8f6cio'},
912
+ {modelID: 'TS0202', manufacturerName: '_TYZB01_71kfvvma'},
917
913
  {modelID: 'TS0202', manufacturerName: '_TZE200_bq5c8xfe'},
918
914
  {modelID: 'TS0202', manufacturerName: '_TYZB01_dl7cejts'},
919
915
  {modelID: 'TS0202', manufacturerName: '_TYZB01_qjqgmqxr'},
@@ -1691,6 +1687,7 @@ module.exports = [
1691
1687
  {modelID: 'TS0601', manufacturerName: '_TZE200_tvrvdj6o'},
1692
1688
  {modelID: 'zo2pocs\u0000', manufacturerName: '_TYST11_fzo2pocs'},
1693
1689
  {modelID: 'TS0601', manufacturerName: '_TZE200_cf1sl3tj'},
1690
+ {modelID: 'TS0601', manufacturerName: '_TZE200_b2u1drdv'},
1694
1691
  // Roller blinds:
1695
1692
  {modelID: 'TS0601', manufacturerName: '_TZE200_fctwhugx'},
1696
1693
  {modelID: 'TS0601', manufacturerName: '_TZE200_zah67ekd'},
@@ -3135,7 +3132,7 @@ module.exports = [
3135
3132
  .withDescription('Shows the presence duration in minutes'),
3136
3133
  exposes.numeric('duration_of_absence', ea.STATE).withUnit('minutes')
3137
3134
  .withDescription('Shows the duration of the absence in minutes'),
3138
- exposes.enum('led_state', ea.STATE_SET, ['on', 'off'])
3135
+ exposes.binary('led_state', ea.STATE_SET, true, false)
3139
3136
  .withDescription('Turns the onboard LED on or off'),
3140
3137
  ],
3141
3138
  },
package/devices/yale.js CHANGED
@@ -55,7 +55,7 @@ module.exports = [
55
55
  vendor: 'Yale',
56
56
  description: 'Real living lock / Intelligent biometric digital lock',
57
57
  // Increased timeout needed: https://github.com/Koenkk/zigbee2mqtt/issues/3290 for YDM4109+
58
- extend: lockExtend({timeout: 20000}),
58
+ extend: lockExtend({battery: {dontDividePercentage: true}}, {timeout: 20000}),
59
59
  },
60
60
  {
61
61
  zigbeeModel: ['YRD210 PB DB'],
@@ -129,7 +129,7 @@ module.exports = [
129
129
  model: 'YDF40',
130
130
  vendor: 'Yale',
131
131
  description: 'Real living lock / Intelligent biometric digital lock',
132
- extend: lockExtend({}, {max: 900}, ['closuresDoorLock']),
132
+ extend: lockExtend({battery: {dontDividePercentage: true}}, {max: 900}, ['closuresDoorLock']),
133
133
  },
134
134
  {
135
135
  zigbeeModel: ['06ffff2027'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.605",
3
+ "version": "14.0.608",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [