"""Support for ASUSWRT routers."""
from __future__ import annotations

from homeassistant.components.device_tracker import SOURCE_TYPE_ROUTER
from homeassistant.components.device_tracker.config_entry import ScannerEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import callback
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.typing import HomeAssistantType

from .const import DATA_ASUSWRT, DOMAIN
from .router import AsusWrtRouter

DEFAULT_DEVICE_NAME = "Unknown device"


async def async_setup_entry(
    hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
) -> None:
    """Set up device tracker for AsusWrt component."""
    router = hass.data[DOMAIN][entry.entry_id][DATA_ASUSWRT]
    tracked = set()

    @callback
    def update_router():
        """Update the values of the router."""
        add_entities(router, async_add_entities, tracked)

    router.async_on_close(
        async_dispatcher_connect(hass, router.signal_device_new, update_router)
    )

    update_router()


@callback
def add_entities(router, async_add_entities, tracked):
    """Add new tracker entities from the router."""
    new_tracked = []

    for mac, device in router.devices.items():
        if mac in tracked:
            continue

        new_tracked.append(AsusWrtDevice(router, device))
        tracked.add(mac)

    if new_tracked:
        async_add_entities(new_tracked)


class AsusWrtDevice(ScannerEntity):
    """Representation of a AsusWrt device."""

    def __init__(self, router: AsusWrtRouter, device) -> None:
        """Initialize a AsusWrt device."""
        self._router = router
        self._mac = device.mac
        self._name = device.name or DEFAULT_DEVICE_NAME
        self._active = False
        self._icon = None
        self._attrs = {}

    @callback
    def async_update_state(self) -> None:
        """Update the AsusWrt device."""
        device = self._router.devices[self._mac]
        self._active = device.is_connected

        self._attrs = {
            "mac": device.mac,
            "ip_address": device.ip_address,
        }
        if device.last_activity:
            self._attrs["last_time_reachable"] = device.last_activity.isoformat(
                timespec="seconds"
            )

    @property
    def unique_id(self) -> str:
        """Return a unique ID."""
        return self._mac

    @property
    def name(self) -> str:
        """Return the name."""
        return self._name

    @property
    def is_connected(self):
        """Return true if the device is connected to the network."""
        return self._active

    @property
    def source_type(self) -> str:
        """Return the source type."""
        return SOURCE_TYPE_ROUTER

    @property
    def icon(self) -> str:
        """Return the icon."""
        return self._icon

    @property
    def extra_state_attributes(self) -> dict[str, any]:
        """Return the attributes."""
        return self._attrs

    @property
    def device_info(self) -> dict[str, any]:
        """Return the device information."""
        return {
            "connections": {(CONNECTION_NETWORK_MAC, self._mac)},
            "identifiers": {(DOMAIN, self.unique_id)},
            "name": self.name,
            "manufacturer": "AsusWRT Tracked device",
        }

    @property
    def should_poll(self) -> bool:
        """No polling needed."""
        return False

    @callback
    def async_on_demand_update(self):
        """Update state."""
        self.async_update_state()
        self.async_write_ha_state()

    async def async_added_to_hass(self):
        """Register state update callback."""
        self.async_update_state()
        self.async_on_remove(
            async_dispatcher_connect(
                self.hass,
                self._router.signal_device_update,
                self.async_on_demand_update,
            )
        )

@@ -1770,624 +1770,23 @@
 lf._
-mac = device.mac%0A        self._name = device.name or DEFAULT_DEVICE_NAME%0A        self._active = False%0A        self._icon = None%0A        self._attrs = %7B%7D%0A%0A    @callback%0A    def async_update_state(self) -%3E None:%0A        %22%22%22Update the AsusWrt device.%22%22%22%0A        device = self._router.devices%5Bself._mac%5D%0A        self._active = device.is_connected%0A%0A        self._attrs = %7B%0A            %22mac%22: device.mac,%0A            %22ip_address%22: device.ip_address,%0A        %7D%0A        if device.last_activity:%0A            self._attrs%5B%22last_time_reachable%22%5D = device.last_activity.isoformat(%0A                timespec=%22seconds%22%0A            )
+device = device
 %0A%0A  
@@ -1884,16 +1884,23 @@
 n self._
+device.
 mac%0A%0A   
@@ -1989,20 +1989,50 @@
 n self._
-name
+device.name or DEFAULT_DEVICE_NAME
 %0A%0A    @p
@@ -2161,14 +2161,27 @@
 lf._
-active
+device.is_connected
 %0A%0A  
@@ -2325,25 +2325,54 @@
 def 
-icon(self) -%3E str
+extra_state_attributes(self) -%3E dict%5Bstr, any%5D
 :%0A  
@@ -2391,20 +2391,26 @@
 urn the 
-icon
+attributes
 .%22%22%22%0A   
@@ -2418,133 +2418,284 @@
     
-return self._icon%0A%0A    @property%0A    def extra_state_attributes(self) -%3E dict%5Bstr, any%5D:%0A        %22%22%22Return the attributes.%22%22%22
+attrs = %7B%0A            %22mac%22: self._device.mac,%0A            %22ip_address%22: self._device.ip_address,%0A        %7D%0A        if self._device.last_activity:%0A            attrs%5B%22last_time_reachable%22%5D = self._device.last_activity.isoformat(%0A                timespec=%22seconds%22%0A            )
 %0A   
@@ -2706,22 +2706,16 @@
  return 
-self._
 attrs%0A%0A 
@@ -2825,22 +2825,22 @@
         
-return
+data =
  %7B%0A     
@@ -2893,16 +2893,23 @@
 , self._
+device.
 mac)%7D,%0A 
@@ -2917,87 +2917,41 @@
     
+  %7D%0A
       
-%22identifiers%22: %7B(DOMAIN, self.unique_id)%7D,%0A            %22name%22: self
+  if self._device
 .name
-,
+:
 %0A   
@@ -2963,59 +2963,69 @@
     
-%22manufacturer%22: %22AsusWRT Tracked device%22,%0A        %7D
+data%5B%22default_name%22%5D = self._device.name%0A%0A        return data
 %0A%0A  
@@ -3219,36 +3219,64 @@
    self.
-async_update_state()
+_device = self._router.devices%5Bself._device.mac%5D
 %0A       
@@ -3396,42 +3396,8 @@
 %22%22%22%0A
-        self.async_update_state()%0A
     

Clean up AsusWRT (#48012)