Add device tracker to Tessie (#105428)
Co-authored-by: J. Nick Koston <nick@koston.org>pull/106212/head^2
parent
8b08b5e8d2
commit
e86ac568e1
|
@ -17,6 +17,7 @@ from .coordinator import TessieDataUpdateCoordinator
|
||||||
PLATFORMS = [
|
PLATFORMS = [
|
||||||
Platform.BINARY_SENSOR,
|
Platform.BINARY_SENSOR,
|
||||||
Platform.CLIMATE,
|
Platform.CLIMATE,
|
||||||
|
Platform.DEVICE_TRACKER,
|
||||||
Platform.SELECT,
|
Platform.SELECT,
|
||||||
Platform.SENSOR,
|
Platform.SENSOR,
|
||||||
Platform.SWITCH,
|
Platform.SWITCH,
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
"""Device Tracker platform for Tessie integration."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from homeassistant.components.device_tracker import SourceType
|
||||||
|
from homeassistant.components.device_tracker.config_entry import TrackerEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.helpers.typing import StateType
|
||||||
|
|
||||||
|
from .const import DOMAIN
|
||||||
|
from .coordinator import TessieDataUpdateCoordinator
|
||||||
|
from .entity import TessieEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
|
) -> None:
|
||||||
|
"""Set up the Tessie device tracker platform from a config entry."""
|
||||||
|
coordinators = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
|
||||||
|
async_add_entities(
|
||||||
|
klass(coordinator)
|
||||||
|
for klass in (
|
||||||
|
TessieDeviceTrackerLocationEntity,
|
||||||
|
TessieDeviceTrackerRouteEntity,
|
||||||
|
)
|
||||||
|
for coordinator in coordinators
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TessieDeviceTrackerEntity(TessieEntity, TrackerEntity):
|
||||||
|
"""Base class for Tessie Tracker Entities."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
coordinator: TessieDataUpdateCoordinator,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize the device tracker."""
|
||||||
|
super().__init__(coordinator, self.key)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def source_type(self) -> SourceType | str:
|
||||||
|
"""Return the source type of the device tracker."""
|
||||||
|
return SourceType.GPS
|
||||||
|
|
||||||
|
|
||||||
|
class TessieDeviceTrackerLocationEntity(TessieDeviceTrackerEntity):
|
||||||
|
"""Vehicle Location Device Tracker Class."""
|
||||||
|
|
||||||
|
_attr_name = None
|
||||||
|
key = "location"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def longitude(self) -> float | None:
|
||||||
|
"""Return the longitude of the device tracker."""
|
||||||
|
return self.get("drive_state_longitude")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def latitude(self) -> float | None:
|
||||||
|
"""Return the latitude of the device tracker."""
|
||||||
|
return self.get("drive_state_latitude")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extra_state_attributes(self) -> dict[str, StateType] | None:
|
||||||
|
"""Return device state attributes."""
|
||||||
|
return {
|
||||||
|
"heading": self.get("drive_state_heading"),
|
||||||
|
"speed": self.get("drive_state_speed"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TessieDeviceTrackerRouteEntity(TessieDeviceTrackerEntity):
|
||||||
|
"""Vehicle Navigation Device Tracker Class."""
|
||||||
|
|
||||||
|
key = "route"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def longitude(self) -> float | None:
|
||||||
|
"""Return the longitude of the device tracker."""
|
||||||
|
return self.get("drive_state_active_route_longitude")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def latitude(self) -> float | None:
|
||||||
|
"""Return the latitude of the device tracker."""
|
||||||
|
return self.get("drive_state_active_route_latitude")
|
|
@ -22,6 +22,21 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
|
"device_tracker": {
|
||||||
|
"location": {
|
||||||
|
"state_attributes": {
|
||||||
|
"heading": {
|
||||||
|
"name": "Heading"
|
||||||
|
},
|
||||||
|
"speed": {
|
||||||
|
"name": "Speed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"route": {
|
||||||
|
"name": "Route"
|
||||||
|
}
|
||||||
|
},
|
||||||
"climate": {
|
"climate": {
|
||||||
"primary": {
|
"primary": {
|
||||||
"name": "[%key:component::climate::title%]",
|
"name": "[%key:component::climate::title%]",
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
"""Test the Tessie device tracker platform."""
|
||||||
|
|
||||||
|
|
||||||
|
from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER_DOMAIN
|
||||||
|
from homeassistant.const import ATTR_LATITUDE, ATTR_LONGITUDE
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from .common import TEST_STATE_OF_ALL_VEHICLES, setup_platform
|
||||||
|
|
||||||
|
STATES = TEST_STATE_OF_ALL_VEHICLES["results"][0]["last_state"]
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_tracker(hass: HomeAssistant) -> None:
|
||||||
|
"""Tests that the device trackers are correct."""
|
||||||
|
|
||||||
|
assert len(hass.states.async_all(DEVICE_TRACKER_DOMAIN)) == 0
|
||||||
|
|
||||||
|
await setup_platform(hass)
|
||||||
|
|
||||||
|
assert len(hass.states.async_all(DEVICE_TRACKER_DOMAIN)) == 2
|
||||||
|
|
||||||
|
entity_id = "device_tracker.test"
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.attributes.get(ATTR_LATITUDE) == STATES["drive_state"]["latitude"]
|
||||||
|
assert state.attributes.get(ATTR_LONGITUDE) == STATES["drive_state"]["longitude"]
|
||||||
|
|
||||||
|
entity_id = "device_tracker.test_route"
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert (
|
||||||
|
state.attributes.get(ATTR_LATITUDE)
|
||||||
|
== STATES["drive_state"]["active_route_latitude"]
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
state.attributes.get(ATTR_LONGITUDE)
|
||||||
|
== STATES["drive_state"]["active_route_longitude"]
|
||||||
|
)
|
Loading…
Reference in New Issue