mirror of
https://github.com/home-assistant/core
synced 2024-10-06 00:24:08 +00:00
Added command templates for the mqtt climate component. (#44976)
This allows integrating with devices which require more complex payloads to be posted when updating their values. Old feature request: https://github.com/home-assistant/core/issues/11496 There are numerous posts requesting this feature, example: https://community.home-assistant.io/t/need-help-with-value-template-for-mqtt-hvac/73395/68https://community.home-assistant.io/t/need-help-with-value-template-for-mqtt-hvac/73395/68 Command templates have been added for the following: - fan_mode - hold - mode - swing_mode - temperature - temperature high/low This doesn't add templates for aux, away mode, power since these already accept custom payload_on/off (although they all share the same payload). It should be straightforward to add templates for them as well if needed.
This commit is contained in:
parent
b1c2cde40b
commit
baab9b9a81
|
@ -55,11 +55,13 @@ ABBREVIATIONS = {
|
|||
"fx_tpl": "effect_template",
|
||||
"fx_val_tpl": "effect_value_template",
|
||||
"exp_aft": "expire_after",
|
||||
"fan_mode_cmd_tpl": "fan_mode_command_template",
|
||||
"fan_mode_cmd_t": "fan_mode_command_topic",
|
||||
"fan_mode_stat_tpl": "fan_mode_state_template",
|
||||
"fan_mode_stat_t": "fan_mode_state_topic",
|
||||
"frc_upd": "force_update",
|
||||
"g_tpl": "green_template",
|
||||
"hold_cmd_tpl": "hold_command_template",
|
||||
"hold_cmd_t": "hold_command_topic",
|
||||
"hold_stat_tpl": "hold_state_template",
|
||||
"hold_stat_t": "hold_state_topic",
|
||||
|
@ -75,6 +77,7 @@ ABBREVIATIONS = {
|
|||
"min_mirs": "min_mireds",
|
||||
"max_temp": "max_temp",
|
||||
"min_temp": "min_temp",
|
||||
"mode_cmd_tpl": "mode_command_template",
|
||||
"mode_cmd_t": "mode_command_topic",
|
||||
"mode_stat_tpl": "mode_state_template",
|
||||
"mode_stat_t": "mode_state_topic",
|
||||
|
@ -151,13 +154,17 @@ ABBREVIATIONS = {
|
|||
"stat_val_tpl": "state_value_template",
|
||||
"stype": "subtype",
|
||||
"sup_feat": "supported_features",
|
||||
"swing_mode_cmd_tpl": "swing_mode_command_template",
|
||||
"swing_mode_cmd_t": "swing_mode_command_topic",
|
||||
"swing_mode_stat_tpl": "swing_mode_state_template",
|
||||
"swing_mode_stat_t": "swing_mode_state_topic",
|
||||
"temp_cmd_tpl": "temperature_command_template",
|
||||
"temp_cmd_t": "temperature_command_topic",
|
||||
"temp_hi_cmd_tpl": "temperature_high_command_template",
|
||||
"temp_hi_cmd_t": "temperature_high_command_topic",
|
||||
"temp_hi_stat_tpl": "temperature_high_state_template",
|
||||
"temp_hi_stat_t": "temperature_high_state_topic",
|
||||
"temp_lo_cmd_tpl": "temperature_low_command_template",
|
||||
"temp_lo_cmd_t": "temperature_low_command_topic",
|
||||
"temp_lo_stat_tpl": "temperature_low_state_template",
|
||||
"temp_lo_stat_t": "temperature_low_state_topic",
|
||||
|
|
|
@ -83,14 +83,17 @@ CONF_AWAY_MODE_STATE_TEMPLATE = "away_mode_state_template"
|
|||
CONF_AWAY_MODE_STATE_TOPIC = "away_mode_state_topic"
|
||||
CONF_CURRENT_TEMP_TEMPLATE = "current_temperature_template"
|
||||
CONF_CURRENT_TEMP_TOPIC = "current_temperature_topic"
|
||||
CONF_FAN_MODE_COMMAND_TEMPLATE = "fan_mode_command_template"
|
||||
CONF_FAN_MODE_COMMAND_TOPIC = "fan_mode_command_topic"
|
||||
CONF_FAN_MODE_LIST = "fan_modes"
|
||||
CONF_FAN_MODE_STATE_TEMPLATE = "fan_mode_state_template"
|
||||
CONF_FAN_MODE_STATE_TOPIC = "fan_mode_state_topic"
|
||||
CONF_HOLD_COMMAND_TEMPLATE = "hold_command_template"
|
||||
CONF_HOLD_COMMAND_TOPIC = "hold_command_topic"
|
||||
CONF_HOLD_STATE_TEMPLATE = "hold_state_template"
|
||||
CONF_HOLD_STATE_TOPIC = "hold_state_topic"
|
||||
CONF_HOLD_LIST = "hold_modes"
|
||||
CONF_MODE_COMMAND_TEMPLATE = "mode_command_template"
|
||||
CONF_MODE_COMMAND_TOPIC = "mode_command_topic"
|
||||
CONF_MODE_LIST = "modes"
|
||||
CONF_MODE_STATE_TEMPLATE = "mode_state_template"
|
||||
|
@ -102,14 +105,18 @@ CONF_POWER_STATE_TEMPLATE = "power_state_template"
|
|||
CONF_POWER_STATE_TOPIC = "power_state_topic"
|
||||
CONF_PRECISION = "precision"
|
||||
CONF_SEND_IF_OFF = "send_if_off"
|
||||
CONF_SWING_MODE_COMMAND_TEMPLATE = "swing_mode_command_template"
|
||||
CONF_SWING_MODE_COMMAND_TOPIC = "swing_mode_command_topic"
|
||||
CONF_SWING_MODE_LIST = "swing_modes"
|
||||
CONF_SWING_MODE_STATE_TEMPLATE = "swing_mode_state_template"
|
||||
CONF_SWING_MODE_STATE_TOPIC = "swing_mode_state_topic"
|
||||
CONF_TEMP_COMMAND_TEMPLATE = "temperature_command_template"
|
||||
CONF_TEMP_COMMAND_TOPIC = "temperature_command_topic"
|
||||
CONF_TEMP_HIGH_COMMAND_TEMPLATE = "temperature_high_command_template"
|
||||
CONF_TEMP_HIGH_COMMAND_TOPIC = "temperature_high_command_topic"
|
||||
CONF_TEMP_HIGH_STATE_TEMPLATE = "temperature_high_state_template"
|
||||
CONF_TEMP_HIGH_STATE_TOPIC = "temperature_high_state_topic"
|
||||
CONF_TEMP_LOW_COMMAND_TEMPLATE = "temperature_low_command_template"
|
||||
CONF_TEMP_LOW_COMMAND_TOPIC = "temperature_low_command_topic"
|
||||
CONF_TEMP_LOW_STATE_TEMPLATE = "temperature_low_state_template"
|
||||
CONF_TEMP_LOW_STATE_TOPIC = "temperature_low_state_topic"
|
||||
|
@ -120,7 +127,7 @@ CONF_TEMP_MAX = "max_temp"
|
|||
CONF_TEMP_MIN = "min_temp"
|
||||
CONF_TEMP_STEP = "temp_step"
|
||||
|
||||
TEMPLATE_KEYS = (
|
||||
VALUE_TEMPLATE_KEYS = (
|
||||
CONF_AUX_STATE_TEMPLATE,
|
||||
CONF_AWAY_MODE_STATE_TEMPLATE,
|
||||
CONF_CURRENT_TEMP_TEMPLATE,
|
||||
|
@ -135,6 +142,16 @@ TEMPLATE_KEYS = (
|
|||
CONF_TEMP_STATE_TEMPLATE,
|
||||
)
|
||||
|
||||
COMMAND_TEMPLATE_KEYS = {
|
||||
CONF_FAN_MODE_COMMAND_TEMPLATE,
|
||||
CONF_HOLD_COMMAND_TEMPLATE,
|
||||
CONF_MODE_COMMAND_TEMPLATE,
|
||||
CONF_SWING_MODE_COMMAND_TEMPLATE,
|
||||
CONF_TEMP_COMMAND_TEMPLATE,
|
||||
CONF_TEMP_HIGH_COMMAND_TEMPLATE,
|
||||
CONF_TEMP_LOW_COMMAND_TEMPLATE,
|
||||
}
|
||||
|
||||
TOPIC_KEYS = (
|
||||
CONF_AUX_COMMAND_TOPIC,
|
||||
CONF_AUX_STATE_TOPIC,
|
||||
|
@ -173,6 +190,7 @@ PLATFORM_SCHEMA = (
|
|||
vol.Optional(CONF_CURRENT_TEMP_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_CURRENT_TEMP_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_DEVICE): MQTT_ENTITY_DEVICE_INFO_SCHEMA,
|
||||
vol.Optional(CONF_FAN_MODE_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_FAN_MODE_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(
|
||||
CONF_FAN_MODE_LIST,
|
||||
|
@ -180,10 +198,12 @@ PLATFORM_SCHEMA = (
|
|||
): cv.ensure_list,
|
||||
vol.Optional(CONF_FAN_MODE_STATE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_FAN_MODE_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_HOLD_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_HOLD_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_HOLD_STATE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_HOLD_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_HOLD_LIST, default=list): cv.ensure_list,
|
||||
vol.Optional(CONF_MODE_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_MODE_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(
|
||||
CONF_MODE_LIST,
|
||||
|
@ -211,6 +231,7 @@ PLATFORM_SCHEMA = (
|
|||
vol.Optional(CONF_SEND_IF_OFF, default=True): cv.boolean,
|
||||
vol.Optional(CONF_ACTION_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_ACTION_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_SWING_MODE_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_SWING_MODE_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(
|
||||
CONF_SWING_MODE_LIST, default=[STATE_ON, HVAC_MODE_OFF]
|
||||
|
@ -221,10 +242,13 @@ PLATFORM_SCHEMA = (
|
|||
vol.Optional(CONF_TEMP_MIN, default=DEFAULT_MIN_TEMP): vol.Coerce(float),
|
||||
vol.Optional(CONF_TEMP_MAX, default=DEFAULT_MAX_TEMP): vol.Coerce(float),
|
||||
vol.Optional(CONF_TEMP_STEP, default=1.0): vol.Coerce(float),
|
||||
vol.Optional(CONF_TEMP_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_TEMP_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_TEMP_HIGH_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_TEMP_HIGH_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_TEMP_HIGH_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_TEMP_HIGH_STATE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_TEMP_LOW_COMMAND_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_TEMP_LOW_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(CONF_TEMP_LOW_STATE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_TEMP_LOW_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
|
@ -282,6 +306,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
self._target_temp_low = None
|
||||
self._topic = None
|
||||
self._value_templates = None
|
||||
self._command_templates = None
|
||||
|
||||
MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
|
||||
|
||||
|
@ -326,21 +351,30 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
self._aux = False
|
||||
|
||||
value_templates = {}
|
||||
for key in TEMPLATE_KEYS:
|
||||
for key in VALUE_TEMPLATE_KEYS:
|
||||
value_templates[key] = lambda value: value
|
||||
if CONF_VALUE_TEMPLATE in config:
|
||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
||||
value_template.hass = self.hass
|
||||
value_templates = {
|
||||
key: value_template.async_render_with_possible_json_value
|
||||
for key in TEMPLATE_KEYS
|
||||
for key in VALUE_TEMPLATE_KEYS
|
||||
}
|
||||
for key in TEMPLATE_KEYS & config.keys():
|
||||
for key in VALUE_TEMPLATE_KEYS & config.keys():
|
||||
tpl = config[key]
|
||||
value_templates[key] = tpl.async_render_with_possible_json_value
|
||||
tpl.hass = self.hass
|
||||
self._value_templates = value_templates
|
||||
|
||||
command_templates = {}
|
||||
for key in COMMAND_TEMPLATE_KEYS:
|
||||
command_templates[key] = lambda value: value
|
||||
for key in COMMAND_TEMPLATE_KEYS & config.keys():
|
||||
tpl = config[key]
|
||||
command_templates[key] = tpl.async_render_with_possible_json_value
|
||||
tpl.hass = self.hass
|
||||
self._command_templates = command_templates
|
||||
|
||||
async def _subscribe_topics(self):
|
||||
"""(Re)Subscribe to topics."""
|
||||
topics = {}
|
||||
|
@ -633,7 +667,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
self._config[CONF_RETAIN],
|
||||
)
|
||||
|
||||
def _set_temperature(self, temp, cmnd_topic, state_topic, attr):
|
||||
def _set_temperature(self, temp, cmnd_topic, cmnd_template, state_topic, attr):
|
||||
if temp is not None:
|
||||
if self._topic[state_topic] is None:
|
||||
# optimistic mode
|
||||
|
@ -643,7 +677,8 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
self._config[CONF_SEND_IF_OFF]
|
||||
or self._current_operation != HVAC_MODE_OFF
|
||||
):
|
||||
self._publish(cmnd_topic, temp)
|
||||
payload = self._command_templates[cmnd_template](temp)
|
||||
self._publish(cmnd_topic, payload)
|
||||
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
"""Set new target temperatures."""
|
||||
|
@ -654,6 +689,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
self._set_temperature(
|
||||
kwargs.get(ATTR_TEMPERATURE),
|
||||
CONF_TEMP_COMMAND_TOPIC,
|
||||
CONF_TEMP_COMMAND_TEMPLATE,
|
||||
CONF_TEMP_STATE_TOPIC,
|
||||
"_target_temp",
|
||||
)
|
||||
|
@ -661,6 +697,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
self._set_temperature(
|
||||
kwargs.get(ATTR_TARGET_TEMP_LOW),
|
||||
CONF_TEMP_LOW_COMMAND_TOPIC,
|
||||
CONF_TEMP_LOW_COMMAND_TEMPLATE,
|
||||
CONF_TEMP_LOW_STATE_TOPIC,
|
||||
"_target_temp_low",
|
||||
)
|
||||
|
@ -668,6 +705,7 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
self._set_temperature(
|
||||
kwargs.get(ATTR_TARGET_TEMP_HIGH),
|
||||
CONF_TEMP_HIGH_COMMAND_TOPIC,
|
||||
CONF_TEMP_HIGH_COMMAND_TEMPLATE,
|
||||
CONF_TEMP_HIGH_STATE_TOPIC,
|
||||
"_target_temp_high",
|
||||
)
|
||||
|
@ -678,7 +716,10 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
async def async_set_swing_mode(self, swing_mode):
|
||||
"""Set new swing mode."""
|
||||
if self._config[CONF_SEND_IF_OFF] or self._current_operation != HVAC_MODE_OFF:
|
||||
self._publish(CONF_SWING_MODE_COMMAND_TOPIC, swing_mode)
|
||||
payload = self._command_templates[CONF_SWING_MODE_COMMAND_TEMPLATE](
|
||||
swing_mode
|
||||
)
|
||||
self._publish(CONF_SWING_MODE_COMMAND_TOPIC, payload)
|
||||
|
||||
if self._topic[CONF_SWING_MODE_STATE_TOPIC] is None:
|
||||
self._current_swing_mode = swing_mode
|
||||
|
@ -687,7 +728,8 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
async def async_set_fan_mode(self, fan_mode):
|
||||
"""Set new target temperature."""
|
||||
if self._config[CONF_SEND_IF_OFF] or self._current_operation != HVAC_MODE_OFF:
|
||||
self._publish(CONF_FAN_MODE_COMMAND_TOPIC, fan_mode)
|
||||
payload = self._command_templates[CONF_FAN_MODE_COMMAND_TEMPLATE](fan_mode)
|
||||
self._publish(CONF_FAN_MODE_COMMAND_TOPIC, payload)
|
||||
|
||||
if self._topic[CONF_FAN_MODE_STATE_TOPIC] is None:
|
||||
self._current_fan_mode = fan_mode
|
||||
|
@ -700,7 +742,8 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
elif self._current_operation != HVAC_MODE_OFF and hvac_mode == HVAC_MODE_OFF:
|
||||
self._publish(CONF_POWER_COMMAND_TOPIC, self._config[CONF_PAYLOAD_OFF])
|
||||
|
||||
self._publish(CONF_MODE_COMMAND_TOPIC, hvac_mode)
|
||||
payload = self._command_templates[CONF_MODE_COMMAND_TEMPLATE](hvac_mode)
|
||||
self._publish(CONF_MODE_COMMAND_TOPIC, payload)
|
||||
|
||||
if self._topic[CONF_MODE_STATE_TOPIC] is None:
|
||||
self._current_operation = hvac_mode
|
||||
|
@ -760,7 +803,10 @@ class MqttClimate(MqttEntity, ClimateEntity):
|
|||
|
||||
Returns if we should optimistically write the state.
|
||||
"""
|
||||
self._publish(CONF_HOLD_COMMAND_TOPIC, hold_mode or "off")
|
||||
payload = self._command_templates[CONF_HOLD_COMMAND_TEMPLATE](
|
||||
hold_mode or "off"
|
||||
)
|
||||
self._publish(CONF_HOLD_COMMAND_TOPIC, payload)
|
||||
|
||||
if self._topic[CONF_HOLD_STATE_TOPIC] is not None:
|
||||
return False
|
||||
|
|
|
@ -644,8 +644,8 @@ async def test_custom_availability_payload(hass, mqtt_mock):
|
|||
)
|
||||
|
||||
|
||||
async def test_set_target_temperature_low_high_with_templates(hass, mqtt_mock, caplog):
|
||||
"""Test setting of temperature high/low templates."""
|
||||
async def test_get_target_temperature_low_high_with_templates(hass, mqtt_mock, caplog):
|
||||
"""Test getting temperature high/low with templates."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||
config["climate"]["temperature_low_state_topic"] = "temperature-state"
|
||||
config["climate"]["temperature_high_state_topic"] = "temperature-state"
|
||||
|
@ -678,8 +678,8 @@ async def test_set_target_temperature_low_high_with_templates(hass, mqtt_mock, c
|
|||
assert state.attributes.get("target_temp_high") == 1032
|
||||
|
||||
|
||||
async def test_set_with_templates(hass, mqtt_mock, caplog):
|
||||
"""Test setting of new fan mode in pessimistic mode."""
|
||||
async def test_get_with_templates(hass, mqtt_mock, caplog):
|
||||
"""Test getting various attributes with templates."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||
# By default, just unquote the JSON-strings
|
||||
config["climate"]["value_template"] = "{{ value_json }}"
|
||||
|
@ -782,6 +782,80 @@ async def test_set_with_templates(hass, mqtt_mock, caplog):
|
|||
assert state.attributes.get("hvac_action") == "cool"
|
||||
|
||||
|
||||
async def test_set_with_templates(hass, mqtt_mock, caplog):
|
||||
"""Test setting various attributes with templates."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||
# Create simple templates
|
||||
config["climate"]["fan_mode_command_template"] = "fan_mode: {{ value }}"
|
||||
config["climate"]["hold_command_template"] = "hold: {{ value }}"
|
||||
config["climate"]["mode_command_template"] = "mode: {{ value }}"
|
||||
config["climate"]["swing_mode_command_template"] = "swing_mode: {{ value }}"
|
||||
config["climate"]["temperature_command_template"] = "temp: {{ value }}"
|
||||
config["climate"]["temperature_high_command_template"] = "temp_hi: {{ value }}"
|
||||
config["climate"]["temperature_low_command_template"] = "temp_lo: {{ value }}"
|
||||
|
||||
assert await async_setup_component(hass, CLIMATE_DOMAIN, config)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Fan Mode
|
||||
await common.async_set_fan_mode(hass, "high", ENTITY_CLIMATE)
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
"fan-mode-topic", "fan_mode: high", 0, False
|
||||
)
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
state = hass.states.get(ENTITY_CLIMATE)
|
||||
assert state.attributes.get("fan_mode") == "high"
|
||||
|
||||
# Hold Mode
|
||||
await common.async_set_preset_mode(hass, PRESET_ECO, ENTITY_CLIMATE)
|
||||
mqtt_mock.async_publish.assert_called_once_with("hold-topic", "hold: eco", 0, False)
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
state = hass.states.get(ENTITY_CLIMATE)
|
||||
assert state.attributes.get("preset_mode") == PRESET_ECO
|
||||
|
||||
# Mode
|
||||
await common.async_set_hvac_mode(hass, "cool", ENTITY_CLIMATE)
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
"mode-topic", "mode: cool", 0, False
|
||||
)
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
state = hass.states.get(ENTITY_CLIMATE)
|
||||
assert state.state == "cool"
|
||||
|
||||
# Swing Mode
|
||||
await common.async_set_swing_mode(hass, "on", ENTITY_CLIMATE)
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
"swing-mode-topic", "swing_mode: on", 0, False
|
||||
)
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
state = hass.states.get(ENTITY_CLIMATE)
|
||||
assert state.attributes.get("swing_mode") == "on"
|
||||
|
||||
# Temperature
|
||||
await common.async_set_temperature(hass, temperature=47, entity_id=ENTITY_CLIMATE)
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
"temperature-topic", "temp: 47.0", 0, False
|
||||
)
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
state = hass.states.get(ENTITY_CLIMATE)
|
||||
assert state.attributes.get("temperature") == 47
|
||||
|
||||
# Temperature Low/High
|
||||
await common.async_set_temperature(
|
||||
hass, target_temp_low=20, target_temp_high=23, entity_id=ENTITY_CLIMATE
|
||||
)
|
||||
mqtt_mock.async_publish.assert_any_call(
|
||||
"temperature-low-topic", "temp_lo: 20.0", 0, False
|
||||
)
|
||||
mqtt_mock.async_publish.assert_any_call(
|
||||
"temperature-high-topic", "temp_hi: 23.0", 0, False
|
||||
)
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
state = hass.states.get(ENTITY_CLIMATE)
|
||||
assert state.attributes.get("target_temp_low") == 20
|
||||
assert state.attributes.get("target_temp_high") == 23
|
||||
|
||||
|
||||
async def test_min_temp_custom(hass, mqtt_mock):
|
||||
"""Test a custom min temp."""
|
||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||
|
|
Loading…
Reference in a new issue