diff --git a/homeassistant/components/insteon/binary_sensor.py b/homeassistant/components/insteon/binary_sensor.py index 9d1ec352bed..f895b9c7f6a 100644 --- a/homeassistant/components/insteon/binary_sensor.py +++ b/homeassistant/components/insteon/binary_sensor.py @@ -25,7 +25,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .insteon_entity import InsteonEntity -from .utils import async_add_insteon_entities +from .utils import async_add_insteon_devices, async_add_insteon_entities SENSOR_TYPES = { OPEN_CLOSE_SENSOR: BinarySensorDeviceClass.OPENING, @@ -62,7 +62,12 @@ async def async_setup_entry( signal = f"{SIGNAL_ADD_ENTITIES}_{Platform.BINARY_SENSOR}" async_dispatcher_connect(hass, signal, async_add_insteon_binary_sensor_entities) - async_add_insteon_binary_sensor_entities() + async_add_insteon_devices( + hass, + Platform.BINARY_SENSOR, + InsteonBinarySensorEntity, + async_add_entities, + ) class InsteonBinarySensorEntity(InsteonEntity, BinarySensorEntity): diff --git a/homeassistant/components/insteon/climate.py b/homeassistant/components/insteon/climate.py index cf5f4ac2c0c..48ff898d6aa 100644 --- a/homeassistant/components/insteon/climate.py +++ b/homeassistant/components/insteon/climate.py @@ -23,7 +23,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .insteon_entity import InsteonEntity -from .utils import async_add_insteon_entities +from .utils import async_add_insteon_devices, async_add_insteon_entities FAN_ONLY = "fan_only" @@ -71,7 +71,12 @@ async def async_setup_entry( signal = f"{SIGNAL_ADD_ENTITIES}_{Platform.CLIMATE}" async_dispatcher_connect(hass, signal, async_add_insteon_climate_entities) - async_add_insteon_climate_entities() + async_add_insteon_devices( + hass, + Platform.CLIMATE, + InsteonClimateEntity, + async_add_entities, + ) class InsteonClimateEntity(InsteonEntity, ClimateEntity): diff --git a/homeassistant/components/insteon/cover.py b/homeassistant/components/insteon/cover.py index 69a66d304ce..0756e603579 100644 --- a/homeassistant/components/insteon/cover.py +++ b/homeassistant/components/insteon/cover.py @@ -15,7 +15,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .insteon_entity import InsteonEntity -from .utils import async_add_insteon_entities +from .utils import async_add_insteon_devices, async_add_insteon_entities async def async_setup_entry( @@ -34,7 +34,12 @@ async def async_setup_entry( signal = f"{SIGNAL_ADD_ENTITIES}_{Platform.COVER}" async_dispatcher_connect(hass, signal, async_add_insteon_cover_entities) - async_add_insteon_cover_entities() + async_add_insteon_devices( + hass, + Platform.COVER, + InsteonCoverEntity, + async_add_entities, + ) class InsteonCoverEntity(InsteonEntity, CoverEntity): diff --git a/homeassistant/components/insteon/fan.py b/homeassistant/components/insteon/fan.py index b0d664a821b..92f56098a91 100644 --- a/homeassistant/components/insteon/fan.py +++ b/homeassistant/components/insteon/fan.py @@ -17,7 +17,7 @@ from homeassistant.util.percentage import ( from .const import SIGNAL_ADD_ENTITIES from .insteon_entity import InsteonEntity -from .utils import async_add_insteon_entities +from .utils import async_add_insteon_devices, async_add_insteon_entities SPEED_RANGE = (1, 255) # off is not included @@ -38,7 +38,12 @@ async def async_setup_entry( signal = f"{SIGNAL_ADD_ENTITIES}_{Platform.FAN}" async_dispatcher_connect(hass, signal, async_add_insteon_fan_entities) - async_add_insteon_fan_entities() + async_add_insteon_devices( + hass, + Platform.FAN, + InsteonFanEntity, + async_add_entities, + ) class InsteonFanEntity(InsteonEntity, FanEntity): diff --git a/homeassistant/components/insteon/ipdb.py b/homeassistant/components/insteon/ipdb.py index ee799e103f9..de3ba7d55f2 100644 --- a/homeassistant/components/insteon/ipdb.py +++ b/homeassistant/components/insteon/ipdb.py @@ -1,4 +1,7 @@ """Utility methods for the Insteon platform.""" +from collections.abc import Iterable + +from pyinsteon.device_types.device_base import Device from pyinsteon.device_types.ipdb import ( AccessControl_Morningstar, ClimateControl_Thermostat, @@ -44,7 +47,7 @@ from pyinsteon.device_types.ipdb import ( from homeassistant.const import Platform -DEVICE_PLATFORM = { +DEVICE_PLATFORM: dict[Device, dict[Platform, Iterable[int]]] = { AccessControl_Morningstar: {Platform.LOCK: [1]}, DimmableLightingControl: {Platform.LIGHT: [1]}, DimmableLightingControl_Dial: {Platform.LIGHT: [1]}, @@ -101,11 +104,11 @@ DEVICE_PLATFORM = { } -def get_device_platforms(device): +def get_device_platforms(device) -> dict[Platform, Iterable[int]]: """Return the HA platforms for a device type.""" - return DEVICE_PLATFORM.get(type(device), {}).keys() + return DEVICE_PLATFORM.get(type(device), {}) -def get_platform_groups(device, domain) -> dict: - """Return the platforms that a device belongs in.""" - return DEVICE_PLATFORM.get(type(device), {}).get(domain, {}) # type: ignore[attr-defined] +def get_device_platform_groups(device: Device, platform: Platform) -> Iterable[int]: + """Return the list of device groups for a platform.""" + return get_device_platforms(device).get(platform, []) diff --git a/homeassistant/components/insteon/light.py b/homeassistant/components/insteon/light.py index 44574c696b4..1c12bc794f9 100644 --- a/homeassistant/components/insteon/light.py +++ b/homeassistant/components/insteon/light.py @@ -12,7 +12,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .insteon_entity import InsteonEntity -from .utils import async_add_insteon_entities +from .utils import async_add_insteon_devices, async_add_insteon_entities MAX_BRIGHTNESS = 255 @@ -37,7 +37,12 @@ async def async_setup_entry( signal = f"{SIGNAL_ADD_ENTITIES}_{Platform.LIGHT}" async_dispatcher_connect(hass, signal, async_add_insteon_light_entities) - async_add_insteon_light_entities() + async_add_insteon_devices( + hass, + Platform.LIGHT, + InsteonDimmerEntity, + async_add_entities, + ) class InsteonDimmerEntity(InsteonEntity, LightEntity): diff --git a/homeassistant/components/insteon/lock.py b/homeassistant/components/insteon/lock.py index 75487e7696c..27fb0fd42d8 100644 --- a/homeassistant/components/insteon/lock.py +++ b/homeassistant/components/insteon/lock.py @@ -11,7 +11,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .insteon_entity import InsteonEntity -from .utils import async_add_insteon_entities +from .utils import async_add_insteon_devices, async_add_insteon_entities async def async_setup_entry( @@ -30,7 +30,12 @@ async def async_setup_entry( signal = f"{SIGNAL_ADD_ENTITIES}_{Platform.LOCK}" async_dispatcher_connect(hass, signal, async_add_insteon_lock_entities) - async_add_insteon_lock_entities() + async_add_insteon_devices( + hass, + Platform.LOCK, + InsteonLockEntity, + async_add_entities, + ) class InsteonLockEntity(InsteonEntity, LockEntity): diff --git a/homeassistant/components/insteon/switch.py b/homeassistant/components/insteon/switch.py index 8f7c396f213..8acde0429cd 100644 --- a/homeassistant/components/insteon/switch.py +++ b/homeassistant/components/insteon/switch.py @@ -10,7 +10,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import SIGNAL_ADD_ENTITIES from .insteon_entity import InsteonEntity -from .utils import async_add_insteon_entities +from .utils import async_add_insteon_devices, async_add_insteon_entities async def async_setup_entry( @@ -33,7 +33,12 @@ async def async_setup_entry( signal = f"{SIGNAL_ADD_ENTITIES}_{Platform.SWITCH}" async_dispatcher_connect(hass, signal, async_add_insteon_switch_entities) - async_add_insteon_switch_entities() + async_add_insteon_devices( + hass, + Platform.SWITCH, + InsteonSwitchEntity, + async_add_entities, + ) class InsteonSwitchEntity(InsteonEntity, SwitchEntity): diff --git a/homeassistant/components/insteon/utils.py b/homeassistant/components/insteon/utils.py index 58b2430092c..2ef9913ab8c 100644 --- a/homeassistant/components/insteon/utils.py +++ b/homeassistant/components/insteon/utils.py @@ -1,7 +1,10 @@ """Utilities used by insteon component.""" +from __future__ import annotations + import asyncio from collections.abc import Callable import logging +from typing import TYPE_CHECKING, Any from pyinsteon import devices from pyinsteon.address import Address @@ -30,6 +33,7 @@ from homeassistant.const import ( CONF_ENTITY_ID, CONF_PLATFORM, ENTITY_MATCH_ALL, + Platform, ) from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.helpers import device_registry as dr @@ -38,6 +42,7 @@ from homeassistant.helpers.dispatcher import ( async_dispatcher_send, dispatcher_send, ) +from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import ( CONF_CAT, @@ -78,7 +83,7 @@ from .const import ( SRV_X10_ALL_LIGHTS_ON, SRV_X10_ALL_UNITS_OFF, ) -from .ipdb import get_device_platforms, get_platform_groups +from .ipdb import get_device_platform_groups, get_device_platforms from .schemas import ( ADD_ALL_LINK_SCHEMA, ADD_DEFAULT_LINKS_SCHEMA, @@ -89,6 +94,9 @@ from .schemas import ( X10_HOUSECODE_SCHEMA, ) +if TYPE_CHECKING: + from .insteon_entity import InsteonEntity + _LOGGER = logging.getLogger(__name__) @@ -160,6 +168,7 @@ def register_new_device_callback(hass): for platform in platforms: signal = f"{SIGNAL_ADD_ENTITIES}_{platform}" dispatcher_send(hass, signal, {"address": device.address}) + add_insteon_events(hass, device) devices.subscribe(async_new_insteon_device, force_strong_ref=True) @@ -383,20 +392,38 @@ def print_aldb_to_log(aldb): @callback def async_add_insteon_entities( - hass, platform, entity_type, async_add_entities, discovery_info -): - """Add Insteon devices to a platform.""" - new_entities = [] - device_list = [discovery_info.get("address")] if discovery_info else devices - - for address in device_list: - device = devices[address] - groups = get_platform_groups(device, platform) - for group in groups: - new_entities.append(entity_type(device, group)) + hass: HomeAssistant, + platform: Platform, + entity_type: type[InsteonEntity], + async_add_entities: AddEntitiesCallback, + discovery_info: dict[str, Any], +) -> None: + """Add an Insteon group to a platform.""" + address = discovery_info["address"] + device = devices[address] + new_entities = [ + entity_type(device=device, group=group) for group in discovery_info["groups"] + ] async_add_entities(new_entities) +@callback +def async_add_insteon_devices( + hass: HomeAssistant, + platform: Platform, + entity_type: type[InsteonEntity], + async_add_entities: AddEntitiesCallback, +) -> None: + """Add all entities to a platform.""" + for address in devices: + device = devices[address] + groups = get_device_platform_groups(device, platform) + discovery_info = {"address": address, "groups": groups} + async_add_insteon_entities( + hass, platform, entity_type, async_add_entities, discovery_info + ) + + def get_usb_ports() -> dict[str, str]: """Return a dict of USB ports and their friendly names.""" ports = list_ports.comports()