Fix Air Conditioner set temperature error in LG ThinQ (#147008)

Co-authored-by: yunseon.park <yunseon.park@lge.com>
This commit is contained in:
LG-ThinQ-Integration 2025-07-25 03:12:41 +09:00 committed by GitHub
parent 5c7913c3bd
commit 5c4862ffe1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 63 deletions

View File

@ -12,6 +12,7 @@ from homeassistant.components.climate import (
ATTR_HVAC_MODE, ATTR_HVAC_MODE,
ATTR_TARGET_TEMP_HIGH, ATTR_TARGET_TEMP_HIGH,
ATTR_TARGET_TEMP_LOW, ATTR_TARGET_TEMP_LOW,
PRESET_NONE,
SWING_OFF, SWING_OFF,
SWING_ON, SWING_ON,
ClimateEntity, ClimateEntity,
@ -22,7 +23,6 @@ from homeassistant.components.climate import (
from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature from homeassistant.const import ATTR_TEMPERATURE, UnitOfTemperature
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.temperature import display_temp
from . import ThinqConfigEntry from . import ThinqConfigEntry
from .coordinator import DeviceDataUpdateCoordinator from .coordinator import DeviceDataUpdateCoordinator
@ -109,11 +109,11 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
) )
self._attr_hvac_modes = [HVACMode.OFF] self._attr_hvac_modes = [HVACMode.OFF]
self._attr_hvac_mode = HVACMode.OFF self._attr_hvac_mode = HVACMode.OFF
self._attr_preset_modes = [] self._attr_preset_modes = [PRESET_NONE]
self._attr_preset_mode = PRESET_NONE
self._attr_temperature_unit = ( self._attr_temperature_unit = (
self._get_unit_of_measurement(self.data.unit) or UnitOfTemperature.CELSIUS self._get_unit_of_measurement(self.data.unit) or UnitOfTemperature.CELSIUS
) )
self._requested_hvac_mode: str | None = None
# Set up HVAC modes. # Set up HVAC modes.
for mode in self.data.hvac_modes: for mode in self.data.hvac_modes:
@ -157,17 +157,19 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
) )
if self.data.is_on: if self.data.is_on:
hvac_mode = self._requested_hvac_mode or self.data.hvac_mode hvac_mode = self.data.hvac_mode
if hvac_mode in STR_TO_HVAC: if hvac_mode in STR_TO_HVAC:
self._attr_hvac_mode = STR_TO_HVAC.get(hvac_mode) self._attr_hvac_mode = STR_TO_HVAC.get(hvac_mode)
self._attr_preset_mode = None self._attr_preset_mode = PRESET_NONE
elif hvac_mode in THINQ_PRESET_MODE: elif hvac_mode in THINQ_PRESET_MODE:
self._attr_hvac_mode = (
HVACMode.COOL if hvac_mode == "energy_saving" else HVACMode.FAN_ONLY
)
self._attr_preset_mode = hvac_mode self._attr_preset_mode = hvac_mode
else: else:
self._attr_hvac_mode = HVACMode.OFF self._attr_hvac_mode = HVACMode.OFF
self._attr_preset_mode = None self._attr_preset_mode = PRESET_NONE
self.reset_requested_hvac_mode()
self._attr_current_humidity = self.data.humidity self._attr_current_humidity = self.data.humidity
self._attr_current_temperature = self.data.current_temp self._attr_current_temperature = self.data.current_temp
@ -202,10 +204,6 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
self.target_temperature_step, self.target_temperature_step,
) )
def reset_requested_hvac_mode(self) -> None:
"""Cancel request to set hvac mode."""
self._requested_hvac_mode = None
async def async_turn_on(self) -> None: async def async_turn_on(self) -> None:
"""Turn the entity on.""" """Turn the entity on."""
_LOGGER.debug( _LOGGER.debug(
@ -226,16 +224,13 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
await self.async_turn_off() await self.async_turn_off()
return return
if hvac_mode == HVACMode.HEAT_COOL:
hvac_mode = HVACMode.AUTO
# If device is off, turn on first. # If device is off, turn on first.
if not self.data.is_on: if not self.data.is_on:
await self.async_turn_on() await self.async_turn_on()
# When we request hvac mode while turning on the device, the previously set
# hvac mode is displayed first and then switches to the requested hvac mode.
# To prevent this, set the requested hvac mode here so that it will be set
# immediately on the next update.
self._requested_hvac_mode = HVAC_TO_STR.get(hvac_mode)
_LOGGER.debug( _LOGGER.debug(
"[%s:%s] async_set_hvac_mode: %s", "[%s:%s] async_set_hvac_mode: %s",
self.coordinator.device_name, self.coordinator.device_name,
@ -244,9 +239,8 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
) )
await self.async_call_api( await self.async_call_api(
self.coordinator.api.async_set_hvac_mode( self.coordinator.api.async_set_hvac_mode(
self.property_id, self._requested_hvac_mode self.property_id, HVAC_TO_STR.get(hvac_mode)
), )
self.reset_requested_hvac_mode,
) )
async def async_set_preset_mode(self, preset_mode: str) -> None: async def async_set_preset_mode(self, preset_mode: str) -> None:
@ -257,6 +251,8 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
self.property_id, self.property_id,
preset_mode, preset_mode,
) )
if preset_mode == PRESET_NONE:
preset_mode = "cool" if self.preset_mode == "energy_saving" else "fan"
await self.async_call_api( await self.async_call_api(
self.coordinator.api.async_set_hvac_mode(self.property_id, preset_mode) self.coordinator.api.async_set_hvac_mode(self.property_id, preset_mode)
) )
@ -301,59 +297,50 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
) )
) )
def _round_by_step(self, temperature: float) -> float:
"""Round the value by step."""
if (
target_temp := display_temp(
self.coordinator.hass,
temperature,
self.coordinator.hass.config.units.temperature_unit,
self.target_temperature_step or 1,
)
) is not None:
return target_temp
return temperature
async def async_set_temperature(self, **kwargs: Any) -> None: async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature.""" """Set new target temperature."""
if hvac_mode := kwargs.get(ATTR_HVAC_MODE):
if hvac_mode == HVACMode.OFF:
await self.async_turn_off()
return
if hvac_mode == HVACMode.HEAT_COOL:
hvac_mode = HVACMode.AUTO
# If device is off, turn on first.
if not self.data.is_on:
await self.async_turn_on()
if hvac_mode and hvac_mode != self.hvac_mode:
await self.async_set_hvac_mode(HVACMode(hvac_mode))
_LOGGER.debug( _LOGGER.debug(
"[%s:%s] async_set_temperature: %s", "[%s:%s] async_set_temperature: %s",
self.coordinator.device_name, self.coordinator.device_name,
self.property_id, self.property_id,
kwargs, kwargs,
) )
if hvac_mode := kwargs.get(ATTR_HVAC_MODE): if temperature := kwargs.get(ATTR_TEMPERATURE):
await self.async_set_hvac_mode(HVACMode(hvac_mode)) if self.data.step >= 1:
if hvac_mode == HVACMode.OFF: temperature = int(temperature)
return if temperature != self.target_temperature:
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is not None:
if (
target_temp := self._round_by_step(temperature)
) != self.target_temperature:
await self.async_call_api( await self.async_call_api(
self.coordinator.api.async_set_target_temperature( self.coordinator.api.async_set_target_temperature(
self.property_id, target_temp self.property_id,
temperature,
) )
) )
if (temperature_low := kwargs.get(ATTR_TARGET_TEMP_LOW)) is not None: if (temperature_low := kwargs.get(ATTR_TARGET_TEMP_LOW)) and (
if ( temperature_high := kwargs.get(ATTR_TARGET_TEMP_HIGH)
target_temp_low := self._round_by_step(temperature_low) ):
) != self.target_temperature_low: if self.data.step >= 1:
temperature_low = int(temperature_low)
temperature_high = int(temperature_high)
await self.async_call_api( await self.async_call_api(
self.coordinator.api.async_set_target_temperature_low( self.coordinator.api.async_set_target_temperature_low_high(
self.property_id, target_temp_low self.property_id,
) temperature_low,
) temperature_high,
if (temperature_high := kwargs.get(ATTR_TARGET_TEMP_HIGH)) is not None:
if (
target_temp_high := self._round_by_step(temperature_high)
) != self.target_temperature_high:
await self.async_call_api(
self.coordinator.api.async_set_target_temperature_high(
self.property_id, target_temp_high
) )
) )

View File

@ -18,6 +18,7 @@
'max_temp': 86, 'max_temp': 86,
'min_temp': 64, 'min_temp': 64,
'preset_modes': list([ 'preset_modes': list([
'none',
'air_clean', 'air_clean',
]), ]),
'swing_horizontal_modes': list([ 'swing_horizontal_modes': list([
@ -78,8 +79,9 @@
]), ]),
'max_temp': 86, 'max_temp': 86,
'min_temp': 64, 'min_temp': 64,
'preset_mode': None, 'preset_mode': 'none',
'preset_modes': list([ 'preset_modes': list([
'none',
'air_clean', 'air_clean',
]), ]),
'supported_features': <ClimateEntityFeature: 955>, 'supported_features': <ClimateEntityFeature: 955>,