Create battery_level deprecation repair for template vacuum platform (#149987)

Co-authored-by: Norbert Rittel <norbert@rittel.de>
This commit is contained in:
Petro31
2025-08-04 15:54:50 -04:00
committed by GitHub
parent 1fbce01e26
commit 4d53450cbf
3 changed files with 84 additions and 2 deletions

View File

@@ -440,6 +440,12 @@
} }
} }
}, },
"issues": {
"deprecated_battery_level": {
"title": "Deprecated battery level option in {entity_name}",
"description": "The template vacuum options `battery_level` and `battery_level_template` are being removed in 2026.8.\n\nPlease remove the `battery_level` or `battery_level_template` option from the YAML configuration for {entity_id} ({entity_name})."
}
},
"options": { "options": {
"step": { "step": {
"alarm_control_panel": { "alarm_control_panel": {

View File

@@ -34,11 +34,16 @@ from homeassistant.const import (
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
from homeassistant.helpers import config_validation as cv, template from homeassistant.helpers import (
config_validation as cv,
issue_registry as ir,
template,
)
from homeassistant.helpers.entity_platform import ( from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback, AddConfigEntryEntitiesCallback,
AddEntitiesCallback, AddEntitiesCallback,
) )
from homeassistant.helpers.issue_registry import IssueSeverity
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from .const import DOMAIN from .const import DOMAIN
@@ -188,6 +193,26 @@ def async_create_preview_vacuum(
) )
def create_issue(
hass: HomeAssistant, supported_features: int, name: str, entity_id: str
) -> None:
"""Create the battery_level issue."""
if supported_features & VacuumEntityFeature.BATTERY:
key = "deprecated_battery_level"
ir.async_create_issue(
hass,
DOMAIN,
f"{key}_{entity_id}",
is_fixable=False,
severity=IssueSeverity.WARNING,
translation_key=key,
translation_placeholders={
"entity_name": name,
"entity_id": entity_id,
},
)
class AbstractTemplateVacuum(AbstractTemplateEntity, StateVacuumEntity): class AbstractTemplateVacuum(AbstractTemplateEntity, StateVacuumEntity):
"""Representation of a template vacuum features.""" """Representation of a template vacuum features."""
@@ -369,6 +394,16 @@ class TemplateStateVacuumEntity(TemplateEntity, AbstractTemplateVacuum):
self.add_script(action_id, action_config, name, DOMAIN) self.add_script(action_id, action_config, name, DOMAIN)
self._attr_supported_features |= supported_feature self._attr_supported_features |= supported_feature
async def async_added_to_hass(self) -> None:
"""Run when entity about to be added to hass."""
await super().async_added_to_hass()
create_issue(
self.hass,
self._attr_supported_features,
self._attr_name or DEFAULT_NAME,
self.entity_id,
)
@callback @callback
def _async_setup_templates(self) -> None: def _async_setup_templates(self) -> None:
"""Set up templates.""" """Set up templates."""
@@ -434,6 +469,16 @@ class TriggerVacuumEntity(TriggerEntity, AbstractTemplateVacuum):
self._to_render_simple.append(key) self._to_render_simple.append(key)
self._parse_result.add(key) self._parse_result.add(key)
async def async_added_to_hass(self) -> None:
"""Run when entity about to be added to hass."""
await super().async_added_to_hass()
create_issue(
self.hass,
self._attr_supported_features,
self._attr_name or DEFAULT_NAME,
self.entity_id,
)
@callback @callback
def _handle_coordinator_update(self) -> None: def _handle_coordinator_update(self) -> None:
"""Handle update of the data.""" """Handle update of the data."""

View File

@@ -15,7 +15,7 @@ from homeassistant.components.vacuum import (
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er, issue_registry as ir
from homeassistant.helpers.entity_component import async_update_entity from homeassistant.helpers.entity_component import async_update_entity
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@@ -589,6 +589,37 @@ async def test_battery_level_template(
_verify(hass, STATE_UNKNOWN, expected) _verify(hass, STATE_UNKNOWN, expected)
@pytest.mark.parametrize(
("count", "state_template", "extra_config", "attribute_template"),
[(1, "{{ states('sensor.test_state') }}", {}, "{{ 50 }}")],
)
@pytest.mark.parametrize(
("style", "attribute"),
[
(ConfigurationStyle.LEGACY, "battery_level_template"),
(ConfigurationStyle.MODERN, "battery_level"),
(ConfigurationStyle.TRIGGER, "battery_level"),
],
)
@pytest.mark.usefixtures("setup_single_attribute_state_vacuum")
async def test_battery_level_template_repair(
hass: HomeAssistant, issue_registry: ir.IssueRegistry
) -> None:
"""Test battery_level template raises issue."""
# Ensure trigger entity templates are rendered
hass.states.async_set(TEST_STATE_SENSOR, VacuumActivity.DOCKED)
await hass.async_block_till_done()
assert len(issue_registry.issues) == 1
issue = issue_registry.async_get_issue(
"template", f"deprecated_battery_level_{TEST_ENTITY_ID}"
)
assert issue.domain == "template"
assert issue.severity == ir.IssueSeverity.WARNING
assert issue.translation_placeholders["entity_name"] == TEST_OBJECT_ID
assert issue.translation_placeholders["entity_id"] == TEST_ENTITY_ID
@pytest.mark.parametrize( @pytest.mark.parametrize(
("count", "state_template", "extra_config"), ("count", "state_template", "extra_config"),
[ [