diff --git a/homeassistant/components/google_assistant/trait.py b/homeassistant/components/google_assistant/trait.py index 5ae72b7a41ae..6c80a69bf4c6 100644 --- a/homeassistant/components/google_assistant/trait.py +++ b/homeassistant/components/google_assistant/trait.py @@ -1076,14 +1076,16 @@ class TemperatureControlTrait(_Trait): float(attrs[water_heater.ATTR_MIN_TEMP]), unit, UnitOfTemperature.CELSIUS, - ) + ), + 1, ) max_temp = round( TemperatureConverter.convert( float(attrs[water_heater.ATTR_MAX_TEMP]), unit, UnitOfTemperature.CELSIUS, - ) + ), + 1, ) response["temperatureRange"] = { "minThresholdCelsius": min_temp, @@ -1236,14 +1238,16 @@ class TemperatureSettingTrait(_Trait): float(attrs[climate.ATTR_MIN_TEMP]), unit, UnitOfTemperature.CELSIUS, - ) + ), + 1, ) max_temp = round( TemperatureConverter.convert( float(attrs[climate.ATTR_MAX_TEMP]), unit, UnitOfTemperature.CELSIUS, - ) + ), + 1, ) response["thermostatTemperatureRange"] = { "minThresholdCelsius": min_temp, diff --git a/tests/components/google_assistant/test_trait.py b/tests/components/google_assistant/test_trait.py index ee2ab1278894..53b03a596e13 100644 --- a/tests/components/google_assistant/test_trait.py +++ b/tests/components/google_assistant/test_trait.py @@ -1325,7 +1325,7 @@ async def test_temperature_setting_climate_onoff(hass: HomeAssistant) -> None: assert trt.sync_attributes() == { "availableThermostatModes": ["off", "cool", "heat", "heatcool", "on"], "thermostatTemperatureRange": { - "minThresholdCelsius": 7, + "minThresholdCelsius": 7.2, "maxThresholdCelsius": 35, }, "thermostatTemperatureUnit": "F", @@ -1373,6 +1373,43 @@ async def test_temperature_setting_climate_no_modes(hass: HomeAssistant) -> None } +async def test_temperature_setting_climate_range_fahrenheit_precision( + hass: HomeAssistant, +) -> None: + """Test that Fahrenheit range bounds are reported to Google with decimal precision. + + Regression test: when a climate entity advertises an integer Fahrenheit min/max + whose Celsius equivalent is non-integer (e.g. 62°F = 16.666…°C), rounding the + converted value to a whole degree Celsius causes Google Home to display a range + shifted by up to 1°F when it converts back for display. Reporting one decimal + place of Celsius precision keeps Google's displayed range aligned with + Home Assistant's. + """ + hass.config.units = US_CUSTOMARY_SYSTEM + + trt = trait.TemperatureSettingTrait( + hass, + State( + "climate.bla", + climate.HVACMode.COOL, + { + ATTR_SUPPORTED_FEATURES: ClimateEntityFeature.TARGET_TEMPERATURE, + climate.ATTR_HVAC_MODES: [climate.HVACMode.OFF, climate.HVACMode.COOL], + climate.ATTR_MIN_TEMP: 62, + climate.ATTR_MAX_TEMP: 86, + }, + ), + BASIC_CONFIG, + ) + attrs = trt.sync_attributes() + assert attrs["thermostatTemperatureRange"] == { + "minThresholdCelsius": 16.7, + "maxThresholdCelsius": 30, + } + # 16.7°C → 62.06°F (displays as 62°F, matching Home Assistant's min of 62°F); + # the pre-fix value of 17°C → 62.6°F would have displayed as 63°F. + + async def test_temperature_setting_climate_range(hass: HomeAssistant) -> None: """Test TemperatureSetting trait support for climate domain - range.""" assert helpers.get_google_type(climate.DOMAIN, None) is not None @@ -1409,7 +1446,7 @@ async def test_temperature_setting_climate_range(hass: HomeAssistant) -> None: "availableThermostatModes": ["off", "cool", "heat", "auto", "on"], "thermostatTemperatureRange": { "minThresholdCelsius": 10, - "maxThresholdCelsius": 27, + "maxThresholdCelsius": 26.7, }, "thermostatTemperatureUnit": "F", }