Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Set up the demo environment that mimics interaction with devices."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 
7 from homeassistant import config_entries, setup
8 from homeassistant.components import persistent_notification
9 from homeassistant.config_entries import ConfigEntry
10 from homeassistant.const import (
11  ATTR_ENTITY_ID,
12  EVENT_HOMEASSISTANT_START,
13  Platform,
14  UnitOfSoundPressure,
15 )
16 import homeassistant.core as ha
17 from homeassistant.core import Event, HomeAssistant
18 from homeassistant.helpers import config_validation as cv
19 from homeassistant.helpers.discovery import async_load_platform
20 from homeassistant.helpers.typing import ConfigType
21 
22 DOMAIN = "demo"
23 
24 COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM = [
25  Platform.AIR_QUALITY,
26  Platform.ALARM_CONTROL_PANEL,
27  Platform.BINARY_SENSOR,
28  Platform.BUTTON,
29  Platform.CAMERA,
30  Platform.CALENDAR,
31  Platform.CLIMATE,
32  Platform.COVER,
33  Platform.DATE,
34  Platform.DATETIME,
35  Platform.EVENT,
36  Platform.FAN,
37  Platform.HUMIDIFIER,
38  Platform.LIGHT,
39  Platform.LOCK,
40  Platform.MEDIA_PLAYER,
41  Platform.NOTIFY,
42  Platform.NUMBER,
43  Platform.SELECT,
44  Platform.SENSOR,
45  Platform.SIREN,
46  Platform.STT,
47  Platform.SWITCH,
48  Platform.TEXT,
49  Platform.TIME,
50  Platform.UPDATE,
51  Platform.VACUUM,
52  Platform.WATER_HEATER,
53  Platform.WEATHER,
54 ]
55 
56 COMPONENTS_WITH_DEMO_PLATFORM = [
57  Platform.TTS,
58  Platform.IMAGE_PROCESSING,
59  Platform.DEVICE_TRACKER,
60 ]
61 
62 CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
63 
64 
65 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
66  """Set up the demo environment."""
67  hass.async_create_task(
68  hass.config_entries.flow.async_init(
69  DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data={}
70  )
71  )
72 
73  if DOMAIN not in config:
74  return True
75 
76  # Set up demo platforms
77  for platform in COMPONENTS_WITH_DEMO_PLATFORM:
78  hass.async_create_task(async_load_platform(hass, platform, DOMAIN, {}, config))
79 
80  config.setdefault(ha.DOMAIN, {})
81  config.setdefault(DOMAIN, {})
82 
83  # Set up sun
84  if not hass.config.latitude:
85  hass.config.latitude = 32.87336
86 
87  if not hass.config.longitude:
88  hass.config.longitude = 117.22743
89 
90  tasks = [setup.async_setup_component(hass, "sun", config)]
91 
92  # Set up input select
93  tasks.append(
94  setup.async_setup_component(
95  hass,
96  "input_select",
97  {
98  "input_select": {
99  "living_room_preset": {
100  "options": ["Visitors", "Visitors with kids", "Home Alone"]
101  },
102  "who_cooks": {
103  "icon": "mdi:panda",
104  "initial": "Anne Therese",
105  "name": "Cook today",
106  "options": ["Paulus", "Anne Therese"],
107  },
108  }
109  },
110  )
111  )
112 
113  # Set up input boolean
114  tasks.append(
115  setup.async_setup_component(
116  hass,
117  "input_boolean",
118  {
119  "input_boolean": {
120  "notify": {
121  "icon": "mdi:car",
122  "initial": False,
123  "name": "Notify Anne Therese is home",
124  }
125  }
126  },
127  )
128  )
129 
130  # Set up input button
131  tasks.append(
132  setup.async_setup_component(
133  hass,
134  "input_button",
135  {
136  "input_button": {
137  "bell": {
138  "icon": "mdi:bell-ring-outline",
139  "name": "Ring bell",
140  }
141  }
142  },
143  )
144  )
145 
146  # Set up input number
147  tasks.append(
148  setup.async_setup_component(
149  hass,
150  "input_number",
151  {
152  "input_number": {
153  "noise_allowance": {
154  "icon": "mdi:bell-ring",
155  "min": 0,
156  "max": 10,
157  "name": "Allowed Noise",
158  "unit_of_measurement": UnitOfSoundPressure.DECIBEL,
159  }
160  }
161  },
162  )
163  )
164 
165  results = await asyncio.gather(*tasks)
166 
167  if any(not result for result in results):
168  return False
169 
170  # Set up example persistent notification
171  persistent_notification.async_create(
172  hass,
173  "This is an example of a persistent notification.",
174  title="Example Notification",
175  )
176 
177  async def demo_start_listener(_event: Event) -> None:
178  """Finish set up."""
179  await finish_setup(hass, config)
180 
181  hass.bus.async_listen(EVENT_HOMEASSISTANT_START, demo_start_listener)
182 
183  return True
184 
185 
186 async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
187  """Set the config entry up."""
188  # Set up demo platforms with config entry
189  await hass.config_entries.async_forward_entry_setups(
190  config_entry, COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM
191  )
192  return True
193 
194 
195 async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
196  """Unload a config entry."""
197  await hass.config_entries.async_unload_platforms(
198  config_entry, COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM
199  )
200  return True
201 
202 
203 async def finish_setup(hass: HomeAssistant, config: ConfigType) -> None:
204  """Finish set up once demo platforms are set up."""
205  switches: list[str] | None = None
206  lights: list[str] | None = None
207 
208  while not switches and not lights:
209  # Not all platforms might be loaded.
210  if switches is not None:
211  await asyncio.sleep(0)
212  switches = sorted(hass.states.async_entity_ids("switch"))
213  lights = sorted(hass.states.async_entity_ids("light"))
214 
215  assert switches is not None
216  assert lights is not None
217  # Set up scripts
218  await setup.async_setup_component(
219  hass,
220  "script",
221  {
222  "script": {
223  "demo": {
224  "alias": f"Toggle {lights[0].split('.')[1]}",
225  "sequence": [
226  {
227  "service": "light.turn_off",
228  "data": {ATTR_ENTITY_ID: lights[0]},
229  },
230  {"delay": {"seconds": 5}},
231  {
232  "service": "light.turn_on",
233  "data": {ATTR_ENTITY_ID: lights[0]},
234  },
235  {"delay": {"seconds": 5}},
236  {
237  "service": "light.turn_off",
238  "data": {ATTR_ENTITY_ID: lights[0]},
239  },
240  ],
241  }
242  }
243  },
244  )
245 
246  # Set up scenes
247  await setup.async_setup_component(
248  hass,
249  "scene",
250  {
251  "scene": [
252  {
253  "name": "Romantic lights",
254  "entities": {
255  lights[0]: True,
256  lights[1]: {
257  "state": "on",
258  "xy_color": [0.33, 0.66],
259  "brightness": 200,
260  },
261  },
262  },
263  {
264  "name": "Switch on and off",
265  "entities": {switches[0]: True, switches[1]: False},
266  },
267  ]
268  },
269  )
None finish_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:203
bool async_setup_entry(HomeAssistant hass, ConfigEntry config_entry)
Definition: __init__.py:186
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:65
bool async_unload_entry(HomeAssistant hass, ConfigEntry config_entry)
Definition: __init__.py:195
None async_load_platform(core.HomeAssistant hass, Platform|str component, str platform, DiscoveryInfoType|None discovered, ConfigType hass_config)
Definition: discovery.py:152