diff --git a/homeassistant/components/fibaro/climate.py b/homeassistant/components/fibaro/climate.py index 2541781773c..d5605e71c73 100644 --- a/homeassistant/components/fibaro/climate.py +++ b/homeassistant/components/fibaro/climate.py @@ -272,7 +272,9 @@ class FibaroThermostat(FibaroEntity, ClimateEntity): if isinstance(fibaro_operation_mode, str): with suppress(ValueError): return HVACMode(fibaro_operation_mode.lower()) - elif fibaro_operation_mode in OPMODES_HVAC: + # when the mode cannot be instantiated a preset_mode is selected + return HVACMode.AUTO + if fibaro_operation_mode in OPMODES_HVAC: return OPMODES_HVAC[fibaro_operation_mode] return None @@ -280,8 +282,6 @@ class FibaroThermostat(FibaroEntity, ClimateEntity): """Set new target operation mode.""" if not self._op_mode_device: return - if self.preset_mode: - return if "setOperatingMode" in self._op_mode_device.fibaro_device.actions: self._op_mode_device.action("setOperatingMode", HA_OPMODES_HVAC[hvac_mode]) diff --git a/tests/components/fibaro/conftest.py b/tests/components/fibaro/conftest.py index 1976a8f310b..583c44a41e6 100644 --- a/tests/components/fibaro/conftest.py +++ b/tests/components/fibaro/conftest.py @@ -129,6 +129,62 @@ def mock_light() -> Mock: return light +@pytest.fixture +def mock_thermostat() -> Mock: + """Fixture for a thermostat.""" + climate = Mock() + climate.fibaro_id = 4 + climate.parent_fibaro_id = 0 + climate.name = "Test climate" + climate.room_id = 1 + climate.dead = False + climate.visible = True + climate.enabled = True + climate.type = "com.fibaro.thermostatDanfoss" + climate.base_type = "com.fibaro.device" + climate.properties = {"manufacturer": ""} + climate.actions = {"setThermostatMode": 1} + climate.supported_features = {} + climate.has_supported_thermostat_modes = True + climate.supported_thermostat_modes = ["Off", "Heat", "CustomerSpecific"] + climate.has_operating_mode = False + climate.has_thermostat_mode = True + climate.thermostat_mode = "CustomerSpecific" + value_mock = Mock() + value_mock.has_value = True + value_mock.int_value.return_value = 20 + climate.value = value_mock + return climate + + +@pytest.fixture +def mock_thermostat_with_operating_mode() -> Mock: + """Fixture for a thermostat.""" + climate = Mock() + climate.fibaro_id = 4 + climate.parent_fibaro_id = 0 + climate.name = "Test climate" + climate.room_id = 1 + climate.dead = False + climate.visible = True + climate.enabled = True + climate.type = "com.fibaro.thermostatDanfoss" + climate.base_type = "com.fibaro.device" + climate.properties = {"manufacturer": ""} + climate.actions = {"setOperationMode": 1} + climate.supported_features = {} + climate.has_supported_operating_modes = True + climate.supported_operating_modes = [0, 1, 15] + climate.has_operating_mode = True + climate.operating_mode = 15 + climate.has_thermostat_mode = False + value_mock = Mock() + value_mock.has_value = True + value_mock.int_value.return_value = 20 + climate.value = value_mock + return climate + + @pytest.fixture def mock_config_entry(hass: HomeAssistant) -> MockConfigEntry: """Return the default mocked config entry.""" diff --git a/tests/components/fibaro/test_climate.py b/tests/components/fibaro/test_climate.py new file mode 100644 index 00000000000..31022e19a08 --- /dev/null +++ b/tests/components/fibaro/test_climate.py @@ -0,0 +1,134 @@ +"""Test the Fibaro climate platform.""" + +from unittest.mock import Mock, patch + +from homeassistant.components.climate import ClimateEntityFeature, HVACMode +from homeassistant.const import Platform +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from .conftest import init_integration + +from tests.common import MockConfigEntry + + +async def test_climate_setup( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + mock_fibaro_client: Mock, + mock_config_entry: MockConfigEntry, + mock_thermostat: Mock, + mock_room: Mock, +) -> None: + """Test that the climate creates an entity.""" + + # Arrange + mock_fibaro_client.read_rooms.return_value = [mock_room] + mock_fibaro_client.read_devices.return_value = [mock_thermostat] + + with patch("homeassistant.components.fibaro.PLATFORMS", [Platform.CLIMATE]): + # Act + await init_integration(hass, mock_config_entry) + # Assert + entry = entity_registry.async_get("climate.room_1_test_climate_4") + assert entry + assert entry.unique_id == "hc2_111111.4" + assert entry.original_name == "Room 1 Test climate" + assert entry.supported_features == ( + ClimateEntityFeature.TURN_ON + | ClimateEntityFeature.TURN_OFF + | ClimateEntityFeature.PRESET_MODE + ) + + +async def test_hvac_mode_preset( + hass: HomeAssistant, + mock_fibaro_client: Mock, + mock_config_entry: MockConfigEntry, + mock_thermostat: Mock, + mock_room: Mock, +) -> None: + """Test that the climate state is auto when a preset is selected.""" + + # Arrange + mock_fibaro_client.read_rooms.return_value = [mock_room] + mock_fibaro_client.read_devices.return_value = [mock_thermostat] + + with patch("homeassistant.components.fibaro.PLATFORMS", [Platform.CLIMATE]): + # Act + await init_integration(hass, mock_config_entry) + # Assert + state = hass.states.get("climate.room_1_test_climate_4") + assert state.state == HVACMode.AUTO + assert state.attributes["preset_mode"] == "CustomerSpecific" + + +async def test_hvac_mode_heat( + hass: HomeAssistant, + mock_fibaro_client: Mock, + mock_config_entry: MockConfigEntry, + mock_thermostat: Mock, + mock_room: Mock, +) -> None: + """Test that the preset mode is None if a hvac mode is active.""" + + # Arrange + mock_thermostat.thermostat_mode = "Heat" + mock_fibaro_client.read_rooms.return_value = [mock_room] + mock_fibaro_client.read_devices.return_value = [mock_thermostat] + + with patch("homeassistant.components.fibaro.PLATFORMS", [Platform.CLIMATE]): + # Act + await init_integration(hass, mock_config_entry) + # Assert + state = hass.states.get("climate.room_1_test_climate_4") + assert state.state == HVACMode.HEAT + assert state.attributes["preset_mode"] is None + + +async def test_set_hvac_mode( + hass: HomeAssistant, + mock_fibaro_client: Mock, + mock_config_entry: MockConfigEntry, + mock_thermostat: Mock, + mock_room: Mock, +) -> None: + """Test that set_hvac_mode() works.""" + + # Arrange + mock_fibaro_client.read_rooms.return_value = [mock_room] + mock_fibaro_client.read_devices.return_value = [mock_thermostat] + + with patch("homeassistant.components.fibaro.PLATFORMS", [Platform.CLIMATE]): + # Act + await init_integration(hass, mock_config_entry) + await hass.services.async_call( + "climate", + "set_hvac_mode", + {"entity_id": "climate.room_1_test_climate_4", "hvac_mode": HVACMode.HEAT}, + blocking=True, + ) + + # Assert + mock_thermostat.execute_action.assert_called_once() + + +async def test_hvac_mode_with_operation_mode_support( + hass: HomeAssistant, + mock_fibaro_client: Mock, + mock_config_entry: MockConfigEntry, + mock_thermostat_with_operating_mode: Mock, + mock_room: Mock, +) -> None: + """Test that operating mode works.""" + + # Arrange + mock_fibaro_client.read_rooms.return_value = [mock_room] + mock_fibaro_client.read_devices.return_value = [mock_thermostat_with_operating_mode] + + with patch("homeassistant.components.fibaro.PLATFORMS", [Platform.CLIMATE]): + # Act + await init_integration(hass, mock_config_entry) + # Assert + state = hass.states.get("climate.room_1_test_climate_4") + assert state.state == HVACMode.AUTO