diff --git a/homeassistant/components/homematicip_cloud/switch.py b/homeassistant/components/homematicip_cloud/switch.py index 66a40229c7efb..ca591adbf5e4a 100644 --- a/homeassistant/components/homematicip_cloud/switch.py +++ b/homeassistant/components/homematicip_cloud/switch.py @@ -4,13 +4,14 @@ from typing import Any -from homematicip.base.enums import DeviceType +from homematicip.base.enums import DeviceType, FunctionalChannelType from homematicip.device import ( BrandSwitch2, DinRailSwitch, DinRailSwitch4, FullFlushInputSwitch, HeatingSwitch2, + MotionDetectorSwitchOutdoor, MultiIOBox, OpenCollector8Module, PlugableSwitch, @@ -47,45 +48,43 @@ async def async_setup_entry( and getattr(device, "deviceType", None) != DeviceType.BRAND_SWITCH_MEASURING ): entities.append(HomematicipSwitchMeasuring(hap, device)) - elif isinstance(device, WiredSwitch8): - entities.extend( - HomematicipMultiSwitch(hap, device, channel=channel) - for channel in range(1, 9) - ) - elif isinstance(device, DinRailSwitch): - entities.append(HomematicipMultiSwitch(hap, device, channel=1)) - elif isinstance(device, DinRailSwitch4): - entities.extend( - HomematicipMultiSwitch(hap, device, channel=channel) - for channel in range(1, 5) - ) elif isinstance( device, ( - PlugableSwitch, - PrintedCircuitBoardSwitchBattery, - FullFlushInputSwitch, + WiredSwitch8, + OpenCollector8Module, + BrandSwitch2, + PrintedCircuitBoardSwitch2, + HeatingSwitch2, + MultiIOBox, + MotionDetectorSwitchOutdoor, + DinRailSwitch, + DinRailSwitch4, ), ): - entities.append(HomematicipSwitch(hap, device)) - elif isinstance(device, OpenCollector8Module): + channel_indices = [ + ch.index + for ch in device.functionalChannels + if ch.functionalChannelType + in ( + FunctionalChannelType.SWITCH_CHANNEL, + FunctionalChannelType.MULTI_MODE_INPUT_SWITCH_CHANNEL, + ) + ] entities.extend( HomematicipMultiSwitch(hap, device, channel=channel) - for channel in range(1, 9) + for channel in channel_indices ) + elif isinstance( device, ( - BrandSwitch2, - PrintedCircuitBoardSwitch2, - HeatingSwitch2, - MultiIOBox, + PlugableSwitch, + PrintedCircuitBoardSwitchBattery, + FullFlushInputSwitch, ), ): - entities.extend( - HomematicipMultiSwitch(hap, device, channel=channel) - for channel in range(1, 3) - ) + entities.append(HomematicipSwitch(hap, device)) async_add_entities(entities) @@ -108,15 +107,15 @@ def __init__( @property def is_on(self) -> bool: """Return true if switch is on.""" - return self._device.functionalChannels[self._channel].on + return self.functional_channel.on async def async_turn_on(self, **kwargs: Any) -> None: """Turn the switch on.""" - await self._device.turn_on_async(self._channel) + await self.functional_channel.async_turn_on() async def async_turn_off(self, **kwargs: Any) -> None: """Turn the switch off.""" - await self._device.turn_off_async(self._channel) + await self.functional_channel.async_turn_off() class HomematicipSwitch(HomematicipMultiSwitch, SwitchEntity): diff --git a/homeassistant/components/motion_blinds/cover.py b/homeassistant/components/motion_blinds/cover.py index 165c4c19675f6..9cff2956a5f1d 100644 --- a/homeassistant/components/motion_blinds/cover.py +++ b/homeassistant/components/motion_blinds/cover.py @@ -62,6 +62,7 @@ BlindType.VerticalBlind: CoverDeviceClass.BLIND, BlindType.VerticalBlindLeft: CoverDeviceClass.BLIND, BlindType.VerticalBlindRight: CoverDeviceClass.BLIND, + BlindType.RollerTiltMotor: CoverDeviceClass.BLIND, } TILT_ONLY_DEVICE_MAP = { diff --git a/homeassistant/components/motion_blinds/manifest.json b/homeassistant/components/motion_blinds/manifest.json index 1a6c9c5f82fa8..a82da20396ffd 100644 --- a/homeassistant/components/motion_blinds/manifest.json +++ b/homeassistant/components/motion_blinds/manifest.json @@ -21,5 +21,5 @@ "documentation": "https://www.home-assistant.io/integrations/motion_blinds", "iot_class": "local_push", "loggers": ["motionblinds"], - "requirements": ["motionblinds==0.6.27"] + "requirements": ["motionblinds==0.6.28"] } diff --git a/homeassistant/components/roku/manifest.json b/homeassistant/components/roku/manifest.json index 7fe2fb3b68631..d5e2e2e52246d 100644 --- a/homeassistant/components/roku/manifest.json +++ b/homeassistant/components/roku/manifest.json @@ -10,7 +10,7 @@ "integration_type": "device", "iot_class": "local_polling", "loggers": ["rokuecp"], - "requirements": ["rokuecp==0.19.3"], + "requirements": ["rokuecp==0.19.5"], "ssdp": [ { "st": "roku:ecp", diff --git a/homeassistant/components/shelly/button.py b/homeassistant/components/shelly/button.py index eab7514514d04..ad03a373dbabb 100644 --- a/homeassistant/components/shelly/button.py +++ b/homeassistant/components/shelly/button.py @@ -235,11 +235,15 @@ def __init__( self._attr_unique_id = f"{coordinator.mac}_{description.key}" if isinstance(coordinator, ShellyBlockCoordinator): self._attr_device_info = get_block_device_info( - coordinator.device, coordinator.mac + coordinator.device, + coordinator.mac, + suggested_area=coordinator.suggested_area, ) else: self._attr_device_info = get_rpc_device_info( - coordinator.device, coordinator.mac + coordinator.device, + coordinator.mac, + suggested_area=coordinator.suggested_area, ) self._attr_device_info = DeviceInfo( connections={(CONNECTION_NETWORK_MAC, coordinator.mac)} diff --git a/homeassistant/components/shelly/climate.py b/homeassistant/components/shelly/climate.py index 26fabe7e8b5f0..abc387f3efdeb 100644 --- a/homeassistant/components/shelly/climate.py +++ b/homeassistant/components/shelly/climate.py @@ -211,7 +211,10 @@ def __init__( elif entry is not None: self._unique_id = entry.unique_id self._attr_device_info = get_block_device_info( - coordinator.device, coordinator.mac, sensor_block + coordinator.device, + coordinator.mac, + sensor_block, + suggested_area=coordinator.suggested_area, ) self._attr_name = get_block_entity_name( self.coordinator.device, sensor_block, None diff --git a/homeassistant/components/shelly/coordinator.py b/homeassistant/components/shelly/coordinator.py index f980ba8f91452..cba559a9773c7 100644 --- a/homeassistant/components/shelly/coordinator.py +++ b/homeassistant/components/shelly/coordinator.py @@ -31,7 +31,11 @@ Platform, ) from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback -from homeassistant.helpers import device_registry as dr, issue_registry as ir +from homeassistant.helpers import ( + area_registry as ar, + device_registry as dr, + issue_registry as ir, +) from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -114,6 +118,7 @@ def __init__( self.device = device self.device_id: str | None = None self._pending_platforms: list[Platform] | None = None + self.suggested_area: str | None = None device_name = device.name if device.initialized else entry.title interval_td = timedelta(seconds=update_interval) # The device has come online at least once. In the case of a sleeping RPC @@ -176,6 +181,11 @@ def async_setup(self, pending_platforms: list[Platform] | None = None) -> None: hw_version=f"gen{get_device_entry_gen(self.config_entry)}", configuration_url=f"http://{get_host(self.config_entry.data[CONF_HOST])}:{get_http_port(self.config_entry.data)}", ) + # We want to use the main device area as the suggested area for sub-devices. + if (area_id := device_entry.area_id) is not None: + area_registry = ar.async_get(self.hass) + if (area := area_registry.async_get_area(area_id)) is not None: + self.suggested_area = area.name self.device_id = device_entry.id async def shutdown(self) -> None: diff --git a/homeassistant/components/shelly/entity.py b/homeassistant/components/shelly/entity.py index 1b0078890af5b..2c1678d56d9a3 100644 --- a/homeassistant/components/shelly/entity.py +++ b/homeassistant/components/shelly/entity.py @@ -362,7 +362,10 @@ def __init__(self, coordinator: ShellyBlockCoordinator, block: Block) -> None: self.block = block self._attr_name = get_block_entity_name(coordinator.device, block) self._attr_device_info = get_block_device_info( - coordinator.device, coordinator.mac, block + coordinator.device, + coordinator.mac, + block, + suggested_area=coordinator.suggested_area, ) self._attr_unique_id = f"{coordinator.mac}-{block.description}" @@ -405,7 +408,10 @@ def __init__(self, coordinator: ShellyRpcCoordinator, key: str) -> None: super().__init__(coordinator) self.key = key self._attr_device_info = get_rpc_device_info( - coordinator.device, coordinator.mac, key + coordinator.device, + coordinator.mac, + key, + suggested_area=coordinator.suggested_area, ) self._attr_unique_id = f"{coordinator.mac}-{key}" self._attr_name = get_rpc_entity_name(coordinator.device, key) @@ -521,7 +527,9 @@ def __init__( ) self._attr_unique_id = f"{coordinator.mac}-{attribute}" self._attr_device_info = get_block_device_info( - coordinator.device, coordinator.mac + coordinator.device, + coordinator.mac, + suggested_area=coordinator.suggested_area, ) self._last_value = None @@ -630,7 +638,10 @@ def __init__( self.entity_description = description self._attr_device_info = get_block_device_info( - coordinator.device, coordinator.mac, block + coordinator.device, + coordinator.mac, + block, + suggested_area=coordinator.suggested_area, ) if block is not None: @@ -698,7 +709,10 @@ def __init__( self.entity_description = description self._attr_device_info = get_rpc_device_info( - coordinator.device, coordinator.mac, key + coordinator.device, + coordinator.mac, + key, + suggested_area=coordinator.suggested_area, ) self._attr_unique_id = self._attr_unique_id = ( f"{coordinator.mac}-{key}-{attribute}" diff --git a/homeassistant/components/shelly/event.py b/homeassistant/components/shelly/event.py index 677ea1f6138ca..2eb9ff00964cc 100644 --- a/homeassistant/components/shelly/event.py +++ b/homeassistant/components/shelly/event.py @@ -207,7 +207,10 @@ def __init__( super().__init__(coordinator) self.event_id = int(key.split(":")[-1]) self._attr_device_info = get_rpc_device_info( - coordinator.device, coordinator.mac, key + coordinator.device, + coordinator.mac, + key, + suggested_area=coordinator.suggested_area, ) self._attr_unique_id = f"{coordinator.mac}-{key}" self._attr_name = get_rpc_entity_name(coordinator.device, key) diff --git a/homeassistant/components/shelly/sensor.py b/homeassistant/components/shelly/sensor.py index 0ea246c773483..3a6f5f221c52b 100644 --- a/homeassistant/components/shelly/sensor.py +++ b/homeassistant/components/shelly/sensor.py @@ -139,7 +139,11 @@ def __init__( super().__init__(coordinator, key, attribute, description) self._attr_device_info = get_rpc_device_info( - coordinator.device, coordinator.mac, key, description.emeter_phase + coordinator.device, + coordinator.mac, + key, + emeter_phase=description.emeter_phase, + suggested_area=coordinator.suggested_area, ) diff --git a/homeassistant/components/shelly/utils.py b/homeassistant/components/shelly/utils.py index cc0f2cf75d5c9..953fcbace06fb 100644 --- a/homeassistant/components/shelly/utils.py +++ b/homeassistant/components/shelly/utils.py @@ -751,6 +751,7 @@ def get_rpc_device_info( mac: str, key: str | None = None, emeter_phase: str | None = None, + suggested_area: str | None = None, ) -> DeviceInfo: """Return device info for RPC device.""" if key is None: @@ -770,6 +771,7 @@ def get_rpc_device_info( identifiers={(DOMAIN, f"{mac}-{key}-{emeter_phase.lower()}")}, name=get_rpc_sub_device_name(device, key, emeter_phase), manufacturer="Shelly", + suggested_area=suggested_area, via_device=(DOMAIN, mac), ) @@ -784,6 +786,7 @@ def get_rpc_device_info( identifiers={(DOMAIN, f"{mac}-{key}")}, name=get_rpc_sub_device_name(device, key), manufacturer="Shelly", + suggested_area=suggested_area, via_device=(DOMAIN, mac), ) @@ -805,7 +808,10 @@ def get_blu_trv_device_info( def get_block_device_info( - device: BlockDevice, mac: str, block: Block | None = None + device: BlockDevice, + mac: str, + block: Block | None = None, + suggested_area: str | None = None, ) -> DeviceInfo: """Return device info for Block device.""" if ( @@ -820,6 +826,7 @@ def get_block_device_info( identifiers={(DOMAIN, f"{mac}-{block.description}")}, name=get_block_sub_device_name(device, block), manufacturer="Shelly", + suggested_area=suggested_area, via_device=(DOMAIN, mac), ) diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 7e6dea5022ed7..ca1d75cc03731 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -7,7 +7,7 @@ aiofiles==24.1.0 aiohasupervisor==0.3.1 aiohttp-asyncmdnsresolver==0.1.1 aiohttp-fast-zlib==0.3.0 -aiohttp==3.12.12 +aiohttp==3.12.13 aiohttp_cors==0.8.1 aiousbwatcher==1.1.1 aiozoneinfo==0.2.3 diff --git a/pyproject.toml b/pyproject.toml index 284a0d39bfecb..2910ee0221dc8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ dependencies = [ # change behavior based on presence of supervisor. Deprecated with #127228 # Lib can be removed with 2025.11 "aiohasupervisor==0.3.1", - "aiohttp==3.12.12", + "aiohttp==3.12.13", "aiohttp_cors==0.8.1", "aiohttp-fast-zlib==0.3.0", "aiohttp-asyncmdnsresolver==0.1.1", diff --git a/requirements.txt b/requirements.txt index c96a62b355d14..b5a949b0a6b48 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ aiodns==3.5.0 aiofiles==24.1.0 aiohasupervisor==0.3.1 -aiohttp==3.12.12 +aiohttp==3.12.13 aiohttp_cors==0.8.1 aiohttp-fast-zlib==0.3.0 aiohttp-asyncmdnsresolver==0.1.1 diff --git a/requirements_all.txt b/requirements_all.txt index 358b1356c4da1..5ad1815e56d32 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1448,7 +1448,7 @@ monzopy==1.4.2 mopeka-iot-ble==0.8.0 # homeassistant.components.motion_blinds -motionblinds==0.6.27 +motionblinds==0.6.28 # homeassistant.components.motionblinds_ble motionblindsble==0.1.3 @@ -2673,7 +2673,7 @@ rjpl==0.3.6 rocketchat-API==0.6.1 # homeassistant.components.roku -rokuecp==0.19.3 +rokuecp==0.19.5 # homeassistant.components.romy romy==0.0.10 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index f3f7b86774a64..110eb5dd31811 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1237,7 +1237,7 @@ monzopy==1.4.2 mopeka-iot-ble==0.8.0 # homeassistant.components.motion_blinds -motionblinds==0.6.27 +motionblinds==0.6.28 # homeassistant.components.motionblinds_ble motionblindsble==0.1.3 @@ -2204,7 +2204,7 @@ rflink==0.0.66 ring-doorbell==0.9.13 # homeassistant.components.roku -rokuecp==0.19.3 +rokuecp==0.19.5 # homeassistant.components.romy romy==0.0.10 diff --git a/tests/components/homematicip_cloud/test_switch.py b/tests/components/homematicip_cloud/test_switch.py index 1a728bfecd417..50d527775bd3b 100644 --- a/tests/components/homematicip_cloud/test_switch.py +++ b/tests/components/homematicip_cloud/test_switch.py @@ -25,14 +25,14 @@ async def test_hmip_switch( ) assert ha_state.state == STATE_ON - service_call_counter = len(hmip_device.mock_calls) + service_call_counter = len(hmip_device.functionalChannels[1].mock_calls) await hass.services.async_call( "switch", "turn_off", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 1 - assert hmip_device.mock_calls[-1][0] == "turn_off_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", False) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_OFF @@ -40,9 +40,9 @@ async def test_hmip_switch( await hass.services.async_call( "switch", "turn_on", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 3 - assert hmip_device.mock_calls[-1][0] == "turn_on_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", True) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_ON @@ -64,14 +64,14 @@ async def test_hmip_switch_input( ) assert ha_state.state == STATE_ON - service_call_counter = len(hmip_device.mock_calls) + service_call_counter = len(hmip_device.functionalChannels[1].mock_calls) await hass.services.async_call( "switch", "turn_off", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 1 - assert hmip_device.mock_calls[-1][0] == "turn_off_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", False) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_OFF @@ -79,9 +79,9 @@ async def test_hmip_switch_input( await hass.services.async_call( "switch", "turn_on", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 3 - assert hmip_device.mock_calls[-1][0] == "turn_on_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", True) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_ON @@ -103,14 +103,14 @@ async def test_hmip_switch_measuring( ) assert ha_state.state == STATE_ON - service_call_counter = len(hmip_device.mock_calls) + service_call_counter = len(hmip_device.functionalChannels[1].mock_calls) await hass.services.async_call( "switch", "turn_off", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 1 - assert hmip_device.mock_calls[-1][0] == "turn_off_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", False) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_OFF @@ -118,9 +118,9 @@ async def test_hmip_switch_measuring( await hass.services.async_call( "switch", "turn_on", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 3 - assert hmip_device.mock_calls[-1][0] == "turn_on_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", True) await async_manipulate_test_data(hass, hmip_device, "currentPowerConsumption", 50) ha_state = hass.states.get(entity_id) @@ -191,14 +191,14 @@ async def test_hmip_multi_switch( ) assert ha_state.state == STATE_OFF - service_call_counter = len(hmip_device.mock_calls) + service_call_counter = len(hmip_device.functionalChannels[1].mock_calls) await hass.services.async_call( "switch", "turn_on", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 1 - assert hmip_device.mock_calls[-1][0] == "turn_on_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", True) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_ON @@ -206,9 +206,9 @@ async def test_hmip_multi_switch( await hass.services.async_call( "switch", "turn_off", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 3 - assert hmip_device.mock_calls[-1][0] == "turn_off_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", False) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_OFF @@ -242,14 +242,14 @@ async def test_hmip_wired_multi_switch( ) assert ha_state.state == STATE_ON - service_call_counter = len(hmip_device.mock_calls) + service_call_counter = len(hmip_device.functionalChannels[1].mock_calls) await hass.services.async_call( "switch", "turn_off", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 1 - assert hmip_device.mock_calls[-1][0] == "turn_off_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 1 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_off" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", False) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_OFF @@ -257,9 +257,9 @@ async def test_hmip_wired_multi_switch( await hass.services.async_call( "switch", "turn_on", {"entity_id": entity_id}, blocking=True ) - assert len(hmip_device.mock_calls) == service_call_counter + 3 - assert hmip_device.mock_calls[-1][0] == "turn_on_async" - assert hmip_device.mock_calls[-1][1] == (1,) + assert len(hmip_device.functionalChannels[1].mock_calls) == service_call_counter + 2 + assert hmip_device.functionalChannels[1].mock_calls[-1][0] == "async_turn_on" + assert hmip_device.functionalChannels[1].mock_calls[-1][1] == () await async_manipulate_test_data(hass, hmip_device, "on", True) ha_state = hass.states.get(entity_id) assert ha_state.state == STATE_ON