Home Assistant Unofficial Reference 2024.12.1
device_condition.py
Go to the documentation of this file.
1 """Provide the device automations for Climate."""
2 
3 from __future__ import annotations
4 
5 import voluptuous as vol
6 
8  async_get_entity_registry_entry_or_raise,
9 )
10 from homeassistant.const import (
11  ATTR_ENTITY_ID,
12  CONF_CONDITION,
13  CONF_DEVICE_ID,
14  CONF_DOMAIN,
15  CONF_ENTITY_ID,
16  CONF_TYPE,
17 )
18 from homeassistant.core import HomeAssistant, callback
19 from homeassistant.exceptions import HomeAssistantError
20 from homeassistant.helpers import (
21  condition,
22  config_validation as cv,
23  entity_registry as er,
24 )
25 from homeassistant.helpers.config_validation import DEVICE_CONDITION_BASE_SCHEMA
26 from homeassistant.helpers.entity import get_capability, get_supported_features
27 from homeassistant.helpers.typing import ConfigType, TemplateVarsType
28 
29 from . import DOMAIN, const
30 
31 CONDITION_TYPES = {"is_hvac_mode", "is_preset_mode"}
32 
33 HVAC_MODE_CONDITION = DEVICE_CONDITION_BASE_SCHEMA.extend(
34  {
35  vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid,
36  vol.Required(CONF_TYPE): "is_hvac_mode",
37  vol.Required(const.ATTR_HVAC_MODE): vol.In(const.HVAC_MODES),
38  }
39 )
40 
41 PRESET_MODE_CONDITION = DEVICE_CONDITION_BASE_SCHEMA.extend(
42  {
43  vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid,
44  vol.Required(CONF_TYPE): "is_preset_mode",
45  vol.Required(const.ATTR_PRESET_MODE): str,
46  }
47 )
48 
49 CONDITION_SCHEMA = vol.Any(HVAC_MODE_CONDITION, PRESET_MODE_CONDITION)
50 
51 
53  hass: HomeAssistant, device_id: str
54 ) -> list[dict[str, str]]:
55  """List device conditions for Climate devices."""
56  registry = er.async_get(hass)
57  conditions = []
58 
59  # Get all the integrations entities for this device
60  for entry in er.async_entries_for_device(registry, device_id):
61  if entry.domain != DOMAIN:
62  continue
63 
64  supported_features = get_supported_features(hass, entry.entity_id)
65 
66  base_condition = {
67  CONF_CONDITION: "device",
68  CONF_DEVICE_ID: device_id,
69  CONF_DOMAIN: DOMAIN,
70  CONF_ENTITY_ID: entry.id,
71  }
72 
73  conditions.append({**base_condition, CONF_TYPE: "is_hvac_mode"})
74 
75  if supported_features & const.ClimateEntityFeature.PRESET_MODE:
76  conditions.append({**base_condition, CONF_TYPE: "is_preset_mode"})
77 
78  return conditions
79 
80 
81 @callback
83  hass: HomeAssistant, config: ConfigType
84 ) -> condition.ConditionCheckerType:
85  """Create a function to test a device condition."""
86 
87  registry = er.async_get(hass)
88  entity_id = er.async_resolve_entity_id(registry, config[ATTR_ENTITY_ID])
89 
90  def test_is_state(hass: HomeAssistant, variables: TemplateVarsType) -> bool:
91  """Test if an entity is a certain state."""
92  if not entity_id or (state := hass.states.get(entity_id)) is None:
93  return False
94 
95  if config[CONF_TYPE] == "is_hvac_mode":
96  return bool(state.state == config[const.ATTR_HVAC_MODE])
97 
98  return bool(
99  state.attributes.get(const.ATTR_PRESET_MODE)
100  == config[const.ATTR_PRESET_MODE]
101  )
102 
103  return test_is_state
104 
105 
107  hass: HomeAssistant, config: ConfigType
108 ) -> dict[str, vol.Schema]:
109  """List condition capabilities."""
110  condition_type = config[CONF_TYPE]
111 
112  fields = {}
113 
114  if condition_type == "is_hvac_mode":
115  try:
117  hass, config[CONF_ENTITY_ID]
118  )
119  hvac_modes = (
120  get_capability(hass, entry.entity_id, const.ATTR_HVAC_MODES) or []
121  )
122  except HomeAssistantError:
123  hvac_modes = []
124  fields[vol.Required(const.ATTR_HVAC_MODE)] = vol.In(hvac_modes)
125 
126  elif condition_type == "is_preset_mode":
127  try:
129  hass, config[CONF_ENTITY_ID]
130  )
131  preset_modes = (
132  get_capability(hass, entry.entity_id, const.ATTR_PRESET_MODES) or []
133  )
134  except HomeAssistantError:
135  preset_modes = []
136  fields[vol.Required(const.ATTR_PRESET_MODE)] = vol.In(preset_modes)
137 
138  return {"extra_fields": vol.Schema(fields)}
list[dict[str, str]] async_get_conditions(HomeAssistant hass, str device_id)
condition.ConditionCheckerType async_condition_from_config(HomeAssistant hass, ConfigType config)
dict[str, vol.Schema] async_get_condition_capabilities(HomeAssistant hass, ConfigType config)
er.RegistryEntry async_get_entity_registry_entry_or_raise(HomeAssistant hass, str entity_registry_id)
Definition: __init__.py:332
int get_supported_features(HomeAssistant hass, str entity_id)
Definition: entity.py:169
Any|None get_capability(HomeAssistant hass, str entity_id, str capability)
Definition: entity.py:139