Deprecate MQTT vacuum battery feature and remove it as default feature

This commit is contained in:
jbouwh
2025-08-03 07:55:56 +00:00
parent 08f7b708a4
commit 624182b2a4
3 changed files with 97 additions and 12 deletions

View File

@@ -1,5 +1,9 @@
{
"issues": {
"deprecated_vacuum_battery_feature": {
"title": "Deprecated battery feature used",
"description": "Vacuum entity {entity_id} implements the battery feature which is deprecated. This will stop working in Home Assistant 2026.3. Implement a separate entity for the battery status instead. To fix the issue `battery` feature should be removed from the configured supported features, and Home Assistant should be restarted to fix this issue."
},
"invalid_platform_config": {
"title": "Invalid config found for MQTT {domain} item",
"description": "Home Assistant detected an invalid config for a manually configured item.\n\nPlatform domain: **{domain}**\nConfiguration file: **{config_file}**\nNear line: **{line}**\nConfiguration found:\n```yaml\n{config}\n```\nError: **{error}**.\n\nMake sure the configuration is valid and [reload](/developer-tools/yaml) the manually configured MQTT items or restart Home Assistant to fix this issue."

View File

@@ -17,7 +17,7 @@ from homeassistant.components.vacuum import (
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_SUPPORTED_FEATURES, CONF_NAME
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import config_validation as cv, issue_registry as ir
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.json import json_dumps
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, VolSchemaType
@@ -25,11 +25,11 @@ from homeassistant.util.json import json_loads_object
from . import subscription
from .config import MQTT_BASE_SCHEMA
from .const import CONF_COMMAND_TOPIC, CONF_RETAIN, CONF_STATE_TOPIC
from .entity import MqttEntity, async_setup_entity_entry_helper
from .const import CONF_COMMAND_TOPIC, CONF_RETAIN, CONF_STATE_TOPIC, DOMAIN
from .entity import IssueSeverity, MqttEntity, async_setup_entity_entry_helper
from .models import ReceiveMessage
from .schemas import MQTT_ENTITY_COMMON_SCHEMA
from .util import valid_publish_topic
from .util import learn_more_url, valid_publish_topic
PARALLEL_UPDATES = 0
@@ -84,6 +84,8 @@ SERVICE_TO_STRING: dict[VacuumEntityFeature, str] = {
VacuumEntityFeature.STOP: "stop",
VacuumEntityFeature.RETURN_HOME: "return_home",
VacuumEntityFeature.FAN_SPEED: "fan_speed",
# Use of the battery feature was deprecated in HA Core 2025.9
# and will removed with HA Core 2026.3
VacuumEntityFeature.BATTERY: "battery",
VacuumEntityFeature.STATUS: "status",
VacuumEntityFeature.SEND_COMMAND: "send_command",
@@ -96,7 +98,6 @@ DEFAULT_SERVICES = (
VacuumEntityFeature.START
| VacuumEntityFeature.STOP
| VacuumEntityFeature.RETURN_HOME
| VacuumEntityFeature.BATTERY
| VacuumEntityFeature.CLEAN_SPOT
)
ALL_SERVICES = (
@@ -106,6 +107,7 @@ ALL_SERVICES = (
| VacuumEntityFeature.FAN_SPEED
| VacuumEntityFeature.SEND_COMMAND
)
DEPRECATED_SERVICES = VacuumEntityFeature.BATTERY
def services_to_strings(
@@ -251,10 +253,35 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
)
}
async def mqtt_async_added_to_hass(self) -> None:
"""Check for use of deprecated battery features."""
if self.supported_features & VacuumEntityFeature.BATTERY:
ir.async_create_issue(
self.hass,
DOMAIN,
f"deprecated_vacuum_battery_feature_{self.entity_id}",
issue_domain=vacuum.DOMAIN,
breaks_in_ha_version="2026.3",
is_fixable=False,
severity=IssueSeverity.WARNING,
learn_more_url=learn_more_url(vacuum.DOMAIN),
translation_placeholders={"entity_id": self.entity_id},
translation_key="deprecated_vacuum_battery_feature",
)
_LOGGER.warning(
"MQTT vacuum entity %s implements the battery feature "
"which is deprecated. This will stop working "
"in Home Assistant 2026.3. Implement a separate entity "
"for the battery status instead",
self.entity_id,
)
def _update_state_attributes(self, payload: dict[str, Any]) -> None:
"""Update the entity state attributes."""
self._state_attrs.update(payload)
self._attr_fan_speed = self._state_attrs.get(FAN_SPEED, 0)
# Use of the battery feature was deprecated in HA Core 2025.9
# and will removed with HA Core 2026.3
self._attr_battery_level = max(0, min(100, self._state_attrs.get(BATTERY, 0)))
@callback

View File

@@ -32,6 +32,7 @@ from homeassistant.components.vacuum import (
from homeassistant.const import CONF_NAME, ENTITY_MATCH_ALL, STATE_UNKNOWN
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import issue_registry as ir
from .common import (
help_custom_config,
@@ -63,7 +64,7 @@ from .common import (
help_test_update_with_json_attrs_not_dict,
)
from tests.common import async_fire_mqtt_message
from tests.common import async_capture_events, async_fire_mqtt_message
from tests.components.vacuum import common
from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
@@ -108,7 +109,7 @@ async def test_default_supported_features(
entity = hass.states.get("vacuum.mqtttest")
entity_features = entity.attributes.get(mqttvacuum.CONF_SUPPORTED_FEATURES, 0)
assert sorted(services_to_strings(entity_features, SERVICE_TO_STRING)) == sorted(
["start", "stop", "return_home", "battery", "clean_spot"]
["start", "stop", "return_home", "clean_spot"]
)
@@ -313,8 +314,6 @@ async def test_status(
async_fire_mqtt_message(hass, "vacuum/state", message)
state = hass.states.get("vacuum.mqtttest")
assert state.state == VacuumActivity.CLEANING
assert state.attributes.get(ATTR_BATTERY_LEVEL) == 54
assert state.attributes.get(ATTR_BATTERY_ICON) == "mdi:battery-50"
assert state.attributes.get(ATTR_FAN_SPEED) == "max"
message = """{
@@ -326,8 +325,6 @@ async def test_status(
async_fire_mqtt_message(hass, "vacuum/state", message)
state = hass.states.get("vacuum.mqtttest")
assert state.state == VacuumActivity.DOCKED
assert state.attributes.get(ATTR_BATTERY_ICON) == "mdi:battery-charging-60"
assert state.attributes.get(ATTR_BATTERY_LEVEL) == 61
assert state.attributes.get(ATTR_FAN_SPEED) == "min"
assert state.attributes.get(ATTR_FAN_SPEED_LIST) == ["min", "medium", "high", "max"]
@@ -337,6 +334,61 @@ async def test_status(
assert state.state == STATE_UNKNOWN
# Use of the battery feature was deprecated in HA Core 2025.9
# and will removed with HA Core 2026.3
@pytest.mark.parametrize(
"hass_config",
[
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
({mqttvacuum.CONF_SUPPORTED_FEATURES: ["battery"]},),
)
],
)
async def test_status_with_deprecated_battery_feature(
hass: HomeAssistant,
mqtt_mock_entry: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test status updates from the vacuum with deprecated battery feature."""
events = async_capture_events(hass, ir.EVENT_REPAIRS_ISSUE_REGISTRY_UPDATED)
await mqtt_mock_entry()
state = hass.states.get("vacuum.mqtttest")
assert state.state == STATE_UNKNOWN
message = """{
"battery_level": 54,
"state": "cleaning"
}"""
async_fire_mqtt_message(hass, "vacuum/state", message)
state = hass.states.get("vacuum.mqtttest")
assert state.state == VacuumActivity.CLEANING
assert state.attributes.get(ATTR_BATTERY_LEVEL) == 54
assert state.attributes.get(ATTR_BATTERY_ICON) == "mdi:battery-50"
message = """{
"battery_level": 61,
"state": "docked"
}"""
async_fire_mqtt_message(hass, "vacuum/state", message)
state = hass.states.get("vacuum.mqtttest")
assert state.state == VacuumActivity.DOCKED
assert state.attributes.get(ATTR_BATTERY_ICON) == "mdi:battery-charging-60"
assert state.attributes.get(ATTR_BATTERY_LEVEL) == 61
message = '{"state":null}'
async_fire_mqtt_message(hass, "vacuum/state", message)
state = hass.states.get("vacuum.mqtttest")
assert state.state == STATE_UNKNOWN
assert (
"MQTT vacuum entity vacuum.mqtttest implements "
"the battery feature which is deprecated." in caplog.text
)
assert len(events) == 1
@pytest.mark.parametrize(
"hass_config",
[
@@ -346,7 +398,9 @@ async def test_status(
(
{
mqttvacuum.CONF_SUPPORTED_FEATURES: services_to_strings(
mqttvacuum.DEFAULT_SERVICES, SERVICE_TO_STRING
mqttvacuum.DEFAULT_SERVICES
| vacuum.VacuumEntityFeature.BATTERY,
SERVICE_TO_STRING,
)
},
),