diff --git a/custom_components/eero/__init__.py b/custom_components/eero/__init__.py index aff8889..a3a10c4 100755 --- a/custom_components/eero/__init__.py +++ b/custom_components/eero/__init__.py @@ -12,7 +12,7 @@ import voluptuous as vol from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_NAME, CONF_SCAN_INTERVAL, Platform +from homeassistant.const import CONF_NAME, CONF_SCAN_INTERVAL, Platform, UNDEFINED from homeassistant.core import HomeAssistant from homeassistant.helpers import ( config_validation as cv, @@ -346,7 +346,10 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b device_entry.name, device_entry.model, ) - device_registry.async_remove_device(device_entry.id) + try: + device_registry.async_remove_device(device_entry.id) + except (KeyError, ValueError): + pass else: for entity_entry in er.async_entries_for_device( entity_registry, device_entry.id @@ -395,7 +398,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b conf_update = {} for network_id, resources in conf_resources.items(): conf_update[network_id] = EeroUpdateConfig( - activity=conf_activity[network_id], + activity=conf_activity.get(network_id, {}), profiles=resources[CONF_PROFILES], get_backup_access_points=bool(resources[CONF_BACKUP_NETWORKS]), get_devices=any( @@ -562,6 +565,7 @@ def __init__( ) -> None: """Initialize device.""" super().__init__(coordinator) + self._attr_has_entity_name = True self.network_id = network_id self.resource_id = resource_id self.entity_description = description @@ -570,7 +574,7 @@ def __init__( @property def network(self) -> EeroNetwork | None: - """Return the state attributes.""" + """Return the network for this entity.""" for network in self.coordinator.data.networks: if network.id == self.network_id: return network @@ -578,7 +582,7 @@ def network(self) -> EeroNetwork | None: @property def resource(self) -> EeroResource | None: - """Return the state attributes.""" + """Return the resource for this entity.""" if self.resource_id: for resource in self.network.resources: if resource.id == self.resource_id: @@ -592,13 +596,24 @@ def unique_id(self) -> str: return f"{self.network.id}-{self.entity_description.key}" return f"{self.network.id}-{self.resource.id}-{self.entity_description.key}" + def _device_name(self) -> str: + """Return the Home Assistant device name for this resource.""" + if self.resource.is_client and self.suffix_connection_type: + name = self.resource.name_connection_type + else: + name = self.resource.name + + if not self.resource.is_network and self.prefix_network_name: + return f"{self.network.name} {name}" + return name + @property def device_info(self) -> dr.DeviceInfo: """Return device specific attributes. Implemented by platform classes. """ - name = self.resource.name + name = self._device_name() if self.resource.is_network: model = MODEL_NETWORK elif self.resource.is_backup_network: @@ -611,8 +626,6 @@ def device_info(self) -> dr.DeviceInfo: model = ( MODEL_CLIENT_WIRELESS if self.resource.wireless else MODEL_CLIENT_WIRED ) - if self.suffix_connection_type: - name = self.resource.name_connection_type entry_type, suggested_area, sw_version, hw_version, via_device = ( None, @@ -656,25 +669,11 @@ def device_info(self) -> dr.DeviceInfo: ) @property - def name(self) -> str: + def name(self) -> str | None: """Return the name of the entity.""" - if self.resource.is_client: - name = self.resource.name - if self.suffix_connection_type: - name = self.resource.name_connection_type - if self.prefix_network_name: - name = f"{self.network.name} {name}" - return f"{name} {self.entity_description.name}" - if ( - self.resource.is_backup_network - or self.resource.is_eero - or self.resource.is_profile - ): - name = f"{self.resource.name} {self.entity_description.name}" - if self.prefix_network_name: - name = f"{self.network.name} {name}" - return name - return f"{self.resource.name} {self.entity_description.name}" + if self.entity_description.name in (None, UNDEFINED): + return None + return self.entity_description.name @dataclass diff --git a/custom_components/eero/api/__init__.py b/custom_components/eero/api/__init__.py index d44a735..5611776 100755 --- a/custom_components/eero/api/__init__.py +++ b/custom_components/eero/api/__init__.py @@ -281,7 +281,6 @@ def save_response(self, response: dict[str, Any] | None, name="response") -> Non default=lambda o: "not-serializable", sort_keys=True, ) - file.close() def update( self, diff --git a/custom_components/eero/api/eero.py b/custom_components/eero/api/eero.py index 1ec3f25..0f2c6af 100755 --- a/custom_components/eero/api/eero.py +++ b/custom_components/eero/api/eero.py @@ -140,7 +140,7 @@ def set_status_light_brightness(self, value: int) -> None: if not isinstance(value, int): return None if not value: - return self.set_status_light_off + return self.set_status_light_off() self.api.call( method=METHOD_PUT, url=self.url_led, diff --git a/custom_components/eero/api/network.py b/custom_components/eero/api/network.py index 8dc1ad3..9bf582d 100755 --- a/custom_components/eero/api/network.py +++ b/custom_components/eero/api/network.py @@ -84,7 +84,7 @@ def ad_block_status(self) -> str: @property def adblock_day(self) -> int | None: - """Adblock dasy.""" + """Adblock day.""" for series in ( self.data.get("activity", {}).get("network", {}).get("adblock_day", []) ): diff --git a/custom_components/eero/device_tracker.py b/custom_components/eero/device_tracker.py index 1cc2766..8854584 100755 --- a/custom_components/eero/device_tracker.py +++ b/custom_components/eero/device_tracker.py @@ -5,21 +5,17 @@ from collections.abc import Mapping from dataclasses import dataclass from datetime import datetime, timedelta -from typing import Any, final +from typing import Any from homeassistant.components.device_tracker import ( - ATTR_HOST_NAME, - ATTR_IP, - ATTR_MAC, - ATTR_SOURCE_TYPE, + BaseScannerEntity, SourceType, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ATTR_MANUFACTURER, STATE_HOME, STATE_NOT_HOME +from homeassistant.const import ATTR_MANUFACTURER from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from homeassistant.util import dt as dt_util @@ -100,7 +96,7 @@ async def async_setup_entry( async_add_entities(entities) -class EeroDeviceTrackerEntity(EeroEntity): +class EeroDeviceTrackerEntity(EeroEntity, BaseScannerEntity): """Representation of an Eero device tracker entity.""" _attr_entity_category = EntityCategory.DIAGNOSTIC @@ -126,17 +122,6 @@ def __init__( ) self.last_seen: datetime | None = None - @property - def name(self) -> str | None: - """Return the name of the entity.""" - if self.resource.is_client and self.suffix_connection_type: - name = self.resource.name_connection_type - else: - name = self.resource.name - if self.prefix_network_name: - return f"{self.network.name} {name}" - return name - @property def is_connected(self) -> bool | None: """Return true if the device is connected to the network.""" @@ -176,26 +161,6 @@ def hostname(self) -> str | None: return self.resource.hostname return None - @property - def state(self) -> str: - """Return the state of the device.""" - if self.is_connected: - return STATE_HOME - return STATE_NOT_HOME - - @final - @property - def state_attributes(self) -> dict[str, StateType]: - """Return the device state attributes.""" - attr: dict[str, StateType] = {ATTR_SOURCE_TYPE: self.source_type} - if ip_address := self.ip_address: - attr[ATTR_IP] = ip_address - if mac_address := self.mac_address: - attr[ATTR_MAC] = mac_address - if hostname := self.hostname: - attr[ATTR_HOST_NAME] = hostname - return attr - @property def extra_state_attributes(self) -> Mapping[str, Any] | None: """Return entity specific state attributes.