zigbee-herdsman-converters 14.0.304 → 14.0.308
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 +1 -0
- package/converters/fromZigbee.js +2 -1
- package/converters/toZigbee.js +11 -0
- package/devices/ajax_online.js +7 -0
- package/devices/danfoss.js +7 -6
- package/devices/envilar.js +18 -0
- package/devices/girier.js +20 -0
- package/devices/hive.js +12 -1
- package/devices/ikea.js +4 -3
- package/devices/perenio.js +1 -0
- package/devices/popp.js +13 -6
- package/devices/tuya.js +5 -3
- package/devices/universal_electronics_inc.js +16 -0
- package/devices/xiaomi.js +29 -0
- package/lib/exposes.js +2 -2
- package/lib/legacy.js +2 -2
- package/lib/reporting.js +1 -1
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,3 +31,4 @@ If any of those commands finish with an error your PR won't pass the tests and w
|
|
|
31
31
|
- `battery`:
|
|
32
32
|
- `{dontDividePercentage: true}`: prevents batteryPercentageRemainig from being divided (ZCL 200=100%, but some report 100=100%) (default: false)
|
|
33
33
|
- `{voltageToPercentage: '3V_2100'}`: convert voltage to percentage using specified option. See utils.batteryVoltageToPercentage() (default: null, no voltage to percentage conversion)
|
|
34
|
+
- `fanStateOn`: value used for fan_mode when using fan_state="ON", the default is "on"
|
package/converters/fromZigbee.js
CHANGED
|
@@ -2798,6 +2798,7 @@ const converters = {
|
|
|
2798
2798
|
const h = parseInt(value.substring(0, 4), 16);
|
|
2799
2799
|
const s = parseInt(value.substring(4, 8), 16);
|
|
2800
2800
|
const b = parseInt(value.substring(8, 12), 16);
|
|
2801
|
+
result.color_mode = 'hs';
|
|
2801
2802
|
result.color = {b: mapNumberRange(b, 0, 1000, 0, 255), h, s: mapNumberRange(s, 0, 1000, 0, 100)};
|
|
2802
2803
|
result.brightness = result.color.b;
|
|
2803
2804
|
} else if (dp === tuya.dataPoints.silvercrestSetEffect) {
|
|
@@ -4840,7 +4841,7 @@ const converters = {
|
|
|
4840
4841
|
}
|
|
4841
4842
|
|
|
4842
4843
|
let buttonLookup = null;
|
|
4843
|
-
if (['WXKG02LM_rev2', 'WXKG07LM'].includes(model.model)) buttonLookup = {1: 'left', 2: 'right', 3: 'both'};
|
|
4844
|
+
if (['WXKG02LM_rev2', 'WXKG07LM', 'WXKG17LM'].includes(model.model)) buttonLookup = {1: 'left', 2: 'right', 3: 'both'};
|
|
4844
4845
|
if (['QBKG12LM', 'QBKG24LM'].includes(model.model)) buttonLookup = {5: 'left', 6: 'right', 7: 'both'};
|
|
4845
4846
|
if (['QBKG25LM', 'QBKG26LM'].includes(model.model)) buttonLookup = {41: 'left', 42: 'center', 43: 'right'};
|
|
4846
4847
|
if (['QBKG39LM', 'QBKG41LM', 'WS-EUK02', 'WS-EUK04', 'QBKG20LM', 'QBKG31LM'].includes(model.model)) {
|
package/converters/toZigbee.js
CHANGED
|
@@ -1192,6 +1192,9 @@ const converters = {
|
|
|
1192
1192
|
fan_mode: {
|
|
1193
1193
|
key: ['fan_mode', 'fan_state'],
|
|
1194
1194
|
convertSet: async (entity, key, value, meta) => {
|
|
1195
|
+
if (key == 'fan_state' && value.toLowerCase() == 'on') {
|
|
1196
|
+
value = utils.getMetaValue(entity, meta.mapped, 'fanStateOn', 'allEqual', 'on');
|
|
1197
|
+
}
|
|
1195
1198
|
const fanMode = constants.fanMode[value.toLowerCase()];
|
|
1196
1199
|
await entity.write('hvacFanCtrl', {fanMode});
|
|
1197
1200
|
return {state: {fan_mode: value.toLowerCase(), fan_state: value.toLowerCase() === 'off' ? 'OFF' : 'ON'}};
|
|
@@ -6114,6 +6117,14 @@ const converters = {
|
|
|
6114
6117
|
await endpoint.read('genOnOff', ['tuyaOperationMode']);
|
|
6115
6118
|
},
|
|
6116
6119
|
},
|
|
6120
|
+
xiaomi_switch_click_mode: {
|
|
6121
|
+
key: ['click_mode'],
|
|
6122
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6123
|
+
const lookupState = {'fast': 0x1, 'multi': 0x02};
|
|
6124
|
+
await entity.write('aqaraOpple', {0x0125: {value: lookupState[value], type: 0x20}}, manufacturerOptions.xiaomi);
|
|
6125
|
+
return {state: {click_mode: value}};
|
|
6126
|
+
},
|
|
6127
|
+
},
|
|
6117
6128
|
// #endregion
|
|
6118
6129
|
|
|
6119
6130
|
// #region Ignore converters
|
package/devices/ajax_online.js
CHANGED
|
@@ -23,4 +23,11 @@ module.exports = [
|
|
|
23
23
|
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
|
|
24
24
|
meta: {turnsOffAtBrightness1: true},
|
|
25
25
|
},
|
|
26
|
+
{
|
|
27
|
+
zigbeeModel: ['ZB_A60_RGBCW'],
|
|
28
|
+
model: 'ZB_A60_RGBCW',
|
|
29
|
+
vendor: 'Ajax Online',
|
|
30
|
+
description: 'Smart Zigbee pro 12W A60 RGBCW bulb',
|
|
31
|
+
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
32
|
+
},
|
|
26
33
|
];
|
package/devices/danfoss.js
CHANGED
|
@@ -9,7 +9,8 @@ const ea = exposes.access;
|
|
|
9
9
|
|
|
10
10
|
module.exports = [
|
|
11
11
|
{
|
|
12
|
-
// eTRV0100 is the same as Hive
|
|
12
|
+
// eTRV0100 is the same as Hive TRV001 and Popp eT093WRO. If implementing anything, please consider
|
|
13
|
+
// changing those two too.
|
|
13
14
|
zigbeeModel: ['eTRV0100'],
|
|
14
15
|
model: '014G2461',
|
|
15
16
|
vendor: 'Danfoss',
|
|
@@ -37,7 +38,7 @@ module.exports = [
|
|
|
37
38
|
exposes.binary('heat_required', ea.STATE_GET, true, false)
|
|
38
39
|
.withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'),
|
|
39
40
|
exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
|
|
40
|
-
.withDescription('Values observed are `0` (
|
|
41
|
+
.withDescription('Values observed are `0` (manual), `1` (schedule) or `2` (externally)'),
|
|
41
42
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
|
|
42
43
|
.withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
|
|
43
44
|
exposes.numeric('external_measured_room_sensor', ea.ALL)
|
|
@@ -71,10 +72,10 @@ module.exports = [
|
|
|
71
72
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
|
|
72
73
|
|
|
73
74
|
// standard ZCL attributes
|
|
74
|
-
await reporting.batteryPercentageRemaining(endpoint
|
|
75
|
-
await reporting.thermostatTemperature(endpoint, {min: 0, max: constants.repInterval.
|
|
76
|
-
await reporting.thermostatPIHeatingDemand(endpoint
|
|
77
|
-
await reporting.thermostatOccupiedHeatingSetpoint(endpoint, {min: 0, max: constants.repInterval.
|
|
75
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
76
|
+
await reporting.thermostatTemperature(endpoint, {min: 0, max: constants.repInterval.HOUR, change: 5});
|
|
77
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
78
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint, {min: 0, max: constants.repInterval.HOUR, change: 5});
|
|
78
79
|
|
|
79
80
|
// danfoss attributes
|
|
80
81
|
await endpoint.configureReporting('hvacThermostat', [{
|
package/devices/envilar.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const reporting = require('../lib/reporting');
|
|
2
2
|
const extend = require('../lib/extend');
|
|
3
|
+
const exposes = require('zigbee-herdsman-converters/lib/exposes');
|
|
4
|
+
const e = exposes.presets;
|
|
3
5
|
|
|
4
6
|
module.exports = [
|
|
5
7
|
{
|
|
@@ -26,4 +28,20 @@ module.exports = [
|
|
|
26
28
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic', 'genIdentify', 'genOnOff']);
|
|
27
29
|
},
|
|
28
30
|
},
|
|
31
|
+
{
|
|
32
|
+
zigbeeModel: ['2CH-ZG-BOX-RELAY'],
|
|
33
|
+
model: '2CH-ZG-BOX-RELAY',
|
|
34
|
+
vendor: 'Envilar',
|
|
35
|
+
description: '2 channel box relay',
|
|
36
|
+
extend: extend.switch(),
|
|
37
|
+
exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2')],
|
|
38
|
+
endpoint: (device) => {
|
|
39
|
+
return {'l1': 1, 'l2': 2};
|
|
40
|
+
},
|
|
41
|
+
meta: {multiEndpoint: true},
|
|
42
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
43
|
+
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
44
|
+
await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
|
|
45
|
+
},
|
|
46
|
+
},
|
|
29
47
|
];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const fz = require('../converters/fromZigbee');
|
|
2
|
+
const tz = require('../converters/toZigbee');
|
|
3
|
+
const exposes = require('../lib/exposes');
|
|
4
|
+
const reporting = require('../lib/reporting');
|
|
5
|
+
const extend = require('../lib/extend');
|
|
6
|
+
|
|
7
|
+
module.exports = [
|
|
8
|
+
{
|
|
9
|
+
fingerprint: [{modelID: 'TS0001', manufacturerName: '_TZ3000_majwnphg'}],
|
|
10
|
+
model: 'JR-ZDS01',
|
|
11
|
+
vendor: 'Girier',
|
|
12
|
+
description: '1 gang mini switch',
|
|
13
|
+
toZigbee: extend.switch().toZigbee.concat([tz.moes_power_on_behavior, tz.tuya_switch_type]),
|
|
14
|
+
fromZigbee: extend.switch().fromZigbee.concat([fz.moes_power_on_behavior, fz.tuya_switch_type]),
|
|
15
|
+
exposes: extend.switch().exposes.concat([exposes.presets.power_on_behavior(), exposes.presets.switch_type_2()]),
|
|
16
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
17
|
+
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
];
|
package/devices/hive.js
CHANGED
|
@@ -150,6 +150,8 @@ module.exports = [
|
|
|
150
150
|
},
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
|
+
// TRV001 is the same as Danfoss Ally (eTRV0100) and Popp eT093WRO. If implementing anything, please consider
|
|
154
|
+
// changing those two too.
|
|
153
155
|
zigbeeModel: ['TRV001'],
|
|
154
156
|
model: 'UK7004240',
|
|
155
157
|
vendor: 'Hive',
|
|
@@ -160,7 +162,7 @@ module.exports = [
|
|
|
160
162
|
tz.danfoss_heat_available, tz.danfoss_heat_required, tz.danfoss_day_of_week, tz.danfoss_trigger_time,
|
|
161
163
|
tz.danfoss_window_open_internal, tz.danfoss_window_open_external, tz.danfoss_load_estimate,
|
|
162
164
|
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.thermostat_keypad_lockout,
|
|
163
|
-
tz.thermostat_system_mode],
|
|
165
|
+
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean],
|
|
164
166
|
exposes: [e.battery(), e.keypad_lockout(),
|
|
165
167
|
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
|
|
166
168
|
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
|
|
@@ -176,6 +178,8 @@ module.exports = [
|
|
|
176
178
|
.withDescription('Not clear how this affects operation. `false` No Heat Available or `true` Heat Available'),
|
|
177
179
|
exposes.binary('heat_required', ea.STATE_GET, true, false)
|
|
178
180
|
.withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'),
|
|
181
|
+
exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
|
|
182
|
+
.withDescription('Values observed are `0` (manual), `1` (schedule) or `2` (externally)'),
|
|
179
183
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
|
|
180
184
|
.withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
|
|
181
185
|
exposes.numeric('external_measured_room_sensor', ea.ALL)
|
|
@@ -195,6 +199,11 @@ module.exports = [
|
|
|
195
199
|
exposes.numeric('algorithm_scale_factor', ea.ALL).withValueMin(1).withValueMax(10)
|
|
196
200
|
.withDescription('Scale factor of setpoint filter timeconstant ("aggressiveness" of control algorithm) '+
|
|
197
201
|
'1= Quick ... 5=Moderate ... 10=Slow'),
|
|
202
|
+
exposes.binary('load_balancing_enable', ea.ALL, true, false)
|
|
203
|
+
.withDescription('Whether or not the thermostat acts as standalone thermostat or shares load with other ' +
|
|
204
|
+
'thermostats in the room. The gateway must update load_room_mean if enabled.'),
|
|
205
|
+
exposes.numeric('load_room_mean', ea.ALL)
|
|
206
|
+
.withDescription('Mean radiator load for room calculated by gateway for load balancing purposes'),
|
|
198
207
|
exposes.numeric('load_estimate', ea.STATE_GET)
|
|
199
208
|
.withDescription('Load estimate on this radiator')],
|
|
200
209
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -243,6 +252,8 @@ module.exports = [
|
|
|
243
252
|
'danfossMountedModeControl',
|
|
244
253
|
'danfossMountedModeActive',
|
|
245
254
|
'danfossExternalMeasuredRoomSensor',
|
|
255
|
+
'danfossLoadBalancingEnable',
|
|
256
|
+
'danfossLoadRoomMean',
|
|
246
257
|
], options);
|
|
247
258
|
|
|
248
259
|
// read systemMode to have an initial value
|
package/devices/ikea.js
CHANGED
|
@@ -446,8 +446,8 @@ module.exports = [
|
|
|
446
446
|
model: 'E1812',
|
|
447
447
|
vendor: 'IKEA',
|
|
448
448
|
description: 'TRADFRI shortcut button',
|
|
449
|
-
fromZigbee: [fz.command_on, fz.command_move, fz.command_stop, fz.battery],
|
|
450
|
-
exposes: [e.battery(), e.action(['on', 'brightness_move_up', 'brightness_stop'])],
|
|
449
|
+
fromZigbee: [fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
|
|
450
|
+
exposes: [e.battery(), e.action(['on', 'off', 'brightness_move_up', 'brightness_stop'])],
|
|
451
451
|
toZigbee: [],
|
|
452
452
|
ota: ota.tradfri,
|
|
453
453
|
meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
|
|
@@ -625,7 +625,8 @@ module.exports = [
|
|
|
625
625
|
model: 'E2007',
|
|
626
626
|
vendor: 'IKEA',
|
|
627
627
|
description: 'STARKVIND air purifier',
|
|
628
|
-
exposes: [e.fan().withModes(['off', 'low', 'medium', 'high', '
|
|
628
|
+
exposes: [e.fan().withModes(['off', 'low', 'medium', 'high', 'auto'])],
|
|
629
|
+
meta: {fanStateOn: 'auto'},
|
|
629
630
|
fromZigbee: [fz.fan],
|
|
630
631
|
toZigbee: [tz.fan_mode],
|
|
631
632
|
configure: async (device, coordinatorEndpoint, logger) => {
|
package/devices/perenio.js
CHANGED
|
@@ -10,6 +10,7 @@ module.exports = [
|
|
|
10
10
|
vendor: 'Perenio',
|
|
11
11
|
description: 'Flood alarm device',
|
|
12
12
|
fromZigbee: [fz.ias_water_leak_alarm_1, fz.ignore_basic_report, fz.battery],
|
|
13
|
+
meta: {battery: {dontDividePercentage: true}},
|
|
13
14
|
toZigbee: [],
|
|
14
15
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
15
16
|
const endpoint = device.getEndpoint(1);
|
package/devices/popp.js
CHANGED
|
@@ -21,7 +21,7 @@ module.exports = [
|
|
|
21
21
|
tz.danfoss_heat_available, tz.danfoss_heat_required, tz.danfoss_day_of_week, tz.danfoss_trigger_time,
|
|
22
22
|
tz.danfoss_window_open_internal, tz.danfoss_window_open_external, tz.danfoss_load_estimate,
|
|
23
23
|
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.thermostat_keypad_lockout,
|
|
24
|
-
tz.thermostat_system_mode],
|
|
24
|
+
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean],
|
|
25
25
|
exposes: [e.battery(), e.keypad_lockout(),
|
|
26
26
|
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
|
|
27
27
|
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
|
|
@@ -38,7 +38,7 @@ module.exports = [
|
|
|
38
38
|
exposes.binary('heat_required', ea.STATE_GET, true, false)
|
|
39
39
|
.withDescription('Whether or not the unit needs warm water. `false` No Heat Request or `true` Heat Request'),
|
|
40
40
|
exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
|
|
41
|
-
.withDescription('Values observed are `0` (
|
|
41
|
+
.withDescription('Values observed are `0` (manual), `1` (schedule) or `2` (externally)'),
|
|
42
42
|
exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature().withPiHeatingDemand()
|
|
43
43
|
.withSystemMode(['heat']).withRunningState(['idle', 'heat'], ea.STATE),
|
|
44
44
|
exposes.numeric('external_measured_room_sensor', ea.ALL)
|
|
@@ -58,6 +58,11 @@ module.exports = [
|
|
|
58
58
|
exposes.numeric('algorithm_scale_factor', ea.ALL).withValueMin(1).withValueMax(10)
|
|
59
59
|
.withDescription('Scale factor of setpoint filter timeconstant ("aggressiveness" of control algorithm) '+
|
|
60
60
|
'1= Quick ... 5=Moderate ... 10=Slow'),
|
|
61
|
+
exposes.binary('load_balancing_enable', ea.ALL, true, false)
|
|
62
|
+
.withDescription('Whether or not the thermostat acts as standalone thermostat or shares load with other ' +
|
|
63
|
+
'thermostats in the room. The gateway must update load_room_mean if enabled.'),
|
|
64
|
+
exposes.numeric('load_room_mean', ea.ALL)
|
|
65
|
+
.withDescription('Mean radiator load for room calculated by gateway for load balancing purposes'),
|
|
61
66
|
exposes.numeric('load_estimate', ea.STATE_GET)
|
|
62
67
|
.withDescription('Load estimate on this radiator')],
|
|
63
68
|
ota: ota.zigbeeOTA,
|
|
@@ -67,10 +72,10 @@ module.exports = [
|
|
|
67
72
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
|
|
68
73
|
|
|
69
74
|
// standard ZCL attributes
|
|
70
|
-
await reporting.batteryPercentageRemaining(endpoint
|
|
71
|
-
await reporting.thermostatTemperature(endpoint, {min: 0, max: constants.repInterval.
|
|
72
|
-
await reporting.thermostatPIHeatingDemand(endpoint
|
|
73
|
-
await reporting.thermostatOccupiedHeatingSetpoint(endpoint, {min: 0, max: constants.repInterval.
|
|
75
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
76
|
+
await reporting.thermostatTemperature(endpoint, {min: 0, max: constants.repInterval.HOUR, change: 5});
|
|
77
|
+
await reporting.thermostatPIHeatingDemand(endpoint);
|
|
78
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint, {min: 0, max: constants.repInterval.HOUR, change: 5});
|
|
74
79
|
|
|
75
80
|
// danfoss attributes
|
|
76
81
|
await endpoint.configureReporting('hvacThermostat', [{
|
|
@@ -107,6 +112,8 @@ module.exports = [
|
|
|
107
112
|
'danfossMountedModeControl',
|
|
108
113
|
'danfossMountedModeActive',
|
|
109
114
|
'danfossExternalMeasuredRoomSensor',
|
|
115
|
+
'danfossLoadBalancingEnable',
|
|
116
|
+
'danfossLoadRoomMean',
|
|
110
117
|
], options);
|
|
111
118
|
|
|
112
119
|
// read systemMode to have an initial value
|
package/devices/tuya.js
CHANGED
|
@@ -750,7 +750,8 @@ module.exports = [
|
|
|
750
750
|
{
|
|
751
751
|
zigbeeModel: ['kud7u2l'],
|
|
752
752
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_ckud7u2l'}, {modelID: 'TS0601', manufacturerName: '_TZE200_ywdxldoj'},
|
|
753
|
-
{modelID: 'TS0601', manufacturerName: '_TZE200_cwnjrr72'}, {modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'}
|
|
753
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_cwnjrr72'}, {modelID: 'TS0601', manufacturerName: '_TZE200_chyvmhay'},
|
|
754
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_pvvbommb'}],
|
|
754
755
|
model: 'TS0601_thermostat',
|
|
755
756
|
vendor: 'TuYa',
|
|
756
757
|
description: 'Radiator valve with thermostat',
|
|
@@ -914,11 +915,12 @@ module.exports = [
|
|
|
914
915
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_ew3ldmgx'},
|
|
915
916
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_ps3dmato'},
|
|
916
917
|
{modelID: 'TS011F', manufacturerName: '_TZ3000_mraovvmm'},
|
|
917
|
-
{modelID: 'TS011F', manufacturerName: '_TZ3000_jvzvulen'}
|
|
918
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_jvzvulen'},
|
|
919
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_w0qqde0g'}],
|
|
918
920
|
model: 'TS011F_plug_1',
|
|
919
921
|
description: 'Smart plug (with power monitoring)',
|
|
920
922
|
vendor: 'TuYa',
|
|
921
|
-
whiteLabel: [{vendor: 'LELLKI', model: 'TS011F_plug'}],
|
|
923
|
+
whiteLabel: [{vendor: 'LELLKI', model: 'TS011F_plug'}, {vendor: 'NEO', model: 'NAS-WR01B'}],
|
|
922
924
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory],
|
|
923
925
|
toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
|
|
924
926
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -7,6 +7,22 @@ const ea = exposes.access;
|
|
|
7
7
|
const globalStore = require('../lib/store');
|
|
8
8
|
|
|
9
9
|
module.exports = [
|
|
10
|
+
{
|
|
11
|
+
zigbeeModel: ['URC4470BC0-X-R'],
|
|
12
|
+
model: 'XHS1-UE',
|
|
13
|
+
vendor: 'Universal Electronics Inc',
|
|
14
|
+
description: 'Wireless digital pet resistant PIR detector',
|
|
15
|
+
fromZigbee: [fz.ias_occupancy_alarm_1, fz.temperature, fz.battery],
|
|
16
|
+
toZigbee: [],
|
|
17
|
+
meta: {battery: {voltageToPercentage: '3V_2100'}},
|
|
18
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
19
|
+
const endpoint = device.getEndpoint(1);
|
|
20
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg']);
|
|
21
|
+
await reporting.temperature(endpoint);
|
|
22
|
+
await reporting.batteryVoltage(endpoint);
|
|
23
|
+
},
|
|
24
|
+
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.temperature(), e.battery()],
|
|
25
|
+
},
|
|
10
26
|
{
|
|
11
27
|
zigbeeModel: ['URC4460BC0-X-R'],
|
|
12
28
|
model: 'XHS2-UE',
|
package/devices/xiaomi.js
CHANGED
|
@@ -40,6 +40,15 @@ const preventReset = async (type, data, device) => {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
module.exports = [
|
|
43
|
+
{
|
|
44
|
+
zigbeeModel: ['lumi.magnet.acn001'],
|
|
45
|
+
model: 'MCCGQ14LM',
|
|
46
|
+
vendor: 'Xiaomi',
|
|
47
|
+
description: 'Aqara E1 door & window contact sensor',
|
|
48
|
+
fromZigbee: [fz.ias_contact_alarm_1, fz.aqara_opple_report],
|
|
49
|
+
toZigbee: [],
|
|
50
|
+
exposes: [e.contact(), e.battery(), e.battery_voltage()],
|
|
51
|
+
},
|
|
43
52
|
{
|
|
44
53
|
zigbeeModel: ['lumi.dimmer.rcbac1'],
|
|
45
54
|
model: 'ZNDDMK11LM',
|
|
@@ -1760,4 +1769,24 @@ module.exports = [
|
|
|
1760
1769
|
await endpoint1.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
|
|
1761
1770
|
},
|
|
1762
1771
|
},
|
|
1772
|
+
{
|
|
1773
|
+
zigbeeModel: ['lumi.remote.acn004'],
|
|
1774
|
+
model: 'WXKG17LM',
|
|
1775
|
+
vendor: 'Xiaomi',
|
|
1776
|
+
description: 'Aqara E1 double key wireless switch',
|
|
1777
|
+
meta: {battery: {voltageToPercentage: '3V_2100'}},
|
|
1778
|
+
exposes: [e.battery(), e.battery_voltage(),
|
|
1779
|
+
e.action(['single_left', 'single_right', 'single_both', 'double_left', 'double_right', 'hold_left', 'hold_right']),
|
|
1780
|
+
// eslint-disable-next-line max-len
|
|
1781
|
+
exposes.enum('click_mode', ea.SET, ['fast', 'multi']).withDescription('Click mode, fast: only supports single click which will be send immediately after clicking, multi: supports more events like double and hold'),
|
|
1782
|
+
],
|
|
1783
|
+
fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple_report],
|
|
1784
|
+
toZigbee: [tz.xiaomi_switch_click_mode],
|
|
1785
|
+
onEvent: preventReset,
|
|
1786
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1787
|
+
const endpoint1 = device.getEndpoint(1);
|
|
1788
|
+
// set multiclick mode
|
|
1789
|
+
await endpoint1.write('aqaraOpple', {0x0125: {value: 0x02, type: 0x20}}, {manufacturerCode: 0x115f});
|
|
1790
|
+
},
|
|
1791
|
+
},
|
|
1763
1792
|
];
|
package/lib/exposes.js
CHANGED
|
@@ -477,8 +477,8 @@ module.exports = {
|
|
|
477
477
|
expose_pin: () => new Binary(`expose_pin`, access.SET, true, false).withDescription(`Expose pin of this lock in the published payload (default false).`),
|
|
478
478
|
occupancy_timeout: () => new Numeric(`occupancy_timeout`, access.SET).withValueMin(0).withDescription('Time in seconds after which occupancy is cleared after detecting it (default 90 seconds).'),
|
|
479
479
|
vibration_timeout: () => new Numeric(`vibration_timeout`, access.SET).withValueMin(0).withDescription('Time in seconds after which vibration is cleared after detecting it (default 90 seconds).'),
|
|
480
|
-
simulated_brightness: () => new Composite('simulated_brightness', 'simulated_brightness')
|
|
481
|
-
.withDescription(
|
|
480
|
+
simulated_brightness: (extraNote='') => new Composite('simulated_brightness', 'simulated_brightness')
|
|
481
|
+
.withDescription(`Simulate a brightness value. If this device provides a brightness_move_up or brightness_move_down action it is possible to specify the update interval and delta.${extraNote}`)
|
|
482
482
|
.withFeature(new Numeric('delta', access.SET).withValueMin(0).withDescription('Delta per interval, 20 by default'))
|
|
483
483
|
.withFeature(new Numeric('interval', access.SET).withValueMin(0).withUnit('ms').withDescription('Interval duration')),
|
|
484
484
|
no_occupancy_since: () => new List(`no_occupancy_since`, access.SET).withDescription('Sends a message the last time occupancy was detected. When setting this for example to [10, 60] a `{"no_occupancy_since": 10}` will be send after 10 seconds and a `{"no_occupancy_since": 60}` after 60 seconds.'),
|
package/lib/legacy.js
CHANGED
|
@@ -885,7 +885,7 @@ const fromZigbee = {
|
|
|
885
885
|
cmd_move: {
|
|
886
886
|
cluster: 'genLevelCtrl',
|
|
887
887
|
type: 'commandMove',
|
|
888
|
-
options: [exposes.options.legacy()],
|
|
888
|
+
options: [exposes.options.legacy(), exposes.options.simulated_brightness(' Note: will only work when legacy: false is set.')],
|
|
889
889
|
convert: (model, msg, publish, options, meta) => {
|
|
890
890
|
if (hasAlreadyProcessedMessage(msg)) return;
|
|
891
891
|
if (isLegacyEnabled(options)) {
|
|
@@ -900,7 +900,7 @@ const fromZigbee = {
|
|
|
900
900
|
cmd_move_with_onoff: {
|
|
901
901
|
cluster: 'genLevelCtrl',
|
|
902
902
|
type: 'commandMoveWithOnOff',
|
|
903
|
-
options: [exposes.options.legacy()],
|
|
903
|
+
options: [exposes.options.legacy(), exposes.options.simulated_brightness(' Note: will only work when legacy: false is set.')],
|
|
904
904
|
convert: (model, msg, publish, options, meta) => {
|
|
905
905
|
if (isLegacyEnabled(options)) {
|
|
906
906
|
ictcg1(model, msg, publish, options, 'move');
|
package/lib/reporting.js
CHANGED
|
@@ -148,7 +148,7 @@ module.exports = {
|
|
|
148
148
|
await endpoint.configureReporting('hvacThermostat', p);
|
|
149
149
|
},
|
|
150
150
|
thermostatPIHeatingDemand: async (endpoint, overrides) => {
|
|
151
|
-
const p = payload('pIHeatingDemand', 0, repInterval.
|
|
151
|
+
const p = payload('pIHeatingDemand', 0, repInterval.HOUR, 10, overrides);
|
|
152
152
|
await endpoint.configureReporting('hvacThermostat', p);
|
|
153
153
|
},
|
|
154
154
|
thermostatRunningState: async (endpoint, overrides) => {
|
package/npm-shrinkwrap.json
CHANGED