Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The Smart Meter Texas integration."""
2 
3 import logging
4 import ssl
5 
6 from smart_meter_texas import Account, Client, ClientSSLContext
7 from smart_meter_texas.exceptions import (
8  SmartMeterTexasAPIError,
9  SmartMeterTexasAuthError,
10 )
11 
12 from homeassistant.config_entries import ConfigEntry
13 from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
14 from homeassistant.core import HomeAssistant
15 from homeassistant.exceptions import ConfigEntryNotReady
16 from homeassistant.helpers import aiohttp_client
17 from homeassistant.helpers.debounce import Debouncer
18 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
19 
20 from .const import (
21  DATA_COORDINATOR,
22  DATA_SMART_METER,
23  DEBOUNCE_COOLDOWN,
24  DOMAIN,
25  SCAN_INTERVAL,
26 )
27 
28 _LOGGER = logging.getLogger(__name__)
29 
30 PLATFORMS = [Platform.SENSOR]
31 
32 
33 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
34  """Set up Smart Meter Texas from a config entry."""
35 
36  username = entry.data[CONF_USERNAME]
37  password = entry.data[CONF_PASSWORD]
38 
39  account = Account(username, password)
40 
41  client_ssl_context = ClientSSLContext()
42  ssl_context = await client_ssl_context.get_ssl_context()
43 
44  smart_meter_texas_data = SmartMeterTexasData(hass, entry, account, ssl_context)
45  try:
46  await smart_meter_texas_data.client.authenticate()
47  except SmartMeterTexasAuthError:
48  _LOGGER.error("Username or password was not accepted")
49  return False
50  except TimeoutError as error:
51  raise ConfigEntryNotReady from error
52 
53  await smart_meter_texas_data.setup()
54 
55  async def async_update_data():
56  _LOGGER.debug("Fetching latest data")
57  await smart_meter_texas_data.read_meters()
58  return smart_meter_texas_data
59 
60  # Use a DataUpdateCoordinator to manage the updates. This is due to the
61  # Smart Meter Texas API which takes around 30 seconds to read a meter.
62  # This avoids Home Assistant from complaining about the component taking
63  # too long to update.
64  coordinator = DataUpdateCoordinator(
65  hass,
66  _LOGGER,
67  config_entry=entry,
68  name="Smart Meter Texas",
69  update_method=async_update_data,
70  update_interval=SCAN_INTERVAL,
71  request_refresh_debouncer=Debouncer(
72  hass, _LOGGER, cooldown=DEBOUNCE_COOLDOWN, immediate=True
73  ),
74  )
75 
76  hass.data.setdefault(DOMAIN, {})
77  hass.data[DOMAIN][entry.entry_id] = {
78  DATA_COORDINATOR: coordinator,
79  DATA_SMART_METER: smart_meter_texas_data,
80  }
81 
82  entry.async_create_background_task(
83  hass, coordinator.async_refresh(), "smart_meter_texas-coordinator-refresh"
84  )
85 
86  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
87 
88  return True
89 
90 
92  """Manages coordinatation of API data updates."""
93 
94  def __init__(
95  self,
96  hass: HomeAssistant,
97  entry: ConfigEntry,
98  account: Account,
99  ssl_context: ssl.SSLContext,
100  ) -> None:
101  """Initialize the data coordintator."""
102  self._entry_entry = entry
103  self.accountaccount = account
104  websession = aiohttp_client.async_get_clientsession(hass)
105  self.clientclient = Client(websession, account, ssl_context=ssl_context)
106  self.metersmeters: list = []
107 
108  async def setup(self):
109  """Fetch all of the user's meters."""
110  self.metersmeters = await self.accountaccount.fetch_meters(self.clientclient)
111  _LOGGER.debug("Discovered %s meter(s)", len(self.metersmeters))
112 
113  async def read_meters(self):
114  """Read each meter."""
115  for meter in self.metersmeters:
116  try:
117  await meter.read_meter(self.clientclient)
118  except (SmartMeterTexasAPIError, SmartMeterTexasAuthError) as error:
119  raise UpdateFailed(error) from error
120  return self.metersmeters
121 
122 
123 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
124  """Unload a config entry."""
125  unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
126  if unload_ok:
127  hass.data[DOMAIN].pop(entry.entry_id)
128 
129  return unload_ok
None __init__(self, HomeAssistant hass, ConfigEntry entry, Account account, ssl.SSLContext ssl_context)
Definition: __init__.py:100
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:123
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:33