From 2f6fa51a74b1a39fe09e5a0dcac3cfb27f0443fb Mon Sep 17 00:00:00 2001 From: "yunseon.park" Date: Fri, 7 Feb 2025 15:04:48 +0900 Subject: [PATCH 1/4] Get temperature data appropriate for hass.config.unit --- homeassistant/components/lg_thinq/climate.py | 9 +++- .../components/lg_thinq/coordinator.py | 43 ++++++++++++++++++- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/lg_thinq/climate.py b/homeassistant/components/lg_thinq/climate.py index 5cf9ccbd442f44..f98862d25d047a 100644 --- a/homeassistant/components/lg_thinq/climate.py +++ b/homeassistant/components/lg_thinq/climate.py @@ -121,7 +121,9 @@ def __init__( self._attr_hvac_modes = [HVACMode.OFF] self._attr_hvac_mode = HVACMode.OFF self._attr_preset_modes = [] - self._attr_temperature_unit = UnitOfTemperature.CELSIUS + self._attr_temperature_unit = ( + self.coordinator.hass.config.units.temperature_unit + ) self._requested_hvac_mode: str | None = None # Set up HVAC modes. @@ -184,6 +186,11 @@ def _update_status(self) -> None: self._attr_target_temperature_high = self.data.target_temp_high 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( "[%s:%s] update status: c:%s, t:%s, l:%s, h:%s, hvac:%s, unit:%s, step:%s", self.coordinator.device_name, diff --git a/homeassistant/components/lg_thinq/coordinator.py b/homeassistant/components/lg_thinq/coordinator.py index 9f317dc21d969d..1af9a89380cb38 100644 --- a/homeassistant/components/lg_thinq/coordinator.py +++ b/homeassistant/components/lg_thinq/coordinator.py @@ -2,17 +2,24 @@ from __future__ import annotations +from collections.abc import Mapping import logging from typing import Any from thinqconnect import ThinQAPIException from thinqconnect.integration import HABridge -from homeassistant.core import HomeAssistant +from homeassistant.const import EVENT_CORE_CONFIG_UPDATE, UnitOfTemperature +from homeassistant.core import Event, HomeAssistant, callback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN +UNIT_CONVERSION_MAP: dict[str, str] = { + UnitOfTemperature.FAHRENHEIT: "F", + UnitOfTemperature.CELSIUS: "C", +} + _LOGGER = logging.getLogger(__name__) @@ -46,6 +53,40 @@ def __init__(self, hass: HomeAssistant, ha_bridge: HABridge) -> None: 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( + UNIT_CONVERSION_MAP.get(self.hass.config.units.temperature_unit) + ) + async def _async_update_data(self) -> dict[str, Any]: """Request to the server to update the status from full response data.""" try: From e4c48bc5913e8b38c8a2c878098d05c2f5dcd5d1 Mon Sep 17 00:00:00 2001 From: "yunseon.park" Date: Mon, 24 Feb 2025 15:32:51 +0900 Subject: [PATCH 2/4] Modify temperature_unit for init --- homeassistant/components/lg_thinq/climate.py | 2 +- .../lg_thinq/snapshots/test_climate.ambr | 16 ++++++++-------- tests/components/lg_thinq/test_climate.py | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/lg_thinq/climate.py b/homeassistant/components/lg_thinq/climate.py index f98862d25d047a..cd131d93ee506c 100644 --- a/homeassistant/components/lg_thinq/climate.py +++ b/homeassistant/components/lg_thinq/climate.py @@ -122,7 +122,7 @@ def __init__( self._attr_hvac_mode = HVACMode.OFF self._attr_preset_modes = [] self._attr_temperature_unit = ( - self.coordinator.hass.config.units.temperature_unit + self._get_unit_of_measurement(self.data.unit) or UnitOfTemperature.CELSIUS ) self._requested_hvac_mode: str | None = None diff --git a/tests/components/lg_thinq/snapshots/test_climate.ambr b/tests/components/lg_thinq/snapshots/test_climate.ambr index 9369367a1f70d7..642e40154a737a 100644 --- a/tests/components/lg_thinq/snapshots/test_climate.ambr +++ b/tests/components/lg_thinq/snapshots/test_climate.ambr @@ -15,12 +15,12 @@ , , ]), - 'max_temp': 30, - 'min_temp': 18, + 'max_temp': 86, + 'min_temp': 64, 'preset_modes': list([ 'air_clean', ]), - 'target_temp_step': 1, + 'target_temp_step': 2, }), 'config_entry_id': , 'device_class': None, @@ -53,7 +53,7 @@ StateSnapshot({ 'attributes': ReadOnlyDict({ 'current_humidity': 40, - 'current_temperature': 25, + 'current_temperature': 77, 'fan_mode': 'mid', 'fan_modes': list([ 'low', @@ -66,8 +66,8 @@ , , ]), - 'max_temp': 30, - 'min_temp': 18, + 'max_temp': 86, + 'min_temp': 64, 'preset_mode': None, 'preset_modes': list([ 'air_clean', @@ -75,8 +75,8 @@ 'supported_features': , 'target_temp_high': None, 'target_temp_low': None, - 'target_temp_step': 1, - 'temperature': 19, + 'target_temp_step': 2, + 'temperature': 66, }), 'context': , 'entity_id': 'climate.test_air_conditioner', diff --git a/tests/components/lg_thinq/test_climate.py b/tests/components/lg_thinq/test_climate.py index 24ed3ad230dbbd..4ac2fa55a21823 100644 --- a/tests/components/lg_thinq/test_climate.py +++ b/tests/components/lg_thinq/test_climate.py @@ -5,7 +5,7 @@ import pytest from syrupy import SnapshotAssertion -from homeassistant.const import Platform +from homeassistant.const import Platform, UnitOfTemperature from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er @@ -23,6 +23,7 @@ async def test_all_entities( entity_registry: er.EntityRegistry, ) -> None: """Test all entities.""" + hass.config.units.temperature_unit = UnitOfTemperature.FAHRENHEIT with patch("homeassistant.components.lg_thinq.PLATFORMS", [Platform.CLIMATE]): await setup_integration(hass, mock_config_entry) From e59e1a39aa9e95ceed738636c9c0e8455a874431 Mon Sep 17 00:00:00 2001 From: "yunseon.park" Date: Fri, 28 Feb 2025 13:14:17 +0900 Subject: [PATCH 3/4] Modify unit's map --- homeassistant/components/lg_thinq/const.py | 9 +++++++++ homeassistant/components/lg_thinq/coordinator.py | 11 +++-------- homeassistant/components/lg_thinq/entity.py | 10 ++-------- 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/homeassistant/components/lg_thinq/const.py b/homeassistant/components/lg_thinq/const.py index a65dee715db710..20c6455241aa4e 100644 --- a/homeassistant/components/lg_thinq/const.py +++ b/homeassistant/components/lg_thinq/const.py @@ -3,6 +3,8 @@ from datetime import timedelta from typing import Final +from homeassistant.const import UnitOfTemperature + # Config flow DOMAIN = "lg_thinq" COMPANY = "LGE" @@ -18,3 +20,10 @@ # MQTT: Message types DEVICE_PUSH_MESSAGE: Final = "DEVICE_PUSH" 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()} diff --git a/homeassistant/components/lg_thinq/coordinator.py b/homeassistant/components/lg_thinq/coordinator.py index a179c2bf83f968..513cd27a7b23b4 100644 --- a/homeassistant/components/lg_thinq/coordinator.py +++ b/homeassistant/components/lg_thinq/coordinator.py @@ -9,19 +9,14 @@ from thinqconnect import ThinQAPIException from thinqconnect.integration import HABridge -from homeassistant.const import EVENT_CORE_CONFIG_UPDATE, UnitOfTemperature +from homeassistant.const import EVENT_CORE_CONFIG_UPDATE from homeassistant.core import Event, HomeAssistant, callback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed if TYPE_CHECKING: from . import ThinqConfigEntry -from .const import DOMAIN - -UNIT_CONVERSION_MAP: dict[str, str] = { - UnitOfTemperature.FAHRENHEIT: "F", - UnitOfTemperature.CELSIUS: "C", -} +from .const import DOMAIN, REVERSE_DEVICE_UNIT_TO_HA _LOGGER = logging.getLogger(__name__) @@ -92,7 +87,7 @@ def async_config_update_filter(self, event_data: Mapping[str, Any]) -> bool: def _update_preferred_temperature_unit(self) -> None: """Update preferred temperature unit.""" self.api.set_preferred_temperature_unit( - UNIT_CONVERSION_MAP.get(self.hass.config.units.temperature_unit) + REVERSE_DEVICE_UNIT_TO_HA.get(self.hass.config.units.temperature_unit) ) async def _async_update_data(self) -> dict[str, Any]: diff --git a/homeassistant/components/lg_thinq/entity.py b/homeassistant/components/lg_thinq/entity.py index 7856506559b1f7..ed6f33e640d5bb 100644 --- a/homeassistant/components/lg_thinq/entity.py +++ b/homeassistant/components/lg_thinq/entity.py @@ -10,25 +10,19 @@ from thinqconnect.devices.const import Location from thinqconnect.integration import PropertyState -from homeassistant.const import UnitOfTemperature from homeassistant.core import callback from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import device_registry as dr from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import COMPANY, DOMAIN +from .const import COMPANY, DOMAIN, DEVICE_UNIT_TO_HA from .coordinator import DeviceDataUpdateCoordinator _LOGGER = logging.getLogger(__name__) EMPTY_STATE = PropertyState() -UNIT_CONVERSION_MAP: dict[str, str] = { - "F": UnitOfTemperature.FAHRENHEIT, - "C": UnitOfTemperature.CELSIUS, -} - class ThinQEntity(CoordinatorEntity[DeviceDataUpdateCoordinator]): """The base implementation of all lg thinq entities.""" @@ -75,7 +69,7 @@ def _get_unit_of_measurement(self, unit: str | None) -> str | None: if unit is None: return None - return UNIT_CONVERSION_MAP.get(unit) + return DEVICE_UNIT_TO_HA.get(unit) def _update_status(self) -> None: """Update status itself. From 95131a4eb81fc7a52f0c09512c14db1732c3df5c Mon Sep 17 00:00:00 2001 From: "yunseon.park" Date: Wed, 5 Mar 2025 09:07:36 +0900 Subject: [PATCH 4/4] Fix ruff error --- homeassistant/components/lg_thinq/entity.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/lg_thinq/entity.py b/homeassistant/components/lg_thinq/entity.py index ed6f33e640d5bb..61d8199f321914 100644 --- a/homeassistant/components/lg_thinq/entity.py +++ b/homeassistant/components/lg_thinq/entity.py @@ -16,7 +16,7 @@ from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import COMPANY, DOMAIN, DEVICE_UNIT_TO_HA +from .const import COMPANY, DEVICE_UNIT_TO_HA, DOMAIN from .coordinator import DeviceDataUpdateCoordinator _LOGGER = logging.getLogger(__name__)