Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The Logitech Harmony Hub integration."""
2 
3 import logging
4 
5 from homeassistant.components.remote import ATTR_ACTIVITY, ATTR_DELAY_SECS
6 from homeassistant.const import CONF_HOST, CONF_NAME, EVENT_HOMEASSISTANT_STOP
7 from homeassistant.core import Event, HomeAssistant, callback
8 from homeassistant.helpers import entity_registry as er
9 from homeassistant.helpers.dispatcher import async_dispatcher_send
10 
11 from .const import HARMONY_OPTIONS_UPDATE, PLATFORMS
12 from .data import HarmonyConfigEntry, HarmonyData
13 
14 _LOGGER = logging.getLogger(__name__)
15 
16 
17 async def async_setup_entry(hass: HomeAssistant, entry: HarmonyConfigEntry) -> bool:
18  """Set up Logitech Harmony Hub from a config entry."""
19  # As there currently is no way to import options from yaml
20  # when setting up a config entry, we fallback to adding
21  # the options to the config entry and pull them out here if
22  # they are missing from the options
24 
25  address = entry.data[CONF_HOST]
26  name = entry.data[CONF_NAME]
27  data = HarmonyData(hass, address, name, entry.unique_id)
28  await data.connect()
29 
30  await _migrate_old_unique_ids(hass, entry.entry_id, data)
31 
32  entry.async_on_unload(entry.add_update_listener(_update_listener))
33 
34  async def _async_on_stop(event: Event) -> None:
35  await data.shutdown()
36 
37  entry.async_on_unload(
38  hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, _async_on_stop)
39  )
40 
41  entry.runtime_data = data
42  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
43 
44  return True
45 
46 
48  hass: HomeAssistant, entry_id: str, data: HarmonyData
49 ) -> None:
50  names_to_ids = {activity["label"]: activity["id"] for activity in data.activities}
51 
52  @callback
53  def _async_migrator(entity_entry: er.RegistryEntry) -> dict[str, str] | None:
54  # Old format for switches was {remote_unique_id}-{activity_name}
55  # New format is activity_{activity_id}
56  parts = entity_entry.unique_id.split("-", 1)
57  if len(parts) > 1: # old format
58  activity_name = parts[1]
59  activity_id = names_to_ids.get(activity_name)
60 
61  if activity_id is not None:
62  _LOGGER.debug(
63  "Migrating unique_id from [%s] to [%s]",
64  entity_entry.unique_id,
65  activity_id,
66  )
67  return {"new_unique_id": f"activity_{activity_id}"}
68 
69  return None
70 
71  await er.async_migrate_entries(hass, entry_id, _async_migrator)
72 
73 
74 @callback
76  hass: HomeAssistant, entry: HarmonyConfigEntry
77 ) -> None:
78  options = dict(entry.options)
79  modified = 0
80  for importable_option in (ATTR_ACTIVITY, ATTR_DELAY_SECS):
81  if importable_option not in entry.options and importable_option in entry.data:
82  options[importable_option] = entry.data[importable_option]
83  modified = 1
84 
85  if modified:
86  hass.config_entries.async_update_entry(entry, options=options)
87 
88 
89 async def _update_listener(hass: HomeAssistant, entry: HarmonyConfigEntry) -> None:
90  """Handle options update."""
92  hass, f"{HARMONY_OPTIONS_UPDATE}-{entry.unique_id}", entry.options
93  )
94 
95 
96 async def async_unload_entry(hass: HomeAssistant, entry: HarmonyConfigEntry) -> bool:
97  """Unload a config entry."""
98  unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
99  # Shutdown a harmony remote for removal
100  await entry.runtime_data.shutdown()
101  return unload_ok
bool async_unload_entry(HomeAssistant hass, HarmonyConfigEntry entry)
Definition: __init__.py:96
bool async_setup_entry(HomeAssistant hass, HarmonyConfigEntry entry)
Definition: __init__.py:17
None _async_import_options_from_data_if_missing(HomeAssistant hass, HarmonyConfigEntry entry)
Definition: __init__.py:77
None _migrate_old_unique_ids(HomeAssistant hass, str entry_id, HarmonyData data)
Definition: __init__.py:49
None _update_listener(HomeAssistant hass, HarmonyConfigEntry entry)
Definition: __init__.py:89
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)
Definition: dispatcher.py:193