Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """The data update coordinator for OctoPrint."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 from typing import cast
8 
9 from pyoctoprintapi import ApiError, OctoprintClient, PrinterOffline
10 from pyoctoprintapi.exceptions import UnauthorizedException
11 from yarl import URL
12 
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.const import CONF_HOST, CONF_PATH, CONF_PORT, CONF_SSL
15 from homeassistant.core import HomeAssistant
16 from homeassistant.exceptions import ConfigEntryAuthFailed
17 from homeassistant.helpers.device_registry import DeviceInfo
18 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
19 import homeassistant.util.dt as dt_util
20 
21 from .const import DOMAIN
22 
23 _LOGGER = logging.getLogger(__name__)
24 
25 
27  """Class to manage fetching Octoprint data."""
28 
29  config_entry: ConfigEntry
30 
31  def __init__(
32  self,
33  hass: HomeAssistant,
34  octoprint: OctoprintClient,
35  config_entry: ConfigEntry,
36  interval: int,
37  ) -> None:
38  """Initialize."""
39  super().__init__(
40  hass,
41  _LOGGER,
42  name=f"octoprint-{config_entry.entry_id}",
43  update_interval=timedelta(seconds=interval),
44  )
45  self.config_entryconfig_entryconfig_entry = config_entry
46  self._octoprint_octoprint = octoprint
47  self._printer_offline_printer_offline = False
48  self.datadatadata = {"printer": None, "job": None, "last_read_time": None}
49 
50  async def _async_update_data(self):
51  """Update data via API."""
52  printer = None
53  try:
54  job = await self._octoprint_octoprint.get_job_info()
55  except UnauthorizedException as err:
56  raise ConfigEntryAuthFailed from err
57  except ApiError as err:
58  raise UpdateFailed(err) from err
59 
60  # If octoprint is on, but the printer is disconnected
61  # printer will return a 409, so continue using the last
62  # reading if there is one
63  try:
64  printer = await self._octoprint_octoprint.get_printer_info()
65  except PrinterOffline:
66  if not self._printer_offline_printer_offline:
67  _LOGGER.debug("Unable to retrieve printer information: Printer offline")
68  self._printer_offline_printer_offline = True
69  except UnauthorizedException as err:
70  raise ConfigEntryAuthFailed from err
71  except ApiError as err:
72  raise UpdateFailed(err) from err
73  else:
74  self._printer_offline_printer_offline = False
75 
76  return {"job": job, "printer": printer, "last_read_time": dt_util.utcnow()}
77 
78  @property
79  def device_info(self) -> DeviceInfo:
80  """Device info."""
81  unique_id = cast(str, self.config_entryconfig_entryconfig_entry.unique_id)
82  configuration_url = URL.build(
83  scheme=self.config_entryconfig_entryconfig_entry.data[CONF_SSL] and "https" or "http",
84  host=self.config_entryconfig_entryconfig_entry.data[CONF_HOST],
85  port=self.config_entryconfig_entryconfig_entry.data[CONF_PORT],
86  path=self.config_entryconfig_entryconfig_entry.data[CONF_PATH],
87  )
88 
89  return DeviceInfo(
90  identifiers={(DOMAIN, unique_id)},
91  manufacturer="OctoPrint",
92  name="OctoPrint",
93  configuration_url=str(configuration_url),
94  )
None __init__(self, HomeAssistant hass, OctoprintClient octoprint, ConfigEntry config_entry, int interval)
Definition: coordinator.py:37