Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """The sma integration."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 from typing import TYPE_CHECKING
8 
9 import pysma
10 
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.const import (
13  CONF_HOST,
14  CONF_PASSWORD,
15  CONF_SCAN_INTERVAL,
16  CONF_SSL,
17  CONF_VERIFY_SSL,
18  EVENT_HOMEASSISTANT_STOP,
19 )
20 from homeassistant.core import HomeAssistant
21 from homeassistant.exceptions import ConfigEntryNotReady
22 from homeassistant.helpers.aiohttp_client import async_get_clientsession
23 from homeassistant.helpers.device_registry import DeviceInfo
24 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
25 
26 from .const import (
27  CONF_GROUP,
28  DEFAULT_SCAN_INTERVAL,
29  DOMAIN,
30  PLATFORMS,
31  PYSMA_COORDINATOR,
32  PYSMA_DEVICE_INFO,
33  PYSMA_OBJECT,
34  PYSMA_REMOVE_LISTENER,
35  PYSMA_SENSORS,
36 )
37 
38 _LOGGER = logging.getLogger(__name__)
39 
40 
41 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
42  """Set up sma from a config entry."""
43  # Init the SMA interface
44  protocol = "https" if entry.data[CONF_SSL] else "http"
45  url = f"{protocol}://{entry.data[CONF_HOST]}"
46  verify_ssl = entry.data[CONF_VERIFY_SSL]
47  group = entry.data[CONF_GROUP]
48  password = entry.data[CONF_PASSWORD]
49 
50  session = async_get_clientsession(hass, verify_ssl=verify_ssl)
51  sma = pysma.SMA(session, url, password, group)
52 
53  try:
54  # Get updated device info
55  sma_device_info = await sma.device_info()
56  # Get all device sensors
57  sensor_def = await sma.get_sensors()
58  except (
59  pysma.exceptions.SmaReadException,
60  pysma.exceptions.SmaConnectionException,
61  ) as exc:
62  raise ConfigEntryNotReady from exc
63 
64  if TYPE_CHECKING:
65  assert entry.unique_id
66 
67  # Create DeviceInfo object from sma_device_info
68  device_info = DeviceInfo(
69  configuration_url=url,
70  identifiers={(DOMAIN, entry.unique_id)},
71  manufacturer=sma_device_info["manufacturer"],
72  model=sma_device_info["type"],
73  name=sma_device_info["name"],
74  sw_version=sma_device_info["sw_version"],
75  )
76 
77  # Define the coordinator
78  async def async_update_data():
79  """Update the used SMA sensors."""
80  try:
81  await sma.read(sensor_def)
82  except (
83  pysma.exceptions.SmaReadException,
84  pysma.exceptions.SmaConnectionException,
85  ) as exc:
86  raise UpdateFailed(exc) from exc
87 
88  interval = timedelta(
89  seconds=entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
90  )
91 
92  coordinator = DataUpdateCoordinator(
93  hass,
94  _LOGGER,
95  config_entry=entry,
96  name="sma",
97  update_method=async_update_data,
98  update_interval=interval,
99  )
100 
101  try:
102  await coordinator.async_config_entry_first_refresh()
103  except ConfigEntryNotReady:
104  await sma.close_session()
105  raise
106 
107  # Ensure we logout on shutdown
108  async def async_close_session(event):
109  """Close the session."""
110  await sma.close_session()
111 
112  remove_stop_listener = hass.bus.async_listen_once(
113  EVENT_HOMEASSISTANT_STOP, async_close_session
114  )
115 
116  hass.data.setdefault(DOMAIN, {})
117  hass.data[DOMAIN][entry.entry_id] = {
118  PYSMA_OBJECT: sma,
119  PYSMA_COORDINATOR: coordinator,
120  PYSMA_SENSORS: sensor_def,
121  PYSMA_REMOVE_LISTENER: remove_stop_listener,
122  PYSMA_DEVICE_INFO: device_info,
123  }
124 
125  await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
126 
127  return True
128 
129 
130 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
131  """Unload a config entry."""
132  unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
133  if unload_ok:
134  data = hass.data[DOMAIN].pop(entry.entry_id)
135  await data[PYSMA_OBJECT].close_session()
136  data[PYSMA_REMOVE_LISTENER]()
137 
138  return unload_ok
139 
140 
141 async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
142  """Migrate entry."""
143 
144  _LOGGER.debug("Migrating from version %s", entry.version)
145 
146  if entry.version == 1:
147  # 1 -> 2: Unique ID from integer to string
148  if entry.minor_version == 1:
149  minor_version = 2
150  hass.config_entries.async_update_entry(
151  entry, unique_id=str(entry.unique_id), minor_version=minor_version
152  )
153 
154  _LOGGER.debug("Migration successful")
155 
156  return True
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:41
bool async_migrate_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:141
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:130
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)