
    vi                        d Z ddlmZ ddlZddlmZmZmZmZm	Z	m
Z
mZmZ  ej                  e      Zeeeegeeedf   f   Z G d d      Zy)um  FR Temporal Analyzer — watches face recognition detections for patterns.

Accumulates face recognition detections over a sliding window and identifies
when a face is consistently detected (same identity or 'unknown') for a
configurable threshold duration.  When a consistent detection is found,
triggers an async callback so the orchestrator can reason about it.
    )annotationsN)AnyCallable	CoroutineDictListOptionalSetTuplec                  t    e Zd ZdZdZdZ	 	 d	 	 	 	 	 ddZ	 	 	 	 ddZ	 	 	 	 	 	 ddZddZ	ddZ
	 	 	 	 dd	Zy
)FRTemporalAnalyzeraU  Watches FR detection stream for temporal patterns.

    Accumulates detections over a sliding window and identifies when
    a face is consistently detected (same identity or ``'unknown'``) for
    a configurable threshold duration.  When a consistent detection is
    found, triggers a callback so the orchestrator can reason about it.
    g333333?   c                Z    || _         || _        g | _        t               | _        d | _        y N)
_threshold_window_detection_historyset_notified_identities_on_consistent_detection)selfconsistency_threshold_swindow_ss      H/home/nelsen/Projects/kognitive/orchestrator/src/services/fr_analyzer.py__init__zFRTemporalAnalyzer.__init__&   s,    
 2LN.1e!OS%    c                    || _         y)z@Register callback: ``async fn(identity, confidence, duration)``.N)r   )r   callbacks     r   on_consistent_detectionz*FRTemporalAnalyzer.on_consistent_detection5   s     )1%r   c                  K   | j                   j                  ||f       || j                  z
  }| j                   D cg c]  \  }}||kD  s||f c}}| _         | j                  |      }|D ]X  \  }}}	|| j                  vs| j                  j                  |       | j                  >| j                  |||	       d{    Z yc c}}w 7 w)a=  Feed a new set of FR detections.

        Called on every ``fr_detections`` message from the edge proxy.

        Args:
            detections: List of detection dicts (each with at least
                ``identity`` and ``confidence`` keys).
            timestamp: Unix epoch seconds of the detection frame.
        N)r   appendr   _find_consistentr   addr   )
r   
detections	timestampcutofftd
consistentidentity
confidencedurations
             r   feedzFRTemporalAnalyzer.feed;   s      	&&	:'>? T\\)#66#
q!!f*QF#

 **95
.8 	*Hj(t888))--h700<77 *h  		#
s.   <CC
C
1C'C,CCCc                l    | j                   j                          | j                  j                          y)z>Reset all state.  Call when the robot moves to a new location.N)r   clearr   )r   s    r   resetzFRTemporalAnalyzer.reset[   s&    %%'!!'')r   c                :    | j                   j                  |       y)zAAllow re-notification for *identity* (after it has been handled).N)r   discard)r   r*   s     r   clear_identityz!FRTemporalAnalyzer.clear_identity`   s    !!))(3r   c                   | j                   sg S || j                  z
  }| j                   D cg c]  \  }}||k\  s||f }}}t        |      | j                  k  rg S i }|D ]V  \  }}|D ]L  }	|	j	                  d      xs d}
|	j	                  dd      }|j                  |
g       j                  ||f       N X g }t        |      }|j                         D ]z  \  }}t        |      |z  | j                  k\  s"t        d |D              t        |      z  }t        d |D              }||z
  }|| j                  k\  sg|j                  |||f       | |S c c}}w )u   Find identities present consistently for ≥ threshold seconds.

        Returns:
            List of ``(identity, avg_confidence, duration_seconds)``.
        r*   unknownr+   g        c              3  &   K   | ]	  \  }}|  y wr    ).0_cs      r   	<genexpr>z6FRTemporalAnalyzer._find_consistent.<locals>.<genexpr>   s     4TQq4   c              3  &   K   | ]	  \  }}|  y wr   r7   )r8   r'   r9   s      r   r;   z6FRTemporalAnalyzer._find_consistent.<locals>.<genexpr>   s      6tq! 6r<   )r   r   len
MIN_FRAMESget
setdefaultr!   itemsPRESENCE_RATIOsummin)r   nowwindow_startr'   r(   relevantidentity_framestsdetsdetidentconfresultstotal_framesr*   framesavg_conf
first_seenr,   s                      r   r"   z#FRTemporalAnalyzer._find_consistenth   s{    &&IT__,#66
q!!|:KQF
 
 x=4??*I AC  	IHB I WWZ0=I!gglC8**5"5<<b$ZHI	I 358} / 5 5 7 	CHf6{\)T-@-@@4V44s6{B  6v 66
+t.NNHh#AB	C 3
s
   EEN)g      @g      $@)r   floatr   rT   returnNone)r   ConsistentDetectionCallbackrU   rV   )r$   zList[Dict[str, Any]]r%   rT   rU   rV   )rU   rV   )r*   strrU   rV   )rF   rT   rU   zList[Tuple[str, float, float]])__name__
__module____qualname____doc__rC   r?   r   r   r-   r0   r3   r"   r7   r   r   r   r      s     N J *-	T!&	T 	T 
		T131	1(  
	@*
4%%	'%r   r   )r\   
__future__r   loggingtypingr   r   r   r   r   r	   r
   r   	getLoggerrY   loggerrX   rT   rW   r   r7   r   r   <module>rb      s`    #  M M M			8	$ '%3T>22 
w wr   