Files
core/homeassistant/components/sma/coordinator.py
Johann Kellerman b116619af1 Bump pysma to 1.0.2 and enable type checking (#154977)
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-10-23 00:01:51 +03:00

115 lines
3.5 KiB
Python

"""Coordinator for the SMA integration."""
from __future__ import annotations
from dataclasses import dataclass
from datetime import timedelta
import logging
from pysma import (
SmaAuthenticationException,
SmaConnectionException,
SmaReadException,
SMAWebConnect,
)
from pysma.helpers import DeviceInfo
from pysma.sensor import Sensors
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_SCAN_INTERVAL
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN
_LOGGER = logging.getLogger(__name__)
@dataclass(slots=True)
class SMACoordinatorData:
"""Data class for SMA sensors."""
sma_device_info: DeviceInfo
sensors: Sensors
class SMADataUpdateCoordinator(DataUpdateCoordinator[SMACoordinatorData]):
"""Data Update Coordinator for SMA."""
config_entry: ConfigEntry
def __init__(
self,
hass: HomeAssistant,
config_entry: ConfigEntry,
sma: SMAWebConnect,
) -> None:
"""Initialize the SMA Data Update Coordinator."""
super().__init__(
hass,
_LOGGER,
config_entry=config_entry,
name=DOMAIN,
update_interval=timedelta(
seconds=config_entry.options.get(
CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
)
),
)
self.sma = sma
self._sma_device_info = DeviceInfo()
self._sensors = Sensors()
async def _async_setup(self) -> None:
"""Setup the SMA Data Update Coordinator."""
try:
self._sma_device_info = await self.sma.device_info()
self._sensors = await self.sma.get_sensors()
except (
SmaReadException,
SmaConnectionException,
) as err:
await self.async_close_sma_session()
raise ConfigEntryNotReady(
translation_domain=DOMAIN,
translation_key="cannot_connect",
translation_placeholders={"error": repr(err)},
) from err
except SmaAuthenticationException as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="invalid_auth",
translation_placeholders={"error": repr(err)},
) from err
async def _async_update_data(self) -> SMACoordinatorData:
"""Update the used SMA sensors."""
try:
await self.sma.read(self._sensors)
except (
SmaReadException,
SmaConnectionException,
) as err:
raise UpdateFailed(
translation_domain=DOMAIN,
translation_key="cannot_connect",
translation_placeholders={"error": repr(err)},
) from err
except SmaAuthenticationException as err:
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN,
translation_key="invalid_auth",
translation_placeholders={"error": repr(err)},
) from err
return SMACoordinatorData(
sma_device_info=self._sma_device_info,
sensors=self._sensors,
)
async def async_close_sma_session(self) -> None:
"""Close the SMA session."""
await self.sma.close_session()
_LOGGER.debug("SMA session closed")