mirror of
https://github.com/home-assistant/core.git
synced 2026-04-17 23:53:49 +01:00
Add climate.is_hvac_mode condition (#166570)
This commit is contained in:
committed by
Franck Nijhof
parent
1b972d4adc
commit
ee9d9781ee
@@ -1,10 +1,18 @@
|
|||||||
"""Provides conditions for climates."""
|
"""Provides conditions for climates."""
|
||||||
|
|
||||||
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.const import ATTR_TEMPERATURE, CONF_OPTIONS, UnitOfTemperature
|
||||||
from homeassistant.core import HomeAssistant, State
|
from homeassistant.core import HomeAssistant, State
|
||||||
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.helpers.automation import DomainSpec
|
from homeassistant.helpers.automation import DomainSpec
|
||||||
from homeassistant.helpers.condition import (
|
from homeassistant.helpers.condition import (
|
||||||
|
ENTITY_STATE_CONDITION_SCHEMA_ANY_ALL,
|
||||||
Condition,
|
Condition,
|
||||||
|
ConditionConfig,
|
||||||
|
EntityConditionBase,
|
||||||
EntityNumericalConditionWithUnitBase,
|
EntityNumericalConditionWithUnitBase,
|
||||||
make_entity_numerical_condition,
|
make_entity_numerical_condition,
|
||||||
make_entity_state_condition,
|
make_entity_state_condition,
|
||||||
@@ -13,6 +21,36 @@ from homeassistant.util.unit_conversion import TemperatureConverter
|
|||||||
|
|
||||||
from .const import ATTR_HUMIDITY, ATTR_HVAC_ACTION, DOMAIN, HVACAction, HVACMode
|
from .const import ATTR_HUMIDITY, ATTR_HVAC_ACTION, DOMAIN, HVACAction, HVACMode
|
||||||
|
|
||||||
|
CONF_HVAC_MODE = "hvac_mode"
|
||||||
|
|
||||||
|
_HVAC_MODE_CONDITION_SCHEMA = ENTITY_STATE_CONDITION_SCHEMA_ANY_ALL.extend(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_OPTIONS): {
|
||||||
|
vol.Required(CONF_HVAC_MODE): vol.All(
|
||||||
|
cv.ensure_list, vol.Length(min=1), [vol.Coerce(HVACMode)]
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ClimateHVACModeCondition(EntityConditionBase):
|
||||||
|
"""Condition for climate HVAC mode."""
|
||||||
|
|
||||||
|
_domain_specs = {DOMAIN: DomainSpec()}
|
||||||
|
_schema = _HVAC_MODE_CONDITION_SCHEMA
|
||||||
|
|
||||||
|
def __init__(self, hass: HomeAssistant, config: ConditionConfig) -> None:
|
||||||
|
"""Initialize the HVAC mode condition."""
|
||||||
|
super().__init__(hass, config)
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
assert config.options is not None
|
||||||
|
self._hvac_modes: set[str] = set(config.options[CONF_HVAC_MODE])
|
||||||
|
|
||||||
|
def is_valid_state(self, entity_state: State) -> bool:
|
||||||
|
"""Check if the state matches any of the expected HVAC modes."""
|
||||||
|
return entity_state.state in self._hvac_modes
|
||||||
|
|
||||||
|
|
||||||
class ClimateTargetTemperatureCondition(EntityNumericalConditionWithUnitBase):
|
class ClimateTargetTemperatureCondition(EntityNumericalConditionWithUnitBase):
|
||||||
"""Mixin for climate target temperature conditions with unit conversion."""
|
"""Mixin for climate target temperature conditions with unit conversion."""
|
||||||
@@ -28,6 +66,7 @@ class ClimateTargetTemperatureCondition(EntityNumericalConditionWithUnitBase):
|
|||||||
|
|
||||||
|
|
||||||
CONDITIONS: dict[str, type[Condition]] = {
|
CONDITIONS: dict[str, type[Condition]] = {
|
||||||
|
"is_hvac_mode": ClimateHVACModeCondition,
|
||||||
"is_off": make_entity_state_condition(DOMAIN, HVACMode.OFF),
|
"is_off": make_entity_state_condition(DOMAIN, HVACMode.OFF),
|
||||||
"is_on": make_entity_state_condition(
|
"is_on": make_entity_state_condition(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
|||||||
@@ -45,6 +45,21 @@ is_cooling: *condition_common
|
|||||||
is_drying: *condition_common
|
is_drying: *condition_common
|
||||||
is_heating: *condition_common
|
is_heating: *condition_common
|
||||||
|
|
||||||
|
is_hvac_mode:
|
||||||
|
target: *condition_climate_target
|
||||||
|
fields:
|
||||||
|
behavior: *condition_behavior
|
||||||
|
hvac_mode:
|
||||||
|
context:
|
||||||
|
filter_target: target
|
||||||
|
required: true
|
||||||
|
selector:
|
||||||
|
state:
|
||||||
|
hide_states:
|
||||||
|
- unavailable
|
||||||
|
- unknown
|
||||||
|
multiple: true
|
||||||
|
|
||||||
target_humidity:
|
target_humidity:
|
||||||
target: *condition_climate_target
|
target: *condition_climate_target
|
||||||
fields:
|
fields:
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
"is_heating": {
|
"is_heating": {
|
||||||
"condition": "mdi:fire"
|
"condition": "mdi:fire"
|
||||||
},
|
},
|
||||||
|
"is_hvac_mode": {
|
||||||
|
"condition": "mdi:thermostat"
|
||||||
|
},
|
||||||
"is_off": {
|
"is_off": {
|
||||||
"condition": "mdi:power-off"
|
"condition": "mdi:power-off"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -41,6 +41,20 @@
|
|||||||
},
|
},
|
||||||
"name": "Climate-control device is heating"
|
"name": "Climate-control device is heating"
|
||||||
},
|
},
|
||||||
|
"is_hvac_mode": {
|
||||||
|
"description": "Tests if one or more climate-control devices are set to a specific HVAC mode.",
|
||||||
|
"fields": {
|
||||||
|
"behavior": {
|
||||||
|
"description": "[%key:component::climate::common::condition_behavior_description%]",
|
||||||
|
"name": "[%key:component::climate::common::condition_behavior_name%]"
|
||||||
|
},
|
||||||
|
"hvac_mode": {
|
||||||
|
"description": "The HVAC modes to test for.",
|
||||||
|
"name": "Modes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Climate-control device HVAC mode"
|
||||||
|
},
|
||||||
"is_off": {
|
"is_off": {
|
||||||
"description": "Tests if one or more climate-control devices are off.",
|
"description": "Tests if one or more climate-control devices are off.",
|
||||||
"fields": {
|
"fields": {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ async def target_climates(hass: HomeAssistant) -> dict[str, list[str]]:
|
|||||||
"climate.is_cooling",
|
"climate.is_cooling",
|
||||||
"climate.is_drying",
|
"climate.is_drying",
|
||||||
"climate.is_heating",
|
"climate.is_heating",
|
||||||
|
"climate.is_hvac_mode",
|
||||||
"climate.target_humidity",
|
"climate.target_humidity",
|
||||||
"climate.target_temperature",
|
"climate.target_temperature",
|
||||||
],
|
],
|
||||||
@@ -83,6 +84,24 @@ async def test_climate_conditions_gated_by_labs_flag(
|
|||||||
],
|
],
|
||||||
other_states=[HVACMode.OFF],
|
other_states=[HVACMode.OFF],
|
||||||
),
|
),
|
||||||
|
*(
|
||||||
|
param
|
||||||
|
for mode in HVACMode
|
||||||
|
for param in parametrize_condition_states_any(
|
||||||
|
condition="climate.is_hvac_mode",
|
||||||
|
condition_options={"hvac_mode": [mode]},
|
||||||
|
target_states=[mode],
|
||||||
|
other_states=[m for m in HVACMode if m != mode],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
*parametrize_condition_states_any(
|
||||||
|
condition="climate.is_hvac_mode",
|
||||||
|
condition_options={"hvac_mode": [HVACMode.HEAT, HVACMode.COOL]},
|
||||||
|
target_states=[HVACMode.HEAT, HVACMode.COOL],
|
||||||
|
other_states=[
|
||||||
|
m for m in HVACMode if m not in (HVACMode.HEAT, HVACMode.COOL)
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_climate_state_condition_behavior_any(
|
async def test_climate_state_condition_behavior_any(
|
||||||
@@ -133,6 +152,24 @@ async def test_climate_state_condition_behavior_any(
|
|||||||
],
|
],
|
||||||
other_states=[HVACMode.OFF],
|
other_states=[HVACMode.OFF],
|
||||||
),
|
),
|
||||||
|
*(
|
||||||
|
param
|
||||||
|
for mode in HVACMode
|
||||||
|
for param in parametrize_condition_states_all(
|
||||||
|
condition="climate.is_hvac_mode",
|
||||||
|
condition_options={"hvac_mode": [mode]},
|
||||||
|
target_states=[mode],
|
||||||
|
other_states=[m for m in HVACMode if m != mode],
|
||||||
|
)
|
||||||
|
),
|
||||||
|
*parametrize_condition_states_all(
|
||||||
|
condition="climate.is_hvac_mode",
|
||||||
|
condition_options={"hvac_mode": [HVACMode.HEAT, HVACMode.COOL]},
|
||||||
|
target_states=[HVACMode.HEAT, HVACMode.COOL],
|
||||||
|
other_states=[
|
||||||
|
m for m in HVACMode if m not in (HVACMode.HEAT, HVACMode.COOL)
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_climate_state_condition_behavior_all(
|
async def test_climate_state_condition_behavior_all(
|
||||||
|
|||||||
Reference in New Issue
Block a user