core/homeassistant/components/weatherflow/__init__.py

94 lines
3.0 KiB
Python

"""Get data from Smart Weather station via UDP."""
from __future__ import annotations
from pyweatherflowudp.client import EVENT_DEVICE_DISCOVERED, WeatherFlowListener
from pyweatherflowudp.device import EVENT_LOAD_COMPLETE, WeatherFlowDevice
from pyweatherflowudp.errors import ListenerError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, Platform
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.device_registry import DeviceEntry
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.start import async_at_started
from .const import DOMAIN, LOGGER, format_dispatch_call
PLATFORMS = [
Platform.SENSOR,
]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up WeatherFlow from a config entry."""
client = WeatherFlowListener()
@callback
def _async_device_discovered(device: WeatherFlowDevice) -> None:
LOGGER.debug("Found a device: %s", device)
@callback
def _async_add_device_if_started(device: WeatherFlowDevice):
async_at_started(
hass,
callback(
lambda _: async_dispatcher_send(
hass, format_dispatch_call(entry), device
)
),
)
entry.async_on_unload(
device.on(
EVENT_LOAD_COMPLETE,
lambda _: _async_add_device_if_started(device),
)
)
entry.async_on_unload(client.on(EVENT_DEVICE_DISCOVERED, _async_device_discovered))
try:
await client.start_listening()
except ListenerError as ex:
raise ConfigEntryNotReady from ex
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = client
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
async def _async_handle_ha_shutdown(event: Event) -> None:
"""Handle HA shutdown."""
await client.stop_listening()
entry.async_on_unload(
hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, _async_handle_ha_shutdown)
)
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
client: WeatherFlowListener = hass.data[DOMAIN].pop(entry.entry_id, None)
if client:
await client.stop_listening()
return unload_ok
async def async_remove_config_entry_device(
hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry
) -> bool:
"""Remove a config entry from a device."""
client: WeatherFlowListener = hass.data[DOMAIN][config_entry.entry_id]
return not any(
identifier
for identifier in device_entry.identifiers
if identifier[0] == DOMAIN
for device in client.devices
if device.serial_number == identifier[1]
)