diff --git a/homeassistant/components/tessie/__init__.py b/homeassistant/components/tessie/__init__.py index 63562faeb60..b360541ef1e 100644 --- a/homeassistant/components/tessie/__init__.py +++ b/homeassistant/components/tessie/__init__.py @@ -17,6 +17,7 @@ from .coordinator import TessieDataUpdateCoordinator PLATFORMS = [ Platform.BINARY_SENSOR, Platform.CLIMATE, + Platform.DEVICE_TRACKER, Platform.SELECT, Platform.SENSOR, Platform.SWITCH, diff --git a/homeassistant/components/tessie/device_tracker.py b/homeassistant/components/tessie/device_tracker.py new file mode 100644 index 00000000000..330623e55b4 --- /dev/null +++ b/homeassistant/components/tessie/device_tracker.py @@ -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") diff --git a/homeassistant/components/tessie/strings.json b/homeassistant/components/tessie/strings.json index f1279ab0daf..a583a6d66eb 100644 --- a/homeassistant/components/tessie/strings.json +++ b/homeassistant/components/tessie/strings.json @@ -22,6 +22,21 @@ } }, "entity": { + "device_tracker": { + "location": { + "state_attributes": { + "heading": { + "name": "Heading" + }, + "speed": { + "name": "Speed" + } + } + }, + "route": { + "name": "Route" + } + }, "climate": { "primary": { "name": "[%key:component::climate::title%]", diff --git a/tests/components/tessie/test_device_tracker.py b/tests/components/tessie/test_device_tracker.py new file mode 100644 index 00000000000..8b42051a10b --- /dev/null +++ b/tests/components/tessie/test_device_tracker.py @@ -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"] + )