Home Assistant Unofficial Reference 2024.12.1
device_tracker.py
Go to the documentation of this file.
1 """Support for Mikrotik routers as device tracker."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
8  DOMAIN as DEVICE_TRACKER,
9  ScannerEntity,
10 )
11 from homeassistant.core import HomeAssistant, callback
12 from homeassistant.helpers import entity_registry as er
13 from homeassistant.helpers.entity_platform import AddEntitiesCallback
14 from homeassistant.helpers.update_coordinator import CoordinatorEntity
15 import homeassistant.util.dt as dt_util
16 
17 from . import MikrotikConfigEntry
18 from .coordinator import Device, MikrotikDataUpdateCoordinator
19 
20 
22  hass: HomeAssistant,
23  config_entry: MikrotikConfigEntry,
24  async_add_entities: AddEntitiesCallback,
25 ) -> None:
26  """Set up device tracker for Mikrotik component."""
27  coordinator = config_entry.runtime_data
28 
29  tracked: dict[str, MikrotikDataUpdateCoordinatorTracker] = {}
30 
31  registry = er.async_get(hass)
32 
33  # Restore clients that is not a part of active clients list.
34  for entity in registry.entities.get_entries_for_config_entry_id(
35  config_entry.entry_id
36  ):
37  if entity.domain == DEVICE_TRACKER:
38  if (
39  entity.unique_id in coordinator.api.devices
40  or entity.unique_id not in coordinator.api.all_devices
41  ):
42  continue
43  coordinator.api.restore_device(entity.unique_id)
44 
45  @callback
46  def update_hub() -> None:
47  """Update the status of the device."""
48  update_items(coordinator, async_add_entities, tracked)
49 
50  config_entry.async_on_unload(coordinator.async_add_listener(update_hub))
51 
52  update_hub()
53 
54 
55 @callback
57  coordinator: MikrotikDataUpdateCoordinator,
58  async_add_entities: AddEntitiesCallback,
59  tracked: dict[str, MikrotikDataUpdateCoordinatorTracker],
60 ) -> None:
61  """Update tracked device state from the hub."""
62  new_tracked: list[MikrotikDataUpdateCoordinatorTracker] = []
63  for mac, device in coordinator.api.devices.items():
64  if mac not in tracked:
65  tracked[mac] = MikrotikDataUpdateCoordinatorTracker(device, coordinator)
66  new_tracked.append(tracked[mac])
67 
68  async_add_entities(new_tracked)
69 
70 
72  CoordinatorEntity[MikrotikDataUpdateCoordinator], ScannerEntity
73 ):
74  """Representation of network device."""
75 
76  def __init__(
77  self, device: Device, coordinator: MikrotikDataUpdateCoordinator
78  ) -> None:
79  """Initialize the tracked device."""
80  super().__init__(coordinator)
81  self.devicedevice = device
82  self._attr_name_attr_name = device.name
83  self._attr_unique_id_attr_unique_id = device.mac
84 
85  @property
86  def is_connected(self) -> bool:
87  """Return true if the client is connected to the network."""
88  if (
89  self.devicedevice.last_seen
90  and (dt_util.utcnow() - self.devicedevice.last_seen)
91  < self.coordinator.option_detection_time
92  ):
93  return True
94  return False
95 
96  @property
97  def hostname(self) -> str:
98  """Return the hostname of the client."""
99  return self.devicedevice.name
100 
101  @property
102  def mac_address(self) -> str:
103  """Return the mac address of the client."""
104  return self.devicedevice.mac
105 
106  @property
107  def ip_address(self) -> str | None:
108  """Return the mac address of the client."""
109  return self.devicedevice.ip_address
110 
111  @property
112  def extra_state_attributes(self) -> dict[str, Any] | None:
113  """Return the device state attributes."""
114  return self.devicedevice.attrs if self.is_connectedis_connected else None
None __init__(self, Device device, MikrotikDataUpdateCoordinator coordinator)
None async_setup_entry(HomeAssistant hass, MikrotikConfigEntry config_entry, AddEntitiesCallback async_add_entities)
None update_items(MikrotikDataUpdateCoordinator coordinator, AddEntitiesCallback async_add_entities, dict[str, MikrotikDataUpdateCoordinatorTracker] tracked)