1 """The Fjäråskupan integration."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
9 from fjaraskupan
import Device
12 BluetoothCallbackMatcher,
14 BluetoothScanningMode,
15 BluetoothServiceInfoBleak,
16 async_rediscover_address,
17 async_register_callback,
25 async_dispatcher_connect,
26 async_dispatcher_send,
31 from .const
import DISPATCH_DETECTION, DOMAIN
32 from .coordinator
import FjaraskupanCoordinator
35 Platform.BINARY_SENSOR,
42 _LOGGER = logging.getLogger(__name__)
47 """Store state of config entry."""
49 coordinators: dict[str, FjaraskupanCoordinator]
53 """Set up Fjäråskupan from a config entry."""
56 hass.data.setdefault(DOMAIN, {})
57 hass.data[DOMAIN][entry.entry_id] = state
59 def detection_callback(
60 service_info: BluetoothServiceInfoBleak, change: BluetoothChange
62 if change != BluetoothChange.ADVERTISEMENT:
64 if data := state.coordinators.get(service_info.address):
65 _LOGGER.debug(
"Update: %s", service_info)
66 data.detection_callback(service_info)
68 _LOGGER.debug(
"Detected: %s", service_info)
70 device =
Device(service_info.device.address)
72 connections={(dr.CONNECTION_BLUETOOTH, service_info.address)},
73 identifiers={(DOMAIN, service_info.address)},
74 manufacturer=
"Fjäråskupan",
79 hass, device, device_info
81 coordinator.detection_callback(service_info)
83 state.coordinators[service_info.address] = coordinator
85 hass, f
"{DISPATCH_DETECTION}.{entry.entry_id}", coordinator
88 entry.async_on_unload(
93 manufacturer_id=20296,
94 manufacturer_data_start=[79, 68, 70, 74, 65, 82],
97 BluetoothScanningMode.ACTIVE,
101 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
109 async_add_entities: AddEntitiesCallback,
110 constructor: Callable[[FjaraskupanCoordinator], list[Entity]],
112 """Set up a platform with added entities."""
114 entry_state: EntryState = hass.data[DOMAIN][entry.entry_id]
117 for coordinator
in entry_state.coordinators.values()
118 for entity
in constructor(coordinator)
122 def _detection(coordinator: FjaraskupanCoordinator) ->
None:
125 entry.async_on_unload(
127 hass, f
"{DISPATCH_DETECTION}.{entry.entry_id}", _detection
133 """Unload a config entry."""
134 unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
136 hass.data[DOMAIN].pop(entry.entry_id)
138 for device_entry
in dr.async_entries_for_config_entry(
139 dr.async_get(hass), entry.entry_id
141 for conn
in device_entry.connections:
142 if conn[0] == dr.CONNECTION_BLUETOOTH:
None async_rediscover_address(HomeAssistant hass, str address)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
None async_setup_entry_platform(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities, Callable[[FjaraskupanCoordinator], list[Entity]] constructor)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Callable[[], None] async_register_callback(HomeAssistant hass, Callable[[SsdpServiceInfo, SsdpChange], Coroutine[Any, Any, None]|None] callback, dict[str, str]|None match_dict=None)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)