Get temperature data appropriate for hass.config.unit in LG ThinQ (#137626)

* Get temperature data appropriate for hass.config.unit

* Modify temperature_unit for init

* Modify unit's map

* Fix ruff error

---------

Co-authored-by: yunseon.park <yunseon.park@lge.com>
This commit is contained in:
LG-ThinQ-Integration 2025-03-05 20:13:11 +09:00 committed by GitHub
parent 7fe75a959f
commit df2248bb82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 67 additions and 20 deletions

View File

@ -110,7 +110,9 @@ 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 = []
self._attr_temperature_unit = UnitOfTemperature.CELSIUS self._attr_temperature_unit = (
self._get_unit_of_measurement(self.data.unit) or UnitOfTemperature.CELSIUS
)
self._requested_hvac_mode: str | None = None self._requested_hvac_mode: str | None = None
# Set up HVAC modes. # Set up HVAC modes.
@ -182,6 +184,11 @@ class ThinQClimateEntity(ThinQEntity, ClimateEntity):
self._attr_target_temperature_high = self.data.target_temp_high self._attr_target_temperature_high = self.data.target_temp_high
self._attr_target_temperature_low = self.data.target_temp_low self._attr_target_temperature_low = self.data.target_temp_low
# Update unit.
self._attr_temperature_unit = (
self._get_unit_of_measurement(self.data.unit) or UnitOfTemperature.CELSIUS
)
_LOGGER.debug( _LOGGER.debug(
"[%s:%s] update status: c:%s, t:%s, l:%s, h:%s, hvac:%s, unit:%s, step:%s", "[%s:%s] update status: c:%s, t:%s, l:%s, h:%s, hvac:%s, unit:%s, step:%s",
self.coordinator.device_name, self.coordinator.device_name,

View File

@ -3,6 +3,8 @@
from datetime import timedelta from datetime import timedelta
from typing import Final from typing import Final
from homeassistant.const import UnitOfTemperature
# Config flow # Config flow
DOMAIN = "lg_thinq" DOMAIN = "lg_thinq"
COMPANY = "LGE" COMPANY = "LGE"
@ -18,3 +20,10 @@ MQTT_SUBSCRIPTION_INTERVAL: Final = timedelta(days=1)
# MQTT: Message types # MQTT: Message types
DEVICE_PUSH_MESSAGE: Final = "DEVICE_PUSH" DEVICE_PUSH_MESSAGE: Final = "DEVICE_PUSH"
DEVICE_STATUS_MESSAGE: Final = "DEVICE_STATUS" DEVICE_STATUS_MESSAGE: Final = "DEVICE_STATUS"
# Unit conversion map
DEVICE_UNIT_TO_HA: dict[str, str] = {
"F": UnitOfTemperature.FAHRENHEIT,
"C": UnitOfTemperature.CELSIUS,
}
REVERSE_DEVICE_UNIT_TO_HA = {v: k for k, v in DEVICE_UNIT_TO_HA.items()}

View File

@ -2,19 +2,21 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Mapping
import logging import logging
from typing import TYPE_CHECKING, Any from typing import TYPE_CHECKING, Any
from thinqconnect import ThinQAPIException from thinqconnect import ThinQAPIException
from thinqconnect.integration import HABridge from thinqconnect.integration import HABridge
from homeassistant.core import HomeAssistant from homeassistant.const import EVENT_CORE_CONFIG_UPDATE
from homeassistant.core import Event, HomeAssistant, callback
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
if TYPE_CHECKING: if TYPE_CHECKING:
from . import ThinqConfigEntry from . import ThinqConfigEntry
from .const import DOMAIN from .const import DOMAIN, REVERSE_DEVICE_UNIT_TO_HA
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -54,6 +56,40 @@ class DeviceDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
f"{self.device_id}_{self.sub_id}" if self.sub_id else self.device_id f"{self.device_id}_{self.sub_id}" if self.sub_id else self.device_id
) )
# Set your preferred temperature unit. This will allow us to retrieve
# temperature values from the API in a converted value corresponding to
# preferred unit.
self._update_preferred_temperature_unit()
# Add a callback to handle core config update.
self.unit_system: str | None = None
self.hass.bus.async_listen(
event_type=EVENT_CORE_CONFIG_UPDATE,
listener=self._handle_update_config,
event_filter=self.async_config_update_filter,
)
async def _handle_update_config(self, _: Event) -> None:
"""Handle update core config."""
self._update_preferred_temperature_unit()
await self.async_refresh()
@callback
def async_config_update_filter(self, event_data: Mapping[str, Any]) -> bool:
"""Filter out unwanted events."""
if (unit_system := event_data.get("unit_system")) != self.unit_system:
self.unit_system = unit_system
return True
return False
def _update_preferred_temperature_unit(self) -> None:
"""Update preferred temperature unit."""
self.api.set_preferred_temperature_unit(
REVERSE_DEVICE_UNIT_TO_HA.get(self.hass.config.units.temperature_unit)
)
async def _async_update_data(self) -> dict[str, Any]: async def _async_update_data(self) -> dict[str, Any]:
"""Request to the server to update the status from full response data.""" """Request to the server to update the status from full response data."""
try: try:

View File

@ -10,25 +10,19 @@ from thinqconnect import ThinQAPIException
from thinqconnect.devices.const import Location from thinqconnect.devices.const import Location
from thinqconnect.integration import PropertyState from thinqconnect.integration import PropertyState
from homeassistant.const import UnitOfTemperature
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.exceptions import ServiceValidationError from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import COMPANY, DOMAIN from .const import COMPANY, DEVICE_UNIT_TO_HA, DOMAIN
from .coordinator import DeviceDataUpdateCoordinator from .coordinator import DeviceDataUpdateCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
EMPTY_STATE = PropertyState() EMPTY_STATE = PropertyState()
UNIT_CONVERSION_MAP: dict[str, str] = {
"F": UnitOfTemperature.FAHRENHEIT,
"C": UnitOfTemperature.CELSIUS,
}
class ThinQEntity(CoordinatorEntity[DeviceDataUpdateCoordinator]): class ThinQEntity(CoordinatorEntity[DeviceDataUpdateCoordinator]):
"""The base implementation of all lg thinq entities.""" """The base implementation of all lg thinq entities."""
@ -75,7 +69,7 @@ class ThinQEntity(CoordinatorEntity[DeviceDataUpdateCoordinator]):
if unit is None: if unit is None:
return None return None
return UNIT_CONVERSION_MAP.get(unit) return DEVICE_UNIT_TO_HA.get(unit)
def _update_status(self) -> None: def _update_status(self) -> None:
"""Update status itself. """Update status itself.

View File

@ -15,8 +15,8 @@
<HVACMode.COOL: 'cool'>, <HVACMode.COOL: 'cool'>,
<HVACMode.DRY: 'dry'>, <HVACMode.DRY: 'dry'>,
]), ]),
'max_temp': 30, 'max_temp': 86,
'min_temp': 18, 'min_temp': 64,
'preset_modes': list([ 'preset_modes': list([
'air_clean', 'air_clean',
]), ]),
@ -28,7 +28,7 @@
'on', 'on',
'off', 'off',
]), ]),
'target_temp_step': 1, 'target_temp_step': 2,
}), }),
'config_entry_id': <ANY>, 'config_entry_id': <ANY>,
'config_subentry_id': <ANY>, 'config_subentry_id': <ANY>,
@ -62,7 +62,7 @@
StateSnapshot({ StateSnapshot({
'attributes': ReadOnlyDict({ 'attributes': ReadOnlyDict({
'current_humidity': 40, 'current_humidity': 40,
'current_temperature': 25, 'current_temperature': 77,
'fan_mode': 'mid', 'fan_mode': 'mid',
'fan_modes': list([ 'fan_modes': list([
'low', 'low',
@ -75,8 +75,8 @@
<HVACMode.COOL: 'cool'>, <HVACMode.COOL: 'cool'>,
<HVACMode.DRY: 'dry'>, <HVACMode.DRY: 'dry'>,
]), ]),
'max_temp': 30, 'max_temp': 86,
'min_temp': 18, 'min_temp': 64,
'preset_mode': None, 'preset_mode': None,
'preset_modes': list([ 'preset_modes': list([
'air_clean', 'air_clean',
@ -94,8 +94,8 @@
]), ]),
'target_temp_high': None, 'target_temp_high': None,
'target_temp_low': None, 'target_temp_low': None,
'target_temp_step': 1, 'target_temp_step': 2,
'temperature': 19, 'temperature': 66,
}), }),
'context': <ANY>, 'context': <ANY>,
'entity_id': 'climate.test_air_conditioner', 'entity_id': 'climate.test_air_conditioner',

View File

@ -5,7 +5,7 @@ from unittest.mock import AsyncMock, patch
import pytest import pytest
from syrupy import SnapshotAssertion from syrupy import SnapshotAssertion
from homeassistant.const import Platform from homeassistant.const import Platform, UnitOfTemperature
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
@ -23,6 +23,7 @@ async def test_all_entities(
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
) -> None: ) -> None:
"""Test all entities.""" """Test all entities."""
hass.config.units.temperature_unit = UnitOfTemperature.FAHRENHEIT
with patch("homeassistant.components.lg_thinq.PLATFORMS", [Platform.CLIMATE]): with patch("homeassistant.components.lg_thinq.PLATFORMS", [Platform.CLIMATE]):
await setup_integration(hass, mock_config_entry) await setup_integration(hass, mock_config_entry)