zigbee-herdsman-converters 14.0.250 → 14.0.254
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/converters/fromZigbee.js +24 -0
- package/converters/toZigbee.js +30 -6
- package/devices/centralite.js +9 -8
- package/devices/enbrighten.js +12 -0
- package/devices/giderwel.js +11 -0
- package/devices/ikea.js +14 -0
- package/devices/lidl.js +12 -0
- package/devices/neo.js +12 -0
- package/devices/philips.js +28 -2
- package/devices/tuya.js +2 -1
- package/devices/xiaomi.js +5 -4
- package/lib/constants.js +1 -0
- package/lib/exposes.js +2 -2
- package/lib/utils.js +7 -0
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -2177,6 +2177,30 @@ const converters = {
|
|
|
2177
2177
|
return result;
|
|
2178
2178
|
},
|
|
2179
2179
|
},
|
|
2180
|
+
neo_nas_pd07: {
|
|
2181
|
+
cluster: 'manuSpecificTuya',
|
|
2182
|
+
type: ['commandSetDataResponse', 'commandGetData'],
|
|
2183
|
+
convert: (model, msg, publish, options, meta) => {
|
|
2184
|
+
const dp = msg.data.dp;
|
|
2185
|
+
if (dp === 101) return {occupancy: msg.data.data[0] > 0};
|
|
2186
|
+
else if (dp === 102) {
|
|
2187
|
+
const value = msg.data.data[0];
|
|
2188
|
+
return {
|
|
2189
|
+
power_type: {0: 'battery_full', 1: 'battery_high', 2: 'battery_medium', 3: 'battery_low', 4: 'usb'}[value],
|
|
2190
|
+
battery_low: value === 3,
|
|
2191
|
+
};
|
|
2192
|
+
} else if (dp === 103) {
|
|
2193
|
+
return {tamper: msg.data.data[0] > 0 ? true : false};
|
|
2194
|
+
} else if (dp === 104) {
|
|
2195
|
+
const temperature = parseFloat(msg.data.data[3]) / 10.0;
|
|
2196
|
+
return {temperature: calibrateAndPrecisionRoundOptions(temperature, options, 'temperature')};
|
|
2197
|
+
} else if (dp === 105) {
|
|
2198
|
+
return {humidity: calibrateAndPrecisionRoundOptions(msg.data.data[3], options, 'humidity')};
|
|
2199
|
+
} else {
|
|
2200
|
+
meta.logger.warn(`zigbee-herdsman-converters:NEO-PD07: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(msg.data)}`);
|
|
2201
|
+
}
|
|
2202
|
+
},
|
|
2203
|
+
},
|
|
2180
2204
|
neo_t_h_alarm: {
|
|
2181
2205
|
cluster: 'manuSpecificTuya',
|
|
2182
2206
|
type: ['commandSetDataResponse', 'commandGetData'],
|
package/converters/toZigbee.js
CHANGED
|
@@ -1233,7 +1233,13 @@ const converters = {
|
|
|
1233
1233
|
thermostat_occupied_heating_setpoint: {
|
|
1234
1234
|
key: ['occupied_heating_setpoint'],
|
|
1235
1235
|
convertSet: async (entity, key, value, meta) => {
|
|
1236
|
-
|
|
1236
|
+
let result;
|
|
1237
|
+
if (meta.options.thermostat_unit === 'fahrenheit') {
|
|
1238
|
+
result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
|
|
1239
|
+
} else {
|
|
1240
|
+
result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
|
|
1241
|
+
}
|
|
1242
|
+
const occupiedHeatingSetpoint = result;
|
|
1237
1243
|
await entity.write('hvacThermostat', {occupiedHeatingSetpoint});
|
|
1238
1244
|
},
|
|
1239
1245
|
convertGet: async (entity, key, meta) => {
|
|
@@ -1243,7 +1249,13 @@ const converters = {
|
|
|
1243
1249
|
thermostat_unoccupied_heating_setpoint: {
|
|
1244
1250
|
key: ['unoccupied_heating_setpoint'],
|
|
1245
1251
|
convertSet: async (entity, key, value, meta) => {
|
|
1246
|
-
|
|
1252
|
+
let result;
|
|
1253
|
+
if (meta.options.thermostat_unit === 'fahrenheit') {
|
|
1254
|
+
result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
|
|
1255
|
+
} else {
|
|
1256
|
+
result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
|
|
1257
|
+
}
|
|
1258
|
+
const unoccupiedHeatingSetpoint = result;
|
|
1247
1259
|
await entity.write('hvacThermostat', {unoccupiedHeatingSetpoint});
|
|
1248
1260
|
},
|
|
1249
1261
|
convertGet: async (entity, key, meta) => {
|
|
@@ -1253,7 +1265,13 @@ const converters = {
|
|
|
1253
1265
|
thermostat_occupied_cooling_setpoint: {
|
|
1254
1266
|
key: ['occupied_cooling_setpoint'],
|
|
1255
1267
|
convertSet: async (entity, key, value, meta) => {
|
|
1256
|
-
|
|
1268
|
+
let result;
|
|
1269
|
+
if (meta.options.thermostat_unit === 'fahrenheit') {
|
|
1270
|
+
result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
|
|
1271
|
+
} else {
|
|
1272
|
+
result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
|
|
1273
|
+
}
|
|
1274
|
+
const occupiedCoolingSetpoint = result;
|
|
1257
1275
|
await entity.write('hvacThermostat', {occupiedCoolingSetpoint});
|
|
1258
1276
|
},
|
|
1259
1277
|
convertGet: async (entity, key, meta) => {
|
|
@@ -1263,7 +1281,13 @@ const converters = {
|
|
|
1263
1281
|
thermostat_unoccupied_cooling_setpoint: {
|
|
1264
1282
|
key: ['unoccupied_cooling_setpoint'],
|
|
1265
1283
|
convertSet: async (entity, key, value, meta) => {
|
|
1266
|
-
|
|
1284
|
+
let result;
|
|
1285
|
+
if (meta.options.thermostat_unit === 'fahrenheit') {
|
|
1286
|
+
result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
|
|
1287
|
+
} else {
|
|
1288
|
+
result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
|
|
1289
|
+
}
|
|
1290
|
+
const unoccupiedCoolingSetpoint = result;
|
|
1267
1291
|
await entity.write('hvacThermostat', {unoccupiedCoolingSetpoint});
|
|
1268
1292
|
},
|
|
1269
1293
|
convertGet: async (entity, key, meta) => {
|
|
@@ -1989,7 +2013,7 @@ const converters = {
|
|
|
1989
2013
|
xiaomi_led_disabled_night: {
|
|
1990
2014
|
key: ['led_disabled_night'],
|
|
1991
2015
|
convertSet: async (entity, key, value, meta) => {
|
|
1992
|
-
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM'].includes(meta.mapped.model)) {
|
|
2016
|
+
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG25LM'].includes(meta.mapped.model)) {
|
|
1993
2017
|
await entity.write('aqaraOpple', {0x0203: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
1994
2018
|
} else if (['ZNCZ11LM'].includes(meta.mapped.model)) {
|
|
1995
2019
|
const payload = value ?
|
|
@@ -2003,7 +2027,7 @@ const converters = {
|
|
|
2003
2027
|
return {state: {led_disabled_night: value}};
|
|
2004
2028
|
},
|
|
2005
2029
|
convertGet: async (entity, key, meta) => {
|
|
2006
|
-
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM'].includes(meta.mapped.model)) {
|
|
2030
|
+
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG25LM'].includes(meta.mapped.model)) {
|
|
2007
2031
|
await entity.read('aqaraOpple', [0x0203], manufacturerOptions.xiaomi);
|
|
2008
2032
|
} else {
|
|
2009
2033
|
throw new Error('Not supported');
|
package/devices/centralite.js
CHANGED
|
@@ -146,15 +146,16 @@ module.exports = [
|
|
|
146
146
|
vendor: 'Centralite',
|
|
147
147
|
description: '3-Series pearl touch thermostat,',
|
|
148
148
|
fromZigbee: [fz.battery, fz.legacy.thermostat_att_report, fz.fan, fz.ignore_time_read],
|
|
149
|
-
toZigbee: [tz.factory_reset, tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration,
|
|
150
|
-
tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
|
|
151
|
-
tz.
|
|
152
|
-
tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
|
|
153
|
-
tz.
|
|
149
|
+
toZigbee: [tz.factory_reset, tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration,
|
|
150
|
+
tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
|
|
151
|
+
tz.thermostat_setpoint_raise_lower, tz.thermostat_remote_sensing,
|
|
152
|
+
tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
|
|
153
|
+
tz.thermostat_relay_status_log, tz.fan_mode, tz.thermostat_running_state],
|
|
154
154
|
exposes: [e.battery(), exposes.climate().withSetpoint('occupied_heating_setpoint', 10, 30, 1).withLocalTemperature()
|
|
155
|
-
.withSystemMode(['off', 'heat', 'cool'
|
|
156
|
-
.
|
|
157
|
-
|
|
155
|
+
.withSystemMode(['off', 'heat', 'cool', 'emergency_heating'])
|
|
156
|
+
.withRunningState(['idle', 'heat', 'cool', 'fan_only']).withFanMode(['auto', 'on'])
|
|
157
|
+
.withSetpoint('occupied_cooling_setpoint', 10, 30, 1).withLocalTemperatureCalibration()],
|
|
158
|
+
meta: {battery: {voltageToPercentage: '3V_1500_2800'}},
|
|
158
159
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
159
160
|
const endpoint = device.getEndpoint(1);
|
|
160
161
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat', 'hvacFanCtrl']);
|
package/devices/enbrighten.js
CHANGED
|
@@ -88,4 +88,16 @@ module.exports = [
|
|
|
88
88
|
await reporting.onOff(endpoint);
|
|
89
89
|
},
|
|
90
90
|
},
|
|
91
|
+
{
|
|
92
|
+
zigbeeModel: ['43094'],
|
|
93
|
+
model: '43094',
|
|
94
|
+
vendor: 'Enbrighten',
|
|
95
|
+
description: 'Zigbee in-wall smart switch ZB4102',
|
|
96
|
+
extend: extend.switch(),
|
|
97
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
98
|
+
const endpoint = device.getEndpoint(1);
|
|
99
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
100
|
+
await reporting.onOff(endpoint);
|
|
101
|
+
},
|
|
102
|
+
},
|
|
91
103
|
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const extend = require('../lib/extend');
|
|
2
|
+
|
|
3
|
+
module.exports = [
|
|
4
|
+
{
|
|
5
|
+
zigbeeModel: ['A10'],
|
|
6
|
+
model: 'GD-ZCRGB012',
|
|
7
|
+
vendor: 'GIDERWEL',
|
|
8
|
+
description: 'Smart Zigbee RGB LED strip controller',
|
|
9
|
+
extend: extend.light_onoff_brightness_color({supportsHS: false}),
|
|
10
|
+
},
|
|
11
|
+
];
|
package/devices/ikea.js
CHANGED
|
@@ -97,6 +97,13 @@ module.exports = [
|
|
|
97
97
|
description: 'TRADFRI LED globe-bulb E27 470 lumen, dimmable, white spectrum, opal white',
|
|
98
98
|
extend: tradfriExtend.light_onoff_brightness_colortemp(),
|
|
99
99
|
},
|
|
100
|
+
{
|
|
101
|
+
zigbeeModel: ['TRADFRIbulbE27WSglobeopal1055lm'],
|
|
102
|
+
model: 'LED2003G10',
|
|
103
|
+
vendor: 'IKEA',
|
|
104
|
+
description: 'TRADFRI LED bulb E27 1055 lumen, dimmable, white spectrum, opal white',
|
|
105
|
+
extend: tradfriExtend.light_onoff_brightness_colortemp(),
|
|
106
|
+
},
|
|
100
107
|
{
|
|
101
108
|
zigbeeModel: ['TRADFRI bulb E27 opal 470lm', 'TRADFRI bulb E27 W opal 470lm', 'TRADFRIbulbT120E27WSopal470lm'],
|
|
102
109
|
model: 'LED1937T5_E27',
|
|
@@ -227,6 +234,13 @@ module.exports = [
|
|
|
227
234
|
description: 'TRADFRI LED bulb E26/E27 806 lumen, dimmable, white spectrum, clear',
|
|
228
235
|
extend: tradfriExtend.light_onoff_brightness_colortemp(),
|
|
229
236
|
},
|
|
237
|
+
{
|
|
238
|
+
zigbeeModel: ['TRADFRIbulbE14WSglobeopal470lm'],
|
|
239
|
+
model: 'LED2002G5',
|
|
240
|
+
vendor: 'IKEA',
|
|
241
|
+
description: 'TRADFRI LED bulb E14 470 lumen, dimmable, white spectrum, clear',
|
|
242
|
+
extend: tradfriExtend.light_onoff_brightness_colortemp(),
|
|
243
|
+
},
|
|
230
244
|
{
|
|
231
245
|
zigbeeModel: ['LEPTITER Recessed spot light'],
|
|
232
246
|
model: 'T1820',
|
package/devices/lidl.js
CHANGED
|
@@ -245,4 +245,16 @@ module.exports = [
|
|
|
245
245
|
extend: extend.light_onoff_brightness({disableEffect: true}),
|
|
246
246
|
meta: {turnsOffAtBrightness1: false},
|
|
247
247
|
},
|
|
248
|
+
{
|
|
249
|
+
fingerprint: [{modelID: 'TS0101', manufacturerName: '_TZ3000_pnzfdr9y'}],
|
|
250
|
+
model: 'HG06619',
|
|
251
|
+
vendor: 'Lidl',
|
|
252
|
+
description: 'Silvercrest oudoor plug',
|
|
253
|
+
extend: extend.switch(),
|
|
254
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
255
|
+
const endpoint = device.getEndpoint(1);
|
|
256
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
257
|
+
await reporting.onOff(endpoint);
|
|
258
|
+
},
|
|
259
|
+
},
|
|
248
260
|
];
|
package/devices/neo.js
CHANGED
|
@@ -3,6 +3,7 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
|
|
|
3
3
|
const tz = require('../converters/toZigbee');
|
|
4
4
|
const e = exposes.presets;
|
|
5
5
|
const ea = exposes.access;
|
|
6
|
+
const tuya = require('../lib/tuya');
|
|
6
7
|
|
|
7
8
|
module.exports = [
|
|
8
9
|
{
|
|
@@ -27,4 +28,15 @@ module.exports = [
|
|
|
27
28
|
exposes.enum('power_type', ea.STATE, ['battery_full', 'battery_high', 'battery_medium', 'battery_low', 'usb']),
|
|
28
29
|
],
|
|
29
30
|
},
|
|
31
|
+
{
|
|
32
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7hfcudw5'}],
|
|
33
|
+
model: 'NAS-PD07',
|
|
34
|
+
vendor: 'Neo',
|
|
35
|
+
description: 'Motion, temperature & humidity sensor',
|
|
36
|
+
fromZigbee: [fz.neo_nas_pd07],
|
|
37
|
+
toZigbee: [],
|
|
38
|
+
onEvent: tuya.setTime,
|
|
39
|
+
exposes: [e.occupancy(), e.humidity(), e.temperature(), e.tamper(),
|
|
40
|
+
exposes.enum('power_type', ea.STATE, ['battery_full', 'battery_high', 'battery_medium', 'battery_low', 'usb'])],
|
|
41
|
+
},
|
|
30
42
|
];
|
package/devices/philips.js
CHANGED
|
@@ -519,6 +519,15 @@ module.exports = [
|
|
|
519
519
|
extend: hueExtend.light_onoff_brightness_colortemp(),
|
|
520
520
|
ota: ota.zigbeeOTA,
|
|
521
521
|
},
|
|
522
|
+
{
|
|
523
|
+
zigbeeModel: ['LTA008'],
|
|
524
|
+
model: '9290022267A',
|
|
525
|
+
vendor: 'Philips',
|
|
526
|
+
description: 'Hue white ambiance E27 with Bluetooth',
|
|
527
|
+
meta: {turnsOffAtBrightness1: true},
|
|
528
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 434]}),
|
|
529
|
+
ota: ota.zigbeeOTA,
|
|
530
|
+
},
|
|
522
531
|
{
|
|
523
532
|
zigbeeModel: ['LCP003'],
|
|
524
533
|
model: '4090631P7',
|
|
@@ -1065,10 +1074,9 @@ module.exports = [
|
|
|
1065
1074
|
description: 'Hue white ambiance Aurelle square panel light',
|
|
1066
1075
|
meta: {turnsOffAtBrightness1: true},
|
|
1067
1076
|
extend: hueExtend.light_onoff_brightness_colortemp(),
|
|
1068
|
-
ota: ota.zigbeeOTA,
|
|
1069
1077
|
},
|
|
1070
1078
|
{
|
|
1071
|
-
zigbeeModel: ['3216131P6'],
|
|
1079
|
+
zigbeeModel: ['3216131P6', 'LTC005'],
|
|
1072
1080
|
model: '3216131P6',
|
|
1073
1081
|
vendor: 'Philips',
|
|
1074
1082
|
description: 'Hue white ambiance Aurelle square panel light',
|
|
@@ -1985,4 +1993,22 @@ module.exports = [
|
|
|
1985
1993
|
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
1986
1994
|
ota: ota.zigbeeOTA,
|
|
1987
1995
|
},
|
|
1996
|
+
{
|
|
1997
|
+
zigbeeModel: ['LWE003'],
|
|
1998
|
+
model: '9290020400',
|
|
1999
|
+
vendor: 'Philips',
|
|
2000
|
+
description: 'Hue White E17 470 lumen',
|
|
2001
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2002
|
+
extend: hueExtend.light_onoff_brightness(),
|
|
2003
|
+
ota: ota.zigbeeOTA,
|
|
2004
|
+
},
|
|
2005
|
+
{
|
|
2006
|
+
zigbeeModel: ['1746630P7'],
|
|
2007
|
+
model: '1746630P7',
|
|
2008
|
+
vendor: 'Philips',
|
|
2009
|
+
description: 'Hue White and Colour Ambiance Amarant linear outdoor light',
|
|
2010
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2011
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2012
|
+
ota: ota.zigbeeOTA,
|
|
2013
|
+
},
|
|
1988
2014
|
];
|
package/devices/tuya.js
CHANGED
|
@@ -787,7 +787,8 @@ module.exports = [
|
|
|
787
787
|
.withDescription('Recover state after power outage')],
|
|
788
788
|
},
|
|
789
789
|
{
|
|
790
|
-
fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_hyfvrar3'}
|
|
790
|
+
fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_hyfvrar3'},
|
|
791
|
+
{modelID: 'TS011F', manufacturerName: '_TZ3000_dpo1ysak'}],
|
|
791
792
|
model: 'TS011F_plug_2',
|
|
792
793
|
description: 'Smart plug (without power monitoring)',
|
|
793
794
|
vendor: 'TuYa',
|
package/devices/xiaomi.js
CHANGED
|
@@ -544,14 +544,14 @@ module.exports = [
|
|
|
544
544
|
model: 'QBKG25LM',
|
|
545
545
|
vendor: 'Xiaomi',
|
|
546
546
|
description: 'Aqara D1 3 gang smart wall switch (no neutral wire)',
|
|
547
|
-
fromZigbee: [fz.on_off, fz.legacy.QBKG25LM_click, fz.xiaomi_operation_mode_opple],
|
|
548
|
-
toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory, tz.
|
|
547
|
+
fromZigbee: [fz.on_off, fz.legacy.QBKG25LM_click, fz.xiaomi_operation_mode_opple, fz.xiaomi_switch_opple_basic],
|
|
548
|
+
toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night],
|
|
549
549
|
meta: {multiEndpoint: true},
|
|
550
550
|
endpoint: (device) => {
|
|
551
551
|
return {'left': 1, 'center': 2, 'right': 3};
|
|
552
552
|
},
|
|
553
553
|
exposes: [
|
|
554
|
-
e.switch().withEndpoint('left'), e.
|
|
554
|
+
e.switch().withEndpoint('left'), e.switch().withEndpoint('center'), e.switch().withEndpoint('right'),
|
|
555
555
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
556
556
|
.withDescription('Decoupled mode for left button')
|
|
557
557
|
.withEndpoint('left'),
|
|
@@ -561,7 +561,8 @@ module.exports = [
|
|
|
561
561
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
562
562
|
.withDescription('Decoupled mode for right button')
|
|
563
563
|
.withEndpoint('right'),
|
|
564
|
-
e.
|
|
564
|
+
e.power_outage_memory(), e.led_disabled_night(), e.temperature().withAccess(ea.STATE),
|
|
565
|
+
e.action([
|
|
565
566
|
'left_single', 'left_double', 'left_triple', 'left_hold', 'left_release',
|
|
566
567
|
'center_single', 'center_double', 'center_triple', 'center_hold', 'center_release',
|
|
567
568
|
'right_single', 'right_double', 'right_triple', 'right_hold', 'right_release']),
|
package/lib/constants.js
CHANGED
package/lib/exposes.js
CHANGED
|
@@ -361,7 +361,7 @@ class Climate extends Base {
|
|
|
361
361
|
|
|
362
362
|
withSystemMode(modes, access=a.ALL) {
|
|
363
363
|
assert(!this.endpoint, 'Cannot add feature after adding endpoint');
|
|
364
|
-
const allowed = ['off', 'heat', 'cool', 'auto', 'dry', 'fan_only', 'sleep'];
|
|
364
|
+
const allowed = ['off', 'heat', 'cool', 'auto', 'dry', 'fan_only', 'sleep', 'emergency_heating'];
|
|
365
365
|
modes.forEach((m) => assert(allowed.includes(m)));
|
|
366
366
|
this.features.push(new Enum('system_mode', access, modes).withDescription('Mode of this device'));
|
|
367
367
|
return this;
|
|
@@ -369,7 +369,7 @@ class Climate extends Base {
|
|
|
369
369
|
|
|
370
370
|
withRunningState(modes, access=a.STATE_GET) {
|
|
371
371
|
assert(!this.endpoint, 'Cannot add feature after adding endpoint');
|
|
372
|
-
const allowed = ['idle', 'heat', 'cool'];
|
|
372
|
+
const allowed = ['idle', 'heat', 'cool', 'fan_only'];
|
|
373
373
|
modes.forEach((m) => assert(allowed.includes(m)));
|
|
374
374
|
this.features.push(new Enum('running_state', access, modes).withDescription('The current running state'));
|
|
375
375
|
return this;
|
package/lib/utils.js
CHANGED
|
@@ -347,6 +347,12 @@ function validateValue(value, allowed) {
|
|
|
347
347
|
}
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
+
function normalizeCelsiusVersionOfFahrenheit(value) {
|
|
351
|
+
const fahrenheit = (value * 1.8) + 32;
|
|
352
|
+
const roundedFahrenheit = (Math.round((fahrenheit * 2).toFixed(1)) / 2).toFixed(1);
|
|
353
|
+
return ((roundedFahrenheit - 32)/1.8).toFixed(2);
|
|
354
|
+
}
|
|
355
|
+
|
|
350
356
|
module.exports = {
|
|
351
357
|
getOptions,
|
|
352
358
|
isLegacyEnabled,
|
|
@@ -374,4 +380,5 @@ module.exports = {
|
|
|
374
380
|
sleep,
|
|
375
381
|
toSnakeCase,
|
|
376
382
|
toCamelCase,
|
|
383
|
+
normalizeCelsiusVersionOfFahrenheit,
|
|
377
384
|
};
|
package/npm-shrinkwrap.json
CHANGED