zigbee-herdsman-converters 14.0.666 → 14.0.667

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
@@ -9,6 +9,7 @@ See [Zigbee2MQTT how to support new devices](https://www.zigbee2mqtt.io/advanced
9
9
  ## Submitting a pull request
10
10
  If you'd like to submit a pull request, you should run the following commands to ensure your changes will pass the tests:
11
11
  ```sh
12
+ npm install
12
13
  npm run lint
13
14
  npm test
14
15
  ```
@@ -1308,7 +1308,7 @@ const converters = {
1308
1308
  thermostat_occupancy: {
1309
1309
  key: ['occupancy'],
1310
1310
  convertGet: async (entity, key, meta) => {
1311
- await entity.read('hvacThermostat', ['ocupancy']);
1311
+ await entity.read('hvacThermostat', ['occupancy']);
1312
1312
  },
1313
1313
  },
1314
1314
  thermostat_clear_weekly_schedule: {
package/devices/giex.js CHANGED
@@ -118,18 +118,18 @@ module.exports = [
118
118
  e.battery(),
119
119
  exposes.binary('state', ea.STATE_SET, 'ON', 'OFF').withDescription('State'),
120
120
  exposes.enum('mode', ea.STATE_SET, ['duration', 'capacity']).withDescription('Irrigation mode'),
121
- exposes.numeric('irrigation_target', exposes.access.STATE_SET).withValueMin(0).withValueMax(1440).withUnit('minutes or Litres')
122
- .withDescription('Irrigation Target, duration in minutes or capacity in Litres (depending on mode)'),
123
- exposes.numeric('cycle_irrigation_num_times', exposes.access.STATE_SET).withValueMin(0).withValueMax(100).withUnit('#')
121
+ exposes.numeric('irrigation_target', exposes.access.STATE_SET).withValueMin(0).withValueMax(3600).withUnit('seconds or litres')
122
+ .withDescription('Irrigation target, duration in seconds or capacity in litres (depending on mode)'),
123
+ exposes.numeric('cycle_irrigation_num_times', exposes.access.STATE_SET).withValueMin(0).withValueMax(100)
124
124
  .withDescription('Number of cycle irrigation times, set to 0 for single cycle'),
125
- exposes.numeric('cycle_irrigation_interval', exposes.access.STATE_SET).withValueMin(0).withValueMax(1440).withUnit('min')
125
+ exposes.numeric('cycle_irrigation_interval', exposes.access.STATE_SET).withValueMin(0).withValueMax(3600).withUnit('sec')
126
126
  .withDescription('Cycle irrigation interval'),
127
- exposes.numeric('irrigation_start_time', ea.STATE).withUnit('GMT+8').withDescription('Irrigation start time'),
128
- exposes.numeric('irrigation_end_time', ea.STATE).withUnit('GMT+8').withDescription('Irrigation end time'),
129
- exposes.numeric('last_irrigation_duration', exposes.access.STATE).withUnit('min')
127
+ exposes.numeric('irrigation_start_time', ea.STATE).withDescription('Last irrigation start time (GMT)'),
128
+ exposes.numeric('irrigation_end_time', ea.STATE).withDescription('Last irrigation end time (GMT)'),
129
+ exposes.numeric('last_irrigation_duration', exposes.access.STATE)
130
130
  .withDescription('Last irrigation duration'),
131
131
  exposes.numeric('water_consumed', exposes.access.STATE).withUnit('L')
132
- .withDescription('Water consumed (Litres)'),
132
+ .withDescription('Last irrigation water consumption'),
133
133
  ],
134
134
  },
135
135
  ];
package/devices/ikea.js CHANGED
@@ -999,4 +999,11 @@ module.exports = [
999
999
  description: 'STOFTMOLN ceiling/wall lamp 24 warm light dimmable',
1000
1000
  extend: tradfriExtend.light_onoff_brightness(),
1001
1001
  },
1002
+ {
1003
+ zigbeeModel: ['TTRADFRIbulbPAR38WS900lm'],
1004
+ model: 'LED2006R9',
1005
+ vendor: 'IKEA',
1006
+ description: 'TRADFRI E26 PAR38 LED bulb 900 lumen, dimmable, white spectrum, downlight',
1007
+ extend: tradfriExtend.light_onoff_brightness_colortemp(),
1008
+ },
1002
1009
  ];
package/devices/innr.js CHANGED
@@ -176,6 +176,14 @@ module.exports = [
176
176
  extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
177
177
  meta: {enhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
178
178
  },
179
+ {
180
+ zigbeeModel: ['RB 286 C'],
181
+ model: 'RB 286 C',
182
+ vendor: 'Innr',
183
+ description: 'E27 bulb RGBW',
184
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
185
+ meta: {applyRedFix: true, turnsOffAtBrightness1: true},
186
+ },
179
187
  {
180
188
  zigbeeModel: ['BY 285 C'],
181
189
  model: 'BY 285 C',
@@ -591,6 +599,7 @@ module.exports = [
591
599
  await reporting.rmsVoltage(endpoint);
592
600
  // Gives UNSUPPORTED_ATTRIBUTE on reporting.readMeteringMultiplierDivisor.
593
601
  endpoint.saveClusterAttributeKeyValue('seMetering', {multiplier: 1, divisor: 100});
602
+ await reporting.currentSummDelivered(endpoint);
594
603
  },
595
604
  ota: ota.zigbeeOTA,
596
605
  exposes: [e.power(), e.current(), e.voltage().withAccess(ea.STATE), e.switch(), e.energy()],
@@ -111,4 +111,20 @@ module.exports = [
111
111
  toZigbee: [],
112
112
  exposes: [e.battery(), e.occupancy()],
113
113
  },
114
+ {
115
+ zigbeeModel: ['LDHD2AZW'],
116
+ model: 'LDHD2AZW',
117
+ vendor: 'Leedarson',
118
+ description: 'Magnetic door & window contact sensor',
119
+ fromZigbee: [fz.ias_contact_alarm_1, fz.temperature, fz.battery],
120
+ toZigbee: [],
121
+ meta: {battery: {voltageToPercentage: '3V_2100'}},
122
+ configure: async (device, coordinatorEndpoint, logger) => {
123
+ const endpoint = device.getEndpoint(1);
124
+ await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg']);
125
+ await reporting.temperature(endpoint);
126
+ await reporting.batteryVoltage(endpoint);
127
+ },
128
+ exposes: [e.contact(), e.battery_low(), e.tamper(), e.temperature(), e.battery()],
129
+ },
114
130
  ];
@@ -148,8 +148,10 @@ module.exports = [
148
148
  model: 'QS-Zigbee-D02-TRIAC-LN',
149
149
  vendor: 'Lonsonho',
150
150
  description: '1 gang smart dimmer switch module with neutral',
151
- fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([fz.tuya_min_brightness]),
152
- toZigbee: extend.light_onoff_brightness().toZigbee.concat([tz.tuya_min_brightness]),
151
+ fromZigbee: extend.light_onoff_brightness({disableMoveStep: true, disableTransition: true})
152
+ .fromZigbee.concat([fz.tuya_min_brightness]),
153
+ toZigbee: extend.light_onoff_brightness({disableMoveStep: true, disableTransition: true})
154
+ .toZigbee.concat([tz.tuya_min_brightness]),
153
155
  exposes: [e.light_brightness().withMinBrightness()],
154
156
  },
155
157
  {
@@ -268,10 +270,10 @@ module.exports = [
268
270
  model: 'TS110E_2gang',
269
271
  vendor: 'Lonsonho',
270
272
  description: 'Zigbee smart dimmer module 2 gang with neutral',
271
- fromZigbee: extend.light_onoff_brightness({disablePowerOnBehavior: true}).fromZigbee.concat([
272
- fz.tuya_switch_power_outage_memory, fzLocal.TS110E_switch_type]),
273
- toZigbee: extend.light_onoff_brightness({disablePowerOnBehavior: true}).toZigbee.concat([
274
- tz.tuya_switch_power_outage_memory, tzLocal.TS110E_switch_type]),
273
+ fromZigbee: extend.light_onoff_brightness({disablePowerOnBehavior: true, disableMoveStep: true, disableTransition: true})
274
+ .fromZigbee.concat([fz.tuya_switch_power_outage_memory, fzLocal.TS110E_switch_type]),
275
+ toZigbee: extend.light_onoff_brightness({disablePowerOnBehavior: true, disableMoveStep: true, disableTransition: true})
276
+ .toZigbee.concat([tz.tuya_switch_power_outage_memory, tzLocal.TS110E_switch_type]),
275
277
  meta: {multiEndpoint: true},
276
278
  exposes: [
277
279
  e.light_brightness().withEndpoint('l1'),
package/devices/owon.js CHANGED
@@ -123,8 +123,8 @@ module.exports = [
123
123
  configure: async (device, coordinatorEndpoint, logger) => {
124
124
  const endpoint2 = device.getEndpoint(2);
125
125
  const endpoint3 = device.getEndpoint(3);
126
- await reporting.bind(endpoint2, coordinatorEndpoint, ['msTemperatureMeasurement', 'msRelativeHumidity']);
127
- await reporting.bind(endpoint3, coordinatorEndpoint, ['msIlluminanceMeasurement']);
126
+ await reporting.bind(endpoint2, coordinatorEndpoint, ['msIlluminanceMeasurement']);
127
+ await reporting.bind(endpoint3, coordinatorEndpoint, ['msTemperatureMeasurement', 'msRelativeHumidity']);
128
128
  device.powerSource = 'Battery';
129
129
  device.save();
130
130
  },
@@ -113,6 +113,13 @@ module.exports = [
113
113
  description: 'LED panels',
114
114
  extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 350]}),
115
115
  },
116
+ {
117
+ zigbeeModel: ['500.44'],
118
+ model: '500.44',
119
+ vendor: 'Paulmann',
120
+ description: 'URail power supply',
121
+ extend: extend.light_onoff_brightness_color(),
122
+ },
116
123
  {
117
124
  zigbeeModel: ['500.45'],
118
125
  model: '500.45',
@@ -20,6 +20,7 @@ module.exports = [
20
20
  {modelID: 'TS0601', manufacturerName: '_TZE200_9gvruqf5'},
21
21
  {modelID: 'TS0601', manufacturerName: '_TZE200_zr9c0day'},
22
22
  {modelID: 'TS0601', manufacturerName: '_TZE200_0dvm9mva'},
23
+ {modelID: 'TS0601', manufacturerName: '_TZE200_h4cgnbzg'},
23
24
  ],
24
25
  model: 'SEA801-Zigbee/SEA802-Zigbee',
25
26
  vendor: 'Saswell',
package/devices/tuya.js CHANGED
@@ -22,7 +22,7 @@ const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak',
22
22
  '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_idrffznf', '_TZ3000_okaz9tjs', '_TZ3210_q7oryllx',
23
23
  '_TZ3000_ss98ec5d', '_TZ3000_gznh2xla', '_TZ3000_hdopuwv6', '_TZ3000_gvn91tmx', '_TZ3000_dksbtrzs', '_TZ3000_b28wrpvx',
24
24
  '_TZ3000_aim0ztek', '_TZ3000_mlswgkc3', '_TZ3000_7dndcnnb', '_TZ3000_waho4jtj', '_TZ3000_nmsciidq', '_TZ3000_jtgxgmks',
25
- '_TZ3000_rdfh8cfs', '_TZ3000_yujkchbz', '_TZ3000_fgwhjm9j'];
25
+ '_TZ3000_rdfh8cfs', '_TZ3000_yujkchbz', '_TZ3000_fgwhjm9j', '_TZ3000_qeuvnohg'];
26
26
 
27
27
  const tzLocal = {
28
28
  SA12IZL_silence_siren: {
@@ -1768,12 +1768,13 @@ module.exports = [
1768
1768
  exposes: [e.battery(), e.water_leak()],
1769
1769
  },
1770
1770
  {
1771
- fingerprint: tuya.fingerprint('TS0001', ['_TZ3000_xkap8wtb', '_TZ3000_qnejhcsu', '_TZ3000_x3ewpzyr']),
1771
+ fingerprint: tuya.fingerprint('TS0001', ['_TZ3000_xkap8wtb', '_TZ3000_qnejhcsu', '_TZ3000_x3ewpzyr', '_TZ3000_mkhkxx1p']),
1772
1772
  model: 'TS0001_power',
1773
1773
  description: 'Switch with power monitoring',
1774
1774
  vendor: 'TuYa',
1775
- fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory],
1776
- toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
1775
+ fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report,
1776
+ fz.tuya_switch_power_outage_memory, fz.tuya_switch_type],
1777
+ toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory, tz.tuya_switch_type],
1777
1778
  configure: async (device, coordinatorEndpoint, logger) => {
1778
1779
  await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
1779
1780
  const endpoint = device.getEndpoint(1);
@@ -1786,7 +1787,7 @@ module.exports = [
1786
1787
  endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
1787
1788
  device.save();
1788
1789
  },
1789
- exposes: [e.switch(), e.power(), e.current(), e.voltage().withAccess(ea.STATE), e.energy(),
1790
+ exposes: [e.switch(), e.power(), e.current(), e.voltage().withAccess(ea.STATE), e.energy(), e.switch_type_2(),
1790
1791
  exposes.enum('power_outage_memory', ea.ALL, ['on', 'off', 'restore']).withDescription('Recover state after power outage')],
1791
1792
  },
1792
1793
  {
@@ -2117,19 +2118,21 @@ module.exports = [
2117
2118
  exposes: [
2118
2119
  e.battery_low(), e.child_lock(), e.open_window(), e.open_window_temperature().withValueMin(5).withValueMax(30),
2119
2120
  e.comfort_temperature().withValueMin(5).withValueMax(30), e.eco_temperature().withValueMin(5).withValueMax(30),
2120
- exposes.climate().withSystemMode(['off', 'heat'], ea.STATE_SET, 'When switched to the "off" mode, the device will display ' +
2121
- '"HS" and the valve will be fully closed. Press the pair button to cancel or switch back to "heat" mode. Battery life ' +
2122
- 'can be prolonged by switching the heating off. After switching to `heat` mode, `preset` will be reset to `auto` and ' +
2123
- 'after changing `preset` to `manual` temperature setpoint will be 20 degrees.').withPreset(['auto', 'manual', 'holiday'],
2124
- '`auto` uses schedule properties, check them. `manual` allows you to control the device, `holiday` uses ' +
2125
- '`holiday_start_stop` and `holiday_temperature` properties.').withLocalTemperatureCalibration(-5, 5, 0.1, ea.STATE_SET)
2126
- .withLocalTemperature(ea.STATE).withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET),
2121
+ tuya.exposes.errorStatus(), tuya.exposes.frostProtection('The device display "AF", press the pair button to cancel.'),
2122
+ exposes.climate()
2123
+ .withSystemMode(['off', 'heat'], ea.STATE_SET, 'When switched to the "off" mode, the device will display ' +
2124
+ '"HS" and the valve will be fully closed. Press the pair button to cancel or switch back to "heat" mode. Battery life' +
2125
+ ' can be prolonged by switching the heating off. After switching to `heat` mode, `preset` will be reset to `auto` and' +
2126
+ ' after changing `preset` to `manual` temperature setpoint will be 20 degrees.')
2127
+ .withPreset(['auto', 'manual', 'holiday'],
2128
+ '`auto` uses schedule properties, check them. `manual` allows you to control the device, `holiday` uses ' +
2129
+ '`holiday_start_stop` and `holiday_temperature` properties.')
2130
+ .withLocalTemperatureCalibration(-5, 5, 0.1, ea.STATE_SET)
2131
+ .withLocalTemperature(ea.STATE)
2132
+ .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET),
2127
2133
  exposes.numeric('boost_timeset_countdown', ea.STATE_SET).withUnit('second').withDescription('Setting '+
2128
2134
  'minimum 0 - maximum 465 seconds boost time. The boost (♨) function is activated. The remaining '+
2129
2135
  'time for the function will be counted down in seconds ( 465 to 0 ).').withValueMin(0).withValueMax(465),
2130
- exposes.binary('frost_protection', ea.STATE_SET, 'ON', 'OFF').withDescription('When Anti-Freezing function'+
2131
- ' is activated, the temperature in the house is kept at 8 °C, the device display "AF".press the '+
2132
- 'pair button to cancel.'),
2133
2136
  exposes.binary('heating_stop', ea.STATE_SET, 'ON', 'OFF').withDescription('Same as `system_mode`. Left for compatibility.'),
2134
2137
  exposes.numeric('holiday_temperature', ea.STATE_SET).withUnit('°C').withDescription('Holiday temperature')
2135
2138
  .withValueMin(5).withValueMax(30),
@@ -2153,17 +2156,10 @@ module.exports = [
2153
2156
  '18:40/24 22:50/19.5`; `06:00/21.5 17:20/26 24:00/18`. The temperature will be set from the beginning/start of one ' +
2154
2157
  'period and until the next period, e.g., `04:00/20 24:00/22` means that from 00:00 to 04:00 temperature will be 20 ' +
2155
2158
  'degrees and from 04:00 to 00:00 temperature will be 22 degrees.'),
2156
- exposes.text('schedule_monday', ea.STATE),
2157
- exposes.text('schedule_tuesday', ea.STATE),
2158
- exposes.text('schedule_wednesday', ea.STATE),
2159
- exposes.text('schedule_thursday', ea.STATE),
2160
- exposes.text('schedule_friday', ea.STATE),
2161
- exposes.text('schedule_saturday', ea.STATE),
2162
- exposes.text('schedule_sunday', ea.STATE),
2159
+ ...tuya.exposes.scheduleAllDays(ea.STATE, 'HH:MM/C'),
2163
2160
  exposes.binary('online', ea.STATE_SET, 'ON', 'OFF').withDescription('Turn on this property to poll current data from the ' +
2164
2161
  'device. It can be used to periodically fetch a new local temperature since the device doesn\'t update itself. ' +
2165
2162
  'Setting this property doesn\'t turn on the display.'),
2166
- exposes.numeric('error_status', ea.STATE).withDescription('Error status'),
2167
2163
  ],
2168
2164
  meta: {
2169
2165
  tuyaDatapoints: [
@@ -2184,20 +2180,67 @@ module.exports = [
2184
2180
  [102, 'open_window_temperature', tuya.valueConverter.divideBy10],
2185
2181
  [104, 'comfort_temperature', tuya.valueConverter.divideBy10],
2186
2182
  [105, 'eco_temperature', tuya.valueConverter.divideBy10],
2187
- [106, 'schedule', tuya.valueConverter.thermostatScheduleDay],
2183
+ [106, 'schedule', tuya.valueConverter.thermostatScheduleDaySingleDP],
2188
2184
  [107, null, tuya.valueConverter.TV02SystemMode],
2189
2185
  [107, 'system_mode', tuya.valueConverterBasic.lookup({'heat': false, 'off': true})],
2190
2186
  [107, 'heating_stop', tuya.valueConverter.onOff],
2191
2187
  [115, 'online', tuya.valueConverter.onOffNotStrict],
2192
- [108, 'schedule_monday', tuya.valueConverter.thermostatScheduleDay],
2193
- [112, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDay],
2194
- [109, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDay],
2195
- [113, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDay],
2196
- [110, 'schedule_friday', tuya.valueConverter.thermostatScheduleDay],
2197
- [114, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDay],
2198
- [111, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDay],
2188
+ [108, 'schedule_monday', tuya.valueConverter.thermostatScheduleDaySingleDP],
2189
+ [112, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDaySingleDP],
2190
+ [109, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDaySingleDP],
2191
+ [113, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDaySingleDP],
2192
+ [110, 'schedule_friday', tuya.valueConverter.thermostatScheduleDaySingleDP],
2193
+ [114, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDaySingleDP],
2194
+ [111, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDaySingleDP],
2195
+ ],
2196
+ },
2197
+ },
2198
+ {
2199
+ fingerprint: tuya.fingerprint('TS0601', [
2200
+ '_TZE200_0hg58wyk', /* model: 'S366', vendor: 'Cloud Even' */
2201
+ ]),
2202
+ model: 'TS0601_thermostat_2',
2203
+ vendor: 'TuYa',
2204
+ description: 'Thermostat radiator valve',
2205
+ whiteLabel: [
2206
+ {vendor: 'S366', model: 'Cloud Even'},
2207
+ ],
2208
+ fromZigbee: [tuya.fzDataPoints],
2209
+ toZigbee: [tuya.tzDataPoints],
2210
+ onEvent: tuya.onEventSetLocalTime,
2211
+ configure: tuya.configureMagicPacket,
2212
+ meta: {
2213
+ tuyaDatapoints: [
2214
+ [1, 'system_mode', tuya.valueConverterBasic.lookup({'heat': true, 'off': false})],
2215
+ [2, 'preset', tuya.valueConverterBasic.lookup({'manual': tuya.enum(0), 'holiday': tuya.enum(1), 'program': tuya.enum(2)})],
2216
+ [3, null, null], // TODO: Unknown DP
2217
+ [8, 'open_window', tuya.valueConverter.onOff],
2218
+ [10, 'frost_protection', tuya.valueConverter.onOff],
2219
+ [16, 'current_heating_setpoint', tuya.valueConverter.divideBy10],
2220
+ [24, 'local_temperature', tuya.valueConverter.divideBy10],
2221
+ [27, 'local_temperature_calibration', tuya.valueConverter.localTempCalibration],
2222
+ [35, 'battery_low', tuya.valueConverter.true0ElseFalse],
2223
+ [40, 'child_lock', tuya.valueConverter.lockUnlock],
2224
+ [45, 'error_status', tuya.valueConverter.raw],
2225
+ [101, 'schedule_monday', tuya.valueConverter.thermostatScheduleDayMultiDP],
2226
+ [102, 'schedule_tuesday', tuya.valueConverter.thermostatScheduleDayMultiDP],
2227
+ [103, 'schedule_wednesday', tuya.valueConverter.thermostatScheduleDayMultiDP],
2228
+ [104, 'schedule_thursday', tuya.valueConverter.thermostatScheduleDayMultiDP],
2229
+ [105, 'schedule_friday', tuya.valueConverter.thermostatScheduleDayMultiDP],
2230
+ [106, 'schedule_saturday', tuya.valueConverter.thermostatScheduleDayMultiDP],
2231
+ [107, 'schedule_sunday', tuya.valueConverter.thermostatScheduleDayMultiDP],
2199
2232
  ],
2200
2233
  },
2234
+ exposes: [
2235
+ e.battery_low(), e.child_lock(), e.open_window(), tuya.exposes.frostProtection(), tuya.exposes.errorStatus(),
2236
+ exposes.climate()
2237
+ .withSystemMode(['off', 'heat'], ea.STATE_SET)
2238
+ .withPreset(['manual', 'holiday', 'program'])
2239
+ .withLocalTemperatureCalibration(-5, 5, 0.1, ea.STATE_SET)
2240
+ .withLocalTemperature(ea.STATE)
2241
+ .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET),
2242
+ ...tuya.exposes.scheduleAllDays(ea.STATE_SET, 'HH:MM/C HH:MM/C HH:MM/C HH:MM/C'),
2243
+ ],
2201
2244
  },
2202
2245
  {
2203
2246
  fingerprint: [
@@ -3015,8 +3058,7 @@ module.exports = [
3015
3058
  },
3016
3059
  {
3017
3060
  fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_8bxrzyxz'},
3018
- {modelID: 'TS011F', manufacturerName: '_TZ3000_ky0fq4ho'},
3019
- {modelID: 'TS011F', manufacturerName: '_TZ3000_qeuvnohg'}],
3061
+ {modelID: 'TS011F', manufacturerName: '_TZ3000_ky0fq4ho'}],
3020
3062
  model: 'TS011F_din_smart_relay',
3021
3063
  description: 'Din smart relay (with power monitoring)',
3022
3064
  vendor: 'TuYa',
package/devices/ubisys.js CHANGED
@@ -80,10 +80,10 @@ const ubisys = {
80
80
  type: ['attributeReport', 'readResponse'],
81
81
  convert: (model, msg, publish, options, meta) => {
82
82
  const result = {};
83
- if (msg.data.hasOwnProperty('input_configurations')) {
84
- result['input_configurations'] = msg.data['input_configurations'];
83
+ if (msg.data['inputConfigurations'] != null) {
84
+ result['input_configurations'] = msg.data['inputConfigurations'];
85
85
  }
86
- if (msg.data.hasOwnProperty('inputActions')) {
86
+ if (msg.data['inputActions'] != null) {
87
87
  result['input_actions'] = msg.data['inputActions'].map(function(el) {
88
88
  return Object.values(el);
89
89
  });
@@ -2,7 +2,7 @@ const extend = require('../lib/extend');
2
2
 
3
3
  module.exports = [
4
4
  {
5
- zigbeeModel: ['5991711'],
5
+ zigbeeModel: ['5991711', '5991713'],
6
6
  model: 'C5850000',
7
7
  vendor: 'Villeroy & Boch',
8
8
  description: 'Subway 3.0 Zigbee home automation kit',
package/lib/extend.js CHANGED
@@ -12,11 +12,13 @@ const extend = {
12
12
  return {exposes, fromZigbee, toZigbee};
13
13
  },
14
14
  light_onoff_brightness: (options={}) => {
15
- options = {disableEffect: false, disablePowerOnBehavior: false, ...options};
15
+ options = {disableEffect: false, disablePowerOnBehavior: false, disableMoveStep: false, disableTransition: false, ...options};
16
16
  const exposes = [e.light_brightness(), ...(!options.disableEffect ? [e.effect()] : [])];
17
17
  const fromZigbee = [fz.on_off, fz.brightness, fz.level_config, fz.ignore_basic_report];
18
- const toZigbee = [tz.light_onoff_brightness, tz.ignore_transition, tz.ignore_rate, tz.light_brightness_move,
19
- tz.light_brightness_step, tz.level_config, ...(!options.disableEffect ? [tz.effect] : [])];
18
+ const toZigbee = [tz.light_onoff_brightness, tz.ignore_rate, tz.level_config,
19
+ ...(!options.disableTransition ? [tz.ignore_transition] : []),
20
+ ...(!options.disableEffect ? [tz.effect] : []),
21
+ ...(!options.disableMoveStep ? [tz.light_brightness_move, tz.light_brightness_step] : [])];
20
22
 
21
23
  if (!options.disablePowerOnBehavior) {
22
24
  exposes.push(e.power_on_behavior(['off', 'on', 'toggle', 'previous']));
package/lib/tuya.js CHANGED
@@ -1165,6 +1165,11 @@ const tuyaExposes = {
1165
1165
  .withDescription('Result of the self-test'),
1166
1166
  faultAlarm: () => exposes.binary('fault_alarm', ea.STATE, true, false).withDescription('Indicates whether a fault was detected'),
1167
1167
  silence: () => exposes.binary('silence', ea.STATE_SET, true, false).withDescription('Silence the alarm'),
1168
+ frostProtection: (extraNote='') => exposes.binary('frost_protection', ea.STATE_SET, 'ON', 'OFF').withDescription(
1169
+ `When Anti-Freezing function is activated, the temperature in the house is kept at 8 °C.${extraNote}`),
1170
+ errorStatus: () => exposes.numeric('error_status', ea.STATE).withDescription('Error status'),
1171
+ scheduleAllDays: (access, format) => ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
1172
+ .map((day) => exposes.text(`schedule_${day}`, access).withDescription(`Schedule for ${day}, format: "${format}"`)),
1168
1173
  };
1169
1174
 
1170
1175
  const skip = {
@@ -1291,7 +1296,7 @@ const valueConverter = {
1291
1296
  return v.match(numberPattern).join([]).toString();
1292
1297
  },
1293
1298
  },
1294
- thermostatScheduleDay: {
1299
+ thermostatScheduleDaySingleDP: {
1295
1300
  from: (v) => {
1296
1301
  // day splitted to 10 min segments = total 144 segments
1297
1302
  const maxPeriodsInDay = 10;
@@ -1381,6 +1386,46 @@ const valueConverter = {
1381
1386
  return payload;
1382
1387
  },
1383
1388
  },
1389
+ thermostatScheduleDayMultiDP: {
1390
+ from: (v) => {
1391
+ const schedule = [];
1392
+ for (let index = 1; index < 17; index = index + 4) {
1393
+ schedule.push(
1394
+ String(parseInt(v[index+0])).padStart(2, '0') + ':' +
1395
+ String(parseInt(v[index+1])).padStart(2, '0') + '/' +
1396
+ (parseFloat((v[index+2] << 8) + v[index+3]) / 10.0).toFixed(1),
1397
+ );
1398
+ }
1399
+ return schedule.join(' ');
1400
+ },
1401
+ to: (v) => {
1402
+ const payload = [0];
1403
+ const transitions = v.split(' ');
1404
+ if (transitions.length != 4) {
1405
+ throw new Error('Invalid schedule: there should be 4 transitions');
1406
+ }
1407
+ for (const transition of transitions) {
1408
+ const timeTemp = transition.split('/');
1409
+ if (timeTemp.length != 2) {
1410
+ throw new Error('Invalid schedule: wrong transition format: ' + transition);
1411
+ }
1412
+ const hourMin = timeTemp[0].split(':');
1413
+ const hour = hourMin[0];
1414
+ const min = hourMin[1];
1415
+ const temperature = Math.floor(timeTemp[1] *10);
1416
+ if (hour < 0 || hour > 24 || min < 0 || min > 60 || temperature < 50 || temperature > 300) {
1417
+ throw new Error('Invalid hour, minute or temperature of: ' + transition);
1418
+ }
1419
+ payload.push(
1420
+ hour,
1421
+ min,
1422
+ (temperature & 0xff00) >> 8,
1423
+ temperature & 0xff,
1424
+ );
1425
+ }
1426
+ return payload;
1427
+ },
1428
+ },
1384
1429
  TV02SystemMode: {
1385
1430
  from: (v) => {
1386
1431
  return {system_mode: v === false ? 'heat' : 'off', heating_stop: v === false ? 'OFF' : 'ON'};
@@ -1395,7 +1440,8 @@ const tzDataPoints = {
1395
1440
  'countdown', 'light_type', 'silence', 'self_test', 'child_lock', 'open_window', 'open_window_temperature', 'frost_protection',
1396
1441
  'system_mode', 'heating_stop', 'current_heating_setpoint', 'local_temperature_calibration', 'preset', 'boost_timeset_countdown',
1397
1442
  'holiday_start_stop', 'holiday_temperature', 'comfort_temperature', 'eco_temperature', 'working_day', 'week_schedule_programming',
1398
- 'online', 'holiday_mode_date', 'schedule',
1443
+ 'online', 'holiday_mode_date', 'schedule', 'schedule_monday', 'schedule_tuesday', 'schedule_wednesday', 'schedule_thursday',
1444
+ 'schedule_friday', 'schedule_saturday', 'schedule_sunday',
1399
1445
  ],
1400
1446
  convertSet: async (entity, key, value, meta) => {
1401
1447
  // A set converter is only called once; therefore we need to loop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.666",
3
+ "version": "14.0.667",
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.68"
41
+ "zigbee-herdsman": "^0.14.71"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",