From 29b8d0827b95fce6d3072ee428a11f85ed3c7547 Mon Sep 17 00:00:00 2001
From: Fabio Manganiello <blacklight86@gmail.com>
Date: Wed, 27 Feb 2019 20:12:40 +0100
Subject: [PATCH] Added basic support for camera events in the camera plugin

---
 platypush/message/event/camera.py    | 47 ++++++++++++++++++++++++++++
 platypush/plugins/camera/__init__.py | 32 +++++++++++++++++++
 2 files changed, 79 insertions(+)
 create mode 100644 platypush/message/event/camera.py

diff --git a/platypush/message/event/camera.py b/platypush/message/event/camera.py
new file mode 100644
index 000000000..ff5eaebaa
--- /dev/null
+++ b/platypush/message/event/camera.py
@@ -0,0 +1,47 @@
+from platypush.message.event import Event
+
+
+class CameraEvent(Event):
+    """ Base class for camera events """
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+
+class CameraRecordingStartedEvent(CameraEvent):
+    """
+    Event triggered when a new recording starts
+    """
+
+    def __init__(self, device_id, filename=None, *args, **kwargs):
+        super().__init__(*args, device_id=device_id, filename=filename, **kwargs)
+
+
+class CameraRecordingStoppedEvent(CameraEvent):
+    """
+    Event triggered when a recording stops
+    """
+
+    def __init__(self, device_id, *args, **kwargs):
+        super().__init__(*args, device_id=device_id, **kwargs)
+
+
+class CameraVideoRenderedEvent(CameraEvent):
+    """
+    Event triggered when a sequence of frames has been rendered into a video
+    """
+
+    def __init__(self, filename=None, *args, **kwargs):
+        super().__init__(*args, filename=filename, **kwargs)
+
+
+class CameraPictureTakenEvent(CameraEvent):
+    """
+    Event triggered when a snapshot has been taken
+    """
+
+    def __init__(self, filename=None, *args, **kwargs):
+        super().__init__(*args, filename=filename, **kwargs)
+
+
+# vim:sw=4:ts=4:et:
diff --git a/platypush/plugins/camera/__init__.py b/platypush/plugins/camera/__init__.py
index dc5c6d134..ba58af3df 100644
--- a/platypush/plugins/camera/__init__.py
+++ b/platypush/plugins/camera/__init__.py
@@ -9,6 +9,11 @@ import cv2
 from datetime import datetime
 
 from platypush.config import Config
+from platypush.context import get_bus
+from platypush.message.event.camera import CameraRecordingStartedEvent, \
+    CameraRecordingStoppedEvent, CameraVideoRenderedEvent, \
+    CameraPictureTakenEvent
+
 from platypush.plugins import Plugin, action
 
 
@@ -16,6 +21,17 @@ class CameraPlugin(Plugin):
     """
     Plugin to control generic cameras over OpenCV.
 
+    Triggers:
+
+        * :class:`platypush.message.event.camera.CameraRecordingStartedEvent`
+            when a new video recording/photo burst starts
+        * :class:`platypush.message.event.camera.CameraRecordingStoppedEvent`
+            when a video recording/photo burst ends
+        * :class:`platypush.message.event.camera.CameraVideoRenderedEvent`
+            when a sequence of captured is successfully rendered into a video
+        * :class:`platypush.message.event.camera.CameraPictureTakenEvent`
+            when a snapshot is captured and stored to an image file
+
     Requires:
 
         * **opencv** (``pip install opencv-python``)
@@ -107,6 +123,7 @@ class CameraPlugin(Plugin):
         if device_id in self._devices:
             self._devices[device_id].release()
             del self._devices[device_id]
+            get_bus().post(CameraRecordingStoppedEvent(device_id=device_id))
 
 
     def _store_frame_to_file(self, frame, frames_dir, image_file):
@@ -118,6 +135,9 @@ class CameraPlugin(Plugin):
                 frames_dir, datetime.now().strftime('%Y-%m-%d_%H-%M-%S-%f.jpg'))
 
         cv2.imwrite(filepath, frame)
+
+        if image_file:
+            get_bus().post(CameraPictureTakenEvent(filename=image_file))
         return filepath
 
 
@@ -169,6 +189,7 @@ class CameraPlugin(Plugin):
         for f in files:
             video.write(cv2.imread(f))
         video.release()
+        get_bus().post(CameraVideoRenderedEvent(filename=video_file))
         shutil.rmtree(frames_dir, ignore_errors=True)
 
 
@@ -185,6 +206,17 @@ class CameraPlugin(Plugin):
             recording_started_time = time.time()
             captured_frames = 0
 
+            evt_args = {
+                'device_id': device_id,
+            }
+
+            if video_file or image_file:
+                evt_args['filename'] = video_file or image_file
+            if frames_dir:
+                evt_args['frames_dir'] = frames_dir
+
+            get_bus().post(CameraRecordingStartedEvent(**evt_args))
+
             while self._is_recording[device_id].is_set():
                 if duration and time.time() - recording_started_time >= duration \
                         or n_frames and captured_frames >= n_frames: