diff --git a/homeassistant/components/fritz/common.py b/homeassistant/components/fritz/common.py index 2a9a5e5cd2e..a8c77f2deb2 100644 --- a/homeassistant/components/fritz/common.py +++ b/homeassistant/components/fritz/common.py @@ -1,6 +1,7 @@ """Support for AVM FRITZ!Box classes.""" from __future__ import annotations +from collections.abc import ValuesView from dataclasses import dataclass, field from datetime import datetime, timedelta import logging @@ -42,6 +43,36 @@ from .const import ( _LOGGER = logging.getLogger(__name__) +def _is_tracked(mac: str, current_devices: ValuesView) -> bool: + """Check if device is already tracked.""" + for tracked in current_devices: + if mac in tracked: + return True + return False + + +def device_filter_out_from_trackers( + mac: str, + device: FritzDevice, + pref_disable_new_entities: bool, + current_devices: ValuesView, +) -> bool: + """Check if device should be filtered out from trackers.""" + reason: str | None = None + if device.ip_address == "": + reason = "Missing IP" + elif _is_tracked(mac, current_devices): + reason = "Already tracked" + elif pref_disable_new_entities: + reason = "Disabled System Options" + + if reason: + _LOGGER.debug( + "Skip adding device %s [%s], reason: %s", device.hostname, mac, reason + ) + return bool(reason) + + class ClassSetupMissing(Exception): """Raised when a Class func is called before setup.""" @@ -170,7 +201,7 @@ class FritzBoxTools: return self._unique_id @property - def devices(self) -> dict[str, Any]: + def devices(self) -> dict[str, FritzDevice]: """Return devices.""" return self._devices diff --git a/homeassistant/components/fritz/device_tracker.py b/homeassistant/components/fritz/device_tracker.py index e18ec8005cc..f3134f32a27 100644 --- a/homeassistant/components/fritz/device_tracker.py +++ b/homeassistant/components/fritz/device_tracker.py @@ -20,7 +20,13 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType -from .common import FritzBoxTools, FritzData, FritzDevice, FritzDeviceBase +from .common import ( + FritzBoxTools, + FritzData, + FritzDevice, + FritzDeviceBase, + device_filter_out_from_trackers, +) from .const import DATA_FRITZ, DOMAIN _LOGGER = logging.getLogger(__name__) @@ -74,7 +80,9 @@ async def async_setup_entry( @callback def update_router() -> None: """Update the values of the router.""" - _async_add_entities(router, async_add_entities, data_fritz) + _async_add_entities( + router, async_add_entities, data_fritz, entry.pref_disable_new_entities + ) entry.async_on_unload( async_dispatcher_connect(hass, router.signal_device_new, update_router) @@ -88,22 +96,18 @@ def _async_add_entities( router: FritzBoxTools, async_add_entities: AddEntitiesCallback, data_fritz: FritzData, + pref_disable_new_entities: bool, ) -> None: """Add new tracker entities from the router.""" - def _is_tracked(mac: str) -> bool: - for tracked in data_fritz.tracked.values(): - if mac in tracked: - return True - - return False - new_tracked = [] if router.unique_id not in data_fritz.tracked: data_fritz.tracked[router.unique_id] = set() for mac, device in router.devices.items(): - if device.ip_address == "" or _is_tracked(mac): + if device_filter_out_from_trackers( + mac, device, pref_disable_new_entities, data_fritz.tracked.values() + ): continue new_tracked.append(FritzBoxTracker(router, device)) diff --git a/homeassistant/components/fritz/switch.py b/homeassistant/components/fritz/switch.py index 430817d4506..bde9cbcb4ce 100644 --- a/homeassistant/components/fritz/switch.py +++ b/homeassistant/components/fritz/switch.py @@ -31,6 +31,7 @@ from .common import ( FritzDevice, FritzDeviceBase, SwitchInfo, + device_filter_out_from_trackers, ) from .const import ( DATA_FRITZ, @@ -267,17 +268,12 @@ def wifi_entities_list( def profile_entities_list( - router: FritzBoxTools, data_fritz: FritzData + router: FritzBoxTools, + data_fritz: FritzData, + pref_disable_new_entities: bool, ) -> list[FritzBoxProfileSwitch]: """Add new tracker entities from the router.""" - def _is_tracked(mac: str) -> bool: - for tracked in data_fritz.profile_switches.values(): - if mac in tracked: - return True - - return False - new_profiles: list[FritzBoxProfileSwitch] = [] if "X_AVM-DE_HostFilter1" not in router.connection.services: @@ -287,7 +283,9 @@ def profile_entities_list( data_fritz.profile_switches[router.unique_id] = set() for mac, device in router.devices.items(): - if device.ip_address == "" or _is_tracked(mac): + if device_filter_out_from_trackers( + mac, device, pref_disable_new_entities, data_fritz.profile_switches.values() + ): continue new_profiles.append(FritzBoxProfileSwitch(router, device)) @@ -301,13 +299,14 @@ def all_entities_list( device_friendly_name: str, data_fritz: FritzData, local_ip: str, + pref_disable_new_entities: bool, ) -> list[Entity]: """Get a list of all entities.""" return [ *deflection_entities_list(fritzbox_tools, device_friendly_name), *port_entities_list(fritzbox_tools, device_friendly_name, local_ip), *wifi_entities_list(fritzbox_tools, device_friendly_name), - *profile_entities_list(fritzbox_tools, data_fritz), + *profile_entities_list(fritzbox_tools, data_fritz, pref_disable_new_entities), ] @@ -326,7 +325,12 @@ async def async_setup_entry( ) entities_list = await hass.async_add_executor_job( - all_entities_list, fritzbox_tools, entry.title, data_fritz, local_ip + all_entities_list, + fritzbox_tools, + entry.title, + data_fritz, + local_ip, + entry.pref_disable_new_entities, ) async_add_entities(entities_list) @@ -334,7 +338,11 @@ async def async_setup_entry( @callback def update_router() -> None: """Update the values of the router.""" - async_add_entities(profile_entities_list(fritzbox_tools, data_fritz)) + async_add_entities( + profile_entities_list( + fritzbox_tools, data_fritz, entry.pref_disable_new_entities + ) + ) entry.async_on_unload( async_dispatcher_connect(hass, fritzbox_tools.signal_device_new, update_router)