Skip to content

Commit 414844c

Browse files
committed
Further reduce complexity of _logs_missing()
1 parent 500fc36 commit 414844c

File tree

1 file changed

+51
-40
lines changed

1 file changed

+51
-40
lines changed

plugwise_usb/nodes/helpers/pulses.py

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -819,28 +819,44 @@ def _logs_missing(self, from_timestamp: datetime) -> list[int] | None:
819819
first = self._first_log_reference()
820820
last = self._last_log_reference()
821821

822-
if None in first or None in last:
823-
_LOGGER.debug(
824-
"_logs_missing | %s | first=%s, last=%s", self._mac, first, last
825-
)
822+
if not self._valid_log_references(first, last):
826823
return None
827824

825+
if self._is_single_unique_log(first, last):
826+
return None
827+
828+
if (missing := self._find_missing_in_range(first, last, from_timestamp)):
829+
return missing
830+
828831
first_address, first_slot = first
829-
last_address, last_slot = last
832+
if not self._is_first_log_recent_enough(first_address, first_slot, from_timestamp):
833+
return []
830834

831-
if (
832-
first == last and
833-
self._logs[first_address][first_slot].timestamp == self._logs[last_address][last_slot].timestamp
834-
):
835-
return None # Only one unique log, not enough to work with
835+
return self._calculate_missing_before_first(first_address, first_slot, from_timestamp)
836836

837-
missing = []
838-
_LOGGER.debug(
839-
"_logs_missing | %s | first_address=%s, last_address=%s",
840-
self._mac, first_address, last_address
837+
# --- Helper Methods for _logs_missing() ---
838+
839+
def _valid_log_references(self, first, last) -> bool:
840+
if None in first or None in last:
841+
_LOGGER.debug("_logs_missing | %s | first=%s, last=%s", self._mac, first, last)
842+
return False
843+
return True
844+
845+
def _is_single_unique_log(self, first, last) -> bool:
846+
if first != last:
847+
return False
848+
849+
address, slot = first
850+
return (
851+
self._logs[address][slot].timestamp
852+
== self._logs[last[0]][last[1]].timestamp
841853
)
842854

843-
# Check for missing logs in the collected range
855+
def _find_missing_in_range(self, first, last, from_timestamp) -> list[int]:
856+
first_address, first_slot = first
857+
last_address, last_slot = last
858+
missing = []
859+
844860
address, slot = last_address, last_slot
845861
while (address, slot) != (first_address, first_slot):
846862
address, slot = calc_log_address(address, slot, -1)
@@ -853,49 +869,44 @@ def _logs_missing(self, from_timestamp: datetime) -> list[int] | None:
853869

854870
if missing:
855871
_LOGGER.debug("_logs_missing | %s | missing in range=%s", self._mac, missing)
856-
return missing
857-
858-
# Check if first slot exists and is recent enough
859-
if (
860-
first_address not in self._logs or
861-
first_slot not in self._logs[first_address] or
862-
self._logs[first_address][first_slot].timestamp < from_timestamp
863-
):
864-
return []
872+
return missing
865873

866-
# Estimate log interval
867-
log_interval = self._log_interval_consumption or self._log_interval_production
868-
if (
869-
self._log_interval_production is not None and
870-
log_interval is not None and
871-
self._log_interval_production < log_interval
872-
):
873-
log_interval = self._log_interval_production
874+
def _is_first_log_recent_enough(self, address, slot, from_timestamp) -> bool:
875+
return (
876+
address in self._logs and
877+
slot in self._logs[address] and
878+
self._logs[address][slot].timestamp >= from_timestamp
879+
)
874880

875-
if log_interval is None:
881+
def _calculate_missing_before_first(self, first_address, first_slot, from_timestamp) -> list[int] | None:
882+
if (log_interval := self._get_log_interval()) is None:
876883
return None
877884

878-
# Walk backward before the first known log to find additional missing logs
879885
timestamp = self._logs[first_address][first_slot].timestamp
880886
calc_timestamp = timestamp - timedelta(minutes=log_interval)
881887
address, slot = calc_log_address(first_address, first_slot, -1)
882888

883-
_LOGGER.debug(
884-
"_logs_missing | %s | calculated timestamp=%s", self._mac, calc_timestamp
885-
)
886-
889+
missing = []
887890
while calc_timestamp > from_timestamp:
888891
if (address, slot) == (self._first_empty_log_address, self._first_empty_log_slot):
889892
break
890-
if address not in missing:
891-
missing.append(address)
893+
missing = update_addresses(address, missing)
892894
calc_timestamp -= timedelta(minutes=log_interval)
893895
address, slot = calc_log_address(address, slot, -1)
894896

895897
missing.sort(reverse=True)
896898
_LOGGER.debug("_logs_missing | %s | calculated missing=%s", self._mac, missing)
897899
return missing
898900

901+
def _get_log_interval(self) -> int | None:
902+
log_interval = self._log_interval_consumption or self._log_interval_production
903+
if (
904+
self._log_interval_production is not None and
905+
log_interval is not None and
906+
self._log_interval_production < log_interval
907+
):
908+
log_interval = self._log_interval_production
909+
return log_interval
899910

900911
def _last_known_duration(self) -> timedelta:
901912
"""Duration for last known logs."""

0 commit comments

Comments
 (0)