Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """DataUpdateCoordinator for the aurora_abb_powerone integration."""
2 
3 import logging
4 from time import sleep
5 
6 from aurorapy.client import AuroraError, AuroraSerialClient, AuroraTimeoutError
7 from serial import SerialException
8 
9 from homeassistant.config_entries import ConfigEntry
10 from homeassistant.core import HomeAssistant
11 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
12 
13 from .const import DOMAIN, SCAN_INTERVAL
14 
15 _LOGGER = logging.getLogger(__name__)
16 
17 
18 type AuroraAbbConfigEntry = ConfigEntry[AuroraAbbDataUpdateCoordinator]
19 
20 
22  """Class to manage fetching AuroraAbbPowerone data."""
23 
24  def __init__(self, hass: HomeAssistant, comport: str, address: int) -> None:
25  """Initialize the data update coordinator."""
26  self.available_prevavailable_prev = False
27  self.availableavailable = False
28  self.clientclient = AuroraSerialClient(address, comport, parity="N", timeout=1)
29  super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)
30 
31  def _update_data(self) -> dict[str, float]:
32  """Fetch new state data for the sensors.
33 
34  This is the only function that should fetch new data for Home Assistant.
35  """
36  data: dict[str, float] = {}
37  self.available_prevavailable_prev = self.availableavailable
38  retries: int = 3
39  while retries > 0:
40  try:
41  self.clientclient.connect()
42 
43  # See command 59 in the protocol manual linked in __init__.py
44  grid_voltage = self.clientclient.measure(1, True)
45  grid_current = self.clientclient.measure(2, True)
46  power_watts = self.clientclient.measure(3, True)
47  frequency = self.clientclient.measure(4)
48  i_leak_dcdc = self.clientclient.measure(6)
49  i_leak_inverter = self.clientclient.measure(7)
50  temperature_c = self.clientclient.measure(21)
51  r_iso = self.clientclient.measure(30)
52  energy_wh = self.clientclient.cumulated_energy(5)
53  [alarm, *_] = self.clientclient.alarms()
54  except AuroraTimeoutError:
55  self.availableavailable = False
56  _LOGGER.debug("No response from inverter (could be dark)")
57  retries = 0
58  except (SerialException, AuroraError) as error:
59  self.availableavailable = False
60  retries -= 1
61  if retries <= 0:
62  raise UpdateFailed(error) from error
63  _LOGGER.debug(
64  "Exception: %s occurred, %d retries remaining",
65  repr(error),
66  retries,
67  )
68  sleep(1)
69  else:
70  data["grid_voltage"] = round(grid_voltage, 1)
71  data["grid_current"] = round(grid_current, 1)
72  data["instantaneouspower"] = round(power_watts, 1)
73  data["grid_frequency"] = round(frequency, 1)
74  data["i_leak_dcdc"] = i_leak_dcdc
75  data["i_leak_inverter"] = i_leak_inverter
76  data["temp"] = round(temperature_c, 1)
77  data["r_iso"] = r_iso
78  data["totalenergy"] = round(energy_wh / 1000, 2)
79  data["alarm"] = alarm
80  self.availableavailable = True
81  retries = 0
82  finally:
83  if self.availableavailable != self.available_prevavailable_prev:
84  if self.availableavailable:
85  _LOGGER.warning("Communication with %s back online", self.namename)
86  else:
87  _LOGGER.warning(
88  "Communication with %s lost",
89  self.namename,
90  )
91  if self.clientclient.serline.isOpen():
92  self.clientclient.close()
93 
94  return data
95 
96  async def _async_update_data(self) -> dict[str, float]:
97  """Update inverter data in the executor."""
98  return await self.hasshass.async_add_executor_job(self._update_data_update_data)
None __init__(self, HomeAssistant hass, str comport, int address)
Definition: coordinator.py:24