Huawei LTE device tracker fixes (#29551)

* Include MAC address in device state attributes for absent devices too

* Use MAC address as default name whether device is connected or not

* Fix initialization of known entities

Closes https://github.com/home-assistant/home-assistant/issues/29354
This commit is contained in:
Ville Skyttä 2019-12-06 22:53:26 +02:00 committed by Martin Hjelmare
parent 74d86dfff9
commit 31c71989e9

View File

@ -2,7 +2,7 @@
import logging import logging
import re import re
from typing import Any, Dict, Set from typing import Any, Dict, List, Optional, Set
import attr import attr
from stringcase import snakecase from stringcase import snakecase
@ -40,13 +40,17 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
# Initialize already tracked entities # Initialize already tracked entities
tracked: Set[str] = set() tracked: Set[str] = set()
registry = await entity_registry.async_get_registry(hass) registry = await entity_registry.async_get_registry(hass)
known_entities: List[HuaweiLteScannerEntity] = []
for entity in registry.entities.values(): for entity in registry.entities.values():
if ( if (
entity.domain == DEVICE_TRACKER_DOMAIN entity.domain == DEVICE_TRACKER_DOMAIN
and entity.config_entry_id == config_entry.entry_id and entity.config_entry_id == config_entry.entry_id
): ):
tracked.add(entity.unique_id) tracked.add(entity.unique_id)
async_add_new_entities(hass, router.url, async_add_entities, tracked, True) known_entities.append(
HuaweiLteScannerEntity(router, entity.unique_id.partition("-")[2])
)
async_add_entities(known_entities, True)
# Tell parent router to poll hosts list to gather new devices # Tell parent router to poll hosts list to gather new devices
router.subscriptions[KEY_WLAN_HOST_LIST].add(_DEVICE_SCAN) router.subscriptions[KEY_WLAN_HOST_LIST].add(_DEVICE_SCAN)
@ -66,13 +70,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
async_add_new_entities(hass, router.url, async_add_entities, tracked) async_add_new_entities(hass, router.url, async_add_entities, tracked)
def async_add_new_entities( def async_add_new_entities(hass, router_url, async_add_entities, tracked):
hass, router_url, async_add_entities, tracked, included: bool = False """Add new entities that are not already being tracked."""
):
"""Add new entities.
:param included: if True, setup only items in tracked, and vice versa
"""
router = hass.data[DOMAIN].routers[router_url] router = hass.data[DOMAIN].routers[router_url]
try: try:
hosts = router.data[KEY_WLAN_HOST_LIST]["Hosts"]["Host"] hosts = router.data[KEY_WLAN_HOST_LIST]["Hosts"]["Host"]
@ -83,8 +82,7 @@ def async_add_new_entities(
new_entities = [] new_entities = []
for host in (x for x in hosts if x.get("MacAddress")): for host in (x for x in hosts if x.get("MacAddress")):
entity = HuaweiLteScannerEntity(router, host["MacAddress"]) entity = HuaweiLteScannerEntity(router, host["MacAddress"])
tracking = entity.unique_id in tracked if entity.unique_id in tracked:
if tracking != included:
continue continue
tracked.add(entity.unique_id) tracked.add(entity.unique_id)
new_entities.append(entity) new_entities.append(entity)
@ -113,12 +111,16 @@ class HuaweiLteScannerEntity(HuaweiLteBaseEntity, ScannerEntity):
mac: str = attr.ib() mac: str = attr.ib()
_is_connected: bool = attr.ib(init=False, default=False) _is_connected: bool = attr.ib(init=False, default=False)
_name: str = attr.ib(init=False, default="device") _hostname: Optional[str] = attr.ib(init=False, default=None)
_device_state_attributes: Dict[str, Any] = attr.ib(init=False, factory=dict) _device_state_attributes: Dict[str, Any] = attr.ib(init=False, factory=dict)
def __attrs_post_init__(self):
"""Initialize internal state."""
self._device_state_attributes["mac_address"] = self.mac
@property @property
def _entity_name(self) -> str: def _entity_name(self) -> str:
return self._name return self._hostname or self.mac
@property @property
def _device_unique_id(self) -> str: def _device_unique_id(self) -> str:
@ -145,8 +147,7 @@ class HuaweiLteScannerEntity(HuaweiLteBaseEntity, ScannerEntity):
host = next((x for x in hosts if x.get("MacAddress") == self.mac), None) host = next((x for x in hosts if x.get("MacAddress") == self.mac), None)
self._is_connected = host is not None self._is_connected = host is not None
if self._is_connected: if self._is_connected:
# HostName may be present with explicit None value self._hostname = host.get("HostName")
self._name = host.get("HostName") or self.mac
self._device_state_attributes = { self._device_state_attributes = {
_better_snakecase(k): v for k, v in host.items() if k != "HostName" _better_snakecase(k): v for k, v in host.items() if k != "HostName"
} }