mirror of
https://github.com/home-assistant/core.git
synced 2026-04-02 00:20:30 +01:00
Add some water heater triggers (#164864)
Co-authored-by: Erik Montnemery <erik@montnemery.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -176,6 +176,7 @@ _EXPERIMENTAL_TRIGGER_PLATFORMS = {
|
||||
"text",
|
||||
"update",
|
||||
"vacuum",
|
||||
"water_heater",
|
||||
"window",
|
||||
}
|
||||
|
||||
|
||||
@@ -37,5 +37,19 @@
|
||||
"turn_on": {
|
||||
"service": "mdi:water-boiler"
|
||||
}
|
||||
},
|
||||
"triggers": {
|
||||
"target_temperature_changed": {
|
||||
"trigger": "mdi:thermometer"
|
||||
},
|
||||
"target_temperature_crossed_threshold": {
|
||||
"trigger": "mdi:thermometer"
|
||||
},
|
||||
"turned_off": {
|
||||
"trigger": "mdi:water-boiler-off"
|
||||
},
|
||||
"turned_on": {
|
||||
"trigger": "mdi:water-boiler"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
{
|
||||
"common": {
|
||||
"trigger_behavior_description": "The behavior of the targeted water heaters to trigger on.",
|
||||
"trigger_behavior_name": "Behavior"
|
||||
},
|
||||
"device_automation": {
|
||||
"action_type": {
|
||||
"turn_off": "[%key:common::device_automation::action_type::turn_off%]",
|
||||
@@ -54,6 +58,29 @@
|
||||
"message": "Operation mode {operation_mode} is not valid for {entity_id}. The operation list is not defined."
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"number_or_entity": {
|
||||
"choices": {
|
||||
"entity": "Entity",
|
||||
"number": "Number"
|
||||
}
|
||||
},
|
||||
"trigger_behavior": {
|
||||
"options": {
|
||||
"any": "Any",
|
||||
"first": "First",
|
||||
"last": "Last"
|
||||
}
|
||||
},
|
||||
"trigger_threshold_type": {
|
||||
"options": {
|
||||
"above": "Above a value",
|
||||
"below": "Below a value",
|
||||
"between": "In a range",
|
||||
"outside": "Outside a range"
|
||||
}
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"set_away_mode": {
|
||||
"description": "Turns away mode on/off.",
|
||||
@@ -98,5 +125,71 @@
|
||||
"name": "[%key:common::action::turn_on%]"
|
||||
}
|
||||
},
|
||||
"title": "Water heater"
|
||||
"title": "Water heater",
|
||||
"triggers": {
|
||||
"target_temperature_changed": {
|
||||
"description": "Triggers after the temperature setpoint of one or more water heaters changes.",
|
||||
"fields": {
|
||||
"above": {
|
||||
"description": "Trigger when the target temperature is above this value.",
|
||||
"name": "Above"
|
||||
},
|
||||
"below": {
|
||||
"description": "Trigger when the target temperature is below this value.",
|
||||
"name": "Below"
|
||||
},
|
||||
"unit": {
|
||||
"description": "All values will be converted to this unit when evaluating the trigger.",
|
||||
"name": "Unit of measurement"
|
||||
}
|
||||
},
|
||||
"name": "Water heater target temperature changed"
|
||||
},
|
||||
"target_temperature_crossed_threshold": {
|
||||
"description": "Triggers after the temperature setpoint of one or more water heaters crosses a threshold.",
|
||||
"fields": {
|
||||
"behavior": {
|
||||
"description": "[%key:component::water_heater::common::trigger_behavior_description%]",
|
||||
"name": "[%key:component::water_heater::common::trigger_behavior_name%]"
|
||||
},
|
||||
"lower_limit": {
|
||||
"description": "Lower threshold limit.",
|
||||
"name": "Lower threshold"
|
||||
},
|
||||
"threshold_type": {
|
||||
"description": "Type of threshold crossing to trigger on.",
|
||||
"name": "Threshold type"
|
||||
},
|
||||
"unit": {
|
||||
"description": "[%key:component::water_heater::triggers::target_temperature_changed::fields::unit::description%]",
|
||||
"name": "[%key:component::water_heater::triggers::target_temperature_changed::fields::unit::name%]"
|
||||
},
|
||||
"upper_limit": {
|
||||
"description": "Upper threshold limit.",
|
||||
"name": "Upper threshold"
|
||||
}
|
||||
},
|
||||
"name": "Water heater target temperature crossed threshold"
|
||||
},
|
||||
"turned_off": {
|
||||
"description": "Triggers after one or more water heaters turn off.",
|
||||
"fields": {
|
||||
"behavior": {
|
||||
"description": "[%key:component::water_heater::common::trigger_behavior_description%]",
|
||||
"name": "[%key:component::water_heater::common::trigger_behavior_name%]"
|
||||
}
|
||||
},
|
||||
"name": "Water heater turned off"
|
||||
},
|
||||
"turned_on": {
|
||||
"description": "Triggers after one or more water heaters turn on, regardless of the operation mode.",
|
||||
"fields": {
|
||||
"behavior": {
|
||||
"description": "[%key:component::water_heater::common::trigger_behavior_description%]",
|
||||
"name": "[%key:component::water_heater::common::trigger_behavior_name%]"
|
||||
}
|
||||
},
|
||||
"name": "Water heater turned on"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
58
homeassistant/components/water_heater/trigger.py
Normal file
58
homeassistant/components/water_heater/trigger.py
Normal file
@@ -0,0 +1,58 @@
|
||||
"""Provides triggers for water heaters."""
|
||||
|
||||
from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
from homeassistant.helpers.automation import NumericalDomainSpec
|
||||
from homeassistant.helpers.trigger import (
|
||||
EntityNumericalStateChangedTriggerWithUnitBase,
|
||||
EntityNumericalStateCrossedThresholdTriggerWithUnitBase,
|
||||
EntityNumericalStateTriggerWithUnitBase,
|
||||
Trigger,
|
||||
make_entity_origin_state_trigger,
|
||||
make_entity_target_state_trigger,
|
||||
)
|
||||
from homeassistant.util.unit_conversion import TemperatureConverter
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
class _WaterHeaterTargetTemperatureTriggerMixin(
|
||||
EntityNumericalStateTriggerWithUnitBase
|
||||
):
|
||||
"""Mixin for water heater target temperature triggers with unit conversion."""
|
||||
|
||||
_base_unit = UnitOfTemperature.CELSIUS
|
||||
_domain_specs = {DOMAIN: NumericalDomainSpec(value_source=ATTR_TEMPERATURE)}
|
||||
_unit_converter = TemperatureConverter
|
||||
|
||||
def _get_entity_unit(self, state: State) -> str | None:
|
||||
"""Get the temperature unit of a water heater entity from its state."""
|
||||
# Water heater entities convert temperatures to the system unit via show_temp
|
||||
return self._hass.config.units.temperature_unit
|
||||
|
||||
|
||||
class WaterHeaterTargetTemperatureChangedTrigger(
|
||||
_WaterHeaterTargetTemperatureTriggerMixin,
|
||||
EntityNumericalStateChangedTriggerWithUnitBase,
|
||||
):
|
||||
"""Trigger for water heater target temperature value changes."""
|
||||
|
||||
|
||||
class WaterHeaterTargetTemperatureCrossedThresholdTrigger(
|
||||
_WaterHeaterTargetTemperatureTriggerMixin,
|
||||
EntityNumericalStateCrossedThresholdTriggerWithUnitBase,
|
||||
):
|
||||
"""Trigger for water heater target temperature value crossing a threshold."""
|
||||
|
||||
|
||||
TRIGGERS: dict[str, type[Trigger]] = {
|
||||
"target_temperature_changed": WaterHeaterTargetTemperatureChangedTrigger,
|
||||
"target_temperature_crossed_threshold": WaterHeaterTargetTemperatureCrossedThresholdTrigger,
|
||||
"turned_off": make_entity_target_state_trigger(DOMAIN, STATE_OFF),
|
||||
"turned_on": make_entity_origin_state_trigger(DOMAIN, from_state=STATE_OFF),
|
||||
}
|
||||
|
||||
|
||||
async def async_get_triggers(hass: HomeAssistant) -> dict[str, type[Trigger]]:
|
||||
"""Return the triggers for water heaters."""
|
||||
return TRIGGERS
|
||||
77
homeassistant/components/water_heater/triggers.yaml
Normal file
77
homeassistant/components/water_heater/triggers.yaml
Normal file
@@ -0,0 +1,77 @@
|
||||
.trigger_common: &trigger_common
|
||||
target: &trigger_water_heater_target
|
||||
entity:
|
||||
domain: water_heater
|
||||
fields:
|
||||
behavior: &trigger_behavior
|
||||
required: true
|
||||
default: any
|
||||
selector:
|
||||
select:
|
||||
translation_key: trigger_behavior
|
||||
options:
|
||||
- first
|
||||
- last
|
||||
- any
|
||||
|
||||
.trigger_threshold_type: &trigger_threshold_type
|
||||
required: true
|
||||
default: above
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- above
|
||||
- below
|
||||
- between
|
||||
- outside
|
||||
translation_key: trigger_threshold_type
|
||||
|
||||
.number_or_entity_temperature: &number_or_entity_temperature
|
||||
required: false
|
||||
selector:
|
||||
choose:
|
||||
choices:
|
||||
number:
|
||||
selector:
|
||||
number:
|
||||
mode: box
|
||||
entity:
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- domain: input_number
|
||||
unit_of_measurement:
|
||||
- "°C"
|
||||
- "°F"
|
||||
- domain: sensor
|
||||
device_class: temperature
|
||||
- domain: number
|
||||
device_class: temperature
|
||||
translation_key: number_or_entity
|
||||
|
||||
.trigger_unit_temperature: &trigger_unit_temperature
|
||||
required: false
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- "°C"
|
||||
- "°F"
|
||||
|
||||
turned_off: *trigger_common
|
||||
turned_on: *trigger_common
|
||||
|
||||
target_temperature_changed:
|
||||
target: *trigger_water_heater_target
|
||||
fields:
|
||||
above: *number_or_entity_temperature
|
||||
below: *number_or_entity_temperature
|
||||
unit: *trigger_unit_temperature
|
||||
|
||||
target_temperature_crossed_threshold:
|
||||
target: *trigger_water_heater_target
|
||||
fields:
|
||||
behavior: *trigger_behavior
|
||||
threshold_type: *trigger_threshold_type
|
||||
lower_limit: *number_or_entity_temperature
|
||||
upper_limit: *number_or_entity_temperature
|
||||
unit: *trigger_unit_temperature
|
||||
327
tests/components/water_heater/test_trigger.py
Normal file
327
tests/components/water_heater/test_trigger.py
Normal file
@@ -0,0 +1,327 @@
|
||||
"""Test water heater trigger."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.water_heater import (
|
||||
STATE_ECO,
|
||||
STATE_ELECTRIC,
|
||||
STATE_GAS,
|
||||
STATE_HEAT_PUMP,
|
||||
STATE_HIGH_DEMAND,
|
||||
STATE_PERFORMANCE,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, STATE_OFF, STATE_ON, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant, ServiceCall
|
||||
|
||||
from tests.components.common import (
|
||||
TriggerStateDescription,
|
||||
assert_trigger_behavior_any,
|
||||
assert_trigger_behavior_first,
|
||||
assert_trigger_behavior_last,
|
||||
assert_trigger_gated_by_labs_flag,
|
||||
parametrize_numerical_attribute_changed_trigger_states,
|
||||
parametrize_numerical_attribute_crossed_threshold_trigger_states,
|
||||
parametrize_target_entities,
|
||||
parametrize_trigger_states,
|
||||
target_entities,
|
||||
)
|
||||
|
||||
ALL_ON_STATES = [
|
||||
STATE_ECO,
|
||||
STATE_ELECTRIC,
|
||||
STATE_GAS,
|
||||
STATE_HEAT_PUMP,
|
||||
STATE_HIGH_DEMAND,
|
||||
STATE_ON,
|
||||
STATE_PERFORMANCE,
|
||||
]
|
||||
|
||||
_TEMPERATURE_TRIGGER_OPTIONS = {"unit": UnitOfTemperature.CELSIUS}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def target_water_heaters(hass: HomeAssistant) -> list[str]:
|
||||
"""Create multiple water heater entities associated with different targets."""
|
||||
return await target_entities(hass, "water_heater")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"trigger_key",
|
||||
[
|
||||
"water_heater.target_temperature_changed",
|
||||
"water_heater.target_temperature_crossed_threshold",
|
||||
"water_heater.turned_off",
|
||||
"water_heater.turned_on",
|
||||
],
|
||||
)
|
||||
async def test_water_heater_triggers_gated_by_labs_flag(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, trigger_key: str
|
||||
) -> None:
|
||||
"""Test the water heater triggers are gated by the labs flag."""
|
||||
await assert_trigger_gated_by_labs_flag(hass, caplog, trigger_key)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_labs_preview_features")
|
||||
@pytest.mark.parametrize(
|
||||
("trigger_target_config", "entity_id", "entities_in_target"),
|
||||
parametrize_target_entities("water_heater"),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_trigger_states(
|
||||
trigger="water_heater.turned_off",
|
||||
target_states=[STATE_OFF],
|
||||
other_states=ALL_ON_STATES,
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger="water_heater.turned_on",
|
||||
target_states=ALL_ON_STATES,
|
||||
other_states=[STATE_OFF],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_water_heater_state_trigger_behavior_any(
|
||||
hass: HomeAssistant,
|
||||
service_calls: list[ServiceCall],
|
||||
target_water_heaters: list[str],
|
||||
trigger_target_config: dict,
|
||||
entity_id: str,
|
||||
entities_in_target: int,
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the water heater state trigger fires when any water heater state changes to a specific state."""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
service_calls=service_calls,
|
||||
target_entities=target_water_heaters,
|
||||
trigger_target_config=trigger_target_config,
|
||||
entity_id=entity_id,
|
||||
entities_in_target=entities_in_target,
|
||||
trigger=trigger,
|
||||
trigger_options=trigger_options,
|
||||
states=states,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_labs_preview_features")
|
||||
@pytest.mark.parametrize(
|
||||
("trigger_target_config", "entity_id", "entities_in_target"),
|
||||
parametrize_target_entities("water_heater"),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_numerical_attribute_changed_trigger_states(
|
||||
"water_heater.target_temperature_changed",
|
||||
STATE_ECO,
|
||||
ATTR_TEMPERATURE,
|
||||
trigger_options=_TEMPERATURE_TRIGGER_OPTIONS,
|
||||
),
|
||||
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
|
||||
"water_heater.target_temperature_crossed_threshold",
|
||||
STATE_ECO,
|
||||
ATTR_TEMPERATURE,
|
||||
trigger_options=_TEMPERATURE_TRIGGER_OPTIONS,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_water_heater_state_attribute_trigger_behavior_any(
|
||||
hass: HomeAssistant,
|
||||
service_calls: list[ServiceCall],
|
||||
target_water_heaters: list[str],
|
||||
trigger_target_config: dict,
|
||||
entity_id: str,
|
||||
entities_in_target: int,
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the water heater target temperature attribute triggers fire when any water heater's target temperature changes or crosses a threshold."""
|
||||
await assert_trigger_behavior_any(
|
||||
hass,
|
||||
service_calls=service_calls,
|
||||
target_entities=target_water_heaters,
|
||||
trigger_target_config=trigger_target_config,
|
||||
entity_id=entity_id,
|
||||
entities_in_target=entities_in_target,
|
||||
trigger=trigger,
|
||||
trigger_options=trigger_options,
|
||||
states=states,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_labs_preview_features")
|
||||
@pytest.mark.parametrize(
|
||||
("trigger_target_config", "entity_id", "entities_in_target"),
|
||||
parametrize_target_entities("water_heater"),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_trigger_states(
|
||||
trigger="water_heater.turned_off",
|
||||
target_states=[STATE_OFF],
|
||||
other_states=ALL_ON_STATES,
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger="water_heater.turned_on",
|
||||
target_states=ALL_ON_STATES,
|
||||
other_states=[STATE_OFF],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_water_heater_state_trigger_behavior_first(
|
||||
hass: HomeAssistant,
|
||||
service_calls: list[ServiceCall],
|
||||
target_water_heaters: list[str],
|
||||
trigger_target_config: dict,
|
||||
entity_id: str,
|
||||
entities_in_target: int,
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the water heater state trigger fires when the first water heater changes to a specific state."""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
service_calls=service_calls,
|
||||
target_entities=target_water_heaters,
|
||||
trigger_target_config=trigger_target_config,
|
||||
entity_id=entity_id,
|
||||
entities_in_target=entities_in_target,
|
||||
trigger=trigger,
|
||||
trigger_options=trigger_options,
|
||||
states=states,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_labs_preview_features")
|
||||
@pytest.mark.parametrize(
|
||||
("trigger_target_config", "entity_id", "entities_in_target"),
|
||||
parametrize_target_entities("water_heater"),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
|
||||
"water_heater.target_temperature_crossed_threshold",
|
||||
STATE_ECO,
|
||||
ATTR_TEMPERATURE,
|
||||
trigger_options=_TEMPERATURE_TRIGGER_OPTIONS,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_water_heater_state_attribute_trigger_behavior_first(
|
||||
hass: HomeAssistant,
|
||||
service_calls: list[ServiceCall],
|
||||
target_water_heaters: list[str],
|
||||
trigger_target_config: dict,
|
||||
entity_id: str,
|
||||
entities_in_target: int,
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[tuple[tuple[str, dict], int]],
|
||||
) -> None:
|
||||
"""Test that the water heater attribute threshold trigger fires when the first water heater's target temperature crosses the configured threshold."""
|
||||
await assert_trigger_behavior_first(
|
||||
hass,
|
||||
service_calls=service_calls,
|
||||
target_entities=target_water_heaters,
|
||||
trigger_target_config=trigger_target_config,
|
||||
entity_id=entity_id,
|
||||
entities_in_target=entities_in_target,
|
||||
trigger=trigger,
|
||||
trigger_options=trigger_options,
|
||||
states=states,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_labs_preview_features")
|
||||
@pytest.mark.parametrize(
|
||||
("trigger_target_config", "entity_id", "entities_in_target"),
|
||||
parametrize_target_entities("water_heater"),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_trigger_states(
|
||||
trigger="water_heater.turned_off",
|
||||
target_states=[STATE_OFF],
|
||||
other_states=ALL_ON_STATES,
|
||||
),
|
||||
*parametrize_trigger_states(
|
||||
trigger="water_heater.turned_on",
|
||||
target_states=ALL_ON_STATES,
|
||||
other_states=[STATE_OFF],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_water_heater_state_trigger_behavior_last(
|
||||
hass: HomeAssistant,
|
||||
service_calls: list[ServiceCall],
|
||||
target_water_heaters: list[str],
|
||||
trigger_target_config: dict,
|
||||
entity_id: str,
|
||||
entities_in_target: int,
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[TriggerStateDescription],
|
||||
) -> None:
|
||||
"""Test that the water heater state trigger fires when the last water heater changes to a specific state."""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
service_calls=service_calls,
|
||||
target_entities=target_water_heaters,
|
||||
trigger_target_config=trigger_target_config,
|
||||
entity_id=entity_id,
|
||||
entities_in_target=entities_in_target,
|
||||
trigger=trigger,
|
||||
trigger_options=trigger_options,
|
||||
states=states,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("enable_labs_preview_features")
|
||||
@pytest.mark.parametrize(
|
||||
("trigger_target_config", "entity_id", "entities_in_target"),
|
||||
parametrize_target_entities("water_heater"),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "trigger_options", "states"),
|
||||
[
|
||||
*parametrize_numerical_attribute_crossed_threshold_trigger_states(
|
||||
"water_heater.target_temperature_crossed_threshold",
|
||||
STATE_ECO,
|
||||
ATTR_TEMPERATURE,
|
||||
trigger_options=_TEMPERATURE_TRIGGER_OPTIONS,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_water_heater_state_attribute_trigger_behavior_last(
|
||||
hass: HomeAssistant,
|
||||
service_calls: list[ServiceCall],
|
||||
target_water_heaters: list[str],
|
||||
trigger_target_config: dict,
|
||||
entity_id: str,
|
||||
entities_in_target: int,
|
||||
trigger: str,
|
||||
trigger_options: dict[str, Any],
|
||||
states: list[tuple[tuple[str, dict], int]],
|
||||
) -> None:
|
||||
"""Test that the water heater trigger fires when the last water heater's target temperature crosses the configured threshold."""
|
||||
await assert_trigger_behavior_last(
|
||||
hass,
|
||||
service_calls=service_calls,
|
||||
target_entities=target_water_heaters,
|
||||
trigger_target_config=trigger_target_config,
|
||||
entity_id=entity_id,
|
||||
entities_in_target=entities_in_target,
|
||||
trigger=trigger,
|
||||
trigger_options=trigger_options,
|
||||
states=states,
|
||||
)
|
||||
Reference in New Issue
Block a user