diff --git a/homeassistant/components/teslemetry/entity.py b/homeassistant/components/teslemetry/entity.py index d2aa4a80238..9849306f771 100644 --- a/homeassistant/components/teslemetry/entity.py +++ b/homeassistant/components/teslemetry/entity.py @@ -74,10 +74,9 @@ class TeslemetryEntity( """Handle a command.""" try: result = await command - LOGGER.debug("Command result: %s", result) except TeslaFleetError as e: - LOGGER.debug("Command error: %s", e.message) raise HomeAssistantError(f"Teslemetry command failed, {e.message}") from e + LOGGER.debug("Command result: %s", result) return result def _handle_coordinator_update(self) -> None: @@ -137,21 +136,20 @@ class TeslemetryVehicleEntity(TeslemetryEntity): """Handle a vehicle command.""" result = await super().handle_command(command) if (response := result.get("response")) is None: - if message := result.get("error"): + if error := result.get("error"): # No response with error - LOGGER.info("Command failure: %s", message) - raise HomeAssistantError(message) + raise HomeAssistantError(error) # No response without error (unexpected) - LOGGER.error("Unknown response: %s", response) - raise HomeAssistantError("Unknown response") - if (message := response.get("result")) is not True: - if message := response.get("reason"): + raise HomeAssistantError(f"Unknown response: {response}") + if (result := response.get("result")) is not True: + if reason := response.get("reason"): + if reason in ("already_set", "not_charging", "requested"): + # Reason is acceptable + return result # Result of false with reason - LOGGER.info("Command failure: %s", message) - raise HomeAssistantError(message) + raise HomeAssistantError(reason) # Result of false without reason (unexpected) - LOGGER.error("Unknown response: %s", response) - raise HomeAssistantError("Unknown response") + raise HomeAssistantError("Command failed with no reason") # Response with result of true return result diff --git a/tests/components/teslemetry/const.py b/tests/components/teslemetry/const.py index e21921b5056..ffb349e4b7e 100644 --- a/tests/components/teslemetry/const.py +++ b/tests/components/teslemetry/const.py @@ -18,6 +18,7 @@ SITE_INFO = load_json_object_fixture("site_info.json", DOMAIN) COMMAND_OK = {"response": {"result": True, "reason": ""}} COMMAND_REASON = {"response": {"result": False, "reason": "already closed"}} +COMMAND_IGNORED_REASON = {"response": {"result": False, "reason": "already_set"}} COMMAND_NOREASON = {"response": {"result": False}} # Unexpected COMMAND_ERROR = { "response": None, diff --git a/tests/components/teslemetry/test_climate.py b/tests/components/teslemetry/test_climate.py index 76910aaab04..edb10872139 100644 --- a/tests/components/teslemetry/test_climate.py +++ b/tests/components/teslemetry/test_climate.py @@ -27,6 +27,7 @@ from homeassistant.helpers import entity_registry as er from . import assert_entities, setup_platform from .const import ( COMMAND_ERRORS, + COMMAND_IGNORED_REASON, METADATA_NOSCOPE, VEHICLE_DATA_ALT, WAKE_UP_ASLEEP, @@ -134,8 +135,7 @@ async def test_climate_offline( assert_entities(hass, entry.entry_id, entity_registry, snapshot) -@pytest.mark.parametrize("response", COMMAND_ERRORS) -async def test_errors(hass: HomeAssistant, response: str) -> None: +async def test_invalid_error(hass: HomeAssistant) -> None: """Tests service error is handled.""" await setup_platform(hass, platforms=[Platform.CLIMATE]) @@ -157,12 +157,20 @@ async def test_errors(hass: HomeAssistant, response: str) -> None: mock_on.assert_called_once() assert error.from_exception == InvalidCommand + +@pytest.mark.parametrize("response", COMMAND_ERRORS) +async def test_errors(hass: HomeAssistant, response: str) -> None: + """Tests service reason is handled.""" + + await setup_platform(hass, platforms=[Platform.CLIMATE]) + entity_id = "climate.test_climate" + with ( patch( "homeassistant.components.teslemetry.VehicleSpecific.auto_conditioning_start", return_value=response, ) as mock_on, - pytest.raises(HomeAssistantError) as error, + pytest.raises(HomeAssistantError), ): await hass.services.async_call( CLIMATE_DOMAIN, @@ -173,6 +181,26 @@ async def test_errors(hass: HomeAssistant, response: str) -> None: mock_on.assert_called_once() +async def test_ignored_error( + hass: HomeAssistant, +) -> None: + """Tests ignored error is handled.""" + + await setup_platform(hass, [Platform.CLIMATE]) + entity_id = "climate.test_climate" + with patch( + "homeassistant.components.teslemetry.VehicleSpecific.auto_conditioning_start", + return_value=COMMAND_IGNORED_REASON, + ) as mock_on: + await hass.services.async_call( + CLIMATE_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: [entity_id]}, + blocking=True, + ) + mock_on.assert_called_once() + + async def test_asleep_or_offline( hass: HomeAssistant, mock_vehicle_data,