1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-18 07:56:03 +01:00

Revert mqtt vacuum segments support (#166761)

This commit is contained in:
Jan Bouwhuis
2026-03-28 21:59:36 +01:00
committed by GitHub
parent cfc58bd415
commit ca51123115
4 changed files with 6 additions and 465 deletions

View File

@@ -18,8 +18,6 @@ ABBREVIATIONS = {
"bri_stat_t": "brightness_state_topic", "bri_stat_t": "brightness_state_topic",
"bri_tpl": "brightness_template", "bri_tpl": "brightness_template",
"bri_val_tpl": "brightness_value_template", "bri_val_tpl": "brightness_value_template",
"cln_segmnts_cmd_t": "clean_segments_command_topic",
"cln_segmnts_cmd_tpl": "clean_segments_command_template",
"clr_temp_cmd_tpl": "color_temp_command_template", "clr_temp_cmd_tpl": "color_temp_command_template",
"clrm_stat_t": "color_mode_state_topic", "clrm_stat_t": "color_mode_state_topic",
"clrm_val_tpl": "color_mode_value_template", "clrm_val_tpl": "color_mode_value_template",
@@ -187,7 +185,6 @@ ABBREVIATIONS = {
"rgbww_cmd_t": "rgbww_command_topic", "rgbww_cmd_t": "rgbww_command_topic",
"rgbww_stat_t": "rgbww_state_topic", "rgbww_stat_t": "rgbww_state_topic",
"rgbww_val_tpl": "rgbww_value_template", "rgbww_val_tpl": "rgbww_value_template",
"segmnts": "segments",
"send_cmd_t": "send_command_topic", "send_cmd_t": "send_command_topic",
"send_if_off": "send_if_off", "send_if_off": "send_if_off",
"set_fan_spd_t": "set_fan_speed_topic", "set_fan_spd_t": "set_fan_speed_topic",

View File

@@ -1484,7 +1484,6 @@ class MqttEntity(
self._config = config self._config = config
self._setup_from_config(self._config) self._setup_from_config(self._config)
self._setup_common_attributes_from_config(self._config) self._setup_common_attributes_from_config(self._config)
self._process_entity_update()
# Prepare MQTT subscriptions # Prepare MQTT subscriptions
self.attributes_prepare_discovery_update(config) self.attributes_prepare_discovery_update(config)
@@ -1587,10 +1586,6 @@ class MqttEntity(
def _setup_from_config(self, config: ConfigType) -> None: def _setup_from_config(self, config: ConfigType) -> None:
"""(Re)Setup the entity.""" """(Re)Setup the entity."""
@callback
def _process_entity_update(self) -> None:
"""Process an entity discovery update."""
@abstractmethod @abstractmethod
@callback @callback
def _prepare_subscribe_topics(self) -> None: def _prepare_subscribe_topics(self) -> None:

View File

@@ -10,13 +10,12 @@ import voluptuous as vol
from homeassistant.components import vacuum from homeassistant.components import vacuum
from homeassistant.components.vacuum import ( from homeassistant.components.vacuum import (
ENTITY_ID_FORMAT, ENTITY_ID_FORMAT,
Segment,
StateVacuumEntity, StateVacuumEntity,
VacuumActivity, VacuumActivity,
VacuumEntityFeature, VacuumEntityFeature,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_SUPPORTED_FEATURES, CONF_NAME, CONF_UNIQUE_ID from homeassistant.const import ATTR_SUPPORTED_FEATURES, CONF_NAME
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@@ -28,7 +27,7 @@ from . import subscription
from .config import MQTT_BASE_SCHEMA from .config import MQTT_BASE_SCHEMA
from .const import CONF_COMMAND_TOPIC, CONF_RETAIN, CONF_STATE_TOPIC from .const import CONF_COMMAND_TOPIC, CONF_RETAIN, CONF_STATE_TOPIC
from .entity import MqttEntity, async_setup_entity_entry_helper from .entity import MqttEntity, async_setup_entity_entry_helper
from .models import MqttCommandTemplate, ReceiveMessage from .models import ReceiveMessage
from .schemas import MQTT_ENTITY_COMMON_SCHEMA from .schemas import MQTT_ENTITY_COMMON_SCHEMA
from .util import valid_publish_topic from .util import valid_publish_topic
@@ -53,9 +52,6 @@ POSSIBLE_STATES: dict[str, VacuumActivity] = {
STATE_CLEANING: VacuumActivity.CLEANING, STATE_CLEANING: VacuumActivity.CLEANING,
} }
CONF_SEGMENTS = "segments"
CONF_CLEAN_SEGMENTS_COMMAND_TOPIC = "clean_segments_command_topic"
CONF_CLEAN_SEGMENTS_COMMAND_TEMPLATE = "clean_segments_command_template"
CONF_SUPPORTED_FEATURES = ATTR_SUPPORTED_FEATURES CONF_SUPPORTED_FEATURES = ATTR_SUPPORTED_FEATURES
CONF_PAYLOAD_TURN_ON = "payload_turn_on" CONF_PAYLOAD_TURN_ON = "payload_turn_on"
CONF_PAYLOAD_TURN_OFF = "payload_turn_off" CONF_PAYLOAD_TURN_OFF = "payload_turn_off"
@@ -141,39 +137,8 @@ MQTT_VACUUM_ATTRIBUTES_BLOCKED = frozenset(
MQTT_VACUUM_DOCS_URL = "https://www.home-assistant.io/integrations/vacuum.mqtt/" MQTT_VACUUM_DOCS_URL = "https://www.home-assistant.io/integrations/vacuum.mqtt/"
def validate_clean_area_config(config: ConfigType) -> ConfigType: PLATFORM_SCHEMA_MODERN = MQTT_BASE_SCHEMA.extend(
"""Check for a valid configuration and check segments."""
if (config[CONF_SEGMENTS] and CONF_CLEAN_SEGMENTS_COMMAND_TOPIC not in config) or (
not config[CONF_SEGMENTS] and CONF_CLEAN_SEGMENTS_COMMAND_TOPIC in config
):
raise vol.Invalid(
f"Options `{CONF_SEGMENTS}` and "
f"`{CONF_CLEAN_SEGMENTS_COMMAND_TOPIC}` must be defined together"
)
segments: list[str]
if segments := config[CONF_SEGMENTS]:
if not config.get(CONF_UNIQUE_ID):
raise vol.Invalid(
f"Option `{CONF_SEGMENTS}` requires `{CONF_UNIQUE_ID}` to be configured"
)
unique_segments: set[str] = set()
for segment in segments:
segment_id, _, _ = segment.partition(".")
if not segment_id or segment_id in unique_segments:
raise vol.Invalid(
f"The `{CONF_SEGMENTS}` option contains an invalid or non-"
f"unique segment ID '{segment_id}'. Got {segments}"
)
unique_segments.add(segment_id)
return config
_BASE_SCHEMA = MQTT_BASE_SCHEMA.extend(
{ {
vol.Optional(CONF_SEGMENTS, default=[]): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_CLEAN_SEGMENTS_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_CLEAN_SEGMENTS_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_FAN_SPEED_LIST, default=[]): vol.All( vol.Optional(CONF_FAN_SPEED_LIST, default=[]): vol.All(
cv.ensure_list, [cv.string] cv.ensure_list, [cv.string]
), ),
@@ -199,10 +164,7 @@ _BASE_SCHEMA = MQTT_BASE_SCHEMA.extend(
} }
).extend(MQTT_ENTITY_COMMON_SCHEMA.schema) ).extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
PLATFORM_SCHEMA_MODERN = vol.All(_BASE_SCHEMA, validate_clean_area_config) DISCOVERY_SCHEMA = PLATFORM_SCHEMA_MODERN.extend({}, extra=vol.ALLOW_EXTRA)
DISCOVERY_SCHEMA = vol.All(
_BASE_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA), validate_clean_area_config
)
async def async_setup_entry( async def async_setup_entry(
@@ -229,11 +191,9 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
_entity_id_format = ENTITY_ID_FORMAT _entity_id_format = ENTITY_ID_FORMAT
_attributes_extra_blocked = MQTT_VACUUM_ATTRIBUTES_BLOCKED _attributes_extra_blocked = MQTT_VACUUM_ATTRIBUTES_BLOCKED
_segments: list[Segment]
_command_topic: str | None _command_topic: str | None
_set_fan_speed_topic: str | None _set_fan_speed_topic: str | None
_send_command_topic: str | None _send_command_topic: str | None
_clean_segments_command_topic: str
_payloads: dict[str, str | None] _payloads: dict[str, str | None]
def __init__( def __init__(
@@ -269,23 +229,6 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
self._attr_supported_features = _strings_to_services( self._attr_supported_features = _strings_to_services(
supported_feature_strings, STRING_TO_SERVICE supported_feature_strings, STRING_TO_SERVICE
) )
if config[CONF_SEGMENTS] and CONF_CLEAN_SEGMENTS_COMMAND_TOPIC in config:
self._attr_supported_features |= VacuumEntityFeature.CLEAN_AREA
segments: list[str] = config[CONF_SEGMENTS]
self._segments = [
Segment(id=segment_id, name=name or segment_id)
for segment_id, _, name in [
segment.partition(".") for segment in segments
]
]
self._clean_segments_command_topic = config[
CONF_CLEAN_SEGMENTS_COMMAND_TOPIC
]
self._clean_segments_command_template = MqttCommandTemplate(
config.get(CONF_CLEAN_SEGMENTS_COMMAND_TEMPLATE),
entity=self,
).async_render
self._attr_fan_speed_list = config[CONF_FAN_SPEED_LIST] self._attr_fan_speed_list = config[CONF_FAN_SPEED_LIST]
self._command_topic = config.get(CONF_COMMAND_TOPIC) self._command_topic = config.get(CONF_COMMAND_TOPIC)
self._set_fan_speed_topic = config.get(CONF_SET_FAN_SPEED_TOPIC) self._set_fan_speed_topic = config.get(CONF_SET_FAN_SPEED_TOPIC)
@@ -303,20 +246,6 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
) )
} }
@callback
def _process_entity_update(self) -> None:
"""Check vacuum segments with registry entry."""
if (
self._attr_supported_features & VacuumEntityFeature.CLEAN_AREA
and (last_seen := self.last_seen_segments) is not None
and {s.id: s for s in last_seen} != {s.id: s for s in self._segments}
):
self.async_create_segments_issue()
async def mqtt_async_added_to_hass(self) -> None:
"""Check vacuum segments with registry entry."""
self._process_entity_update()
def _update_state_attributes(self, payload: dict[str, Any]) -> None: def _update_state_attributes(self, payload: dict[str, Any]) -> None:
"""Update the entity state attributes.""" """Update the entity state attributes."""
self._state_attrs.update(payload) self._state_attrs.update(payload)
@@ -348,19 +277,6 @@ class MqttStateVacuum(MqttEntity, StateVacuumEntity):
"""(Re)Subscribe to topics.""" """(Re)Subscribe to topics."""
subscription.async_subscribe_topics_internal(self.hass, self._sub_state) subscription.async_subscribe_topics_internal(self.hass, self._sub_state)
async def async_clean_segments(self, segment_ids: list[str], **kwargs: Any) -> None:
"""Perform an area clean."""
await self.async_publish_with_config(
self._clean_segments_command_topic,
self._clean_segments_command_template(
json_dumps(segment_ids), {"value": segment_ids}
),
)
async def async_get_segments(self) -> list[Segment]:
"""Return the available segments."""
return self._segments
async def _async_publish_command(self, feature: VacuumEntityFeature) -> None: async def _async_publish_command(self, feature: VacuumEntityFeature) -> None:
"""Publish a command.""" """Publish a command."""
if self._command_topic is None: if self._command_topic is None:

View File

@@ -3,7 +3,7 @@
from copy import deepcopy from copy import deepcopy
import json import json
from typing import Any from typing import Any
from unittest.mock import call, patch from unittest.mock import patch
import pytest import pytest
@@ -30,7 +30,6 @@ from homeassistant.components.vacuum import (
from homeassistant.const import CONF_NAME, ENTITY_MATCH_ALL, STATE_UNKNOWN from homeassistant.const import CONF_NAME, ENTITY_MATCH_ALL, STATE_UNKNOWN
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er, issue_registry as ir
from .common import ( from .common import (
help_custom_config, help_custom_config,
@@ -64,11 +63,7 @@ from .common import (
from tests.common import async_fire_mqtt_message from tests.common import async_fire_mqtt_message
from tests.components.vacuum import common from tests.components.vacuum import common
from tests.typing import ( from tests.typing import MqttMockHAClientGenerator, MqttMockPahoClient
MqttMockHAClientGenerator,
MqttMockPahoClient,
WebSocketGenerator,
)
COMMAND_TOPIC = "vacuum/command" COMMAND_TOPIC = "vacuum/command"
SEND_COMMAND_TOPIC = "vacuum/send_command" SEND_COMMAND_TOPIC = "vacuum/send_command"
@@ -87,27 +82,6 @@ DEFAULT_CONFIG = {
} }
} }
CONFIG_CLEAN_SEGMENTS_1 = {
mqtt.DOMAIN: {
vacuum.DOMAIN: {
"name": "test",
"unique_id": "veryunique",
"segments": ["Livingroom", "Kitchen"],
"clean_segments_command_topic": "vacuum/clean_segment",
}
}
}
CONFIG_CLEAN_SEGMENTS_2 = {
mqtt.DOMAIN: {
vacuum.DOMAIN: {
"name": "test",
"unique_id": "veryunique",
"segments": ["1.Livingroom", "2.Kitchen"],
"clean_segments_command_topic": "vacuum/clean_segment",
}
}
}
DEFAULT_CONFIG_2 = {mqtt.DOMAIN: {vacuum.DOMAIN: {"name": "test"}}} DEFAULT_CONFIG_2 = {mqtt.DOMAIN: {vacuum.DOMAIN: {"name": "test"}}}
CONFIG_ALL_SERVICES = help_custom_config( CONFIG_ALL_SERVICES = help_custom_config(
@@ -320,347 +294,6 @@ async def test_command_without_command_topic(
mqtt_mock.async_publish.reset_mock() mqtt_mock.async_publish.reset_mock()
@pytest.mark.parametrize("hass_config", [CONFIG_CLEAN_SEGMENTS_1])
async def test_clean_segments_initial_setup_without_repair_issue(
hass: HomeAssistant,
mqtt_mock_entry: MqttMockHAClientGenerator,
) -> None:
"""Test cleanable segments initial setup does not fire repair flow."""
await mqtt_mock_entry()
issue_registry = ir.async_get(hass)
assert len(issue_registry.issues) == 0
@pytest.mark.parametrize("hass_config", [CONFIG_CLEAN_SEGMENTS_1])
async def test_clean_segments_command_without_id(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
entity_registry: er.EntityRegistry,
mqtt_mock_entry: MqttMockHAClientGenerator,
) -> None:
"""Test cleanable segments without ID."""
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
entity_registry.async_get_or_create(
vacuum.DOMAIN,
mqtt.DOMAIN,
"veryunique",
config_entry=config_entry,
suggested_object_id="test",
)
entity_registry.async_update_entity_options(
"vacuum.test",
vacuum.DOMAIN,
{
"area_mapping": {"Nabu Casa": ["Kitchen", "Livingroom"]},
"last_seen_segments": [
{"id": "Livingroom", "name": "Livingroom"},
{"id": "Kitchen", "name": "Kitchen"},
],
},
)
mqtt_mock = await mqtt_mock_entry()
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
# We do not expect a repair flow
assert len(issue_registry.issues) == 0
state = hass.states.get("vacuum.test")
assert state.state == STATE_UNKNOWN
await common.async_clean_area(hass, ["Nabu Casa"], entity_id="vacuum.test")
assert (
call("vacuum/clean_segment", '["Kitchen","Livingroom"]', 0, False)
in mqtt_mock.async_publish.mock_calls
)
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{"type": "vacuum/get_segments", "entity_id": "vacuum.test"}
)
msg = await client.receive_json()
assert msg["success"]
assert msg["result"]["segments"] == [
{"id": "Livingroom", "name": "Livingroom", "group": None},
{"id": "Kitchen", "name": "Kitchen", "group": None},
]
@pytest.mark.parametrize("hass_config", [CONFIG_CLEAN_SEGMENTS_2])
async def test_clean_segments_command_with_id(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
entity_registry: er.EntityRegistry,
mqtt_mock_entry: MqttMockHAClientGenerator,
) -> None:
"""Test cleanable segments with ID."""
mqtt_mock = await mqtt_mock_entry()
# Set the area mapping
entity_registry.async_update_entity_options(
"vacuum.test",
vacuum.DOMAIN,
{
"area_mapping": {"Livingroom": ["1"], "Kitchen": ["2"]},
"last_seen_segments": [
{"id": "1", "name": "Livingroom"},
{"id": "2", "name": "Kitchen"},
],
},
)
await hass.async_block_till_done()
state = hass.states.get("vacuum.test")
assert state.state == STATE_UNKNOWN
await common.async_clean_area(hass, ["Kitchen"], entity_id="vacuum.test")
assert (
call("vacuum/clean_segment", '["2"]', 0, False)
in mqtt_mock.async_publish.mock_calls
)
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{"type": "vacuum/get_segments", "entity_id": "vacuum.test"}
)
msg = await client.receive_json()
assert msg["success"]
assert msg["result"]["segments"] == [
{"id": "1", "name": "Livingroom", "group": None},
{"id": "2", "name": "Kitchen", "group": None},
]
async def test_clean_segments_command_update(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
entity_registry: er.EntityRegistry,
mqtt_mock_entry: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test cleanable segments update via discovery."""
# Prepare original entity config entry
config_entry = hass.config_entries.async_entries(mqtt.DOMAIN)[0]
entity_registry.async_get_or_create(
vacuum.DOMAIN,
mqtt.DOMAIN,
"veryunique",
config_entry=config_entry,
suggested_object_id="test",
)
entity_registry.async_update_entity_options(
"vacuum.test",
vacuum.DOMAIN,
{
"area_mapping": {"Livingroom": ["1"], "Kitchen": ["2"]},
"last_seen_segments": [
{"id": "1", "name": "Livingroom"},
{"id": "2", "name": "Kitchen"},
],
},
)
await mqtt_mock_entry()
# Do initial discovery
config1 = CONFIG_CLEAN_SEGMENTS_2[mqtt.DOMAIN][vacuum.DOMAIN]
payload1 = json.dumps(config1)
config_topic = "homeassistant/vacuum/bla/config"
async_fire_mqtt_message(hass, config_topic, payload1)
await hass.async_block_till_done()
state = hass.states.get("vacuum.test")
assert state.state == STATE_UNKNOWN
issue_registry = ir.async_get(hass)
# We do not expect a repair flow
assert len(issue_registry.issues) == 0
# Update the segments
config2 = config1.copy()
config2["segments"] = ["1.Livingroom", "2.Kitchen", "3.Diningroom"]
payload2 = json.dumps(config2)
async_fire_mqtt_message(hass, config_topic, payload2)
await hass.async_block_till_done()
# A repair flow should start
assert len(issue_registry.issues) == 1
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{"type": "vacuum/get_segments", "entity_id": "vacuum.test"}
)
msg = await client.receive_json()
assert msg["success"]
assert msg["result"]["segments"] == [
{"id": "1", "name": "Livingroom", "group": None},
{"id": "2", "name": "Kitchen", "group": None},
{"id": "3", "name": "Diningroom", "group": None},
]
# Test update with a non-unique segment list fails
config3 = config1.copy()
config3["segments"] = ["1.Livingroom", "2.Kitchen", "2.Diningroom"]
payload3 = json.dumps(config3)
async_fire_mqtt_message(hass, config_topic, payload3)
await hass.async_block_till_done()
assert (
"Error 'The `segments` option contains an invalid or non-unique segment ID '2'"
in caplog.text
)
@pytest.mark.parametrize(
"hass_config",
[
{
mqtt.DOMAIN: {
vacuum.DOMAIN: {
"name": "test",
"unique_id": "veryunique",
"segments": ["Livingroom", "Kitchen", "Kitchen"],
"clean_segments_command_topic": "vacuum/clean_segment",
}
}
},
{
mqtt.DOMAIN: {
vacuum.DOMAIN: {
"name": "test",
"unique_id": "veryunique",
"segments": ["Livingroom", "Kitchen", ""],
"clean_segments_command_topic": "vacuum/clean_segment",
}
}
},
{
mqtt.DOMAIN: {
vacuum.DOMAIN: {
"name": "test",
"unique_id": "veryunique",
"segments": ["1.Livingroom", "1.Kitchen"],
"clean_segments_command_topic": "vacuum/clean_segment",
}
}
},
{
mqtt.DOMAIN: {
vacuum.DOMAIN: {
"name": "test",
"unique_id": "veryunique",
"segments": ["1.Livingroom", "1.Kitchen", ".Diningroom"],
"clean_segments_command_topic": "vacuum/clean_segment",
}
}
},
],
)
async def test_non_unique_segments(
hass: HomeAssistant,
mqtt_mock_entry: MqttMockHAClientGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test with non-unique list of cleanable segments with valid segment IDs."""
await mqtt_mock_entry()
assert (
"The `segments` option contains an invalid or non-unique segment ID"
in caplog.text
)
@pytest.mark.usefixtures("hass")
@pytest.mark.parametrize(
("hass_config", "error_message"),
[
(
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
({"clean_segments_command_topic": "test-topic"},),
),
"Options `segments` and "
"`clean_segments_command_topic` must be defined together",
),
(
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
({"segments": ["Livingroom"]},),
),
"Options `segments` and "
"`clean_segments_command_topic` must be defined together",
),
(
help_custom_config(
vacuum.DOMAIN,
DEFAULT_CONFIG,
(
{
"segments": ["Livingroom"],
"clean_segments_command_topic": "test-topic",
},
),
),
"Option `segments` requires `unique_id` to be configured",
),
],
)
async def test_clean_segments_config_validation(
mqtt_mock_entry: MqttMockHAClientGenerator,
error_message: str,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test status clean segment config validation."""
await mqtt_mock_entry()
assert error_message in caplog.text
@pytest.mark.parametrize(
"hass_config",
[
help_custom_config(
vacuum.DOMAIN,
CONFIG_CLEAN_SEGMENTS_2,
({"clean_segments_command_template": "{{ ';'.join(value) }}"},),
)
],
)
async def test_clean_segments_command_with_id_and_command_template(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
entity_registry: er.EntityRegistry,
mqtt_mock_entry: MqttMockHAClientGenerator,
) -> None:
"""Test clean segments with command template."""
mqtt_mock = await mqtt_mock_entry()
entity_registry.async_update_entity_options(
"vacuum.test",
vacuum.DOMAIN,
{
"area_mapping": {"Livingroom": ["1"], "Kitchen": ["2"]},
"last_seen_segments": [
{"id": "1", "name": "Livingroom"},
{"id": "2", "name": "Kitchen"},
],
},
)
await hass.async_block_till_done()
state = hass.states.get("vacuum.test")
assert state.state == STATE_UNKNOWN
await common.async_clean_area(
hass, ["Livingroom", "Kitchen"], entity_id="vacuum.test"
)
assert (
call("vacuum/clean_segment", "1;2", 0, False)
in mqtt_mock.async_publish.mock_calls
)
client = await hass_ws_client(hass)
await client.send_json_auto_id(
{"type": "vacuum/get_segments", "entity_id": "vacuum.test"}
)
msg = await client.receive_json()
assert msg["success"]
assert msg["result"]["segments"] == [
{"id": "1", "name": "Livingroom", "group": None},
{"id": "2", "name": "Kitchen", "group": None},
]
@pytest.mark.parametrize("hass_config", [CONFIG_ALL_SERVICES]) @pytest.mark.parametrize("hass_config", [CONFIG_ALL_SERVICES])
async def test_status( async def test_status(
hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator hass: HomeAssistant, mqtt_mock_entry: MqttMockHAClientGenerator