mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Improve SmartThings deprecation (#141939)
* Improve SmartThings deprecation * Improve SmartThings deprecation
This commit is contained in:
parent
faac51d219
commit
4bfc96c02b
@ -7,26 +7,21 @@ from dataclasses import dataclass
|
||||
|
||||
from pysmartthings import Attribute, Capability, Category, SmartThings, Status
|
||||
|
||||
from homeassistant.components.automation import automations_with_entity
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DOMAIN as BINARY_SENSOR_DOMAIN,
|
||||
BinarySensorDeviceClass,
|
||||
BinarySensorEntity,
|
||||
BinarySensorEntityDescription,
|
||||
)
|
||||
from homeassistant.components.script import scripts_with_entity
|
||||
from homeassistant.const import EntityCategory
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
from homeassistant.helpers.issue_registry import (
|
||||
IssueSeverity,
|
||||
async_create_issue,
|
||||
async_delete_issue,
|
||||
)
|
||||
|
||||
from . import FullDevice, SmartThingsConfigEntry
|
||||
from .const import DOMAIN, MAIN
|
||||
from .const import MAIN
|
||||
from .entity import SmartThingsEntity
|
||||
from .util import deprecate_entity
|
||||
|
||||
|
||||
@dataclass(frozen=True, kw_only=True)
|
||||
@ -192,24 +187,64 @@ async def async_setup_entry(
|
||||
) -> None:
|
||||
"""Add binary sensors for a config entry."""
|
||||
entry_data = entry.runtime_data
|
||||
async_add_entities(
|
||||
SmartThingsBinarySensor(
|
||||
entry_data.client, device, description, capability, attribute, component
|
||||
)
|
||||
for device in entry_data.devices.values()
|
||||
for capability, attribute_map in CAPABILITY_TO_SENSORS.items()
|
||||
for attribute, description in attribute_map.items()
|
||||
for component in device.status
|
||||
if capability in device.status[component]
|
||||
and (
|
||||
component == MAIN
|
||||
or (description.exists_fn is not None and description.exists_fn(component))
|
||||
)
|
||||
and (
|
||||
not description.category
|
||||
or get_main_component_category(device) in description.category
|
||||
)
|
||||
)
|
||||
entities = []
|
||||
|
||||
entity_registry = er.async_get(hass)
|
||||
|
||||
for device in entry_data.devices.values(): # pylint: disable=too-many-nested-blocks
|
||||
for capability, attribute_map in CAPABILITY_TO_SENSORS.items():
|
||||
for attribute, description in attribute_map.items():
|
||||
for component in device.status:
|
||||
if (
|
||||
capability in device.status[component]
|
||||
and (
|
||||
component == MAIN
|
||||
or (
|
||||
description.exists_fn is not None
|
||||
and description.exists_fn(component)
|
||||
)
|
||||
)
|
||||
and (
|
||||
not description.category
|
||||
or get_main_component_category(device)
|
||||
in description.category
|
||||
)
|
||||
):
|
||||
if (
|
||||
component == MAIN
|
||||
and (issue := description.deprecated_fn(device.status))
|
||||
is not None
|
||||
):
|
||||
if deprecate_entity(
|
||||
hass,
|
||||
entity_registry,
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
f"{device.device.device_id}_{component}_{capability}_{attribute}_{attribute}",
|
||||
f"deprecated_binary_{issue}",
|
||||
):
|
||||
entities.append(
|
||||
SmartThingsBinarySensor(
|
||||
entry_data.client,
|
||||
device,
|
||||
description,
|
||||
capability,
|
||||
attribute,
|
||||
component,
|
||||
)
|
||||
)
|
||||
continue
|
||||
entities.append(
|
||||
SmartThingsBinarySensor(
|
||||
entry_data.client,
|
||||
device,
|
||||
description,
|
||||
capability,
|
||||
attribute,
|
||||
component,
|
||||
)
|
||||
)
|
||||
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class SmartThingsBinarySensor(SmartThingsEntity, BinarySensorEntity):
|
||||
@ -257,57 +292,3 @@ class SmartThingsBinarySensor(SmartThingsEntity, BinarySensorEntity):
|
||||
self.get_attribute_value(self.capability, self._attribute)
|
||||
== self.entity_description.is_on_key
|
||||
)
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Call when entity is added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
if (issue := self.entity_description.deprecated_fn(self.device.status)) is None:
|
||||
return
|
||||
automations = automations_with_entity(self.hass, self.entity_id)
|
||||
scripts = scripts_with_entity(self.hass, self.entity_id)
|
||||
items = automations + scripts
|
||||
if not items:
|
||||
return
|
||||
|
||||
entity_reg: er.EntityRegistry = er.async_get(self.hass)
|
||||
entity_automations = [
|
||||
automation_entity
|
||||
for automation_id in automations
|
||||
if (automation_entity := entity_reg.async_get(automation_id))
|
||||
]
|
||||
entity_scripts = [
|
||||
script_entity
|
||||
for script_id in scripts
|
||||
if (script_entity := entity_reg.async_get(script_id))
|
||||
]
|
||||
|
||||
items_list = [
|
||||
f"- [{item.original_name}](/config/automation/edit/{item.unique_id})"
|
||||
for item in entity_automations
|
||||
] + [
|
||||
f"- [{item.original_name}](/config/script/edit/{item.unique_id})"
|
||||
for item in entity_scripts
|
||||
]
|
||||
|
||||
async_create_issue(
|
||||
self.hass,
|
||||
DOMAIN,
|
||||
f"deprecated_binary_{issue}_{self.entity_id}",
|
||||
breaks_in_ha_version="2025.10.0",
|
||||
is_fixable=False,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key=f"deprecated_binary_{issue}",
|
||||
translation_placeholders={
|
||||
"entity": self.entity_id,
|
||||
"items": "\n".join(items_list),
|
||||
},
|
||||
)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Call when entity will be removed from hass."""
|
||||
await super().async_will_remove_from_hass()
|
||||
if (issue := self.entity_description.deprecated_fn(self.device.status)) is None:
|
||||
return
|
||||
async_delete_issue(
|
||||
self.hass, DOMAIN, f"deprecated_binary_{issue}_{self.entity_id}"
|
||||
)
|
||||
|
@ -480,12 +480,20 @@
|
||||
},
|
||||
"issues": {
|
||||
"deprecated_binary_valve": {
|
||||
"title": "Deprecated valve binary sensor detected in some automations or scripts",
|
||||
"description": "The valve binary sensor `{entity}` is deprecated and is used in the following automations or scripts:\n{items}\n\nA valve entity with controls is available and should be used going forward. Please use the new valve entity in the above automations or scripts to fix this issue."
|
||||
"title": "Valve binary sensor deprecated",
|
||||
"description": "The valve binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. A valve entity with controls is available and should be used going forward. Please update your dashboards, templates accordingly and disable the entity to fix this issue."
|
||||
},
|
||||
"deprecated_binary_valve_scripts": {
|
||||
"title": "[%key:component::smartthings::issues::deprecated_binary_valve::title%]",
|
||||
"description": "The valve binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. The entity is used in the following automations or scripts:\n{items}\n\nA valve entity with controls is available and should be used going forward. Please use the new valve entity in the above automations or scripts and disable the entity to fix this issue."
|
||||
},
|
||||
"deprecated_binary_fridge_door": {
|
||||
"title": "Deprecated refrigerator door binary sensor detected in some automations or scripts",
|
||||
"description": "The refrigerator door binary sensor `{entity}` is deprecated and is used in the following automations or scripts:\n{items}\n\nSeparate entities for cooler and freezer door are available and should be used going forward. Please use them in the above automations or scripts to fix this issue."
|
||||
"title": "Refrigerator door binary sensor deprecated",
|
||||
"description": "The refrigerator door binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. Separate entities for cooler and freezer door are available and should be used going forward. Please update your dashboards, templates accordingly and disable the entity to fix this issue."
|
||||
},
|
||||
"deprecated_binary_fridge_door_scripts": {
|
||||
"title": "[%key:component::smartthings::issues::deprecated_binary_fridge_door::title%]",
|
||||
"description": "The refrigerator door binary sensor {entity_name} (`{entity_id}`) is deprecated and will be removed in the future. The entity is used in the following automations or scripts:\n{items}\n\nSeparate entities for cooler and freezer door are available and should be used going forward. Please use them in the above automations or scripts and disable the entity to fix this issue."
|
||||
},
|
||||
"deprecated_switch_appliance": {
|
||||
"title": "Deprecated switch detected in some automations or scripts",
|
||||
|
83
homeassistant/components/smartthings/util.py
Normal file
83
homeassistant/components/smartthings/util.py
Normal file
@ -0,0 +1,83 @@
|
||||
"""Utility functions for SmartThings integration."""
|
||||
|
||||
from homeassistant.components.automation import automations_with_entity
|
||||
from homeassistant.components.script import scripts_with_entity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.issue_registry import (
|
||||
IssueSeverity,
|
||||
async_create_issue,
|
||||
async_delete_issue,
|
||||
)
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
def deprecate_entity(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
platform_domain: str,
|
||||
entity_unique_id: str,
|
||||
issue_string: str,
|
||||
) -> bool:
|
||||
"""Create an issue for deprecated entities."""
|
||||
if entity_id := entity_registry.async_get_entity_id(
|
||||
platform_domain, DOMAIN, entity_unique_id
|
||||
):
|
||||
entity_entry = entity_registry.async_get(entity_id)
|
||||
if not entity_entry:
|
||||
return False
|
||||
if entity_entry.disabled:
|
||||
entity_registry.async_remove(entity_id)
|
||||
async_delete_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
f"{issue_string}_{entity_id}",
|
||||
)
|
||||
return False
|
||||
translation_key = issue_string
|
||||
placeholders = {
|
||||
"entity_id": entity_id,
|
||||
"entity_name": entity_entry.name or entity_entry.original_name or "Unknown",
|
||||
}
|
||||
if items := get_automations_and_scripts_using_entity(hass, entity_id):
|
||||
translation_key = f"{translation_key}_scripts"
|
||||
placeholders.update(
|
||||
{
|
||||
"items": "\n".join(items),
|
||||
}
|
||||
)
|
||||
async_create_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
f"{issue_string}_{entity_id}",
|
||||
breaks_in_ha_version="2025.10.0",
|
||||
is_fixable=False,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key=translation_key,
|
||||
translation_placeholders=placeholders,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_automations_and_scripts_using_entity(
|
||||
hass: HomeAssistant,
|
||||
entity_id: str,
|
||||
) -> list[str]:
|
||||
"""Get automations and scripts using an entity."""
|
||||
automations = automations_with_entity(hass, entity_id)
|
||||
scripts = scripts_with_entity(hass, entity_id)
|
||||
if not automations and not scripts:
|
||||
return []
|
||||
|
||||
entity_reg = er.async_get(hass)
|
||||
return [
|
||||
f"- [{item.original_name}](/config/{integration}/edit/{item.unique_id})"
|
||||
for integration, entities in (
|
||||
("automation", automations),
|
||||
("script", scripts),
|
||||
)
|
||||
for entity_id in entities
|
||||
if (item := entity_reg.async_get(entity_id))
|
||||
]
|
@ -713,54 +713,6 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_000001][binary_sensor.refrigerator_door-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.refrigerator_door',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.DOOR: 'door'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Door',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '7db87911-7dce-1cf2-7119-b953432a2f09_main_contactSensor_contact_contact',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_000001][binary_sensor.refrigerator_door-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'door',
|
||||
'friendly_name': 'Refrigerator Door',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.refrigerator_door',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_000001][binary_sensor.refrigerator_freezer_door-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@ -857,54 +809,6 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_01011][binary_sensor.frigo_door-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.frigo_door',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.DOOR: 'door'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Door',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '5758b2ec-563e-f39b-ec39-208e54aabf60_main_contactSensor_contact_contact',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_01011][binary_sensor.frigo_door-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'door',
|
||||
'friendly_name': 'Frigo Door',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.frigo_door',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[da_ref_normal_01011][binary_sensor.frigo_freezer_door-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@ -2139,54 +2043,6 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_valve][binary_sensor.volvo_valve-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.volvo_valve',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <BinarySensorDeviceClass.OPENING: 'opening'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Valve',
|
||||
'platform': 'smartthings',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'valve',
|
||||
'unique_id': '612ab3c2-3bb0-48f7-b2c0-15b169cb2fc3_main_valve_valve_valve',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_valve][binary_sensor.volvo_valve-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'opening',
|
||||
'friendly_name': 'volvo Valve',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.volvo_valve',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[virtual_water_sensor][binary_sensor.asd_moisture-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
@ -8,8 +8,9 @@ from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components import automation, script
|
||||
from homeassistant.components.automation import automations_with_entity
|
||||
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
|
||||
from homeassistant.components.script import scripts_with_entity
|
||||
from homeassistant.components.smartthings import DOMAIN
|
||||
from homeassistant.components.smartthings import DOMAIN, MAIN
|
||||
from homeassistant.const import STATE_OFF, STATE_ON, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
@ -44,7 +45,7 @@ async def test_state_update(
|
||||
"""Test state update."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert hass.states.get("binary_sensor.refrigerator_door").state == STATE_OFF
|
||||
assert hass.states.get("binary_sensor.refrigerator_cooler_door").state == STATE_OFF
|
||||
|
||||
await trigger_update(
|
||||
hass,
|
||||
@ -53,35 +54,60 @@ async def test_state_update(
|
||||
Capability.CONTACT_SENSOR,
|
||||
Attribute.CONTACT,
|
||||
"open",
|
||||
component="cooler",
|
||||
)
|
||||
|
||||
assert hass.states.get("binary_sensor.refrigerator_door").state == STATE_ON
|
||||
assert hass.states.get("binary_sensor.refrigerator_cooler_door").state == STATE_ON
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
@pytest.mark.parametrize(
|
||||
("device_fixture", "issue_string", "entity_id"),
|
||||
("device_fixture", "unique_id", "suggested_object_id", "issue_string", "entity_id"),
|
||||
[
|
||||
("virtual_valve", "valve", "binary_sensor.volvo_valve"),
|
||||
("da_ref_normal_000001", "fridge_door", "binary_sensor.refrigerator_door"),
|
||||
(
|
||||
"virtual_valve",
|
||||
f"612ab3c2-3bb0-48f7-b2c0-15b169cb2fc3_{MAIN}_{Capability.VALVE}_{Attribute.VALVE}_{Attribute.VALVE}",
|
||||
"volvo_valve",
|
||||
"valve",
|
||||
"binary_sensor.volvo_valve",
|
||||
),
|
||||
(
|
||||
"da_ref_normal_000001",
|
||||
f"7db87911-7dce-1cf2-7119-b953432a2f09_{MAIN}_{Capability.CONTACT_SENSOR}_{Attribute.CONTACT}_{Attribute.CONTACT}",
|
||||
"refrigerator_door",
|
||||
"fridge_door",
|
||||
"binary_sensor.refrigerator_door",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_create_issue(
|
||||
async def test_create_issue_with_items(
|
||||
hass: HomeAssistant,
|
||||
devices: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
unique_id: str,
|
||||
suggested_object_id: str,
|
||||
issue_string: str,
|
||||
entity_id: str,
|
||||
) -> None:
|
||||
"""Test we create an issue when an automation or script is using a deprecated entity."""
|
||||
issue_id = f"deprecated_binary_{issue_string}_{entity_id}"
|
||||
|
||||
entity_entry = entity_registry.async_get_or_create(
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
unique_id,
|
||||
suggested_object_id=suggested_object_id,
|
||||
original_name=suggested_object_id,
|
||||
)
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: {
|
||||
"id": "test",
|
||||
"alias": "test",
|
||||
"trigger": {"platform": "state", "entity_id": entity_id},
|
||||
"action": {
|
||||
@ -113,13 +139,95 @@ async def test_create_issue(
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
assert automations_with_entity(hass, entity_id)[0] == "automation.test"
|
||||
assert scripts_with_entity(hass, entity_id)[0] == "script.test"
|
||||
|
||||
assert len(issue_registry.issues) == 1
|
||||
assert issue_registry.async_get_issue(DOMAIN, issue_id)
|
||||
issue = issue_registry.async_get_issue(DOMAIN, issue_id)
|
||||
assert issue is not None
|
||||
assert issue.translation_key == f"deprecated_binary_{issue_string}_scripts"
|
||||
assert issue.translation_placeholders == {
|
||||
"entity_id": entity_id,
|
||||
"entity_name": suggested_object_id,
|
||||
"items": "- [test](/config/automation/edit/test)\n- [test](/config/script/edit/test)",
|
||||
}
|
||||
|
||||
await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||
entity_registry.async_update_entity(
|
||||
entity_entry.entity_id,
|
||||
disabled_by=er.RegistryEntryDisabler.USER,
|
||||
)
|
||||
|
||||
await hass.config_entries.async_reload(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Assert the issue is no longer present
|
||||
assert not issue_registry.async_get_issue(DOMAIN, issue_id)
|
||||
assert len(issue_registry.issues) == 0
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
@pytest.mark.parametrize(
|
||||
("device_fixture", "unique_id", "suggested_object_id", "issue_string", "entity_id"),
|
||||
[
|
||||
(
|
||||
"virtual_valve",
|
||||
f"612ab3c2-3bb0-48f7-b2c0-15b169cb2fc3_{MAIN}_{Capability.VALVE}_{Attribute.VALVE}_{Attribute.VALVE}",
|
||||
"volvo_valve",
|
||||
"valve",
|
||||
"binary_sensor.volvo_valve",
|
||||
),
|
||||
(
|
||||
"da_ref_normal_000001",
|
||||
f"7db87911-7dce-1cf2-7119-b953432a2f09_{MAIN}_{Capability.CONTACT_SENSOR}_{Attribute.CONTACT}_{Attribute.CONTACT}",
|
||||
"refrigerator_door",
|
||||
"fridge_door",
|
||||
"binary_sensor.refrigerator_door",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_create_issue(
|
||||
hass: HomeAssistant,
|
||||
devices: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
unique_id: str,
|
||||
suggested_object_id: str,
|
||||
issue_string: str,
|
||||
entity_id: str,
|
||||
) -> None:
|
||||
"""Test we create an issue when an automation or script is using a deprecated entity."""
|
||||
issue_id = f"deprecated_binary_{issue_string}_{entity_id}"
|
||||
|
||||
entity_entry = entity_registry.async_get_or_create(
|
||||
BINARY_SENSOR_DOMAIN,
|
||||
DOMAIN,
|
||||
unique_id,
|
||||
suggested_object_id=suggested_object_id,
|
||||
original_name=suggested_object_id,
|
||||
)
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
assert len(issue_registry.issues) == 1
|
||||
issue = issue_registry.async_get_issue(DOMAIN, issue_id)
|
||||
assert issue is not None
|
||||
assert issue.translation_key == f"deprecated_binary_{issue_string}"
|
||||
assert issue.translation_placeholders == {
|
||||
"entity_id": entity_id,
|
||||
"entity_name": suggested_object_id,
|
||||
}
|
||||
|
||||
entity_registry.async_update_entity(
|
||||
entity_entry.entity_id,
|
||||
disabled_by=er.RegistryEntryDisabler.USER,
|
||||
)
|
||||
|
||||
await hass.config_entries.async_reload(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Assert the issue is no longer present
|
||||
|
Loading…
x
Reference in New Issue
Block a user