1
mirror of https://github.com/home-assistant/core synced 2024-08-28 03:36:46 +02:00

Avoid unnecessary domain dataclass in Discovergy (#106869)

This commit is contained in:
Jan-Philipp Benecke 2024-01-02 13:28:55 +01:00 committed by GitHub
parent f0132a6b88
commit d2a03a4706
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 27 additions and 45 deletions

View File

@ -1,12 +1,9 @@
"""The Discovergy integration.""" """The Discovergy integration."""
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass
from pydiscovergy import Discovergy from pydiscovergy import Discovergy
from pydiscovergy.authentication import BasicAuth from pydiscovergy.authentication import BasicAuth
import pydiscovergy.error as discovergyError import pydiscovergy.error as discovergyError
from pydiscovergy.models import Meter
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform
@ -20,35 +17,21 @@ from .coordinator import DiscovergyUpdateCoordinator
PLATFORMS = [Platform.SENSOR] PLATFORMS = [Platform.SENSOR]
@dataclass
class DiscovergyData:
"""Discovergy data class to share meters and api client."""
api_client: Discovergy
meters: list[Meter]
coordinators: dict[str, DiscovergyUpdateCoordinator]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Discovergy from a config entry.""" """Set up Discovergy from a config entry."""
hass.data.setdefault(DOMAIN, {}) hass.data.setdefault(DOMAIN, {})
# init discovergy data class client = Discovergy(
discovergy_data = DiscovergyData( email=entry.data[CONF_EMAIL],
api_client=Discovergy( password=entry.data[CONF_PASSWORD],
email=entry.data[CONF_EMAIL], httpx_client=get_async_client(hass),
password=entry.data[CONF_PASSWORD], authentication=BasicAuth(),
httpx_client=get_async_client(hass),
authentication=BasicAuth(),
),
meters=[],
coordinators={},
) )
try: try:
# try to get meters from api to check if credentials are still valid and for later use # try to get meters from api to check if credentials are still valid and for later use
# if no exception is raised everything is fine to go # if no exception is raised everything is fine to go
discovergy_data.meters = await discovergy_data.api_client.meters() meters = await client.meters()
except discovergyError.InvalidLogin as err: except discovergyError.InvalidLogin as err:
raise ConfigEntryAuthFailed("Invalid email or password") from err raise ConfigEntryAuthFailed("Invalid email or password") from err
except Exception as err: except Exception as err:
@ -57,19 +40,19 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
) from err ) from err
# Init coordinators for meters # Init coordinators for meters
for meter in discovergy_data.meters: coordinators = []
for meter in meters:
# Create coordinator for meter, set config entry and fetch initial data, # Create coordinator for meter, set config entry and fetch initial data,
# so we have data when entities are added # so we have data when entities are added
coordinator = DiscovergyUpdateCoordinator( coordinator = DiscovergyUpdateCoordinator(
hass=hass, hass=hass,
meter=meter, meter=meter,
discovergy_client=discovergy_data.api_client, discovergy_client=client,
) )
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
coordinators.append(coordinator)
discovergy_data.coordinators[meter.meter_id] = coordinator hass.data[DOMAIN][entry.entry_id] = coordinators
hass.data[DOMAIN][entry.entry_id] = discovergy_data
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
entry.async_on_unload(entry.add_update_listener(async_reload_entry)) entry.async_on_unload(entry.add_update_listener(async_reload_entry))

View File

@ -8,12 +8,11 @@ from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from . import DiscovergyData
from .const import DOMAIN from .const import DOMAIN
from .coordinator import DiscovergyUpdateCoordinator
TO_REDACT_METER = { TO_REDACT_METER = {
"serial_number", "serial_number",
"full_serial_number",
"location", "location",
"full_serial_number", "full_serial_number",
"printed_full_serial_number", "printed_full_serial_number",
@ -27,15 +26,16 @@ async def async_get_config_entry_diagnostics(
"""Return diagnostics for a config entry.""" """Return diagnostics for a config entry."""
flattened_meter: list[dict] = [] flattened_meter: list[dict] = []
last_readings: dict[str, dict] = {} last_readings: dict[str, dict] = {}
data: DiscovergyData = hass.data[DOMAIN][entry.entry_id] coordinators: list[DiscovergyUpdateCoordinator] = hass.data[DOMAIN][entry.entry_id]
for meter in data.meters: for coordinator in coordinators:
# make a dict of meter data and redact some data # make a dict of meter data and redact some data
flattened_meter.append(async_redact_data(asdict(meter), TO_REDACT_METER)) flattened_meter.append(
async_redact_data(asdict(coordinator.meter), TO_REDACT_METER)
)
# get last reading for meter and make a dict of it # get last reading for meter and make a dict of it
coordinator = data.coordinators[meter.meter_id] last_readings[coordinator.meter.meter_id] = asdict(coordinator.data)
last_readings[meter.meter_id] = asdict(coordinator.data)
return { return {
"meters": flattened_meter, "meters": flattened_meter,

View File

@ -3,7 +3,7 @@ from collections.abc import Callable
from dataclasses import dataclass, field from dataclasses import dataclass, field
from datetime import datetime from datetime import datetime
from pydiscovergy.models import Meter, Reading from pydiscovergy.models import Reading
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@ -24,8 +24,8 @@ from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import DiscovergyData, DiscovergyUpdateCoordinator
from .const import DOMAIN, MANUFACTURER from .const import DOMAIN, MANUFACTURER
from .coordinator import DiscovergyUpdateCoordinator
def _get_and_scale(reading: Reading, key: str, scale: int) -> datetime | float | None: def _get_and_scale(reading: Reading, key: str, scale: int) -> datetime | float | None:
@ -165,21 +165,20 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None: ) -> None:
"""Set up the Discovergy sensors.""" """Set up the Discovergy sensors."""
data: DiscovergyData = hass.data[DOMAIN][entry.entry_id] coordinators: list[DiscovergyUpdateCoordinator] = hass.data[DOMAIN][entry.entry_id]
entities: list[DiscovergySensor] = [] entities: list[DiscovergySensor] = []
for meter in data.meters: for coordinator in coordinators:
sensors: tuple[DiscovergySensorEntityDescription, ...] = () sensors: tuple[DiscovergySensorEntityDescription, ...] = ()
coordinator: DiscovergyUpdateCoordinator = data.coordinators[meter.meter_id]
# select sensor descriptions based on meter type and combine with additional sensors # select sensor descriptions based on meter type and combine with additional sensors
if meter.measurement_type == "ELECTRICITY": if coordinator.meter.measurement_type == "ELECTRICITY":
sensors = ELECTRICITY_SENSORS + ADDITIONAL_SENSORS sensors = ELECTRICITY_SENSORS + ADDITIONAL_SENSORS
elif meter.measurement_type == "GAS": elif coordinator.meter.measurement_type == "GAS":
sensors = GAS_SENSORS + ADDITIONAL_SENSORS sensors = GAS_SENSORS + ADDITIONAL_SENSORS
entities.extend( entities.extend(
DiscovergySensor(value_key, description, meter, coordinator) DiscovergySensor(value_key, description, coordinator)
for description in sensors for description in sensors
for value_key in {description.key, *description.alternative_keys} for value_key in {description.key, *description.alternative_keys}
if description.value_fn(coordinator.data, value_key, description.scale) if description.value_fn(coordinator.data, value_key, description.scale)
@ -200,15 +199,15 @@ class DiscovergySensor(CoordinatorEntity[DiscovergyUpdateCoordinator], SensorEnt
self, self,
data_key: str, data_key: str,
description: DiscovergySensorEntityDescription, description: DiscovergySensorEntityDescription,
meter: Meter,
coordinator: DiscovergyUpdateCoordinator, coordinator: DiscovergyUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
super().__init__(coordinator) super().__init__(coordinator)
self.data_key = data_key self.data_key = data_key
self.entity_description = description self.entity_description = description
meter = coordinator.meter
self._attr_unique_id = f"{meter.full_serial_number}-{data_key}" self._attr_unique_id = f"{meter.full_serial_number}-{data_key}"
self._attr_device_info = DeviceInfo( self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, meter.meter_id)}, identifiers={(DOMAIN, meter.meter_id)},