Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Support for monitoring a Sense energy sensor."""
2 
3 from dataclasses import dataclass
4 from functools import partial
5 import logging
6 
7 from sense_energy import (
8  ASyncSenseable,
9  SenseAuthenticationException,
10  SenseMFARequiredException,
11 )
12 
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.const import CONF_TIMEOUT, Platform
15 from homeassistant.core import HomeAssistant
16 from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
17 from homeassistant.helpers.aiohttp_client import async_get_clientsession
18 
19 from .const import (
20  ACTIVE_UPDATE_RATE,
21  SENSE_CONNECT_EXCEPTIONS,
22  SENSE_TIMEOUT_EXCEPTIONS,
23  SENSE_WEBSOCKET_EXCEPTIONS,
24 )
25 from .coordinator import SenseRealtimeCoordinator, SenseTrendCoordinator
26 
27 _LOGGER = logging.getLogger(__name__)
28 
29 PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR]
30 type SenseConfigEntry = ConfigEntry[SenseData]
31 
32 
33 @dataclass(kw_only=True, slots=True)
34 class SenseData:
35  """Sense data type."""
36 
37  data: ASyncSenseable
38  trends: SenseTrendCoordinator
39  rt: SenseRealtimeCoordinator
40 
41 
42 async def async_setup_entry(hass: HomeAssistant, entry: SenseConfigEntry) -> bool:
43  """Set up Sense from a config entry."""
44 
45  entry_data = entry.data
46  timeout = entry_data[CONF_TIMEOUT]
47 
48  access_token = entry_data.get("access_token", "")
49  user_id = entry_data.get("user_id", "")
50  device_id = entry_data.get("device_id", "")
51  refresh_token = entry_data.get("refresh_token", "")
52  monitor_id = entry_data.get("monitor_id", "")
53 
54  client_session = async_get_clientsession(hass)
55 
56  # Creating the AsyncSenseable object loads
57  # ssl certificates which does blocking IO
58  gateway = await hass.async_add_executor_job(
59  partial(
60  ASyncSenseable,
61  api_timeout=timeout,
62  wss_timeout=timeout,
63  client_session=client_session,
64  )
65  )
66  gateway.rate_limit = ACTIVE_UPDATE_RATE
67 
68  try:
69  gateway.load_auth(access_token, user_id, device_id, refresh_token)
70  gateway.set_monitor_id(monitor_id)
71  await gateway.get_monitor_data()
72  except (SenseAuthenticationException, SenseMFARequiredException) as err:
73  _LOGGER.warning("Sense authentication expired")
74  raise ConfigEntryAuthFailed(err) from err
75  except SENSE_TIMEOUT_EXCEPTIONS as err:
76  raise ConfigEntryNotReady(
77  str(err) or "Timed out during authentication"
78  ) from err
79  except SENSE_CONNECT_EXCEPTIONS as err:
80  raise ConfigEntryNotReady(str(err)) from err
81 
82  try:
83  await gateway.fetch_devices()
84  await gateway.update_realtime()
85  except SENSE_TIMEOUT_EXCEPTIONS as err:
86  raise ConfigEntryNotReady(
87  str(err) or "Timed out during realtime update"
88  ) from err
89  except SENSE_WEBSOCKET_EXCEPTIONS as err:
90  raise ConfigEntryNotReady(str(err) or "Error during realtime update") from err
91 
92  trends_coordinator = SenseTrendCoordinator(hass, gateway)
93  realtime_coordinator = SenseRealtimeCoordinator(hass, gateway)
94 
95  # This can take longer than 60s and we already know
96  # sense is online since get_discovered_device_data was
97  # successful so we do it later.
98  entry.async_create_background_task(
99  hass,
100  trends_coordinator.async_request_refresh(),
101  "sense.trends-coordinator-refresh",
102  )
103  entry.async_create_background_task(
104  hass,
105  realtime_coordinator.async_request_refresh(),
106  "sense.realtime-coordinator-refresh",
107  )
108 
109  entry.runtime_data = SenseData(
110  data=gateway,
111  trends=trends_coordinator,
112  rt=realtime_coordinator,
113  )
114 
115  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
116  return True
117 
118 
119 async def async_unload_entry(hass: HomeAssistant, entry: SenseConfigEntry) -> bool:
120  """Unload a config entry."""
121  return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
bool async_unload_entry(HomeAssistant hass, SenseConfigEntry entry)
Definition: __init__.py:119
bool async_setup_entry(HomeAssistant hass, SenseConfigEntry entry)
Definition: __init__.py:42
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)