diff --git a/homeassistant/components/plugwise/climate.py b/homeassistant/components/plugwise/climate.py index 84dc4576700..8d0d3578c2c 100644 --- a/homeassistant/components/plugwise/climate.py +++ b/homeassistant/components/plugwise/climate.py @@ -5,6 +5,8 @@ from collections.abc import Mapping from typing import Any from homeassistant.components.climate import ( + ATTR_TARGET_TEMP_HIGH, + ATTR_TARGET_TEMP_LOW, ClimateEntity, ClimateEntityFeature, HVACAction, @@ -52,8 +54,12 @@ class PlugwiseClimateEntity(PlugwiseEntity, ClimateEntity): self._attr_extra_state_attributes = {} self._attr_unique_id = f"{device_id}-climate" - # Determine preset modes + # Determine supported features self._attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE + if self.coordinator.data.gateway["cooling_present"]: + self._attr_supported_features = ( + ClimateEntityFeature.TARGET_TEMPERATURE_RANGE + ) if presets := self.device.get("preset_modes"): self._attr_supported_features |= ClimateEntityFeature.PRESET_MODE self._attr_preset_modes = presets @@ -61,7 +67,7 @@ class PlugwiseClimateEntity(PlugwiseEntity, ClimateEntity): # Determine hvac modes and current hvac mode self._attr_hvac_modes = [HVACMode.HEAT] if self.coordinator.data.gateway["cooling_present"]: - self._attr_hvac_modes.append(HVACMode.COOL) + self._attr_hvac_modes = [HVACMode.HEAT_COOL] if self.device["available_schedules"] != ["None"]: self._attr_hvac_modes.append(HVACMode.AUTO) @@ -79,12 +85,32 @@ class PlugwiseClimateEntity(PlugwiseEntity, ClimateEntity): @property def target_temperature(self) -> float: - """Return the temperature we try to reach.""" + """Return the temperature we try to reach. + + Connected to the HVACMode combination of AUTO-HEAT. + """ + return self.device["thermostat"]["setpoint"] + @property + def target_temperature_high(self) -> float: + """Return the temperature we try to reach in case of cooling. + + Connected to the HVACMode combination of AUTO-HEAT_COOL. + """ + return self.device["thermostat"]["setpoint_high"] + + @property + def target_temperature_low(self) -> float: + """Return the heating temperature we try to reach in case of heating. + + Connected to the HVACMode combination AUTO-HEAT_COOL. + """ + return self.device["thermostat"]["setpoint_low"] + @property def hvac_mode(self) -> HVACMode: - """Return HVAC operation ie. heat, cool mode.""" + """Return HVAC operation ie. auto, heat, or heat_cool mode.""" if (mode := self.device.get("mode")) is None or mode not in self.hvac_modes: return HVACMode.HEAT return HVACMode(mode) @@ -127,12 +153,21 @@ class PlugwiseClimateEntity(PlugwiseEntity, ClimateEntity): @plugwise_command async def async_set_temperature(self, **kwargs: Any) -> None: """Set new target temperature.""" - if ((temperature := kwargs.get(ATTR_TEMPERATURE)) is None) or not ( - self._attr_min_temp <= temperature <= self._attr_max_temp - ): - raise ValueError("Invalid temperature change requested") + data: dict[str, Any] = {} + if ATTR_TEMPERATURE in kwargs: + data["setpoint"] = kwargs.get(ATTR_TEMPERATURE) + if ATTR_TARGET_TEMP_HIGH in kwargs: + data["setpoint_high"] = kwargs.get(ATTR_TARGET_TEMP_HIGH) + if ATTR_TARGET_TEMP_LOW in kwargs: + data["setpoint_low"] = kwargs.get(ATTR_TARGET_TEMP_LOW) - await self.coordinator.api.set_temperature(self.device["location"], temperature) + for temperature in data.values(): + if temperature is None or not ( + self._attr_min_temp <= temperature <= self._attr_max_temp + ): + raise ValueError("Invalid temperature change requested") + + await self.coordinator.api.set_temperature(self.device["location"], data) @plugwise_command async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: diff --git a/homeassistant/components/plugwise/manifest.json b/homeassistant/components/plugwise/manifest.json index f49e7b7c508..43da399a8f2 100644 --- a/homeassistant/components/plugwise/manifest.json +++ b/homeassistant/components/plugwise/manifest.json @@ -2,7 +2,7 @@ "domain": "plugwise", "name": "Plugwise", "documentation": "https://www.home-assistant.io/integrations/plugwise", - "requirements": ["plugwise==0.25.0"], + "requirements": ["plugwise==0.25.2"], "codeowners": ["@CoMPaTech", "@bouwew", "@brefra", "@frenck"], "zeroconf": ["_plugwise._tcp.local."], "config_flow": true, diff --git a/requirements_all.txt b/requirements_all.txt index 774942a9074..921c816ffca 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1312,7 +1312,7 @@ plexauth==0.0.6 plexwebsocket==0.0.13 # homeassistant.components.plugwise -plugwise==0.25.0 +plugwise==0.25.2 # homeassistant.components.plum_lightpad plumlightpad==0.0.11 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 2f49c44d769..8762340a1e6 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -939,7 +939,7 @@ plexauth==0.0.6 plexwebsocket==0.0.13 # homeassistant.components.plugwise -plugwise==0.25.0 +plugwise==0.25.2 # homeassistant.components.plum_lightpad plumlightpad==0.0.11 diff --git a/tests/components/plugwise/fixtures/anna_heatpump_heating/all_data.json b/tests/components/plugwise/fixtures/anna_heatpump_heating/all_data.json index be2dd05011b..546a11b2c68 100644 --- a/tests/components/plugwise/fixtures/anna_heatpump_heating/all_data.json +++ b/tests/components/plugwise/fixtures/anna_heatpump_heating/all_data.json @@ -68,7 +68,6 @@ "thermostat": { "setpoint_low": 20.5, "setpoint_high": 24.0, - "setpoint": 20.5, "lower_bound": 4.0, "upper_bound": 30.0, "resolution": 0.1 diff --git a/tests/components/plugwise/fixtures/m_adam_cooling/all_data.json b/tests/components/plugwise/fixtures/m_adam_cooling/all_data.json index 246ae5dff50..ae9a16b7d1a 100644 --- a/tests/components/plugwise/fixtures/m_adam_cooling/all_data.json +++ b/tests/components/plugwise/fixtures/m_adam_cooling/all_data.json @@ -14,7 +14,6 @@ "name": "Anna", "vendor": "Plugwise", "thermostat": { - "setpoint": 20.0, "setpoint_low": 20.0, "setpoint_high": 23.5, "lower_bound": 1.0, @@ -28,10 +27,9 @@ "selected_schedule": "None", "last_used": "Weekschema", "control_state": "cooling", - "mode": "cool", + "mode": "heat_cool", "sensors": { "temperature": 25.8, - "setpoint": 20.0, "setpoint_low": 20.0, "setpoint_high": 23.5 } @@ -63,7 +61,6 @@ "zigbee_mac_address": "ABCD012345670A04", "vendor": "Plugwise", "thermostat": { - "setpoint": 19.0, "setpoint_low": 19.0, "setpoint_high": 25.0, "lower_bound": 0.0, @@ -81,7 +78,6 @@ "sensors": { "temperature": 239, "battery": 56, - "setpoint": 20.0, "setpoint_low": 20.0, "setpoint_high": 23.5 } diff --git a/tests/components/plugwise/fixtures/m_anna_heatpump_cooling/all_data.json b/tests/components/plugwise/fixtures/m_anna_heatpump_cooling/all_data.json index d6d34801641..6326a02fedb 100644 --- a/tests/components/plugwise/fixtures/m_anna_heatpump_cooling/all_data.json +++ b/tests/components/plugwise/fixtures/m_anna_heatpump_cooling/all_data.json @@ -66,7 +66,6 @@ "name": "Anna", "vendor": "Plugwise", "thermostat": { - "setpoint": 24.0, "setpoint_low": 20.5, "setpoint_high": 24.0, "lower_bound": 4.0, @@ -85,7 +84,6 @@ "illuminance": 86.0, "cooling_activation_outdoor_temperature": 21.0, "cooling_deactivation_threshold": 4.0, - "setpoint": 24.0, "setpoint_low": 20.5, "setpoint_high": 24.0 } diff --git a/tests/components/plugwise/fixtures/m_anna_heatpump_idle/all_data.json b/tests/components/plugwise/fixtures/m_anna_heatpump_idle/all_data.json index ca9559ca073..cd2747f423b 100644 --- a/tests/components/plugwise/fixtures/m_anna_heatpump_idle/all_data.json +++ b/tests/components/plugwise/fixtures/m_anna_heatpump_idle/all_data.json @@ -66,7 +66,6 @@ "name": "Anna", "vendor": "Plugwise", "thermostat": { - "setpoint": 20.5, "setpoint_low": 20.5, "setpoint_high": 24.0, "lower_bound": 4.0, @@ -85,7 +84,6 @@ "illuminance": 86.0, "cooling_activation_outdoor_temperature": 25.0, "cooling_deactivation_threshold": 4.0, - "setpoint": 20.5, "setpoint_low": 20.5, "setpoint_high": 24.0 } diff --git a/tests/components/plugwise/test_climate.py b/tests/components/plugwise/test_climate.py index bcca1a32abb..ad5443a678c 100644 --- a/tests/components/plugwise/test_climate.py +++ b/tests/components/plugwise/test_climate.py @@ -75,11 +75,10 @@ async def test_adam_3_climate_entity_attributes( state = hass.states.get("climate.anna") assert state - assert state.state == HVACMode.COOL + assert state.state == HVACMode.HEAT_COOL assert state.attributes["hvac_action"] == "cooling" assert state.attributes["hvac_modes"] == [ - HVACMode.HEAT, - HVACMode.COOL, + HVACMode.HEAT_COOL, HVACMode.AUTO, ] @@ -133,7 +132,7 @@ async def test_adam_climate_entity_climate_changes( assert mock_smile_adam.set_temperature.call_count == 1 mock_smile_adam.set_temperature.assert_called_with( - "c50f167537524366a5af7aa3942feb1e", 25.0 + "c50f167537524366a5af7aa3942feb1e", {"setpoint": 25.0} ) with pytest.raises(ValueError): @@ -165,7 +164,7 @@ async def test_adam_climate_entity_climate_changes( assert mock_smile_adam.set_temperature.call_count == 2 mock_smile_adam.set_temperature.assert_called_with( - "82fa13f017d240daa0d0ea1775420f24", 25.0 + "82fa13f017d240daa0d0ea1775420f24", {"setpoint": 25.0} ) await hass.services.async_call( @@ -203,8 +202,7 @@ async def test_anna_climate_entity_attributes( assert state.state == HVACMode.AUTO assert state.attributes["hvac_action"] == "heating" assert state.attributes["hvac_modes"] == [ - HVACMode.HEAT, - HVACMode.COOL, + HVACMode.HEAT_COOL, HVACMode.AUTO, ] @@ -213,8 +211,9 @@ async def test_anna_climate_entity_attributes( assert state.attributes["current_temperature"] == 19.3 assert state.attributes["preset_mode"] == "home" - assert state.attributes["supported_features"] == 17 - assert state.attributes["temperature"] == 20.5 + assert state.attributes["supported_features"] == 18 + assert state.attributes["target_temp_high"] == 24.0 + assert state.attributes["target_temp_low"] == 20.5 assert state.attributes["min_temp"] == 4.0 assert state.attributes["max_temp"] == 30.0 assert state.attributes["target_temp_step"] == 0.1 @@ -231,12 +230,12 @@ async def test_anna_2_climate_entity_attributes( assert state.state == HVACMode.AUTO assert state.attributes["hvac_action"] == "cooling" assert state.attributes["hvac_modes"] == [ - HVACMode.HEAT, - HVACMode.COOL, + HVACMode.HEAT_COOL, HVACMode.AUTO, ] - assert state.attributes["temperature"] == 24.0 - assert state.attributes["supported_features"] == 17 + assert state.attributes["supported_features"] == 18 + assert state.attributes["target_temp_high"] == 24.0 + assert state.attributes["target_temp_low"] == 20.5 async def test_anna_3_climate_entity_attributes( @@ -250,8 +249,7 @@ async def test_anna_3_climate_entity_attributes( assert state.state == HVACMode.AUTO assert state.attributes["hvac_action"] == "idle" assert state.attributes["hvac_modes"] == [ - HVACMode.HEAT, - HVACMode.COOL, + HVACMode.HEAT_COOL, HVACMode.AUTO, ] @@ -263,14 +261,14 @@ async def test_anna_climate_entity_climate_changes( await hass.services.async_call( "climate", "set_temperature", - {"entity_id": "climate.anna", "temperature": 25}, + {"entity_id": "climate.anna", "target_temp_high": 25, "target_temp_low": 20}, blocking=True, ) assert mock_smile_anna.set_temperature.call_count == 1 mock_smile_anna.set_temperature.assert_called_with( "c784ee9fdab44e1395b8dee7d7a497d5", - 25.0, + {"setpoint_high": 25.0, "setpoint_low": 20.0}, ) await hass.services.async_call( @@ -288,7 +286,7 @@ async def test_anna_climate_entity_climate_changes( await hass.services.async_call( "climate", "set_hvac_mode", - {"entity_id": "climate.anna", "hvac_mode": "heat"}, + {"entity_id": "climate.anna", "hvac_mode": "heat_cool"}, blocking=True, )