Home Assistant Unofficial Reference 2024.12.1
migrate.py
Go to the documentation of this file.
1 """UniFi Protect data migrations."""
2 
3 from __future__ import annotations
4 
5 from itertools import chain
6 import logging
7 from typing import TypedDict
8 
9 from uiprotect import ProtectApiClient
10 from uiprotect.data import Bootstrap
11 
12 from homeassistant.components.automation import automations_with_entity
13 from homeassistant.components.script import scripts_with_entity
14 from homeassistant.const import Platform
15 from homeassistant.core import HomeAssistant, callback
16 from homeassistant.helpers import entity_registry as er, issue_registry as ir
17 from homeassistant.helpers.issue_registry import IssueSeverity
18 
19 from .const import DOMAIN
20 from .data import UFPConfigEntry
21 
22 _LOGGER = logging.getLogger(__name__)
23 
24 
25 class EntityRef(TypedDict):
26  """Entity ref parameter variable."""
27 
28  id: str
29  platform: Platform
30 
31 
32 class EntityUsage(TypedDict):
33  """Entity usages response variable."""
34 
35  automations: dict[str, list[str]]
36  scripts: dict[str, list[str]]
37 
38 
39 @callback
41  hass: HomeAssistant, entry: UFPConfigEntry, entities: dict[str, EntityRef]
42 ) -> dict[str, EntityUsage]:
43  """Check for usages of entities and return them."""
44 
45  entity_registry = er.async_get(hass)
46  refs: dict[str, EntityUsage] = {
47  ref: {"automations": {}, "scripts": {}} for ref in entities
48  }
49 
50  for entity in er.async_entries_for_config_entry(entity_registry, entry.entry_id):
51  for ref_id, ref in entities.items():
52  if (
53  entity.domain == ref["platform"]
54  and entity.disabled_by is None
55  and ref["id"] in entity.unique_id
56  ):
57  entity_automations = automations_with_entity(hass, entity.entity_id)
58  entity_scripts = scripts_with_entity(hass, entity.entity_id)
59  if entity_automations:
60  refs[ref_id]["automations"][entity.entity_id] = entity_automations
61  if entity_scripts:
62  refs[ref_id]["scripts"][entity.entity_id] = entity_scripts
63 
64  return refs
65 
66 
67 @callback
69  hass: HomeAssistant,
70  entry: UFPConfigEntry,
71  breaks_in: str,
72  entities: dict[str, EntityRef],
73 ) -> None:
74  """Create repairs for used entities that are deprecated."""
75 
76  usages = check_if_used(hass, entry, entities)
77  for ref_id, refs in usages.items():
78  issue_id = f"deprecate_{ref_id}"
79  automations = refs["automations"]
80  scripts = refs["scripts"]
81  if automations or scripts:
82  items = sorted(
83  set(chain.from_iterable(chain(automations.values(), scripts.values())))
84  )
85  ir.async_create_issue(
86  hass,
87  DOMAIN,
88  issue_id,
89  is_fixable=False,
90  breaks_in_ha_version=breaks_in,
91  severity=IssueSeverity.WARNING,
92  translation_key=issue_id,
93  translation_placeholders={
94  "items": "* `" + "`\n* `".join(items) + "`\n"
95  },
96  )
97  else:
98  _LOGGER.debug("No found usages of %s", ref_id)
99  ir.async_delete_issue(hass, DOMAIN, issue_id)
100 
101 
103  hass: HomeAssistant,
104  entry: UFPConfigEntry,
105  protect: ProtectApiClient,
106  bootstrap: Bootstrap,
107 ) -> None:
108  """Run all valid UniFi Protect data migrations."""
109 
110  _LOGGER.debug("Start Migrate: async_deprecate_hdr")
111  async_deprecate_hdr(hass, entry)
112  _LOGGER.debug("Completed Migrate: async_deprecate_hdr")
113 
114 
115 @callback
116 def async_deprecate_hdr(hass: HomeAssistant, entry: UFPConfigEntry) -> None:
117  """Check for usages of hdr_mode switch and raise repair if it is used.
118 
119  UniFi Protect v3.0.22 changed how HDR works so it is no longer a simple on/off toggle. There is
120  Always On, Always Off and Auto. So it has been migrated to a select. The old switch is now deprecated.
121 
122  Added in 2024.4.0
123  """
124 
126  hass,
127  entry,
128  "2024.10.0",
129  {"hdr_switch": {"id": "hdr_mode", "platform": Platform.SWITCH}},
130  )
list[str] automations_with_entity(HomeAssistant hass, str entity_id)
Definition: __init__.py:191
list[str] scripts_with_entity(HomeAssistant hass, str entity_id)
Definition: __init__.py:126
None async_deprecate_hdr(HomeAssistant hass, UFPConfigEntry entry)
Definition: migrate.py:116
dict[str, EntityUsage] check_if_used(HomeAssistant hass, UFPConfigEntry entry, dict[str, EntityRef] entities)
Definition: migrate.py:42
None create_repair_if_used(HomeAssistant hass, UFPConfigEntry entry, str breaks_in, dict[str, EntityRef] entities)
Definition: migrate.py:73
None async_migrate_data(HomeAssistant hass, UFPConfigEntry entry, ProtectApiClient protect, Bootstrap bootstrap)
Definition: migrate.py:107