Home Assistant Unofficial Reference 2024.12.1
device_tracker.py
Go to the documentation of this file.
1 """Support for Tractive device trackers."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from homeassistant.components.device_tracker import SourceType, TrackerEntity
8 from homeassistant.core import HomeAssistant, callback
9 from homeassistant.helpers.dispatcher import async_dispatcher_connect
10 from homeassistant.helpers.entity_platform import AddEntitiesCallback
11 
12 from . import Trackables, TractiveClient, TractiveConfigEntry
13 from .const import (
14  SERVER_UNAVAILABLE,
15  TRACKER_HARDWARE_STATUS_UPDATED,
16  TRACKER_POSITION_UPDATED,
17 )
18 from .entity import TractiveEntity
19 
20 
22  hass: HomeAssistant,
23  entry: TractiveConfigEntry,
24  async_add_entities: AddEntitiesCallback,
25 ) -> None:
26  """Set up Tractive device trackers."""
27  client = entry.runtime_data.client
28  trackables = entry.runtime_data.trackables
29 
30  entities = [TractiveDeviceTracker(client, item) for item in trackables]
31 
32  async_add_entities(entities)
33 
34 
35 class TractiveDeviceTracker(TractiveEntity, TrackerEntity):
36  """Tractive device tracker."""
37 
38  _attr_translation_key = "tracker"
39 
40  def __init__(self, client: TractiveClient, item: Trackables) -> None:
41  """Initialize tracker entity."""
42  super().__init__(
43  client,
44  item.trackable,
45  item.tracker_details,
46  f"{TRACKER_HARDWARE_STATUS_UPDATED}-{item.tracker_details['_id']}",
47  )
48 
49  self._battery_level_battery_level: int | None = item.hw_info.get("battery_level")
50  self._attr_latitude_attr_latitude = item.pos_report["latlong"][0]
51  self._attr_longitude_attr_longitude = item.pos_report["latlong"][1]
52  self._attr_location_accuracy_attr_location_accuracy: int = item.pos_report["pos_uncertainty"]
53  self._source_type_source_type: str = item.pos_report["sensor_used"]
54  self._attr_unique_id_attr_unique_id = item.trackable["_id"]
55 
56  @property
57  def source_type(self) -> SourceType:
58  """Return the source type, eg gps or router, of the device."""
59  if self._source_type_source_type == "PHONE":
60  return SourceType.BLUETOOTH
61  if self._source_type_source_type == "KNOWN_WIFI":
62  return SourceType.ROUTER
63  return SourceType.GPS
64 
65  @property
66  def battery_level(self) -> int | None:
67  """Return the battery level of the device."""
68  return self._battery_level_battery_level
69 
70  @callback
71  def _handle_hardware_status_update(self, event: dict[str, Any]) -> None:
72  self._battery_level_battery_level = event["battery_level"]
73  self._attr_available_attr_available_attr_available = True
74  self.async_write_ha_stateasync_write_ha_state()
75 
76  @callback
77  def _handle_position_update(self, event: dict[str, Any]) -> None:
78  self._attr_latitude_attr_latitude = event["latitude"]
79  self._attr_longitude_attr_longitude = event["longitude"]
80  self._attr_location_accuracy_attr_location_accuracy = event["accuracy"]
81  self._source_type_source_type = event["sensor_used"]
82  self._attr_available_attr_available_attr_available = True
83  self.async_write_ha_stateasync_write_ha_state()
84 
85  # pylint: disable-next=hass-missing-super-call
86  async def async_added_to_hass(self) -> None:
87  """Handle entity which will be added."""
88  if not self._client_client.subscribed:
89  self._client_client.subscribe()
90 
91  self.async_on_removeasync_on_remove(
93  self.hasshass,
94  self._dispatcher_signal_dispatcher_signal,
95  self._handle_hardware_status_update_handle_hardware_status_update,
96  )
97  )
98 
99  self.async_on_removeasync_on_remove(
101  self.hasshass,
102  f"{TRACKER_POSITION_UPDATED}-{self._tracker_id}",
103  self._handle_position_update_handle_position_update,
104  )
105  )
106 
107  self.async_on_removeasync_on_remove(
109  self.hasshass,
110  f"{SERVER_UNAVAILABLE}-{self._user_id}",
111  self.handle_server_unavailablehandle_server_unavailable,
112  )
113  )
None __init__(self, TractiveClient client, Trackables item)
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
Callable[[], None] subscribe(HomeAssistant hass, str topic, MessageCallbackType msg_callback, int qos=DEFAULT_QOS, str encoding="utf-8")
Definition: client.py:247
None async_setup_entry(HomeAssistant hass, TractiveConfigEntry entry, AddEntitiesCallback async_add_entities)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103