From 6305cbb438375bd0dc409b853a07daeb4760600d Mon Sep 17 00:00:00 2001 From: David Wu <133224895+David-Wu1119@users.noreply.github.com> Date: Tue, 8 Sep 2026 09:05:10 -0700 Subject: [PATCH] Type the ios registration data with a HassKey (#181122) --- homeassistant/components/ios/__init__.py | 33 ++++++++++++++---------- homeassistant/components/ios/const.py | 8 ++++++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/ios/__init__.py b/homeassistant/components/ios/__init__.py index a8ebe2ac6927..3c4f0940e9ae 100644 --- a/homeassistant/components/ios/__init__.py +++ b/homeassistant/components/ios/__init__.py @@ -1,8 +1,7 @@ """Native Home Assistant iOS app component.""" -# pylint: disable=home-assistant-use-runtime-data # Uses legacy hass.data[DOMAIN] pattern from http import HTTPStatus -from typing import Any +from typing import Any, cast from aiohttp import web import voluptuous as vol @@ -41,6 +40,7 @@ from .const import ( CONF_ACTION_SHOW_IN_WATCH, CONF_ACTION_USE_CUSTOM_COLORS, DOMAIN, + IOS_DATA, ) CONF_PUSH = "push" @@ -217,7 +217,7 @@ def devices_with_push(hass: HomeAssistant) -> dict[str, str]: """Return a dictionary of push enabled targets.""" return { device_name: device.get(ATTR_PUSH_ID) - for device_name, device in hass.data[DOMAIN][ATTR_DEVICES].items() + for device_name, device in hass.data[IOS_DATA][ATTR_DEVICES].items() if device.get(ATTR_PUSH_ID) is not None } @@ -226,21 +226,21 @@ def enabled_push_ids(hass: HomeAssistant) -> list[str]: """Return a list of push enabled target push IDs.""" return [ device.get(ATTR_PUSH_ID) - for device in hass.data[DOMAIN][ATTR_DEVICES].values() + for device in hass.data[IOS_DATA][ATTR_DEVICES].values() if device.get(ATTR_PUSH_ID) is not None ] def devices(hass: HomeAssistant) -> dict[str, dict[str, Any]]: """Return a dictionary of all identified devices.""" - return hass.data[DOMAIN][ATTR_DEVICES] # type: ignore[no-any-return] + return hass.data[IOS_DATA][ATTR_DEVICES] def device_name_for_push_id(hass: HomeAssistant, push_id: str) -> str | None: """Return the device name for the push ID.""" - for device_name, device in hass.data[DOMAIN][ATTR_DEVICES].items(): + for device_name, device in hass.data[IOS_DATA][ATTR_DEVICES].items(): if device.get(ATTR_PUSH_ID) is push_id: - return device_name # type: ignore[no-any-return] + return device_name return None @@ -248,8 +248,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the iOS component.""" conf: ConfigType | None = config.get(DOMAIN) - ios_config = await hass.async_add_executor_job( - load_json_object, hass.config.path(CONFIGURATION_FILE) + ios_config = cast( + dict[str, dict[str, Any]], + await hass.async_add_executor_job( + load_json_object, hass.config.path(CONFIGURATION_FILE) + ), ) if ios_config == {}: @@ -260,7 +263,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: ios_config[CONF_USER] = conf_user - hass.data[DOMAIN] = ios_config + hass.data[IOS_DATA] = ios_config # No entry support for notify component yet discovery.load_platform(hass, Platform.NOTIFY, DOMAIN, {}, config) @@ -282,8 +285,10 @@ async def async_setup_entry( await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) hass.http.register_view(iOSIdentifyDeviceView(hass.config.path(CONFIGURATION_FILE))) - hass.http.register_view(iOSPushConfigView(hass.data[DOMAIN][CONF_USER][CONF_PUSH])) - hass.http.register_view(iOSConfigView(hass.data[DOMAIN][CONF_USER])) + hass.http.register_view( + iOSPushConfigView(hass.data[IOS_DATA][CONF_USER][CONF_PUSH]) + ) + hass.http.register_view(iOSConfigView(hass.data[IOS_DATA][CONF_USER])) return True @@ -341,12 +346,12 @@ class iOSIdentifyDeviceView(HomeAssistantView): device_id = data[ATTR_DEVICE_ID] - hass.data[DOMAIN][ATTR_DEVICES][device_id] = data + hass.data[IOS_DATA][ATTR_DEVICES][device_id] = data async_dispatcher_send(hass, f"{DOMAIN}.{device_id}", data) try: - save_json(self._config_path, hass.data[DOMAIN]) + save_json(self._config_path, hass.data[IOS_DATA]) except HomeAssistantError: return self.json_message( "Error saving device.", HTTPStatus.INTERNAL_SERVER_ERROR diff --git a/homeassistant/components/ios/const.py b/homeassistant/components/ios/const.py index 1687a1faa226..66278134eee5 100644 --- a/homeassistant/components/ios/const.py +++ b/homeassistant/components/ios/const.py @@ -1,7 +1,15 @@ """Const for iOS.""" +from typing import Any + +from homeassistant.util.hass_dict import HassKey + DOMAIN = "ios" +# The iOS app's registration file, holding every registered device and the +# push configuration. It is integration-wide, not per config entry. +IOS_DATA: HassKey[dict[str, dict[str, Any]]] = HassKey(DOMAIN) + ATTR_BATTERY = "battery" ATTR_BATTERY_LEVEL = "level" ATTR_BATTERY_STATE = "state"