"""Support for Ring Doorbell/Chimes.""" from __future__ import annotations from functools import partial import logging from ring_doorbell import Auth, Ring from homeassistant.config_entries import ConfigEntry from homeassistant.const import APPLICATION_NAME, CONF_TOKEN, __version__ from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.helpers import device_registry as dr from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from .const import ( DOMAIN, PLATFORMS, RING_API, RING_DEVICES, RING_DEVICES_COORDINATOR, RING_NOTIFICATIONS_COORDINATOR, ) from .coordinator import RingDataCoordinator, RingNotificationsCoordinator _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" def token_updater(token): """Handle from sync context when token is updated.""" hass.loop.call_soon_threadsafe( partial( hass.config_entries.async_update_entry, entry, data={**entry.data, CONF_TOKEN: token}, ) ) auth = Auth( f"{APPLICATION_NAME}/{__version__}", entry.data[CONF_TOKEN], token_updater ) ring = Ring(auth) devices_coordinator = RingDataCoordinator(hass, ring) notifications_coordinator = RingNotificationsCoordinator(hass, ring) await devices_coordinator.async_config_entry_first_refresh() await notifications_coordinator.async_config_entry_first_refresh() hass.data.setdefault(DOMAIN, {})[entry.entry_id] = { RING_API: ring, RING_DEVICES: ring.devices(), RING_DEVICES_COORDINATOR: devices_coordinator, RING_NOTIFICATIONS_COORDINATOR: notifications_coordinator, } await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) if hass.services.has_service(DOMAIN, "update"): return True async def async_refresh_all(_: ServiceCall) -> None: """Refresh all ring data.""" _LOGGER.warning( "Detected use of service 'ring.update'. " "This is deprecated and will stop working in Home Assistant 2024.10. " "Use 'homeassistant.update_entity' instead which updates all ring entities", ) async_create_issue( hass, DOMAIN, "deprecated_service_ring_update", breaks_in_ha_version="2024.10.0", is_fixable=True, is_persistent=False, issue_domain=DOMAIN, severity=IssueSeverity.WARNING, translation_key="deprecated_service_ring_update", ) for info in hass.data[DOMAIN].values(): await info[RING_DEVICES_COORDINATOR].async_refresh() await info[RING_NOTIFICATIONS_COORDINATOR].async_refresh() # register service hass.services.async_register(DOMAIN, "update", async_refresh_all) return True async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload Ring entry.""" if not await hass.config_entries.async_unload_platforms(entry, PLATFORMS): return False hass.data[DOMAIN].pop(entry.entry_id) if len(hass.data[DOMAIN]) != 0: return True # Last entry unloaded, clean up service hass.services.async_remove(DOMAIN, "update") return True async def async_remove_config_entry_device( hass: HomeAssistant, config_entry: ConfigEntry, device_entry: dr.DeviceEntry ) -> bool: """Remove a config entry from a device.""" return True