zigbee-herdsman-converters 14.0.586 → 14.0.589

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.
package/README.md CHANGED
@@ -28,6 +28,7 @@ If any of those commands finish with an error your PR won't pass the tests and w
28
28
  - `disableActionGroup`: Prevents some converters adding the action_group to the payload (default: false)
29
29
  - `tuyaThermostatSystemMode`/`tuyaThermostatPreset`: TuYa specific thermostat options
30
30
  - `thermostat`: see e.g. HT-08 definition
31
+ - `{dontMapPIHeatingDemand: true}`: do not map piHeatingDemand from 0-255 -> 0-100, see fromZigbee.thermostat (default: false)
31
32
  - `battery`:
32
33
  - `{dontDividePercentage: true}`: prevents batteryPercentageRemainig from being divided (ZCL 200=100%, but some report 100=100%) (default: false)
33
34
  - `{voltageToPercentage: '3V_2100'}`: convert voltage to percentage using specified option. See utils.batteryVoltageToPercentage() (default: null, no voltage to percentage conversion)
@@ -37,6 +37,7 @@ const converters = {
37
37
  type: ['attributeReport', 'readResponse'],
38
38
  convert: (model, msg, publish, options, meta) => {
39
39
  const result = {};
40
+ const dontMapPIHeatingDemand = model.meta && model.meta.thermostat && model.meta.thermostat.dontMapPIHeatingDemand;
40
41
  if (msg.data.hasOwnProperty('localTemp')) {
41
42
  result[postfixWithEndpointName('local_temperature', msg, model, meta)] = precisionRound(msg.data['localTemp'], 2) / 100;
42
43
  }
@@ -110,7 +111,7 @@ const converters = {
110
111
  }
111
112
  if (msg.data.hasOwnProperty('pIHeatingDemand')) {
112
113
  result[postfixWithEndpointName('pi_heating_demand', msg, model, meta)] =
113
- mapNumberRange(msg.data['pIHeatingDemand'], 0, 255, 0, 100);
114
+ mapNumberRange(msg.data['pIHeatingDemand'], 0, (dontMapPIHeatingDemand ? 100: 255), 0, 100);
114
115
  }
115
116
  if (msg.data.hasOwnProperty('tempSetpointHold')) {
116
117
  result[postfixWithEndpointName('temperature_setpoint_hold', msg, model, meta)] = msg.data['tempSetpointHold'] == 1;
@@ -2488,18 +2489,6 @@ const converters = {
2488
2489
  }
2489
2490
  },
2490
2491
  },
2491
- sinope_thermostat: {
2492
- cluster: 'hvacThermostat',
2493
- type: ['attributeReport', 'readResponse'],
2494
- convert: (model, msg, publish, options, meta) => {
2495
- const result = converters.thermostat.convert(model, msg, publish, options, meta);
2496
- // Sinope seems to report pIHeatingDemand between 0 and 100 already
2497
- if (msg.data.hasOwnProperty('pIHeatingDemand')) {
2498
- result.pi_heating_demand = precisionRound(msg.data['pIHeatingDemand'], 0);
2499
- }
2500
- return result;
2501
- },
2502
- },
2503
2492
  stelpro_thermostat: {
2504
2493
  cluster: 'hvacThermostat',
2505
2494
  type: ['attributeReport', 'readResponse'],
@@ -3516,11 +3505,6 @@ const converters = {
3516
3505
  type: ['attributeReport', 'readResponse'],
3517
3506
  convert: (model, msg, publish, options, meta) => {
3518
3507
  const result = {};
3519
- // Danfoss sends pi_heating_demand as raw %
3520
- if (typeof msg.data['pIHeatingDemand'] == 'number') {
3521
- result[postfixWithEndpointName('pi_heating_demand', msg, model, meta)] =
3522
- precisionRound(msg.data['pIHeatingDemand'], 0);
3523
- }
3524
3508
  if (msg.data.hasOwnProperty('danfossWindowOpenFeatureEnable')) {
3525
3509
  result[postfixWithEndpointName('window_open_feature', msg, model, meta)] =
3526
3510
  (msg.data['danfossWindowOpenFeatureEnable'] === 1);
@@ -8445,6 +8429,9 @@ const converters = {
8445
8429
  break;
8446
8430
  }
8447
8431
  break;
8432
+ case tuya.dataPoints.AM02AddRemoter: // DP 101: Ignore until need is defined
8433
+ case tuya.dataPoints.AM02TimeTotal: // DP 10: Ignore until need is defined
8434
+ break;
8448
8435
  default: // Unknown code
8449
8436
  meta.logger.warn(`ZMAM02_cover: Unhandled DP #${dp} for ${meta.device.manufacturerName}:
8450
8437
  ${JSON.stringify(dpValue)}`);
@@ -2562,15 +2562,15 @@ const converters = {
2562
2562
  },
2563
2563
  lidl_watering_timer: {
2564
2564
  key: ['timer'],
2565
- convertSet: (entity, key, value, meta) => {
2566
- tuya.sendDataPointRaw(entity, tuya.dataPoints.lidlTimer, tuya.convertDecimalValueTo4ByteHexArray(value));
2565
+ convertSet: async (entity, key, value, meta) => {
2566
+ await tuya.sendDataPointRaw(entity, tuya.dataPoints.lidlTimer, tuya.convertDecimalValueTo4ByteHexArray(value));
2567
2567
  },
2568
2568
  },
2569
2569
  matsee_garage_door_opener: {
2570
2570
  key: ['trigger'],
2571
- convertSet: (entity, key, value, meta) => {
2571
+ convertSet: async (entity, key, value, meta) => {
2572
2572
  const state = meta.message.hasOwnProperty('trigger') ? meta.message.trigger : true;
2573
- tuya.sendDataPointBool(entity, tuya.dataPoints.garageDoorTrigger, state);
2573
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.garageDoorTrigger, state);
2574
2574
  return {state: {trigger: state}};
2575
2575
  },
2576
2576
  },
@@ -4927,7 +4927,7 @@ const converters = {
4927
4927
  payload[i * 3 + 2] = value[prob][i].temperature;
4928
4928
  }
4929
4929
  }
4930
- tuya.sendDataPointRaw(entity, dpId, payload);
4930
+ await tuya.sendDataPointRaw(entity, dpId, payload);
4931
4931
  }
4932
4932
  },
4933
4933
  },
@@ -4956,7 +4956,7 @@ const converters = {
4956
4956
  payload[i*3+1] = minute;
4957
4957
  payload[i*3+2] = temperature;
4958
4958
  }
4959
- tuya.sendDataPointRaw(entity, dpId, payload);
4959
+ await tuya.sendDataPointRaw(entity, dpId, payload);
4960
4960
  },
4961
4961
  },
4962
4962
  tuya_thermostat_week: {
@@ -6613,7 +6613,7 @@ const converters = {
6613
6613
  },
6614
6614
  wiser_sed_thermostat_local_temperature_calibration: {
6615
6615
  key: ['local_temperature_calibration'],
6616
- convertSet: (entity, key, value, meta) => {
6616
+ convertSet: async (entity, key, value, meta) => {
6617
6617
  entity.write('hvacThermostat', {localTemperatureCalibration: Math.round(value * 10)},
6618
6618
  {srcEndpoint: 11, disableDefaultResponse: true, sendWhen: 'active'});
6619
6619
  return {state: {local_temperature_calibration: value}};
@@ -6762,7 +6762,7 @@ const converters = {
6762
6762
  await tuya.sendDataPointRaw(entity, 102, [value]);
6763
6763
  break;
6764
6764
  } else {
6765
- tuya.sendDataPointRaw(entity, 105, [value]);
6765
+ await tuya.sendDataPointRaw(entity, 105, [value]);
6766
6766
  break;
6767
6767
  }
6768
6768
  case 'led_enable':// OK (value true/false or 1/0)
package/devices/adeo.js CHANGED
@@ -5,7 +5,37 @@ const extend = require('../lib/extend');
5
5
  const tz = require('../converters/toZigbee');
6
6
  const e = exposes.presets;
7
7
 
8
+ const fzLocal = {
9
+ LDSENK08: {
10
+ cluster: 'ssIasZone',
11
+ type: 'commandStatusChangeNotification',
12
+ convert: (model, msg, publish, options, meta) => {
13
+ const zoneStatus = msg.data.zonestatus;
14
+ return {
15
+ contact: !((zoneStatus & 1) > 0),
16
+ vibration: (zoneStatus & 1<<1) > 0,
17
+ tamper: (zoneStatus & 1<<2) > 0,
18
+ battery_low: (zoneStatus & 1<<3) > 0,
19
+ };
20
+ },
21
+ },
22
+ };
23
+
8
24
  module.exports = [
25
+ {
26
+ zigbeeModel: ['LDSENK08'],
27
+ model: 'LDSENK08',
28
+ vendor: 'ADEO',
29
+ description: 'ENKI LEXMAN wireless smart door window sensor with vibration',
30
+ fromZigbee: [fzLocal.LDSENK08, fz.battery],
31
+ toZigbee: [],
32
+ exposes: [e.battery_low(), e.contact(), e.vibration(), e.tamper(), e.battery()],
33
+ configure: async (device, coordinatorEndpoint, logger) => {
34
+ const endpoint = device.getEndpoint(1);
35
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
36
+ await reporting.batteryPercentageRemaining(endpoint);
37
+ },
38
+ },
9
39
  {
10
40
  zigbeeModel: ['LDSENK09'],
11
41
  model: 'LDSENK09',
@@ -7,7 +7,7 @@ const e = exposes.presets;
7
7
 
8
8
  module.exports = [
9
9
  {
10
- zigbeeModel: ['5j6ifxj'],
10
+ zigbeeModel: ['5j6ifxj', '5j6ifxj\u0000'],
11
11
  model: 'BW-IS3',
12
12
  vendor: 'BlitzWolf',
13
13
  description: 'Rechargeable Zigbee PIR motion sensor',
@@ -16,6 +16,7 @@ module.exports = [
16
16
  vendor: 'Danfoss',
17
17
  description: 'Ally thermostat',
18
18
  whiteLabel: [{vendor: 'Danfoss', model: '014G2463'}],
19
+ meta: {thermostat: {dontMapPIHeatingDemand: true}},
19
20
  fromZigbee: [fz.battery, fz.thermostat, fz.thermostat_weekly_schedule, fz.hvac_user_interface, fz.danfoss_thermostat],
20
21
  toZigbee: [tz.danfoss_thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature, tz.danfoss_mounted_mode_active,
21
22
  tz.danfoss_mounted_mode_control, tz.danfoss_thermostat_vertical_orientation, tz.danfoss_algorithm_scale_factor,
@@ -213,7 +214,7 @@ module.exports = [
213
214
  tz.danfoss_system_status_code,
214
215
  tz.danfoss_multimaster_role,
215
216
  ],
216
- meta: {multiEndpoint: true},
217
+ meta: {multiEndpoint: true, thermostat: {dontMapPIHeatingDemand: true}},
217
218
  // ota: ota.zigbeeOTA,
218
219
  endpoint: (device) => {
219
220
  return {
package/devices/ikea.js CHANGED
@@ -5,7 +5,9 @@ const ota = require('../lib/ota');
5
5
  const constants = require('../lib/constants');
6
6
  const reporting = require('../lib/reporting');
7
7
  const {repInterval} = require('../lib/constants');
8
+ const utils = require('../lib/utils');
8
9
  const extend = require('../lib/extend');
10
+ const globalStore = require('../lib/store');
9
11
  const e = exposes.presets;
10
12
  const ea = exposes.access;
11
13
  const herdsman = require('zigbee-herdsman');
@@ -58,6 +60,39 @@ const configureRemote = async (device, coordinatorEndpoint, logger) => {
58
60
  await reporting.batteryPercentageRemaining(endpoint);
59
61
  };
60
62
 
63
+ const fzLocal = {
64
+ // The STYRBAR sends an on +- 500ms after the arrow release. We don't want to send the ON action in this case.
65
+ // https://github.com/Koenkk/zigbee2mqtt/issues/13335
66
+ STYRBAR_on: {
67
+ cluster: 'genOnOff',
68
+ type: 'commandOn',
69
+ convert: (model, msg, publish, options, meta) => {
70
+ if (utils.hasAlreadyProcessedMessage(msg)) return;
71
+ const arrowReleaseAgo = Date.now() - globalStore.getValue(msg.endpoint, 'arrow_release', 0);
72
+ if (arrowReleaseAgo > 700) {
73
+ return {action: 'on'};
74
+ }
75
+ },
76
+ },
77
+ STYRBAR_arrow_release: {
78
+ cluster: 'genScenes',
79
+ type: 'commandTradfriArrowRelease',
80
+ options: [exposes.options.legacy()],
81
+ convert: (model, msg, publish, options, meta) => {
82
+ if (utils.hasAlreadyProcessedMessage(msg)) return;
83
+ globalStore.putValue(msg.endpoint, 'arrow_release', Date.now());
84
+ const direction = globalStore.getValue(msg.endpoint, 'direction');
85
+ if (direction) {
86
+ globalStore.clearValue(msg.endpoint, 'direction');
87
+ const duration = msg.data.value / 1000;
88
+ const result = {action: `arrow_${direction}_release`, duration, action_duration: duration};
89
+ if (!utils.isLegacyEnabled(options)) delete result.duration;
90
+ return result;
91
+ }
92
+ },
93
+ },
94
+ };
95
+
61
96
  const tradfriExtend = {
62
97
  light_onoff_brightness: (options = {}) => ({
63
98
  ...extend.light_onoff_brightness(options),
@@ -571,9 +606,9 @@ module.exports = [
571
606
  zigbeeModel: ['Remote Control N2'],
572
607
  model: 'E2001/E2002',
573
608
  vendor: 'IKEA',
574
- description: 'STYRBAR remote control N2',
575
- fromZigbee: [fz.battery, fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.ikea_arrow_click,
576
- fz.ikea_arrow_hold, fz.ikea_arrow_release],
609
+ description: 'STYRBAR remote control',
610
+ fromZigbee: [fz.battery, fzLocal.STYRBAR_on, fz.command_off, fz.command_move, fz.command_stop, fz.ikea_arrow_click,
611
+ fz.ikea_arrow_hold, fzLocal.STYRBAR_arrow_release],
577
612
  exposes: [e.battery(), e.action(['on', 'off', 'brightness_move_up', 'brightness_move_down',
578
613
  'brightness_stop', 'arrow_left_click', 'arrow_right_click', 'arrow_left_hold',
579
614
  'arrow_right_hold', 'arrow_left_release', 'arrow_right_release'])],
@@ -0,0 +1,51 @@
1
+ const exposes = require('../lib/exposes');
2
+ const fz = require('../converters/fromZigbee');
3
+ const tz = require('../converters/toZigbee');
4
+ const reporting = require('../lib/reporting');
5
+ const utils = require('../lib/utils');
6
+ const e = exposes.presets;
7
+ const ea = exposes.access;
8
+
9
+ const fzLocal = {
10
+ // MG-AUZG01 requires multiEndpoint only for on_off
11
+ // https://github.com/Koenkk/zigbee2mqtt/issues/13190
12
+ MGAUZG01_on_off: {
13
+ cluster: 'genOnOff',
14
+ type: ['attributeReport', 'readResponse'],
15
+ convert: (model, msg, publish, options, meta) => {
16
+ if (msg.data.hasOwnProperty('onOff')) {
17
+ const endpointName = utils.getKey(model.endpoint(meta.device), msg.endpoint.ID);
18
+ return {[`state_${endpointName}`]: msg.data['onOff'] === 1 ? 'ON' : 'OFF'};
19
+ }
20
+ },
21
+ },
22
+ };
23
+
24
+ module.exports = [
25
+ {
26
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_dd8wwzcy'}],
27
+ model: 'MG-AUZG01',
28
+ vendor: 'Makegood',
29
+ description: 'Double Zigbee power point',
30
+ fromZigbee: [fzLocal.MGAUZG01_on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report],
31
+ toZigbee: [tz.on_off],
32
+ exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.power(), e.current(), e.voltage().withAccess(ea.STATE),
33
+ e.energy()],
34
+ endpoint: (device) => {
35
+ return {'l1': 1, 'l2': 2};
36
+ },
37
+ configure: async (device, coordinatorEndpoint, logger) => {
38
+ const endpoint = device.getEndpoint(1);
39
+ await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
40
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
41
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
42
+ await reporting.rmsVoltage(endpoint, {change: 5});
43
+ await reporting.rmsCurrent(endpoint, {change: 50});
44
+ await reporting.activePower(endpoint, {change: 10});
45
+ await reporting.currentSummDelivered(endpoint);
46
+ endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
47
+ endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
48
+ device.save();
49
+ },
50
+ },
51
+ ];
@@ -100,7 +100,8 @@ module.exports = [
100
100
  toZigbee: extend.light_onoff_brightness_colortemp_color().toZigbee.concat([tz.tint_scene]),
101
101
  },
102
102
  {
103
- fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_mntza0sw'}],
103
+ fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_mntza0sw'},
104
+ {modelID: 'TS0505B', manufacturerName: '_TZ3210_r0vzq1oj'}],
104
105
  model: '404062',
105
106
  vendor: 'Müller Licht',
106
107
  description: 'Kea RGB+CCT',
package/devices/namron.js CHANGED
@@ -8,6 +8,13 @@ const ea = exposes.access;
8
8
  const e = exposes.presets;
9
9
 
10
10
  module.exports = [
11
+ {
12
+ zigbeeModel: ['3308431'],
13
+ model: '3308431',
14
+ vendor: 'Namron',
15
+ description: 'Luna ceiling light',
16
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
17
+ },
11
18
  {
12
19
  zigbeeModel: ['3802967'],
13
20
  model: '3802967',
package/devices/sinope.js CHANGED
@@ -13,6 +13,7 @@ module.exports = [
13
13
  model: 'TH1123ZB',
14
14
  vendor: 'Sinopé',
15
15
  description: 'Zigbee line volt thermostat',
16
+ meta: {thermostat: {dontMapPIHeatingDemand: true}},
16
17
  fromZigbee: [fz.legacy.sinope_thermostat_att_report, fz.legacy.hvac_user_interface, fz.electrical_measurement, fz.metering,
17
18
  fz.ignore_temperature_report, fz.legacy.sinope_thermostat_state],
18
19
  toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
@@ -69,6 +70,7 @@ module.exports = [
69
70
  model: 'TH1124ZB',
70
71
  vendor: 'Sinopé',
71
72
  description: 'Zigbee line volt thermostat',
73
+ meta: {thermostat: {dontMapPIHeatingDemand: true}},
72
74
  fromZigbee: [fz.legacy.sinope_thermostat_att_report, fz.legacy.hvac_user_interface, fz.electrical_measurement, fz.metering,
73
75
  fz.ignore_temperature_report, fz.legacy.sinope_thermostat_state],
74
76
  toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
@@ -126,6 +128,7 @@ module.exports = [
126
128
  model: 'TH1300ZB',
127
129
  vendor: 'Sinopé',
128
130
  description: 'Zigbee smart floor heating thermostat',
131
+ meta: {thermostat: {dontMapPIHeatingDemand: true}},
129
132
  fromZigbee: [fz.legacy.sinope_thermostat_att_report, fz.legacy.hvac_user_interface, fz.electrical_measurement,
130
133
  fz.ignore_temperature_report, fz.legacy.sinope_thermostat_state, fz.sinope_TH1300ZB_specific],
131
134
  toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
@@ -184,6 +187,7 @@ module.exports = [
184
187
  model: 'TH1400ZB',
185
188
  vendor: 'Sinopé',
186
189
  description: 'Zigbee low volt thermostat',
190
+ meta: {thermostat: {dontMapPIHeatingDemand: true}},
187
191
  fromZigbee: [fz.legacy.sinope_thermostat_att_report, fz.legacy.sinope_thermostat_state],
188
192
  toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_temperature_display_mode,
189
193
  tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.thermostat_running_state,
package/devices/tuya.js CHANGED
@@ -19,7 +19,7 @@ const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak',
19
19
  '_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
20
20
  '_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5', '_TZ3000_amdymr7l', '_TZ3000_z1pnpsdo', '_TZ3000_ksw8qtmt',
21
21
  '_TZ3000_1h2x4akh', '_TZ3000_9vo5icau', '_TZ3000_cehuw1lw', '_TZ3000_ko6v90pg', '_TZ3000_f1bapcit', '_TZ3000_cjrngdr3',
22
- '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_dd8wwzcy', '_TZ3000_okaz9tjs', '_TZ3210_q7oryllx'];
22
+ '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_idrffznf', '_TZ3000_okaz9tjs', '_TZ3210_q7oryllx'];
23
23
 
24
24
  const tzLocal = {
25
25
  TS0504B_color: {
@@ -795,7 +795,8 @@ module.exports = [
795
795
  {modelID: 'TS0503B', manufacturerName: '_TZ3000_g5xawfcq'},
796
796
  {modelID: 'TS0503B', manufacturerName: '_TZ3210_trm3l2aw'},
797
797
  {modelID: 'TS0503B', manufacturerName: '_TZ3210_95txyzbx'},
798
- {modelID: 'TS0503B', manufacturerName: '_TZ3210_odlghna1'}],
798
+ {modelID: 'TS0503B', manufacturerName: '_TZ3210_odlghna1'},
799
+ {modelID: 'TS0503B', manufacturerName: '_TZ3220_wp1k8xws'}],
799
800
  model: 'TS0503B',
800
801
  vendor: 'TuYa',
801
802
  description: 'Zigbee RGB light',
@@ -1162,6 +1163,7 @@ module.exports = [
1162
1163
  },
1163
1164
  {
1164
1165
  fingerprint: [{modelID: 'TS0215A', manufacturerName: '_TZ3000_p6ju8myv'},
1166
+ {modelID: 'TS0215A', manufacturerName: '_TZ3000_0zrccfgx'},
1165
1167
  {modelID: 'TS0215A', manufacturerName: '_TZ3000_fsiepnrh'}],
1166
1168
  model: 'TS0215A_remote',
1167
1169
  vendor: 'TuYa',
@@ -1478,7 +1480,11 @@ module.exports = [
1478
1480
  meta: {multiEndpoint: true},
1479
1481
  configure: async (device, coordinatorEndpoint, logger) => {
1480
1482
  const ep1 = device.getEndpoint(1);
1481
- await ep1.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
1483
+ try {
1484
+ await ep1.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
1485
+ } catch (e) {
1486
+ // Fails for some: https://github.com/Koenkk/zigbee2mqtt/discussions/13368
1487
+ }
1482
1488
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
1483
1489
  await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
1484
1490
  },
package/devices/ubisys.js CHANGED
@@ -792,6 +792,7 @@ module.exports = [
792
792
  model: 'H1',
793
793
  vendor: 'Ubisys',
794
794
  description: 'Heating regulator',
795
+ meta: {thermostat: {dontMapPIHeatingDemand: true}},
795
796
  fromZigbee: [fz.battery, fz.thermostat, fz.thermostat_weekly_schedule, ubisys.fz.thermostat_vacation_mode],
796
797
  toZigbee: [
797
798
  tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
@@ -154,10 +154,7 @@ module.exports = [
154
154
  },
155
155
  },
156
156
  {
157
- fingerprint: [
158
- {modelID: 'TS0601', manufacturerName: '_TZE200_iossyxra'},
159
- {modelID: 'TS0601', manufacturerName: '_TZE200_gubdgai2'},
160
- ],
157
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_iossyxra'}],
161
158
  model: 'ZM-AM02_cover',
162
159
  vendor: 'Zemismart',
163
160
  description: 'Zigbee/RF curtain converter',
@@ -183,6 +180,18 @@ module.exports = [
183
180
  // exposes.enum('situation_set', ea.STATE, Object.values(tuya.ZMAM02.AM02Situation)),
184
181
  ],
185
182
  },
183
+ {
184
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_gubdgai2'}],
185
+ model: 'M515EGBZTN',
186
+ vendor: 'Zemismart',
187
+ description: 'Roller shade driver',
188
+ fromZigbee: [fz.ZMAM02_cover],
189
+ toZigbee: [tz.ZMAM02_cover],
190
+ exposes: [e.cover_position().setAccess('position', ea.STATE_SET),
191
+ exposes.enum('motor_direction', ea.STATE_SET, Object.values(tuya.ZMLookups.AM02Direction)),
192
+ exposes.enum('border', ea.STATE_SET, Object.values(tuya.ZMLookups.AM02Border)),
193
+ ],
194
+ },
186
195
  {
187
196
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_fzo2pocs'}],
188
197
  model: 'ZM25TQ',
package/lib/legacy.js CHANGED
@@ -1726,7 +1726,7 @@ const fromZigbee = {
1726
1726
  options: [exposes.options.legacy()],
1727
1727
  convert: (model, msg, publish, options, meta) => {
1728
1728
  if (!isLegacyEnabled(options)) {
1729
- return fromZigbeeConverters.sinope_thermostat.convert(model, msg, publish, options, meta);
1729
+ return fromZigbeeConverters.thermostat.convert(model, msg, publish, options, meta);
1730
1730
  }
1731
1731
 
1732
1732
  const result = fromZigbee.thermostat_att_report.convert(model, msg, publish, options, meta);
package/lib/reporting.js CHANGED
@@ -171,7 +171,7 @@ module.exports = {
171
171
  await endpoint.configureReporting('hvacThermostat', p);
172
172
  },
173
173
  thermostatRunningMode: async (endpoint, overrides) => {
174
- const p = payload('runningMode', 0, repInterval.HOUR, 0, overrides);
174
+ const p = payload('runningMode', 10, repInterval.HOUR, null, overrides);
175
175
  await endpoint.configureReporting('hvacThermostat', p);
176
176
  },
177
177
  thermostatOcupancy: async (endpoint, overrides) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.586",
3
+ "version": "14.0.589",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -38,7 +38,7 @@
38
38
  "buffer-crc32": "^0.2.13",
39
39
  "https-proxy-agent": "^5.0.1",
40
40
  "tar-stream": "^2.2.0",
41
- "zigbee-herdsman": "^0.14.46"
41
+ "zigbee-herdsman": "^0.14.47"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",