Desmond-Dong commited on
Commit
c0d0c4e
·
1 Parent(s): 73128d7

feat: push face_detected entity state updates to Home Assistant

Browse files

- Add _face_state_callback to camera_server.py for state change notifications
- Track face detection state changes in capture loop
- Connect callback in satellite.py to entity_registry.update_face_detected_state()
- Face detected binary sensor now updates in real-time when face appears/disappears

reachy_mini_ha_voice/camera_server.py CHANGED
@@ -103,7 +103,11 @@ class MJPEGCameraServer:
103
  self._gesture_frame_counter = 0
104
  self._gesture_detection_interval = 3 # Run gesture detection every N frames
105
  self._gesture_state_callback = None # Callback to notify entity registry
106
-
 
 
 
 
107
  # Face tracking timing (smooth interpolation when face lost)
108
  self._last_face_detected_time: Optional[float] = None
109
  self._interpolation_start_time: Optional[float] = None
@@ -274,7 +278,18 @@ class MJPEGCameraServer:
274
  self._current_fps = self._fps_low
275
 
276
  self._last_face_check_time = current_time
277
-
 
 
 
 
 
 
 
 
 
 
 
278
  # Handle smooth interpolation when face lost
279
  self._process_face_lost_interpolation(current_time)
280
 
@@ -629,6 +644,10 @@ class MJPEGCameraServer:
629
  """Set callback to notify when gesture state changes."""
630
  self._gesture_state_callback = callback
631
 
 
 
 
 
632
  def _get_camera_frame(self) -> Optional[np.ndarray]:
633
  """Get a frame from Reachy Mini's camera."""
634
  if self.reachy_mini is None:
 
103
  self._gesture_frame_counter = 0
104
  self._gesture_detection_interval = 3 # Run gesture detection every N frames
105
  self._gesture_state_callback = None # Callback to notify entity registry
106
+
107
+ # Face detection state callback (similar to gesture)
108
+ self._face_state_callback = None # Callback to notify entity registry
109
+ self._last_face_detected_state = False # Track previous state for change detection
110
+
111
  # Face tracking timing (smooth interpolation when face lost)
112
  self._last_face_detected_time: Optional[float] = None
113
  self._interpolation_start_time: Optional[float] = None
 
278
  self._current_fps = self._fps_low
279
 
280
  self._last_face_check_time = current_time
281
+
282
+ # Check for face detection state change and notify callback
283
+ # Use is_face_detected() which considers face_lost_delay
284
+ current_face_state = self.is_face_detected()
285
+ if current_face_state != self._last_face_detected_state:
286
+ self._last_face_detected_state = current_face_state
287
+ if self._face_state_callback:
288
+ try:
289
+ self._face_state_callback()
290
+ except Exception as e:
291
+ _LOGGER.debug("Face state callback error: %s", e)
292
+
293
  # Handle smooth interpolation when face lost
294
  self._process_face_lost_interpolation(current_time)
295
 
 
644
  """Set callback to notify when gesture state changes."""
645
  self._gesture_state_callback = callback
646
 
647
+ def set_face_state_callback(self, callback) -> None:
648
+ """Set callback to notify when face detection state changes."""
649
+ self._face_state_callback = callback
650
+
651
  def _get_camera_frame(self) -> Optional[np.ndarray]:
652
  """Get a frame from Reachy Mini's camera."""
653
  if self.reachy_mini is None:
reachy_mini_ha_voice/satellite.py CHANGED
@@ -115,6 +115,7 @@ class VoiceSatelliteProtocol(APIServer):
115
  # Connect gesture state callback
116
  if camera_server:
117
  camera_server.set_gesture_state_callback(self._entity_registry.update_gesture_state)
 
118
 
119
  # Only setup entities once (check if already initialized)
120
  # This prevents duplicate entity registration on reconnection
 
115
  # Connect gesture state callback
116
  if camera_server:
117
  camera_server.set_gesture_state_callback(self._entity_registry.update_gesture_state)
118
+ camera_server.set_face_state_callback(self._entity_registry.update_face_detected_state)
119
 
120
  # Only setup entities once (check if already initialized)
121
  # This prevents duplicate entity registration on reconnection