Skip to content

Commit

Permalink
Merge pull request #249 from Gifford47/main
Browse files Browse the repository at this point in the history
added time and day related evu events (related #38) #248
  • Loading branch information
BenPru authored Oct 5, 2024
2 parents 6f52d16 + dcdb928 commit 80205a0
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions custom_components/luxtronik/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,7 @@ class SensorAttrKey(StrEnum):
EVU_SECOND_START_TIME = "EVU_second_start_time"
EVU_SECOND_END_TIME = "EVU_second_end_time"
EVU_MINUTES_UNTIL_NEXT_EVENT = "EVU_minutes_until_next_event"
EVU_DAYS = "EVU_days"
TIMESTAMP = "timestamp"
CODE = "code"
CAUSE = "cause"
Expand Down
33 changes: 31 additions & 2 deletions custom_components/luxtronik/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from __future__ import annotations

from datetime import date, datetime, time, timezone
import calendar
from decimal import Decimal
from typing import Any

Expand Down Expand Up @@ -182,11 +183,12 @@ class LuxtronikStatusSensorEntity(LuxtronikSensorEntity, SensorEntity):
_coordinator: LuxtronikCoordinator
_last_state: StateType | date | datetime | Decimal = None

_attr_cache: dict[SA, time] = {}
_attr_cache: dict[SA, object] = {}
_attr_cache[SA.EVU_FIRST_START_TIME] = time.min
_attr_cache[SA.EVU_FIRST_END_TIME] = time.min
_attr_cache[SA.EVU_SECOND_START_TIME] = time.min
_attr_cache[SA.EVU_SECOND_END_TIME] = time.min
_attr_cache[SA.EVU_DAYS] = list()

_unrecorded_attributes = frozenset(
LuxtronikSensorEntity._unrecorded_attributes
Expand All @@ -198,6 +200,7 @@ class LuxtronikStatusSensorEntity(LuxtronikSensorEntity, SensorEntity):
SA.EVU_SECOND_START_TIME,
SA.EVU_SECOND_END_TIME,
SA.EVU_MINUTES_UNTIL_NEXT_EVENT,
SA.EVU_DAYS,
}
)

Expand All @@ -212,6 +215,7 @@ def _handle_coordinator_update(
super()._handle_coordinator_update(data)
time_now = time(datetime.now().hour, datetime.now().minute)
evu = LuxOperationMode.evu.value
weekday = datetime.today().weekday()
if self._attr_native_value is None or self._last_state is None:
pass
elif self._attr_native_value == evu and str(self._last_state) != evu:
Expand All @@ -228,6 +232,8 @@ def _handle_coordinator_update(
self._attr_cache[SA.EVU_FIRST_START_TIME] = time_now
else:
self._attr_cache[SA.EVU_SECOND_START_TIME] = time_now
if weekday not in self._attr_cache[SA.EVU_DAYS]:
self._attr_cache[SA.EVU_DAYS].append(weekday)
elif self._attr_native_value != evu and str(self._last_state) == evu:
# evu end
if (
Expand Down Expand Up @@ -319,6 +325,9 @@ def _handle_coordinator_update(
attr[SA.EVU_SECOND_END_TIME] = self._tm_txt(
self._attr_cache[SA.EVU_SECOND_END_TIME]
)
attr[SA.EVU_DAYS] = self._wd_txt(
self._attr_cache[SA.EVU_DAYS]
)
self._enrich_extra_attributes()
self.async_write_ha_state()

Expand Down Expand Up @@ -384,7 +393,19 @@ def _calc_next_evu_event_minutes(self) -> int | None:
if evu_time == time.min:
return None
evu_hours = (24 if evu_time < time_now else 0) + evu_time.hour
return (evu_hours - time_now.hour) * 60 + evu_time.minute - time_now.minute
weekday = datetime.today().weekday()
evu_pause = 0
if not self._attr_cache[SA.EVU_DAYS] and weekday not in self._attr_cache[SA.EVU_DAYS]:
evu_pause += (24 - datetime.now().hour)*60 - datetime.now().minute
for i in range(1, 7):
if weekday+i > 6:
i = -7+i
if weekday+i in self._attr_cache[SA.EVU_DAYS]:
return (evu_hours - time_now.hour) * 60 + evu_time.minute - time_now.minute + evu_pause
else:
evu_pause += 1440
else:
return (evu_hours - time_now.hour) * 60 + evu_time.minute - time_now.minute

def _get_next_evu_event_time(self) -> time:
event: time = time.min
Expand Down Expand Up @@ -415,6 +436,14 @@ def _get_next_evu_event_time(self) -> time:
def _tm_txt(self, value: time) -> str:
return "" if value == time.min else value.strftime("%H:%M")

def _wd_txt(self, value: list) -> str:
if not value:
return ""
days = []
for i in value:
days.append(calendar.day_name[i])
return ','.join(days)

def _restore_attr_value(self, value: Any | None) -> Any:
if value is None or ":" not in str(value):
return time.min
Expand Down
1 change: 1 addition & 0 deletions custom_components/luxtronik/sensor_entities_predefined.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
attr(SA.EVU_FIRST_END_TIME, LC.UNSET, None, True),
attr(SA.EVU_SECOND_START_TIME, LC.UNSET, None, True),
attr(SA.EVU_SECOND_END_TIME, LC.UNSET, None, True),
attr(SA.EVU_DAYS, LC.UNSET, None, True),
),
options=[e.value for e in LuxOperationMode],
update_interval=UPDATE_INTERVAL_NORMAL,
Expand Down

0 comments on commit 80205a0

Please sign in to comment.