Refactor.

This commit is contained in:
Koen Kanters
2020-04-11 20:34:50 +02:00
parent cc008db2ad
commit 9da1a35bbd
2 changed files with 174 additions and 181 deletions
+173 -180
View File
@@ -573,64 +573,6 @@ const cfg = {
},
},
// Thermostat/HVAC
'thermostat': (minTemp=7, maxTemp=30, temperatureStateProperty='occupied_heating_setpoint', tempStep=1) => {
return {
type: 'climate',
object_id: 'climate',
discovery_payload: {
state_topic: false,
min_temp: `${minTemp}`,
max_temp: `${maxTemp}`,
modes: ['off', 'auto', 'heat'],
mode_state_topic: true,
mode_state_template: '{{ value_json.system_mode }}',
mode_command_topic: true,
current_temperature_topic: true,
current_temperature_template: '{{ value_json.local_temperature }}',
temperature_state_topic: true,
temperature_state_template: `{{ value_json.${temperatureStateProperty} }}`,
temperature_command_topic: temperatureStateProperty,
temp_step: tempStep,
action_topic: true,
action_template: '{{ value_json.operation }}',
},
};
},
'thermostat_heatcool': /* istanbul ignore next */ (minTemp=7, maxTemp=30, tempStep=0.5, fanModes=[]) => {
return {
type: 'climate',
object_id: 'climate',
discovery_payload: {
state_topic: false,
unit_of_measurement: '°C',
min_temp: `${minTemp}`,
max_temp: `${maxTemp}`,
modes: ['off', 'auto', 'heat', 'cool'],
mode_state_topic: true,
mode_state_template: '{{ value_json.system_mode }}',
mode_command_topic: true,
current_temperature_topic: true,
current_temperature_template: '{{ value_json.local_temperature }}',
temperature_low_state_topic: true,
temperature_low_state_template: `{{ value_json.occupied_heating_setpoint }}`,
temperature_high_state_topic: true,
temperature_high_state_template: `{{ value_json.occupied_cooling_setpoint }}`,
temperature_low_command_topic: 'occupied_heating_setpoint',
temperature_high_command_topic: 'occupied_cooling_setpoint',
temp_step: tempStep,
action_topic: true,
action_template:
'{% set values = {\'idle\':\'off\',\'heat\':\'heating\',\'cool\':\'cooling\',\'fan only\':\'fan\'}'+
' %}{{ values[value_json.running_state] }}',
fan_modes: fanModes,
fan_mode_command_topic: true,
fan_mode_state_topic: true,
fan_mode_state_template: '{{ value_json.fan_mode }}',
},
};
},
// Fan
'fan': {
type: 'fan',
@@ -664,29 +606,87 @@ const cfg = {
},
};
const switchWithPostfix = (postfix) => {
const switchEndpoint = (endpointName) => {
return {
type: 'switch',
object_id: `switch_${postfix}`,
object_id: `switch_${endpointName}`,
discovery_payload: {
payload_off: 'OFF',
payload_on: 'ON',
value_template: `{{ value_json.state_${postfix} }}`,
value_template: `{{ value_json.state_${endpointName} }}`,
command_topic: true,
command_topic_prefix: postfix,
command_topic_prefix: endpointName,
},
};
};
const lightWithPostfix = (configType, postfix) => {
const lightEndpoint = (configType, endpointName) => {
const config = objectAssignDeep.noMutate(cfg[configType]);
config['object_id'] = `light_${postfix}`;
config['discovery_payload']['command_topic_prefix'] = postfix;
config['discovery_payload']['state_topic_postfix'] = postfix;
config['object_id'] = `light_${endpointName}`;
config['discovery_payload']['command_topic_prefix'] = endpointName;
config['discovery_payload']['state_topic_postfix'] = endpointName;
return config;
};
// Map homeassitant configurations to devices.
const thermostat = (minTemp=7, maxTemp=30, temperatureStateProperty='occupied_heating_setpoint', tempStep=1) => {
return {
type: 'climate',
object_id: 'climate',
discovery_payload: {
state_topic: false,
min_temp: `${minTemp}`,
max_temp: `${maxTemp}`,
modes: ['off', 'auto', 'heat'],
mode_state_topic: true,
mode_state_template: '{{ value_json.system_mode }}',
mode_command_topic: true,
current_temperature_topic: true,
current_temperature_template: '{{ value_json.local_temperature }}',
temperature_state_topic: true,
temperature_state_template: `{{ value_json.${temperatureStateProperty} }}`,
temperature_command_topic: temperatureStateProperty,
temp_step: tempStep,
action_topic: true,
action_template: '{{ value_json.operation }}',
},
};
};
const thermostatHeatCool = /* istanbul ignore next */ (minTemp=7, maxTemp=30, tempStep=0.5, fanModes=[]) => {
return {
type: 'climate',
object_id: 'climate',
discovery_payload: {
state_topic: false,
unit_of_measurement: '°C',
min_temp: `${minTemp}`,
max_temp: `${maxTemp}`,
modes: ['off', 'auto', 'heat', 'cool'],
mode_state_topic: true,
mode_state_template: '{{ value_json.system_mode }}',
mode_command_topic: true,
current_temperature_topic: true,
current_temperature_template: '{{ value_json.local_temperature }}',
temperature_low_state_topic: true,
temperature_low_state_template: `{{ value_json.occupied_heating_setpoint }}`,
temperature_high_state_topic: true,
temperature_high_state_template: `{{ value_json.occupied_cooling_setpoint }}`,
temperature_low_command_topic: 'occupied_heating_setpoint',
temperature_high_command_topic: 'occupied_cooling_setpoint',
temp_step: tempStep,
action_topic: true,
action_template:
'{% set values = {\'idle\':\'off\',\'heat\':\'heating\',\'cool\':\'cooling\',\'fan only\':\'fan\'}'+
' %}{{ values[value_json.running_state] }}',
fan_modes: fanModes,
fan_mode_command_topic: true,
fan_mode_state_topic: true,
fan_mode_state_template: '{{ value_json.fan_mode }}',
},
};
};
// Map Home Assistant configurations to devices.
const mapping = {
'WXKG01LM': [cfg.sensor_click, cfg.sensor_battery],
'WXKG11LM': [cfg.sensor_click, cfg.sensor_battery, cfg.sensor_action],
@@ -695,7 +695,7 @@ const mapping = {
'WXKG03LM': [cfg.sensor_click, cfg.sensor_battery, cfg.sensor_action],
'WXKG02LM': [cfg.sensor_click, cfg.sensor_battery],
'QBKG04LM': [cfg.switch, cfg.sensor_click, cfg.sensor_action],
'QBKG03LM': [switchWithPostfix('left'), switchWithPostfix('right'), cfg.sensor_click, cfg.sensor_temperature],
'QBKG03LM': [switchEndpoint('left'), switchEndpoint('right'), cfg.sensor_click, cfg.sensor_temperature],
'WSDCGQ01LM': [cfg.sensor_temperature, cfg.sensor_humidity, cfg.sensor_battery],
'WSDCGQ11LM': [cfg.sensor_temperature, cfg.sensor_humidity, cfg.sensor_pressure, cfg.sensor_battery],
'RTCGQ01LM': [cfg.binary_sensor_occupancy, cfg.sensor_battery],
@@ -770,7 +770,7 @@ const mapping = {
'AA68199': [cfg.light_brightness_colortemp],
'QBKG11LM': [cfg.switch, cfg.sensor_power, cfg.sensor_click],
'QBKG12LM': [
switchWithPostfix('left'), switchWithPostfix('right'), cfg.sensor_power, cfg.sensor_click,
switchEndpoint('left'), switchEndpoint('right'), cfg.sensor_power, cfg.sensor_click,
cfg.sensor_temperature,
],
'K2RGBW01': [cfg.light_brightness_colortemp_colorxy],
@@ -804,11 +804,11 @@ const mapping = {
'AC03642': [cfg.light_brightness_colortemp],
'AC08560': [cfg.light_brightness],
'AC10786-DIM': [cfg.light_brightness],
'DNCKATSW002': [switchWithPostfix('left'), switchWithPostfix('right')],
'DNCKATSW003': [switchWithPostfix('left'), switchWithPostfix('right'), switchWithPostfix('center')],
'DNCKATSW002': [switchEndpoint('left'), switchEndpoint('right')],
'DNCKATSW003': [switchEndpoint('left'), switchEndpoint('right'), switchEndpoint('center')],
'DNCKATSW004': [
switchWithPostfix('bottom_left'), switchWithPostfix('bottom_right'),
switchWithPostfix('top_left'), switchWithPostfix('top_right'),
switchEndpoint('bottom_left'), switchEndpoint('bottom_right'),
switchEndpoint('top_left'), switchEndpoint('top_right'),
],
'BY 165': [cfg.light_brightness],
'ZLED-2709': [cfg.light_brightness],
@@ -844,7 +844,7 @@ const mapping = {
'53170161': [cfg.light_brightness_colortemp],
'4058075036147': [cfg.light_brightness_colortemp_colorxy],
'KS-SM001': [cfg.switch],
'MG-AUWS01': [switchWithPostfix('left'), switchWithPostfix('right')],
'MG-AUWS01': [switchEndpoint('left'), switchEndpoint('right')],
'9290002579A': [cfg.light_brightness_colortemp_colorxy],
'4256251-RZHAC': [cfg.switch, cfg.sensor_power],
'4257050-ZHAC': [cfg.light_brightness, cfg.sensor_power, cfg.sensor_current, cfg.sensor_voltage],
@@ -893,7 +893,7 @@ const mapping = {
'GL-B-008Z': [cfg.light_brightness_colortemp_colorxy],
'AV2010/25': [cfg.switch, cfg.sensor_power],
'E12-N14': [cfg.light_brightness],
'1TST-EU': [cfg.thermostat(), cfg.sensor_battery],
'1TST-EU': [thermostat(), cfg.sensor_battery],
'RB 178 T': [cfg.light_brightness_colortemp],
'45856GE': [cfg.switch],
'GL-D-003Z': [cfg.light_brightness_colortemp_colorxy],
@@ -904,7 +904,7 @@ const mapping = {
'D1531': [cfg.light_brightness],
'D1532': [cfg.light_brightness],
'D1533': [cfg.light_brightness],
'AV2010/32': [cfg.thermostat(7, 30, 'occupied_heating_setpoint', 0.5), cfg.sensor_battery],
'AV2010/32': [thermostat(7, 30, 'occupied_heating_setpoint', 0.5), cfg.sensor_battery],
'HGZB-07A': [cfg.light_brightness_colortemp_colorxy],
'E1524/E1810': [cfg.sensor_action, cfg.sensor_battery],
'GL-C-006': [cfg.light_brightness_colortemp],
@@ -928,8 +928,8 @@ const mapping = {
'81809': [cfg.light_brightness_colortemp_colorxy],
'4090130P7': [cfg.light_brightness_colortemp_colorxy],
'100.110.39': [cfg.light_brightness_colortemp_colorxy],
'TI0001': [switchWithPostfix('left'), switchWithPostfix('right')],
'SPZB0001': [cfg.thermostat(5, 30, 'current_heating_setpoint', 0.5), cfg.sensor_battery],
'TI0001': [switchEndpoint('left'), switchEndpoint('right')],
'SPZB0001': [thermostat(5, 30, 'current_heating_setpoint', 0.5), cfg.sensor_battery],
'HS3CG': [cfg.binary_sensor_gas],
'81825': [cfg.sensor_action],
'Z809AF': [cfg.switch, cfg.sensor_power],
@@ -950,8 +950,8 @@ const mapping = {
cfg.binary_sensor_occupancy, cfg.sensor_temperature,
cfg.sensor_illuminance, cfg.sensor_illuminance_lux, cfg.sensor_battery,
],
'HGZB-042': [switchWithPostfix('top'), switchWithPostfix('bottom')],
'HGZB-42': [switchWithPostfix('top'), switchWithPostfix('bottom')],
'HGZB-042': [switchEndpoint('top'), switchEndpoint('bottom')],
'HGZB-42': [switchEndpoint('top'), switchEndpoint('bottom')],
'GL-FL-004TZ': [cfg.light_brightness_colortemp_colorxy],
'IM6001-OTP05': [cfg.switch],
'SV01': [
@@ -976,7 +976,7 @@ const mapping = {
],
'9290018195': [cfg.light_brightness],
'HGZB-04D / HGZB-4D-UK': [cfg.light_brightness],
'HGZB-043': [switchWithPostfix('top'), switchWithPostfix('bottom'), switchWithPostfix('center')],
'HGZB-043': [switchEndpoint('top'), switchEndpoint('bottom'), switchEndpoint('center')],
'NCZ-3043-HA': [
cfg.binary_sensor_occupancy, cfg.sensor_temperature,
cfg.sensor_battery, cfg.binary_sensor_battery_low,
@@ -1013,7 +1013,7 @@ const mapping = {
],
'HGZB-1S': [cfg.switch, cfg.sensor_click],
'HGZB-045': [cfg.switch, cfg.sensor_click],
'HGZB-43': [switchWithPostfix('top'), switchWithPostfix('bottom'), switchWithPostfix('center')],
'HGZB-43': [switchEndpoint('top'), switchEndpoint('bottom'), switchEndpoint('center')],
'HGZB-01A': [cfg.switch],
'HGZB-02A': [cfg.light_brightness],
'MCT-350 SMA': [cfg.binary_sensor_contact],
@@ -1041,17 +1041,17 @@ const mapping = {
'RS 122': [cfg.light_brightness],
'GL-B-001Z': [cfg.light_brightness_colortemp_colorxy],
'IM6001-MTP01': [cfg.sensor_temperature, cfg.sensor_battery, cfg.binary_sensor_occupancy],
'U86K31ND6': [switchWithPostfix('left'), switchWithPostfix('right'), switchWithPostfix('center')],
'U86K31ND6': [switchEndpoint('left'), switchEndpoint('right'), switchEndpoint('center')],
'HLD812-Z-SC': [cfg.light_brightness],
'HLC610-Z': [cfg.light_brightness],
'BY 285 C': [cfg.light_brightness_colortemp_colorxy],
'HS1RC-M': [cfg.sensor_action, cfg.sensor_battery],
'SWO-WDS1PA': [cfg.binary_sensor_contact],
'LLKZMK11LM': [
switchWithPostfix('l1'), switchWithPostfix('l2'),
switchEndpoint('l1'), switchEndpoint('l2'),
cfg.sensor_power, cfg.sensor_temperature, cfg.sensor_consumption,
],
'T18W3Z': [switchWithPostfix('l1'), switchWithPostfix('l2'), switchWithPostfix('l3')],
'T18W3Z': [switchEndpoint('l1'), switchEndpoint('l2'), switchEndpoint('l3')],
'LVS-SM10ZW': [cfg.binary_sensor_contact, cfg.binary_sensor_battery_low],
'HS2SK': [cfg.switch, cfg.sensor_power],
'45853GE': [cfg.switch, cfg.sensor_power],
@@ -1107,8 +1107,8 @@ const mapping = {
'ST8AU-CON': [cfg.light_brightness],
'HS3MS': [cfg.binary_sensor_occupancy],
'DIYRUZ_R4_5': [
switchWithPostfix('bottom_left'), switchWithPostfix('bottom_right'), switchWithPostfix('center'),
switchWithPostfix('top_left'), switchWithPostfix('top_right'),
switchEndpoint('bottom_left'), switchEndpoint('bottom_right'), switchEndpoint('center'),
switchEndpoint('top_left'), switchEndpoint('top_right'),
],
'NCZ-3011-HA': [cfg.binary_sensor_contact, cfg.sensor_battery],
'MEAZON_BIZY_PLUG': [cfg.sensor_power, cfg.switch, cfg.sensor_temperature],
@@ -1144,19 +1144,19 @@ const mapping = {
'RH3040': [cfg.sensor_battery, cfg.binary_sensor_occupancy],
'DZ4743-00B': [cfg.switch],
'GLSK3ZB-1711': [cfg.switch],
'GLSK3ZB-1712': [switchWithPostfix('top'), switchWithPostfix('bottom')],
'GLSK3ZB-1713': [switchWithPostfix('top'), switchWithPostfix('center'), switchWithPostfix('bottom')],
'GLSK3ZB-1712': [switchEndpoint('top'), switchEndpoint('bottom')],
'GLSK3ZB-1713': [switchEndpoint('top'), switchEndpoint('center'), switchEndpoint('bottom')],
'GLSK6ZB-1714': [
switchWithPostfix('top_left'), switchWithPostfix('bottom_left'),
switchWithPostfix('top_right'), switchWithPostfix('bottom_right'),
switchEndpoint('top_left'), switchEndpoint('bottom_left'),
switchEndpoint('top_right'), switchEndpoint('bottom_right'),
],
'GLSK6ZB-1715': [
switchWithPostfix('top_left'), switchWithPostfix('center_left'), switchWithPostfix('bottom_left'),
switchWithPostfix('top_right'), switchWithPostfix('bottom_right'),
switchEndpoint('top_left'), switchEndpoint('center_left'), switchEndpoint('bottom_left'),
switchEndpoint('top_right'), switchEndpoint('bottom_right'),
],
'GLSK6ZB-1716': [
switchWithPostfix('top_left'), switchWithPostfix('center_left'), switchWithPostfix('bottom_left'),
switchWithPostfix('top_right'), switchWithPostfix('center_right'), switchWithPostfix('bottom_right'),
switchEndpoint('top_left'), switchEndpoint('center_left'), switchEndpoint('bottom_left'),
switchEndpoint('top_right'), switchEndpoint('center_right'), switchEndpoint('bottom_right'),
],
'3306431P7': [cfg.light_brightness_colortemp],
'AC08559': [cfg.light_brightness_colortemp_colorxy],
@@ -1165,28 +1165,28 @@ const mapping = {
'2AJZ4KPKEY': [cfg.sensor_click, cfg.sensor_battery],
'2AJZ4KPFT': [cfg.sensor_temperature, cfg.sensor_humidity, cfg.sensor_battery],
'TT001ZAV20': [cfg.sensor_temperature, cfg.sensor_humidity, cfg.sensor_battery],
'TS0002': [switchWithPostfix('l1'), switchWithPostfix('l2')],
'TS0002': [switchEndpoint('l1'), switchEndpoint('l2')],
'LVS-SN10ZW': [cfg.sensor_battery, cfg.binary_sensor_occupancy],
'LVS-ZB15R': [cfg.switch],
'TH1123ZB': [
cfg.thermostat(7, 30, 'occupied_heating_setpoint', 1.0), cfg.sensor_local_temperature,
thermostat(7, 30, 'occupied_heating_setpoint', 1.0), cfg.sensor_local_temperature,
cfg.lock_keypad_lockout, cfg.sensor_power,
],
'TH1124ZB': [cfg.thermostat()],
'TH1400ZB': [cfg.thermostat()],
'TH1500ZB': [cfg.thermostat()],
'Zen-01-W': [cfg.thermostat()],
'TH1124ZB': [thermostat()],
'TH1400ZB': [thermostat()],
'TH1500ZB': [thermostat()],
'Zen-01-W': [thermostat()],
'9290022166': [cfg.light_brightness_colortemp_colorxy],
'PM-C140-ZB': [cfg.sensor_power, cfg.switch],
'PM-B530-ZB': [cfg.sensor_power, cfg.switch],
'PM-B430-ZB': [cfg.sensor_power, cfg.switch],
'ptvo.switch': [
switchWithPostfix('bottom_left'), switchWithPostfix('bottom_right'), switchWithPostfix('top_left'),
switchWithPostfix('top_right'), switchWithPostfix('center'), cfg.sensor_click,
switchEndpoint('bottom_left'), switchEndpoint('bottom_right'), switchEndpoint('top_left'),
switchEndpoint('top_right'), switchEndpoint('center'), cfg.sensor_click,
],
'DIYRuZ_R4_5': [
switchWithPostfix('bottom_left'), switchWithPostfix('bottom_right'), switchWithPostfix('top_left'),
switchWithPostfix('top_right'), switchWithPostfix('center'),
switchEndpoint('bottom_left'), switchEndpoint('bottom_right'), switchEndpoint('top_left'),
switchEndpoint('top_right'), switchEndpoint('center'),
],
'DIYRuZ_KEYPAD20': [],
'DTB190502A1': [],
@@ -1199,7 +1199,7 @@ const mapping = {
'B00TN589ZG': [cfg.light_brightness],
'PSB19-SW27': [cfg.light_brightness],
'S1': [cfg.switch, cfg.sensor_power],
'S2': [switchWithPostfix('l1'), switchWithPostfix('l2'), cfg.sensor_power],
'S2': [switchEndpoint('l1'), switchEndpoint('l2'), cfg.sensor_power],
'ZWallRemote0': [cfg.sensor_click],
'D1': [cfg.light_brightness, cfg.sensor_power],
'J1': [cfg.cover_position_tilt, cfg.sensor_power],
@@ -1276,7 +1276,7 @@ const mapping = {
'CR11S8UZ': [cfg.sensor_action],
'RB 148 T': [cfg.light_brightness_colortemp],
'STS-OUT-US-2': [cfg.switch, cfg.sensor_power],
'UK7004240': [cfg.thermostat(), cfg.sensor_battery],
'UK7004240': [thermostat(), cfg.sensor_battery],
'S31ZB': [cfg.switch],
'SA-003-Zigbee': [cfg.switch],
'SZ-DWS04': [cfg.binary_sensor_contact, cfg.sensor_temperature, cfg.sensor_battery],
@@ -1315,10 +1315,10 @@ const mapping = {
'SP-EUC01': [cfg.switch, cfg.sensor_power],
'511.012': [cfg.light_brightness],
'GL-S-008Z': [cfg.light_brightness_colortemp_colorxy],
'TZSW22FW-L4': [switchWithPostfix('top'), switchWithPostfix('bottom')],
'TZSW22FW-L4': [switchEndpoint('top'), switchEndpoint('bottom')],
'GDKES-01TZXD': [cfg.switch],
'GDKES-02TZXD': [switchWithPostfix('left'), switchWithPostfix('right')],
'GDKES-03TZXD': [switchWithPostfix('left'), switchWithPostfix('center'), switchWithPostfix('right')],
'GDKES-02TZXD': [switchEndpoint('left'), switchEndpoint('right')],
'GDKES-03TZXD': [switchEndpoint('left'), switchEndpoint('center'), switchEndpoint('right')],
'6735/6736/6737': [cfg.switch, cfg.sensor_action],
'4034031P7': [cfg.light_brightness_colortemp],
'5900131C5': [cfg.light_brightness_colortemp],
@@ -1344,22 +1344,22 @@ const mapping = {
'E1C-NB6': [cfg.switch],
'LVS-SC7': [cfg.sensor_action],
'1742930P7': [cfg.light_brightness_colortemp_colorxy],
'ZM-L03E-Z': [switchWithPostfix('left'), switchWithPostfix('center'), switchWithPostfix('right')],
'ZM-L03E-Z': [switchEndpoint('left'), switchEndpoint('center'), switchEndpoint('right')],
'DL15S-1BZ': [cfg.switch],
'E1D-G73WNA': [cfg.binary_sensor_contact, cfg.binary_sensor_battery_low],
'WV704R0A0902': [cfg.thermostat()],
'WV704R0A0902': [thermostat()],
'067776': [cfg.cover_position],
'067773': [cfg.sensor_action, cfg.sensor_battery],
'067771': [cfg.switch],
'064873': [cfg.sensor_action],
'K4003C': [cfg.switch],
'STZB402': [
cfg.thermostat(5, 30, 'occupied_heating_setpoint', 0.5),
thermostat(5, 30, 'occupied_heating_setpoint', 0.5),
cfg.sensor_local_temperature,
cfg.lock_keypad_lockout,
],
'SMT402': [
cfg.thermostat(5, 30, 'occupied_heating_setpoint', 0.5),
thermostat(5, 30, 'occupied_heating_setpoint', 0.5),
cfg.sensor_local_temperature,
cfg.lock_keypad_lockout,
],
@@ -1385,14 +1385,14 @@ const mapping = {
'AV2010/21A': [cfg.binary_sensor_battery_low, cfg.binary_sensor_contact, cfg.binary_sensor_tamper],
'AL-PIR02': [cfg.binary_sensor_occupancy, cfg.binary_sensor_tamper, cfg.sensor_battery],
'MKS-CM-W5': [
switchWithPostfix('l1'), switchWithPostfix('l2'),
switchWithPostfix('l3'), switchWithPostfix('l4'),
switchEndpoint('l1'), switchEndpoint('l2'),
switchEndpoint('l3'), switchEndpoint('l4'),
],
'STS-WTR-250': [cfg.binary_sensor_water_leak, cfg.sensor_battery, cfg.sensor_temperature],
'ZG2835RAC': [cfg.light_brightness],
'BW-IS2': [cfg.binary_sensor_contact, cfg.sensor_battery],
'BW-IS3': [cfg.binary_sensor_occupancy],
'SLR1b': [cfg.thermostat()],
'SLR1b': [thermostat()],
'WPT1': [],
'4058075047853': [cfg.light_brightness_colortemp_colorxy],
'ROB_200-003-0': [cfg.switch],
@@ -1431,7 +1431,7 @@ const mapping = {
'GL-D-003ZS': [cfg.light_brightness_colortemp_colorxy],
'66492-001': [cfg.lock, cfg.sensor_battery],
'798.09': [cfg.light_brightness_colortemp_colorxy],
'U202DST600ZB': [lightWithPostfix('light_brightness', 'l1'), lightWithPostfix('light_brightness', 'l2')],
'U202DST600ZB': [lightEndpoint('light_brightness', 'l1'), lightEndpoint('light_brightness', 'l2')],
'SM10ZW': [cfg.binary_sensor_contact, cfg.sensor_battery],
'ICZB-R11D': [cfg.light_brightness],
'SW2500ZB': [cfg.switch],
@@ -1440,8 +1440,8 @@ const mapping = {
'4090331P9': [cfg.light_brightness_colortemp_colorxy],
'HS1EB': [cfg.sensor_click],
'HS2SW1A-N': [cfg.switch],
'HS2SW2A-N': [switchWithPostfix('left'), switchWithPostfix('right')],
'HS2SW3A-N': [switchWithPostfix('left'), switchWithPostfix('right'), switchWithPostfix('center')],
'HS2SW2A-N': [switchEndpoint('left'), switchEndpoint('right')],
'HS2SW3A-N': [switchEndpoint('left'), switchEndpoint('right'), switchEndpoint('center')],
'LifeControl_Leak_Sensor': [cfg.binary_sensor_water_leak, cfg.sensor_battery],
'LifeControl_Door_Sensor': [cfg.binary_sensor_contact, cfg.sensor_battery],
'LifeControl_RGB_Led': [cfg.light_brightness_colortemp_colorxy],
@@ -1449,21 +1449,21 @@ const mapping = {
'ZL1000400-CCT-EU-2-V1A02': [cfg.light_brightness_colortemp],
'ROB_200-007-0': [cfg.sensor_action, cfg.sensor_battery],
'PM-S140-ZB': [cfg.switch],
'PM-S240-ZB': [switchWithPostfix('top'), switchWithPostfix('bottom')],
'PM-S340-ZB': [switchWithPostfix('top'), switchWithPostfix('center'), switchWithPostfix('bottom')],
'PM-S240-ZB': [switchEndpoint('top'), switchEndpoint('bottom')],
'PM-S340-ZB': [switchEndpoint('top'), switchEndpoint('center'), switchEndpoint('bottom')],
'U201DST600ZB': [cfg.light_brightness],
'U201SRY2KWZB': [cfg.switch],
'U202SRY2KWZB': [switchWithPostfix('l1'), switchWithPostfix('l2')],
'U202SRY2KWZB': [switchEndpoint('l1'), switchEndpoint('l2')],
'93999': [cfg.light_brightness],
'ZHS-15': [cfg.switch, cfg.sensor_power, cfg.sensor_current, cfg.sensor_voltage],
'GS361A-H04': [
cfg.lock_child_lock,
cfg.switch_window_detection,
cfg.switch_valve_detection,
cfg.thermostat(5, 30, 'current_heating_setpoint', 0.5),
thermostat(5, 30, 'current_heating_setpoint', 0.5),
cfg.sensor_battery,
],
'HLC614-ZLL': [switchWithPostfix('l1'), switchWithPostfix('l2'), switchWithPostfix('l3')],
'HLC614-ZLL': [switchEndpoint('l1'), switchEndpoint('l2'), switchEndpoint('l3')],
'EMIZB-132': [
cfg.sensor_power, cfg.sensor_voltage, cfg.sensor_current, cfg.sensor_energy, cfg.sensor_current_phase_b,
cfg.sensor_current_phase_c, cfg.sensor_voltage_phase_b, cfg.sensor_voltage_phase_c,
@@ -1489,22 +1489,22 @@ const mapping = {
'SWA01ZB': [cfg.binary_sensor_water_leak, cfg.sensor_battery],
'SDM01ZB': [cfg.binary_sensor_contact, cfg.sensor_battery],
'SFS01ZB': [cfg.switch],
'SLS301ZB_2': [switchWithPostfix('left'), switchWithPostfix('right')],
'SLS301ZB_3': [switchWithPostfix('left'), switchWithPostfix('right'), switchWithPostfix('center')],
'SLS301ZB_2': [switchEndpoint('left'), switchEndpoint('right')],
'SLS301ZB_3': [switchEndpoint('left'), switchEndpoint('right'), switchEndpoint('center')],
'SSS401ZB': [cfg.switch, cfg.sensor_action],
'E12-N1E': [cfg.light_brightness_colortemp_colorxy],
'4040B': [cfg.sensor_power, switchWithPostfix('l1'), switchWithPostfix('l2')],
'4040B': [cfg.sensor_power, switchEndpoint('l1'), switchEndpoint('l2')],
'3460-L': [cfg.sensor_action, cfg.sensor_temperature, cfg.sensor_battery],
'3157100': [cfg.thermostat_heatcool(10, 30, 1, ['auto', 'on']), cfg.sensor_battery],
'3157100': [thermostatHeatCool(10, 30, 1, ['auto', 'on']), cfg.sensor_battery],
'4257050-RZHAC': [cfg.switch, cfg.sensor_power],
'27087-03': [cfg.switch, cfg.sensor_battery],
'99140-002': [cfg.lock, cfg.sensor_battery],
'4512706': [cfg.sensor_battery, cfg.sensor_action],
'GL-S-004ZS': [cfg.light_brightness_colortemp_colorxy],
'7121131PU': [cfg.light_brightness_colortemp_colorxy],
'RL804QZB': [switchWithPostfix('l1'), switchWithPostfix('l2'), switchWithPostfix('l3')],
'RC-2000WH': [cfg.thermostat_heatcool(10, 30, 1, ['auto', 'on', 'smart'])],
'TH1300ZB': [cfg.thermostat()],
'RL804QZB': [switchEndpoint('l1'), switchEndpoint('l2'), switchEndpoint('l3')],
'RC-2000WH': [thermostatHeatCool(10, 30, 1, ['auto', 'on', 'smart'])],
'TH1300ZB': [thermostat()],
'SP 220': [cfg.switch],
'511.040': [cfg.light_brightness_colortemp_colorxy],
'511.344': [cfg.sensor_battery, cfg.sensor_action, cfg.sensor_action_color],
@@ -1521,10 +1521,6 @@ const mapping = {
'AU-A1GSZ9RGBW': [cfg.light_brightness_colortemp_colorxy],
};
Object.keys(mapping).forEach((key) => {
mapping[key].push(cfg.sensor_linkquality);
});
/**
* This extensions handles integration with HomeAssistant
*/
@@ -1553,10 +1549,10 @@ class HomeAssistant extends Extension {
}
onDeviceRemoved(device) {
const mappedModel = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
if (mappedModel) {
const definition = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
if (definition) {
logger.info(`Clearing Home Assistant discovery topic for '${device.ieeeAddr}'`);
this.getConfigs(mappedModel).forEach((config) => {
this.getConfigs(definition).forEach((config) => {
const topic = this.getDiscoveryTopic(config, device);
this.mqtt.publish(topic, null, {retain: true, qos: 0}, this.discoveryTopic);
});
@@ -1565,7 +1561,7 @@ class HomeAssistant extends Extension {
async onPublishEntityState(data) {
/**
* In case we deal with a lightWithPostfix configuration Zigbee2mqtt publishes
* In case we deal with a lightEndpoint configuration Zigbee2mqtt publishes
* e.g. {state_l1: ON, brightness_l1: 250} to zigbee2mqtt/mydevice.
* As the Home Assistant MQTT JSON light cannot be configured to use state_l1/brightness_l1
* as the state variables, the state topic is set to zigbee2mqtt/mydevice/l1.
@@ -1576,18 +1572,18 @@ class HomeAssistant extends Extension {
for (const config of mapping[data.entity.definition.model]) {
const match = /light_(.*)/.exec(config['object_id']);
if (match) {
const postfix = match[1];
const posfixRegExp = new RegExp(`(.*)_${postfix}`);
const endpoint = match[1];
const endpointRegExp = new RegExp(`(.*)_${endpoint}`);
const payload = {};
for (const key of Object.keys(data.payload)) {
const keyMatch = posfixRegExp.exec(key);
const keyMatch = endpointRegExp.exec(key);
if (keyMatch) {
payload[keyMatch[1]] = data.payload[key];
}
}
await this.mqtt.publish(
`${data.entity.name}/${postfix}`, JSON.stringify(payload), {},
`${data.entity.name}/${endpoint}`, JSON.stringify(payload), {},
);
}
}
@@ -1618,7 +1614,7 @@ class HomeAssistant extends Extension {
subtype: value,
payload: value,
topic: `${settings.get().mqtt.base_topic}/${data.entity.name}/${key}`,
device: this.getDevicePayload(data.entity.settings, data.entity.definition),
device: this.getDevicePayload(data.entity),
};
await this.mqtt.publish(topic, JSON.stringify(payload), {retain: true, qos: 0}, this.discoveryTopic);
@@ -1655,9 +1651,9 @@ class HomeAssistant extends Extension {
}
onDeviceRenamed(device) {
const mappedModel = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
const resolvedEntity = this.zigbee.resolveEntity(device);
logger.info(`Refreshing Home Assistant discovery topic for '${device.ieeeAddr}'`);
this.discover(device, mappedModel, true);
this.discover(resolvedEntity, true);
}
async onMQTTConnected() {
@@ -1665,15 +1661,15 @@ class HomeAssistant extends Extension {
// MQTT discovery of all paired devices on startup.
for (const device of this.zigbee.getClients()) {
const mappedModel = zigbeeHerdsmanConverters.findByZigbeeModel(device.modelID);
if (mappedModel) {
this.discover(device, mappedModel, true);
}
const resolvedEntity = this.zigbee.resolveEntity(device);
this.discover(resolvedEntity, true);
}
}
getConfigs(mappedModel) {
let configs = mapping[mappedModel.model].slice();
configs.push(cfg.sensor_linkquality);
if (mappedModel.hasOwnProperty('ota')) {
configs.push(cfg.binary_sensor_update_available);
}
@@ -1685,23 +1681,21 @@ class HomeAssistant extends Extension {
return configs;
}
discover(device, mappedModel, force=false) {
discover(resolvedEntity, force=false) {
// Check if already discoverd and check if there are configs.
const {device, definition} = resolvedEntity;
const deviceSettings = resolvedEntity.settings;
const discover = force || !this.discovered[device.ieeeAddr];
if (!discover) {
if (!discover || !device || !definition || !mapping[definition.model] || !deviceSettings ||
(deviceSettings.hasOwnProperty('homeassistant') && !deviceSettings.homeassistant)) {
return;
}
const entity = settings.getEntity(device.ieeeAddr);
if (!entity || (entity.type === 'device' && !mapping[mappedModel.model]) ||
(entity.hasOwnProperty('homeassistant') && !entity.homeassistant)) {
return;
}
this.getConfigs(mappedModel).forEach((config) => {
const friendlyName = deviceSettings.friendlyName;
this.getConfigs(definition).forEach((config) => {
const topic = this.getDiscoveryTopic(config, device);
const payload = {...config.discovery_payload};
let stateTopic = `${settings.get().mqtt.base_topic}/${entity.friendlyName}`;
let stateTopic = `${settings.get().mqtt.base_topic}/${deviceSettings.friendlyName}`;
if (payload.state_topic_postfix) {
stateTopic += `/${payload.state_topic_postfix}`;
delete payload.state_topic_postfix;
@@ -1727,26 +1721,26 @@ class HomeAssistant extends Extension {
payload.json_attributes_topic = stateTopic;
// Set (unique) name
payload.name = `${entity.friendlyName}_${config.object_id}`;
payload.name = `${friendlyName}_${config.object_id}`;
// Set unique_id
payload.unique_id = `${entity.ID}_${config.object_id}_${settings.get().mqtt.base_topic}`;
payload.unique_id = `${deviceSettings.ID}_${config.object_id}_${settings.get().mqtt.base_topic}`;
// Attributes for device registry
payload.device = this.getDevicePayload(entity, mappedModel);
payload.device = this.getDevicePayload(resolvedEntity);
// Set availability payload
// When using availability_timeout each device has it's own availability topic.
// If not, use the availability topic of zigbee2mqtt.
if (settings.get().advanced.availability_timeout) {
payload.availability_topic = `${settings.get().mqtt.base_topic}/${entity.friendlyName}/availability`;
payload.availability_topic = `${settings.get().mqtt.base_topic}/${friendlyName}/availability`;
} else {
payload.availability_topic = `${settings.get().mqtt.base_topic}/bridge/state`;
}
// Add precision to value_template
if (entity.hasOwnProperty(`${config.object_id}_precision`)) {
const precision = entity[`${config.object_id}_precision`];
if (deviceSettings.hasOwnProperty(`${config.object_id}_precision`)) {
const precision = deviceSettings[`${config.object_id}_precision`];
let template = payload.value_template;
template = template.replace('{{ ', '').replace(' }}', '');
template = `{{ (${template} | float) | round(${precision}) }}`;
@@ -1754,7 +1748,7 @@ class HomeAssistant extends Extension {
}
if (payload.command_topic) {
payload.command_topic = `${settings.get().mqtt.base_topic}/${entity.friendlyName}/`;
payload.command_topic = `${settings.get().mqtt.base_topic}/${friendlyName}/`;
if (payload.command_topic_prefix) {
payload.command_topic += `${payload.command_topic_prefix}/`;
@@ -1836,7 +1830,7 @@ class HomeAssistant extends Extension {
}
// Override configuration with user settings.
if (entity.hasOwnProperty('homeassistant')) {
if (deviceSettings.hasOwnProperty('homeassistant')) {
const add = (obj) => {
Object.keys(obj).forEach((key) => {
if (['number', 'string', 'boolean'].includes(typeof obj[key])) {
@@ -1851,10 +1845,10 @@ class HomeAssistant extends Extension {
});
};
add(entity.homeassistant);
add(deviceSettings.homeassistant);
if (entity.homeassistant.hasOwnProperty(config.object_id)) {
add(entity.homeassistant[config.object_id]);
if (deviceSettings.homeassistant.hasOwnProperty(config.object_id)) {
add(deviceSettings.homeassistant[config.object_id]);
}
}
@@ -1884,19 +1878,18 @@ class HomeAssistant extends Extension {
}
onZigbeeEvent(type, data, resolvedEntity) {
const device = data.device;
if (device && resolvedEntity && resolvedEntity.definition) {
this.discover(device, resolvedEntity.definition);
if (resolvedEntity && type !== 'deviceLeave') {
this.discover(resolvedEntity);
}
}
getDevicePayload(entity, mappedModel) {
getDevicePayload(resolvedEntity) {
return {
identifiers: [`zigbee2mqtt_${entity.ID}`],
name: entity.friendlyName,
identifiers: [`zigbee2mqtt_${resolvedEntity.settings.ID}`],
name: resolvedEntity.settings.friendlyName,
sw_version: `Zigbee2mqtt ${zigbee2mqttVersion}`,
model: `${mappedModel.description} (${mappedModel.model})`,
manufacturer: mappedModel.vendor,
model: `${resolvedEntity.definition.description} (${resolvedEntity.definition.model})`,
manufacturer: resolvedEntity.definition.vendor,
};
}
+1 -1
View File
@@ -558,7 +558,7 @@ describe('HomeAssistant extension', () => {
);
});
it('Shouldnt discover when message has no device yet', async () => {
it('Shouldnt discover when device leaves', async () => {
controller = new Controller();
await controller.start();
await flushPromises();