1 """Manager to set up IO with Crownstone devices for a config entry."""
3 from __future__
import annotations
8 from crownstone_cloud
import CrownstoneCloud
9 from crownstone_cloud.exceptions
import (
10 CrownstoneAuthenticationError,
11 CrownstoneUnknownError,
13 from crownstone_sse
import CrownstoneSSEAsync
14 from crownstone_uart
import CrownstoneUart, UartEventBus
15 from crownstone_uart.Exceptions
import UartException
34 from .helpers
import get_port
35 from .listeners
import setup_sse_listeners, setup_uart_listeners
37 _LOGGER = logging.getLogger(__name__)
41 """Manage a Crownstone config entry."""
43 uart: CrownstoneUart |
None =
None
44 cloud: CrownstoneCloud
45 sse: CrownstoneSSEAsync
47 def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) ->
None:
48 """Initialize the hub."""
51 self.listeners: dict[str, Any] = {}
55 """Set up a Crownstone config entry.
57 Returns True if the setup was successful.
60 password = self.
config_entryconfig_entry.data[CONF_PASSWORD]
62 self.
cloudcloud = CrownstoneCloud(
65 clientsession=aiohttp_client.async_get_clientsession(self.
hasshass),
69 await self.
cloudcloud.async_initialize()
70 except CrownstoneAuthenticationError
as auth_err:
72 "Auth error during login with type: %s and message: %s",
77 except CrownstoneUnknownError
as unknown_err:
78 _LOGGER.error(
"Unknown error during login")
79 raise ConfigEntryNotReady
from unknown_err
82 self.
ssesse = CrownstoneSSEAsync(
85 access_token=self.
cloudcloud.access_token,
86 websession=aiohttp_client.async_create_clientsession(self.
hasshass),
87 project_name=PROJECT_NAME,
90 self.
config_entryconfig_entry.async_create_background_task(
96 if self.
config_entryconfig_entry.options[CONF_USB_PATH]
is not None:
103 await self.
hasshass.config_entries.async_forward_entry_setups(
109 self.
config_entryconfig_entry.add_update_listener(_async_update_listener)
112 self.
hasshass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self.
on_shutdownon_shutdown)
118 """Asynchronous iteration of Crownstone SSE events."""
119 async
with sse_client
as client:
120 async
for event
in client:
121 if event
is not None:
125 """Attempt setup of a Crownstone usb dongle."""
127 serial_port = await self.
hasshass.async_add_executor_job(
128 get_port, self.
config_entryconfig_entry.options[CONF_USB_PATH]
130 if serial_port
is None:
133 self.
uartuart = CrownstoneUart()
136 await self.
uartuart.initialize_usb(serial_port)
137 except UartException:
140 updated_options = self.
config_entryconfig_entry.options.copy()
141 updated_options[CONF_USB_PATH] =
None
142 updated_options[CONF_USB_SPHERE] =
None
144 self.
hasshass.config_entries.async_update_entry(
148 persistent_notification.async_create(
151 "Setup of Crownstone USB dongle was unsuccessful on port"
152 f
" {serial_port}.\n Crownstone Cloud will be used"
153 " to switch Crownstones.\n Please check if your"
154 " port is correct and set up the USB again from integration"
158 "crownstone_usb_dongle_setup",
165 """Unload the current config entry."""
167 if self.
cloudcloud.cloud_data
is None:
170 self.
ssesse.close_client()
171 for sse_unsub
in self.listeners[SSE_LISTENERS]:
176 for subscription_id
in self.listeners[UART_LISTENERS]:
177 UartEventBus.unsubscribe(subscription_id)
179 unload_ok = await self.
hasshass.config_entries.async_unload_platforms(
190 """Close all IO connections."""
191 self.
ssesse.close_client()
197 """Handle options update."""
198 await hass.config_entries.async_reload(entry.entry_id)
None async_process_events(self, CrownstoneSSEAsync sse_client)
None __init__(self, HomeAssistant hass, ConfigEntry config_entry)
None on_shutdown(self, Event _)
None async_setup_usb(self)
None _async_update_listener(HomeAssistant hass, ConfigEntry entry)
None setup_sse_listeners(CrownstoneEntryManager manager)
None setup_uart_listeners(CrownstoneEntryManager manager)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)