Add button platform to La Marzocco (#108236)

* add button

* Update homeassistant/components/lamarzocco/button.py

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* Update homeassistant/components/lamarzocco/strings.json

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>

* update snapshot

---------

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
Josef Zweck 2024-01-17 15:20:24 +01:00 committed by GitHub
parent ee44e9d4d6
commit 90f4900f2c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 156 additions and 0 deletions

View file

@ -9,6 +9,7 @@ from .coordinator import LaMarzoccoUpdateCoordinator
PLATFORMS = [
Platform.BINARY_SENSOR,
Platform.BUTTON,
Platform.NUMBER,
Platform.SELECT,
Platform.SENSOR,

View file

@ -0,0 +1,60 @@
"""Button platform for La Marzocco espresso machines."""
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import Any
from lmcloud import LMCloud as LaMarzoccoClient
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .entity import LaMarzoccoEntity, LaMarzoccoEntityDescription
@dataclass(frozen=True, kw_only=True)
class LaMarzoccoButtonEntityDescription(
LaMarzoccoEntityDescription,
ButtonEntityDescription,
):
"""Description of a La Marzocco button."""
press_fn: Callable[[LaMarzoccoClient], Coroutine[Any, Any, None]]
ENTITIES: tuple[LaMarzoccoButtonEntityDescription, ...] = (
LaMarzoccoButtonEntityDescription(
key="start_backflush",
translation_key="start_backflush",
icon="mdi:water-sync",
press_fn=lambda lm: lm.start_backflush(),
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up button entities."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]
async_add_entities(
LaMarzoccoButtonEntity(coordinator, description)
for description in ENTITIES
if description.supported_fn(coordinator)
)
class LaMarzoccoButtonEntity(LaMarzoccoEntity, ButtonEntity):
"""La Marzocco Button Entity."""
entity_description: LaMarzoccoButtonEntityDescription
async def async_press(self) -> None:
"""Press button."""
await self.entity_description.press_fn(self.coordinator.lm)

View file

@ -51,6 +51,11 @@
"name": "Water tank empty"
}
},
"button": {
"start_backflush": {
"name": "Start backflush"
}
},
"number": {
"coffee_temp": {
"name": "Coffee target temperature"

View file

@ -0,0 +1,45 @@
# serializer version: 1
# name: test_start_backflush
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'GS01234 Start backflush',
'icon': 'mdi:water-sync',
}),
'context': <ANY>,
'entity_id': 'button.gs01234_start_backflush',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_start_backflush.1
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': None,
'entity_id': 'button.gs01234_start_backflush',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': 'mdi:water-sync',
'original_name': 'Start backflush',
'platform': 'lamarzocco',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'start_backflush',
'unique_id': 'GS01234_start_backflush',
'unit_of_measurement': None,
})
# ---

View file

@ -0,0 +1,45 @@
"""Tests for the La Marzocco Buttons."""
from unittest.mock import MagicMock
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
pytestmark = pytest.mark.usefixtures("init_integration")
async def test_start_backflush(
hass: HomeAssistant,
mock_lamarzocco: MagicMock,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
) -> None:
"""Test the La Marzocco backflush button."""
serial_number = mock_lamarzocco.serial_number
state = hass.states.get(f"button.{serial_number}_start_backflush")
assert state
assert state == snapshot
entry = entity_registry.async_get(state.entity_id)
assert entry
assert entry == snapshot
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{
ATTR_ENTITY_ID: f"button.{serial_number}_start_backflush",
},
blocking=True,
)
assert len(mock_lamarzocco.start_backflush.mock_calls) == 1
mock_lamarzocco.start_backflush.assert_called_once()