From 2f50531be1f2855b5e84eda0088ded479b6a5880 Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Sat, 29 Aug 2026 17:49:21 +0200 Subject: [PATCH] Scan every supported wireless interface in Mikrotik (#180636) --- .../components/mikrotik/coordinator.py | 28 +++++++++++-------- .../mikrotik/test_device_tracker.py | 27 ++++++++++++++++++ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/mikrotik/coordinator.py b/homeassistant/components/mikrotik/coordinator.py index 90edbabfb4ec..0f7a97cc1633 100644 --- a/homeassistant/components/mikrotik/coordinator.py +++ b/homeassistant/components/mikrotik/coordinator.py @@ -239,18 +239,22 @@ class MikrotikData: with mikrotik_config_entry_errors(): # Retrieve data self.all_devices = self.get_list_from_interface(DHCP) - if self.support_capsman: - LOGGER.debug("Hub is a CAPSman manager") - device_list = wireless_devices = self.get_list_from_interface(CAPSMAN) - elif self.support_wireless: - LOGGER.debug("Hub supports wireless Interface") - device_list = wireless_devices = self.get_list_from_interface(WIRELESS) - elif self.support_wifiwave2: - LOGGER.debug("Hub supports wifiwave2 Interface") - device_list = wireless_devices = self.get_list_from_interface(WIFIWAVE2) - elif self.support_wifi: - LOGGER.debug("Hub supports wifi Interface") - device_list = wireless_devices = self.get_list_from_interface(WIFI) + + # A hub can expose more than one wireless stack at once (e.g. the + # legacy "wireless" package kept for CAPsMAN alongside the newer + # "wifi" registration table), so merge every supported interface + # instead of picking only the first match. + for supported, interface, message in ( + (self.support_capsman, CAPSMAN, "Hub is a CAPSman manager"), + (self.support_wireless, WIRELESS, "Hub supports wireless Interface"), + (self.support_wifiwave2, WIFIWAVE2, "Hub supports wifiwave2 Interface"), + (self.support_wifi, WIFI, "Hub supports wifi Interface"), + ): + if supported: + LOGGER.debug(message) + wireless_devices.update(self.get_list_from_interface(interface)) + + device_list = wireless_devices if not device_list or self.force_dhcp: device_list = self.all_devices diff --git a/tests/components/mikrotik/test_device_tracker.py b/tests/components/mikrotik/test_device_tracker.py index 97a0f63392d1..53cb8c90a219 100644 --- a/tests/components/mikrotik/test_device_tracker.py +++ b/tests/components/mikrotik/test_device_tracker.py @@ -190,6 +190,33 @@ async def test_hub_wifi(hass: HomeAssistant) -> None: assert device_2.state == "home" +@pytest.mark.usefixtures("mock_device_registry_devices") +async def test_hub_wireless_and_wifi(hass: HomeAssistant) -> None: + """Test a hub exposing both the legacy wireless package and the wifi driver. + + The legacy ``wireless`` package can linger on a hub acting as a CAPsMAN for + ``wifi`` access points, leaving its registration table empty while the + connected clients are only listed on the ``wifi`` interface. + """ + device_2_without_active_address = { + key: value for key, value in DEVICE_2_DHCP.items() if key != "active-address" + } + + await setup_mikrotik_entry( + hass, + dhcp_data=[DEVICE_1_DHCP, device_2_without_active_address], + support_wireless=True, + wireless_data=[], + support_wifi=True, + wifi_data=[DEVICE_2_WIRELESS], + ) + + # device_2 is only present on the wifi interface, not in the wireless list + device_2 = hass.states.get("device_tracker.device_2") + assert device_2 + assert device_2.state == "home" + + @pytest.mark.usefixtures("mock_device_registry_devices") async def test_wired_device_without_active_address_is_not_home( hass: HomeAssistant,