mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Add remain, running, schedule time sensors to LG ThinQ (#131133)
Co-authored-by: yunseon.park <yunseon.park@lge.com>
This commit is contained in:
parent
3a0072d42d
commit
98ef32c668
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from datetime import datetime, time, timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from thinqconnect import DeviceType
|
from thinqconnect import DeviceType
|
||||||
@ -22,6 +23,7 @@ from homeassistant.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
from . import ThinqConfigEntry
|
from . import ThinqConfigEntry
|
||||||
from .coordinator import DeviceDataUpdateCoordinator
|
from .coordinator import DeviceDataUpdateCoordinator
|
||||||
@ -93,6 +95,11 @@ FILTER_INFO_SENSOR_DESC: dict[ThinQProperty, SensorEntityDescription] = {
|
|||||||
native_unit_of_measurement=UnitOfTime.HOURS,
|
native_unit_of_measurement=UnitOfTime.HOURS,
|
||||||
translation_key=ThinQProperty.FILTER_LIFETIME,
|
translation_key=ThinQProperty.FILTER_LIFETIME,
|
||||||
),
|
),
|
||||||
|
ThinQProperty.FILTER_REMAIN_PERCENT: SensorEntityDescription(
|
||||||
|
key=ThinQProperty.FILTER_REMAIN_PERCENT,
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
translation_key=ThinQProperty.FILTER_LIFETIME,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
HUMIDITY_SENSOR_DESC: dict[ThinQProperty, SensorEntityDescription] = {
|
HUMIDITY_SENSOR_DESC: dict[ThinQProperty, SensorEntityDescription] = {
|
||||||
ThinQProperty.CURRENT_HUMIDITY: SensorEntityDescription(
|
ThinQProperty.CURRENT_HUMIDITY: SensorEntityDescription(
|
||||||
@ -255,9 +262,90 @@ WATER_INFO_SENSOR_DESC: dict[ThinQProperty, SensorEntityDescription] = {
|
|||||||
translation_key=ThinQProperty.WATER_TYPE,
|
translation_key=ThinQProperty.WATER_TYPE,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
ELAPSED_DAY_SENSOR_DESC: dict[ThinQProperty, SensorEntityDescription] = {
|
||||||
|
ThinQProperty.ELAPSED_DAY_STATE: SensorEntityDescription(
|
||||||
|
key=ThinQProperty.ELAPSED_DAY_STATE,
|
||||||
|
device_class=SensorDeviceClass.DURATION,
|
||||||
|
native_unit_of_measurement=UnitOfTime.DAYS,
|
||||||
|
translation_key=ThinQProperty.ELAPSED_DAY_STATE,
|
||||||
|
),
|
||||||
|
ThinQProperty.ELAPSED_DAY_TOTAL: SensorEntityDescription(
|
||||||
|
key=ThinQProperty.ELAPSED_DAY_TOTAL,
|
||||||
|
device_class=SensorDeviceClass.DURATION,
|
||||||
|
native_unit_of_measurement=UnitOfTime.DAYS,
|
||||||
|
translation_key=ThinQProperty.ELAPSED_DAY_TOTAL,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
TIME_SENSOR_DESC: dict[ThinQProperty, SensorEntityDescription] = {
|
||||||
|
TimerProperty.LIGHT_START: SensorEntityDescription(
|
||||||
|
key=TimerProperty.LIGHT_START,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
translation_key=TimerProperty.LIGHT_START,
|
||||||
|
),
|
||||||
|
TimerProperty.ABSOLUTE_TO_START: SensorEntityDescription(
|
||||||
|
key=TimerProperty.ABSOLUTE_TO_START,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
translation_key=TimerProperty.ABSOLUTE_TO_START,
|
||||||
|
),
|
||||||
|
TimerProperty.ABSOLUTE_TO_STOP: SensorEntityDescription(
|
||||||
|
key=TimerProperty.ABSOLUTE_TO_STOP,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
translation_key=TimerProperty.ABSOLUTE_TO_STOP,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
TIMER_SENSOR_DESC: dict[ThinQProperty, SensorEntityDescription] = {
|
||||||
|
TimerProperty.TOTAL: SensorEntityDescription(
|
||||||
|
key=TimerProperty.TOTAL,
|
||||||
|
device_class=SensorDeviceClass.DURATION,
|
||||||
|
native_unit_of_measurement=UnitOfTime.MINUTES,
|
||||||
|
translation_key=TimerProperty.TOTAL,
|
||||||
|
),
|
||||||
|
TimerProperty.RELATIVE_TO_START: SensorEntityDescription(
|
||||||
|
key=TimerProperty.RELATIVE_TO_START,
|
||||||
|
device_class=SensorDeviceClass.DURATION,
|
||||||
|
native_unit_of_measurement=UnitOfTime.MINUTES,
|
||||||
|
translation_key=TimerProperty.RELATIVE_TO_START,
|
||||||
|
),
|
||||||
|
TimerProperty.RELATIVE_TO_STOP: SensorEntityDescription(
|
||||||
|
key=TimerProperty.RELATIVE_TO_STOP,
|
||||||
|
device_class=SensorDeviceClass.DURATION,
|
||||||
|
native_unit_of_measurement=UnitOfTime.MINUTES,
|
||||||
|
translation_key=TimerProperty.RELATIVE_TO_STOP,
|
||||||
|
),
|
||||||
|
TimerProperty.SLEEP_TIMER_RELATIVE_TO_STOP: SensorEntityDescription(
|
||||||
|
key=TimerProperty.SLEEP_TIMER_RELATIVE_TO_STOP,
|
||||||
|
device_class=SensorDeviceClass.DURATION,
|
||||||
|
native_unit_of_measurement=UnitOfTime.MINUTES,
|
||||||
|
translation_key=TimerProperty.SLEEP_TIMER_RELATIVE_TO_STOP,
|
||||||
|
),
|
||||||
|
TimerProperty.RELATIVE_TO_START_WM: SensorEntityDescription(
|
||||||
|
key=TimerProperty.RELATIVE_TO_START,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
translation_key=TimerProperty.RELATIVE_TO_START_WM,
|
||||||
|
),
|
||||||
|
TimerProperty.RELATIVE_TO_STOP_WM: SensorEntityDescription(
|
||||||
|
key=TimerProperty.RELATIVE_TO_STOP,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
translation_key=TimerProperty.RELATIVE_TO_STOP_WM,
|
||||||
|
),
|
||||||
|
TimerProperty.REMAIN: SensorEntityDescription(
|
||||||
|
key=TimerProperty.REMAIN,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
translation_key=TimerProperty.REMAIN,
|
||||||
|
),
|
||||||
|
TimerProperty.RUNNING: SensorEntityDescription(
|
||||||
|
key=TimerProperty.RUNNING,
|
||||||
|
device_class=SensorDeviceClass.TIMESTAMP,
|
||||||
|
translation_key=TimerProperty.RUNNING,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
WASHER_SENSORS: tuple[SensorEntityDescription, ...] = (
|
WASHER_SENSORS: tuple[SensorEntityDescription, ...] = (
|
||||||
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.TOTAL],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.RELATIVE_TO_START_WM],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.RELATIVE_TO_STOP_WM],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.REMAIN],
|
||||||
)
|
)
|
||||||
DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] = {
|
DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] = {
|
||||||
DeviceType.AIR_CONDITIONER: (
|
DeviceType.AIR_CONDITIONER: (
|
||||||
@ -268,6 +356,12 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.ODOR_LEVEL],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.ODOR_LEVEL],
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
||||||
FILTER_INFO_SENSOR_DESC[ThinQProperty.FILTER_LIFETIME],
|
FILTER_INFO_SENSOR_DESC[ThinQProperty.FILTER_LIFETIME],
|
||||||
|
FILTER_INFO_SENSOR_DESC[ThinQProperty.FILTER_REMAIN_PERCENT],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.RELATIVE_TO_START],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.RELATIVE_TO_STOP],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.SLEEP_TIMER_RELATIVE_TO_STOP],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_START],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_STOP],
|
||||||
),
|
),
|
||||||
DeviceType.AIR_PURIFIER_FAN: (
|
DeviceType.AIR_PURIFIER_FAN: (
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.PM1],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.PM1],
|
||||||
@ -278,6 +372,9 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.MONITORING_ENABLED],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.MONITORING_ENABLED],
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.ODOR_LEVEL],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.ODOR_LEVEL],
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.SLEEP_TIMER_RELATIVE_TO_STOP],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_START],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_STOP],
|
||||||
),
|
),
|
||||||
DeviceType.AIR_PURIFIER: (
|
DeviceType.AIR_PURIFIER: (
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.PM1],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.PM1],
|
||||||
@ -287,8 +384,11 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.MONITORING_ENABLED],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.MONITORING_ENABLED],
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.ODOR_LEVEL],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.ODOR_LEVEL],
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
||||||
|
FILTER_INFO_SENSOR_DESC[ThinQProperty.FILTER_REMAIN_PERCENT],
|
||||||
JOB_MODE_SENSOR_DESC[ThinQProperty.CURRENT_JOB_MODE],
|
JOB_MODE_SENSOR_DESC[ThinQProperty.CURRENT_JOB_MODE],
|
||||||
JOB_MODE_SENSOR_DESC[ThinQProperty.PERSONALIZATION_MODE],
|
JOB_MODE_SENSOR_DESC[ThinQProperty.PERSONALIZATION_MODE],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_START],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_STOP],
|
||||||
),
|
),
|
||||||
DeviceType.COOKTOP: (
|
DeviceType.COOKTOP: (
|
||||||
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
||||||
@ -303,6 +403,9 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
PREFERENCE_SENSOR_DESC[ThinQProperty.RINSE_LEVEL],
|
PREFERENCE_SENSOR_DESC[ThinQProperty.RINSE_LEVEL],
|
||||||
PREFERENCE_SENSOR_DESC[ThinQProperty.SOFTENING_LEVEL],
|
PREFERENCE_SENSOR_DESC[ThinQProperty.SOFTENING_LEVEL],
|
||||||
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.TOTAL],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.RELATIVE_TO_START_WM],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.REMAIN],
|
||||||
),
|
),
|
||||||
DeviceType.DRYER: WASHER_SENSORS,
|
DeviceType.DRYER: WASHER_SENSORS,
|
||||||
DeviceType.HOME_BREW: (
|
DeviceType.HOME_BREW: (
|
||||||
@ -313,6 +416,8 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
RECIPE_SENSOR_DESC[ThinQProperty.FLAVOR_INFO],
|
RECIPE_SENSOR_DESC[ThinQProperty.FLAVOR_INFO],
|
||||||
RECIPE_SENSOR_DESC[ThinQProperty.BEER_REMAIN],
|
RECIPE_SENSOR_DESC[ThinQProperty.BEER_REMAIN],
|
||||||
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
||||||
|
ELAPSED_DAY_SENSOR_DESC[ThinQProperty.ELAPSED_DAY_STATE],
|
||||||
|
ELAPSED_DAY_SENSOR_DESC[ThinQProperty.ELAPSED_DAY_TOTAL],
|
||||||
),
|
),
|
||||||
DeviceType.HUMIDIFIER: (
|
DeviceType.HUMIDIFIER: (
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.PM1],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.PM1],
|
||||||
@ -322,6 +427,9 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TEMPERATURE],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TEMPERATURE],
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.MONITORING_ENABLED],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.MONITORING_ENABLED],
|
||||||
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
AIR_QUALITY_SENSOR_DESC[ThinQProperty.TOTAL_POLLUTION_LEVEL],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.SLEEP_TIMER_RELATIVE_TO_STOP],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_START],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_STOP],
|
||||||
),
|
),
|
||||||
DeviceType.KIMCHI_REFRIGERATOR: (
|
DeviceType.KIMCHI_REFRIGERATOR: (
|
||||||
REFRIGERATION_SENSOR_DESC[ThinQProperty.FRESH_AIR_FILTER],
|
REFRIGERATION_SENSOR_DESC[ThinQProperty.FRESH_AIR_FILTER],
|
||||||
@ -344,6 +452,7 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
TEMPERATURE_SENSOR_DESC[ThinQProperty.DAY_TARGET_TEMPERATURE],
|
TEMPERATURE_SENSOR_DESC[ThinQProperty.DAY_TARGET_TEMPERATURE],
|
||||||
TEMPERATURE_SENSOR_DESC[ThinQProperty.NIGHT_TARGET_TEMPERATURE],
|
TEMPERATURE_SENSOR_DESC[ThinQProperty.NIGHT_TARGET_TEMPERATURE],
|
||||||
TEMPERATURE_SENSOR_DESC[ThinQProperty.TEMPERATURE_STATE],
|
TEMPERATURE_SENSOR_DESC[ThinQProperty.TEMPERATURE_STATE],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.LIGHT_START],
|
||||||
),
|
),
|
||||||
DeviceType.REFRIGERATOR: (
|
DeviceType.REFRIGERATOR: (
|
||||||
REFRIGERATION_SENSOR_DESC[ThinQProperty.FRESH_AIR_FILTER],
|
REFRIGERATION_SENSOR_DESC[ThinQProperty.FRESH_AIR_FILTER],
|
||||||
@ -352,6 +461,8 @@ DEVICE_TYPE_SENSOR_MAP: dict[DeviceType, tuple[SensorEntityDescription, ...]] =
|
|||||||
DeviceType.ROBOT_CLEANER: (
|
DeviceType.ROBOT_CLEANER: (
|
||||||
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
RUN_STATE_SENSOR_DESC[ThinQProperty.CURRENT_STATE],
|
||||||
JOB_MODE_SENSOR_DESC[ThinQProperty.CURRENT_JOB_MODE],
|
JOB_MODE_SENSOR_DESC[ThinQProperty.CURRENT_JOB_MODE],
|
||||||
|
TIMER_SENSOR_DESC[TimerProperty.RUNNING],
|
||||||
|
TIME_SENSOR_DESC[TimerProperty.ABSOLUTE_TO_START],
|
||||||
),
|
),
|
||||||
DeviceType.STICK_CLEANER: (
|
DeviceType.STICK_CLEANER: (
|
||||||
BATTERY_SENSOR_DESC[ThinQProperty.BATTERY_PERCENT],
|
BATTERY_SENSOR_DESC[ThinQProperty.BATTERY_PERCENT],
|
||||||
@ -426,11 +537,59 @@ class ThinQSensorEntity(ThinQEntity, SensorEntity):
|
|||||||
if entity_description.device_class == SensorDeviceClass.ENUM:
|
if entity_description.device_class == SensorDeviceClass.ENUM:
|
||||||
self._attr_options = self.data.options
|
self._attr_options = self.data.options
|
||||||
|
|
||||||
|
self._device_state: str | None = None
|
||||||
|
self._device_state_id = (
|
||||||
|
ThinQProperty.CURRENT_STATE
|
||||||
|
if self.location is None
|
||||||
|
else f"{self.location}_{ThinQProperty.CURRENT_STATE}"
|
||||||
|
)
|
||||||
|
|
||||||
def _update_status(self) -> None:
|
def _update_status(self) -> None:
|
||||||
"""Update status itself."""
|
"""Update status itself."""
|
||||||
super()._update_status()
|
super()._update_status()
|
||||||
|
|
||||||
self._attr_native_value = self.data.value
|
value = self.data.value
|
||||||
|
|
||||||
|
if isinstance(value, time):
|
||||||
|
local_now = datetime.now(
|
||||||
|
tz=dt_util.get_time_zone(self.coordinator.hass.config.time_zone)
|
||||||
|
)
|
||||||
|
if value in [0, None, time.min]:
|
||||||
|
# Reset to None
|
||||||
|
value = None
|
||||||
|
elif self.entity_description.device_class == SensorDeviceClass.TIMESTAMP:
|
||||||
|
if self.entity_description.key in TIME_SENSOR_DESC:
|
||||||
|
# Set timestamp for time
|
||||||
|
value = local_now.replace(hour=value.hour, minute=value.minute)
|
||||||
|
else:
|
||||||
|
# Set timestamp for delta
|
||||||
|
new_state = (
|
||||||
|
self.coordinator.data[self._device_state_id].value
|
||||||
|
if self._device_state_id in self.coordinator.data
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
self.native_value is not None
|
||||||
|
and self._device_state == new_state
|
||||||
|
):
|
||||||
|
# Skip update when same state
|
||||||
|
return
|
||||||
|
|
||||||
|
self._device_state = new_state
|
||||||
|
time_delta = timedelta(
|
||||||
|
hours=value.hour, minutes=value.minute, seconds=value.second
|
||||||
|
)
|
||||||
|
value = (
|
||||||
|
(local_now - time_delta)
|
||||||
|
if self.entity_description.key == TimerProperty.RUNNING
|
||||||
|
else (local_now + time_delta)
|
||||||
|
)
|
||||||
|
elif self.entity_description.device_class == SensorDeviceClass.DURATION:
|
||||||
|
# Set duration
|
||||||
|
value = self._get_duration(
|
||||||
|
value, self.entity_description.native_unit_of_measurement
|
||||||
|
)
|
||||||
|
self._attr_native_value = value
|
||||||
|
|
||||||
if (data_unit := self._get_unit_of_measurement(self.data.unit)) is not None:
|
if (data_unit := self._get_unit_of_measurement(self.data.unit)) is not None:
|
||||||
# For different from description's unit
|
# For different from description's unit
|
||||||
@ -445,3 +604,10 @@ class ThinQSensorEntity(ThinQEntity, SensorEntity):
|
|||||||
self.options,
|
self.options,
|
||||||
self.native_unit_of_measurement,
|
self.native_unit_of_measurement,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _get_duration(self, data: time, unit: str | None) -> float | None:
|
||||||
|
if unit == UnitOfTime.MINUTES:
|
||||||
|
return (data.hour * 60) + data.minute
|
||||||
|
if unit == UnitOfTime.SECONDS:
|
||||||
|
return (data.hour * 3600) + (data.minute * 60) + data.second
|
||||||
|
return 0
|
||||||
|
@ -203,3 +203,146 @@
|
|||||||
'state': '24',
|
'state': '24',
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
# name: test_all_entities[sensor.test_air_conditioner_schedule_turn_off-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.test_air_conditioner_schedule_turn_off',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Schedule turn-off',
|
||||||
|
'platform': 'lg_thinq',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': <TimerProperty.RELATIVE_TO_STOP: 'relative_to_stop'>,
|
||||||
|
'unique_id': 'MW2-2E247F93-B570-46A6-B827-920E9E10F966_relative_to_stop',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_all_entities[sensor.test_air_conditioner_schedule_turn_off-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Test air conditioner Schedule turn-off',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.test_air_conditioner_schedule_turn_off',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'unknown',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_all_entities[sensor.test_air_conditioner_schedule_turn_on-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.test_air_conditioner_schedule_turn_on',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Schedule turn-on',
|
||||||
|
'platform': 'lg_thinq',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': <TimerProperty.RELATIVE_TO_START: 'relative_to_start'>,
|
||||||
|
'unique_id': 'MW2-2E247F93-B570-46A6-B827-920E9E10F966_relative_to_start',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_all_entities[sensor.test_air_conditioner_schedule_turn_on-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Test air conditioner Schedule turn-on',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.test_air_conditioner_schedule_turn_on',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'unknown',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_all_entities[sensor.test_air_conditioner_schedule_turn_on_2-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'sensor',
|
||||||
|
'entity_category': None,
|
||||||
|
'entity_id': 'sensor.test_air_conditioner_schedule_turn_on_2',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Schedule turn-on',
|
||||||
|
'platform': 'lg_thinq',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': <TimerProperty.ABSOLUTE_TO_START: 'absolute_to_start'>,
|
||||||
|
'unique_id': 'MW2-2E247F93-B570-46A6-B827-920E9E10F966_absolute_to_start',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_all_entities[sensor.test_air_conditioner_schedule_turn_on_2-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'timestamp',
|
||||||
|
'friendly_name': 'Test air conditioner Schedule turn-on',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'sensor.test_air_conditioner_schedule_turn_on_2',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '2024-10-10T13:14:00+00:00',
|
||||||
|
})
|
||||||
|
# ---
|
@ -1,5 +1,6 @@
|
|||||||
"""Tests for the LG Thinq sensor platform."""
|
"""Tests for the LG Thinq sensor platform."""
|
||||||
|
|
||||||
|
from datetime import UTC, datetime
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -15,6 +16,7 @@ from tests.common import MockConfigEntry, snapshot_platform
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||||
|
@pytest.mark.freeze_time(datetime(2024, 10, 10, tzinfo=UTC))
|
||||||
async def test_all_entities(
|
async def test_all_entities(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
snapshot: SnapshotAssertion,
|
snapshot: SnapshotAssertion,
|
||||||
@ -23,6 +25,7 @@ async def test_all_entities(
|
|||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test all entities."""
|
"""Test all entities."""
|
||||||
|
hass.config.time_zone = "UTC"
|
||||||
with patch("homeassistant.components.lg_thinq.PLATFORMS", [Platform.SENSOR]):
|
with patch("homeassistant.components.lg_thinq.PLATFORMS", [Platform.SENSOR]):
|
||||||
await setup_integration(hass, mock_config_entry)
|
await setup_integration(hass, mock_config_entry)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user