diff --git a/lib/extension/homeassistant.js b/lib/extension/homeassistant.js index 48f3ba60..84061e43 100644 --- a/lib/extension/homeassistant.js +++ b/lib/extension/homeassistant.js @@ -776,6 +776,7 @@ const climate = (minTemp=7, maxTemp=30, temperatureStateProperty='occupied_heati object_id: 'climate', discovery_payload: { state_topic: false, + temperature_unit: 'C', min_temp: `${minTemp}`, max_temp: `${maxTemp}`, mode_state_topic: true, @@ -783,9 +784,6 @@ const climate = (minTemp=7, maxTemp=30, temperatureStateProperty='occupied_heati 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: @@ -813,6 +811,12 @@ const climate = (minTemp=7, maxTemp=30, temperatureStateProperty='occupied_heati retVal.discovery_payload.fan_mode_state_template = `{{ value_json.fan_mode }}`; retVal.discovery_payload.fan_mode_state_topic = true; } + // if no high and low temp used then use temperature_state_topic + if (!temperatureHighStateTopic && !temperatureLowStateTopic) { + retVal.discovery_payload.temperature_state_topic = true; + retVal.discovery_payload.temperature_state_template = `{{ value_json.${temperatureStateProperty} }}`; + retVal.discovery_payload.temperature_command_topic = temperatureStateProperty; + } // use low target temperature if (temperatureLowStateTopic) { retVal.discovery_payload.temperature_low_state_topic = temperatureLowStateTopic; @@ -822,8 +826,8 @@ const climate = (minTemp=7, maxTemp=30, temperatureStateProperty='occupied_heati // use high target temperature if (temperatureHighStateTopic) { retVal.discovery_payload.temperature_high_state_topic = temperatureHighStateTopic; - retVal.discovery_payload.temperature_high_state_template = `{{ value_json.occupied_heating_setpoint }}`; - retVal.discovery_payload.temperature_high_command_topic = 'occupied_heating_setpoint'; + retVal.discovery_payload.temperature_high_state_template = `{{ value_json.occupied_cooling_setpoint }}`; + retVal.discovery_payload.temperature_high_command_topic = 'occupied_cooling_setpoint'; } return retVal; }; @@ -2205,6 +2209,14 @@ class HomeAssistant extends Extension { payload.mode_command_topic = `${stateTopic}/set/system_mode`; } + if (payload.hold_command_topic) { + payload.hold_command_topic = `${stateTopic}/set/preset`; + } + + if (payload.hold_state_topic) { + payload.hold_state_topic = stateTopic; + } + if (payload.current_temperature_topic) { payload.current_temperature_topic = stateTopic; } diff --git a/test/homeassistant.test.js b/test/homeassistant.test.js index 75e16eaf..531559b6 100644 --- a/test/homeassistant.test.js +++ b/test/homeassistant.test.js @@ -426,6 +426,66 @@ describe('HomeAssistant extension', () => { ); }); + it('Should discover thermostat devices', async () => { + controller = new Controller(false); + await controller.start(); + + let payload; + await flushPromises(); + + payload = { + "action_template":"{% set values = {'idle':'off','heat':'heating','cool':'cooling','fan only':'fan'} %}{{ values[value_json.running_state] }}", + "action_topic":"zigbee2mqtt/TS0601_thermostat", + "availability_topic":"zigbee2mqtt/bridge/state", + "current_temperature_template":"{{ value_json.local_temperature }}", + "current_temperature_topic":"zigbee2mqtt/TS0601_thermostat", + "device":{ + "identifiers":[ + "zigbee2mqtt_0x0017882104a44559" + ], + "manufacturer":"TuYa", + "model":"Radiator valve with thermostat (TS0601_thermostat)", + "name":"TS0601_thermostat", + "sw_version": this.version, + }, + "hold_command_topic":"zigbee2mqtt/TS0601_thermostat/set/preset", + "hold_modes":[ + "schedule", + "manual", + "away", + "boost", + "complex", + "comfort", + "eco" + ], + "hold_state_template":"{{ value_json.preset }}", + "hold_state_topic":"zigbee2mqtt/TS0601_thermostat", + "json_attributes_topic":"zigbee2mqtt/TS0601_thermostat", + "max_temp":"30", + "min_temp":"5", + "mode_command_topic":"zigbee2mqtt/TS0601_thermostat/set/system_mode", + "mode_state_template":"{{ value_json.system_mode }}", + "mode_state_topic":"zigbee2mqtt/TS0601_thermostat", + "modes":[ + "auto" + ], + "name":"TS0601_thermostat_climate", + "temp_step":0.5, + "temperature_command_topic":"zigbee2mqtt/TS0601_thermostat/set/current_heating_setpoint", + "temperature_state_template":"{{ value_json.current_heating_setpoint }}", + "temperature_state_topic":"zigbee2mqtt/TS0601_thermostat", + "temperature_unit":"C", + "unique_id":"0x0017882104a44559_climate_zigbee2mqtt" + }; + + expect(MQTT.publish).toHaveBeenCalledWith( + 'homeassistant/climate/0x0017882104a44559/climate/config', + stringify(payload), + { retain: true, qos: 0 }, + expect.any(Function), + ); + }); + it('Should discover devices with cover_position', async () => { controller = new Controller(false); await controller.start(); diff --git a/test/stub/data.js b/test/stub/data.js index b324aea6..7d300a39 100644 --- a/test/stub/data.js +++ b/test/stub/data.js @@ -159,6 +159,9 @@ function writeDefaultConfiguration() { '0x0017880104a44559': { friendly_name: 'J1_cover', }, + '0x0017882104a44559': { + friendly_name: 'TS0601_thermostat', + }, }, groups: { '1': { diff --git a/test/stub/zigbeeHerdsman.js b/test/stub/zigbeeHerdsman.js index 4bde032e..b0d7ac50 100644 --- a/test/stub/zigbeeHerdsman.js +++ b/test/stub/zigbeeHerdsman.js @@ -150,6 +150,7 @@ const devices = { 'U202DST600ZB': new Device('Router', '0x0017880104e43559', 6540,4151, [new Endpoint(10, [0, 6], [], '0x0017880104e43559'), new Endpoint(11, [0, 6], [], '0x0017880104e43559')], true, "Mains (single phase)", 'U202DST600ZB'), '3157100': new Device('Router', '0x0017880104e44559', 6542,4151, [new Endpoint(1, [], [], '0x0017880104e44559')], true, "Mains (single phase)", '3157100'), 'J1': new Device('Router', '0x0017880104a44559', 6543,4151, [new Endpoint(1, [], [], '0x0017880104a44559')], true, "Mains (single phase)", 'J1 (5502)'), + 'TS0601_thermostat': new Device('EndDevice', '0x0017882104a44559', 6544,4151, [new Endpoint(1, [], [], '0x0017882104a44559')], true, "Mains (single phase)", 'kud7u2l'), } const groups = {