Start configuration details.
authorBenjamin Braatz <benjamin.braatz@graph-it.com>
Wed, 11 Aug 2021 14:27:07 +0000 (16:27 +0200)
committerBenjamin Braatz <benjamin.braatz@graph-it.com>
Wed, 11 Aug 2021 14:27:07 +0000 (16:27 +0200)
controlpi_plugins/camera.py

index fe5e3be9dd2656f932be9db6459fd4f99c1ae0e9..58752d86f0b5cc514fde9cd6dd401c8986d5da6c 100644 (file)
@@ -18,7 +18,36 @@ class Camera(BasePlugin):
     CONF_SCHEMA = {'properties':
                    {'pause': {'type': 'number'},
                     'keep': {'type': 'integer'},
-                    'path': {'type': 'string'}},
+                    'path': {'type': 'string'},
+                    'iso': {'enum': [0, 100, 200, 320, 400, 500, 640, 800]},
+                    'shutter speed': {'type': 'integer',
+                                      'minimum': 0,
+                                      'maximum': 11111},
+                    'exposure mode': {'enum': ['off', 'auto', 'night',
+                                               'nightpreview', 'backlight',
+                                               'spotlight', 'sports', 'snow',
+                                               'beach', 'verylong',
+                                               'fixedfps', 'antishake',
+                                               'fireworks']},
+                    'exposure compensation': {'type': 'integer',
+                                              'minimum': -25,
+                                              'maximum': 25},
+                    'brightness': {'type': 'integer',
+                                   'minimum': 0,
+                                   'maximum': 100},
+                    'sharpness': {'type': 'integer',
+                                  'minimum': -100,
+                                  'maximum': 100},
+                    'contrast': {'type': 'integer',
+                                 'minimum': -100,
+                                 'maximum': 100},
+                    'saturation': {'type': 'integer',
+                                   'minimum': -100,
+                                   'maximum': 100},
+                    'awb mode': {'enum': ['off', 'auto', 'sunlight', 'cloudy',
+                                          'shade', 'tungsten', 'fluorescent',
+                                          'incandescent', 'flash',
+                                          'horizon']}},
                    'required': ['pause', 'keep', 'path']}
 
     async def _receive(self, message: Message) -> None:
@@ -36,11 +65,62 @@ class Camera(BasePlugin):
         """Register plugin as bus client."""
         self._images: Deque[Tuple[str, str]] = collections.deque()
         self._capture = False
+        self._camera = picamera.PiCamera(sensor_mode=7,
+                                         resolution=(640, 480),
+                                         framerate=90)
+        if 'iso' not in self.conf:
+            self.conf['iso'] = 0
+        if 'shutter speed' not in self.conf:
+            self.conf['shutter speed'] = 0
+        if 'exposure mode' not in self.conf:
+            self.conf['exposure mode'] = 'auto'
+        if 'exposure compensation' not in self.conf:
+            self.conf['exposure compensation'] = 0
+        if 'brightness' not in self.conf:
+            self.conf['brightness'] = 50
+        if 'sharpness' not in self.conf:
+            self.conf['sharpness'] = 0
+        if 'contrast' not in self.conf:
+            self.conf['contrast'] = 0
+        if 'saturation' not in self.conf:
+            self.conf['saturation'] = 0
+        if 'awb mode' not in self.conf:
+            self.conf['awb mode'] = 'auto'
         sends = [MessageTemplate({'event': {'const': 'new image'},
                                   'image': {'type': 'string'},
                                   'date': {'type': 'string'}}),
                  MessageTemplate({'image': {'type': 'string'},
-                                  'date': {'type': 'string'}})]
+                                  'date': {'type': 'string'}}),
+                 MessageTemplate({'event': {'const': 'new iso'},
+                                  'iso': {'type': 'integer'}}),
+                 MessageTemplate({'iso': {'type': 'integer'}}),
+                 MessageTemplate({'event': {'const': 'new shutter speed'},
+                                  'shutter speed': {'type': 'integer'}}),
+                 MessageTemplate({'shutter speed': {'type': 'integer'}}),
+                 MessageTemplate({'event': {'const': 'new exposure mode'},
+                                  'exposure mode': {'type': 'string'}}),
+                 MessageTemplate({'exposure mode': {'type': 'string'}}),
+                 MessageTemplate({'event': {'const':
+                                            'new exposure compensation'},
+                                  'exposure compensation':
+                                  {'type': 'integer'}}),
+                 MessageTemplate({'exposure compensation':
+                                  {'type': 'integer'}}),
+                 MessageTemplate({'event': {'const': 'new brightness'},
+                                  'brightness': {'type': 'integer'}}),
+                 MessageTemplate({'brightness': {'type': 'integer'}}),
+                 MessageTemplate({'event': {'const': 'new sharpness'},
+                                  'sharpness': {'type': 'integer'}}),
+                 MessageTemplate({'sharpness': {'type': 'integer'}}),
+                 MessageTemplate({'event': {'const': 'new contrast'},
+                                  'contrast': {'type': 'integer'}}),
+                 MessageTemplate({'contrast': {'type': 'integer'}}),
+                 MessageTemplate({'event': {'const': 'new saturation'},
+                                  'saturation': {'type': 'integer'}}),
+                 MessageTemplate({'saturation': {'type': 'integer'}}),
+                 MessageTemplate({'event': {'const': 'new awb mode'},
+                                  'awb mode': {'type': 'string'}}),
+                 MessageTemplate({'awb mode': {'type': 'string'}})]
         receives = [MessageTemplate({'target': {'const': self.name},
                                      'command': {'const': 'get image'}}),
                     MessageTemplate({'target': {'const': self.name},
@@ -53,15 +133,10 @@ class Camera(BasePlugin):
         """Run camera."""
         loop = asyncio.get_running_loop()
         executor = concurrent.futures.ThreadPoolExecutor()
-        camera = picamera.PiCamera(sensor_mode=7,
-                                   resolution=(640, 480),
-                                   framerate=90)
         try:
             while True:
                 if self._capture:
-                    camera.exposure_mode = 'sports'
-                    camera.awb_mode = 'auto'
-                    camera.start_preview()
+                    self._camera.start_preview()
                     await asyncio.sleep(2)
                     while self._capture:
                         while len(self._images) >= self.conf['keep']:
@@ -78,7 +153,7 @@ class Camera(BasePlugin):
                         await loop.run_in_executor(
                                 executor,
                                 functools.partial(
-                                    camera.capture,
+                                    self._camera.capture,
                                     stream,
                                     'jpeg',
                                     use_video_port=True))
@@ -96,11 +171,11 @@ class Camera(BasePlugin):
                                                      'image': file_name,
                                                      'date': iso_time}))
                         await asyncio.sleep(self.conf['pause'])
-                    camera.stop_preview()
+                    self._camera.stop_preview()
                 await asyncio.sleep(2)
         except asyncio.CancelledError:
-            camera.stop_preview()
-            camera.close()
+            self._camera.stop_preview()
+            self._camera.close()
             while len(self._images) > 0:
                 file_name = self._images.popleft()[0]
                 file_path = os.path.join(self.conf['path'], file_name)