diff --git a/homeassistant/components/sensibo/climate.py b/homeassistant/components/sensibo/climate.py index 4ff63a25455..da86ba8fe24 100644 --- a/homeassistant/components/sensibo/climate.py +++ b/homeassistant/components/sensibo/climate.py @@ -54,6 +54,22 @@ ATTR_HORIZONTAL_SWING_MODE = "horizontal_swing_mode" ATTR_LIGHT = "light" BOOST_INCLUSIVE = "boost_inclusive" +AVAILABLE_FAN_MODES = {"quiet", "low", "medium", "medium_high", "high", "auto"} +AVAILABLE_SWING_MODES = { + "stopped", + "fixedtop", + "fixedmiddletop", + "fixedmiddle", + "fixedmiddlebottom", + "fixedbottom", + "rangetop", + "rangemiddle", + "rangebottom", + "rangefull", + "horizontal", + "both", +} + PARALLEL_UPDATES = 0 FIELD_TO_FLAG = { @@ -178,6 +194,7 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity): ) self._attr_supported_features = self.get_features() self._attr_precision = PRECISION_TENTHS + self._attr_translation_key = "climate_device" def get_features(self) -> ClimateEntityFeature: """Get supported features.""" @@ -309,6 +326,10 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity): """Set new target fan mode.""" if "fanLevel" not in self.device_data.active_features: raise HomeAssistantError("Current mode doesn't support setting Fanlevel") + if fan_mode not in AVAILABLE_FAN_MODES: + raise HomeAssistantError( + f"Climate fan mode {fan_mode} is not supported by the integration, please open an issue" + ) transformation = self.device_data.fan_modes_translated await self.async_send_api_call( @@ -350,6 +371,10 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity): """Set new target swing operation.""" if "swing" not in self.device_data.active_features: raise HomeAssistantError("Current mode doesn't support setting Swing") + if swing_mode not in AVAILABLE_SWING_MODES: + raise HomeAssistantError( + f"Climate swing mode {swing_mode} is not supported by the integration, please open an issue" + ) transformation = self.device_data.swing_modes_translated await self.async_send_api_call( diff --git a/homeassistant/components/sensibo/strings.json b/homeassistant/components/sensibo/strings.json index 38ae94d4fa3..a6f14b73ace 100644 --- a/homeassistant/components/sensibo/strings.json +++ b/homeassistant/components/sensibo/strings.json @@ -79,7 +79,9 @@ "fixedright": "Fixed right", "fixedleftright": "Fixed left right", "rangecenter": "Range center", - "rangefull": "Range full" + "rangefull": "Range full", + "rangeleft": "Range left", + "rangeright": "Range right" } }, "light": { @@ -338,6 +340,38 @@ "fw_ver_available": { "name": "Update available" } + }, + "climate": { + "climate_device": { + "state_attributes": { + "fan_mode": { + "state": { + "quiet": "Quiet", + "low": "[%key:component::climate::entity_component::_::state_attributes::fan_mode::state::low%]", + "medium": "[%key:component::climate::entity_component::_::state_attributes::fan_mode::state::medium%]", + "medium_high": "Medium high", + "high": "[%key:component::climate::entity_component::_::state_attributes::fan_mode::state::high%]", + "auto": "[%key:component::climate::entity_component::_::state_attributes::fan_mode::state::auto%]" + } + }, + "swing_mode": { + "state": { + "stopped": "[%key:common::state::off%]", + "fixedtop": "Fixed top", + "fixedmiddletop": "Fixed middle top", + "fixedmiddle": "Fixed middle", + "fixedmiddlebottom": "Fixed middle bottom", + "fixedbottom": "Fixed bottom", + "rangetop": "Range top", + "rangemiddle": "Range middle", + "rangebottom": "Range bottom", + "rangefull": "[%key:component::sensibo::entity::select::horizontalswing::state::rangefull%]", + "horizontal": "Horizontal", + "both": "[%key:component::climate::entity_component::_::state_attributes::swing_mode::state::both%]" + } + } + } + } } }, "services": { diff --git a/tests/components/sensibo/test_climate.py b/tests/components/sensibo/test_climate.py index 56a7a8c902c..688a373b8f0 100644 --- a/tests/components/sensibo/test_climate.py +++ b/tests/components/sensibo/test_climate.py @@ -101,11 +101,7 @@ async def test_climate( "max_temp": 20, "target_temp_step": 1, "fan_modes": ["low", "medium", "quiet"], - "swing_modes": [ - "fixedmiddletop", - "fixedtop", - "stopped", - ], + "swing_modes": ["fixedmiddletop", "fixedtop", "stopped"], "current_temperature": 21.2, "temperature": 25, "current_humidity": 32.9, @@ -1336,3 +1332,56 @@ async def test_climate_full_ac_state( assert state.state == "cool" assert state.attributes["temperature"] == 22 + + +async def test_climate_fan_mode_and_swing_mode_not_supported( + hass: HomeAssistant, + load_int: ConfigEntry, + monkeypatch: pytest.MonkeyPatch, + get_data: SensiboData, +) -> None: + """Test the Sensibo climate fan_mode and swing_mode not supported is raising error.""" + + state1 = hass.states.get("climate.hallway") + assert state1.attributes["fan_mode"] == "high" + assert state1.attributes["swing_mode"] == "stopped" + + with patch( + "homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property", + ), pytest.raises( + HomeAssistantError, + match="Climate swing mode faulty_swing_mode is not supported by the integration, please open an issue", + ): + await hass.services.async_call( + CLIMATE_DOMAIN, + SERVICE_SET_SWING_MODE, + {ATTR_ENTITY_ID: state1.entity_id, ATTR_SWING_MODE: "faulty_swing_mode"}, + blocking=True, + ) + + with patch( + "homeassistant.components.sensibo.util.SensiboClient.async_set_ac_state_property", + ), pytest.raises( + HomeAssistantError, + match="Climate fan mode faulty_fan_mode is not supported by the integration, please open an issue", + ): + await hass.services.async_call( + CLIMATE_DOMAIN, + SERVICE_SET_FAN_MODE, + {ATTR_ENTITY_ID: state1.entity_id, ATTR_FAN_MODE: "faulty_fan_mode"}, + blocking=True, + ) + + with patch( + "homeassistant.components.sensibo.coordinator.SensiboClient.async_get_devices_data", + return_value=get_data, + ): + async_fire_time_changed( + hass, + dt_util.utcnow() + timedelta(minutes=5), + ) + await hass.async_block_till_done() + + state2 = hass.states.get("climate.hallway") + assert state2.attributes["fan_mode"] == "high" + assert state2.attributes["swing_mode"] == "stopped"