Home Assistant Unofficial Reference 2024.12.1
update.py
Go to the documentation of this file.
1 """Support for RainMachine updates."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 from enum import Enum
7 from typing import Any
8 
9 from regenmaschine.errors import RequestError
10 
12  UpdateDeviceClass,
13  UpdateEntity,
14  UpdateEntityDescription,
15  UpdateEntityFeature,
16 )
17 from homeassistant.core import HomeAssistant, callback
18 from homeassistant.exceptions import HomeAssistantError
19 from homeassistant.helpers.entity_platform import AddEntitiesCallback
20 
21 from . import RainMachineConfigEntry
22 from .const import DATA_MACHINE_FIRMWARE_UPDATE_STATUS
23 from .entity import RainMachineEntity, RainMachineEntityDescription
24 
25 
26 class UpdateStates(Enum):
27  """Define an enum for update states."""
28 
29  IDLE = 1
30  CHECKING = 2
31  DOWNLOADING = 3
32  UPGRADING = 4
33  ERROR = 5
34  REBOOT = 6
35 
36 
37 UPDATE_STATE_MAP = {
38  1: UpdateStates.IDLE,
39  2: UpdateStates.CHECKING,
40  3: UpdateStates.DOWNLOADING,
41  4: UpdateStates.UPGRADING,
42  5: UpdateStates.ERROR,
43  6: UpdateStates.REBOOT,
44 }
45 
46 
47 @dataclass(frozen=True, kw_only=True)
49  UpdateEntityDescription, RainMachineEntityDescription
50 ):
51  """Describe a RainMachine update."""
52 
53 
55  key="update",
56  api_category=DATA_MACHINE_FIRMWARE_UPDATE_STATUS,
57 )
58 
59 
61  hass: HomeAssistant,
62  entry: RainMachineConfigEntry,
63  async_add_entities: AddEntitiesCallback,
64 ) -> None:
65  """Set up Rainmachine update based on a config entry."""
66  data = entry.runtime_data
67  async_add_entities([RainMachineUpdateEntity(entry, data, UPDATE_DESCRIPTION)])
68 
69 
71  """Define a RainMachine update entity."""
72 
73  _attr_device_class = UpdateDeviceClass.FIRMWARE
74  _attr_name = None
75  _attr_supported_features = (
76  UpdateEntityFeature.INSTALL
77  | UpdateEntityFeature.PROGRESS
78  | UpdateEntityFeature.SPECIFIC_VERSION
79  )
80 
81  async def async_install(
82  self, version: str | None, backup: bool, **kwargs: Any
83  ) -> None:
84  """Install an update."""
85  try:
86  await self._data_data.controller.machine.update_firmware()
87  except RequestError as err:
88  raise HomeAssistantError(f"Error while updating firmware: {err}") from err
89 
90  await self.coordinator.async_refresh()
91 
92  @callback
93  def update_from_latest_data(self) -> None:
94  """Update the state."""
95  if version := self._version_coordinator_version_coordinator.data["swVer"]:
96  self._attr_installed_version_attr_installed_version = version
97  else:
98  self._attr_installed_version_attr_installed_version = None
99 
100  data = self.coordinator.data
101 
102  if not data["update"]:
103  self._attr_in_progress_attr_in_progress_attr_in_progress = False
104  self._attr_latest_version_attr_latest_version = self._attr_installed_version_attr_installed_version
105  return
106 
107  self._attr_in_progress_attr_in_progress_attr_in_progress = UPDATE_STATE_MAP[data["updateStatus"]] in (
108  UpdateStates.DOWNLOADING,
109  UpdateStates.UPGRADING,
110  UpdateStates.REBOOT,
111  )
112 
113  # The RainMachine API docs say that multiple "packages" can be updated, but
114  # don't give details on what types exist (which makes it impossible to have
115  # update entities per update type); so, we use the first one (with the idea that
116  # after it succeeds, the entity will show the next update):
117  package_details = data["packageDetails"][0]
118  self._attr_latest_version_attr_latest_version = package_details["newVersion"]
119  self._attr_title_attr_title = package_details["packageName"]
None async_install(self, str|None version, bool backup, **Any kwargs)
Definition: update.py:83
None async_setup_entry(HomeAssistant hass, RainMachineConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: update.py:64