@@ -88,6 +88,8 @@ def __init__(self, mac: str) -> None:
8888 self ._rollover_consumption = False
8989 self ._rollover_production = False
9090
91+ self ._first_next_log_processed = False
92+ self ._first_prev_log_processed = False
9193 self ._logs : dict [int , dict [int , PulseLogRecord ]] | None = None
9294 self ._log_addresses_missing : list [int ] | None = None
9395 self ._log_production : bool | None = None
@@ -377,6 +379,8 @@ def _detect_rollover(
377379 )
378380 return False
379381
382+ return False
383+
380384 def add_empty_log (self , address : int , slot : int ) -> None :
381385 """Add empty energy log record to mark any start of beginning of energy log collection."""
382386 recalculate = False
@@ -439,11 +443,12 @@ def add_log(
439443 self .recalculate_missing_log_addresses ()
440444
441445 _LOGGER .debug (
442- "add_log | pulses=%s | address=%s | slot= %s |time: %s" ,
446+ "add_log | pulses=%s | address=%s | slot=%s | time=%s, direction= %s" ,
443447 pulses ,
444448 address ,
445449 slot ,
446450 timestamp ,
451+ direction ,
447452 )
448453 return True
449454
@@ -504,37 +509,70 @@ def _update_log_direction(
504509 if self ._logs is None :
505510 return
506511
512+ prev_timestamp = self ._check_prev_production (address , slot , timestamp )
513+ next_timestamp = self ._check_next_production (address , slot , timestamp )
514+ if self ._first_prev_log_processed and self ._first_next_log_processed :
515+ # _log_production is True when 2 out of 3 consecutive slots have
516+ # the same timestamp, otherwise it is False
517+ self ._log_production = (
518+ next_timestamp == timestamp and prev_timestamp != timestamp
519+ ) or (next_timestamp == prev_timestamp and next_timestamp != timestamp )
520+
521+ def _check_prev_production (
522+ self , address : int , slot : int , timestamp : datetime
523+ ) -> datetime | None :
524+ """Check the previous slot for production pulses."""
507525 prev_address , prev_slot = calc_log_address (address , slot , - 1 )
508526 if self ._log_exists (prev_address , prev_slot ):
509- if self ._logs [prev_address ][prev_slot ].timestamp == timestamp :
510- # Given log is the second log with same timestamp,
511- # mark direction as production
512- self ._logs [address ][slot ].is_consumption = False
513- self ._logs [prev_address ][prev_slot ].is_consumption = True
514- self ._log_production = True
515- elif self ._log_production :
516- self ._logs [address ][slot ].is_consumption = True
517- if self ._logs [prev_address ][prev_slot ].is_consumption :
518- self ._logs [prev_address ][prev_slot ].is_consumption = False
519- self ._reset_log_references ()
520- elif self ._log_production is None :
521- self ._log_production = False
527+ prev_timestamp = self ._logs [prev_address ][prev_slot ].timestamp
528+ if not self ._first_prev_log_processed :
529+ self ._first_prev_log_processed = True
530+ if prev_timestamp == timestamp :
531+ # Given log is the second log with same timestamp,
532+ # mark direction as production
533+ self ._logs [address ][slot ].is_consumption = False
534+ self ._logs [prev_address ][prev_slot ].is_consumption = True
535+ self ._log_production = True
536+ elif self ._log_production :
537+ self ._logs [address ][slot ].is_consumption = True
538+ if self ._logs [prev_address ][prev_slot ].is_consumption :
539+ self ._logs [prev_address ][prev_slot ].is_consumption = False
540+ self ._reset_log_references ()
541+ elif self ._log_production is None :
542+ self ._log_production = False
543+ return prev_timestamp
544+
545+ if self ._first_prev_log_processed :
546+ self ._first_prev_log_processed = False
547+ return None
522548
549+ def _check_next_production (
550+ self , address : int , slot : int , timestamp : datetime
551+ ) -> datetime | None :
552+ """Check the next slot for production pulses."""
523553 next_address , next_slot = calc_log_address (address , slot , 1 )
524554 if self ._log_exists (next_address , next_slot ):
525- if self ._logs [next_address ][next_slot ].timestamp == timestamp :
526- # Given log is the first log with same timestamp,
527- # mark direction as production of next log
528- self ._logs [address ][slot ].is_consumption = True
529- if self ._logs [next_address ][next_slot ].is_consumption :
530- self ._logs [next_address ][next_slot ].is_consumption = False
531- self ._reset_log_references ()
532- self ._log_production = True
533- elif self ._log_production :
534- self ._logs [address ][slot ].is_consumption = False
535- self ._logs [next_address ][next_slot ].is_consumption = True
536- elif self ._log_production is None :
537- self ._log_production = False
555+ next_timestamp = self ._logs [next_address ][next_slot ].timestamp
556+ if not self ._first_next_log_processed :
557+ self ._first_next_log_processed = True
558+ if next_timestamp == timestamp :
559+ # Given log is the first log with same timestamp,
560+ # mark direction as production of next log
561+ self ._logs [address ][slot ].is_consumption = True
562+ if self ._logs [next_address ][next_slot ].is_consumption :
563+ self ._logs [next_address ][next_slot ].is_consumption = False
564+ self ._reset_log_references ()
565+ self ._log_production = True
566+ elif self ._log_production :
567+ self ._logs [address ][slot ].is_consumption = False
568+ self ._logs [next_address ][next_slot ].is_consumption = True
569+ elif self ._log_production is None :
570+ self ._log_production = False
571+ return next_timestamp
572+
573+ if self ._first_next_log_processed :
574+ self ._first_next_log_processed = False
575+ return None
538576
539577 def _update_log_interval (self ) -> None :
540578 """Update the detected log interval based on the most recent two logs."""
0 commit comments