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.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
_LOGGER = logging.getLogger(__name__)
@ -66,6 +71,7 @@ class HomeConnectApplianceData:
def update(self, other: HomeConnectApplianceData) -> None:
"""Update data with data from other instance."""
self.commands.clear()
self.commands.update(other.commands)
self.events.update(other.events)
self.info.connected = other.info.connected
@ -201,6 +207,28 @@ class HomeConnectCoordinator(
raw_key=status_key.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)
case EventType.NOTIFY:

View File

@ -1,12 +1,14 @@
"""Tests for home_connect button entities."""
from collections.abc import Awaitable, Callable
from typing import Any
from typing import Any, cast
from unittest.mock import AsyncMock, MagicMock
from aiohomeconnect.model import (
ArrayOfCommands,
CommandKey,
Event,
EventKey,
EventMessage,
HomeAppliance,
)
@ -317,3 +319,62 @@ async def test_stop_program_button_exception(
{ATTR_ENTITY_ID: entity_id},
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)