core/homeassistant/components/tractive/device_tracker.py

140 lines
4.1 KiB
Python

"""Support for Tractive device trackers."""
import asyncio
import logging
from homeassistant.components.device_tracker import SOURCE_TYPE_GPS
from homeassistant.components.device_tracker.config_entry import TrackerEntity
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import (
DOMAIN,
SERVER_UNAVAILABLE,
TRACKER_HARDWARE_STATUS_UPDATED,
TRACKER_POSITION_UPDATED,
)
from .entity import TractiveEntity
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, entry, async_add_entities):
"""Set up Tractive device trackers."""
client = hass.data[DOMAIN][entry.entry_id]
trackables = await client.trackable_objects()
entities = await asyncio.gather(
*(create_trackable_entity(client, trackable) for trackable in trackables)
)
async_add_entities(entities)
async def create_trackable_entity(client, trackable):
"""Create an entity instance."""
trackable = await trackable.details()
tracker = client.tracker(trackable["device_id"])
tracker_details, hw_info, pos_report = await asyncio.gather(
tracker.details(), tracker.hw_info(), tracker.pos_report()
)
return TractiveDeviceTracker(
client.user_id, trackable, tracker_details, hw_info, pos_report
)
class TractiveDeviceTracker(TractiveEntity, TrackerEntity):
"""Tractive device tracker."""
_attr_icon = "mdi:paw"
def __init__(self, user_id, trackable, tracker_details, hw_info, pos_report):
"""Initialize tracker entity."""
super().__init__(user_id, trackable, tracker_details)
self._battery_level = hw_info["battery_level"]
self._latitude = pos_report["latlong"][0]
self._longitude = pos_report["latlong"][1]
self._accuracy = pos_report["pos_uncertainty"]
self._attr_name = f"{self._tracker_id} {trackable['details']['name']}"
self._attr_unique_id = trackable["_id"]
@property
def source_type(self):
"""Return the source type, eg gps or router, of the device."""
return SOURCE_TYPE_GPS
@property
def latitude(self):
"""Return latitude value of the device."""
return self._latitude
@property
def longitude(self):
"""Return longitude value of the device."""
return self._longitude
@property
def location_accuracy(self):
"""Return the gps accuracy of the device."""
return self._accuracy
@property
def battery_level(self):
"""Return the battery level of the device."""
return self._battery_level
@callback
def _handle_hardware_status_update(self, event):
self._battery_level = event["battery_level"]
self._attr_available = True
self.async_write_ha_state()
@callback
def _handle_position_update(self, event):
self._latitude = event["latitude"]
self._longitude = event["longitude"]
self._accuracy = event["accuracy"]
self._attr_available = True
self.async_write_ha_state()
@callback
def _handle_server_unavailable(self):
self._latitude = None
self._longitude = None
self._accuracy = None
self._battery_level = None
self._attr_available = False
self.async_write_ha_state()
async def async_added_to_hass(self):
"""Handle entity which will be added."""
self.async_on_remove(
async_dispatcher_connect(
self.hass,
f"{TRACKER_HARDWARE_STATUS_UPDATED}-{self._tracker_id}",
self._handle_hardware_status_update,
)
)
self.async_on_remove(
async_dispatcher_connect(
self.hass,
f"{TRACKER_POSITION_UPDATED}-{self._tracker_id}",
self._handle_position_update,
)
)
self.async_on_remove(
async_dispatcher_connect(
self.hass,
f"{SERVER_UNAVAILABLE}-{self._user_id}",
self._handle_server_unavailable,
)
)