Fix incorrect temperature in Gree if temp units changed on device (#121041)

This commit is contained in:
Clifford Roche 2024-07-07 11:05:14 -04:00 committed by GitHub
parent 792c6a9cd9
commit 27975c7517
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 96 additions and 19 deletions

View File

@ -123,21 +123,15 @@ class GreeClimateEntity(GreeEntity, ClimateEntity):
_attr_fan_modes = [*FAN_MODES_REVERSE]
_attr_swing_modes = SWING_MODES
_attr_name = None
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_min_temp = TEMP_MIN
_attr_max_temp = TEMP_MAX
_enable_turn_on_off_backwards_compatibility = False
def __init__(self, coordinator: DeviceDataUpdateCoordinator) -> None:
"""Initialize the Gree device."""
super().__init__(coordinator)
self._attr_unique_id = coordinator.device.device_info.mac
units = self.coordinator.device.temperature_units
if units == TemperatureUnits.C:
self._attr_temperature_unit = UnitOfTemperature.CELSIUS
self._attr_min_temp = TEMP_MIN
self._attr_max_temp = TEMP_MAX
else:
self._attr_temperature_unit = UnitOfTemperature.FAHRENHEIT
self._attr_min_temp = TEMP_MIN_F
self._attr_max_temp = TEMP_MAX_F
@property
def current_temperature(self) -> float:
@ -164,7 +158,7 @@ class GreeClimateEntity(GreeEntity, ClimateEntity):
self._attr_name,
)
self.coordinator.device.target_temperature = round(temperature)
self.coordinator.device.target_temperature = temperature
await self.coordinator.push_state_update()
self.async_write_ha_state()
@ -306,3 +300,25 @@ class GreeClimateEntity(GreeEntity, ClimateEntity):
await self.coordinator.push_state_update()
self.async_write_ha_state()
def _handle_coordinator_update(self) -> None:
"""Update the state of the entity."""
units = self.coordinator.device.temperature_units
if (
units == TemperatureUnits.C
and self._attr_temperature_unit != UnitOfTemperature.CELSIUS
):
_LOGGER.debug("Setting temperature unit to Celsius")
self._attr_temperature_unit = UnitOfTemperature.CELSIUS
self._attr_min_temp = TEMP_MIN
self._attr_max_temp = TEMP_MAX
elif (
units == TemperatureUnits.F
and self._attr_temperature_unit != UnitOfTemperature.FAHRENHEIT
):
_LOGGER.debug("Setting temperature unit to Fahrenheit")
self._attr_temperature_unit = UnitOfTemperature.FAHRENHEIT
self._attr_min_temp = TEMP_MIN_F
self._attr_max_temp = TEMP_MAX_F
super()._handle_coordinator_update()

View File

@ -4,13 +4,19 @@ from datetime import timedelta
from unittest.mock import DEFAULT as DEFAULT_MOCK, AsyncMock, patch
from freezegun.api import FrozenDateTimeFactory
from greeclimate.device import HorizontalSwing, VerticalSwing
from greeclimate.device import (
TEMP_MAX,
TEMP_MAX_F,
TEMP_MIN,
TEMP_MIN_F,
HorizontalSwing,
VerticalSwing,
)
from greeclimate.exceptions import DeviceNotBoundError, DeviceTimeoutError
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.climate import (
ATTR_CURRENT_TEMPERATURE,
ATTR_FAN_MODE,
ATTR_HVAC_MODE,
ATTR_PRESET_MODE,
@ -40,11 +46,13 @@ from homeassistant.components.gree.climate import (
FAN_MODES_REVERSE,
HVAC_MODES,
HVAC_MODES_REVERSE,
GreeClimateEntity,
)
from homeassistant.components.gree.const import FAN_MEDIUM_HIGH, FAN_MEDIUM_LOW
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_TEMPERATURE,
ATTR_UNIT_OF_MEASUREMENT,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_UNAVAILABLE,
@ -385,7 +393,7 @@ async def test_send_power_off_device_timeout(
@pytest.mark.parametrize(
("units", "temperature"),
[(UnitOfTemperature.CELSIUS, 26), (UnitOfTemperature.FAHRENHEIT, 74)],
[(UnitOfTemperature.CELSIUS, 26), (UnitOfTemperature.FAHRENHEIT, 73)],
)
async def test_send_target_temperature(
hass: HomeAssistant, discovery, device, units, temperature
@ -405,6 +413,14 @@ async def test_send_target_temperature(
# Make sure we're trying to test something that isn't the default
assert fake_device.current_temperature != temperature
hass.states.async_set(
ENTITY_ID,
"off",
{
ATTR_UNIT_OF_MEASUREMENT: units,
},
)
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
@ -415,10 +431,6 @@ async def test_send_target_temperature(
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.attributes.get(ATTR_TEMPERATURE) == temperature
assert (
state.attributes.get(ATTR_CURRENT_TEMPERATURE)
== fake_device.current_temperature
)
assert state.state == HVAC_MODES.get(fake_device.mode)
# Reset config temperature_unit back to CELSIUS, required for
@ -462,7 +474,11 @@ async def test_send_target_temperature_with_hvac_mode(
@pytest.mark.parametrize(
("units", "temperature"),
[(UnitOfTemperature.CELSIUS, 25), (UnitOfTemperature.FAHRENHEIT, 74)],
[
(UnitOfTemperature.CELSIUS, 25),
(UnitOfTemperature.FAHRENHEIT, 73),
(UnitOfTemperature.FAHRENHEIT, 74),
],
)
async def test_send_target_temperature_device_timeout(
hass: HomeAssistant, discovery, device, units, temperature
@ -492,7 +508,11 @@ async def test_send_target_temperature_device_timeout(
@pytest.mark.parametrize(
("units", "temperature"),
[(UnitOfTemperature.CELSIUS, 25), (UnitOfTemperature.FAHRENHEIT, 74)],
[
(UnitOfTemperature.CELSIUS, 25),
(UnitOfTemperature.FAHRENHEIT, 73),
(UnitOfTemperature.FAHRENHEIT, 74),
],
)
async def test_update_target_temperature(
hass: HomeAssistant, discovery, device, units, temperature
@ -505,6 +525,13 @@ async def test_update_target_temperature(
await async_setup_gree(hass)
await hass.services.async_call(
DOMAIN,
SERVICE_SET_TEMPERATURE,
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_TEMPERATURE: temperature},
blocking=True,
)
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.attributes.get(ATTR_TEMPERATURE) == temperature
@ -843,6 +870,40 @@ async def test_update_swing_mode(
assert state.attributes.get(ATTR_SWING_MODE) == swing_mode
async def test_coordinator_update_handler(
hass: HomeAssistant, discovery, device
) -> None:
"""Test for coordinator update handler."""
await async_setup_gree(hass)
await hass.async_block_till_done()
entity: GreeClimateEntity = hass.data[DOMAIN].get_entity(ENTITY_ID)
assert entity is not None
# Initial state
assert entity.temperature_unit == UnitOfTemperature.CELSIUS
assert entity.min_temp == TEMP_MIN
assert entity.max_temp == TEMP_MAX
# Set unit to FAHRENHEIT
device().temperature_units = 1
entity.coordinator.async_set_updated_data(UnitOfTemperature.FAHRENHEIT)
await hass.async_block_till_done()
assert entity.temperature_unit == UnitOfTemperature.FAHRENHEIT
assert entity.min_temp == TEMP_MIN_F
assert entity.max_temp == TEMP_MAX_F
# Set unit back to CELSIUS
device().temperature_units = 0
entity.coordinator.async_set_updated_data(UnitOfTemperature.CELSIUS)
await hass.async_block_till_done()
assert entity.temperature_unit == UnitOfTemperature.CELSIUS
assert entity.min_temp == TEMP_MIN
assert entity.max_temp == TEMP_MAX
@patch("homeassistant.components.gree.PLATFORMS", [DOMAIN])
async def test_registry_settings(
hass: HomeAssistant, entity_registry: er.EntityRegistry, snapshot: SnapshotAssertion