mirror of
https://github.com/home-assistant/core.git
synced 2025-11-30 13:08:01 +00:00
145 lines
5.1 KiB
Python
145 lines
5.1 KiB
Python
"""Support for Litter-Robot switches."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Callable, Coroutine
|
|
from dataclasses import dataclass
|
|
from typing import Any, Generic
|
|
|
|
from pylitterbot import FeederRobot, LitterRobot, LitterRobot3, LitterRobot4, Robot
|
|
|
|
from homeassistant.components.switch import (
|
|
DOMAIN as SWITCH_DOMAIN,
|
|
SwitchEntity,
|
|
SwitchEntityDescription,
|
|
)
|
|
from homeassistant.const import EntityCategory
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import entity_registry as er
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
from homeassistant.helpers.issue_registry import (
|
|
IssueSeverity,
|
|
async_create_issue,
|
|
async_delete_issue,
|
|
)
|
|
|
|
from .const import DOMAIN
|
|
from .coordinator import LitterRobotConfigEntry
|
|
from .entity import LitterRobotEntity, _WhiskerEntityT
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class RobotSwitchEntityDescription(SwitchEntityDescription, Generic[_WhiskerEntityT]):
|
|
"""A class that describes robot switch entities."""
|
|
|
|
entity_category: EntityCategory = EntityCategory.CONFIG
|
|
set_fn: Callable[[_WhiskerEntityT, bool], Coroutine[Any, Any, bool]]
|
|
value_fn: Callable[[_WhiskerEntityT], bool]
|
|
|
|
|
|
NIGHT_LIGHT_MODE_ENTITY_DESCRIPTION = RobotSwitchEntityDescription[
|
|
LitterRobot | FeederRobot
|
|
](
|
|
key="night_light_mode_enabled",
|
|
translation_key="night_light_mode",
|
|
set_fn=lambda robot, value: robot.set_night_light(value),
|
|
value_fn=lambda robot: robot.night_light_mode_enabled,
|
|
)
|
|
|
|
SWITCH_MAP: dict[type[Robot], tuple[RobotSwitchEntityDescription, ...]] = {
|
|
FeederRobot: (
|
|
RobotSwitchEntityDescription[FeederRobot](
|
|
key="gravity_mode",
|
|
translation_key="gravity_mode",
|
|
set_fn=lambda robot, value: robot.set_gravity_mode(value),
|
|
value_fn=lambda robot: robot.gravity_mode_enabled,
|
|
),
|
|
NIGHT_LIGHT_MODE_ENTITY_DESCRIPTION,
|
|
),
|
|
LitterRobot3: (NIGHT_LIGHT_MODE_ENTITY_DESCRIPTION,),
|
|
Robot: ( # type: ignore[type-abstract] # only used for isinstance check
|
|
RobotSwitchEntityDescription[LitterRobot | FeederRobot](
|
|
key="panel_lock_enabled",
|
|
translation_key="panel_lockout",
|
|
set_fn=lambda robot, value: robot.set_panel_lockout(value),
|
|
value_fn=lambda robot: robot.panel_lock_enabled,
|
|
),
|
|
),
|
|
}
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: LitterRobotConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up Litter-Robot switches using config entry."""
|
|
coordinator = entry.runtime_data
|
|
entities = [
|
|
RobotSwitchEntity(robot=robot, coordinator=coordinator, description=description)
|
|
for robot in coordinator.account.robots
|
|
for robot_type, entity_descriptions in SWITCH_MAP.items()
|
|
if isinstance(robot, robot_type)
|
|
for description in entity_descriptions
|
|
]
|
|
|
|
ent_reg = er.async_get(hass)
|
|
|
|
def add_deprecated_entity(
|
|
robot: LitterRobot4,
|
|
description: RobotSwitchEntityDescription,
|
|
entity_cls: type[RobotSwitchEntity],
|
|
) -> None:
|
|
"""Add deprecated entities."""
|
|
unique_id = f"{robot.serial}-{description.key}"
|
|
if entity_id := ent_reg.async_get_entity_id(SWITCH_DOMAIN, DOMAIN, unique_id):
|
|
entity_entry = ent_reg.async_get(entity_id)
|
|
if entity_entry and entity_entry.disabled:
|
|
ent_reg.async_remove(entity_id)
|
|
async_delete_issue(
|
|
hass,
|
|
DOMAIN,
|
|
f"deprecated_entity_{unique_id}",
|
|
)
|
|
elif entity_entry:
|
|
entities.append(entity_cls(robot, coordinator, description))
|
|
async_create_issue(
|
|
hass,
|
|
DOMAIN,
|
|
f"deprecated_entity_{unique_id}",
|
|
breaks_in_ha_version="2026.4.0",
|
|
is_fixable=False,
|
|
severity=IssueSeverity.WARNING,
|
|
translation_key="deprecated_entity",
|
|
translation_placeholders={
|
|
"name": f"{robot.name} {entity_entry.name or entity_entry.original_name}",
|
|
"entity": entity_id,
|
|
},
|
|
)
|
|
|
|
for robot in coordinator.account.get_robots(LitterRobot4):
|
|
add_deprecated_entity(
|
|
robot, NIGHT_LIGHT_MODE_ENTITY_DESCRIPTION, RobotSwitchEntity
|
|
)
|
|
|
|
async_add_entities(entities)
|
|
|
|
|
|
class RobotSwitchEntity(LitterRobotEntity[_WhiskerEntityT], SwitchEntity):
|
|
"""Litter-Robot switch entity."""
|
|
|
|
entity_description: RobotSwitchEntityDescription[_WhiskerEntityT]
|
|
|
|
@property
|
|
def is_on(self) -> bool | None:
|
|
"""Return true if switch is on."""
|
|
return self.entity_description.value_fn(self.robot)
|
|
|
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
|
"""Turn the switch on."""
|
|
await self.entity_description.set_fn(self.robot, True)
|
|
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the switch off."""
|
|
await self.entity_description.set_fn(self.robot, False)
|