zigbee-herdsman-converters 14.0.292 → 14.0.296

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.
@@ -108,6 +108,26 @@ const converters = {
108
108
  if (msg.data.hasOwnProperty('tempSetpointHoldDuration')) {
109
109
  result[postfixWithEndpointName('temperature_setpoint_hold_duration', msg, model)] = msg.data['tempSetpointHoldDuration'];
110
110
  }
111
+ if (msg.data.hasOwnProperty('minHeatSetpointLimit')) {
112
+ let value = precisionRound(msg.data['minHeatSetpointLimit'], 2) / 100;
113
+ value = value < -250 ? 0 : value;
114
+ result[postfixWithEndpointName('min_heat_setpoint_limit', msg, model)] = value;
115
+ }
116
+ if (msg.data.hasOwnProperty('maxHeatSetpointLimit')) {
117
+ let value = precisionRound(msg.data['maxHeatSetpointLimit'], 2) / 100;
118
+ value = value < -250 ? 0 : value;
119
+ result[postfixWithEndpointName('max_heat_setpoint_limit', msg, model)] = value;
120
+ }
121
+ if (msg.data.hasOwnProperty('absMinHeatSetpointLimit')) {
122
+ let value = precisionRound(msg.data['absMinHeatSetpointLimit'], 2) / 100;
123
+ value = value < -250 ? 0 : value;
124
+ result[postfixWithEndpointName('abs_min_heat_setpoint_limit', msg, model)] = value;
125
+ }
126
+ if (msg.data.hasOwnProperty('absMaxHeatSetpointLimit')) {
127
+ let value = precisionRound(msg.data['absMaxHeatSetpointLimit'], 2) / 100;
128
+ value = value < -250 ? 0 : value;
129
+ result[postfixWithEndpointName('abs_max_heat_setpoint_limit', msg, model)] = value;
130
+ }
111
131
  return result;
112
132
  },
113
133
  },
@@ -3007,6 +3027,62 @@ const converters = {
3007
3027
  if (msg.data.hasOwnProperty('danfossLoadEstimate')) {
3008
3028
  result[postfixWithEndpointName('load_estimate', msg, model)] = msg.data['danfossLoadEstimate'];
3009
3029
  }
3030
+ // Danfoss Icon Converters
3031
+ if (msg.data.hasOwnProperty('danfossRoomStatusCode')) {
3032
+ result[postfixWithEndpointName('room_status_code', msg, model)] =
3033
+ constants.danfossRoomStatusCode.hasOwnProperty(msg.data['danfossRoomStatusCode']) ?
3034
+ constants.danfossRoomStatusCode[msg.data['danfossRoomStatusCode']] :
3035
+ msg.data['danfossRoomStatusCode'];
3036
+ }
3037
+ if (msg.data.hasOwnProperty('danfossOutputStatus')) {
3038
+ result[postfixWithEndpointName('output_status', msg, model)] =
3039
+ constants.danfossOutputStatus.hasOwnProperty(msg.data['danfossOutputStatus']) ?
3040
+ constants.danfossOutputStatus[msg.data['danfossOutputStatus']] :
3041
+ msg.data['danfossOutputStatus'];
3042
+ }
3043
+ return result;
3044
+ },
3045
+ },
3046
+ danfoss_icon_battery: {
3047
+ cluster: 'genPowerCfg',
3048
+ type: ['attributeReport', 'readResponse'],
3049
+ convert: (model, msg, publish, options, meta) => {
3050
+ const result = {};
3051
+ if (msg.data.hasOwnProperty('batteryPercentageRemaining')) {
3052
+ // Some devices do not comply to the ZCL and report a
3053
+ // batteryPercentageRemaining of 100 when the battery is full (should be 200).
3054
+ const dontDividePercentage = model.meta && model.meta.battery && model.meta.battery.dontDividePercentage;
3055
+ let percentage = msg.data['batteryPercentageRemaining'];
3056
+ percentage = dontDividePercentage ? percentage : percentage / 2;
3057
+
3058
+ result[postfixWithEndpointName('battery', msg, model)] = precisionRound(percentage, 2);
3059
+ }
3060
+ return result;
3061
+ },
3062
+ },
3063
+ danfoss_icon_regulator: {
3064
+ cluster: 'haDiagnostic',
3065
+ type: ['attributeReport', 'readResponse'],
3066
+ convert: (model, msg, publish, options, meta) => {
3067
+ const result = {};
3068
+ if (msg.data.hasOwnProperty('danfossSystemStatusCode')) {
3069
+ result[postfixWithEndpointName('system_status_code', msg, model)] =
3070
+ constants.danfossSystemStatusCode.hasOwnProperty(msg.data['danfossSystemStatusCode']) ?
3071
+ constants.danfossSystemStatusCode[msg.data['danfossSystemStatusCode']] :
3072
+ msg.data['danfossSystemStatusCode'];
3073
+ }
3074
+ if (msg.data.hasOwnProperty('danfossSystemStatusWater')) {
3075
+ result[postfixWithEndpointName('system_status_water', msg, model)] =
3076
+ constants.danfossSystemStatusWater.hasOwnProperty(msg.data['danfossSystemStatusWater']) ?
3077
+ constants.danfossSystemStatusWater[msg.data['danfossSystemStatusWater']] :
3078
+ msg.data['danfossSystemStatusWater'];
3079
+ }
3080
+ if (msg.data.hasOwnProperty('danfossMultimasterRole')) {
3081
+ result[postfixWithEndpointName('multimaster_role', msg, model)] =
3082
+ constants.danfossMultimasterRole.hasOwnProperty(msg.data['danfossMultimasterRole']) ?
3083
+ constants.danfossMultimasterRole[msg.data['danfossMultimasterRole']] :
3084
+ msg.data['danfossMultimasterRole'];
3085
+ }
3010
3086
  return result;
3011
3087
  },
3012
3088
  },
@@ -5366,22 +5442,30 @@ const converters = {
5366
5442
  tradfri_occupancy: {
5367
5443
  cluster: 'genOnOff',
5368
5444
  type: 'commandOnWithTimedOff',
5369
- options: [exposes.options.occupancy_timeout()],
5445
+ options: [exposes.options.occupancy_timeout(), exposes.options.illuminance_below_threshold_check()],
5370
5446
  convert: (model, msg, publish, options, meta) => {
5371
- if (msg.data.ctrlbits === 1) return;
5447
+ const onlyWhenOnFlag = (msg.data.ctrlbits & 1) != 0;
5448
+ if (onlyWhenOnFlag &&
5449
+ (!options || !options.hasOwnProperty('illuminance_below_threshold_check') ||
5450
+ options.illuminance_below_threshold_check) &&
5451
+ !globalStore.hasValue(msg.endpoint, 'timer')) return;
5372
5452
 
5373
5453
  const timeout = options && options.hasOwnProperty('occupancy_timeout') ?
5374
5454
  options.occupancy_timeout : msg.data.ontime / 10;
5375
5455
 
5376
5456
  // Stop existing timer because motion is detected and set a new one.
5377
5457
  clearTimeout(globalStore.getValue(msg.endpoint, 'timer'));
5458
+ globalStore.clearValue(msg.endpoint, 'timer');
5378
5459
 
5379
5460
  if (timeout !== 0) {
5380
- const timer = setTimeout(() => publish({occupancy: false}), timeout * 1000);
5461
+ const timer = setTimeout(() => {
5462
+ publish({occupancy: false});
5463
+ globalStore.clearValue(msg.endpoint, 'timer');
5464
+ }, timeout * 1000);
5381
5465
  globalStore.putValue(msg.endpoint, 'timer', timer);
5382
5466
  }
5383
5467
 
5384
- return {occupancy: true};
5468
+ return {occupancy: true, illuminance_above_threshold: onlyWhenOnFlag};
5385
5469
  },
5386
5470
  },
5387
5471
  almond_click: {
@@ -6865,10 +6949,10 @@ const converters = {
6865
6949
  }
6866
6950
  break;
6867
6951
  case tuya.dataPoints.tvWindowDetection:
6868
- result = {window_detection: {1: false, 0: true}[value]};
6952
+ result = {window_detection: {1: true, 0: false}[value]};
6869
6953
  break;
6870
6954
  case tuya.dataPoints.tvFrostDetection:
6871
- result = {frost_detection: {1: false, 0: true}[value]};
6955
+ result = {frost_detection: {1: true, 0: false}[value]};
6872
6956
  break;
6873
6957
  case tuya.dataPoints.tvHeatingSetpoint:
6874
6958
  result = {current_heating_setpoint: (value / 10).toFixed(1)};
@@ -6931,6 +7015,23 @@ const converters = {
6931
7015
  return {people: msg.data.presentValue};
6932
7016
  },
6933
7017
  },
7018
+ sihas_action: {
7019
+ cluster: 'genOnOff',
7020
+ type: ['commandOn', 'commandOff', 'commandToggle'],
7021
+ convert: (model, msg, publish, options, meta) => {
7022
+ const lookup = {'commandToggle': 'long', 'commandOn': 'double', 'commandOff': 'single'};
7023
+ let buttonMapping = null;
7024
+ if (model.model === 'SBM300ZB2') {
7025
+ buttonMapping = {1: '1', 2: '2'};
7026
+ } else if (model.model === 'SBM300ZB3') {
7027
+ buttonMapping = {1: '1', 2: '2', 3: '3'};
7028
+ } else if (model.model === 'MSM-300ZB') {
7029
+ buttonMapping = {1: '1', 2: '2', 3: '3', 4: '4'};
7030
+ }
7031
+ const button = buttonMapping ? `${buttonMapping[msg.endpoint.ID]}_` : '';
7032
+ return {action: `${button}${lookup[msg.type]}`};
7033
+ },
7034
+ },
6934
7035
  hoch_din: {
6935
7036
  cluster: 'manuSpecificTuya',
6936
7037
  type: ['commandGetData', 'commandSetDataResponse'],
@@ -7035,6 +7136,17 @@ const converters = {
7035
7136
  return result;
7036
7137
  },
7037
7138
  },
7139
+ tuya_operation_mode: {
7140
+ cluster: 'genOnOff',
7141
+ type: ['attributeReport', 'readResponse'],
7142
+ convert: (model, msg, publish, options, meta) => {
7143
+ if (msg.data.hasOwnProperty('tuyaOperationMode')) {
7144
+ const value = msg.data['tuyaOperationMode'];
7145
+ const lookup = {0: 'command', 1: 'event'};
7146
+ return {operation_mode: lookup[value]};
7147
+ }
7148
+ },
7149
+ },
7038
7150
  // #endregion
7039
7151
 
7040
7152
  // #region Ignore converters (these message dont need parsing).
@@ -1327,6 +1327,38 @@ const converters = {
1327
1327
  await entity.read('hvacThermostat', ['runningMode']);
1328
1328
  },
1329
1329
  },
1330
+ thermostat_min_heat_setpoint_limit: {
1331
+ key: ['min_heat_setpoint_limit'],
1332
+ convertSet: async (entity, key, value, meta) => {
1333
+ let result;
1334
+ if (meta.options.thermostat_unit === 'fahrenheit') {
1335
+ result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1336
+ } else {
1337
+ result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1338
+ }
1339
+ const minHeatSetpointLimit = result;
1340
+ await entity.write('hvacThermostat', {minHeatSetpointLimit});
1341
+ },
1342
+ convertGet: async (entity, key, meta) => {
1343
+ await entity.read('hvacThermostat', ['minHeatSetpointLimit']);
1344
+ },
1345
+ },
1346
+ thermostat_max_heat_setpoint_limit: {
1347
+ key: ['max_heat_setpoint_limit'],
1348
+ convertSet: async (entity, key, value, meta) => {
1349
+ let result;
1350
+ if (meta.options.thermostat_unit === 'fahrenheit') {
1351
+ result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
1352
+ } else {
1353
+ result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
1354
+ }
1355
+ const maxHeatSetpointLimit = result;
1356
+ await entity.write('hvacThermostat', {maxHeatSetpointLimit});
1357
+ },
1358
+ convertGet: async (entity, key, meta) => {
1359
+ await entity.read('hvacThermostat', ['maxHeatSetpointLimit']);
1360
+ },
1361
+ },
1330
1362
  electrical_measurement_power: {
1331
1363
  key: ['power'],
1332
1364
  convertGet: async (entity, key, meta) => {
@@ -2484,6 +2516,36 @@ const converters = {
2484
2516
  await entity.read('hvacThermostat', ['danfossLoadEstimate'], manufacturerOptions.danfoss);
2485
2517
  },
2486
2518
  },
2519
+ danfoss_output_status: {
2520
+ key: ['output_status'],
2521
+ convertGet: async (entity, key, meta) => {
2522
+ await entity.read('hvacThermostat', ['danfossOutputStatus'], manufacturerOptions.danfoss);
2523
+ },
2524
+ },
2525
+ danfoss_room_status_code: {
2526
+ key: ['room_status_code'],
2527
+ convertGet: async (entity, key, meta) => {
2528
+ await entity.read('hvacThermostat', ['danfossRoomStatusCode'], manufacturerOptions.danfoss);
2529
+ },
2530
+ },
2531
+ danfoss_system_status_code: {
2532
+ key: ['system_status_code'],
2533
+ convertGet: async (entity, key, meta) => {
2534
+ await entity.read('haDiagnostic', ['danfossSystemStatusCode'], manufacturerOptions.danfoss);
2535
+ },
2536
+ },
2537
+ danfoss_system_status_water: {
2538
+ key: ['system_status_water'],
2539
+ convertGet: async (entity, key, meta) => {
2540
+ await entity.read('haDiagnostic', ['danfossSystemStatusWater'], manufacturerOptions.danfoss);
2541
+ },
2542
+ },
2543
+ danfoss_multimaster_role: {
2544
+ key: ['multimaster_role'],
2545
+ convertGet: async (entity, key, meta) => {
2546
+ await entity.read('haDiagnostic', ['danfossMultimasterRole'], manufacturerOptions.danfoss);
2547
+ },
2548
+ },
2487
2549
  ZMCSW032D_cover_position: {
2488
2550
  key: ['position', 'tilt'],
2489
2551
  convertSet: async (entity, key, value, meta) => {
@@ -5868,7 +5930,7 @@ const converters = {
5868
5930
  key: [
5869
5931
  'system_mode', 'window_detection', 'frost_detection', 'child_lock',
5870
5932
  'current_heating_setpoint', 'local_temperature_calibration',
5871
- 'holiday_temperature', 'comfort_temperature', 'eco_temperature', 'boost_mode',
5933
+ 'holiday_temperature', 'comfort_temperature', 'eco_temperature',
5872
5934
  'open_window_temperature', 'heating_stop', 'preset',
5873
5935
  ],
5874
5936
  convertSet: async (entity, key, value, meta) => {
@@ -5882,13 +5944,18 @@ const converters = {
5882
5944
  }
5883
5945
  break;
5884
5946
  case 'window_detection':
5885
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvWindowDetection, (value) ? 0 : 1);
5947
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvWindowDetection, value);
5886
5948
  break;
5887
5949
  case 'frost_detection':
5888
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvFrostDetection, (value) ? 0 : 1);
5950
+ if (value == false) {
5951
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 0);
5952
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvMode, 1);
5953
+ } else {
5954
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 1);
5955
+ }
5889
5956
  break;
5890
5957
  case 'child_lock':
5891
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvChildLock, {'unlock': 0, 'lock': 1}[value.toLowerCase()]);
5958
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvChildLock, value === 'LOCK');
5892
5959
  break;
5893
5960
  case 'local_temperature_calibration':
5894
5961
  value = Math.round(value * 10);
@@ -5949,6 +6016,22 @@ const converters = {
5949
6016
  await endpoint.read('genAnalogInput', ['presentValue']);
5950
6017
  },
5951
6018
  },
6019
+ tuya_operation_mode: {
6020
+ key: ['operation_mode'],
6021
+ convertSet: async (entity, key, value, meta) => {
6022
+ // modes:
6023
+ // 0 - 'command' mode. keys send commands. useful for group control
6024
+ // 1 - 'event' mode. keys send events. useful for handling
6025
+ const lookup = {command: 0, event: 1};
6026
+ const endpoint = meta.device.getEndpoint(1);
6027
+ await endpoint.write('genOnOff', {'tuyaOperationMode': lookup[value.toLowerCase()]});
6028
+ return {state: {operation_mode: value.toLowerCase()}};
6029
+ },
6030
+ convertGet: async (entity, key, meta) => {
6031
+ const endpoint = meta.device.getEndpoint(1);
6032
+ await endpoint.read('genOnOff', ['tuyaOperationMode']);
6033
+ },
6034
+ },
5952
6035
  // #endregion
5953
6036
 
5954
6037
  // #region Ignore converters
package/devices/adeo.js CHANGED
@@ -76,4 +76,13 @@ module.exports = [
76
76
  },
77
77
  exposes: [e.power(), e.switch(), e.energy()],
78
78
  },
79
+ {
80
+ zigbeeModel: ['LDSENK10'],
81
+ model: 'LDSENK10',
82
+ vendor: 'ADEO',
83
+ description: 'LEXMAN motion sensor',
84
+ fromZigbee: [fz.ias_occupancy_alarm_1],
85
+ toZigbee: [],
86
+ exposes: [e.occupancy(), e.battery_low(), e.tamper()],
87
+ },
79
88
  ];
@@ -122,4 +122,133 @@ module.exports = [
122
122
  endpoint.write('genTime', values);
123
123
  },
124
124
  },
125
+ {
126
+ fingerprint: [
127
+ {modelID: '0x8020', manufacturerName: 'Danfoss'}, // RT24V Display
128
+ {modelID: '0x8021', manufacturerName: 'Danfoss'}, // RT24V Display Floor sensor
129
+ {modelID: '0x8030', manufacturerName: 'Danfoss'}, // RTbattery Display
130
+ {modelID: '0x8031', manufacturerName: 'Danfoss'}, // RTbattery Display Infrared
131
+ {modelID: '0x8034', manufacturerName: 'Danfoss'}, // RTbattery Dial
132
+ {modelID: '0x8035', manufacturerName: 'Danfoss'}], // RTbattery Dial Infrared
133
+ model: 'Icon',
134
+ vendor: 'Danfoss',
135
+ description: 'Icon floor heating (regulator, Zigbee module & thermostats)',
136
+ fromZigbee: [
137
+ fz.danfoss_icon_regulator,
138
+ fz.danfoss_thermostat,
139
+ fz.danfoss_icon_battery,
140
+ fz.thermostat],
141
+ toZigbee: [
142
+ tz.thermostat_local_temperature,
143
+ tz.thermostat_occupied_heating_setpoint,
144
+ tz.thermostat_system_mode,
145
+ tz.thermostat_min_heat_setpoint_limit,
146
+ tz.thermostat_max_heat_setpoint_limit,
147
+ tz.danfoss_output_status,
148
+ tz.danfoss_room_status_code,
149
+ tz.danfoss_system_status_water,
150
+ tz.danfoss_system_status_code,
151
+ tz.danfoss_multimaster_role,
152
+ ],
153
+ meta: {multiEndpoint: true},
154
+ // ota: ota.zigbeeOTA,
155
+ endpoint: (device) => {
156
+ return {
157
+ 'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4, 'l5': 5,
158
+ 'l6': 6, 'l7': 7, 'l8': 8, 'l9': 9, 'l10': 10,
159
+ 'l11': 11, 'l12': 12, 'l13': 13, 'l14': 14, 'l15': 15, 'l16': 232,
160
+ };
161
+ },
162
+ exposes: [].concat(((endpointsCount) => {
163
+ const features = [];
164
+ for (let i = 1; i <= endpointsCount; i++) {
165
+ const epName = `l${i}`;
166
+ if (i!=16) {
167
+ features.push(e.battery().withEndpoint(epName));
168
+ features.push(exposes.climate().withSetpoint('occupied_heating_setpoint', 4, 30, 0.5)
169
+ .withLocalTemperature().withSystemMode(['heat']).withEndpoint(epName));
170
+ features.push(exposes.numeric('abs_min_heat_setpoint_limit', ea.STATE)
171
+ .withUnit('°C').withEndpoint(epName)
172
+ .withDescription('Absolute min temperature allowed on the device'));
173
+ features.push(exposes.numeric('abs_max_heat_setpoint_limit', ea.STATE)
174
+ .withUnit('°C').withEndpoint(epName)
175
+ .withDescription('Absolute max temperature allowed on the device'));
176
+ features.push(exposes.numeric('min_heat_setpoint_limit', ea.ALL)
177
+ .withValueMin(4).withValueMax(30).withValueStep(0.5).withUnit('°C')
178
+ .withEndpoint(epName).withDescription('Min temperature limit set on the device'));
179
+ features.push(exposes.numeric('max_heat_setpoint_limit', ea.ALL)
180
+ .withValueMin(4).withValueMax(30).withValueStep(0.5).withUnit('°C')
181
+ .withEndpoint(epName).withDescription('Max temperature limit set on the device'));
182
+ features.push(exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
183
+ .withEndpoint(epName));
184
+ features.push(exposes.enum('output_status', ea.STATE_GET, ['inactive', 'active'])
185
+ .withEndpoint(epName).withDescription('Danfoss Output Status [Active vs Inactive])'));
186
+ features.push(exposes.enum('room_status_code', ea.STATE_GET, ['no_error', 'missing_rt',
187
+ 'rt_touch_error', 'floor_sensor_short_circuit', 'floor_sensor_disconnected'])
188
+ .withEndpoint(epName).withDescription('Thermostat status'));
189
+ } else {
190
+ features.push(exposes.enum('system_status_code', ea.STATE_GET, ['no_error', 'missing_expansion_board',
191
+ 'missing_radio_module', 'missing_command_module', 'missing_master_rail', 'missing_slave_rail_no_1',
192
+ 'missing_slave_rail_no_2', 'pt1000_input_short_circuit', 'pt1000_input_open_circuit',
193
+ 'error_on_one_or_more_output']).withEndpoint('l16').withDescription('Regulator Status'));
194
+ features.push(exposes.enum('system_status_water', ea.STATE_GET, ['hot_water_flow_in_pipes', 'cool_water_flow_in_pipes'])
195
+ .withEndpoint('l16').withDescription('Water Status of Regulator'));
196
+ features.push(exposes.enum('multimaster_role', ea.STATE_GET, ['invalid_unused', 'master', 'slave_1', 'slave_2'])
197
+ .withEndpoint('l16').withDescription('Regulator role (Master vs Slave)'));
198
+ }
199
+ }
200
+
201
+ return features;
202
+ })(16)),
203
+ configure: async (device, coordinatorEndpoint, logger) => {
204
+ const options = {manufacturerCode: 0x1246};
205
+
206
+ for (let i = 1; i <= 15; i++) {
207
+ const endpoint = device.getEndpoint(i);
208
+ if (typeof endpoint !== 'undefined') {
209
+ await reporting.bind(endpoint, coordinatorEndpoint,
210
+ ['genPowerCfg', 'hvacThermostat', 'hvacUserInterfaceCfg']);
211
+ await reporting.batteryPercentageRemaining(endpoint,
212
+ {min: constants.repInterval.HOUR, max: 43200, change: 1});
213
+ await reporting.thermostatTemperature(endpoint,
214
+ {min: 0, max: constants.repInterval.MINUTES_10, change: 10});
215
+ await reporting.thermostatOccupiedHeatingSetpoint(endpoint,
216
+ {min: 0, max: constants.repInterval.MINUTES_10, change: 10});
217
+
218
+ await endpoint.configureReporting('hvacThermostat', [{
219
+ attribute: 'danfossOutputStatus',
220
+ minimumReportInterval: constants.repInterval.MINUTE,
221
+ maximumReportInterval: constants.repInterval.MINUTES_10,
222
+ reportableChange: 1,
223
+ }], options);
224
+
225
+ // Danfoss Icon Thermostat Specific
226
+ await endpoint.read('hvacThermostat', [
227
+ 'danfossOutputStatus',
228
+ 'danfossRoomStatusCode'], options);
229
+
230
+ // Standard Thermostat
231
+ await endpoint.read('hvacThermostat', ['localTemp']);
232
+ await endpoint.read('hvacThermostat', ['occupiedHeatingSetpoint']);
233
+ await endpoint.read('hvacThermostat', ['systemMode']);
234
+ await endpoint.read('hvacThermostat', ['setpointChangeSource']);
235
+ await endpoint.read('hvacThermostat', ['absMinHeatSetpointLimit']);
236
+ await endpoint.read('hvacThermostat', ['absMaxHeatSetpointLimit']);
237
+ await endpoint.read('hvacThermostat', ['minHeatSetpointLimit']);
238
+ await endpoint.read('hvacThermostat', ['maxHeatSetpointLimit']);
239
+ await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']);
240
+ }
241
+ }
242
+
243
+ // Danfoss Icon Regulator Specific
244
+ const endpoint232 = device.getEndpoint(232);
245
+
246
+ await reporting.bind(endpoint232, coordinatorEndpoint, ['haDiagnostic']);
247
+
248
+ await endpoint232.read('haDiagnostic', [
249
+ 'danfossSystemStatusCode',
250
+ 'danfossSystemStatusWater',
251
+ 'danfossMultimasterRole'], options);
252
+ },
253
+ },
125
254
  ];
package/devices/ikea.js CHANGED
@@ -194,10 +194,8 @@ module.exports = [
194
194
  model: 'LED1624G9',
195
195
  vendor: 'IKEA',
196
196
  description: 'TRADFRI LED bulb E14/E26/E27 600 lumen, dimmable, color, opal white',
197
- extend: extend.light_onoff_brightness_color(),
198
- ota: ota.tradfri,
197
+ extend: tradfriExtend.light_onoff_brightness_colortemp_color(),
199
198
  meta: {supportsHueAndSaturation: false},
200
- onEvent: bulbOnEvent,
201
199
  },
202
200
  {
203
201
  zigbeeModel: ['TRADFRI bulb E26 CWS 800lm', 'TRADFRI bulb E27 CWS 806lm'],
@@ -488,7 +486,9 @@ module.exports = [
488
486
  toZigbee: [],
489
487
  exposes: [e.battery(), e.occupancy(),
490
488
  exposes.numeric('requested_brightness_level', ea.STATE).withValueMin(76).withValueMax(254),
491
- exposes.numeric('requested_brightness_percent', ea.STATE).withValueMin(30).withValueMax(100)],
489
+ exposes.numeric('requested_brightness_percent', ea.STATE).withValueMin(30).withValueMax(100),
490
+ exposes.binary('illuminance_above_threshold', ea.STATE, true, false)
491
+ .withDescription('Indicates whether the device detected bright light (works only in night mode)')],
492
492
  ota: ota.tradfri,
493
493
  meta: {battery: {dontDividePercentage: true}},
494
494
  configure: async (device, coordinatorEndpoint, logger) => {
package/devices/lupus.js CHANGED
@@ -54,7 +54,7 @@ module.exports = [
54
54
  },
55
55
  },
56
56
  {
57
- zigbeeModel: ['PRS3CH2_00.00.05.10TC', 'PRS3CH2_00.00.05.11TC'],
57
+ zigbeeModel: ['PRS3CH2_00.00.05.10TC', 'PRS3CH2_00.00.05.11TC', 'PRS3CH2_00.00.05.12TC'],
58
58
  model: '12127',
59
59
  vendor: 'Lupus',
60
60
  description: '2 chanel relay',
@@ -2165,4 +2165,22 @@ module.exports = [
2165
2165
  meta: {turnsOffAtBrightness1: true},
2166
2166
  ota: ota.zigbeeOTA,
2167
2167
  },
2168
+ {
2169
+ zigbeeModel: ['LTF001'],
2170
+ model: '6109231C5',
2171
+ vendor: 'Philips',
2172
+ description: 'Hue white ambiance Apogee square',
2173
+ meta: {turnsOffAtBrightness1: true},
2174
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2175
+ ota: ota.zigbeeOTA,
2176
+ },
2177
+ {
2178
+ zigbeeModel: ['LTF002'],
2179
+ model: '6109331C5',
2180
+ vendor: 'Philips',
2181
+ description: 'Hue white ambiance Apogee round',
2182
+ meta: {turnsOffAtBrightness1: true},
2183
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2184
+ ota: ota.zigbeeOTA,
2185
+ },
2168
2186
  ];
@@ -70,7 +70,7 @@ module.exports = [
70
70
  exposes: [e.contact(), e.battery_low(), e.tamper(), e.temperature(), e.battery()],
71
71
  },
72
72
  {
73
- zigbeeModel: ['SZ-DWS08N'],
73
+ zigbeeModel: ['SZ-DWS08N', 'SZ-DWS08'],
74
74
  model: 'SZ-DWS08',
75
75
  vendor: 'Sercomm',
76
76
  description: 'Magnetic door & window contact sensor',
@@ -11,7 +11,7 @@ module.exports = [
11
11
  zigbeeModel: ['CSM-300Z'],
12
12
  model: 'CSM-300ZB',
13
13
  vendor: 'ShinaSystem',
14
- description: 'Sihas multipurpose sensor',
14
+ description: 'SiHAS multipurpose sensor',
15
15
  meta: {battery: {voltageToPercentage: '3V_2100'}},
16
16
  fromZigbee: [fz.battery, fz.sihas_people_cnt],
17
17
  toZigbee: [tz.sihas_set_people],
@@ -30,7 +30,7 @@ module.exports = [
30
30
  zigbeeModel: ['USM-300Z'],
31
31
  model: 'USM-300ZB',
32
32
  vendor: 'ShinaSystem',
33
- description: 'Sihas multipurpose sensor',
33
+ description: 'SiHAS multipurpose sensor',
34
34
  meta: {battery: {voltageToPercentage: '3V_2100'}},
35
35
  fromZigbee: [fz.battery, fz.temperature, fz.humidity, fz.occupancy, fz.illuminance],
36
36
  toZigbee: [],
@@ -51,7 +51,7 @@ module.exports = [
51
51
  zigbeeModel: ['SBM300Z1'],
52
52
  model: 'SBM300Z1',
53
53
  vendor: 'ShinaSystem',
54
- description: 'IOT smart switch 1 gang',
54
+ description: 'SiHAS IOT smart switch 1 gang',
55
55
  extend: extend.switch(),
56
56
  configure: async (device, coordinatorEndpoint, logger) => {
57
57
  const endpoint = device.getEndpoint(1);
@@ -63,7 +63,7 @@ module.exports = [
63
63
  zigbeeModel: ['SBM300Z2'],
64
64
  model: 'SBM300Z2',
65
65
  vendor: 'ShinaSystem',
66
- description: 'IOT smart switch 2 gang',
66
+ description: 'SiHAS IOT smart switch 2 gang',
67
67
  extend: extend.switch(),
68
68
  exposes: [e.switch().withEndpoint('top'), e.switch().withEndpoint('bottom')],
69
69
  endpoint: (device) => {
@@ -81,7 +81,7 @@ module.exports = [
81
81
  zigbeeModel: ['SBM300Z3'],
82
82
  model: 'SBM300Z3',
83
83
  vendor: 'ShinaSystem',
84
- description: 'IOT smart switch 3 gang',
84
+ description: 'SiHAS IOT smart switch 3 gang',
85
85
  extend: extend.switch(),
86
86
  exposes: [e.switch().withEndpoint('top'), e.switch().withEndpoint('center'), e.switch().withEndpoint('bottom')],
87
87
  endpoint: (device) => {
@@ -101,7 +101,7 @@ module.exports = [
101
101
  zigbeeModel: ['SBM300Z4'],
102
102
  model: 'SBM300Z4',
103
103
  vendor: 'ShinaSystem',
104
- description: 'IOT smart switch 4 gang',
104
+ description: 'SiHAS IOT smart switch 4 gang',
105
105
  extend: extend.switch(),
106
106
  exposes: [e.switch().withEndpoint('top_left'), e.switch().withEndpoint('bottom_left'),
107
107
  e.switch().withEndpoint('top_right'), e.switch().withEndpoint('bottom_right')],
@@ -124,7 +124,7 @@ module.exports = [
124
124
  zigbeeModel: ['SBM300Z5'],
125
125
  model: 'SBM300Z5',
126
126
  vendor: 'ShinaSystem',
127
- description: 'IOT smart switch 5 gang',
127
+ description: 'SiHAS IOT smart switch 5 gang',
128
128
  extend: extend.switch(),
129
129
  exposes: [e.switch().withEndpoint('top_left'), e.switch().withEndpoint('top_right'), e.switch().withEndpoint('center_left'),
130
130
  e.switch().withEndpoint('bottom_left'), e.switch().withEndpoint('bottom_right')],
@@ -149,7 +149,7 @@ module.exports = [
149
149
  zigbeeModel: ['SBM300Z6'],
150
150
  model: 'SBM300Z6',
151
151
  vendor: 'ShinaSystem',
152
- description: 'IOT smart switch 6 gang',
152
+ description: 'SiHAS IOT smart switch 6 gang',
153
153
  extend: extend.switch(),
154
154
  exposes: [e.switch().withEndpoint('top_left'), e.switch().withEndpoint('bottom_left'), e.switch().withEndpoint('center_left'),
155
155
  e.switch().withEndpoint('center_right'), e.switch().withEndpoint('top_right'), e.switch().withEndpoint('bottom_right')],
@@ -172,4 +172,114 @@ module.exports = [
172
172
  await reporting.onOff(device.getEndpoint(6));
173
173
  },
174
174
  },
175
+ {
176
+ zigbeeModel: ['BSM-300Z'],
177
+ model: 'BSM-300ZB',
178
+ vendor: 'ShinaSystem',
179
+ description: 'SiHAS remote control',
180
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
181
+ fromZigbee: [fz.battery, fz.sihas_action],
182
+ toZigbee: [],
183
+ configure: async (device, coordinatorEndpoint, logger) => {
184
+ const endpoint = device.getEndpoint(1);
185
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
186
+ await reporting.batteryVoltage(endpoint);
187
+ },
188
+ exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'long'])],
189
+ },
190
+ {
191
+ zigbeeModel: ['TSM-300Z'],
192
+ model: 'TSM-300ZB',
193
+ vendor: 'ShinaSystem',
194
+ description: 'SiHAS temperature/humidity sensor',
195
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
196
+ fromZigbee: [fz.temperature, fz.humidity, fz.battery],
197
+ toZigbee: [],
198
+ configure: async (device, coordinatorEndpoint, logger) => {
199
+ const endpoint = device.getEndpoint(1);
200
+ await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'msRelativeHumidity', 'genPowerCfg']);
201
+ await reporting.temperature(endpoint, {min: 30, max: 300, change: 30});
202
+ await reporting.humidity(endpoint, {min: 30, max: 3600, change: 50});
203
+ await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
204
+ },
205
+ exposes: [e.temperature(), e.humidity(), e.battery(), e.battery_voltage()],
206
+ },
207
+ {
208
+ zigbeeModel: ['DSM-300Z'],
209
+ model: 'DSM-300ZB',
210
+ vendor: 'ShinaSystem',
211
+ description: 'SiHAS contact sensor',
212
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
213
+ fromZigbee: [fz.ias_contact_alarm_1, fz.battery],
214
+ toZigbee: [],
215
+ configure: async (device, coordinatorEndpoint, logger) => {
216
+ const endpoint = device.getEndpoint(1);
217
+ await reporting.bind(endpoint, coordinatorEndpoint, ['ssIasZone', 'genPowerCfg']);
218
+ await endpoint.read('ssIasZone', ['iasCieAddr', 'zoneState', 'zoneId']);
219
+ await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
220
+ },
221
+ exposes: [e.contact(), e.battery(), e.battery_voltage()],
222
+ },
223
+ {
224
+ zigbeeModel: ['MSM-300Z'],
225
+ model: 'MSM-300ZB',
226
+ vendor: 'ShinaSystem',
227
+ description: 'SiHAS remote control 4 button',
228
+ fromZigbee: [fz.sihas_action, fz.battery],
229
+ toZigbee: [],
230
+ exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long',
231
+ '3_single', '3_double', '3_long', '4_single', '4_double', '4_long']), e.battery(), e.battery_voltage()],
232
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
233
+ configure: async (device, coordinatorEndpoint, logger) => {
234
+ const endpoint = device.getEndpoint(1);
235
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
236
+ await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
237
+ },
238
+ },
239
+ {
240
+ zigbeeModel: ['SBM300ZB1'],
241
+ model: 'SBM300ZB1',
242
+ vendor: 'ShinaSystem',
243
+ description: 'SiHAS remote control',
244
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
245
+ fromZigbee: [fz.battery, fz.sihas_action],
246
+ toZigbee: [],
247
+ configure: async (device, coordinatorEndpoint, logger) => {
248
+ const endpoint = device.getEndpoint(1);
249
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
250
+ await reporting.batteryVoltage(endpoint);
251
+ },
252
+ exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'long'])],
253
+ },
254
+ {
255
+ zigbeeModel: ['SBM300ZB2'],
256
+ model: 'SBM300ZB2',
257
+ vendor: 'ShinaSystem',
258
+ description: 'SiHAS remote control 2 button',
259
+ fromZigbee: [fz.sihas_action, fz.battery],
260
+ toZigbee: [],
261
+ exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long']), e.battery(), e.battery_voltage()],
262
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
263
+ configure: async (device, coordinatorEndpoint, logger) => {
264
+ const endpoint = device.getEndpoint(1);
265
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
266
+ await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
267
+ },
268
+ },
269
+ {
270
+ zigbeeModel: ['SBM300ZB3'],
271
+ model: 'SBM300ZB3',
272
+ vendor: 'ShinaSystem',
273
+ description: 'SiHAS remote control 3 button',
274
+ fromZigbee: [fz.sihas_action, fz.battery],
275
+ toZigbee: [],
276
+ exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long',
277
+ '3_single', '3_double', '3_long']), e.battery(), e.battery_voltage()],
278
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
279
+ configure: async (device, coordinatorEndpoint, logger) => {
280
+ const endpoint = device.getEndpoint(1);
281
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
282
+ await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
283
+ },
284
+ },
175
285
  ];
@@ -1,5 +1,7 @@
1
1
  const exposes = require('../lib/exposes');
2
2
  const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
+ const reporting = require('../lib/reporting');
4
+ const extend = require('../lib/extend');
3
5
  const e = exposes.presets;
4
6
 
5
7
  module.exports = [
@@ -21,4 +23,17 @@ module.exports = [
21
23
  return {l1: 1, l2: 2, l3: 3, l4: 4};
22
24
  },
23
25
  },
26
+ {
27
+ zigbeeModel: ['S24013'],
28
+ model: 'S24013',
29
+ vendor: 'The Light Group',
30
+ description: 'SLC SmartOne AC dimmer mini 200W Zigbee LN',
31
+ extend: extend.light_onoff_brightness({noConfigure: true}),
32
+ configure: async (device, coordinatorEndpoint, logger) => {
33
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
34
+ const endpoint = device.getEndpoint(1);
35
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
36
+ await reporting.onOff(endpoint);
37
+ },
38
+ },
24
39
  ];
package/devices/tuya.js CHANGED
@@ -103,6 +103,7 @@ module.exports = [
103
103
  {
104
104
  fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3000_qqjaziws'},
105
105
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_jtmhndw2'},
106
+ {modelID: 'TS0505B', manufacturerName: '_TZ3000_ezlg0pht'},
106
107
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_5snkkrxw'},
107
108
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_12sxjap4'},
108
109
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_x2fqbdun'},
@@ -423,6 +424,7 @@ module.exports = [
423
424
  {
424
425
  fingerprint: [
425
426
  {modelID: 'TS0502B', manufacturerName: '_TZ3210_s1x7gcq0'},
427
+ {modelID: 'TS0502B', manufacturerName: '_TZ3000_muqovqv0'},
426
428
  {modelID: 'TS0502B', manufacturerName: '_TZ3210_hi1ym4bl'},
427
429
  {modelID: 'TS0502B', manufacturerName: '_TZ3210_psgq7ysz'},
428
430
  {modelID: 'TS0502B', manufacturerName: '_TZ3000_zw7wr5uo'},
@@ -744,13 +746,12 @@ module.exports = [
744
746
  {
745
747
  zigbeeModel: ['kud7u2l'],
746
748
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_ckud7u2l'}, {modelID: 'TS0601', manufacturerName: '_TZE200_ywdxldoj'},
747
- {modelID: 'TS0601', manufacturerName: '_TZE200_cwnjrr72'}, {modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'},
748
- {modelID: 'TS0601', manufacturerName: '_TZE200_a4bpgplm'}],
749
+ {modelID: 'TS0601', manufacturerName: '_TZE200_cwnjrr72'}, {modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'}],
749
750
  model: 'TS0601_thermostat',
750
751
  vendor: 'TuYa',
751
752
  description: 'Radiator valve with thermostat',
752
753
  whiteLabel: [{vendor: 'Moes', model: 'HY368'}, {vendor: 'Moes', model: 'HY369RT'}, {vendor: 'SHOJZJ', model: '378RT'},
753
- {vendor: 'Silvercrest', model: 'TVR01'}, {vendor: 'Haozee', model: 'TRV601'}],
754
+ {vendor: 'Silvercrest', model: 'TVR01'}],
754
755
  meta: {tuyaThermostatPreset: tuya.thermostatPresets, tuyaThermostatSystemMode: tuya.thermostatSystemModes3},
755
756
  ota: ota.zigbeeOTA,
756
757
  onEvent: tuya.onEventSetLocalTime,
@@ -865,7 +866,7 @@ module.exports = [
865
866
  extend: extend.switch(),
866
867
  },
867
868
  {
868
- fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7'},
869
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 67},
869
870
  {modelID: 'TS011F', manufacturerName: '_TZ3000_ew3ldmgx'},
870
871
  {modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato'},
871
872
  {modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm'},
@@ -906,7 +907,8 @@ module.exports = [
906
907
  .withDescription('Recover state after power outage')],
907
908
  },
908
909
  {
909
- fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak'}],
910
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak'},
911
+ {modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 69}],
910
912
  model: 'TS011F_plug_3',
911
913
  description: 'Smart plug (with power monitoring by polling)',
912
914
  vendor: 'TuYa',
@@ -914,6 +916,7 @@ module.exports = [
914
916
  toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
915
917
  configure: async (device, coordinatorEndpoint, logger) => {
916
918
  const endpoint = device.getEndpoint(1);
919
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
917
920
  endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
918
921
  endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
919
922
  device.save();
@@ -1411,20 +1414,26 @@ module.exports = [
1411
1414
  model: 'YSR-MINI-Z',
1412
1415
  vendor: 'TuYa',
1413
1416
  description: '2 in 1 dimming remote control and scene control',
1414
- exposes: [e.battery(), e.action([
1415
- 'on', 'off',
1416
- 'brightness_move_up', 'brightness_step_up', 'brightness_step_down', 'brightness_move_down', 'brightness_stop',
1417
- 'color_temperature_step_down', 'color_temperature_step_up',
1418
- '1_single', '1_double', '1_hold', '2_single', '2_double', '2_hold',
1419
- '3_single', '3_double', '3_hold', '4_single', '4_double', '4_hold',
1420
- ])],
1417
+ exposes: [
1418
+ e.battery(),
1419
+ e.action(['on', 'off',
1420
+ 'brightness_move_up', 'brightness_step_up', 'brightness_step_down', 'brightness_move_down', 'brightness_stop',
1421
+ 'color_temperature_step_down', 'color_temperature_step_up',
1422
+ '1_single', '1_double', '1_hold', '2_single', '2_double', '2_hold',
1423
+ '3_single', '3_double', '3_hold', '4_single', '4_double', '4_hold',
1424
+ ]),
1425
+ exposes.enum('operation_mode', ea.ALL, ['command', 'event']).withDescription(
1426
+ 'Operation mode: "command" - for group control, "event" - for clicks'),
1427
+ ],
1421
1428
  fromZigbee: [fz.battery, fz.command_on, fz.command_off, fz.command_step, fz.command_move, fz.command_stop,
1422
- fz.command_step_color_temperature, fz.tuya_on_off_action],
1423
- toZigbee: [],
1429
+ fz.command_step_color_temperature, fz.tuya_on_off_action, fz.tuya_operation_mode],
1430
+ toZigbee: [tz.tuya_operation_mode],
1431
+ onEvent: tuya.onEventSetLocalTime,
1424
1432
  configure: async (device, coordinatorEndpoint, logger) => {
1425
1433
  const endpoint = device.getEndpoint(1);
1426
1434
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
1427
1435
  await reporting.batteryPercentageRemaining(endpoint);
1436
+ await endpoint.read('genOnOff', ['tuyaOperationMode']);
1428
1437
  },
1429
1438
  },
1430
1439
  {
package/devices/yale.js CHANGED
@@ -100,6 +100,13 @@ module.exports = [
100
100
  description: 'Assure lock SL',
101
101
  extend: lockExtend(),
102
102
  },
103
+ {
104
+ zigbeeModel: ['YRL226 TS'],
105
+ model: 'YRL226 TS',
106
+ vendor: 'Yale',
107
+ description: 'Assure lock SL',
108
+ extend: lockExtend(),
109
+ },
103
110
  {
104
111
  // Appears to be a slightly rebranded Assure lock SL
105
112
  // Just with Lockwood | Assa Abloy branding instead of Yale
package/lib/constants.js CHANGED
@@ -91,6 +91,44 @@ const danfossWindowOpen = {
91
91
  4: 'external_open',
92
92
  };
93
93
 
94
+ const danfossRoomStatusCode = {
95
+ 0x0000: 'no_error',
96
+ 0x0101: 'missing_rt',
97
+ 0x0201: 'rt_touch_error',
98
+ 0x0401: 'floor_sensor_short_circuit',
99
+ 0x0801: 'floor_sensor_disconnected',
100
+ };
101
+
102
+ const danfossOutputStatus = {
103
+ 0: 'inactive',
104
+ 1: 'active',
105
+ };
106
+
107
+ const danfossSystemStatusWater = {
108
+ 0: 'hot_water_flow_in_pipes',
109
+ 1: 'cool_water_flow_in_pipes',
110
+ };
111
+
112
+ const danfossSystemStatusCode = {
113
+ 0x0000: 'no_error',
114
+ 0x0101: 'missing_expansion_board',
115
+ 0x0201: 'missing_radio_module',
116
+ 0x0401: 'missing_command_module',
117
+ 0x0801: 'missing_master_rail',
118
+ 0x1001: 'missing_slave_rail_no_1',
119
+ 0x2001: 'missing_slave_rail_no_2',
120
+ 0x4001: 'pt1000_input_short_circuit',
121
+ 0x8001: 'pt1000_input_open_circuit',
122
+ 0x0102: 'error_on_one_or_more_output',
123
+ };
124
+
125
+ const danfossMultimasterRole = {
126
+ 0: 'invalid_unused',
127
+ 1: 'master',
128
+ 2: 'slave_1',
129
+ 3: 'slave_2',
130
+ };
131
+
94
132
  const keypadLockoutMode = {
95
133
  0: 'unlock',
96
134
  1: 'lock1',
@@ -196,6 +234,11 @@ module.exports = {
196
234
  fanMode,
197
235
  temperatureDisplayMode,
198
236
  danfossWindowOpen,
237
+ danfossRoomStatusCode,
238
+ danfossOutputStatus,
239
+ danfossSystemStatusWater,
240
+ danfossSystemStatusCode,
241
+ danfossMultimasterRole,
199
242
  keypadLockoutMode,
200
243
  lockSourceName,
201
244
  armMode,
package/lib/exposes.js CHANGED
@@ -486,6 +486,7 @@ module.exports = {
486
486
  transition: () => new Numeric(`transition`, access.SET).withValueMin(0).withDescription('Controls the transition time (in seconds) of on/off, brightness, color temperature (if applicable) and color (if applicable) changes. Defaults to `0` (no transition).'),
487
487
  legacy: () => new Binary(`legacy`, access.SET, true, false).withDescription(`Set to false to disable the legacy integration (highly recommended), will change structure of the published payload (default true).`),
488
488
  measurement_poll_interval: () => new Numeric(`measurement_poll_interval`, access.SET).withValueMin(0).withDescription(`This device does not support reporting electric measurements so it is polled instead. The default poll interval is 60 seconds.`),
489
+ illuminance_below_threshold_check: () => new Binary(`illuminance_below_threshold_check`, access.SET, true, false).withDescription(`Set to false to also send messages when illuminance is above threshold in night mode (default true).`),
489
490
  },
490
491
  presets: {
491
492
  action: (values) => new Enum('action', access.STATE, values).withDescription('Triggered action (e.g. a button click)'),
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.292",
3
+ "version": "14.0.296",
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.292",
3
+ "version": "14.0.296",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [