Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The PrusaLink integration."""
2 
3 from __future__ import annotations
4 
5 from pyprusalink import PrusaLink
6 from pyprusalink.types import InvalidAuth
7 
8 from homeassistant.config_entries import ConfigEntry
9 from homeassistant.const import (
10  CONF_API_KEY,
11  CONF_HOST,
12  CONF_PASSWORD,
13  CONF_USERNAME,
14  Platform,
15 )
16 from homeassistant.core import HomeAssistant
17 from homeassistant.exceptions import ConfigEntryError
18 from homeassistant.helpers import issue_registry as ir
19 from homeassistant.helpers.httpx_client import get_async_client
20 
21 from .config_flow import ConfigFlow
22 from .const import DOMAIN
23 from .coordinator import (
24  InfoUpdateCoordinator,
25  JobUpdateCoordinator,
26  LegacyStatusCoordinator,
27  StatusCoordinator,
28 )
29 
30 PLATFORMS: list[Platform] = [
31  Platform.BINARY_SENSOR,
32  Platform.BUTTON,
33  Platform.CAMERA,
34  Platform.SENSOR,
35 ]
36 
37 
38 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
39  """Set up PrusaLink from a config entry."""
40  if entry.version == 1 and entry.minor_version < 2:
41  raise ConfigEntryError("Please upgrade your printer's firmware.")
42 
43  api = PrusaLink(
44  get_async_client(hass),
45  entry.data[CONF_HOST],
46  entry.data[CONF_USERNAME],
47  entry.data[CONF_PASSWORD],
48  )
49 
50  coordinators = {
51  "legacy_status": LegacyStatusCoordinator(hass, api),
52  "status": StatusCoordinator(hass, api),
53  "job": JobUpdateCoordinator(hass, api),
54  "info": InfoUpdateCoordinator(hass, api),
55  }
56  for coordinator in coordinators.values():
57  await coordinator.async_config_entry_first_refresh()
58 
59  hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinators
60 
61  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
62 
63  return True
64 
65 
66 async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
67  """Migrate old entry."""
68  if config_entry.version > ConfigFlow.VERSION:
69  # This means the user has downgraded from a future version
70  return False
71 
72  new_data = dict(config_entry.data)
73  if config_entry.version == 1:
74  if config_entry.minor_version < 2:
75  # Add username and password
76  # "maker" is currently hardcoded in the firmware
77  # https://github.com/prusa3d/Prusa-Firmware-Buddy/blob/bfb0ffc745ee6546e7efdba618d0e7c0f4c909cd/lib/WUI/wui_api.h#L19
78  username = "maker"
79  password = config_entry.data[CONF_API_KEY]
80 
81  api = PrusaLink(
82  get_async_client(hass),
83  config_entry.data[CONF_HOST],
84  username,
85  password,
86  )
87  try:
88  await api.get_info()
89  except InvalidAuth:
90  # We are unable to reach the new API which usually means
91  # that the user is running an outdated firmware version
92  ir.async_create_issue(
93  hass,
94  DOMAIN,
95  "firmware_5_1_required",
96  is_fixable=False,
97  severity=ir.IssueSeverity.ERROR,
98  translation_key="firmware_5_1_required",
99  translation_placeholders={
100  "entry_title": config_entry.title,
101  "prusa_mini_firmware_update": "https://help.prusa3d.com/article/firmware-updating-mini-mini_124784",
102  "prusa_mk4_xl_firmware_update": "https://help.prusa3d.com/article/how-to-update-firmware-mk4-xl_453086",
103  },
104  )
105  # There is a check in the async_setup_entry to prevent the setup if minor_version < 2
106  # Currently we can't reload the config entry
107  # if the migration returns False.
108  # Return True here to workaround that.
109  return True
110 
111  new_data[CONF_USERNAME] = username
112  new_data[CONF_PASSWORD] = password
113 
114  ir.async_delete_issue(hass, DOMAIN, "firmware_5_1_required")
115  hass.config_entries.async_update_entry(
116  config_entry, data=new_data, minor_version=2
117  )
118 
119  return True
120 
121 
122 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
123  """Unload a config entry."""
124  if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
125  hass.data[DOMAIN].pop(entry.entry_id)
126 
127  return unload_ok
httpx.AsyncClient get_async_client(HomeAssistant hass, bool verify_ssl=True)
Definition: httpx_client.py:41