Home Assistant Unofficial Reference 2024.12.1
coordinator.py
Go to the documentation of this file.
1 """Update coordinator for Goodwe."""
2 
3 from __future__ import annotations
4 
5 import logging
6 from typing import Any
7 
8 from goodwe import Inverter, InverterError, RequestFailedException
9 
10 from homeassistant.config_entries import ConfigEntry
11 from homeassistant.core import HomeAssistant
12 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
13 
14 from .const import SCAN_INTERVAL
15 
16 _LOGGER = logging.getLogger(__name__)
17 
18 
20  """Gather data for the energy device."""
21 
22  def __init__(
23  self,
24  hass: HomeAssistant,
25  entry: ConfigEntry,
26  inverter: Inverter,
27  ) -> None:
28  """Initialize update coordinator."""
29  super().__init__(
30  hass,
31  _LOGGER,
32  name=entry.title,
33  update_interval=SCAN_INTERVAL,
34  )
35  self.inverter: Inverter = inverter
36  self._last_data_last_data: dict[str, Any] = {}
37 
38  async def _async_update_data(self) -> dict[str, Any]:
39  """Fetch data from the inverter."""
40  try:
41  self._last_data_last_data = self.datadata if self.datadata else {}
42  return await self.inverter.read_runtime_data()
43  except RequestFailedException as ex:
44  # UDP communication with inverter is by definition unreliable.
45  # It is rather normal in many environments to fail to receive
46  # proper response in usual time, so we intentionally ignore isolated
47  # failures and report problem with availability only after
48  # consecutive streak of 3 of failed requests.
49  if ex.consecutive_failures_count < 3:
50  _LOGGER.debug(
51  "No response received (streak of %d)", ex.consecutive_failures_count
52  )
53  # return last known data
54  return self._last_data_last_data
55  # Inverter does not respond anymore (e.g. it went to sleep mode)
56  _LOGGER.debug(
57  "Inverter not responding (streak of %d)", ex.consecutive_failures_count
58  )
59  raise UpdateFailed(ex) from ex
60  except InverterError as ex:
61  raise UpdateFailed(ex) from ex
62 
63  def sensor_value(self, sensor: str) -> Any:
64  """Answer current (or last known) value of the sensor."""
65  val = self.datadata.get(sensor)
66  return val if val is not None else self._last_data_last_data.get(sensor)
67 
68  def total_sensor_value(self, sensor: str) -> Any:
69  """Answer current value of the 'total' (never 0) sensor."""
70  val = self.datadata.get(sensor)
71  return val if val else self._last_data_last_data.get(sensor)
72 
73  def reset_sensor(self, sensor: str) -> None:
74  """Reset sensor value to 0.
75 
76  Intended for "daily" cumulative sensors (e.g. PV energy produced today),
77  which should be explicitly reset to 0 at midnight if inverter is suspended.
78  """
79  self._last_data_last_data[sensor] = 0
80  self.datadata[sensor] = 0
None __init__(self, HomeAssistant hass, ConfigEntry entry, Inverter inverter)
Definition: coordinator.py:27
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88