diff --git a/homeassistant/components/netgear/__init__.py b/homeassistant/components/netgear/__init__.py index 72a56427e17..518a9051847 100644 --- a/homeassistant/components/netgear/__init__.py +++ b/homeassistant/components/netgear/__init__.py @@ -9,7 +9,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SSL from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady -from homeassistant.helpers import device_registry as dr +from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( @@ -17,6 +17,7 @@ from .const import ( KEY_COORDINATOR, KEY_COORDINATOR_TRAFFIC, KEY_ROUTER, + MODE_ROUTER, PLATFORMS, ) from .errors import CannotLoginException @@ -69,7 +70,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_update_devices() -> bool: """Fetch data from the router.""" - return await router.async_update_device_trackers() + if router.mode == MODE_ROUTER: + return await router.async_update_device_trackers() + return False async def async_update_traffic_meter() -> dict[str, Any] | None: """Fetch data from the router.""" @@ -91,7 +94,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: update_interval=SCAN_INTERVAL, ) - await coordinator.async_config_entry_first_refresh() + if router.mode == MODE_ROUTER: + await coordinator.async_config_entry_first_refresh() await coordinator_traffic_meter.async_config_entry_first_refresh() hass.data[DOMAIN][entry.entry_id] = { @@ -109,11 +113,32 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) + router = hass.data[DOMAIN][entry.entry_id][KEY_ROUTER] + if unload_ok: hass.data[DOMAIN].pop(entry.entry_id) if not hass.data[DOMAIN]: hass.data.pop(DOMAIN) + if router.mode != MODE_ROUTER: + router_id = None + # Remove devices that are no longer tracked + device_registry = dr.async_get(hass) + devices = dr.async_entries_for_config_entry(device_registry, entry.entry_id) + for device_entry in devices: + if device_entry.via_device_id is None: + router_id = device_entry.id + continue # do not remove the router itself + device_registry.async_update_device( + device_entry.id, remove_config_entry_id=entry.entry_id + ) + # Remove entities that are no longer tracked + entity_registry = er.async_get(hass) + entries = er.async_entries_for_config_entry(entity_registry, entry.entry_id) + for entity_entry in entries: + if entity_entry.device_id is not router_id: + entity_registry.async_remove(entity_entry.entity_id) + return unload_ok diff --git a/homeassistant/components/netgear/const.py b/homeassistant/components/netgear/const.py index f2e0263a4e4..bc4f37114fd 100644 --- a/homeassistant/components/netgear/const.py +++ b/homeassistant/components/netgear/const.py @@ -16,6 +16,9 @@ KEY_COORDINATOR_TRAFFIC = "coordinator_traffic" DEFAULT_CONSIDER_HOME = timedelta(seconds=180) DEFAULT_NAME = "Netgear router" +MODE_ROUTER = "0" +MODE_AP = "1" + # models using port 80 instead of 5000 MODELS_PORT_80 = [ "Orbi", diff --git a/homeassistant/components/netgear/router.py b/homeassistant/components/netgear/router.py index f543ba8a5f3..6fb44e569d6 100644 --- a/homeassistant/components/netgear/router.py +++ b/homeassistant/components/netgear/router.py @@ -32,6 +32,7 @@ from .const import ( DEFAULT_CONSIDER_HOME, DEFAULT_NAME, DOMAIN, + MODE_ROUTER, MODELS_V2, ) from .errors import CannotLoginException @@ -73,6 +74,7 @@ class NetgearRouter: self._info = None self.model = "" + self.mode = MODE_ROUTER self.device_name = "" self.firmware_version = "" self.hardware_version = "" @@ -108,12 +110,13 @@ class NetgearRouter: self.firmware_version = self._info.get("Firmwareversion") self.hardware_version = self._info.get("Hardwareversion") self.serial_number = self._info["SerialNumber"] + self.mode = self._info.get("DeviceMode", MODE_ROUTER) for model in MODELS_V2: if self.model.startswith(model): self.method_version = 2 - if self.method_version == 2: + if self.method_version == 2 and self.mode == MODE_ROUTER: if not self._api.get_attached_devices_2(): _LOGGER.error( "Netgear Model '%s' in MODELS_V2 list, but failed to get attached devices using V2", @@ -130,28 +133,29 @@ class NetgearRouter: return False # set already known devices to away instead of unavailable - device_registry = dr.async_get(self.hass) - devices = dr.async_entries_for_config_entry(device_registry, self.entry_id) - for device_entry in devices: - if device_entry.via_device_id is None: - continue # do not add the router itself + if self.mode == MODE_ROUTER: + device_registry = dr.async_get(self.hass) + devices = dr.async_entries_for_config_entry(device_registry, self.entry_id) + for device_entry in devices: + if device_entry.via_device_id is None: + continue # do not add the router itself - device_mac = dict(device_entry.connections)[dr.CONNECTION_NETWORK_MAC] - self.devices[device_mac] = { - "mac": device_mac, - "name": device_entry.name, - "active": False, - "last_seen": dt_util.utcnow() - timedelta(days=365), - "device_model": None, - "device_type": None, - "type": None, - "link_rate": None, - "signal": None, - "ip": None, - "ssid": None, - "conn_ap_mac": None, - "allow_or_block": None, - } + device_mac = dict(device_entry.connections)[dr.CONNECTION_NETWORK_MAC] + self.devices[device_mac] = { + "mac": device_mac, + "name": device_entry.name, + "active": False, + "last_seen": dt_util.utcnow() - timedelta(days=365), + "device_model": None, + "device_type": None, + "type": None, + "link_rate": None, + "signal": None, + "ip": None, + "ssid": None, + "conn_ap_mac": None, + "allow_or_block": None, + } return True