Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

range: add oven timers and cook timers #843

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions custom_components/smartthinq_sensors/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,50 @@ class ThinQSensorEntityDescription(SensorEntityDescription):
device_class=SensorDeviceClass.TEMPERATURE,
unit_fn=lambda x: x.oven_temp_unit,
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_UPPER_TIMER_TIME,
name="Oven upper timer",
icon="mdi:timer-outline",
device_class=SensorDeviceClass.TIMESTAMP,
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_UPPER_TIMER_STATE,
name="Oven upper timer state",
icon="mdi:timer-cog-outline",
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_UPPER_COOK_TIMER_TIME,
name="Oven upper cook time",
icon="mdi:timer-check-outline",
device_class=SensorDeviceClass.TIMESTAMP,
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_UPPER_COOK_TIMER_STATE,
name="Oven upper cook time state",
icon="mdi:timer-cog-outline",
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_LOWER_TIMER_TIME,
name="Oven lower timer",
icon="mdi:timer-outline",
device_class=SensorDeviceClass.TIMESTAMP,
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_LOWER_TIMER_STATE,
name="Oven lower timer state",
icon="mdi:timer-cog-outline",
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_LOWER_COOK_TIMER_TIME,
name="Oven lower cook time",
icon="mdi:timer-check-outline",
device_class=SensorDeviceClass.TIMESTAMP,
),
ThinQSensorEntityDescription(
key=RangeFeatures.OVEN_LOWER_COOK_TIMER_STATE,
name="Oven lower cook time state",
icon="mdi:timer-cog-outline",
),
)
AIR_PURIFIER_SENSORS: tuple[ThinQSensorEntityDescription, ...] = (
ThinQSensorEntityDescription(
Expand Down
8 changes: 8 additions & 0 deletions custom_components/smartthinq_sensors/wideq/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ class RangeFeatures(StrEnum):
OVEN_UPPER_CURRENT_TEMP = "oven_upper_current_temp"
OVEN_UPPER_MODE = "oven_upper_mode"
OVEN_UPPER_STATE = "oven_upper_state"
OVEN_UPPER_TIMER_TIME = "oven_upper_timer"
OVEN_UPPER_COOK_TIMER_TIME = "oven_upper_cook_time"
OVEN_LOWER_TIMER_TIME = "oven_lower_timer"
OVEN_LOWER_COOK_TIMER_TIME = "oven_lower_cook_time"
OVEN_UPPER_TIMER_STATE = "oven_upper_timer_state"
OVEN_UPPER_COOK_TIMER_STATE = "oven_upper_cook_timer_state"
OVEN_LOWER_TIMER_STATE = "oven_lower_timer_state"
OVEN_LOWER_COOK_TIMER_STATE = "oven_lower_cook_timer_state"


class RefrigeratorFeatures(StrEnum):
Expand Down
115 changes: 115 additions & 0 deletions custom_components/smartthinq_sensors/wideq/devices/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from __future__ import annotations

from datetime import datetime, timedelta

from ..const import BIT_OFF, RangeFeatures, StateOptions, TemperatureUnit
from ..core_async import ClientAsync
from ..device import Device, DeviceStatus
Expand Down Expand Up @@ -127,6 +129,111 @@ def _get_bit_target_temp(self, key: str):

return target_temp

def _get_time_delta(
self, hour_key: str, min_key: str, sec_key: str
) -> timedelta | None:
"""Get the time remaining as a timedelta."""
try:
hours = self.to_int_or_none(self._data.get(hour_key))
mins = self.to_int_or_none(self._data.get(min_key))
secs = self.to_int_or_none(self._data.get(sec_key))

if any(x is not None for x in (hours, mins, secs)):
return timedelta(hours=hours or 0, minutes=mins or 0, seconds=secs or 0)
except (ValueError, TypeError):
pass
return None

def _get_finish_time(self, delta: timedelta | None) -> datetime | None:
"""Get the finish time based on the time delta."""
if delta is not None:
now = datetime.now().astimezone()
if delta.total_seconds() > 0:
return now + delta
# Return start of current day when timer is 0/off
return now.replace(hour=0, minute=0, second=0, microsecond=0).astimezone()
return None

@property
def oven_upper_timer_time(self) -> datetime | None:
"""Get the upper timer finish time."""
delta = self._get_time_delta("UpperTimerHour", "UpperTimerMin", "UpperTimerSec")
return self._update_feature(
RangeFeatures.OVEN_UPPER_TIMER_TIME, self._get_finish_time(delta), False
)

@property
def oven_upper_cook_timer_time(self) -> datetime | None:
"""Get the upper cook time finish time."""
delta = self._get_time_delta(
"UpperCookTimeHour", "UpperCookTimeMin", "UpperCookTimeSec"
)
return self._update_feature(
RangeFeatures.OVEN_UPPER_COOK_TIMER_TIME,
self._get_finish_time(delta),
False,
)
Comment on lines +165 to +175
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should find a way to check if the device provide this sensor (oven_upper_cook) and if not just return None, otherwise sensor for not existing cook zone will be created.
This is the same for all the other new properties.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. My oven only has upper, so the lower cook zone sensors are non-functional. I'll make the necessary changes for this.

Also, the stove top of my oven only reports whether any of the (five) burners are on, and it uses the front-left cooktop state to report it. So should cooktop state sensors also be modified (in a separate PR) in the same way you're suggesting here?

Thanks.


@property
def oven_lower_timer_time(self) -> datetime | None:
"""Get the lower timer finish time."""
delta = self._get_time_delta("LowerTimerHour", "LowerTimerMin", "LowerTimerSec")
return self._update_feature(
RangeFeatures.OVEN_LOWER_TIMER_TIME, self._get_finish_time(delta), False
)

@property
def oven_lower_cook_timer_time(self) -> datetime | None:
"""Get the lower cook time finish time."""
delta = self._get_time_delta(
"LowerCookTimeHour", "LowerCookTimeMin", "LowerCookTimeSec"
)
return self._update_feature(
RangeFeatures.OVEN_LOWER_COOK_TIMER_TIME,
self._get_finish_time(delta),
False,
)

@property
def oven_upper_timer_state(self) -> str | None:
"""Get the upper timer state."""
delta = self._get_time_delta("UpperTimerHour", "UpperTimerMin", "UpperTimerSec")
state = (
StateOptions.ON if delta and delta.total_seconds() > 0 else StateOptions.OFF
)
return self._update_feature(RangeFeatures.OVEN_UPPER_TIMER_STATE, state)

@property
def oven_upper_cook_timer_state(self) -> str | None:
"""Get the upper cook time state."""
delta = self._get_time_delta(
"UpperCookTimeHour", "UpperCookTimeMin", "UpperCookTimeSec"
)
state = (
StateOptions.ON if delta and delta.total_seconds() > 0 else StateOptions.OFF
)
return self._update_feature(RangeFeatures.OVEN_UPPER_COOK_TIMER_STATE, state)

@property
def oven_lower_timer_state(self) -> str | None:
"""Get the lower timer state."""
delta = self._get_time_delta("LowerTimerHour", "LowerTimerMin", "LowerTimerSec")
state = (
StateOptions.ON if delta and delta.total_seconds() > 0 else StateOptions.OFF
)
return self._update_feature(RangeFeatures.OVEN_LOWER_TIMER_STATE, state)

@property
def oven_lower_cook_timer_state(self) -> str | None:
"""Get the lower cook time state."""
delta = self._get_time_delta(
"LowerCookTimeHour", "LowerCookTimeMin", "LowerCookTimeSec"
)
state = (
StateOptions.ON if delta and delta.total_seconds() > 0 else StateOptions.OFF
)
return self._update_feature(RangeFeatures.OVEN_LOWER_COOK_TIMER_STATE, state)

@property
def is_on(self):
"""Return if device is on."""
Expand Down Expand Up @@ -313,4 +420,12 @@ def _update_features(self):
self.oven_upper_state,
self.oven_upper_mode,
self.oven_upper_current_temp,
self.oven_upper_timer_time,
self.oven_upper_cook_timer_time,
self.oven_lower_timer_time,
self.oven_lower_cook_timer_time,
self.oven_upper_timer_state,
self.oven_upper_cook_timer_state,
self.oven_lower_timer_state,
self.oven_lower_cook_timer_state,
]