core/homeassistant/components/lamarzocco/switch.py

169 lines
5.9 KiB
Python
Raw Normal View History

"""Switch platform for La Marzocco espresso machines."""
from collections.abc import Callable, Coroutine
from dataclasses import dataclass
from typing import Any
Migrate lamarzocco to lmcloud 1.1 (#113935) * migrate to 1.1 * bump to 1.1.1 * fix newlines docstring * cleanup entity_description fns * strict generics * restructure import * tweaks to generics * tweaks to generics * removed exceptions * move initialization, websocket clean shutdown * get rid of duplicate entry addign * bump lmcloud * re-add calendar, auto on/off switches * use asdict for diagnostics * change number generator * use name as entry title * also migrate title * don't migrate title * remove generics for now * satisfy mypy * add s * adapt * migrate entry.runtime_data * remove auto/onoff * add issue on wrong gw firmware * silence mypy * remove breaks in ha version * parametrize issue test * Update update.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * regen snapshots * mapping steam level * remove commented code * fix typo * coderabbitai availability tweak * remove microsecond moving * additonal schedule for coverage * be more specific on date offset * keep mappings the same * config_entry imports sharpened * remove unneccessary testcase, clenup date moving * remove superfluous calendar testcase from diag * guard against future version downgrade * use new entry for downgrade test * switch to lmcloud 1.1.11 * revert runtimedata * revert runtimedata * version to helper * conistent Generator * generator from typing_extensions --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-10 17:59:39 +00:00
from lmcloud.const import BoilerType
from lmcloud.exceptions import RequestNotSuccessful
Migrate lamarzocco to lmcloud 1.1 (#113935) * migrate to 1.1 * bump to 1.1.1 * fix newlines docstring * cleanup entity_description fns * strict generics * restructure import * tweaks to generics * tweaks to generics * removed exceptions * move initialization, websocket clean shutdown * get rid of duplicate entry addign * bump lmcloud * re-add calendar, auto on/off switches * use asdict for diagnostics * change number generator * use name as entry title * also migrate title * don't migrate title * remove generics for now * satisfy mypy * add s * adapt * migrate entry.runtime_data * remove auto/onoff * add issue on wrong gw firmware * silence mypy * remove breaks in ha version * parametrize issue test * Update update.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * regen snapshots * mapping steam level * remove commented code * fix typo * coderabbitai availability tweak * remove microsecond moving * additonal schedule for coverage * be more specific on date offset * keep mappings the same * config_entry imports sharpened * remove unneccessary testcase, clenup date moving * remove superfluous calendar testcase from diag * guard against future version downgrade * use new entry for downgrade test * switch to lmcloud 1.1.11 * revert runtimedata * revert runtimedata * version to helper * conistent Generator * generator from typing_extensions --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-10 17:59:39 +00:00
from lmcloud.lm_machine import LaMarzoccoMachine
from lmcloud.models import LaMarzoccoMachineConfig
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import LaMarzoccoConfigEntry
from .const import DOMAIN
from .coordinator import LaMarzoccoUpdateCoordinator
from .entity import LaMarzoccoBaseEntity, LaMarzoccoEntity, LaMarzoccoEntityDescription
@dataclass(frozen=True, kw_only=True)
class LaMarzoccoSwitchEntityDescription(
LaMarzoccoEntityDescription,
SwitchEntityDescription,
):
"""Description of a La Marzocco Switch."""
Migrate lamarzocco to lmcloud 1.1 (#113935) * migrate to 1.1 * bump to 1.1.1 * fix newlines docstring * cleanup entity_description fns * strict generics * restructure import * tweaks to generics * tweaks to generics * removed exceptions * move initialization, websocket clean shutdown * get rid of duplicate entry addign * bump lmcloud * re-add calendar, auto on/off switches * use asdict for diagnostics * change number generator * use name as entry title * also migrate title * don't migrate title * remove generics for now * satisfy mypy * add s * adapt * migrate entry.runtime_data * remove auto/onoff * add issue on wrong gw firmware * silence mypy * remove breaks in ha version * parametrize issue test * Update update.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * regen snapshots * mapping steam level * remove commented code * fix typo * coderabbitai availability tweak * remove microsecond moving * additonal schedule for coverage * be more specific on date offset * keep mappings the same * config_entry imports sharpened * remove unneccessary testcase, clenup date moving * remove superfluous calendar testcase from diag * guard against future version downgrade * use new entry for downgrade test * switch to lmcloud 1.1.11 * revert runtimedata * revert runtimedata * version to helper * conistent Generator * generator from typing_extensions --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-10 17:59:39 +00:00
control_fn: Callable[[LaMarzoccoMachine, bool], Coroutine[Any, Any, bool]]
is_on_fn: Callable[[LaMarzoccoMachineConfig], bool]
ENTITIES: tuple[LaMarzoccoSwitchEntityDescription, ...] = (
LaMarzoccoSwitchEntityDescription(
key="main",
translation_key="main",
name=None,
Migrate lamarzocco to lmcloud 1.1 (#113935) * migrate to 1.1 * bump to 1.1.1 * fix newlines docstring * cleanup entity_description fns * strict generics * restructure import * tweaks to generics * tweaks to generics * removed exceptions * move initialization, websocket clean shutdown * get rid of duplicate entry addign * bump lmcloud * re-add calendar, auto on/off switches * use asdict for diagnostics * change number generator * use name as entry title * also migrate title * don't migrate title * remove generics for now * satisfy mypy * add s * adapt * migrate entry.runtime_data * remove auto/onoff * add issue on wrong gw firmware * silence mypy * remove breaks in ha version * parametrize issue test * Update update.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * regen snapshots * mapping steam level * remove commented code * fix typo * coderabbitai availability tweak * remove microsecond moving * additonal schedule for coverage * be more specific on date offset * keep mappings the same * config_entry imports sharpened * remove unneccessary testcase, clenup date moving * remove superfluous calendar testcase from diag * guard against future version downgrade * use new entry for downgrade test * switch to lmcloud 1.1.11 * revert runtimedata * revert runtimedata * version to helper * conistent Generator * generator from typing_extensions --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-10 17:59:39 +00:00
control_fn=lambda machine, state: machine.set_power(state),
is_on_fn=lambda config: config.turned_on,
),
LaMarzoccoSwitchEntityDescription(
key="steam_boiler_enable",
translation_key="steam_boiler",
Migrate lamarzocco to lmcloud 1.1 (#113935) * migrate to 1.1 * bump to 1.1.1 * fix newlines docstring * cleanup entity_description fns * strict generics * restructure import * tweaks to generics * tweaks to generics * removed exceptions * move initialization, websocket clean shutdown * get rid of duplicate entry addign * bump lmcloud * re-add calendar, auto on/off switches * use asdict for diagnostics * change number generator * use name as entry title * also migrate title * don't migrate title * remove generics for now * satisfy mypy * add s * adapt * migrate entry.runtime_data * remove auto/onoff * add issue on wrong gw firmware * silence mypy * remove breaks in ha version * parametrize issue test * Update update.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * regen snapshots * mapping steam level * remove commented code * fix typo * coderabbitai availability tweak * remove microsecond moving * additonal schedule for coverage * be more specific on date offset * keep mappings the same * config_entry imports sharpened * remove unneccessary testcase, clenup date moving * remove superfluous calendar testcase from diag * guard against future version downgrade * use new entry for downgrade test * switch to lmcloud 1.1.11 * revert runtimedata * revert runtimedata * version to helper * conistent Generator * generator from typing_extensions --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-10 17:59:39 +00:00
control_fn=lambda machine, state: machine.set_steam(state),
is_on_fn=lambda config: config.boilers[BoilerType.STEAM].enabled,
),
LaMarzoccoSwitchEntityDescription(
key="smart_standby_enabled",
translation_key="smart_standby_enabled",
entity_category=EntityCategory.CONFIG,
control_fn=lambda machine, state: machine.set_smart_standby(
enabled=state,
mode=machine.config.smart_standby.mode,
minutes=machine.config.smart_standby.minutes,
),
is_on_fn=lambda config: config.smart_standby.enabled,
),
)
async def async_setup_entry(
hass: HomeAssistant,
entry: LaMarzoccoConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up switch entities and services."""
coordinator = entry.runtime_data
entities: list[SwitchEntity] = []
entities.extend(
LaMarzoccoSwitchEntity(coordinator, description)
for description in ENTITIES
if description.supported_fn(coordinator)
)
entities.extend(
LaMarzoccoAutoOnOffSwitchEntity(coordinator, wake_up_sleep_entry_id)
for wake_up_sleep_entry_id in coordinator.device.config.wake_up_sleep_entries
)
async_add_entities(entities)
class LaMarzoccoSwitchEntity(LaMarzoccoEntity, SwitchEntity):
"""Switches representing espresso machine power, prebrew, and auto on/off."""
entity_description: LaMarzoccoSwitchEntityDescription
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn device on."""
try:
await self.entity_description.control_fn(self.coordinator.device, True)
except RequestNotSuccessful as exc:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="switch_on_error",
translation_placeholders={"key": self.entity_description.key},
) from exc
self.async_write_ha_state()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn device off."""
try:
await self.entity_description.control_fn(self.coordinator.device, False)
except RequestNotSuccessful as exc:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="switch_off_error",
translation_placeholders={"name": self.entity_description.key},
) from exc
self.async_write_ha_state()
@property
def is_on(self) -> bool:
"""Return true if device is on."""
Migrate lamarzocco to lmcloud 1.1 (#113935) * migrate to 1.1 * bump to 1.1.1 * fix newlines docstring * cleanup entity_description fns * strict generics * restructure import * tweaks to generics * tweaks to generics * removed exceptions * move initialization, websocket clean shutdown * get rid of duplicate entry addign * bump lmcloud * re-add calendar, auto on/off switches * use asdict for diagnostics * change number generator * use name as entry title * also migrate title * don't migrate title * remove generics for now * satisfy mypy * add s * adapt * migrate entry.runtime_data * remove auto/onoff * add issue on wrong gw firmware * silence mypy * remove breaks in ha version * parametrize issue test * Update update.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update test_config_flow.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * regen snapshots * mapping steam level * remove commented code * fix typo * coderabbitai availability tweak * remove microsecond moving * additonal schedule for coverage * be more specific on date offset * keep mappings the same * config_entry imports sharpened * remove unneccessary testcase, clenup date moving * remove superfluous calendar testcase from diag * guard against future version downgrade * use new entry for downgrade test * switch to lmcloud 1.1.11 * revert runtimedata * revert runtimedata * version to helper * conistent Generator * generator from typing_extensions --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2024-06-10 17:59:39 +00:00
return self.entity_description.is_on_fn(self.coordinator.device.config)
class LaMarzoccoAutoOnOffSwitchEntity(LaMarzoccoBaseEntity, SwitchEntity):
"""Switch representing espresso machine auto on/off."""
coordinator: LaMarzoccoUpdateCoordinator
_attr_translation_key = "auto_on_off"
def __init__(
self,
coordinator: LaMarzoccoUpdateCoordinator,
identifier: str,
) -> None:
"""Initialize the switch."""
super().__init__(coordinator, f"auto_on_off_{identifier}")
self._identifier = identifier
self._attr_translation_placeholders = {"id": identifier}
self.entity_category = EntityCategory.CONFIG
async def _async_enable(self, state: bool) -> None:
"""Enable or disable the auto on/off schedule."""
wake_up_sleep_entry = self.coordinator.device.config.wake_up_sleep_entries[
self._identifier
]
wake_up_sleep_entry.enabled = state
try:
await self.coordinator.device.set_wake_up_sleep(wake_up_sleep_entry)
except RequestNotSuccessful as exc:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="auto_on_off_error",
translation_placeholders={"id": self._identifier, "state": str(state)},
) from exc
self.async_write_ha_state()
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn switch on."""
await self._async_enable(True)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn switch off."""
await self._async_enable(False)
@property
def is_on(self) -> bool:
"""Return true if switch is on."""
return self.coordinator.device.config.wake_up_sleep_entries[
self._identifier
].enabled