Deprecate Home Connect program switches (#131641)
parent
4399d09820
commit
c06bc53724
|
@ -90,6 +90,10 @@
|
|||
"deprecated_binary_common_door_sensor": {
|
||||
"title": "Deprecated binary door sensor detected in some automations or scripts",
|
||||
"description": "The binary door sensor `{entity}`, which is deprecated, is used in the following automations or scripts:\n{items}\n\nA sensor entity with additional possible states is available and should be used going forward; Please use it on the above automations or scripts to fix this issue."
|
||||
},
|
||||
"deprecated_program_switch": {
|
||||
"title": "Deprecated program switch detected in some automations or scripts",
|
||||
"description": "Program switch are deprecated and {entity_id} is used in the following automations or scripts:\n{items}\n\nYou can use active program select entity to run the program without any additional option and get the current running program on the above automations or scripts to fix this issue."
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
|
|
|
@ -6,10 +6,18 @@ from typing import Any
|
|||
|
||||
from homeconnect.api import HomeConnectError
|
||||
|
||||
from homeassistant.components.automation import automations_with_entity
|
||||
from homeassistant.components.script import scripts_with_entity
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.issue_registry import (
|
||||
IssueSeverity,
|
||||
async_create_issue,
|
||||
async_delete_issue,
|
||||
)
|
||||
|
||||
from . import HomeConnectConfigEntry, get_dict_from_home_connect_error
|
||||
from .const import (
|
||||
|
@ -201,6 +209,55 @@ class HomeConnectProgramSwitch(HomeConnectEntity, SwitchEntity):
|
|||
self._attr_has_entity_name = False
|
||||
self.program_name = program_name
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Call when entity is added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
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_program_switch_{self.entity_id}",
|
||||
breaks_in_ha_version="2025.6.0",
|
||||
is_fixable=False,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_program_switch",
|
||||
translation_placeholders={
|
||||
"entity_id": 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."""
|
||||
async_delete_issue(
|
||||
self.hass, DOMAIN, f"deprecated_program_switch_{self.entity_id}"
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Start the program."""
|
||||
_LOGGER.debug("Tried to turn on program %s", self.program_name)
|
||||
|
|
|
@ -6,6 +6,8 @@ from unittest.mock import MagicMock, Mock
|
|||
from homeconnect.api import HomeConnectAppliance, HomeConnectError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components import automation, script
|
||||
from homeassistant.components.automation import automations_with_entity
|
||||
from homeassistant.components.home_connect.const import (
|
||||
ATTR_ALLOWED_VALUES,
|
||||
ATTR_CONSTRAINTS,
|
||||
|
@ -16,8 +18,10 @@ from homeassistant.components.home_connect.const import (
|
|||
BSH_POWER_ON,
|
||||
BSH_POWER_STANDBY,
|
||||
BSH_POWER_STATE,
|
||||
DOMAIN,
|
||||
REFRIGERATION_SUPERMODEFREEZER,
|
||||
)
|
||||
from homeassistant.components.script import scripts_with_entity
|
||||
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
|
@ -30,6 +34,8 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.issue_registry as ir
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .conftest import get_all_appliances
|
||||
|
||||
|
@ -506,3 +512,72 @@ async def test_power_switch_service_validation_errors(
|
|||
await hass.services.async_call(
|
||||
SWITCH_DOMAIN, service, {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
@pytest.mark.usefixtures("bypass_throttle")
|
||||
async def test_create_issue(
|
||||
hass: HomeAssistant,
|
||||
appliance: Mock,
|
||||
config_entry: MockConfigEntry,
|
||||
integration_setup: Callable[[], Awaitable[bool]],
|
||||
setup_credentials: None,
|
||||
get_appliances: MagicMock,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test we create an issue when an automation or script is using a deprecated entity."""
|
||||
entity_id = "switch.washer_program_mix"
|
||||
appliance.status.update(SETTINGS_STATUS)
|
||||
appliance.get_programs_available.return_value = [PROGRAM]
|
||||
get_appliances.return_value = [appliance]
|
||||
issue_id = f"deprecated_program_switch_{entity_id}"
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: {
|
||||
"alias": "test",
|
||||
"trigger": {"platform": "state", "entity_id": entity_id},
|
||||
"action": {
|
||||
"action": "automation.turn_on",
|
||||
"target": {
|
||||
"entity_id": "automation.test",
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
script.DOMAIN,
|
||||
{
|
||||
script.DOMAIN: {
|
||||
"test": {
|
||||
"sequence": [
|
||||
{
|
||||
"action": "switch.turn_on",
|
||||
"entity_id": entity_id,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||
assert await integration_setup()
|
||||
assert config_entry.state == ConfigEntryState.LOADED
|
||||
|
||||
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)
|
||||
|
||||
await hass.config_entries.async_unload(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
|
||||
|
|
Loading…
Reference in New Issue