Move smart_meter_texas coordinator to separate module (#164926)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
epenet
2026-03-06 20:11:38 +01:00
committed by GitHub
parent 2f7ac2b439
commit 1471cb93bc
3 changed files with 95 additions and 74 deletions
@@ -1,30 +1,17 @@
"""The Smart Meter Texas integration."""
import logging
import ssl
from smart_meter_texas import Account, Client
from smart_meter_texas.exceptions import (
SmartMeterTexasAPIError,
SmartMeterTexasAuthError,
)
from smart_meter_texas import Account
from smart_meter_texas.exceptions import SmartMeterTexasAuthError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util.ssl import get_default_context
from .const import (
DATA_COORDINATOR,
DATA_SMART_METER,
DEBOUNCE_COOLDOWN,
DOMAIN,
SCAN_INTERVAL,
)
from .const import DATA_COORDINATOR, DATA_SMART_METER, DOMAIN
from .coordinator import SmartMeterTexasCoordinator, SmartMeterTexasData
_LOGGER = logging.getLogger(__name__)
@@ -39,9 +26,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
account = Account(username, password)
ssl_context = get_default_context()
smart_meter_texas_data = SmartMeterTexasData(hass, entry, account, ssl_context)
smart_meter_texas_data = SmartMeterTexasData(hass, account)
try:
await smart_meter_texas_data.client.authenticate()
except SmartMeterTexasAuthError:
@@ -52,26 +37,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await smart_meter_texas_data.setup()
async def async_update_data():
_LOGGER.debug("Fetching latest data")
await smart_meter_texas_data.read_meters()
return smart_meter_texas_data
# Use a DataUpdateCoordinator to manage the updates. This is due to the
# Smart Meter Texas API which takes around 30 seconds to read a meter.
# This avoids Home Assistant from complaining about the component taking
# too long to update.
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
config_entry=entry,
name="Smart Meter Texas",
update_method=async_update_data,
update_interval=SCAN_INTERVAL,
request_refresh_debouncer=Debouncer(
hass, _LOGGER, cooldown=DEBOUNCE_COOLDOWN, immediate=True
),
)
coordinator = SmartMeterTexasCoordinator(hass, entry, smart_meter_texas_data)
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = {
@@ -88,38 +58,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
class SmartMeterTexasData:
"""Manages coordinatation of API data updates."""
def __init__(
self,
hass: HomeAssistant,
entry: ConfigEntry,
account: Account,
ssl_context: ssl.SSLContext,
) -> None:
"""Initialize the data coordintator."""
self._entry = entry
self.account = account
websession = aiohttp_client.async_get_clientsession(hass)
self.client = Client(websession, account, ssl_context=ssl_context)
self.meters: list = []
async def setup(self):
"""Fetch all of the user's meters."""
self.meters = await self.account.fetch_meters(self.client)
_LOGGER.debug("Discovered %s meter(s)", len(self.meters))
async def read_meters(self):
"""Read each meter."""
for meter in self.meters:
try:
await meter.read_meter(self.client)
except (SmartMeterTexasAPIError, SmartMeterTexasAuthError) as error:
raise UpdateFailed(error) from error
return self.meters
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
@@ -0,0 +1,83 @@
"""DataUpdateCoordinator for the Smart Meter Texas integration."""
import logging
from smart_meter_texas import Account, Client, Meter
from smart_meter_texas.exceptions import (
SmartMeterTexasAPIError,
SmartMeterTexasAuthError,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.util.ssl import get_default_context
from .const import DEBOUNCE_COOLDOWN, SCAN_INTERVAL
_LOGGER = logging.getLogger(__name__)
class SmartMeterTexasData:
"""Manages coordination of API data updates."""
def __init__(
self,
hass: HomeAssistant,
account: Account,
) -> None:
"""Initialize the data coordinator."""
self.account = account
self.client = Client(
aiohttp_client.async_get_clientsession(hass),
account,
ssl_context=get_default_context(),
)
self.meters: list[Meter] = []
async def setup(self) -> None:
"""Fetch all of the user's meters."""
self.meters = await self.account.fetch_meters(self.client)
_LOGGER.debug("Discovered %s meter(s)", len(self.meters))
async def read_meters(self) -> list[Meter]:
"""Read each meter."""
for meter in self.meters:
try:
await meter.read_meter(self.client)
except (SmartMeterTexasAPIError, SmartMeterTexasAuthError) as error:
raise UpdateFailed(error) from error
return self.meters
class SmartMeterTexasCoordinator(DataUpdateCoordinator[SmartMeterTexasData]):
"""Class to manage fetching Smart Meter Texas data."""
config_entry: ConfigEntry
def __init__(
self,
hass: HomeAssistant,
entry: ConfigEntry,
smart_meter_texas_data: SmartMeterTexasData,
) -> None:
"""Initialize the coordinator."""
super().__init__(
hass,
_LOGGER,
config_entry=entry,
name="Smart Meter Texas",
update_interval=SCAN_INTERVAL,
request_refresh_debouncer=Debouncer(
hass, _LOGGER, cooldown=DEBOUNCE_COOLDOWN, immediate=True
),
)
self._smart_meter_texas_data = smart_meter_texas_data
async def _async_update_data(self) -> SmartMeterTexasData:
"""Fetch latest data."""
_LOGGER.debug("Fetching latest data")
await self._smart_meter_texas_data.read_meters()
return self._smart_meter_texas_data
@@ -14,10 +14,7 @@ from homeassistant.const import CONF_ADDRESS, UnitOfEnergy
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
)
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import (
DATA_COORDINATOR,
@@ -27,6 +24,7 @@ from .const import (
ESIID,
METER_NUMBER,
)
from .coordinator import SmartMeterTexasCoordinator
async def async_setup_entry(
@@ -44,7 +42,9 @@ async def async_setup_entry(
# pylint: disable-next=hass-invalid-inheritance # needs fixing
class SmartMeterTexasSensor(CoordinatorEntity, RestoreEntity, SensorEntity):
class SmartMeterTexasSensor(
CoordinatorEntity[SmartMeterTexasCoordinator], RestoreEntity, SensorEntity
):
"""Representation of an Smart Meter Texas sensor."""
_attr_device_class = SensorDeviceClass.ENERGY
@@ -52,7 +52,7 @@ class SmartMeterTexasSensor(CoordinatorEntity, RestoreEntity, SensorEntity):
_attr_native_unit_of_measurement = UnitOfEnergy.KILO_WATT_HOUR
_attr_available = False
def __init__(self, meter: Meter, coordinator: DataUpdateCoordinator) -> None:
def __init__(self, meter: Meter, coordinator: SmartMeterTexasCoordinator) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self.meter = meter