mirror of
https://github.com/home-assistant/core.git
synced 2026-04-20 08:29:39 +02:00
tibber refactor
Signed-off-by: Daniel Hjelseth Høyer <github@dahoiv.net>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
|
||||
import aiohttp
|
||||
@@ -38,8 +38,8 @@ class TibberRuntimeData:
|
||||
"""Runtime data for Tibber API entries."""
|
||||
|
||||
session: OAuth2Session
|
||||
data_api_coordinator: TibberDataAPICoordinator | None = field(default=None)
|
||||
data_coordinator: TibberDataCoordinator | None = field(default=None)
|
||||
data_api_coordinator: TibberDataAPICoordinator
|
||||
data_coordinator: TibberDataCoordinator
|
||||
_client: tibber.Tibber | None = None
|
||||
|
||||
async def async_get_client(self, hass: HomeAssistant) -> tibber.Tibber:
|
||||
@@ -101,8 +101,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: TibberConfigEntry) -> bo
|
||||
except ClientError as err:
|
||||
raise ConfigEntryNotReady from err
|
||||
|
||||
data_api_coordinator = TibberDataAPICoordinator(hass, entry)
|
||||
await data_api_coordinator.async_config_entry_first_refresh()
|
||||
data_coordinator = TibberDataCoordinator(hass, entry, entry.runtime_data)
|
||||
await data_coordinator.async_config_entry_first_refresh()
|
||||
await data_coordinator.update_listeners(dt_util.utcnow())
|
||||
entry.runtime_data = TibberRuntimeData(
|
||||
session=session,
|
||||
data_api_coordinator=data_api_coordinator,
|
||||
data_coordinator=data_coordinator,
|
||||
)
|
||||
|
||||
tibber_connection = await entry.runtime_data.async_get_client(hass)
|
||||
@@ -125,14 +132,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: TibberConfigEntry) -> bo
|
||||
except tibber.FatalHttpExceptionError as err:
|
||||
raise ConfigEntryNotReady("Fatal HTTP error from Tibber API") from err
|
||||
|
||||
data_api_coordinator = TibberDataAPICoordinator(hass, entry)
|
||||
await data_api_coordinator.async_config_entry_first_refresh()
|
||||
entry.runtime_data.data_api_coordinator = data_api_coordinator
|
||||
|
||||
data_coordinator = TibberDataCoordinator(hass, entry, entry.runtime_data)
|
||||
await data_coordinator.async_config_entry_first_refresh()
|
||||
entry.runtime_data.data_coordinator = data_coordinator
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
return True
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, UnitOfEnergy
|
||||
from homeassistant.core import Event, HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||
from homeassistant.helpers.event import async_track_point_in_utc_time
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.util.unit_conversion import EnergyConverter
|
||||
@@ -109,9 +110,33 @@ class TibberDataCoordinator(DataUpdateCoordinator[dict[str, TibberHomeData]]):
|
||||
_LOGGER,
|
||||
config_entry=config_entry,
|
||||
name="Tibber",
|
||||
update_interval=timedelta(minutes=15),
|
||||
)
|
||||
self._runtime_data = runtime_data
|
||||
self._listener_unsub: Callable[[], None] | None = None
|
||||
|
||||
def _get_next_15_interval(self, now: datetime) -> datetime:
|
||||
"""Compute next time we need to notify listeners (minutes 0, 15, 30, 45)."""
|
||||
next_run = dt_util.utcnow() + timedelta(minutes=15)
|
||||
next_minute = next_run.minute // 15 * 15
|
||||
return next_run.replace(
|
||||
minute=next_minute, second=0, microsecond=0, tzinfo=dt_util.UTC
|
||||
)
|
||||
|
||||
async def async_shutdown(self) -> None:
|
||||
"""Cancel any scheduled listener updates."""
|
||||
await super().async_shutdown()
|
||||
if self._listener_unsub:
|
||||
self._listener_unsub()
|
||||
self._listener_unsub = None
|
||||
|
||||
async def update_listeners(self, now: datetime) -> None:
|
||||
"""Notify listeners at 15-min boundaries."""
|
||||
self._listener_unsub = async_track_point_in_utc_time(
|
||||
self.hass,
|
||||
self.update_listeners,
|
||||
self._get_next_15_interval(now),
|
||||
)
|
||||
self.async_update_listeners()
|
||||
|
||||
async def _async_update_data(self) -> dict[str, TibberHomeData]:
|
||||
"""Update data via API and return per-home data for sensors."""
|
||||
|
||||
@@ -113,7 +113,7 @@ RT_SENSORS: tuple[SensorEntityDescription, ...] = (
|
||||
translation_key="accumulated_consumption",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="accumulatedConsumptionLastHour",
|
||||
@@ -641,14 +641,14 @@ async def _async_setup_graphql_sensors(
|
||||
entry: TibberConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up the Tibber GraphQL-based sensors."""
|
||||
"""Set up the Tibber sensor."""
|
||||
|
||||
tibber_connection = await entry.runtime_data.async_get_client(hass)
|
||||
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
coordinator: TibberDataCoordinator = entry.runtime_data.data_coordinator
|
||||
entities: list[TibberSensor] = []
|
||||
coordinator = entry.runtime_data.data_coordinator
|
||||
for home in tibber_connection.get_homes(only_active=False):
|
||||
try:
|
||||
await home.update_info()
|
||||
@@ -663,7 +663,7 @@ async def _async_setup_graphql_sensors(
|
||||
_LOGGER.error("Error connecting to Tibber home: %s ", err)
|
||||
raise PlatformNotReady from err
|
||||
|
||||
if coordinator is not None and home.has_active_subscription:
|
||||
if home.has_active_subscription:
|
||||
entities.extend(TibberSensor(home, coordinator, desc) for desc in SENSORS)
|
||||
|
||||
if home.has_real_time_consumption:
|
||||
@@ -689,8 +689,6 @@ def _setup_data_api_sensors(
|
||||
"""Set up sensors backed by the Tibber Data API."""
|
||||
|
||||
coordinator = entry.runtime_data.data_api_coordinator
|
||||
if coordinator is None:
|
||||
return
|
||||
|
||||
entities: list[TibberDataAPISensor] = []
|
||||
api_sensors = {sensor.key: sensor for sensor in DATA_API_SENSORS}
|
||||
|
||||
Reference in New Issue
Block a user