diff --git a/homeassistant/components/litterrobot/button.py b/homeassistant/components/litterrobot/button.py index 5cb65596ec6..7c7990edf07 100644 --- a/homeassistant/components/litterrobot/button.py +++ b/homeassistant/components/litterrobot/button.py @@ -35,6 +35,7 @@ async def async_setup_entry( class LitterRobotResetWasteDrawerButton(LitterRobotEntity, ButtonEntity): """Litter-Robot reset waste drawer button.""" + robot: LitterRobot3 _attr_icon = "mdi:delete-variant" _attr_entity_category = EntityCategory.CONFIG diff --git a/homeassistant/components/litterrobot/entity.py b/homeassistant/components/litterrobot/entity.py index b169e075455..c81e4ea4c79 100644 --- a/homeassistant/components/litterrobot/entity.py +++ b/homeassistant/components/litterrobot/entity.py @@ -6,7 +6,7 @@ from datetime import time import logging from typing import Any -from pylitterbot import LitterRobot +from pylitterbot import LitterRobot, Robot from pylitterbot.exceptions import InvalidCommandException from typing_extensions import ParamSpec @@ -23,7 +23,6 @@ from .const import DOMAIN from .hub import LitterRobotHub _P = ParamSpec("_P") - _LOGGER = logging.getLogger(__name__) REFRESH_WAIT_TIME_SECONDS = 8 @@ -32,9 +31,7 @@ REFRESH_WAIT_TIME_SECONDS = 8 class LitterRobotEntity(CoordinatorEntity[DataUpdateCoordinator[bool]]): """Generic Litter-Robot entity representing common data and methods.""" - def __init__( - self, robot: LitterRobot, entity_type: str, hub: LitterRobotHub - ) -> None: + def __init__(self, robot: Robot, entity_type: str, hub: LitterRobotHub) -> None: """Pass coordinator to CoordinatorEntity.""" super().__init__(hub.coordinator) self.robot = robot @@ -60,15 +57,16 @@ class LitterRobotEntity(CoordinatorEntity[DataUpdateCoordinator[bool]]): manufacturer="Litter-Robot", model=self.robot.model, name=self.robot.name, + sw_version=getattr(self.robot, "firmware", None), ) class LitterRobotControlEntity(LitterRobotEntity): """A Litter-Robot entity that can control the unit.""" - def __init__( - self, robot: LitterRobot, entity_type: str, hub: LitterRobotHub - ) -> None: + robot: LitterRobot + + def __init__(self, robot: Robot, entity_type: str, hub: LitterRobotHub) -> None: """Init a Litter-Robot control entity.""" super().__init__(robot=robot, entity_type=entity_type, hub=hub) self._refresh_callback: CALLBACK_TYPE | None = None @@ -135,11 +133,10 @@ class LitterRobotControlEntity(LitterRobotEntity): class LitterRobotConfigEntity(LitterRobotControlEntity): """A Litter-Robot entity that can control configuration of the unit.""" + robot: LitterRobot _attr_entity_category = EntityCategory.CONFIG - def __init__( - self, robot: LitterRobot, entity_type: str, hub: LitterRobotHub - ) -> None: + def __init__(self, robot: Robot, entity_type: str, hub: LitterRobotHub) -> None: """Init a Litter-Robot control entity.""" super().__init__(robot=robot, entity_type=entity_type, hub=hub) self._assumed_state: bool | None = None diff --git a/homeassistant/components/litterrobot/hub.py b/homeassistant/components/litterrobot/hub.py index 627075208cc..8fab3346cec 100644 --- a/homeassistant/components/litterrobot/hub.py +++ b/homeassistant/components/litterrobot/hub.py @@ -6,7 +6,7 @@ from datetime import timedelta import logging from typing import Any -from pylitterbot import Account, LitterRobot +from pylitterbot import Account, FeederRobot, LitterRobot from pylitterbot.exceptions import LitterRobotException, LitterRobotLoginException from homeassistant.const import CONF_PASSWORD, CONF_USERNAME @@ -62,3 +62,9 @@ class LitterRobotHub: return ( robot for robot in self.account.robots if isinstance(robot, LitterRobot) ) + + def feeder_robots(self) -> Generator[FeederRobot, Any, Any]: + """Get Feeder-Robots from the account.""" + return ( + robot for robot in self.account.robots if isinstance(robot, FeederRobot) + ) diff --git a/homeassistant/components/litterrobot/sensor.py b/homeassistant/components/litterrobot/sensor.py index 53ed3605c68..5f6579e83c5 100644 --- a/homeassistant/components/litterrobot/sensor.py +++ b/homeassistant/components/litterrobot/sensor.py @@ -6,7 +6,7 @@ from dataclasses import dataclass from datetime import datetime from typing import Any, Union, cast -from pylitterbot import LitterRobot +from pylitterbot import FeederRobot, LitterRobot, Robot from homeassistant.components.sensor import ( SensorDeviceClass, @@ -36,23 +36,30 @@ def icon_for_gauge_level(gauge_level: int | None = None, offset: int = 0) -> str @dataclass -class LitterRobotSensorEntityDescription(SensorEntityDescription): - """A class that describes Litter-Robot sensor entities.""" +class RobotSensorEntityDescription(SensorEntityDescription): + """A class that describes robot sensor entities.""" icon_fn: Callable[[Any], str | None] = lambda _: None + should_report: Callable[[Robot], bool] = lambda _: True + + +@dataclass +class LitterRobotSensorEntityDescription(RobotSensorEntityDescription): + """A class that describes Litter-Robot sensor entities.""" + should_report: Callable[[LitterRobot], bool] = lambda _: True class LitterRobotSensorEntity(LitterRobotEntity, SensorEntity): """Litter-Robot sensor entity.""" - entity_description: LitterRobotSensorEntityDescription + entity_description: RobotSensorEntityDescription def __init__( self, - robot: LitterRobot, + robot: LitterRobot | FeederRobot, hub: LitterRobotHub, - description: LitterRobotSensorEntityDescription, + description: RobotSensorEntityDescription, ) -> None: """Initialize a Litter-Robot sensor entity.""" assert description.name @@ -76,7 +83,7 @@ class LitterRobotSensorEntity(LitterRobotEntity, SensorEntity): return super().icon -ROBOT_SENSORS = [ +LITTER_ROBOT_SENSORS = [ LitterRobotSensorEntityDescription( name="Waste Drawer", key="waste_drawer_level", @@ -109,6 +116,13 @@ ROBOT_SENSORS = [ ), ] +FEEDER_ROBOT_SENSOR = RobotSensorEntityDescription( + name="Food Level", + key="food_level", + native_unit_of_measurement=PERCENTAGE, + icon_fn=lambda state: icon_for_gauge_level(state, 10), +) + async def async_setup_entry( hass: HomeAssistant, @@ -118,7 +132,15 @@ async def async_setup_entry( """Set up Litter-Robot sensors using config entry.""" hub: LitterRobotHub = hass.data[DOMAIN][entry.entry_id] async_add_entities( - LitterRobotSensorEntity(robot=robot, hub=hub, description=description) - for description in ROBOT_SENSORS - for robot in hub.litter_robots() + [ + LitterRobotSensorEntity(robot=robot, hub=hub, description=description) + for description in LITTER_ROBOT_SENSORS + for robot in hub.litter_robots() + ] + + [ + LitterRobotSensorEntity( + robot=robot, hub=hub, description=FEEDER_ROBOT_SENSOR + ) + for robot in hub.feeder_robots() + ] )