zigbee-herdsman-converters 14.0.291 → 14.0.295

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.
@@ -3819,6 +3819,17 @@ const converters = {
3819
3819
  }
3820
3820
  },
3821
3821
  },
3822
+ tuya_min_brightness: {
3823
+ cluster: 'genLevelCtrl',
3824
+ type: ['attributeReport', 'readResponse'],
3825
+ convert: (model, msg, publish, options, meta) => {
3826
+ if (msg.data.hasOwnProperty(0xfc00)) {
3827
+ const property = postfixWithEndpointName('min_brightness', msg, model);
3828
+ const value = parseInt(msg.data[0xfc00].toString(16).slice(0, 2), 16);
3829
+ return {[property]: value};
3830
+ }
3831
+ },
3832
+ },
3822
3833
  restorable_brightness: {
3823
3834
  cluster: 'genLevelCtrl',
3824
3835
  type: ['attributeReport', 'readResponse'],
@@ -5355,22 +5366,30 @@ const converters = {
5355
5366
  tradfri_occupancy: {
5356
5367
  cluster: 'genOnOff',
5357
5368
  type: 'commandOnWithTimedOff',
5358
- options: [exposes.options.occupancy_timeout()],
5369
+ options: [exposes.options.occupancy_timeout(), exposes.options.illuminance_below_threshold_check()],
5359
5370
  convert: (model, msg, publish, options, meta) => {
5360
- if (msg.data.ctrlbits === 1) return;
5371
+ const onlyWhenOnFlag = (msg.data.ctrlbits & 1) != 0;
5372
+ if (onlyWhenOnFlag &&
5373
+ (!options || !options.hasOwnProperty('illuminance_below_threshold_check') ||
5374
+ options.illuminance_below_threshold_check) &&
5375
+ !globalStore.hasValue(msg.endpoint, 'timer')) return;
5361
5376
 
5362
5377
  const timeout = options && options.hasOwnProperty('occupancy_timeout') ?
5363
5378
  options.occupancy_timeout : msg.data.ontime / 10;
5364
5379
 
5365
5380
  // Stop existing timer because motion is detected and set a new one.
5366
5381
  clearTimeout(globalStore.getValue(msg.endpoint, 'timer'));
5382
+ globalStore.clearValue(msg.endpoint, 'timer');
5367
5383
 
5368
5384
  if (timeout !== 0) {
5369
- const timer = setTimeout(() => publish({occupancy: false}), timeout * 1000);
5385
+ const timer = setTimeout(() => {
5386
+ publish({occupancy: false});
5387
+ globalStore.clearValue(msg.endpoint, 'timer');
5388
+ }, timeout * 1000);
5370
5389
  globalStore.putValue(msg.endpoint, 'timer', timer);
5371
5390
  }
5372
5391
 
5373
- return {occupancy: true};
5392
+ return {occupancy: true, illuminance_above_threshold: onlyWhenOnFlag};
5374
5393
  },
5375
5394
  },
5376
5395
  almond_click: {
@@ -6854,10 +6873,10 @@ const converters = {
6854
6873
  }
6855
6874
  break;
6856
6875
  case tuya.dataPoints.tvWindowDetection:
6857
- result = {window_detection: {1: false, 0: true}[value]};
6876
+ result = {window_detection: {1: true, 0: false}[value]};
6858
6877
  break;
6859
6878
  case tuya.dataPoints.tvFrostDetection:
6860
- result = {frost_detection: {1: false, 0: true}[value]};
6879
+ result = {frost_detection: {1: true, 0: false}[value]};
6861
6880
  break;
6862
6881
  case tuya.dataPoints.tvHeatingSetpoint:
6863
6882
  result = {current_heating_setpoint: (value / 10).toFixed(1)};
@@ -6920,6 +6939,19 @@ const converters = {
6920
6939
  return {people: msg.data.presentValue};
6921
6940
  },
6922
6941
  },
6942
+ sihas_action: {
6943
+ cluster: 'genOnOff',
6944
+ type: ['commandOn', 'commandOff', 'commandToggle'],
6945
+ convert: (model, msg, publish, options, meta) => {
6946
+ const lookup = {'commandToggle': 'long', 'commandOn': 'double', 'commandOff': 'single'};
6947
+ let buttonMapping = null;
6948
+ if (model.model === 'MSM-300ZB') {
6949
+ buttonMapping = {1: '1', 2: '2', 3: '3', 4: '4'};
6950
+ }
6951
+ const button = buttonMapping ? `${buttonMapping[msg.endpoint.ID]}_` : '';
6952
+ return {action: `${button}${lookup[msg.type]}`};
6953
+ },
6954
+ },
6923
6955
  hoch_din: {
6924
6956
  cluster: 'manuSpecificTuya',
6925
6957
  type: ['commandGetData', 'commandSetDataResponse'],
@@ -7024,6 +7056,17 @@ const converters = {
7024
7056
  return result;
7025
7057
  },
7026
7058
  },
7059
+ tuya_operation_mode: {
7060
+ cluster: 'genOnOff',
7061
+ type: ['attributeReport', 'readResponse'],
7062
+ convert: (model, msg, publish, options, meta) => {
7063
+ if (msg.data.hasOwnProperty('tuyaOperationMode')) {
7064
+ const value = msg.data['tuyaOperationMode'];
7065
+ const lookup = {0: 'command', 1: 'event'};
7066
+ return {operation_mode: lookup[value]};
7067
+ }
7068
+ },
7069
+ },
7027
7070
  // #endregion
7028
7071
 
7029
7072
  // #region Ignore converters (these message dont need parsing).
@@ -2917,6 +2917,20 @@ const converters = {
2917
2917
  await entity.read('manuSpecificTuya_3', ['switchType']);
2918
2918
  },
2919
2919
  },
2920
+ tuya_min_brightness: {
2921
+ key: ['min_brightness'],
2922
+ convertSet: async (entity, key, value, meta) => {
2923
+ const minValueHex = value.toString(16);
2924
+ const maxValueHex = 'ff';
2925
+ const minMaxValue = parseInt(`${minValueHex}${maxValueHex}`, 16);
2926
+ const payload = {0xfc00: {value: minMaxValue, type: 0x21}};
2927
+ await entity.write('genLevelCtrl', payload, {disableDefaultResponse: true});
2928
+ return {state: {min_brightness: value}};
2929
+ },
2930
+ convertGet: async (entity, key, meta) => {
2931
+ await entity.read('genLevelCtrl', [0xfc00]);
2932
+ },
2933
+ },
2920
2934
  frankever_threshold: {
2921
2935
  key: ['threshold'],
2922
2936
  convertSet: async (entity, key, value, meta) => {
@@ -5854,7 +5868,7 @@ const converters = {
5854
5868
  key: [
5855
5869
  'system_mode', 'window_detection', 'frost_detection', 'child_lock',
5856
5870
  'current_heating_setpoint', 'local_temperature_calibration',
5857
- 'holiday_temperature', 'comfort_temperature', 'eco_temperature', 'boost_mode',
5871
+ 'holiday_temperature', 'comfort_temperature', 'eco_temperature',
5858
5872
  'open_window_temperature', 'heating_stop', 'preset',
5859
5873
  ],
5860
5874
  convertSet: async (entity, key, value, meta) => {
@@ -5868,13 +5882,18 @@ const converters = {
5868
5882
  }
5869
5883
  break;
5870
5884
  case 'window_detection':
5871
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvWindowDetection, (value) ? 0 : 1);
5885
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvWindowDetection, value);
5872
5886
  break;
5873
5887
  case 'frost_detection':
5874
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvFrostDetection, (value) ? 0 : 1);
5888
+ if (value == false) {
5889
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 0);
5890
+ await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvMode, 1);
5891
+ } else {
5892
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 1);
5893
+ }
5875
5894
  break;
5876
5895
  case 'child_lock':
5877
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvChildLock, {'unlock': 0, 'lock': 1}[value.toLowerCase()]);
5896
+ await tuya.sendDataPointBool(entity, tuya.dataPoints.tvChildLock, value === 'LOCK');
5878
5897
  break;
5879
5898
  case 'local_temperature_calibration':
5880
5899
  value = Math.round(value * 10);
@@ -5935,6 +5954,22 @@ const converters = {
5935
5954
  await endpoint.read('genAnalogInput', ['presentValue']);
5936
5955
  },
5937
5956
  },
5957
+ tuya_operation_mode: {
5958
+ key: ['operation_mode'],
5959
+ convertSet: async (entity, key, value, meta) => {
5960
+ // modes:
5961
+ // 0 - 'command' mode. keys send commands. useful for group control
5962
+ // 1 - 'event' mode. keys send events. useful for handling
5963
+ const lookup = {command: 0, event: 1};
5964
+ const endpoint = meta.device.getEndpoint(1);
5965
+ await endpoint.write('genOnOff', {'tuyaOperationMode': lookup[value.toLowerCase()]});
5966
+ return {state: {operation_mode: value.toLowerCase()}};
5967
+ },
5968
+ convertGet: async (entity, key, meta) => {
5969
+ const endpoint = meta.device.getEndpoint(1);
5970
+ await endpoint.read('genOnOff', ['tuyaOperationMode']);
5971
+ },
5972
+ },
5938
5973
  // #endregion
5939
5974
 
5940
5975
  // #region Ignore converters
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',
@@ -47,6 +47,15 @@ module.exports = [
47
47
  extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
48
48
  ota: ota.zigbeeOTA,
49
49
  },
50
+ {
51
+ zigbeeModel: ['5633031P9'],
52
+ model: '5633031P9',
53
+ vendor: 'Philips',
54
+ description: 'Hue White ambiance Pillar spotlight',
55
+ meta: {turnsOffAtBrightness1: true},
56
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
57
+ ota: ota.zigbeeOTA,
58
+ },
50
59
  {
51
60
  zigbeeModel: ['929002376301'],
52
61
  model: '929002376301',
@@ -1877,6 +1886,15 @@ module.exports = [
1877
1886
  meta: {turnsOffAtBrightness1: true},
1878
1887
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [222, 454]}),
1879
1888
  },
1889
+ {
1890
+ zigbeeModel: ['LTV004'],
1891
+ model: '929002478401',
1892
+ vendor: 'Philips',
1893
+ description: 'Hue white filament Edison ST19 E26 LED warm-to-cool',
1894
+ ota: ota.zigbeeOTA,
1895
+ meta: {turnsOffAtBrightness1: true},
1896
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [222, 454]}),
1897
+ },
1880
1898
  {
1881
1899
  zigbeeModel: ['LWV002'],
1882
1900
  model: '046677551780',
@@ -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: [],
@@ -49,9 +49,9 @@ module.exports = [
49
49
  },
50
50
  {
51
51
  zigbeeModel: ['SBM300Z1'],
52
- model: 'SBM-300-ZB1',
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);
@@ -61,9 +61,9 @@ module.exports = [
61
61
  },
62
62
  {
63
63
  zigbeeModel: ['SBM300Z2'],
64
- model: 'SBM-300-ZB2',
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) => {
@@ -79,9 +79,9 @@ module.exports = [
79
79
  },
80
80
  {
81
81
  zigbeeModel: ['SBM300Z3'],
82
- model: 'SBM-300-ZB3',
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) => {
@@ -99,9 +99,9 @@ module.exports = [
99
99
  },
100
100
  {
101
101
  zigbeeModel: ['SBM300Z4'],
102
- model: 'SBM-300-ZB4',
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')],
@@ -122,9 +122,9 @@ module.exports = [
122
122
  },
123
123
  {
124
124
  zigbeeModel: ['SBM300Z5'],
125
- model: 'SBM-300-ZB5',
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')],
@@ -147,9 +147,9 @@ module.exports = [
147
147
  },
148
148
  {
149
149
  zigbeeModel: ['SBM300Z6'],
150
- model: 'SBM-300-ZB6',
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,68 @@ 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
+ },
175
239
  ];
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,
@@ -858,7 +859,14 @@ module.exports = [
858
859
  },
859
860
  },
860
861
  {
861
- fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7'},
862
+ fingerprint: [{modelID: 'TS0111', manufacturerName: '_TYZB01_ymcdbl3u'}],
863
+ model: 'TS0111_valve',
864
+ vendor: 'TuYa',
865
+ description: 'Smart water/gas valve',
866
+ extend: extend.switch(),
867
+ },
868
+ {
869
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 67},
862
870
  {modelID: 'TS011F', manufacturerName: '_TZ3000_ew3ldmgx'},
863
871
  {modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato'},
864
872
  {modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm'},
@@ -899,7 +907,8 @@ module.exports = [
899
907
  .withDescription('Recover state after power outage')],
900
908
  },
901
909
  {
902
- fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak'}],
910
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak'},
911
+ {modelID: 'TS011F', manufacturerName: '_TZ3000_cphmq0q7', applicationVersion: 69}],
903
912
  model: 'TS011F_plug_3',
904
913
  description: 'Smart plug (with power monitoring by polling)',
905
914
  vendor: 'TuYa',
@@ -960,6 +969,32 @@ module.exports = [
960
969
  },
961
970
  exposes: [e.switch().setAccess('state', ea.STATE_SET), e.voltage(), e.power(), e.current(), e.energy()],
962
971
  },
972
+ {
973
+ fingerprint: [{modelID: 'TS1101', manufacturerName: '_TZ3000_7ysdnebc'}],
974
+ model: 'TS1101_dimmer_module',
975
+ vendor: 'TuYa',
976
+ description: '2CH Zigbee dimmer module',
977
+ whiteLabel: [{vendor: 'OXT', model: 'SWTZ25'}],
978
+ fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([
979
+ fz.tuya_min_brightness,
980
+ ]),
981
+ toZigbee: extend.light_onoff_brightness().toZigbee.concat([
982
+ tz.tuya_min_brightness,
983
+ ]),
984
+ exposes: [
985
+ e.light_brightness().withMinBrightness().withEndpoint('l1'),
986
+ e.light_brightness().withMinBrightness().withEndpoint('l2'),
987
+ ],
988
+ endpoint: (device) => {
989
+ return {'l1': 1, 'l2': 2};
990
+ },
991
+ meta: {multiEndpoint: true},
992
+ configure: async (device, coordinatorEndpoint, logger) => {
993
+ await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
994
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
995
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
996
+ },
997
+ },
963
998
  {
964
999
  zigbeeModel: ['RH3001'],
965
1000
  fingerprint: [{type: 'EndDevice', manufacturerID: 4098, applicationVersion: 66, endpoints: [
@@ -1378,20 +1413,26 @@ module.exports = [
1378
1413
  model: 'YSR-MINI-Z',
1379
1414
  vendor: 'TuYa',
1380
1415
  description: '2 in 1 dimming remote control and scene control',
1381
- exposes: [e.battery(), e.action([
1382
- 'on', 'off',
1383
- 'brightness_move_up', 'brightness_step_up', 'brightness_step_down', 'brightness_move_down', 'brightness_stop',
1384
- 'color_temperature_step_down', 'color_temperature_step_up',
1385
- '1_single', '1_double', '1_hold', '2_single', '2_double', '2_hold',
1386
- '3_single', '3_double', '3_hold', '4_single', '4_double', '4_hold',
1387
- ])],
1416
+ exposes: [
1417
+ e.battery(),
1418
+ e.action(['on', 'off',
1419
+ 'brightness_move_up', 'brightness_step_up', 'brightness_step_down', 'brightness_move_down', 'brightness_stop',
1420
+ 'color_temperature_step_down', 'color_temperature_step_up',
1421
+ '1_single', '1_double', '1_hold', '2_single', '2_double', '2_hold',
1422
+ '3_single', '3_double', '3_hold', '4_single', '4_double', '4_hold',
1423
+ ]),
1424
+ exposes.enum('operation_mode', ea.ALL, ['command', 'event']).withDescription(
1425
+ 'Operation mode: "command" - for group control, "event" - for clicks'),
1426
+ ],
1388
1427
  fromZigbee: [fz.battery, fz.command_on, fz.command_off, fz.command_step, fz.command_move, fz.command_stop,
1389
- fz.command_step_color_temperature, fz.tuya_on_off_action],
1390
- toZigbee: [],
1428
+ fz.command_step_color_temperature, fz.tuya_on_off_action, fz.tuya_operation_mode],
1429
+ toZigbee: [tz.tuya_operation_mode],
1430
+ onEvent: tuya.onEventSetLocalTime,
1391
1431
  configure: async (device, coordinatorEndpoint, logger) => {
1392
1432
  const endpoint = device.getEndpoint(1);
1393
1433
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
1394
1434
  await reporting.batteryPercentageRemaining(endpoint);
1435
+ await endpoint.read('genOnOff', ['tuyaOperationMode']);
1395
1436
  },
1396
1437
  },
1397
1438
  {
package/lib/exposes.js CHANGED
@@ -211,6 +211,12 @@ class Light extends Base {
211
211
  return this;
212
212
  }
213
213
 
214
+ withMinBrightness() {
215
+ assert(!this.endpoint, 'Cannot add feature after adding endpoint');
216
+ this.features.push(new Numeric('min_brightness', access.ALL).withValueMin(1).withValueMax(255).withDescription('Minimum light brightness'));
217
+ return this;
218
+ }
219
+
214
220
  withLevelConfig() {
215
221
  assert(!this.endpoint, 'Cannot add feature after adding endpoint');
216
222
  const levelConfig = new Composite('level_config', 'level_config')
@@ -480,6 +486,7 @@ module.exports = {
480
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).'),
481
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).`),
482
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).`),
483
490
  },
484
491
  presets: {
485
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.291",
3
+ "version": "14.0.295",
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.291",
3
+ "version": "14.0.295",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [