1 """The Husqvarna Automower integration."""
5 from aioautomower.session
import AutomowerSession
6 from aiohttp
import ClientResponseError
14 config_entry_oauth2_flow,
15 device_registry
as dr,
16 entity_registry
as er,
21 from .const
import DOMAIN
22 from .coordinator
import AutomowerDataUpdateCoordinator
24 _LOGGER = logging.getLogger(__name__)
26 PLATFORMS: list[Platform] = [
27 Platform.BINARY_SENSOR,
30 Platform.DEVICE_TRACKER,
38 type AutomowerConfigEntry = ConfigEntry[AutomowerDataUpdateCoordinator]
42 """Set up this integration using UI."""
44 await config_entry_oauth2_flow.async_get_config_entry_implementation(
48 session = config_entry_oauth2_flow.OAuth2Session(hass, entry, implementation)
50 aiohttp_client.async_get_clientsession(hass),
53 time_zone_str =
str(dt_util.DEFAULT_TIME_ZONE)
54 automower_api = AutomowerSession(
56 await dt_util.async_get_time_zone(time_zone_str),
59 await api_api.async_get_access_token()
60 except ClientResponseError
as err:
61 if 400 <= err.status < 500:
62 raise ConfigEntryAuthFailed
from err
63 raise ConfigEntryNotReady
from err
66 await coordinator.async_config_entry_first_refresh()
67 available_devices =
list(coordinator.data)
69 entry.runtime_data = coordinator
71 entry.async_create_background_task(
73 coordinator.client_listen(hass, entry, automower_api),
77 if "amc:api" not in entry.data[
"token"][
"scope"]:
80 raise ConfigEntryAuthFailed
82 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
87 """Handle unload of an entry."""
88 return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
92 hass: HomeAssistant, config_entry: ConfigEntry, available_devices: list[str]
94 """Cleanup entity and device registry from removed devices."""
95 device_reg = dr.async_get(hass)
96 identifiers = {(DOMAIN, mower_id)
for mower_id
in available_devices}
97 for device
in dr.async_entries_for_config_entry(device_reg, config_entry.entry_id):
98 if not set(device.identifiers) & identifiers:
99 _LOGGER.debug(
"Removing obsolete device entry %s", device.name)
100 device_reg.async_update_device(
101 device.id, remove_config_entry_id=config_entry.entry_id
107 config_entry: ConfigEntry,
108 removed_work_areas: set[int],
111 """Remove all unused work area entities for the specified mower."""
112 entity_reg = er.async_get(hass)
113 for entity_entry
in er.async_entries_for_config_entry(
114 entity_reg, config_entry.entry_id
116 for work_area_id
in removed_work_areas:
117 if entity_entry.unique_id.startswith(f
"{mower_id}_{work_area_id}_"):
118 _LOGGER.info(
"Deleting: %s", entity_entry.entity_id)
119 entity_reg.async_remove(entity_entry.entity_id)
bool async_unload_entry(HomeAssistant hass, AutomowerConfigEntry entry)
None remove_work_area_entities(HomeAssistant hass, ConfigEntry config_entry, set[int] removed_work_areas, str mower_id)
bool async_setup_entry(HomeAssistant hass, AutomowerConfigEntry entry)
None cleanup_removed_devices(HomeAssistant hass, ConfigEntry config_entry, list[str] available_devices)