Deprecate speed limit lock in Tessie (#113848)
This commit is contained in:
parent
18132916fa
commit
0e0b543dec
3 changed files with 145 additions and 10 deletions
|
@ -12,10 +12,14 @@ from tessie_api import (
|
||||||
unlock,
|
unlock,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from homeassistant.components.automation import automations_with_entity
|
||||||
from homeassistant.components.lock import ATTR_CODE, LockEntity
|
from homeassistant.components.lock import ATTR_CODE, LockEntity
|
||||||
|
from homeassistant.components.script import scripts_with_entity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ServiceValidationError
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
|
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .const import DOMAIN, TessieChargeCableLockStates
|
from .const import DOMAIN, TessieChargeCableLockStates
|
||||||
|
@ -29,11 +33,46 @@ async def async_setup_entry(
|
||||||
"""Set up the Tessie sensor platform from a config entry."""
|
"""Set up the Tessie sensor platform from a config entry."""
|
||||||
data = hass.data[DOMAIN][entry.entry_id]
|
data = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
|
||||||
async_add_entities(
|
entities = [
|
||||||
klass(vehicle.state_coordinator)
|
klass(vehicle.state_coordinator)
|
||||||
for klass in (TessieLockEntity, TessieCableLockEntity, TessieSpeedLimitEntity)
|
for klass in (TessieLockEntity, TessieCableLockEntity)
|
||||||
for vehicle in data
|
for vehicle in data
|
||||||
)
|
]
|
||||||
|
|
||||||
|
ent_reg = er.async_get(hass)
|
||||||
|
|
||||||
|
for vehicle in data:
|
||||||
|
entity_id = ent_reg.async_get_entity_id(
|
||||||
|
Platform.LOCK,
|
||||||
|
DOMAIN,
|
||||||
|
f"{vehicle.state_coordinator.vin}-vehicle_state_speed_limit_mode_active",
|
||||||
|
)
|
||||||
|
if entity_id:
|
||||||
|
entity_entry = ent_reg.async_get(entity_id)
|
||||||
|
assert entity_entry
|
||||||
|
if entity_entry.disabled:
|
||||||
|
ent_reg.async_remove(entity_id)
|
||||||
|
else:
|
||||||
|
entities.append(TessieSpeedLimitEntity(vehicle.state_coordinator))
|
||||||
|
|
||||||
|
entity_automations = automations_with_entity(hass, entity_id)
|
||||||
|
entity_scripts = scripts_with_entity(hass, entity_id)
|
||||||
|
for item in entity_automations + entity_scripts:
|
||||||
|
ir.async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
f"deprecated_speed_limit_{entity_id}_{item}",
|
||||||
|
breaks_in_ha_version="2024.11.0",
|
||||||
|
is_fixable=True,
|
||||||
|
is_persistent=False,
|
||||||
|
severity=ir.IssueSeverity.WARNING,
|
||||||
|
translation_key="deprecated_speed_limit_entity",
|
||||||
|
translation_placeholders={
|
||||||
|
"entity": entity_id,
|
||||||
|
"info": item,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
class TessieLockEntity(TessieEntity, LockEntity):
|
class TessieLockEntity(TessieEntity, LockEntity):
|
||||||
|
@ -81,6 +120,16 @@ class TessieSpeedLimitEntity(TessieEntity, LockEntity):
|
||||||
|
|
||||||
async def async_lock(self, **kwargs: Any) -> None:
|
async def async_lock(self, **kwargs: Any) -> None:
|
||||||
"""Enable speed limit with pin."""
|
"""Enable speed limit with pin."""
|
||||||
|
ir.async_create_issue(
|
||||||
|
self.coordinator.hass,
|
||||||
|
DOMAIN,
|
||||||
|
"deprecated_speed_limit_locked",
|
||||||
|
breaks_in_ha_version="2024.11.0",
|
||||||
|
is_fixable=True,
|
||||||
|
is_persistent=False,
|
||||||
|
severity=ir.IssueSeverity.WARNING,
|
||||||
|
translation_key="deprecated_speed_limit_locked",
|
||||||
|
)
|
||||||
code: str | None = kwargs.get(ATTR_CODE)
|
code: str | None = kwargs.get(ATTR_CODE)
|
||||||
if code:
|
if code:
|
||||||
await self.run(enable_speed_limit, pin=code)
|
await self.run(enable_speed_limit, pin=code)
|
||||||
|
@ -88,6 +137,16 @@ class TessieSpeedLimitEntity(TessieEntity, LockEntity):
|
||||||
|
|
||||||
async def async_unlock(self, **kwargs: Any) -> None:
|
async def async_unlock(self, **kwargs: Any) -> None:
|
||||||
"""Disable speed limit with pin."""
|
"""Disable speed limit with pin."""
|
||||||
|
ir.async_create_issue(
|
||||||
|
self.coordinator.hass,
|
||||||
|
DOMAIN,
|
||||||
|
"deprecated_speed_limit_unlocked",
|
||||||
|
breaks_in_ha_version="2024.11.0",
|
||||||
|
is_fixable=True,
|
||||||
|
is_persistent=False,
|
||||||
|
severity=ir.IssueSeverity.WARNING,
|
||||||
|
translation_key="deprecated_speed_limit_unlocked",
|
||||||
|
)
|
||||||
code: str | None = kwargs.get(ATTR_CODE)
|
code: str | None = kwargs.get(ATTR_CODE)
|
||||||
if code:
|
if code:
|
||||||
await self.run(disable_speed_limit, pin=code)
|
await self.run(disable_speed_limit, pin=code)
|
||||||
|
|
|
@ -410,5 +410,40 @@
|
||||||
"no_cable": {
|
"no_cable": {
|
||||||
"message": "Insert cable to lock"
|
"message": "Insert cable to lock"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"issues": {
|
||||||
|
"deprecated_speed_limit_entity": {
|
||||||
|
"title": "Detected Tessie speed limit lock entity usage",
|
||||||
|
"fix_flow": {
|
||||||
|
"step": {
|
||||||
|
"confirm": {
|
||||||
|
"title": "[%key:component::tessie::issues::deprecated_speed_limit_entity::title%]",
|
||||||
|
"description": "The Tessie integration's speed limit lock entity has been deprecated and will be remove in 2024.11.0.\nHome Assistant detected that entity `{entity}` is being used in `{info}`\n\nYou should remove the speed limit lock entity from `{info}` then click submit to fix this issue."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated_speed_limit_locked": {
|
||||||
|
"title": "Detected Tessie speed limit lock entity locked",
|
||||||
|
"fix_flow": {
|
||||||
|
"step": {
|
||||||
|
"confirm": {
|
||||||
|
"title": "[%key:component::tessie::issues::deprecated_speed_limit_locked::title%]",
|
||||||
|
"description": "The Tessie integration's speed limit lock entity has been deprecated and will be remove in 2024.11.0.\n\nPlease remove this entity from any automation or script, disable the entity then click submit to fix this issue."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated_speed_limit_unlocked": {
|
||||||
|
"title": "Detected Tessie speed limit lock entity unlocked",
|
||||||
|
"fix_flow": {
|
||||||
|
"step": {
|
||||||
|
"confirm": {
|
||||||
|
"title": "[%key:component::tessie::issues::deprecated_speed_limit_unlocked::title%]",
|
||||||
|
"description": "The Tessie integration's speed limit lock entity has been deprecated and will be remove in 2024.11.0.\n\nPlease remove this entity from any automation or script, disable the entity then click submit to fix this issue."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,9 @@ from homeassistant.const import ATTR_ENTITY_ID, STATE_LOCKED, STATE_UNLOCKED, Pl
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ServiceValidationError
|
from homeassistant.exceptions import ServiceValidationError
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
from homeassistant.helpers.issue_registry import async_get as async_get_issue_registry
|
||||||
|
|
||||||
from .common import assert_entities, setup_platform
|
from .common import DOMAIN, assert_entities, setup_platform
|
||||||
|
|
||||||
|
|
||||||
async def test_locks(
|
async def test_locks(
|
||||||
|
@ -24,6 +25,17 @@ async def test_locks(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Tests that the lock entity is correct."""
|
"""Tests that the lock entity is correct."""
|
||||||
|
|
||||||
|
# Create the deprecated speed limit lock entity
|
||||||
|
entity_registry.async_get_or_create(
|
||||||
|
LOCK_DOMAIN,
|
||||||
|
DOMAIN,
|
||||||
|
"VINVINVIN-vehicle_state_speed_limit_mode_active",
|
||||||
|
original_name="Charge cable lock",
|
||||||
|
has_entity_name=True,
|
||||||
|
translation_key="vehicle_state_speed_limit_mode_active",
|
||||||
|
disabled_by=er.RegistryEntryDisabler.INTEGRATION,
|
||||||
|
)
|
||||||
|
|
||||||
entry = await setup_platform(hass, [Platform.LOCK])
|
entry = await setup_platform(hass, [Platform.LOCK])
|
||||||
|
|
||||||
assert_entities(hass, entry.entry_id, entity_registry, snapshot)
|
assert_entities(hass, entry.entry_id, entity_registry, snapshot)
|
||||||
|
@ -72,19 +84,47 @@ async def test_locks(
|
||||||
assert hass.states.get(entity_id).state == STATE_UNLOCKED
|
assert hass.states.get(entity_id).state == STATE_UNLOCKED
|
||||||
mock_run.assert_called_once()
|
mock_run.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
async def test_speed_limit_lock(
|
||||||
|
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
||||||
|
) -> None:
|
||||||
|
"""Tests that the deprecated speed limit lock entity is correct."""
|
||||||
|
|
||||||
|
issue_registry = async_get_issue_registry(hass)
|
||||||
|
|
||||||
|
# Create the deprecated speed limit lock entity
|
||||||
|
entity = entity_registry.async_get_or_create(
|
||||||
|
LOCK_DOMAIN,
|
||||||
|
DOMAIN,
|
||||||
|
"VINVINVIN-vehicle_state_speed_limit_mode_active",
|
||||||
|
original_name="Charge cable lock",
|
||||||
|
has_entity_name=True,
|
||||||
|
translation_key="vehicle_state_speed_limit_mode_active",
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.tessie.lock.automations_with_entity",
|
||||||
|
return_value=["item"],
|
||||||
|
):
|
||||||
|
await setup_platform(hass, [Platform.LOCK])
|
||||||
|
assert issue_registry.async_get_issue(
|
||||||
|
DOMAIN, f"deprecated_speed_limit_{entity.entity_id}_item"
|
||||||
|
)
|
||||||
|
|
||||||
# Test lock set value functions
|
# Test lock set value functions
|
||||||
entity_id = "lock.test_speed_limit"
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.tessie.lock.enable_speed_limit"
|
"homeassistant.components.tessie.lock.enable_speed_limit"
|
||||||
) as mock_enable_speed_limit:
|
) as mock_enable_speed_limit:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
LOCK_DOMAIN,
|
LOCK_DOMAIN,
|
||||||
SERVICE_LOCK,
|
SERVICE_LOCK,
|
||||||
{ATTR_ENTITY_ID: [entity_id], ATTR_CODE: "1234"},
|
{ATTR_ENTITY_ID: [entity.entity_id], ATTR_CODE: "1234"},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
assert hass.states.get(entity_id).state == STATE_LOCKED
|
assert hass.states.get(entity.entity_id).state == STATE_LOCKED
|
||||||
mock_enable_speed_limit.assert_called_once()
|
mock_enable_speed_limit.assert_called_once()
|
||||||
|
# Assert issue has been raised in the issue register
|
||||||
|
assert issue_registry.async_get_issue(DOMAIN, "deprecated_speed_limit_locked")
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.tessie.lock.disable_speed_limit"
|
"homeassistant.components.tessie.lock.disable_speed_limit"
|
||||||
|
@ -92,16 +132,17 @@ async def test_locks(
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
LOCK_DOMAIN,
|
LOCK_DOMAIN,
|
||||||
SERVICE_UNLOCK,
|
SERVICE_UNLOCK,
|
||||||
{ATTR_ENTITY_ID: [entity_id], ATTR_CODE: "1234"},
|
{ATTR_ENTITY_ID: [entity.entity_id], ATTR_CODE: "1234"},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
assert hass.states.get(entity_id).state == STATE_UNLOCKED
|
assert hass.states.get(entity.entity_id).state == STATE_UNLOCKED
|
||||||
mock_disable_speed_limit.assert_called_once()
|
mock_disable_speed_limit.assert_called_once()
|
||||||
|
assert issue_registry.async_get_issue(DOMAIN, "deprecated_speed_limit_unlocked")
|
||||||
|
|
||||||
with pytest.raises(ServiceValidationError):
|
with pytest.raises(ServiceValidationError):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
LOCK_DOMAIN,
|
LOCK_DOMAIN,
|
||||||
SERVICE_UNLOCK,
|
SERVICE_UNLOCK,
|
||||||
{ATTR_ENTITY_ID: [entity_id], ATTR_CODE: "abc"},
|
{ATTR_ENTITY_ID: [entity.entity_id], ATTR_CODE: "abc"},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue