Add Home Connect resume command button when an appliance is paused (#148512)

This commit is contained in:
J. Diego Rodríguez Royo 2025-07-10 00:26:13 +02:00 committed by GitHub
parent 24a7ebd2bb
commit 49baa65f61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 91 additions and 2 deletions

View File

@ -41,7 +41,12 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr, issue_registry as ir from homeassistant.helpers import device_registry as dr, issue_registry as ir
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import API_DEFAULT_RETRY_AFTER, APPLIANCES_WITH_PROGRAMS, DOMAIN from .const import (
API_DEFAULT_RETRY_AFTER,
APPLIANCES_WITH_PROGRAMS,
BSH_OPERATION_STATE_PAUSE,
DOMAIN,
)
from .utils import get_dict_from_home_connect_error from .utils import get_dict_from_home_connect_error
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -66,6 +71,7 @@ class HomeConnectApplianceData:
def update(self, other: HomeConnectApplianceData) -> None: def update(self, other: HomeConnectApplianceData) -> None:
"""Update data with data from other instance.""" """Update data with data from other instance."""
self.commands.clear()
self.commands.update(other.commands) self.commands.update(other.commands)
self.events.update(other.events) self.events.update(other.events)
self.info.connected = other.info.connected self.info.connected = other.info.connected
@ -201,6 +207,28 @@ class HomeConnectCoordinator(
raw_key=status_key.value, raw_key=status_key.value,
value=event.value, value=event.value,
) )
if (
status_key == StatusKey.BSH_COMMON_OPERATION_STATE
and event.value == BSH_OPERATION_STATE_PAUSE
and CommandKey.BSH_COMMON_RESUME_PROGRAM
not in (
commands := self.data[
event_message_ha_id
].commands
)
):
# All the appliances that can be paused
# should have the resume command available.
commands.add(CommandKey.BSH_COMMON_RESUME_PROGRAM)
for (
listener,
context,
) in self._special_listeners.values():
if (
EventKey.BSH_COMMON_APPLIANCE_DEPAIRED
not in context
):
listener()
self._call_event_listener(event_message) self._call_event_listener(event_message)
case EventType.NOTIFY: case EventType.NOTIFY:

View File

@ -1,12 +1,14 @@
"""Tests for home_connect button entities.""" """Tests for home_connect button entities."""
from collections.abc import Awaitable, Callable from collections.abc import Awaitable, Callable
from typing import Any from typing import Any, cast
from unittest.mock import AsyncMock, MagicMock from unittest.mock import AsyncMock, MagicMock
from aiohomeconnect.model import ( from aiohomeconnect.model import (
ArrayOfCommands, ArrayOfCommands,
CommandKey, CommandKey,
Event,
EventKey,
EventMessage, EventMessage,
HomeAppliance, HomeAppliance,
) )
@ -317,3 +319,62 @@ async def test_stop_program_button_exception(
{ATTR_ENTITY_ID: entity_id}, {ATTR_ENTITY_ID: entity_id},
blocking=True, blocking=True,
) )
@pytest.mark.parametrize("appliance", ["Washer"], indirect=True)
async def test_enable_resume_command_on_pause(
hass: HomeAssistant,
client: MagicMock,
config_entry: MockConfigEntry,
integration_setup: Callable[[MagicMock], Awaitable[bool]],
appliance: HomeAppliance,
) -> None:
"""Test if all commands enabled option works as expected."""
entity_id = "button.washer_resume_program"
original_get_available_commands = client.get_available_commands
async def get_available_commands_side_effect(ha_id: str) -> ArrayOfCommands:
array_of_commands = cast(
ArrayOfCommands, await original_get_available_commands(ha_id)
)
if ha_id == appliance.ha_id:
for command in array_of_commands.commands:
if command.key == CommandKey.BSH_COMMON_RESUME_PROGRAM:
# Simulate that the resume command is not available initially
array_of_commands.commands.remove(command)
break
return array_of_commands
client.get_available_commands = AsyncMock(
side_effect=get_available_commands_side_effect
)
assert await integration_setup(client)
assert config_entry.state is ConfigEntryState.LOADED
assert not hass.states.get(entity_id)
await client.add_events(
[
EventMessage(
appliance.ha_id,
EventType.STATUS,
data=ArrayOfEvents(
[
Event(
key=EventKey.BSH_COMMON_STATUS_OPERATION_STATE,
raw_key=EventKey.BSH_COMMON_STATUS_OPERATION_STATE.value,
timestamp=0,
level="",
handling="",
value="BSH.Common.EnumType.OperationState.Pause",
)
]
),
)
]
)
await hass.async_block_till_done()
assert hass.states.get(entity_id)