@@ -805,122 +805,91 @@ def _first_log_reference(
805805
806806 def _logs_missing (self , from_timestamp : datetime ) -> list [int ] | None :
807807 """Calculate list of missing log addresses."""
808- if self ._logs is None :
808+ if self ._logs is None or self . collected_logs < 2 :
809809 self ._log_addresses_missing = None
810810 return None
811811
812- if self .collected_logs < 2 :
813- return None
812+ first = self ._first_log_reference ()
813+ last = self . _last_log_reference ()
814814
815- last_address , last_slot = self ._last_log_reference ()
816- if last_address is None or last_slot is None :
815+ if None in first or None in last :
817816 _LOGGER .debug (
818- "_logs_missing | %s | last_address=%s, last_slot=%s" ,
819- self ._mac ,
820- last_address ,
821- last_slot ,
817+ "_logs_missing | %s | first=%s, last=%s" , self ._mac , first , last
822818 )
823819 return None
824820
825- first_address , first_slot = self ._first_log_reference ()
826- if first_address is None or first_slot is None :
827- _LOGGER .debug (
828- "_logs_missing | %s | first_address=%s, first_slot=%s" ,
829- self ._mac ,
830- first_address ,
831- first_slot ,
832- )
833- return None
821+ first_address , first_slot = first
822+ last_address , last_slot = last
823+
824+ if (
825+ first == last and
826+ self ._logs [first_address ][first_slot ].timestamp == self ._logs [last_address ][last_slot ].timestamp
827+ ):
828+ return None # Only one unique log, not enough to work with
834829
835830 missing = []
836831 _LOGGER .debug (
837832 "_logs_missing | %s | first_address=%s, last_address=%s" ,
838- self ._mac ,
839- first_address ,
840- last_address ,
833+ self ._mac , first_address , last_address
841834 )
842835
843- if (
844- last_address == first_address
845- and last_slot == first_slot
846- and self ._logs [first_address ][first_slot ].timestamp
847- == self ._logs [last_address ][last_slot ].timestamp
848- ):
849- # Power consumption logging, so we need at least 4 logs.
850- return None
851-
852- # Collect any missing address in current range
853- address = last_address
854- slot = last_slot
855- while not (address == first_address and slot == first_slot ):
836+ # Check for missing logs in the collected range
837+ address , slot = last_address , last_slot
838+ while (address , slot ) != (first_address , first_slot ):
856839 address , slot = calc_log_address (address , slot , - 1 )
857840 if address in missing :
858841 continue
859842 if not self ._log_exists (address , slot ):
860843 missing .append (address )
861- continue
862- if self ._logs [address ][slot ].timestamp <= from_timestamp :
844+ elif self ._logs [address ][slot ].timestamp <= from_timestamp :
863845 break
864846
865- _LOGGER .debug (
866- "_logs_missing | %s | missing in range=%s" , self ._mac , missing
867- )
868-
869- # return missing logs in range first
870- if len (missing ) > 0 :
847+ if missing :
848+ _LOGGER .debug ("_logs_missing | %s | missing in range=%s" , self ._mac , missing )
871849 return missing
872850
873- if first_address not in self ._logs :
874- return missing
875-
876- if first_slot not in self ._logs [first_address ]:
877- return missing
878-
879- if self ._logs [first_address ][first_slot ].timestamp < from_timestamp :
880- return missing
881-
882- # Check if we are able to calculate log interval
883- address , slot = calc_log_address (first_address , first_slot , - 1 )
884- log_interval : int | None = None
885- if self ._log_interval_consumption is not None :
886- log_interval = self ._log_interval_consumption
887- elif self ._log_interval_production is not None :
888- log_interval = self ._log_interval_production
851+ # Check if first slot exists and is recent enough
852+ if (
853+ first_address not in self ._logs or
854+ first_slot not in self ._logs [first_address ] or
855+ self ._logs [first_address ][first_slot ].timestamp < from_timestamp
856+ ):
857+ return []
889858
859+ # Estimate log interval
860+ log_interval = self ._log_interval_consumption or self ._log_interval_production
890861 if (
891- self ._log_interval_production is not None
892- and log_interval is not None
893- and self ._log_interval_production < log_interval
862+ self ._log_interval_production is not None and
863+ log_interval is not None and
864+ self ._log_interval_production < log_interval
894865 ):
895866 log_interval = self ._log_interval_production
896867
897868 if log_interval is None :
898869 return None
899870
900- # We have an suspected interval, so try to calculate missing log addresses prior to first collected log
901- calculated_timestamp = self ._logs [first_address ][
902- first_slot
903- ].timestamp - timedelta (minutes = log_interval )
871+ # Walk backward before the first known log to find additional missing logs
872+ timestamp = self ._logs [first_address ][first_slot ].timestamp
873+ calc_timestamp = timestamp - timedelta (minutes = log_interval )
874+ address , slot = calc_log_address (first_address , first_slot , - 1 )
875+
904876 _LOGGER .debug (
905- "_logs_missing | %s | calculated timestamp=%s" ,
906- self ._mac ,
907- calculated_timestamp ,
877+ "_logs_missing | %s | calculated timestamp=%s" , self ._mac , calc_timestamp
908878 )
909- while from_timestamp < calculated_timestamp :
910- if (
911- address == self ._first_empty_log_address
912- and slot == self ._first_empty_log_slot
913- ):
879+
880+ while calc_timestamp > from_timestamp :
881+ if (address , slot ) == (self ._first_empty_log_address , self ._first_empty_log_slot ):
914882 break
915883 if address not in missing :
916884 missing .append (address )
917- calculated_timestamp -= timedelta (minutes = log_interval )
885+ calc_timestamp -= timedelta (minutes = log_interval )
918886 address , slot = calc_log_address (address , slot , - 1 )
919887
920888 missing .sort (reverse = True )
921889 _LOGGER .debug ("_logs_missing | %s | calculated missing=%s" , self ._mac , missing )
922890 return missing
923891
892+
924893 def _last_known_duration (self ) -> timedelta :
925894 """Duration for last known logs."""
926895 if self ._logs is None :
0 commit comments