mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Rework entity description functions in Tessie (#106287)
* use lamdba to return the library function * Rename mocks * lambda number * Lambda button * Add missing * Remove context manager
This commit is contained in:
parent
ea7c839423
commit
043f3e640c
@ -33,21 +33,27 @@ class TessieButtonEntityDescription(ButtonEntityDescription):
|
|||||||
|
|
||||||
|
|
||||||
DESCRIPTIONS: tuple[TessieButtonEntityDescription, ...] = (
|
DESCRIPTIONS: tuple[TessieButtonEntityDescription, ...] = (
|
||||||
TessieButtonEntityDescription(key="wake", func=wake, icon="mdi:sleep-off"),
|
TessieButtonEntityDescription(key="wake", func=lambda: wake, icon="mdi:sleep-off"),
|
||||||
TessieButtonEntityDescription(
|
TessieButtonEntityDescription(
|
||||||
key="flash_lights", func=flash_lights, icon="mdi:flashlight"
|
key="flash_lights", func=lambda: flash_lights, icon="mdi:flashlight"
|
||||||
),
|
),
|
||||||
TessieButtonEntityDescription(key="honk", func=honk, icon="mdi:bullhorn"),
|
TessieButtonEntityDescription(key="honk", func=honk, icon="mdi:bullhorn"),
|
||||||
TessieButtonEntityDescription(
|
TessieButtonEntityDescription(
|
||||||
key="trigger_homelink", func=trigger_homelink, icon="mdi:garage"
|
key="trigger_homelink", func=lambda: trigger_homelink, icon="mdi:garage"
|
||||||
),
|
),
|
||||||
TessieButtonEntityDescription(
|
TessieButtonEntityDescription(
|
||||||
key="enable_keyless_driving", func=enable_keyless_driving, icon="mdi:car-key"
|
key="enable_keyless_driving",
|
||||||
|
func=lambda: 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(
|
TessieButtonEntityDescription(
|
||||||
key="trunk", func=open_close_rear_trunk, icon="mdi:car-back"
|
key="boombox", func=lambda: boombox, icon="mdi:volume-high"
|
||||||
|
),
|
||||||
|
TessieButtonEntityDescription(
|
||||||
|
key="frunk", func=lambda: open_front_trunk, icon="mdi:car"
|
||||||
|
),
|
||||||
|
TessieButtonEntityDescription(
|
||||||
|
key="trunk", func=lambda: open_close_rear_trunk, icon="mdi:car-back"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -81,4 +87,4 @@ class TessieButtonEntity(TessieEntity, ButtonEntity):
|
|||||||
|
|
||||||
async def async_press(self) -> None:
|
async def async_press(self) -> None:
|
||||||
"""Press the button."""
|
"""Press the button."""
|
||||||
await self.run(self.entity_description.func)
|
await self.run(self.entity_description.func())
|
||||||
|
@ -48,7 +48,7 @@ DESCRIPTIONS: tuple[TessieNumberEntityDescription, ...] = (
|
|||||||
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
|
||||||
device_class=NumberDeviceClass.CURRENT,
|
device_class=NumberDeviceClass.CURRENT,
|
||||||
max_key="charge_state_charge_current_request_max",
|
max_key="charge_state_charge_current_request_max",
|
||||||
func=set_charging_amps,
|
func=lambda: set_charging_amps,
|
||||||
arg="amps",
|
arg="amps",
|
||||||
),
|
),
|
||||||
TessieNumberEntityDescription(
|
TessieNumberEntityDescription(
|
||||||
@ -60,7 +60,7 @@ DESCRIPTIONS: tuple[TessieNumberEntityDescription, ...] = (
|
|||||||
device_class=NumberDeviceClass.BATTERY,
|
device_class=NumberDeviceClass.BATTERY,
|
||||||
min_key="charge_state_charge_limit_soc_min",
|
min_key="charge_state_charge_limit_soc_min",
|
||||||
max_key="charge_state_charge_limit_soc_max",
|
max_key="charge_state_charge_limit_soc_max",
|
||||||
func=set_charge_limit,
|
func=lambda: set_charge_limit,
|
||||||
arg="percent",
|
arg="percent",
|
||||||
),
|
),
|
||||||
TessieNumberEntityDescription(
|
TessieNumberEntityDescription(
|
||||||
@ -73,7 +73,7 @@ DESCRIPTIONS: tuple[TessieNumberEntityDescription, ...] = (
|
|||||||
mode=NumberMode.BOX,
|
mode=NumberMode.BOX,
|
||||||
min_key="vehicle_state_speed_limit_mode_min_limit_mph",
|
min_key="vehicle_state_speed_limit_mode_min_limit_mph",
|
||||||
max_key="vehicle_state_speed_limit_mode_max_limit_mph",
|
max_key="vehicle_state_speed_limit_mode_max_limit_mph",
|
||||||
func=set_speed_limit,
|
func=lambda: set_speed_limit,
|
||||||
arg="mph",
|
arg="mph",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -132,6 +132,6 @@ class TessieNumberEntity(TessieEntity, NumberEntity):
|
|||||||
async def async_set_native_value(self, value: float) -> None:
|
async def async_set_native_value(self, value: float) -> None:
|
||||||
"""Set new value."""
|
"""Set new value."""
|
||||||
await self.run(
|
await self.run(
|
||||||
self.entity_description.func, **{self.entity_description.arg: value}
|
self.entity_description.func(), **{self.entity_description.arg: value}
|
||||||
)
|
)
|
||||||
self.set((self.key, value))
|
self.set((self.key, value))
|
||||||
|
@ -43,32 +43,32 @@ class TessieSwitchEntityDescription(SwitchEntityDescription):
|
|||||||
DESCRIPTIONS: tuple[TessieSwitchEntityDescription, ...] = (
|
DESCRIPTIONS: tuple[TessieSwitchEntityDescription, ...] = (
|
||||||
TessieSwitchEntityDescription(
|
TessieSwitchEntityDescription(
|
||||||
key="charge_state_charge_enable_request",
|
key="charge_state_charge_enable_request",
|
||||||
on_func=start_charging,
|
on_func=lambda: start_charging,
|
||||||
off_func=stop_charging,
|
off_func=lambda: stop_charging,
|
||||||
icon="mdi:ev-station",
|
icon="mdi:ev-station",
|
||||||
),
|
),
|
||||||
TessieSwitchEntityDescription(
|
TessieSwitchEntityDescription(
|
||||||
key="climate_state_defrost_mode",
|
key="climate_state_defrost_mode",
|
||||||
on_func=start_defrost,
|
on_func=lambda: start_defrost,
|
||||||
off_func=stop_defrost,
|
off_func=lambda: stop_defrost,
|
||||||
icon="mdi:snowflake",
|
icon="mdi:snowflake",
|
||||||
),
|
),
|
||||||
TessieSwitchEntityDescription(
|
TessieSwitchEntityDescription(
|
||||||
key="vehicle_state_sentry_mode",
|
key="vehicle_state_sentry_mode",
|
||||||
on_func=enable_sentry_mode,
|
on_func=lambda: enable_sentry_mode,
|
||||||
off_func=disable_sentry_mode,
|
off_func=lambda: disable_sentry_mode,
|
||||||
icon="mdi:shield-car",
|
icon="mdi:shield-car",
|
||||||
),
|
),
|
||||||
TessieSwitchEntityDescription(
|
TessieSwitchEntityDescription(
|
||||||
key="vehicle_state_valet_mode",
|
key="vehicle_state_valet_mode",
|
||||||
on_func=enable_valet_mode,
|
on_func=lambda: enable_valet_mode,
|
||||||
off_func=disable_valet_mode,
|
off_func=lambda: disable_valet_mode,
|
||||||
icon="mdi:car-key",
|
icon="mdi:car-key",
|
||||||
),
|
),
|
||||||
TessieSwitchEntityDescription(
|
TessieSwitchEntityDescription(
|
||||||
key="climate_state_steering_wheel_heater",
|
key="climate_state_steering_wheel_heater",
|
||||||
on_func=start_steering_wheel_heater,
|
on_func=lambda: start_steering_wheel_heater,
|
||||||
off_func=stop_steering_wheel_heater,
|
off_func=lambda: stop_steering_wheel_heater,
|
||||||
icon="mdi:steering",
|
icon="mdi:steering",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -112,10 +112,10 @@ class TessieSwitchEntity(TessieEntity, SwitchEntity):
|
|||||||
|
|
||||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn on the Switch."""
|
"""Turn on the Switch."""
|
||||||
await self.run(self.entity_description.on_func)
|
await self.run(self.entity_description.on_func())
|
||||||
self.set((self.entity_description.key, True))
|
self.set((self.entity_description.key, True))
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn off the Switch."""
|
"""Turn off the Switch."""
|
||||||
await self.run(self.entity_description.off_func)
|
await self.run(self.entity_description.off_func())
|
||||||
self.set((self.entity_description.key, False))
|
self.set((self.entity_description.key, False))
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
"""Tessie common helpers for tests."""
|
"""Tessie common helpers for tests."""
|
||||||
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from aiohttp import ClientConnectionError, ClientResponseError
|
from aiohttp import ClientConnectionError, ClientResponseError
|
||||||
from aiohttp.client import RequestInfo
|
from aiohttp.client import RequestInfo
|
||||||
@ -10,7 +9,6 @@ from aiohttp.client import RequestInfo
|
|||||||
from homeassistant.components.tessie.const import DOMAIN
|
from homeassistant.components.tessie.const import DOMAIN
|
||||||
from homeassistant.const import CONF_ACCESS_TOKEN
|
from homeassistant.const import CONF_ACCESS_TOKEN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity import EntityDescription
|
|
||||||
|
|
||||||
from tests.common import MockConfigEntry, load_json_object_fixture
|
from tests.common import MockConfigEntry, load_json_object_fixture
|
||||||
|
|
||||||
@ -61,16 +59,3 @@ async def setup_platform(hass: HomeAssistant, side_effect=None):
|
|||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
return mock_entry
|
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)
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
"""Test the Tessie button platform."""
|
"""Test the Tessie button platform."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
|
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.const import ATTR_ENTITY_ID
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .common import patch_description, setup_platform
|
from .common import setup_platform
|
||||||
|
|
||||||
|
|
||||||
async def test_buttons(hass: HomeAssistant) -> None:
|
async def test_buttons(hass: HomeAssistant) -> None:
|
||||||
@ -14,7 +14,9 @@ async def test_buttons(hass: HomeAssistant) -> None:
|
|||||||
await setup_platform(hass)
|
await setup_platform(hass)
|
||||||
|
|
||||||
# Test wake button
|
# Test wake button
|
||||||
with patch_description("wake", "func", DESCRIPTIONS) as mock_wake:
|
with patch(
|
||||||
|
"homeassistant.components.tessie.button.wake",
|
||||||
|
) as mock_wake:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
BUTTON_DOMAIN,
|
BUTTON_DOMAIN,
|
||||||
SERVICE_PRESS,
|
SERVICE_PRESS,
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
"""Test the Tessie number platform."""
|
"""Test the Tessie number platform."""
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN, SERVICE_SET_VALUE
|
from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN, SERVICE_SET_VALUE
|
||||||
from homeassistant.components.tessie.number import DESCRIPTIONS
|
from homeassistant.components.tessie.number import DESCRIPTIONS
|
||||||
from homeassistant.const import ATTR_ENTITY_ID
|
from homeassistant.const import ATTR_ENTITY_ID
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .common import TEST_VEHICLE_STATE_ONLINE, patch_description, setup_platform
|
from .common import TEST_VEHICLE_STATE_ONLINE, setup_platform
|
||||||
|
|
||||||
|
|
||||||
async def test_numbers(hass: HomeAssistant) -> None:
|
async def test_numbers(hass: HomeAssistant) -> None:
|
||||||
@ -33,8 +34,8 @@ async def test_numbers(hass: HomeAssistant) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test number set value functions
|
# Test number set value functions
|
||||||
with patch_description(
|
with patch(
|
||||||
"charge_state_charge_current_request", "func", DESCRIPTIONS
|
"homeassistant.components.tessie.number.set_charging_amps",
|
||||||
) as mock_set_charging_amps:
|
) as mock_set_charging_amps:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
NUMBER_DOMAIN,
|
NUMBER_DOMAIN,
|
||||||
@ -45,8 +46,8 @@ async def test_numbers(hass: HomeAssistant) -> None:
|
|||||||
assert hass.states.get("number.test_charge_current").state == "16.0"
|
assert hass.states.get("number.test_charge_current").state == "16.0"
|
||||||
mock_set_charging_amps.assert_called_once()
|
mock_set_charging_amps.assert_called_once()
|
||||||
|
|
||||||
with patch_description(
|
with patch(
|
||||||
"charge_state_charge_limit_soc", "func", DESCRIPTIONS
|
"homeassistant.components.tessie.number.set_charge_limit",
|
||||||
) as mock_set_charge_limit:
|
) as mock_set_charge_limit:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
NUMBER_DOMAIN,
|
NUMBER_DOMAIN,
|
||||||
@ -57,8 +58,8 @@ async def test_numbers(hass: HomeAssistant) -> None:
|
|||||||
assert hass.states.get("number.test_charge_limit").state == "80.0"
|
assert hass.states.get("number.test_charge_limit").state == "80.0"
|
||||||
mock_set_charge_limit.assert_called_once()
|
mock_set_charge_limit.assert_called_once()
|
||||||
|
|
||||||
with patch_description(
|
with patch(
|
||||||
"vehicle_state_speed_limit_mode_current_limit_mph", "func", DESCRIPTIONS
|
"homeassistant.components.tessie.number.set_speed_limit",
|
||||||
) as mock_set_speed_limit:
|
) as mock_set_speed_limit:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
NUMBER_DOMAIN,
|
NUMBER_DOMAIN,
|
||||||
|
@ -30,9 +30,8 @@ async def test_switches(hass: HomeAssistant) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.tessie.entity.TessieEntity.run",
|
"homeassistant.components.tessie.switch.start_charging",
|
||||||
return_value=True,
|
) as mock_start_charging:
|
||||||
) as mock_run:
|
|
||||||
# Test Switch On
|
# Test Switch On
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
SWITCH_DOMAIN,
|
SWITCH_DOMAIN,
|
||||||
@ -40,9 +39,10 @@ async def test_switches(hass: HomeAssistant) -> None:
|
|||||||
{ATTR_ENTITY_ID: ["switch.test_charge"]},
|
{ATTR_ENTITY_ID: ["switch.test_charge"]},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
mock_run.assert_called_once()
|
mock_start_charging.assert_called_once()
|
||||||
mock_run.reset_mock()
|
with patch(
|
||||||
|
"homeassistant.components.tessie.switch.stop_charging",
|
||||||
|
) as mock_stop_charging:
|
||||||
# Test Switch Off
|
# Test Switch Off
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
SWITCH_DOMAIN,
|
SWITCH_DOMAIN,
|
||||||
@ -50,4 +50,4 @@ async def test_switches(hass: HomeAssistant) -> None:
|
|||||||
{ATTR_ENTITY_ID: ["switch.test_charge"]},
|
{ATTR_ENTITY_ID: ["switch.test_charge"]},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
mock_run.assert_called_once()
|
mock_stop_charging.assert_called_once()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user