Просмотр исходного кода

enable turning clips on and off via mqtt

Blake Blackshear 4 лет назад
Родитель
Сommit
e5399ae07a
4 измененных файлов с 45 добавлено и 10 удалено
  1. 1 1
      frigate/app.py
  2. 1 1
      frigate/config.py
  3. 3 0
      frigate/events.py
  4. 40 8
      frigate/mqtt.py

+ 1 - 1
frigate/app.py

@@ -119,7 +119,7 @@ class FrigateApp():
         self.flask_app = create_app(self.config, self.db, self.camera_metrics, self.detectors, self.detected_frames_processor)
 
     def init_mqtt(self):
-        self.mqtt_client = create_mqtt_client(self.config.mqtt)
+        self.mqtt_client = create_mqtt_client(self.config)
 
     def start_detectors(self):
         model_shape = (self.config.model.height, self.config.model.width)

+ 1 - 1
frigate/config.py

@@ -806,7 +806,7 @@ class CameraConfig():
             ffmpeg_output_args = self.ffmpeg.output_args['rtmp'] + [
                 f"rtmp://127.0.0.1/live/{self.name}"
             ] + ffmpeg_output_args
-        if 'clips' in ffmpeg_input.roles and self.clips.enabled:
+        if 'clips' in ffmpeg_input.roles:
             ffmpeg_output_args = self.ffmpeg.output_args['clips'] + [
                 f"{os.path.join(CACHE_DIR, self.name)}-%Y%m%d%H%M%S.mp4"
             ] + ffmpeg_output_args

+ 3 - 0
frigate/events.py

@@ -102,6 +102,7 @@ class EventProcessor(threading.Thread):
         sorted_clips = sorted([c for c in self.cached_clips.values() if c['camera'] == camera], key = lambda i: i['start_time'])
 
         while len(sorted_clips) == 0 or sorted_clips[-1]['start_time'] + sorted_clips[-1]['duration'] < event_data['end_time']+post_capture:
+            logger.debug(f"No cache clips for {camera}. Waiting...")
             time.sleep(5)
             self.refresh_cache()
             # get all clips from the camera with the event sorted
@@ -162,12 +163,14 @@ class EventProcessor(threading.Thread):
                     self.refresh_cache()
                 continue
 
+            logger.debug(f"Event received: {event_type} {camera} {event_data['id']}")
             self.refresh_cache()
 
             clips_config = self.config.cameras[camera].clips
 
             # if save clips is not enabled for this camera, just continue
             if not clips_config.enabled:
+                logger.debug(f"Clips not enabled for {camera}. Not making a clip.")
                 if event_type == 'end':
                     self.event_processed_queue.put((event_data['id'], camera))
                 continue

+ 40 - 8
frigate/mqtt.py

@@ -3,12 +3,31 @@ import threading
 
 import paho.mqtt.client as mqtt
 
-from frigate.config import MqttConfig
+from frigate.config import FrigateConfig
 
 logger = logging.getLogger(__name__)
 
-def create_mqtt_client(config: MqttConfig):
-    client = mqtt.Client(client_id=config.client_id)
+def create_mqtt_client(config: FrigateConfig):
+    mqtt_config = config.mqtt
+
+    def on_clips_command(client, userdata, message):
+        payload = message.payload.decode()
+        logger.debug(f"on_clips_toggle: {message.topic} {payload}")
+
+        camera_name = message.topic.split('/')[-3]
+        command = message.topic.split('/')[-1]
+
+        if payload == 'ON':
+            config.cameras[camera_name].clips._enabled = True
+        elif payload == 'OFF':
+            config.cameras[camera_name].clips._enabled = False
+        else:
+            logger.warning(f"Received unsupported value at {message.topic}: {payload}")
+
+        if command == "set":
+            state_topic = f"{message.topic[:-4]}/state"
+            client.publish(state_topic, payload, retain=True)
+
     def on_connect(client, userdata, flags, rc):
         threading.current_thread().name = "mqtt"
         if rc != 0:
@@ -22,15 +41,28 @@ def create_mqtt_client(config: MqttConfig):
                 logger.error("Unable to connect to MQTT: Connection refused. Error code: " + str(rc))
             
         logger.info("MQTT connected")
-        client.publish(config.topic_prefix+'/available', 'online', retain=True)       
+        client.publish(mqtt_config.topic_prefix+'/available', 'online', retain=True)   
+
+    client = mqtt.Client(client_id=mqtt_config.client_id)    
     client.on_connect = on_connect
-    client.will_set(config.topic_prefix+'/available', payload='offline', qos=1, retain=True)
-    if not config.user is None:
-        client.username_pw_set(config.user, password=config.password)
+    client.will_set(mqtt_config.topic_prefix+'/available', payload='offline', qos=1, retain=True)
+    
+    # register callbacks
+    for name in config.cameras.keys():
+        clips_topic = f"{mqtt_config.topic_prefix}/{name}/clips/#"
+        client.message_callback_add(clips_topic, on_clips_command)
+
+    if not mqtt_config.user is None:
+        client.username_pw_set(mqtt_config.user, password=mqtt_config.password)
     try:
-        client.connect(config.host, config.port, 60)
+        client.connect(mqtt_config.host, mqtt_config.port, 60)
     except Exception as e:
         logger.error(f"Unable to connect to MQTT server: {e}")
         raise
+
     client.loop_start()
+
+    clips_topic = f"{mqtt_config.topic_prefix}/+/clips/#"
+    client.subscribe(clips_topic)
+
     return client