Sync Climate min/max temp with Google Assistant (#94143)

* Sync climate min/max temp to Google Assistant

* Improving coverage on TemperatureSettingTrait
This commit is contained in:
hookedonunix 2023-06-08 10:46:35 +10:00 committed by GitHub
parent a6a2b8d29f
commit 85a12c37ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 104 additions and 10 deletions

View File

@ -922,9 +922,28 @@ class TemperatureSettingTrait(_Trait):
def sync_attributes(self): def sync_attributes(self):
"""Return temperature point and modes attributes for a sync request.""" """Return temperature point and modes attributes for a sync request."""
response = {} response = {}
response["thermostatTemperatureUnit"] = _google_temp_unit( attrs = self.state.attributes
self.hass.config.units.temperature_unit unit = self.hass.config.units.temperature_unit
response["thermostatTemperatureUnit"] = _google_temp_unit(unit)
min_temp = round(
TemperatureConverter.convert(
float(attrs[climate.ATTR_MIN_TEMP]),
unit,
UnitOfTemperature.CELSIUS,
)
) )
max_temp = round(
TemperatureConverter.convert(
float(attrs[climate.ATTR_MAX_TEMP]),
unit,
UnitOfTemperature.CELSIUS,
)
)
response["thermostatTemperatureRange"] = {
"minThresholdCelsius": min_temp,
"maxThresholdCelsius": max_temp,
}
modes = self.climate_google_modes modes = self.climate_google_modes

View File

@ -854,14 +854,18 @@ async def test_temperature_setting_climate_onoff(hass: HomeAssistant) -> None:
climate.HVACMode.HEAT, climate.HVACMode.HEAT,
climate.HVACMode.HEAT_COOL, climate.HVACMode.HEAT_COOL,
], ],
climate.ATTR_MIN_TEMP: None, climate.ATTR_MIN_TEMP: 45,
climate.ATTR_MAX_TEMP: None, climate.ATTR_MAX_TEMP: 95,
}, },
), ),
BASIC_CONFIG, BASIC_CONFIG,
) )
assert trt.sync_attributes() == { assert trt.sync_attributes() == {
"availableThermostatModes": ["off", "cool", "heat", "heatcool", "on"], "availableThermostatModes": ["off", "cool", "heat", "heatcool", "on"],
"thermostatTemperatureRange": {
"minThresholdCelsius": 7,
"maxThresholdCelsius": 35,
},
"thermostatTemperatureUnit": "F", "thermostatTemperatureUnit": "F",
} }
assert trt.can_execute(trait.COMMAND_THERMOSTAT_SET_MODE, {}) assert trt.can_execute(trait.COMMAND_THERMOSTAT_SET_MODE, {})
@ -893,14 +897,18 @@ async def test_temperature_setting_climate_no_modes(hass: HomeAssistant) -> None
climate.HVACMode.AUTO, climate.HVACMode.AUTO,
{ {
climate.ATTR_HVAC_MODES: [], climate.ATTR_HVAC_MODES: [],
climate.ATTR_MIN_TEMP: None, climate.ATTR_MIN_TEMP: climate.DEFAULT_MIN_TEMP,
climate.ATTR_MAX_TEMP: None, climate.ATTR_MAX_TEMP: climate.DEFAULT_MAX_TEMP,
}, },
), ),
BASIC_CONFIG, BASIC_CONFIG,
) )
assert trt.sync_attributes() == { assert trt.sync_attributes() == {
"availableThermostatModes": ["heat"], "availableThermostatModes": ["heat"],
"thermostatTemperatureRange": {
"minThresholdCelsius": climate.DEFAULT_MIN_TEMP,
"maxThresholdCelsius": climate.DEFAULT_MAX_TEMP,
},
"thermostatTemperatureUnit": "C", "thermostatTemperatureUnit": "C",
} }
@ -937,6 +945,10 @@ async def test_temperature_setting_climate_range(hass: HomeAssistant) -> None:
) )
assert trt.sync_attributes() == { assert trt.sync_attributes() == {
"availableThermostatModes": ["off", "cool", "heat", "auto", "on"], "availableThermostatModes": ["off", "cool", "heat", "auto", "on"],
"thermostatTemperatureRange": {
"minThresholdCelsius": 10,
"maxThresholdCelsius": 27,
},
"thermostatTemperatureUnit": "F", "thermostatTemperatureUnit": "F",
} }
assert trt.query_attributes() == { assert trt.query_attributes() == {
@ -978,12 +990,40 @@ async def test_temperature_setting_climate_range(hass: HomeAssistant) -> None:
with pytest.raises(helpers.SmartHomeError) as err: with pytest.raises(helpers.SmartHomeError) as err:
await trt.execute( await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, trait.COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE,
BASIC_DATA, BASIC_DATA,
{"thermostatTemperatureSetpoint": -100}, {
"thermostatTemperatureSetpointHigh": 26,
"thermostatTemperatureSetpointLow": -100,
},
{}, {},
) )
assert err.value.code == const.ERR_VALUE_OUT_OF_RANGE assert err.value.code == const.ERR_VALUE_OUT_OF_RANGE
with pytest.raises(helpers.SmartHomeError) as err:
await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE,
BASIC_DATA,
{
"thermostatTemperatureSetpointHigh": 100,
"thermostatTemperatureSetpointLow": 18,
},
{},
)
assert err.value.code == const.ERR_VALUE_OUT_OF_RANGE
calls = async_mock_service(hass, climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE)
await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT,
BASIC_DATA,
{"thermostatTemperatureSetpoint": 23.9},
{},
)
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: "climate.bla",
climate.ATTR_TEMPERATURE: 75,
}
hass.config.units.temperature_unit = UnitOfTemperature.CELSIUS hass.config.units.temperature_unit = UnitOfTemperature.CELSIUS
@ -1000,9 +1040,11 @@ async def test_temperature_setting_climate_setpoint(hass: HomeAssistant) -> None
"climate.bla", "climate.bla",
climate.HVACMode.COOL, climate.HVACMode.COOL,
{ {
ATTR_SUPPORTED_FEATURES: climate.SUPPORT_TARGET_TEMPERATURE,
climate.ATTR_HVAC_MODES: [STATE_OFF, climate.HVACMode.COOL], climate.ATTR_HVAC_MODES: [STATE_OFF, climate.HVACMode.COOL],
climate.ATTR_MIN_TEMP: 10, climate.ATTR_MIN_TEMP: 10,
climate.ATTR_MAX_TEMP: 30, climate.ATTR_MAX_TEMP: 30,
climate.ATTR_PRESET_MODE: climate.PRESET_ECO,
ATTR_TEMPERATURE: 18, ATTR_TEMPERATURE: 18,
climate.ATTR_CURRENT_TEMPERATURE: 20, climate.ATTR_CURRENT_TEMPERATURE: 20,
}, },
@ -1011,10 +1053,14 @@ async def test_temperature_setting_climate_setpoint(hass: HomeAssistant) -> None
) )
assert trt.sync_attributes() == { assert trt.sync_attributes() == {
"availableThermostatModes": ["off", "cool", "on"], "availableThermostatModes": ["off", "cool", "on"],
"thermostatTemperatureRange": {
"minThresholdCelsius": 10,
"maxThresholdCelsius": 30,
},
"thermostatTemperatureUnit": "C", "thermostatTemperatureUnit": "C",
} }
assert trt.query_attributes() == { assert trt.query_attributes() == {
"thermostatMode": "cool", "thermostatMode": "eco",
"thermostatTemperatureAmbient": 20, "thermostatTemperatureAmbient": 20,
"thermostatTemperatureSetpoint": 18, "thermostatTemperatureSetpoint": 18,
} }
@ -1022,7 +1068,6 @@ async def test_temperature_setting_climate_setpoint(hass: HomeAssistant) -> None
assert trt.can_execute(trait.COMMAND_THERMOSTAT_SET_MODE, {}) assert trt.can_execute(trait.COMMAND_THERMOSTAT_SET_MODE, {})
calls = async_mock_service(hass, climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE) calls = async_mock_service(hass, climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE)
with pytest.raises(helpers.SmartHomeError): with pytest.raises(helpers.SmartHomeError):
await trt.execute( await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT, trait.COMMAND_THERMOSTAT_TEMPERATURE_SETPOINT,
@ -1040,6 +1085,32 @@ async def test_temperature_setting_climate_setpoint(hass: HomeAssistant) -> None
assert len(calls) == 1 assert len(calls) == 1
assert calls[0].data == {ATTR_ENTITY_ID: "climate.bla", ATTR_TEMPERATURE: 19} assert calls[0].data == {ATTR_ENTITY_ID: "climate.bla", ATTR_TEMPERATURE: 19}
calls = async_mock_service(hass, climate.DOMAIN, climate.SERVICE_SET_PRESET_MODE)
await trt.execute(
trait.COMMAND_THERMOSTAT_SET_MODE,
BASIC_DATA,
{"thermostatMode": "eco"},
{},
)
assert len(calls) == 1
assert calls[0].data == {
ATTR_ENTITY_ID: "climate.bla",
climate.ATTR_PRESET_MODE: "eco",
}
calls = async_mock_service(hass, climate.DOMAIN, climate.SERVICE_SET_TEMPERATURE)
await trt.execute(
trait.COMMAND_THERMOSTAT_TEMPERATURE_SET_RANGE,
BASIC_DATA,
{
"thermostatTemperatureSetpointHigh": 15,
"thermostatTemperatureSetpointLow": 22,
},
{},
)
assert len(calls) == 1
assert calls[0].data == {ATTR_ENTITY_ID: "climate.bla", ATTR_TEMPERATURE: 18.5}
async def test_temperature_setting_climate_setpoint_auto(hass: HomeAssistant) -> None: async def test_temperature_setting_climate_setpoint_auto(hass: HomeAssistant) -> None:
"""Test TemperatureSetting trait support for climate domain. """Test TemperatureSetting trait support for climate domain.
@ -1068,6 +1139,10 @@ async def test_temperature_setting_climate_setpoint_auto(hass: HomeAssistant) ->
) )
assert trt.sync_attributes() == { assert trt.sync_attributes() == {
"availableThermostatModes": ["off", "heatcool", "on"], "availableThermostatModes": ["off", "heatcool", "on"],
"thermostatTemperatureRange": {
"minThresholdCelsius": 10,
"maxThresholdCelsius": 30,
},
"thermostatTemperatureUnit": "C", "thermostatTemperatureUnit": "C",
} }
assert trt.query_attributes() == { assert trt.query_attributes() == {