Move smart_meter_texas coordinator to separate module (#164926)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user