diff --git a/homeassistant/components/zimi/cover.py b/homeassistant/components/zimi/cover.py index c3deb122dea3..8374f96673b6 100644 --- a/homeassistant/components/zimi/cover.py +++ b/homeassistant/components/zimi/cover.py @@ -26,9 +26,13 @@ async def async_setup_entry( api = config_entry.runtime_data - covers = [ZimiCover(device, api) for device in api.blinds] + covers = [ + ZimiCover(hass, device, api, config_entry.entry_id) for device in api.blinds + ] - covers.extend(ZimiCover(device, api) for device in api.doors) + covers.extend( + ZimiCover(hass, device, api, config_entry.entry_id) for device in api.doors + ) async_add_entities(covers) diff --git a/homeassistant/components/zimi/entity.py b/homeassistant/components/zimi/entity.py index eb631b114a32..139abc526305 100644 --- a/homeassistant/components/zimi/entity.py +++ b/homeassistant/components/zimi/entity.py @@ -6,6 +6,8 @@ from typing import override from zcc import ControlPoint from zcc.device import ControlPointDevice +from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity @@ -21,7 +23,12 @@ class ZimiEntity(Entity): _attr_has_entity_name = True def __init__( - self, device: ControlPointDevice, api: ControlPoint, use_device_name=True + self, + hass: HomeAssistant, + device: ControlPointDevice, + api: ControlPoint, + config_entry_id: str, + use_device_name: bool = True, ) -> None: """Initialize an HA Entity which is a ZimiDevice.""" @@ -35,7 +42,9 @@ class ZimiEntity(Entity): hw_version=device.manufacture_info.hwVersion, sw_version=device.manufacture_info.firmwareVersion, suggested_area=device.room, - via_device=(DOMAIN, api.mac), + via_device_id=dr.async_get_device_id_by_identifier( + hass, (DOMAIN, api.mac), config_entry_id=config_entry_id + ), ) if use_device_name: self._attr_name = device.name.strip() diff --git a/homeassistant/components/zimi/fan.py b/homeassistant/components/zimi/fan.py index 919cb764e8da..2d46796b5f34 100644 --- a/homeassistant/components/zimi/fan.py +++ b/homeassistant/components/zimi/fan.py @@ -28,7 +28,9 @@ async def async_setup_entry( api = config_entry.runtime_data - async_add_entities([ZimiFan(device, api) for device in api.fans]) + async_add_entities( + ZimiFan(hass, device, api, config_entry.entry_id) for device in api.fans + ) class ZimiFan(ZimiEntity, FanEntity): diff --git a/homeassistant/components/zimi/light.py b/homeassistant/components/zimi/light.py index c2abcd0daf67..b26f93258ada 100644 --- a/homeassistant/components/zimi/light.py +++ b/homeassistant/components/zimi/light.py @@ -26,11 +26,15 @@ async def async_setup_entry( api = config_entry.runtime_data lights: list[ZimiLight | ZimiDimmer] = [ - ZimiLight(device, api) for device in api.lights if device.type != "dimmer" + ZimiLight(hass, device, api, config_entry.entry_id) + for device in api.lights + if device.type != "dimmer" ] lights.extend( - ZimiDimmer(device, api) for device in api.lights if device.type == "dimmer" + ZimiDimmer(hass, device, api, config_entry.entry_id) + for device in api.lights + if device.type == "dimmer" ) async_add_entities(lights) @@ -39,10 +43,16 @@ async def async_setup_entry( class ZimiLight(ZimiEntity, LightEntity): """Representation of a Zimi Light.""" - def __init__(self, device: ControlPointDevice, api: ControlPoint) -> None: + def __init__( + self, + hass: HomeAssistant, + device: ControlPointDevice, + api: ControlPoint, + config_entry_id: str, + ) -> None: """Initialize a ZimiLight.""" - super().__init__(device, api) + super().__init__(hass, device, api, config_entry_id) self._attr_color_mode = ColorMode.ONOFF self._attr_supported_color_modes = {ColorMode.ONOFF} @@ -77,9 +87,15 @@ class ZimiLight(ZimiEntity, LightEntity): class ZimiDimmer(ZimiLight): """Zimi Light supporting dimming.""" - def __init__(self, device: ControlPointDevice, api: ControlPoint) -> None: + def __init__( + self, + hass: HomeAssistant, + device: ControlPointDevice, + api: ControlPoint, + config_entry_id: str, + ) -> None: """Initialize a ZimiDimmer.""" - super().__init__(device, api) + super().__init__(hass, device, api, config_entry_id) self._attr_color_mode = ColorMode.BRIGHTNESS self._attr_supported_color_modes = {ColorMode.BRIGHTNESS} diff --git a/homeassistant/components/zimi/sensor.py b/homeassistant/components/zimi/sensor.py index 2ab507343a14..306043b2670e 100644 --- a/homeassistant/components/zimi/sensor.py +++ b/homeassistant/components/zimi/sensor.py @@ -71,7 +71,7 @@ async def async_setup_entry( api = config_entry.runtime_data async_add_entities( - ZimiSensor(device, description, api) + ZimiSensor(hass, device, description, api, config_entry.entry_id) for device in api.sensors for description in GARAGE_SENSOR_DESCRIPTIONS ) @@ -84,13 +84,15 @@ class ZimiSensor(ZimiEntity, SensorEntity): def __init__( self, + hass: HomeAssistant, device: ControlPointDevice, description: ZimiSensorEntityDescription, api: ControlPoint, + config_entry_id: str, ) -> None: """Initialize an ZimiSensor with specified type.""" - super().__init__(device, api, use_device_name=False) + super().__init__(hass, device, api, config_entry_id, use_device_name=False) self.entity_description = description self._attr_unique_id = device.identifier + "." + self.entity_description.key diff --git a/homeassistant/components/zimi/switch.py b/homeassistant/components/zimi/switch.py index 689e348acd8a..acb3b89049ea 100644 --- a/homeassistant/components/zimi/switch.py +++ b/homeassistant/components/zimi/switch.py @@ -22,7 +22,9 @@ async def async_setup_entry( api = config_entry.runtime_data - outlets = [ZimiSwitch(device, api) for device in api.outlets] + outlets = [ + ZimiSwitch(hass, device, api, config_entry.entry_id) for device in api.outlets + ] async_add_entities(outlets) diff --git a/tests/components/zimi/test_switch.py b/tests/components/zimi/test_switch.py index 873d3c2c68e1..61a71c31aa89 100644 --- a/tests/components/zimi/test_switch.py +++ b/tests/components/zimi/test_switch.py @@ -5,11 +5,13 @@ from unittest.mock import MagicMock from syrupy.assertion import SnapshotAssertion from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN +from homeassistant.components.zimi.const import DOMAIN from homeassistant.const import SERVICE_TURN_OFF, SERVICE_TURN_ON, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers import entity_registry as er +from homeassistant.helpers import device_registry as dr, entity_registry as er -from .common import ENTITY_INFO, mock_api_device, setup_platform +from .common import DEVICE_INFO, ENTITY_INFO, mock_api_device, setup_platform +from .conftest import INPUT_MAC async def test_switch_entity( @@ -53,3 +55,26 @@ async def test_switch_entity( ) assert mock_api.outlets[0].turn_off.called + + +async def test_switch_via_device_id( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + mock_api: MagicMock, +) -> None: + """Tests switch device is linked to the controller device via via_device_id.""" + + mock_api.outlets = [mock_api_device(entity_type="switch")] + + config_entry = await setup_platform(hass, Platform.SWITCH) + + controller_device = device_registry.async_get_device_by_identifier( + (DOMAIN, INPUT_MAC), config_entry.entry_id + ) + assert controller_device is not None + + switch_device = device_registry.async_get_device_by_identifier( + (DOMAIN, DEVICE_INFO["id"]), config_entry.entry_id + ) + assert switch_device is not None + assert switch_device.via_device_id == controller_device.id