Reflect unavailable state when litter robot hasn't been seen recently (#70810)

This commit is contained in:
Nathan Spencer 2022-04-30 03:43:13 -06:00 committed by GitHub
parent 5e3740d5ed
commit 1ede67e51f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 14 deletions

View File

@ -1,6 +1,7 @@
"""Support for Litter-Robot "Vacuum"."""
from __future__ import annotations
from datetime import datetime, timedelta, timezone
import logging
from typing import Any
@ -17,7 +18,7 @@ from homeassistant.components.vacuum import (
VacuumEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_OFF
from homeassistant.const import STATE_OFF, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -34,6 +35,19 @@ SERVICE_RESET_WASTE_DRAWER = "reset_waste_drawer"
SERVICE_SET_SLEEP_MODE = "set_sleep_mode"
SERVICE_SET_WAIT_TIME = "set_wait_time"
LITTER_BOX_STATUS_STATE_MAP = {
LitterBoxStatus.CLEAN_CYCLE: STATE_CLEANING,
LitterBoxStatus.EMPTY_CYCLE: STATE_CLEANING,
LitterBoxStatus.CLEAN_CYCLE_COMPLETE: STATE_DOCKED,
LitterBoxStatus.CAT_SENSOR_TIMING: STATE_DOCKED,
LitterBoxStatus.DRAWER_FULL_1: STATE_DOCKED,
LitterBoxStatus.DRAWER_FULL_2: STATE_DOCKED,
LitterBoxStatus.READY: STATE_DOCKED,
LitterBoxStatus.CAT_SENSOR_INTERRUPTED: STATE_PAUSED,
LitterBoxStatus.OFF: STATE_OFF,
}
UNAVAILABLE_AFTER = timedelta(minutes=30)
async def async_setup_entry(
hass: HomeAssistant,
@ -85,19 +99,10 @@ class LitterRobotCleaner(LitterRobotControlEntity, StateVacuumEntity):
@property
def state(self) -> str:
"""Return the state of the cleaner."""
switcher = {
LitterBoxStatus.CLEAN_CYCLE: STATE_CLEANING,
LitterBoxStatus.EMPTY_CYCLE: STATE_CLEANING,
LitterBoxStatus.CLEAN_CYCLE_COMPLETE: STATE_DOCKED,
LitterBoxStatus.CAT_SENSOR_TIMING: STATE_DOCKED,
LitterBoxStatus.DRAWER_FULL_1: STATE_DOCKED,
LitterBoxStatus.DRAWER_FULL_2: STATE_DOCKED,
LitterBoxStatus.READY: STATE_DOCKED,
LitterBoxStatus.CAT_SENSOR_INTERRUPTED: STATE_PAUSED,
LitterBoxStatus.OFF: STATE_OFF,
}
if self.robot.last_seen < datetime.now(timezone.utc) - UNAVAILABLE_AFTER:
return STATE_UNAVAILABLE
return switcher.get(self.robot.status, STATE_ERROR)
return LITTER_BOX_STATUS_STATE_MAP.get(self.robot.status, STATE_ERROR)
@property
def status(self) -> str:

View File

@ -1,6 +1,7 @@
"""Configure pytest for Litter-Robot tests."""
from __future__ import annotations
from datetime import datetime
from typing import Any
from unittest.mock import AsyncMock, MagicMock, patch
@ -9,6 +10,7 @@ from pylitterbot.exceptions import InvalidCommandException
import pytest
from homeassistant.components import litterrobot
from homeassistant.components.litterrobot.vacuum import UNAVAILABLE_AFTER
from homeassistant.core import HomeAssistant
from .common import CONFIG, ROBOT_DATA
@ -65,6 +67,14 @@ def mock_account_with_sleeping_robot() -> MagicMock:
return create_mock_account({"sleepModeActive": "102:00:00"})
@pytest.fixture
def mock_account_with_robot_not_recently_seen() -> MagicMock:
"""Mock a Litter-Robot account with a sleeping robot."""
return create_mock_account(
{"lastSeen": (datetime.now() - UNAVAILABLE_AFTER).isoformat()}
)
@pytest.fixture
def mock_account_with_error() -> MagicMock:
"""Mock a Litter-Robot account with error."""

View File

@ -24,7 +24,7 @@ from homeassistant.components.vacuum import (
STATE_DOCKED,
STATE_ERROR,
)
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.util.dt import utcnow
@ -62,6 +62,19 @@ async def test_vacuum_status_when_sleeping(
assert vacuum.attributes.get(ATTR_STATUS) == "Ready (Sleeping)"
async def test_vacuum_state_when_not_recently_seen(
hass: HomeAssistant, mock_account_with_robot_not_recently_seen: MagicMock
) -> None:
"""Tests the vacuum state when not seen recently."""
await setup_integration(
hass, mock_account_with_robot_not_recently_seen, PLATFORM_DOMAIN
)
vacuum = hass.states.get(VACUUM_ENTITY_ID)
assert vacuum
assert vacuum.state == STATE_UNAVAILABLE
async def test_no_robots(
hass: HomeAssistant, mock_account_with_no_robots: MagicMock
) -> None: