mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Add button platform to Tessie (#106210)
This commit is contained in:
parent
e86ac568e1
commit
8918a9c2c4
@ -16,6 +16,7 @@ from .coordinator import TessieDataUpdateCoordinator
|
||||
|
||||
PLATFORMS = [
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.BUTTON,
|
||||
Platform.CLIMATE,
|
||||
Platform.DEVICE_TRACKER,
|
||||
Platform.SELECT,
|
||||
|
84
homeassistant/components/tessie/button.py
Normal file
84
homeassistant/components/tessie/button.py
Normal file
@ -0,0 +1,84 @@
|
||||
"""Button platform for Tessie integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
|
||||
from tessie_api import (
|
||||
boombox,
|
||||
enable_keyless_driving,
|
||||
flash_lights,
|
||||
honk,
|
||||
open_close_rear_trunk,
|
||||
open_front_trunk,
|
||||
trigger_homelink,
|
||||
wake,
|
||||
)
|
||||
|
||||
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .coordinator import TessieDataUpdateCoordinator
|
||||
from .entity import TessieEntity
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
class TessieButtonEntityDescription(ButtonEntityDescription):
|
||||
"""Describes a Tessie Button entity."""
|
||||
|
||||
func: Callable
|
||||
|
||||
|
||||
DESCRIPTIONS: tuple[TessieButtonEntityDescription, ...] = (
|
||||
TessieButtonEntityDescription(key="wake", func=wake, icon="mdi:sleep-off"),
|
||||
TessieButtonEntityDescription(
|
||||
key="flash_lights", func=flash_lights, icon="mdi:flashlight"
|
||||
),
|
||||
TessieButtonEntityDescription(key="honk", func=honk, icon="mdi:bullhorn"),
|
||||
TessieButtonEntityDescription(
|
||||
key="trigger_homelink", func=trigger_homelink, icon="mdi:garage"
|
||||
),
|
||||
TessieButtonEntityDescription(
|
||||
key="enable_keyless_driving", func=enable_keyless_driving, icon="mdi:car-key"
|
||||
),
|
||||
TessieButtonEntityDescription(key="boombox", func=boombox, icon="mdi:volume-high"),
|
||||
TessieButtonEntityDescription(key="frunk", func=open_front_trunk, icon="mdi:car"),
|
||||
TessieButtonEntityDescription(
|
||||
key="trunk", func=open_close_rear_trunk, icon="mdi:car-back"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||
) -> None:
|
||||
"""Set up the Tessie Button platform from a config entry."""
|
||||
coordinators = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
async_add_entities(
|
||||
TessieButtonEntity(coordinator, description)
|
||||
for coordinator in coordinators
|
||||
for description in DESCRIPTIONS
|
||||
)
|
||||
|
||||
|
||||
class TessieButtonEntity(TessieEntity, ButtonEntity):
|
||||
"""Base class for Tessie Buttons."""
|
||||
|
||||
entity_description: TessieButtonEntityDescription
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: TessieDataUpdateCoordinator,
|
||||
description: TessieButtonEntityDescription,
|
||||
) -> None:
|
||||
"""Initialize the Button."""
|
||||
super().__init__(coordinator, description.key)
|
||||
self.entity_description = description
|
||||
|
||||
async def async_press(self) -> None:
|
||||
"""Press the button."""
|
||||
await self.run(self.entity_description.func)
|
@ -241,6 +241,14 @@
|
||||
"name": "Tire pressure warning rear right"
|
||||
}
|
||||
},
|
||||
"button": {
|
||||
"wake": { "name": "Wake" },
|
||||
"flash_lights": { "name": "Flash lights" },
|
||||
"honk": { "name": "Honk horn" },
|
||||
"trigger_homelink": { "name": "Homelink" },
|
||||
"enable_keyless_driving": { "name": "Keyless driving" },
|
||||
"boombox": { "name": "Play fart" }
|
||||
},
|
||||
"switch": {
|
||||
"charge_state_charge_enable_request": {
|
||||
"name": "Charge"
|
||||
|
@ -1,7 +1,8 @@
|
||||
"""Tessie common helpers for tests."""
|
||||
|
||||
from contextlib import contextmanager
|
||||
from http import HTTPStatus
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from aiohttp import ClientConnectionError, ClientResponseError
|
||||
from aiohttp.client import RequestInfo
|
||||
@ -9,6 +10,7 @@ from aiohttp.client import RequestInfo
|
||||
from homeassistant.components.tessie.const import DOMAIN
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity import EntityDescription
|
||||
|
||||
from tests.common import MockConfigEntry, load_json_object_fixture
|
||||
|
||||
@ -54,3 +56,16 @@ async def setup_platform(hass: HomeAssistant, side_effect=None):
|
||||
await hass.async_block_till_done()
|
||||
|
||||
return mock_entry
|
||||
|
||||
|
||||
@contextmanager
|
||||
def patch_description(
|
||||
key: str, attr: str, descriptions: tuple[EntityDescription]
|
||||
) -> AsyncMock:
|
||||
"""Patch a description."""
|
||||
to_patch = next(filter(lambda x: x.key == key, descriptions))
|
||||
original = to_patch.func
|
||||
mock = AsyncMock()
|
||||
object.__setattr__(to_patch, attr, mock)
|
||||
yield mock
|
||||
object.__setattr__(to_patch, attr, original)
|
||||
|
24
tests/components/tessie/test_button.py
Normal file
24
tests/components/tessie/test_button.py
Normal file
@ -0,0 +1,24 @@
|
||||
"""Test the Tessie button platform."""
|
||||
|
||||
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
|
||||
from homeassistant.components.tessie.button import DESCRIPTIONS
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .common import patch_description, setup_platform
|
||||
|
||||
|
||||
async def test_buttons(hass: HomeAssistant) -> None:
|
||||
"""Tests that the buttons are correct."""
|
||||
|
||||
await setup_platform(hass)
|
||||
|
||||
# Test wake button
|
||||
with patch_description("wake", "func", DESCRIPTIONS) as mock_wake:
|
||||
await hass.services.async_call(
|
||||
BUTTON_DOMAIN,
|
||||
SERVICE_PRESS,
|
||||
{ATTR_ENTITY_ID: ["button.test_wake"]},
|
||||
blocking=True,
|
||||
)
|
||||
mock_wake.assert_called_once()
|
Loading…
x
Reference in New Issue
Block a user