Add navigation destination text entity to Tessie integration (#169155)

This commit is contained in:
Mattheinrichs
2026-07-08 23:05:28 +02:00
committed by GitHub
parent 30815a0f41
commit ee59001f72
6 changed files with 188 additions and 0 deletions
@@ -50,6 +50,7 @@ PLATFORMS = [
Platform.SELECT,
Platform.SENSOR,
Platform.SWITCH,
Platform.TEXT,
Platform.UPDATE,
]
@@ -291,6 +291,11 @@
"vehicle_state_valet_mode": {
"default": "mdi:bow-tie"
}
},
"text": {
"navigation_destination": {
"default": "mdi:map-marker"
}
}
}
}
@@ -612,6 +612,11 @@
"name": "Valet mode"
}
},
"text": {
"navigation_destination": {
"name": "Navigation destination"
}
},
"update": {
"update": {
"name": "[%key:component::update::title%]"
+42
View File
@@ -0,0 +1,42 @@
"""Text platform for Tessie integration."""
from typing import override
from homeassistant.components.text import TextEntity, TextMode
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import TessieConfigEntry
from .entity import TessieEntity
from .models import TessieVehicleData
PARALLEL_UPDATES = 0
async def async_setup_entry(
hass: HomeAssistant,
entry: TessieConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the Tessie Text platform from a config entry."""
async_add_entities(
TessieNavigationTextEntity(vehicle) for vehicle in entry.runtime_data.vehicles
)
class TessieNavigationTextEntity(TessieEntity, TextEntity):
"""Text entity to send a navigation destination to the vehicle."""
_attr_mode = TextMode.TEXT
_attr_native_max = 255
_attr_native_min = 1
_attr_native_value: str | None = None
def __init__(self, vehicle: TessieVehicleData) -> None:
"""Initialize the navigation text entity."""
super().__init__(vehicle, "navigation_destination")
@override
async def async_set_value(self, value: str) -> None:
"""Send a navigation destination to the vehicle."""
await self.run(self.api.navigation_request(value))
@@ -0,0 +1,60 @@
# serializer version: 1
# name: test_text_entities[text.test_navigation_destination-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
]),
'area_id': None,
'capabilities': dict({
<TextEntityCapabilityAttribute.MAX: 'max'>: 255,
<TextEntityCapabilityAttribute.MIN: 'min'>: 1,
<TextEntityCapabilityAttribute.MODE: 'mode'>: <TextMode.TEXT: 'text'>,
<TextEntityCapabilityAttribute.PATTERN: 'pattern'>: None,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'text',
'entity_category': None,
'entity_id': 'text.test_navigation_destination',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Navigation destination',
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Navigation destination',
'platform': 'tessie',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'navigation_destination',
'unique_id': 'VINVINVIN-navigation_destination',
'unit_of_measurement': None,
})
# ---
# name: test_text_entities[text.test_navigation_destination-state]
StateSnapshot({
'attributes': ReadOnlyDict({
<EntityStateAttribute.FRIENDLY_NAME: 'friendly_name'>: 'Test Navigation destination',
<TextEntityCapabilityAttribute.MAX: 'max'>: 255,
<TextEntityCapabilityAttribute.MIN: 'min'>: 1,
<TextEntityCapabilityAttribute.MODE: 'mode'>: <TextMode.TEXT: 'text'>,
<TextEntityCapabilityAttribute.PATTERN: 'pattern'>: None,
}),
'context': <ANY>,
'entity_id': 'text.test_navigation_destination',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
+75
View File
@@ -0,0 +1,75 @@
"""Test the Tessie text platform."""
from unittest.mock import patch
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.text import (
ATTR_VALUE,
DOMAIN as TEXT_DOMAIN,
SERVICE_SET_VALUE,
)
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from .common import ERROR_UNKNOWN, assert_entities, setup_platform
NAVIGATION_ENTITY_ID = "text.test_navigation_destination"
async def test_text_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
) -> None:
"""Test that the navigation text entity is set up correctly."""
entry = await setup_platform(hass, [Platform.TEXT])
assert_entities(hass, entry.entry_id, entity_registry, snapshot)
async def test_set_navigation_destination(hass: HomeAssistant) -> None:
"""Test sending a navigation destination to the vehicle."""
await setup_platform(hass, [Platform.TEXT])
with patch(
"tesla_fleet_api.tessie.Vehicle.navigation_request",
) as mock_nav:
await hass.services.async_call(
TEXT_DOMAIN,
SERVICE_SET_VALUE,
{
ATTR_ENTITY_ID: NAVIGATION_ENTITY_ID,
ATTR_VALUE: "1 Infinite Loop, Cupertino, CA",
},
blocking=True,
)
mock_nav.assert_called_once_with("1 Infinite Loop, Cupertino, CA")
async def test_set_navigation_destination_error(hass: HomeAssistant) -> None:
"""Test that a transport error is translated to HomeAssistantError."""
await setup_platform(hass, [Platform.TEXT])
with (
patch(
"tesla_fleet_api.tessie.Vehicle.navigation_request",
side_effect=ERROR_UNKNOWN,
) as mock_nav,
pytest.raises(HomeAssistantError) as error,
):
await hass.services.async_call(
TEXT_DOMAIN,
SERVICE_SET_VALUE,
{
ATTR_ENTITY_ID: NAVIGATION_ENTITY_ID,
ATTR_VALUE: "Times Square, New York",
},
blocking=True,
)
mock_nav.assert_called_once()
assert error.value.translation_domain == "tessie"
assert error.value.translation_key == "cannot_connect"