zigbee-herdsman-converters 15.0.16 → 15.0.18

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.
@@ -7651,57 +7651,6 @@ const converters = {
7651
7651
  return result;
7652
7652
  },
7653
7653
  },
7654
- tuya_radar_sensor_fall: {
7655
- cluster: 'manuSpecificTuya',
7656
- type: ['commandDataResponse', 'commandDataReport'],
7657
- convert: (model, msg, publish, options, meta) => {
7658
- const dpValue = tuya.firstDpValue(msg, meta, 'tuya_radar_sensor_fall');
7659
- const dp = dpValue.dp;
7660
- const value = tuya.getDataValue(dpValue);
7661
- let result = null;
7662
- switch (dp) {
7663
- case tuya.dataPoints.trsfPresenceState:
7664
- result = {presence: {0: false, 1: true}[value]};
7665
- break;
7666
- case tuya.dataPoints.trsfMotionState:
7667
- result = {occupancy: {1: false, 2: true}[value]};
7668
- break;
7669
- case tuya.dataPoints.trsfMotionSpeed:
7670
- result = {motion_speed: value};
7671
- break;
7672
- case tuya.dataPoints.trsfMotionDirection:
7673
- result = {motion_direction: tuya.tuyaRadar.motionDirection[value]};
7674
- break;
7675
- case tuya.dataPoints.trsfScene:
7676
- result = {radar_scene: tuya.tuyaRadar.radarScene[value]};
7677
- break;
7678
- case tuya.dataPoints.trsfSensitivity:
7679
- result = {radar_sensitivity: value};
7680
- break;
7681
- case tuya.dataPoints.trsfIlluminanceLux:
7682
- result = {illuminance_lux: value};
7683
- break;
7684
- case tuya.dataPoints.trsfTumbleAlarmTime:
7685
- result = {tumble_alarm_time: value+1};
7686
- break;
7687
- case tuya.dataPoints.trsfTumbleSwitch:
7688
- result = {tumble_switch: {false: 'OFF', true: 'ON'}[value]};
7689
- break;
7690
- case tuya.dataPoints.trsfFallDownStatus:
7691
- result = {fall_down_status: tuya.tuyaRadar.fallDown[value]};
7692
- break;
7693
- case tuya.dataPoints.trsfStaticDwellAlarm:
7694
- result = {static_dwell_alarm: value};
7695
- break;
7696
- case tuya.dataPoints.trsfFallSensitivity:
7697
- result = {fall_sensitivity: value};
7698
- break;
7699
- default:
7700
- meta.logger.warn(`fromZigbee.tuya_radar_sensor_fall: NOT RECOGNIZED DP ${dp} with data ${JSON.stringify(dpValue)}`);
7701
- }
7702
- return result;
7703
- },
7704
- },
7705
7654
  tuya_smart_vibration_sensor: {
7706
7655
  cluster: 'manuSpecificTuya',
7707
7656
  type: ['commandGetData', 'commandDataResponse', 'raw'],
@@ -6607,30 +6607,6 @@ const converters = {
6607
6607
  }
6608
6608
  },
6609
6609
  },
6610
- tuya_radar_sensor_fall: {
6611
- key: ['radar_scene', 'radar_sensitivity', 'tumble_alarm_time', 'tumble_switch', 'fall_sensitivity'],
6612
- convertSet: async (entity, key, value, meta) => {
6613
- switch (key) {
6614
- case 'radar_scene':
6615
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.trsfScene, utils.getKey(tuya.tuyaRadar.radarScene, value));
6616
- break;
6617
- case 'radar_sensitivity':
6618
- await tuya.sendDataPointValue(entity, tuya.dataPoints.trsfSensitivity, value);
6619
- break;
6620
- case 'tumble_switch':
6621
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.trsfTumbleSwitch, {'on': true, 'off': false}[value.toLowerCase()]);
6622
- break;
6623
- case 'tumble_alarm_time':
6624
- await tuya.sendDataPointEnum(entity, tuya.dataPoints.trsfTumbleAlarmTime, value-1);
6625
- break;
6626
- case 'fall_sensitivity':
6627
- await tuya.sendDataPointValue(entity, tuya.dataPoints.trsfFallSensitivity, value);
6628
- break;
6629
- default: // Unknown Key
6630
- meta.logger.warn(`toZigbee.tuya_radar_sensor_fall: Unhandled Key ${key}`);
6631
- }
6632
- },
6633
- },
6634
6610
  javis_microwave_sensor: {
6635
6611
  key: [
6636
6612
  'illuminance_calibration', 'led_enable',
package/devices/bosch.js CHANGED
@@ -5,6 +5,7 @@ const tz = require('../converters/toZigbee');
5
5
  const reporting = require('../lib/reporting');
6
6
  const utils = require('../lib/utils');
7
7
  const constants = require('../lib/constants');
8
+ const ota = require('../lib/ota');
8
9
  const e = exposes.presets;
9
10
  const ea = exposes.access;
10
11
 
@@ -396,6 +397,7 @@ const definition = [
396
397
  model: 'BTH-RA',
397
398
  vendor: 'Bosch',
398
399
  description: 'Radiator thermostat II',
400
+ ota: ota.zigbeeOTA,
399
401
  fromZigbee: [fz.thermostat, fz.battery, fzLocal.bosch_thermostat, fzLocal.bosch_userInterface],
400
402
  toZigbee: [
401
403
  tz.thermostat_occupied_heating_setpoint,
@@ -16,9 +16,10 @@ module.exports = [
16
16
  toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn, tz.legrand_identify],
17
17
  exposes: [
18
18
  e.switch(), e.action(['identify', 'on', 'off']),
19
- exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
20
- see the switch in the dark`),
19
+ exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing ` +
20
+ `to see the switch in the dark`),
21
21
  exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on'),
22
+ exposes.enum('identify', ea.SET, ['blink']).withDescription(`Blinks the built-in LED to make it easier to find the device`),
22
23
  ],
23
24
  configure: async (device, coordinatorEndpoint, logger) => {
24
25
  const endpoint = device.getEndpoint(1);
@@ -34,15 +35,18 @@ module.exports = [
34
35
  fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
35
36
  toZigbee: [tz.light_onoff_brightness, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn,
36
37
  tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
37
- exposes: [e.light_brightness(),
38
+ exposes: [
39
+ e.light_brightness(),
38
40
  exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
39
41
  .withDescription('Specifies the minimum brightness value'),
40
42
  exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
41
43
  .withDescription('Specifies the maximum brightness value'),
42
44
  exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
43
- exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
44
- see the switch in the dark`),
45
- exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
45
+ exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing ` +
46
+ `to see the switch in the dark`),
47
+ exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on'),
48
+ exposes.enum('identify', ea.SET, ['blink']).withDescription(`Blinks the built-in LED to make it easier to find the device`),
49
+ ],
46
50
  configure: async (device, coordinatorEndpoint, logger) => {
47
51
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
48
52
  const endpoint = device.getEndpoint(1);
@@ -65,7 +69,12 @@ module.exports = [
65
69
  fz.cover_position_tilt],
66
70
  toZigbee: [tz.bticino_4027C_cover_state, tz.bticino_4027C_cover_position, tz.legrand_identify,
67
71
  tz.legrand_settingEnableLedInDark],
68
- exposes: [e.cover_position()],
72
+ exposes: [
73
+ e.cover_position(), e.action(['moving', 'identify', '']),
74
+ exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing ` +
75
+ `to see the switch in the dark`),
76
+ exposes.enum('identify', ea.SET, ['blink']).withDescription(`Blinks the built-in LED to make it easier to find the device`),
77
+ ],
69
78
  configure: async (device, coordinatorEndpoint, logger) => {
70
79
  const endpoint = device.getEndpoint(1);
71
80
  await reporting.bind(endpoint, coordinatorEndpoint, ['genBinaryInput', 'closuresWindowCovering', 'genIdentify']);
@@ -63,12 +63,12 @@ module.exports = [
63
63
  'from the `local_temperature` measured by the TRV by 5°C to 8°C. In this case you might choose to use an external ' +
64
64
  'room sensor and send the measured value of the external room sensor to the `External_measured_room_sensor` property.' +
65
65
  'The way the TRV operates on the `External_measured_room_sensor` depends on the setting of the `Radiator_covered` ' +
66
- 'property: If `Radiator_covered` is `true` (Auto Offset Mode): You *must* set the `External_measured_room_sensor` ' +
66
+ 'property: If `Radiator_covered` is `false` (Auto Offset Mode): You *must* set the `External_measured_room_sensor` ' +
67
67
  'property *at least* every 3 hours. After 3 hours the TRV disables this function and resets the value of the ' +
68
68
  '`External_measured_room_sensor` property to -8000 (disabled). You *should* set the `External_measured_room_sensor` ' +
69
69
  'property *at most* every 30 minutes or every 0.1K change in measured room temperature.' +
70
- 'If `Radiator_covered` is `false` (Room Sensor Mode): You *must* set the `External_measured_room_sensor` property at ' +
71
- 'least every 30 minutes. After 35 minutes the TRV disables this function and resets the value of the ' +
70
+ 'If `Radiator_covered` is `true` (Room Sensor Mode): You *must* set the `External_measured_room_sensor` property *at ' +
71
+ 'least* every 30 minutes. After 35 minutes the TRV disables this function and resets the value of the ' +
72
72
  '`External_measured_room_sensor` property to -8000 (disabled). You *should* set the `External_measured_room_sensor` ' +
73
73
  'property *at most* every 5 minutes or every 0.1K change in measured room temperature.')
74
74
  .withValueMin(-8000).withValueMax(3500),
@@ -109,7 +109,7 @@ module.exports = [
109
109
  model: 'PM-S140-ZB',
110
110
  vendor: 'Dawon DNS',
111
111
  description: 'IOT smart switch 1 gang without neutral wire',
112
- extend: extend.switch(),
112
+ extend: extend.switch({disablePowerOnBehavior: true}),
113
113
  configure: async (device, coordinatorEndpoint, logger) => {
114
114
  const endpoint = device.getEndpoint(1);
115
115
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
@@ -159,7 +159,7 @@ module.exports = [
159
159
  model: 'PM-S140R-ZB',
160
160
  vendor: 'Dawon DNS',
161
161
  description: 'IOT smart switch 1 gang router without neutral wire',
162
- extend: extend.switch(),
162
+ extend: extend.switch({disablePowerOnBehavior: true}),
163
163
  configure: async (device, coordinatorEndpoint, logger) => {
164
164
  const endpoint = device.getEndpoint(1);
165
165
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
@@ -209,7 +209,7 @@ module.exports = [
209
209
  model: 'PM-S150-ZB',
210
210
  vendor: 'Dawon DNS',
211
211
  description: 'IOT smart switch 1 gang router without neutral wire',
212
- extend: extend.switch(),
212
+ extend: extend.switch({disablePowerOnBehavior: true}),
213
213
  configure: async (device, coordinatorEndpoint, logger) => {
214
214
  const endpoint = device.getEndpoint(1);
215
215
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
package/devices/heiman.js CHANGED
@@ -122,7 +122,7 @@ module.exports = [
122
122
  {
123
123
  zigbeeModel: ['RH3070'],
124
124
  model: 'HS1CG',
125
- vendor: 'Heiman',
125
+ vendor: 'HEIMAN',
126
126
  description: 'Smart combustible gas sensor',
127
127
  fromZigbee: [fz.ias_gas_alarm_1],
128
128
  toZigbee: [],
@@ -403,7 +403,7 @@ module.exports = [
403
403
  zigbeeModel: ['STHM-I1H'],
404
404
  model: 'STHM-I1H',
405
405
  vendor: 'HEIMAN',
406
- description: 'Heiman temperature & humidity sensor',
406
+ description: 'Temperature & humidity sensor',
407
407
  fromZigbee: [fz.temperature, fz.humidity, fz.battery],
408
408
  toZigbee: [],
409
409
  meta: {battery: {voltageToPercentage: '3V_2500'}},
@@ -0,0 +1,11 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ zigbeeModel: ['Hilux DZ8'],
6
+ model: 'DZ8',
7
+ vendor: 'Hilux',
8
+ description: 'Spot 7W',
9
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370], disablePowerOnBehavior: true}),
10
+ },
11
+ ];
package/devices/iris.js CHANGED
@@ -111,7 +111,7 @@ module.exports = [
111
111
  meta: {battery: {voltageToPercentage: '3V_2100'}},
112
112
  configure: async (device, coordinatorEndpoint, logger) => {
113
113
  const endpoint = device.getEndpoint(1);
114
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg', 'msTemperatureMeasurement']);
114
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'msTemperatureMeasurement']);
115
115
  await reporting.onOff(endpoint);
116
116
  await reporting.batteryVoltage(endpoint);
117
117
  await reporting.temperature(endpoint);
@@ -253,6 +253,7 @@ module.exports = [
253
253
  await reporting.onOff(endpoint);
254
254
  await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
255
255
  await reporting.activePower(endpoint);
256
+ await reporting.apparentPower(endpoint);
256
257
  },
257
258
  },
258
259
  {
@@ -310,8 +311,15 @@ module.exports = [
310
311
  await reporting.bind(endpoint, coordinatorEndpoint, ['haElectricalMeasurement', 'genIdentify']);
311
312
  await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
312
313
  await reporting.activePower(endpoint);
313
- // Read configuration values that are not sent periodically as well as current power (activePower).
314
- await endpoint.read('haElectricalMeasurement', ['activePower', 0xf000, 0xf001, 0xf002]);
314
+ await endpoint.read('haElectricalMeasurement', ['activePower']);
315
+ try {
316
+ await reporting.apparentPower(endpoint);
317
+ await endpoint.read('haElectricalMeasurement', ['apparentPower']);
318
+ } catch (e) {
319
+ // Some version/firmware don't seem to support this.
320
+ }
321
+ // Read configuration values that are not sent periodically.
322
+ await endpoint.read('haElectricalMeasurement', [0xf000, 0xf001, 0xf002]);
315
323
  },
316
324
  onEvent: async (type, data, device, options, state) => {
317
325
  /**
@@ -377,6 +385,7 @@ module.exports = [
377
385
  exposes.enum('cable_outlet_mode', ea.ALL, ['comfort', 'comfort-1', 'comfort-2', 'eco', 'frost_protection', 'off']),
378
386
  exposes.switch().withState('state', true, 'Works only when the pilot wire is deactivated'),
379
387
  e.power().withAccess(ea.STATE_GET),
388
+ e.power_apparent(),
380
389
  e.power_on_behavior().withDescription(`Controls the behavior when the device is powered on. Works only when the pilot wire is
381
390
  deactivated`)],
382
391
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -385,6 +394,7 @@ module.exports = [
385
394
  await reporting.onOff(endpoint);
386
395
  await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
387
396
  await reporting.activePower(endpoint);
397
+ await reporting.apparentPower(endpoint);
388
398
  },
389
399
  },
390
400
  {
package/devices/moes.js CHANGED
@@ -97,6 +97,7 @@ module.exports = [
97
97
  {
98
98
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_aoclfnxz'},
99
99
  {modelID: 'TS0601', manufacturerName: '_TZE200_ztvwu4nk'},
100
+ {modelID: 'TS0601', manufacturerName: '_TZE200_5toc8efa'},
100
101
  {modelID: 'TS0601', manufacturerName: '_TZE200_ye5jkfsb'},
101
102
  {modelID: 'TS0601', manufacturerName: '_TZE200_u9bfwha0'}],
102
103
  model: 'BHT-002-GCLZB',
package/devices/nodon.js CHANGED
@@ -47,6 +47,9 @@ module.exports = [
47
47
  await reporting.bind(ep, coordinatorEndpoint, ['genOnOff']);
48
48
  await reporting.onOff(ep);
49
49
  },
50
+ endpoint: (device) => {
51
+ return {default: 1};
52
+ },
50
53
  },
51
54
  {
52
55
  zigbeeModel: ['SIN-4-2-20'],
package/devices/osram.js CHANGED
@@ -205,7 +205,7 @@ module.exports = [
205
205
  model: 'AB3257001NJ',
206
206
  description: 'Smart+ plug',
207
207
  vendor: 'OSRAM',
208
- extend: extend.switch(),
208
+ extend: extend.switch({disablePowerOnBehavior: true}),
209
209
  whiteLabel: [{vendor: 'LEDVANCE', model: 'AB3257001NJ'}, {vendor: 'LEDVANCE', model: 'AC03360'}],
210
210
  ota: ota.ledvance,
211
211
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -226,7 +226,7 @@ module.exports = [
226
226
  model: 'AC10691',
227
227
  description: 'Smart+ plug',
228
228
  vendor: 'OSRAM',
229
- extend: extend.switch(),
229
+ extend: extend.switch({disablePowerOnBehavior: true}),
230
230
  ota: ota.ledvance,
231
231
  whiteLabel: [{vendor: 'LEDVANCE', model: 'AC10691'}],
232
232
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -1379,14 +1379,14 @@ module.exports = [
1379
1379
  model: '8718696598283',
1380
1380
  vendor: 'Philips',
1381
1381
  description: 'Hue white ambiance GU10',
1382
- extend: hueExtend.light_onoff_brightness_colortemp(),
1382
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
1383
1383
  },
1384
1384
  {
1385
1385
  zigbeeModel: ['LTG002'],
1386
1386
  model: '929001953301',
1387
1387
  vendor: 'Philips',
1388
1388
  description: 'Hue white ambiance GU10 with Bluetooth',
1389
- extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 500], disableHueEffects: false}),
1389
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454], disableHueEffects: false}),
1390
1390
  },
1391
1391
  {
1392
1392
  zigbeeModel: ['LTD005'],
@@ -1400,7 +1400,7 @@ module.exports = [
1400
1400
  model: '9290019534',
1401
1401
  vendor: 'Philips',
1402
1402
  description: 'Hue white ambiance GU10 with Bluetooth',
1403
- extend: hueExtend.light_onoff_brightness_colortemp(),
1403
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
1404
1404
  },
1405
1405
  {
1406
1406
  zigbeeModel: ['3417831P6', '929003056101'],
@@ -1561,7 +1561,7 @@ module.exports = [
1561
1561
  model: '4090230P9',
1562
1562
  vendor: 'Philips',
1563
1563
  description: 'Hue Liane (black)',
1564
- extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1564
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disableHueEffects: false}),
1565
1565
  },
1566
1566
  {
1567
1567
  zigbeeModel: ['929003053201'],
@@ -1589,14 +1589,14 @@ module.exports = [
1589
1589
  model: '3261030P6',
1590
1590
  vendor: 'Philips',
1591
1591
  description: 'Hue Being black',
1592
- extend: hueExtend.light_onoff_brightness_colortemp(),
1592
+ extend: hueExtend.light_onoff_brightness_colortemp({disableHueEffects: false}),
1593
1593
  },
1594
1594
  {
1595
1595
  zigbeeModel: ['3261031P6', '929003055001', '929003055101'],
1596
1596
  model: '3261031P6',
1597
1597
  vendor: 'Philips',
1598
1598
  description: 'Hue Being white',
1599
- extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
1599
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454], disableHueEffects: false}),
1600
1600
  },
1601
1601
  {
1602
1602
  zigbeeModel: ['3261048P6'],
@@ -1955,6 +1955,13 @@ module.exports = [
1955
1955
  description: 'Hue Gradient Signe floor lamp (white)',
1956
1956
  extend: hueExtend.light_onoff_brightness_colortemp_color_gradient({colorTempRange: [153, 500]}),
1957
1957
  },
1958
+ {
1959
+ zigbeeModel: ['915005987701'],
1960
+ model: '915005987701',
1961
+ vendor: 'Philips',
1962
+ description: 'Hue Gradient Signe floor lamp (wood)',
1963
+ extend: hueExtend.light_onoff_brightness_colortemp_color_gradient({colorTempRange: [153, 500]}),
1964
+ },
1958
1965
  {
1959
1966
  zigbeeModel: ['LCT020'],
1960
1967
  model: '4080148P7',
@@ -2553,7 +2560,7 @@ module.exports = [
2553
2560
  model: '1741530P7',
2554
2561
  vendor: 'Philips',
2555
2562
  description: 'Hue Lily outdoor spot light',
2556
- extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2563
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disableHueEffects: false}),
2557
2564
  },
2558
2565
  {
2559
2566
  zigbeeModel: ['1741730V7'],
@@ -51,7 +51,7 @@ module.exports = [
51
51
  },
52
52
  },
53
53
  {
54
- fingerprint: [{modelID: 'Dimmer-Switch-ZB3.0', manufacturerName: 'Samotech'}],
54
+ fingerprint: [{modelID: 'Dimmer-Switch-ZB3.0', manufacturerName: 'Samotech'}, {modelID: 'HK_DIM_A', manufacturerName: 'Samotech'}],
55
55
  model: 'SM323',
56
56
  vendor: 'Samotech',
57
57
  description: 'ZigBee retrofit dimmer 250W',
package/devices/sinope.js CHANGED
@@ -724,19 +724,25 @@ module.exports = [
724
724
  description: 'Zigbee low volt thermostat',
725
725
  fromZigbee: [fzLocal.thermostat, fzLocal.sinope, fz.legacy.hvac_user_interface,
726
726
  fz.electrical_measurement, fz.metering, fz.ignore_temperature_report],
727
- toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_temperature_display_mode,
728
- tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim, tzLocal.thermostat_time,
729
- tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature, tzLocal.floor_control_mode,
730
- tzLocal.ambiant_max_heat_setpoint, tzLocal.floor_min_heat_setpoint, tzLocal.floor_max_heat_setpoint, tzLocal.temperature_sensor,
731
- tz.thermostat_min_heat_setpoint_limit, tz.thermostat_max_heat_setpoint_limit, tzLocal.connected_load,
732
- tzLocal.aux_connected_load, tzLocal.main_cycle_output, tzLocal.aux_cycle_output, tzLocal.pump_protection],
727
+ toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint,
728
+ tz.thermostat_temperature_display_mode, tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tzLocal.backlight_autodim,
729
+ tzLocal.thermostat_time, tzLocal.time_format, tzLocal.enable_outdoor_temperature, tzLocal.outdoor_temperature,
730
+ tzLocal.thermostat_occupancy, tzLocal.floor_control_mode, tzLocal.ambiant_max_heat_setpoint, tzLocal.floor_min_heat_setpoint,
731
+ tzLocal.floor_max_heat_setpoint, tzLocal.temperature_sensor, tz.thermostat_min_heat_setpoint_limit,
732
+ tz.thermostat_max_heat_setpoint_limit, tzLocal.connected_load, tzLocal.aux_connected_load, tzLocal.main_cycle_output,
733
+ tzLocal.aux_cycle_output, tzLocal.pump_protection],
733
734
  exposes: [
734
735
  exposes.climate()
735
736
  .withSetpoint('occupied_heating_setpoint', 5, 36, 0.5)
737
+ .withSetpoint('unoccupied_heating_setpoint', 5, 36, 0.5)
736
738
  .withLocalTemperature()
737
739
  .withSystemMode(['off', 'heat'])
738
740
  .withPiHeatingDemand()
739
741
  .withRunningState(['idle', 'heat'], ea.STATE),
742
+ e.max_heat_setpoint_limit(5, 36, 0.5),
743
+ e.min_heat_setpoint_limit(5, 36, 0.5),
744
+ exposes.enum('thermostat_occupancy', ea.ALL, ['unoccupied', 'occupied'])
745
+ .withDescription('Occupancy state of the thermostat'),
740
746
  exposes.binary('enable_outdoor_temperature', ea.ALL, 'ON', 'OFF')
741
747
  .withDescription('Showing outdoor temperature on secondary display'),
742
748
  exposes.enum('temperature_display_mode', ea.ALL, ['celsius', 'fahrenheit'])
@@ -747,34 +753,21 @@ module.exports = [
747
753
  .withDescription('The display backlight behavior'),
748
754
  exposes.enum('keypad_lockout', ea.ALL, ['unlock', 'lock1'])
749
755
  .withDescription('Enables or disables the device’s buttons'),
750
- exposes.presets.max_heat_setpoint_limit(5, 36, 0.5),
751
- exposes.presets.min_heat_setpoint_limit(5, 36, 0.5),
752
756
  exposes.numeric('connected_load', ea.ALL)
753
- .withUnit('W')
754
- .withValueMin(1)
755
- .withValueMax(20000)
757
+ .withUnit('W').withValueMin(1).withValueMax(20000)
756
758
  .withDescription('The power in watts of the electrical load connected to the device'),
757
759
  exposes.enum('floor_control_mode', ea.ALL, ['ambiant', 'floor'])
758
760
  .withDescription('Control mode using floor or ambient temperature'),
759
761
  exposes.numeric('floor_max_heat_setpoint', ea.ALL)
760
- .withUnit('°C')
761
- .withValueMin(7)
762
- .withValueMax(36)
763
- .withValueStep(0.5)
762
+ .withUnit('°C').withValueMin(7).withValueMax(36).withValueStep(0.5)
764
763
  .withPreset('off', 'off', 'Use minimum permitted value')
765
764
  .withDescription('The maximum floor temperature limit of the floor when in ambient control mode'),
766
765
  exposes.numeric('floor_min_heat_setpoint', ea.ALL)
767
- .withUnit('°C')
768
- .withValueMin(5)
769
- .withValueMax(34)
770
- .withValueStep(0.5)
766
+ .withUnit('°C').withValueMin(5).withValueMax(34).withValueStep(0.5)
771
767
  .withPreset('off', 'off', 'Use minimum permitted value')
772
768
  .withDescription('The minimum floor temperature limit of the floor when in ambient control mode'),
773
769
  exposes.numeric('ambiant_max_heat_setpoint', ea.ALL)
774
- .withUnit('°C')
775
- .withValueMin(5)
776
- .withValueMax(36)
777
- .withValueStep(0.5)
770
+ .withUnit('°C').withValueMin(5).withValueMax(36).withValueStep(0.5)
778
771
  .withPreset('off', 'off', 'Use minimum permitted value')
779
772
  .withDescription('The maximum ambient temperature limit when in floor control mode'),
780
773
  exposes.enum('floor_temperature_sensor', ea.ALL, ['10k', '12k'])
@@ -786,9 +779,7 @@ module.exports = [
786
779
  exposes.binary('pump_protection', ea.ALL, 'ON', 'OFF')
787
780
  .withDescription('This function prevents the seizure of the pump'),
788
781
  exposes.numeric('aux_connected_load', ea.ALL)
789
- .withUnit('W')
790
- .withValueMin(0)
791
- .withValueMax(20000)
782
+ .withUnit('W').withValueMin(0).withValueMax(20000)
792
783
  .withDescription('The power in watts of the heater connected to the auxiliary output of the thermostat'),
793
784
  ],
794
785
 
@@ -929,18 +920,16 @@ module.exports = [
929
920
  description: 'Zigbee smart plug',
930
921
  fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
931
922
  toZigbee: [tz.on_off, tz.frequency],
932
- exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy(), e.ac_frequency().withAccess(ea.STATE_GET)],
923
+ exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy()],
933
924
  configure: async (device, coordinatorEndpoint, logger) => {
934
925
  const endpoint = device.getEndpoint(1);
935
926
  const binds = ['genBasic', 'genIdentify', 'genOnOff', 'haElectricalMeasurement', 'seMetering'];
936
927
  await reporting.bind(endpoint, coordinatorEndpoint, binds);
937
- await reporting.readEletricalMeasurementMultiplierDivisors(endpoint, {readFrequencyAttrs: true});
928
+ await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
938
929
  await reporting.onOff(endpoint);
939
930
  await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 10 : 0.1W
940
931
  await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 10}); // divider 100: 0.1Arms
941
932
  await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 10}); // divider 100: 0.1Vrms
942
- await reporting.acFrequency(endpoint, {min: 10, max: 308, change: 100}); // divider 100: 1Hz
943
- await endpoint.read('haElectricalMeasurement', ['acFrequency']); // get a first read
944
933
  await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
945
934
  },
946
935
  },
@@ -951,18 +940,16 @@ module.exports = [
951
940
  description: 'Zigbee smart plug',
952
941
  fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
953
942
  toZigbee: [tz.on_off, tz.frequency],
954
- exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy(), e.ac_frequency().withAccess(ea.STATE_GET)],
943
+ exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy()],
955
944
  configure: async (device, coordinatorEndpoint, logger) => {
956
945
  const endpoint = device.getEndpoint(1);
957
946
  const binds = ['genBasic', 'genIdentify', 'genOnOff', 'haElectricalMeasurement', 'seMetering'];
958
947
  await reporting.bind(endpoint, coordinatorEndpoint, binds);
959
- await reporting.readEletricalMeasurementMultiplierDivisors(endpoint, {readFrequencyAttrs: true});
948
+ await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
960
949
  await reporting.onOff(endpoint);
961
950
  await reporting.activePower(endpoint, {min: 10, max: 305, change: 1}); // divider 10 : 0.1W
962
951
  await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 10}); // divider 100: 0.1Arms
963
952
  await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 10}); // divider 100: 0.1Vrms
964
- await reporting.acFrequency(endpoint, {min: 10, max: 308, change: 100}); // divider 100: 1Hz
965
- await endpoint.read('haElectricalMeasurement', ['acFrequency']); // get a first read
966
953
  await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [1, 1]});
967
954
  },
968
955
  },
@@ -606,7 +606,7 @@ module.exports = [
606
606
  },
607
607
  },
608
608
  {
609
- fingerprint: [{modelID: 'TERNCY-DC01', manufacturer: 'Sunricher'}],
609
+ fingerprint: [{modelID: 'TERNCY-DC01', manufacturerName: 'Sunricher'}],
610
610
  model: 'SR-ZG9010A',
611
611
  vendor: 'Sunricher',
612
612
  description: 'Door windows sensor',
package/devices/tuya.js CHANGED
@@ -1253,10 +1253,10 @@ module.exports = [
1253
1253
  fromZigbee: [tuya.fz.datapoints],
1254
1254
  toZigbee: [tuya.tz.datapoints],
1255
1255
  configure: tuya.configureMagicPacket,
1256
- exposes: [e.temperature(), e.humidity(), tuya.exposes.temperatureUnit(), e.battery(), tuya.exposes.batteryState()],
1256
+ exposes: [e.temperature(), e.soil_moisture(), tuya.exposes.temperatureUnit(), e.battery(), tuya.exposes.batteryState()],
1257
1257
  meta: {
1258
1258
  tuyaDatapoints: [
1259
- [3, 'humidity', tuya.valueConverter.raw],
1259
+ [3, 'soil_moisture', tuya.valueConverter.raw],
1260
1260
  [5, 'temperature', tuya.valueConverter.raw],
1261
1261
  [9, 'temperature_unit', tuya.valueConverter.temperatureUnit],
1262
1262
  [14, 'battery_state', tuya.valueConverter.batteryState],
@@ -1513,6 +1513,7 @@ module.exports = [
1513
1513
  fingerprint: [
1514
1514
  {modelID: 'TS0601', manufacturerName: '_TZE200_nkjintbl'},
1515
1515
  {modelID: 'TS0601', manufacturerName: '_TZE200_ji1gn7rw'},
1516
+ {modelID: 'TS0601', manufacturerName: '_TZE200_3t91nb6k'},
1516
1517
  ],
1517
1518
  model: 'TS0601_switch_2_gang',
1518
1519
  vendor: 'TuYa',
@@ -1881,6 +1882,30 @@ module.exports = [
1881
1882
  exposes: [e.switch(), e.power(), e.current(), e.voltage().withAccess(ea.STATE), e.energy(), tuya.exposes.switchType(),
1882
1883
  exposes.enum('power_outage_memory', ea.ALL, ['on', 'off', 'restore']).withDescription('Recover state after power outage')],
1883
1884
  },
1885
+ {
1886
+ fingerprint: [{modelID: 'TS0002', manufacturerName: '_TZ3000_irrmjcgi'}],
1887
+ model: 'TS0002_power',
1888
+ vendor: 'TuYa',
1889
+ description: '2 gang switch with power monitoring',
1890
+ extend: tuya.extend.switch({switchType: true, endpoints: ['l1', 'l2'], electricalMeasurements: true}),
1891
+ endpoint: (device) => {
1892
+ return {'l1': 1, 'l2': 2};
1893
+ },
1894
+ meta: {multiEndpoint: true, multiEndpointSkip: ['energy', 'current', 'voltage', 'power']},
1895
+ configure: async (device, coordinatorEndpoint, logger) => {
1896
+ const endpoint = device.getEndpoint(1);
1897
+ await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
1898
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
1899
+ await reporting.rmsVoltage(endpoint, {change: 5});
1900
+ await reporting.rmsCurrent(endpoint, {change: 50});
1901
+ await reporting.activePower(endpoint, {change: 10});
1902
+ await reporting.currentSummDelivered(endpoint);
1903
+ endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
1904
+ endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
1905
+ device.save();
1906
+ await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
1907
+ },
1908
+ },
1884
1909
  {
1885
1910
  fingerprint: tuya.fingerprint('TS000F', ['_TZ3000_xkap8wtb']),
1886
1911
  model: 'TS000F_power',
@@ -1935,7 +1960,7 @@ module.exports = [
1935
1960
  },
1936
1961
  },
1937
1962
  {
1938
- fingerprint: [{modelID: 'TS0001', manufacturerName: '_TZ3000_tqlv4ug4'}],
1963
+ fingerprint: [{modelID: 'TS0001', manufacturerName: '_TZ3000_tqlv4ug4'}, {modelID: 'TS0001', manufacturerName: '_TZ3000_gjrubzje'}],
1939
1964
  model: 'TS0001_switch_module',
1940
1965
  vendor: 'TuYa',
1941
1966
  description: '1 gang switch module',
@@ -2102,6 +2127,7 @@ module.exports = [
2102
2127
  {modelID: 'TS0601', manufacturerName: '_TZE200_9sfg7gm0'}, // HomeCloud
2103
2128
  {modelID: 'TS0601', manufacturerName: '_TZE200_2atgpdho'}, // HY367
2104
2129
  {modelID: 'TS0601', manufacturerName: '_TZE200_cpmgn2cf'},
2130
+ {modelID: 'TS0601', manufacturerName: '_TZE200_8thwkzxl'}, // Tervix eva2
2105
2131
  {modelID: 'TS0601', manufacturerName: '_TZE200_4eeyebrt'}, // Immax 07732B
2106
2132
  {modelID: 'TS0601', manufacturerName: '_TZE200_8whxpsiw'}, // EVOLVEO
2107
2133
  {modelID: 'TS0601', manufacturerName: '_TZE200_xby0s3ta'}, // Sandy Beach HY367
@@ -2515,14 +2541,14 @@ module.exports = [
2515
2541
  },
2516
2542
  },
2517
2543
  {
2518
- fingerprint: [160, 69, 68, 65, 64, 66].map((applicationVersion) => {
2544
+ fingerprint: [160, 100, 69, 68, 65, 64, 66].map((applicationVersion) => {
2519
2545
  return {modelID: 'TS011F', applicationVersion, priority: -1};
2520
2546
  }),
2521
2547
  model: 'TS011F_plug_3',
2522
2548
  description: 'Smart plug (with power monitoring by polling)',
2523
2549
  vendor: 'TuYa',
2524
2550
  whiteLabel: [{vendor: 'VIKEFON', model: 'TS011F'}, {vendor: 'BlitzWolf', model: 'BW-SHP15'},
2525
- {vendor: 'Avatto', model: 'MIUCOT10Z'}, {vendor: 'Neo', model: 'NAS-WR01B'}],
2551
+ {vendor: 'Avatto', model: 'MIUCOT10Z'}, {vendor: 'Neo', model: 'NAS-WR01B'}, {vendor: 'Neo', model: 'PLUG-001SPB2'}],
2526
2552
  ota: ota.zigbeeOTA,
2527
2553
  extend: tuya.extend.switch({electricalMeasurements: true, powerOutageMemory: true, indicatorMode: true, childLock: true}),
2528
2554
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -2536,7 +2562,7 @@ module.exports = [
2536
2562
  onEvent: (type, data, device, options) =>
2537
2563
  tuya.onEventMeasurementPoll(type, data, device, options,
2538
2564
  device.applicationVersion !== 66, // polling for voltage, current and power
2539
- device.applicationVersion === 160 || device.applicationVersion === 66, // polling for energy
2565
+ [66, 100, 160].includes(device.applicationVersion), // polling for energy
2540
2566
  ),
2541
2567
  },
2542
2568
  {
@@ -3342,34 +3368,60 @@ module.exports = [
3342
3368
  ],
3343
3369
  },
3344
3370
  {
3345
- fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_lu01t0zl'},
3346
- {modelID: 'TS0601', manufacturerName: '_TZE200_vrfecyku'}],
3371
+ fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lu01t0zl', '_TZE200_vrfecyku']),
3347
3372
  model: 'MIR-HE200-TY',
3348
3373
  vendor: 'TuYa',
3349
3374
  description: 'Human presence sensor with fall function',
3350
- fromZigbee: [fz.tuya_radar_sensor_fall],
3351
- toZigbee: [tz.tuya_radar_sensor_fall],
3375
+ fromZigbee: [tuya.fz.datapoints],
3376
+ toZigbee: [tuya.tz.datapoints],
3377
+ configure: async (device, coordinatorEndpoint, logger) => {
3378
+ const endpoint = device.getEndpoint(1);
3379
+ await tuya.sendDataPointEnum(endpoint, tuya.dataPoints.trsfTumbleSwitch, false);
3380
+ await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
3381
+ },
3352
3382
  exposes: [
3353
3383
  e.illuminance_lux(), e.presence(), e.occupancy(),
3354
3384
  exposes.numeric('motion_speed', ea.STATE).withDescription('Speed of movement'),
3355
- exposes.enum('motion_direction', ea.STATE, Object.values(tuya.tuyaRadar.motionDirection))
3385
+ exposes.enum('motion_direction', ea.STATE, ['standing_still', 'moving_forward', 'moving_backward'])
3356
3386
  .withDescription('direction of movement from the point of view of the radar'),
3357
3387
  exposes.numeric('radar_sensitivity', ea.STATE_SET).withValueMin(0).withValueMax(10).withValueStep(1)
3358
- .withDescription('sensitivity of the radar'),
3359
- exposes.enum('radar_scene', ea.STATE_SET, Object.values(tuya.tuyaRadar.radarScene))
3360
- .withDescription('presets for sensitivity for presence and movement'),
3388
+ .withDescription('Sensitivity of the radar'),
3389
+ exposes.enum('radar_scene', ea.STATE_SET, ['default', 'area', 'toilet', 'bedroom', 'parlour', 'office', 'hotel'])
3390
+ .withDescription('Presets for sensitivity for presence and movement'),
3361
3391
  exposes.enum('tumble_switch', ea.STATE_SET, ['ON', 'OFF']).withDescription('Tumble status switch'),
3362
3392
  exposes.numeric('fall_sensitivity', ea.STATE_SET).withValueMin(1).withValueMax(10).withValueStep(1)
3363
- .withDescription('fall sensitivity of the radar'),
3393
+ .withDescription('Fall sensitivity of the radar'),
3364
3394
  exposes.numeric('tumble_alarm_time', ea.STATE_SET).withValueMin(1).withValueMax(5).withValueStep(1)
3365
- .withUnit('min').withDescription('tumble alarm time'),
3366
- exposes.enum('fall_down_status', ea.STATE, Object.values(tuya.tuyaRadar.fallDown))
3367
- .withDescription('fall down status'),
3368
- exposes.text('static_dwell_alarm', ea.STATE).withDescription('static dwell alarm'),
3395
+ .withUnit('min').withDescription('Tumble alarm time'),
3396
+ exposes.enum('fall_down_status', ea.STATE, ['none', 'maybe_fall', 'fall'])
3397
+ .withDescription('Fall down status'),
3398
+ exposes.text('static_dwell_alarm', ea.STATE).withDescription('Static dwell alarm'),
3369
3399
  ],
3370
- configure: async (device, coordinatorEndpoint, logger) => {
3371
- const endpoint = device.getEndpoint(1);
3372
- await tuya.sendDataPointEnum(endpoint, tuya.dataPoints.trsfTumbleSwitch, false);
3400
+ meta: {
3401
+ tuyaDatapoints: [
3402
+ [1, 'presence', tuya.valueConverter.trueFalse],
3403
+ [2, 'radar_sensitivity', tuya.valueConverter.raw],
3404
+ [102, 'occupancy', tuya.valueConverterBasic.lookup({false: 1, true: 2})],
3405
+ [103, 'illuminance_lux', tuya.valueConverter.raw],
3406
+ [105, 'tumble_switch', tuya.valueConverter.plus1],
3407
+ [106, 'tumble_alarm_time', tuya.valueConverter.raw],
3408
+ [112, 'radar_scene', tuya.valueConverterBasic.lookup(
3409
+ {'default': 0, 'area': 1, 'toilet': 2, 'bedroom': 3, 'parlour': 4, 'office': 5, 'hotel': 6})],
3410
+ [114, 'motion_direction', tuya.valueConverterBasic.lookup(
3411
+ {'standing_still': 0, 'moving_forward': 1, 'moving_backward': 2})],
3412
+ [115, 'motion_speed', tuya.valueConverter.raw],
3413
+ [116, 'fall_down_status', tuya.valueConverterBasic.lookup({'none': 0, 'maybe_fall': 1, 'fall': 2})],
3414
+ [117, 'static_dwell_alarm', tuya.valueConverter.raw],
3415
+ [118, 'fall_sensitivity', tuya.valueConverter.raw],
3416
+ // Below are ignored
3417
+ [101, null, null], // reset_flag_code
3418
+ [104, null, null], // detection_flag_code
3419
+ [107, null, null], // radar_check_end_code
3420
+ [108, null, null], // radar_check_start_code
3421
+ [109, null, null], // hw_version_code
3422
+ [110, null, null], // sw_version_code
3423
+ [111, null, null], // radar_id_code
3424
+ ],
3373
3425
  },
3374
3426
  },
3375
3427
  {
package/devices/ubisys.js CHANGED
@@ -86,7 +86,7 @@ const ubisys = {
86
86
  cluster: 'manuSpecificUbisysDeviceSetup',
87
87
  type: ['attributeReport', 'readResponse'],
88
88
  convert: (model, msg, publish, options, meta) => {
89
- const result = {};
89
+ const result = meta.state.hasOwnProperty('configure_device_setup') ? meta.state.configure_device_setup : {};
90
90
  if (msg.data['inputConfigurations'] != null) {
91
91
  result['input_configurations'] = msg.data['inputConfigurations'];
92
92
  }
@@ -501,7 +501,7 @@ const ubisys = {
501
501
  endpoint += 1;
502
502
  }
503
503
 
504
- meta.logger.debug(`ubisys: input_actions to be sent to '${meta.options.friendlyName}': ` +
504
+ meta.logger.debug(`ubisys: input_actions to be sent to '${meta.options.friendly_name}': ` +
505
505
  JSON.stringify(resultingInputActions));
506
506
  await devMgmtEp.write(
507
507
  'manuSpecificUbisysDeviceSetup',
@@ -511,12 +511,14 @@ const ubisys = {
511
511
  }
512
512
 
513
513
  // re-read effective settings and dump them to the log
514
- ubisys.tz.configure_device_setup.convertGet(entity, key, meta);
514
+ await ubisys.tz.configure_device_setup.convertGet(entity, key, meta);
515
515
  },
516
516
 
517
517
  convertGet: async (entity, key, meta) => {
518
518
  const devMgmtEp = meta.device.getEndpoint(232);
519
- await devMgmtEp.read('manuSpecificUbisysDeviceSetup', ['inputConfigurations', 'inputActions'],
519
+ await devMgmtEp.read('manuSpecificUbisysDeviceSetup', ['inputConfigurations'],
520
+ manufacturerOptions.ubisysNull);
521
+ await devMgmtEp.read('manuSpecificUbisysDeviceSetup', ['inputActions'],
520
522
  manufacturerOptions.ubisysNull);
521
523
  },
522
524
  },
@@ -835,13 +837,17 @@ module.exports = [
835
837
  fromZigbee: [fz.legacy.ubisys_c4_scenes, fz.legacy.ubisys_c4_onoff, fz.legacy.ubisys_c4_level, fz.legacy.ubisys_c4_cover,
836
838
  ubisys.fz.configure_device_setup],
837
839
  toZigbee: [ubisys.tz.configure_device_setup],
838
- exposes: [e.action([
839
- '1_scene_*', '1_on', '1_off', '1_toggle', '1_level_move_down', '1_level_move_up',
840
- '2_scene_*', '2_on', '2_off', '2_toggle', '2_level_move_down', '2_level_move_up',
841
- '3_scene_*', '3_on', '3_off', '3_toggle', '3_level_move_down', '3_level_move_up',
842
- '4_scene_*', '4_on', '4_off', '4_toggle', '4_level_move_down', '4_level_move_up',
843
- '5_scene_*', '5_cover_open', '5_cover_close', '5_cover_stop',
844
- '6_scene_*', '6_cover_open', '6_cover_close', '6_cover_stop'])],
840
+ exposes: [
841
+ e.action([
842
+ 'toggle_s1', 'toggle_s2', 'toggle_s3', 'toggle_s4', 'on_s1', 'on_s2', 'on_s3', 'on_s4',
843
+ 'off_s1', 'off_s2', 'off_s3', 'off_s4', 'recall_*_s1', 'recal_*_s2', 'recall_*_s3', 'recal_*_s4',
844
+ 'brightness_move_up_s1', 'brightness_move_up_s2', 'brightness_move_up_s3', 'brightness_move_up_s4',
845
+ 'brightness_move_down_s1', 'brightness_move_down_s2', 'brightness_move_down_s3', 'brightness_move_down_s4',
846
+ 'brightness_stop_s1', 'brightness_stop_s2', 'brightness_stop_s3', 'brightness_stop_s4',
847
+ 'cover_open_s5', 'cover_close_s5', 'cover_stop_s5',
848
+ 'cover_open_s6', 'cover_close_s6', 'cover_stop_s6',
849
+ ]),
850
+ ],
845
851
  configure: async (device, coordinatorEndpoint, logger) => {
846
852
  for (const ep of [1, 2, 3, 4]) {
847
853
  await reporting.bind(device.getEndpoint(ep), coordinatorEndpoint, ['genScenes', 'genOnOff', 'genLevelCtrl']);
@@ -850,6 +856,10 @@ module.exports = [
850
856
  await reporting.bind(device.getEndpoint(ep), coordinatorEndpoint, ['genScenes', 'closuresWindowCovering']);
851
857
  }
852
858
  },
859
+ meta: {multiEndpoint: true},
860
+ endpoint: (device) => {
861
+ return {'s1': 1, 's2': 2, 's3': 3, 's4': 4, 's5': 5, 's6': 6};
862
+ },
853
863
  ota: ota.ubisys,
854
864
  },
855
865
  {
package/lib/ota/common.js CHANGED
@@ -261,12 +261,9 @@ async function isNewImageAvailable(current, logger, device, getImageMeta) {
261
261
  const [currentS, metaS] = [JSON.stringify(current), JSON.stringify(meta)];
262
262
  logger.debug(`Is new image available for '${device.ieeeAddr}', current '${currentS}', latest meta '${metaS}'`);
263
263
 
264
- if (meta.force) {
265
- return -1; // Negative number means the new firmware is 'newer' than current one
266
- }
267
-
264
+ // Negative number means the new firmware is 'newer' than current one
268
265
  return {
269
- available: Math.sign(current.fileVersion - meta.fileVersion),
266
+ available: meta.force ? -1 : Math.sign(current.fileVersion - meta.fileVersion),
270
267
  currentFileVersion: current.fileVersion,
271
268
  otaFileVersion: meta.fileVersion,
272
269
  };
package/lib/reporting.js CHANGED
@@ -202,6 +202,10 @@ module.exports = {
202
202
  const p = payload('activePower', 5, repInterval.HOUR, 1, overrides);
203
203
  await endpoint.configureReporting('haElectricalMeasurement', p);
204
204
  },
205
+ apparentPower: async (endpoint, overrides) => {
206
+ const p = payload('apparentPower', 5, repInterval.HOUR, 1, overrides);
207
+ await endpoint.configureReporting('haElectricalMeasurement', p);
208
+ },
205
209
  rmsCurrent: async (endpoint, overrides) => {
206
210
  const p = payload('rmsCurrent', 5, repInterval.HOUR, 1, overrides);
207
211
  await endpoint.configureReporting('haElectricalMeasurement', p);
package/lib/tuya.js CHANGED
@@ -1246,7 +1246,7 @@ const valueConverterBasic = {
1246
1246
  };
1247
1247
 
1248
1248
  const valueConverter = {
1249
- trueFalse: valueConverterBasic.lookup({1: true, 0: false}),
1249
+ trueFalse: valueConverterBasic.lookup({true: 1, false: 0}),
1250
1250
  onOff: valueConverterBasic.lookup({'ON': true, 'OFF': false}),
1251
1251
  powerOnBehavior: valueConverterBasic.lookup({'off': 0, 'on': 1, 'previous': 2}),
1252
1252
  lightType: valueConverterBasic.lookup({'led': 0, 'incandescent': 1, 'halogen': 2}),
@@ -1259,6 +1259,10 @@ const valueConverter = {
1259
1259
  divideBy10: valueConverterBasic.divideBy(10),
1260
1260
  divideBy1000: valueConverterBasic.divideBy(1000),
1261
1261
  raw: valueConverterBasic.raw(),
1262
+ plus1: {
1263
+ from: (v) => v + 1,
1264
+ to: (v) => v - 1,
1265
+ },
1262
1266
  static: (value) => {
1263
1267
  return {
1264
1268
  from: (v) => {
@@ -1577,7 +1581,7 @@ const tuyaTz = {
1577
1581
  'holiday_start_stop', 'holiday_temperature', 'comfort_temperature', 'eco_temperature', 'working_day',
1578
1582
  'week_schedule_programming', 'online', 'holiday_mode_date', 'schedule', 'schedule_monday', 'schedule_tuesday',
1579
1583
  'schedule_wednesday', 'schedule_thursday', 'schedule_friday', 'schedule_saturday', 'schedule_sunday', 'clear_fault',
1580
- 'scale_protection', 'error',
1584
+ 'scale_protection', 'error', 'radar_scene', 'radar_sensitivity', 'tumble_alarm_time', 'tumble_switch', 'fall_sensitivity',
1581
1585
  ],
1582
1586
  convertSet: async (entity, key, value, meta) => {
1583
1587
  // 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": "15.0.16",
3
+ "version": "15.0.18",
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": "^3.0.0",
41
- "zigbee-herdsman": "^0.14.83"
41
+ "zigbee-herdsman": "^0.14.84"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",