diff --git a/homeassistant/components/litterrobot/__init__.py b/homeassistant/components/litterrobot/__init__.py index 04a98a5bf608be62ddc5a495149e989679d8f7bd..17bef9a23a8df7b635c3d4c67feb012c6dde24ea 100644 --- a/homeassistant/components/litterrobot/__init__.py +++ b/homeassistant/components/litterrobot/__init__.py @@ -9,7 +9,7 @@ from homeassistant.exceptions import ConfigEntryNotReady from .const import DOMAIN from .hub import LitterRobotHub -PLATFORMS = ["sensor", "switch", "vacuum"] +PLATFORMS = ["select", "sensor", "switch", "vacuum"] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/litterrobot/select.py b/homeassistant/components/litterrobot/select.py new file mode 100644 index 0000000000000000000000000000000000000000..6dfb44e97f64e66f45ddda7dd4c1c0dabe566d40 --- /dev/null +++ b/homeassistant/components/litterrobot/select.py @@ -0,0 +1,53 @@ +"""Support for Litter-Robot selects.""" +from __future__ import annotations + +from pylitterbot.robot import VALID_WAIT_TIMES + +from homeassistant.components.select import SelectEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN +from .entity import LitterRobotControlEntity +from .hub import LitterRobotHub + +TYPE_CLEAN_CYCLE_WAIT_TIME_MINUTES = "Clean Cycle Wait Time Minutes" + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up Litter-Robot selects using config entry.""" + hub: LitterRobotHub = hass.data[DOMAIN][config_entry.entry_id] + + entities = [ + LitterRobotSelect( + robot=robot, entity_type=TYPE_CLEAN_CYCLE_WAIT_TIME_MINUTES, hub=hub + ) + for robot in hub.account.robots + ] + + async_add_entities(entities) + + +class LitterRobotSelect(LitterRobotControlEntity, SelectEntity): + """Litter-Robot Select.""" + + _attr_icon = "mdi:timer-outline" + + @property + def current_option(self) -> str | None: + """Return the selected entity option to represent the entity state.""" + return str(self.robot.clean_cycle_wait_time_minutes) + + @property + def options(self) -> list[str]: + """Return a set of selectable options.""" + return [str(minute) for minute in VALID_WAIT_TIMES] + + async def async_select_option(self, option: str) -> None: + """Change the selected option.""" + await self.perform_action_and_refresh(self.robot.set_wait_time, int(option)) diff --git a/tests/components/litterrobot/test_select.py b/tests/components/litterrobot/test_select.py new file mode 100644 index 0000000000000000000000000000000000000000..c0c436764af279177b87593a10b0aea17ae8ad2d --- /dev/null +++ b/tests/components/litterrobot/test_select.py @@ -0,0 +1,66 @@ +"""Test the Litter-Robot select entity.""" +from datetime import timedelta + +from pylitterbot.robot import VALID_WAIT_TIMES +import pytest + +from homeassistant.components.litterrobot.entity import REFRESH_WAIT_TIME_SECONDS +from homeassistant.components.select import ( + ATTR_OPTION, + DOMAIN as PLATFORM_DOMAIN, + SERVICE_SELECT_OPTION, +) +from homeassistant.const import ATTR_ENTITY_ID +from homeassistant.core import HomeAssistant +from homeassistant.util.dt import utcnow + +from .conftest import setup_integration + +from tests.common import async_fire_time_changed + +SELECT_ENTITY_ID = "select.test_clean_cycle_wait_time_minutes" + + +async def test_wait_time_select(hass: HomeAssistant, mock_account): + """Tests the wait time select entity.""" + await setup_integration(hass, mock_account, PLATFORM_DOMAIN) + + select = hass.states.get(SELECT_ENTITY_ID) + assert select + + data = {ATTR_ENTITY_ID: SELECT_ENTITY_ID} + + count = 0 + for wait_time in VALID_WAIT_TIMES: + count += 1 + data[ATTR_OPTION] = wait_time + + await hass.services.async_call( + PLATFORM_DOMAIN, + SERVICE_SELECT_OPTION, + data, + blocking=True, + ) + + future = utcnow() + timedelta(seconds=REFRESH_WAIT_TIME_SECONDS) + async_fire_time_changed(hass, future) + assert mock_account.robots[0].set_wait_time.call_count == count + + +async def test_invalid_wait_time_select(hass: HomeAssistant, mock_account): + """Tests the wait time select entity with invalid value.""" + await setup_integration(hass, mock_account, PLATFORM_DOMAIN) + + select = hass.states.get(SELECT_ENTITY_ID) + assert select + + data = {ATTR_ENTITY_ID: SELECT_ENTITY_ID, ATTR_OPTION: "10"} + + with pytest.raises(ValueError): + await hass.services.async_call( + PLATFORM_DOMAIN, + SERVICE_SELECT_OPTION, + data, + blocking=True, + ) + assert not mock_account.robots[0].set_wait_time.called