Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The command_line component."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from collections.abc import Coroutine
7 import logging
8 from typing import Any
9 
10 import voluptuous as vol
11 
13  DEVICE_CLASSES_SCHEMA as BINARY_SENSOR_DEVICE_CLASSES_SCHEMA,
14  DOMAIN as BINARY_SENSOR_DOMAIN,
15  SCAN_INTERVAL as BINARY_SENSOR_DEFAULT_SCAN_INTERVAL,
16 )
18  DEVICE_CLASSES_SCHEMA as COVER_DEVICE_CLASSES_SCHEMA,
19  DOMAIN as COVER_DOMAIN,
20  SCAN_INTERVAL as COVER_DEFAULT_SCAN_INTERVAL,
21 )
22 from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN
24  CONF_STATE_CLASS,
25  DEVICE_CLASSES_SCHEMA as SENSOR_DEVICE_CLASSES_SCHEMA,
26  DOMAIN as SENSOR_DOMAIN,
27  SCAN_INTERVAL as SENSOR_DEFAULT_SCAN_INTERVAL,
28  STATE_CLASSES_SCHEMA as SENSOR_STATE_CLASSES_SCHEMA,
29 )
31  DOMAIN as SWITCH_DOMAIN,
32  SCAN_INTERVAL as SWITCH_DEFAULT_SCAN_INTERVAL,
33 )
34 from homeassistant.const import (
35  CONF_COMMAND,
36  CONF_COMMAND_CLOSE,
37  CONF_COMMAND_OFF,
38  CONF_COMMAND_ON,
39  CONF_COMMAND_OPEN,
40  CONF_COMMAND_STATE,
41  CONF_COMMAND_STOP,
42  CONF_DEVICE_CLASS,
43  CONF_ICON,
44  CONF_NAME,
45  CONF_PAYLOAD_OFF,
46  CONF_PAYLOAD_ON,
47  CONF_SCAN_INTERVAL,
48  CONF_UNIQUE_ID,
49  CONF_UNIT_OF_MEASUREMENT,
50  CONF_VALUE_TEMPLATE,
51  SERVICE_RELOAD,
52  Platform,
53 )
54 from homeassistant.core import Event, HomeAssistant, ServiceCall
55 from homeassistant.helpers import discovery
57 from homeassistant.helpers.entity_platform import async_get_platforms
58 from homeassistant.helpers.reload import async_integration_yaml_config
59 from homeassistant.helpers.service import async_register_admin_service
60 from homeassistant.helpers.trigger_template_entity import CONF_AVAILABILITY
61 from homeassistant.helpers.typing import ConfigType
62 
63 from .const import (
64  CONF_COMMAND_TIMEOUT,
65  CONF_JSON_ATTRIBUTES,
66  CONF_JSON_ATTRIBUTES_PATH,
67  DEFAULT_TIMEOUT,
68  DOMAIN,
69 )
70 
71 BINARY_SENSOR_DEFAULT_NAME = "Binary Command Sensor"
72 DEFAULT_PAYLOAD_ON = "ON"
73 DEFAULT_PAYLOAD_OFF = "OFF"
74 SENSOR_DEFAULT_NAME = "Command Sensor"
75 CONF_NOTIFIERS = "notifiers"
76 
77 PLATFORM_MAPPING = {
78  BINARY_SENSOR_DOMAIN: Platform.BINARY_SENSOR,
79  COVER_DOMAIN: Platform.COVER,
80  NOTIFY_DOMAIN: Platform.NOTIFY,
81  SENSOR_DOMAIN: Platform.SENSOR,
82  SWITCH_DOMAIN: Platform.SWITCH,
83 }
84 
85 _LOGGER = logging.getLogger(__name__)
86 
87 BINARY_SENSOR_SCHEMA = vol.Schema(
88  {
89  vol.Required(CONF_COMMAND): cv.string,
90  vol.Optional(CONF_NAME, default=BINARY_SENSOR_DEFAULT_NAME): cv.string,
91  vol.Optional(CONF_ICON): cv.template,
92  vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
93  vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
94  vol.Optional(CONF_DEVICE_CLASS): BINARY_SENSOR_DEVICE_CLASSES_SCHEMA,
95  vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
96  vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
97  vol.Optional(CONF_UNIQUE_ID): cv.string,
98  vol.Optional(
99  CONF_SCAN_INTERVAL, default=BINARY_SENSOR_DEFAULT_SCAN_INTERVAL
100  ): vol.All(cv.time_period, cv.positive_timedelta),
101  vol.Optional(CONF_AVAILABILITY): cv.template,
102  }
103 )
104 COVER_SCHEMA = vol.Schema(
105  {
106  vol.Optional(CONF_COMMAND_CLOSE, default="true"): cv.string,
107  vol.Optional(CONF_COMMAND_OPEN, default="true"): cv.string,
108  vol.Optional(CONF_COMMAND_STATE): cv.string,
109  vol.Optional(CONF_COMMAND_STOP, default="true"): cv.string,
110  vol.Required(CONF_NAME): cv.string,
111  vol.Optional(CONF_ICON): cv.template,
112  vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
113  vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
114  vol.Optional(CONF_DEVICE_CLASS): COVER_DEVICE_CLASSES_SCHEMA,
115  vol.Optional(CONF_UNIQUE_ID): cv.string,
116  vol.Optional(CONF_SCAN_INTERVAL, default=COVER_DEFAULT_SCAN_INTERVAL): vol.All(
117  cv.time_period, cv.positive_timedelta
118  ),
119  vol.Optional(CONF_AVAILABILITY): cv.template,
120  }
121 )
122 NOTIFY_SCHEMA = vol.Schema(
123  {
124  vol.Required(CONF_COMMAND): cv.string,
125  vol.Optional(CONF_NAME): cv.string,
126  vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
127  }
128 )
129 SENSOR_SCHEMA = vol.Schema(
130  {
131  vol.Required(CONF_COMMAND): cv.string,
132  vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
133  vol.Optional(CONF_JSON_ATTRIBUTES): cv.ensure_list_csv,
134  vol.Optional(CONF_JSON_ATTRIBUTES_PATH): cv.string,
135  vol.Optional(CONF_NAME, default=SENSOR_DEFAULT_NAME): cv.string,
136  vol.Optional(CONF_ICON): cv.template,
137  vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
138  vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
139  vol.Optional(CONF_UNIQUE_ID): cv.string,
140  vol.Optional(CONF_DEVICE_CLASS): SENSOR_DEVICE_CLASSES_SCHEMA,
141  vol.Optional(CONF_STATE_CLASS): SENSOR_STATE_CLASSES_SCHEMA,
142  vol.Optional(CONF_SCAN_INTERVAL, default=SENSOR_DEFAULT_SCAN_INTERVAL): vol.All(
143  cv.time_period, cv.positive_timedelta
144  ),
145  vol.Optional(CONF_AVAILABILITY): cv.template,
146  }
147 )
148 SWITCH_SCHEMA = vol.Schema(
149  {
150  vol.Optional(CONF_COMMAND_OFF, default="true"): cv.string,
151  vol.Optional(CONF_COMMAND_ON, default="true"): cv.string,
152  vol.Optional(CONF_COMMAND_STATE): cv.string,
153  vol.Required(CONF_NAME): cv.string,
154  vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
155  vol.Optional(CONF_ICON): cv.template,
156  vol.Optional(CONF_COMMAND_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
157  vol.Optional(CONF_UNIQUE_ID): cv.string,
158  vol.Optional(CONF_SCAN_INTERVAL, default=SWITCH_DEFAULT_SCAN_INTERVAL): vol.All(
159  cv.time_period, cv.positive_timedelta
160  ),
161  vol.Optional(CONF_AVAILABILITY): cv.template,
162  }
163 )
164 COMBINED_SCHEMA = vol.Schema(
165  {
166  vol.Optional(BINARY_SENSOR_DOMAIN): BINARY_SENSOR_SCHEMA,
167  vol.Optional(COVER_DOMAIN): COVER_SCHEMA,
168  vol.Optional(NOTIFY_DOMAIN): NOTIFY_SCHEMA,
169  vol.Optional(SENSOR_DOMAIN): SENSOR_SCHEMA,
170  vol.Optional(SWITCH_DOMAIN): SWITCH_SCHEMA,
171  }
172 )
173 CONFIG_SCHEMA = vol.Schema(
174  {
175  vol.Optional(DOMAIN): vol.All(
176  cv.ensure_list,
177  [COMBINED_SCHEMA],
178  )
179  },
180  extra=vol.ALLOW_EXTRA,
181 )
182 
183 
184 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
185  """Set up Command Line from yaml config."""
186 
187  async def _reload_config(call: Event | ServiceCall) -> None:
188  """Reload Command Line."""
189  reload_config = await async_integration_yaml_config(hass, DOMAIN)
190  reset_platforms = async_get_platforms(hass, DOMAIN)
191  for reset_platform in reset_platforms:
192  _LOGGER.debug("Reload resetting platform: %s", reset_platform.domain)
193  await reset_platform.async_reset()
194  if not reload_config:
195  return
196  await async_load_platforms(hass, reload_config.get(DOMAIN, []), reload_config)
197 
198  async_register_admin_service(hass, DOMAIN, SERVICE_RELOAD, _reload_config)
199 
200  await async_load_platforms(hass, config.get(DOMAIN, []), config)
201 
202  return True
203 
204 
206  hass: HomeAssistant,
207  command_line_config: list[dict[str, dict[str, Any]]],
208  config: ConfigType,
209 ) -> None:
210  """Load platforms from yaml."""
211  if not command_line_config:
212  return
213 
214  _LOGGER.debug("Full config loaded: %s", command_line_config)
215 
216  load_coroutines: list[Coroutine[Any, Any, None]] = []
217  platforms: list[Platform] = []
218  reload_configs: list[tuple[Platform, dict[str, Any]]] = []
219  for platform_config in command_line_config:
220  for platform, _config in platform_config.items():
221  if (mapped_platform := PLATFORM_MAPPING[platform]) not in platforms:
222  platforms.append(mapped_platform)
223  _LOGGER.debug(
224  "Loading config %s for platform %s",
225  platform_config,
226  PLATFORM_MAPPING[platform],
227  )
228  reload_configs.append((PLATFORM_MAPPING[platform], _config))
229  load_coroutines.append(
230  discovery.async_load_platform(
231  hass,
232  PLATFORM_MAPPING[platform],
233  DOMAIN,
234  _config,
235  config,
236  )
237  )
238 
239  if load_coroutines:
240  _LOGGER.debug("Loading platforms: %s", platforms)
241  await asyncio.gather(*load_coroutines)
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:184
None async_load_platforms(HomeAssistant hass, list[dict[str, dict[str, Any]]] command_line_config, ConfigType config)
Definition: __init__.py:209
list[EntityPlatform] async_get_platforms(HomeAssistant hass, str integration_name)
ConfigType|None async_integration_yaml_config(HomeAssistant hass, str integration_name)
Definition: reload.py:142
None async_register_admin_service(HomeAssistant hass, str domain, str service, Callable[[ServiceCall], Awaitable[None]|None] service_func, VolSchemaType schema=vol.Schema({}, extra=vol.PREVENT_EXTRA))
Definition: service.py:1121