diff --git a/homeassistant/components/litterrobot/strings.json b/homeassistant/components/litterrobot/strings.json index 7acfad69735..85d75e13dd2 100644 --- a/homeassistant/components/litterrobot/strings.json +++ b/homeassistant/components/litterrobot/strings.json @@ -25,6 +25,30 @@ "reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]" } }, + "issues": { + "service_deprecation_turn_off": { + "title": "Litter-Robot vaccum support for {old_service} is being removed", + "fix_flow": { + "step": { + "confirm": { + "title": "[%key:component::litterrobot::issues::service_deprecation_turn_off::title%]", + "description": "Litter-Robot vaccum support for the {old_service} service is deprecated and will be removed in Home Assistant 2024.2; Please adjust any automation or script that uses the service to instead call {new_service} and select submit below to mark this issue as resolved." + } + } + } + }, + "service_deprecation_turn_on": { + "title": "[%key:component::litterrobot::issues::service_deprecation_turn_off::title%]", + "fix_flow": { + "step": { + "confirm": { + "title": "[%key:component::litterrobot::issues::service_deprecation_turn_off::title%]", + "description": "[%key:component::litterrobot::issues::service_deprecation_turn_off::fix_flow::step::confirm::description%]" + } + } + } + } + }, "entity": { "binary_sensor": { "sleeping": { diff --git a/homeassistant/components/litterrobot/vacuum.py b/homeassistant/components/litterrobot/vacuum.py index d1352c1e45f..4b1a8effb98 100644 --- a/homeassistant/components/litterrobot/vacuum.py +++ b/homeassistant/components/litterrobot/vacuum.py @@ -20,7 +20,11 @@ from homeassistant.components.vacuum import ( from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF from homeassistant.core import HomeAssistant -from homeassistant.helpers import config_validation as cv, entity_platform +from homeassistant.helpers import ( + config_validation as cv, + entity_platform, + issue_registry as ir, +) from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.util.dt as dt_util @@ -77,7 +81,7 @@ class LitterRobotCleaner(LitterRobotEntity[LitterRobot], StateVacuumEntity): _attr_supported_features = ( VacuumEntityFeature.START | VacuumEntityFeature.STATE - | VacuumEntityFeature.STATUS + | VacuumEntityFeature.STOP | VacuumEntityFeature.TURN_OFF | VacuumEntityFeature.TURN_ON ) @@ -97,15 +101,48 @@ class LitterRobotCleaner(LitterRobotEntity[LitterRobot], StateVacuumEntity): async def async_turn_on(self, **kwargs: Any) -> None: """Turn the cleaner on, starting a clean cycle.""" await self.robot.set_power_status(True) + ir.async_create_issue( + self.hass, + DOMAIN, + "service_deprecation_turn_on", + breaks_in_ha_version="2024.2.0", + is_fixable=True, + is_persistent=True, + severity=ir.IssueSeverity.WARNING, + translation_key="service_deprecation_turn_on", + translation_placeholders={ + "old_service": "vacuum.turn_on", + "new_service": "vacuum.start", + }, + ) async def async_turn_off(self, **kwargs: Any) -> None: """Turn the unit off, stopping any cleaning in progress as is.""" await self.robot.set_power_status(False) + ir.async_create_issue( + self.hass, + DOMAIN, + "service_deprecation_turn_off", + breaks_in_ha_version="2024.2.0", + is_fixable=True, + is_persistent=True, + severity=ir.IssueSeverity.WARNING, + translation_key="service_deprecation_turn_off", + translation_placeholders={ + "old_service": "vacuum.turn_off", + "new_service": "vacuum.stop", + }, + ) async def async_start(self) -> None: """Start a clean cycle.""" + await self.robot.set_power_status(True) await self.robot.start_cleaning() + async def async_stop(self, **kwargs: Any) -> None: + """Stop the vacuum cleaner.""" + await self.robot.set_power_status(False) + async def async_set_sleep_mode( self, enabled: bool, start_time: str | None = None ) -> None: diff --git a/tests/components/litterrobot/test_vacuum.py b/tests/components/litterrobot/test_vacuum.py index 655f58fa94f..3aee7b5075f 100644 --- a/tests/components/litterrobot/test_vacuum.py +++ b/tests/components/litterrobot/test_vacuum.py @@ -12,6 +12,7 @@ from homeassistant.components.vacuum import ( ATTR_STATUS, DOMAIN as PLATFORM_DOMAIN, SERVICE_START, + SERVICE_STOP, SERVICE_TURN_OFF, SERVICE_TURN_ON, STATE_DOCKED, @@ -19,7 +20,7 @@ from homeassistant.components.vacuum import ( ) from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant -import homeassistant.helpers.entity_registry as er +from homeassistant.helpers import entity_registry as er, issue_registry as ir from .common import VACUUM_ENTITY_ID from .conftest import setup_integration @@ -98,8 +99,17 @@ async def test_vacuum_with_error( ("service", "command", "extra"), [ (SERVICE_START, "start_cleaning", None), - (SERVICE_TURN_OFF, "set_power_status", None), - (SERVICE_TURN_ON, "set_power_status", None), + (SERVICE_STOP, "set_power_status", None), + ( + SERVICE_TURN_OFF, + "set_power_status", + {"issues": {(DOMAIN, "service_deprecation_turn_off")}}, + ), + ( + SERVICE_TURN_ON, + "set_power_status", + {"issues": {(DOMAIN, "service_deprecation_turn_on")}}, + ), ( SERVICE_SET_SLEEP_MODE, "set_sleep_mode", @@ -126,7 +136,7 @@ async def test_commands( extra = extra or {} data = {ATTR_ENTITY_ID: VACUUM_ENTITY_ID, **extra.get("data", {})} - deprecated = extra.get("deprecated", False) + issues = extra.get("issues", set()) await hass.services.async_call( COMPONENT_SERVICE_DOMAIN.get(service, PLATFORM_DOMAIN), @@ -135,4 +145,56 @@ async def test_commands( blocking=True, ) getattr(mock_account.robots[0], command).assert_called_once() - assert (f"'{DOMAIN}.{service}' service is deprecated" in caplog.text) is deprecated + + issue_registry = ir.async_get(hass) + assert set(issue_registry.issues.keys()) == issues + + +@pytest.mark.parametrize( + ("service", "issue_id", "placeholders"), + [ + ( + SERVICE_TURN_OFF, + "service_deprecation_turn_off", + { + "old_service": "vacuum.turn_off", + "new_service": "vacuum.stop", + }, + ), + ( + SERVICE_TURN_ON, + "service_deprecation_turn_on", + { + "old_service": "vacuum.turn_on", + "new_service": "vacuum.start", + }, + ), + ], +) +async def test_issues( + hass: HomeAssistant, + mock_account: MagicMock, + caplog: pytest.LogCaptureFixture, + service: str, + issue_id: str, + placeholders: dict[str, str], +) -> None: + """Test issues raised by calling deprecated services.""" + await setup_integration(hass, mock_account, PLATFORM_DOMAIN) + + vacuum = hass.states.get(VACUUM_ENTITY_ID) + assert vacuum + assert vacuum.state == STATE_DOCKED + + await hass.services.async_call( + PLATFORM_DOMAIN, + service, + {ATTR_ENTITY_ID: VACUUM_ENTITY_ID}, + blocking=True, + ) + + issue_registry = ir.async_get(hass) + issue = issue_registry.async_get_issue(DOMAIN, issue_id) + assert issue.is_fixable is True + assert issue.is_persistent is True + assert issue.translation_placeholders == placeholders