Files
core/homeassistant/components/husqvarna_automower/lawn_mower.py
Thomas55555 fe3027f7de Adjust base entities in Husqvarna Automower (#120258)
* adjust base entities

* Adjust docstrings
2024-06-24 08:16:26 +02:00

150 lines
4.8 KiB
Python

"""Husqvarna Automower lawn mower entity."""
from collections.abc import Awaitable, Callable, Coroutine
from datetime import timedelta
import functools
import logging
from typing import Any
from aioautomower.exceptions import ApiException
from aioautomower.model import MowerActivities, MowerStates
import voluptuous as vol
from homeassistant.components.lawn_mower import (
LawnMowerActivity,
LawnMowerEntity,
LawnMowerEntityFeature,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AutomowerConfigEntry
from .const import DOMAIN
from .coordinator import AutomowerDataUpdateCoordinator
from .entity import AutomowerAvailableEntity
DOCKED_ACTIVITIES = (MowerActivities.PARKED_IN_CS, MowerActivities.CHARGING)
MOWING_ACTIVITIES = (
MowerActivities.MOWING,
MowerActivities.LEAVING,
MowerActivities.GOING_HOME,
)
PAUSED_STATES = [
MowerStates.PAUSED,
MowerStates.WAIT_UPDATING,
MowerStates.WAIT_POWER_UP,
]
SUPPORT_STATE_SERVICES = (
LawnMowerEntityFeature.DOCK
| LawnMowerEntityFeature.PAUSE
| LawnMowerEntityFeature.START_MOWING
)
MOW = "mow"
PARK = "park"
OVERRIDE_MODES = [MOW, PARK]
_LOGGER = logging.getLogger(__name__)
def handle_sending_exception(
func: Callable[..., Awaitable[Any]],
) -> Callable[..., Coroutine[Any, Any, None]]:
"""Handle exceptions while sending a command."""
@functools.wraps(func)
async def wrapper(self: Any, *args: Any, **kwargs: Any) -> Any:
try:
return await func(self, *args, **kwargs)
except ApiException as exception:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="command_send_failed",
translation_placeholders={"exception": str(exception)},
) from exception
return wrapper
async def async_setup_entry(
hass: HomeAssistant,
entry: AutomowerConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up lawn mower platform."""
coordinator = entry.runtime_data
async_add_entities(
AutomowerLawnMowerEntity(mower_id, coordinator) for mower_id in coordinator.data
)
platform = entity_platform.async_get_current_platform()
platform.async_register_entity_service(
"override_schedule",
{
vol.Required("override_mode"): vol.In(OVERRIDE_MODES),
vol.Required("duration"): vol.All(
cv.time_period,
cv.positive_timedelta,
vol.Range(min=timedelta(minutes=1), max=timedelta(days=42)),
),
},
"async_override_schedule",
)
class AutomowerLawnMowerEntity(AutomowerAvailableEntity, LawnMowerEntity):
"""Defining each mower Entity."""
_attr_name = None
_attr_supported_features = SUPPORT_STATE_SERVICES
def __init__(
self,
mower_id: str,
coordinator: AutomowerDataUpdateCoordinator,
) -> None:
"""Set up HusqvarnaAutomowerEntity."""
super().__init__(mower_id, coordinator)
self._attr_unique_id = mower_id
@property
def activity(self) -> LawnMowerActivity:
"""Return the state of the mower."""
mower_attributes = self.mower_attributes
if mower_attributes.mower.state in PAUSED_STATES:
return LawnMowerActivity.PAUSED
if mower_attributes.mower.activity in MOWING_ACTIVITIES:
return LawnMowerActivity.MOWING
if (mower_attributes.mower.state == "RESTRICTED") or (
mower_attributes.mower.activity in DOCKED_ACTIVITIES
):
return LawnMowerActivity.DOCKED
return LawnMowerActivity.ERROR
@handle_sending_exception
async def async_start_mowing(self) -> None:
"""Resume schedule."""
await self.coordinator.api.commands.resume_schedule(self.mower_id)
@handle_sending_exception
async def async_pause(self) -> None:
"""Pauses the mower."""
await self.coordinator.api.commands.pause_mowing(self.mower_id)
@handle_sending_exception
async def async_dock(self) -> None:
"""Parks the mower until next schedule."""
await self.coordinator.api.commands.park_until_next_schedule(self.mower_id)
@handle_sending_exception
async def async_override_schedule(
self, override_mode: str, duration: timedelta
) -> None:
"""Override the schedule with mowing or parking."""
if override_mode == MOW:
await self.coordinator.api.commands.start_for(self.mower_id, duration)
if override_mode == PARK:
await self.coordinator.api.commands.park_for(self.mower_id, duration)