예제 #1
0
    def run(self):

        service_list = []

        try:
            log.info("""

    ----------------------------
    ---  Picammory Starting  ---
    ----------------------------
""")

            os.chdir(os.path.expanduser('~/picammory/picammory/'))
            log.info("os.getcwd() = '%s'", os.getcwd())


            #---

#            for gpio_pin in (5, 23, 24, 25):
#                subprocess.call(['/usr/local/bin/gpio', 'export', str(gpio_pin), 'out'])

#            wiringpi2.wiringPiSetupSys()

            #---

            config.config_load('picammory.ini')

            #---

#            LEDProcessor.start()
#            service_list.append(LEDProcessor)
#
#            LEDProcessor.blue(True)

            #---

            MailService.start()
            service_list.append(MailService)
            MailService.send_message('Picammory', 'Picammory Server Starting')

#            LEDProcessor.green(True)

            #---

            FtpUploader.start()
            service_list.append(FtpUploader)

#            LEDProcessor.red(True)

            #---

            log.info("Start Cam Processor")
            self.cam_processor = CamProcessor(os.path.expanduser('~/picammory_storage/'))
            service_list.append(self.cam_processor)

#            LEDProcessor.blue(False)

            #---

#            LEDProcessor.green(False)
#            LEDProcessor.red(False)

            #--- Wait until one thread stop...
            stopped_service = None
            while(stopped_service is None):
                for service in service_list:
                    if not service.is_alive():
                        log.info("Service %s is dead", service)
                        stopped_service = service
                        break
                time.sleep(1)

        except EnvironmentError as e:
            log.exception("Picammory failed 1")
            MailService.send_message("Picammory Error", "EnvironmentError: SprinklermoryServer failed: %d (%s)" % (e.errno, e.strerror))
        except Exception as e:
            log.exception("Picammory failed 2")
            MailService.send_message("Picammory Error", "Exception: Scheduler failed: %s" % (e))
        finally:
            for service in service_list:
                service.terminate()
            log.info(
'''

    ------------------------
    ---  Picammory Exit  ---
    ------------------------
''')

        sys.exit(1)
예제 #2
0
    def run(self):
        try:
            log.info("CamProcessorServer Started")

            camera_name = config.config['camera']['name']

            with CamMotionDetector(self._storage_path) as camMotionDetector:

                # Take a shot at boot, them every hour on the hour
                log.info("Start After Boot Picture")
                #                LEDProcessor.green(True)
                with picamera.PiCamera() as camera:
                    nowtime = datetime.now()
                    imageFilename = "%s-%04d%02d%02d-%02d%02d%02d-Boot.jpg" % (
                        camera_name, nowtime.year, nowtime.month, nowtime.day,
                        nowtime.hour, nowtime.minute, nowtime.second)
                    imageFilepath = self._periodic_path + imageFilename
                    camera.resolution = (2592, 1944)
                    #                    camera.hflip = True
                    #                    camera.vflip = True
                    #camera.exif_tags['EXIF.UserComment'] = b'Garden'
                    camera.start_preview()
                    # Camera warm-up time
                    time.sleep(2)
                    #                    LEDProcessor.green(False)
                    camera.capture(imageFilepath)
                    #                    LEDProcessor.green(True)

                    remotePath = ("%04d" % (nowtime.year),
                                  "%02d" % (nowtime.month),
                                  "%02d" % (nowtime.day))
                    FtpUploader.upload_move(remotePath, imageFilename,
                                            imageFilepath)
#                LEDProcessor.green(False)

#                LEDProcessor.red(False)
#                LEDProcessor.blue(False)

                self.lastPictureTime = datetime.utcnow().hour

                while not self._terminate:

                    log.info("Start Motion detection")

                    with picamera.PiCamera() as camera:

                        #camera.led = False
                        #                        LEDProcessor.camera(False)

                        camera.resolution = (1280, 720)
                        #                        camera.hflip = True
                        #                        camera.vflip = True
                        camera.framerate = 6
                        #camera.video_stabilization = True
                        stream = picamera.PiCameraCircularIO(camera, seconds=5)

                        camera.start_recording(stream, format='h264')

                        try:
                            while not self._terminate:
                                camera.wait_recording(0.2)
                                if camMotionDetector.detect_motion(
                                        camera, True):
                                    self.process_motion(
                                        camera, stream, camMotionDetector)

                                # 'datetime.utcnow().hour' take about 25 usec
                                # 'time.gmtime()[3]' take about 26 usec
                                utc_now_hour = datetime.utcnow().hour
                                if (utc_now_hour != self.lastPictureTime):
                                    self.lastPictureTime = utc_now_hour
                                    break
                        except Exception as e:
                            log.exception("Motion detection")
                        finally:
                            camera.stop_recording()

                    if (self._terminate):
                        log.info("CamProcessorServer terminated %d" %
                                 (self._terminate))
                        break

                    # Take a shot at boot, them every hour on the hour
                    log.info("Start Periodic Picture")
                    #                    LEDProcessor.green(True)
                    with picamera.PiCamera() as camera:
                        nowtime = datetime.now()
                        log.info('Periodic Picture')

                        imageFilename = "%s-%04d%02d%02d-%02d0000.jpg" % (
                            camera_name, nowtime.year, nowtime.month,
                            nowtime.day, nowtime.hour)
                        imageFilepath = self._periodic_path + imageFilename
                        camera.resolution = (2592, 1944)
                        #                        camera.hflip = True
                        #                        camera.vflip = True
                        #camera.exif_tags['EXIF.UserComment'] = b'Garden'
                        camera.start_preview()
                        # Camera warm-up time
                        time.sleep(1)
                        #                        LEDProcessor.green(False)
                        camera.capture(imageFilepath)
                        #                        LEDProcessor.green(True)

                        remotePath = ('Periodic', "%04d" % (nowtime.year),
                                      "%02d" % (nowtime.month),
                                      "%02d" % (nowtime.day))
                        FtpUploader.upload_move(remotePath, imageFilename,
                                                imageFilepath)
#                    LEDProcessor.green(False)

        except EnvironmentError as e:
            log.exception("CamProcessorServer Daemon failed: %d (%s)" %
                          (e.errno, e.strerror))
        except Exception as e:
            log.exception("CamProcessorServer Daemon failed (Exception)")
        finally:
            log.info("CamProcessorServer Daemon Exit.")
예제 #3
0
    def detect_motion(self, camera, debug_detection):
        motionDetected = False

        timeStart = time.time()

        #---

        if (CamMotionDetector._frame_processed_count >= 10):
            CamMotionDetector._frame_processed_fps = CamMotionDetector._frame_processed_count / (
                timeStart - CamMotionDetector._frame_processed_start_time)
            CamMotionDetector._frame_processed_count = 0
            CamMotionDetector._frame_processed_start_time = timeStart
        else:
            CamMotionDetector._frame_processed_count += 1

        #---

        # finish to dump previous ymi file before to process next dectection
        if (CamMotionDetector._frame_before_ymi_dump < 0):
            pass
        elif (CamMotionDetector._frame_before_ymi_dump > 0):
            CamMotionDetector._frame_before_ymi_dump -= 1
        else:
            # Dump images used for detection up to detection time

            filename = self._motionDetectedPrefixFilename + ".ymi"
            filepath = self._motionDebugPath + filename
            write_image_buffer(filepath)

            FtpUploader.upload_move(self.remotePath, filename, filepath)

            CamMotionDetector._frame_before_ymi_dump = -1

        #---

        stream = io.BytesIO()
        camera.capture(stream,
                       format='yuv',
                       resize=(CamMotionDetector._detectionImageWidth,
                               CamMotionDetector._detectionImageHeight),
                       use_video_port=True)
        stream.seek(0)

        time1 = time.time() - timeStart
        timeStart2 = time.time()

        if self._buffer1 is None:
            #self._buffer1 = bytearray(stream.getbuffer())
            self._buffer1 = stream.getbuffer()
        else:

            #--- Motion Detection -----------------------------------------------
            # Compare current_image to prior_image to detect motion.

            # Buffer packed 4 byte per pixel, line after line. (RGBA)(RGBA)
            # process on a copy improve performance by 30%. but we cannot modify image buffer anymore
            #self._buffer2 = bytearray(stream.getbuffer())
            self._buffer2 = stream.getbuffer()

            motionDetected = detect_motion(self._buffer1, self._buffer2)
            self._buffer1 = self._buffer2

            time2 = time.time() - timeStart2

            #self._counter_debug_dump += 1

            # Debug when threshold is reached
            #if (motionDetected or self._counter_debug_dump >= 10):
            if (motionDetected and debug_detection):
                #self._counter_debug_dump = 0

                timeStart3 = time.time()

                nowtime = datetime.now()

                camera_name = config.config['camera']['name']

                self._motionDetectedPrefixFilename = "%s-%04d%02d%02d-%02d%02d%02d" % (
                    camera_name, nowtime.year, nowtime.month, nowtime.day,
                    nowtime.hour, nowtime.minute, nowtime.second)
                self.remotePath = ("%04d" % (nowtime.year),
                                   "%02d" % (nowtime.month),
                                   "%02d/" % (nowtime.day))

                #---
                # Schedule YMI file generation (if not yet scheduled)
                if (CamMotionDetector._frame_before_ymi_dump < 0):
                    CamMotionDetector._frame_before_ymi_dump = 180

                #---

                filename = self._motionDetectedPrefixFilename + ".tiff"
                filepath = self._motionDebugPath + filename
                img = Image.frombuffer(
                    "CMYK",
                    (self._detectionImageWidth, self._detectionImageHeight),
                    self._debugImageData, 'raw', "CMYK", 0, 1)
                img.save(filepath)

                FtpUploader.upload_move(self.remotePath, filename, filepath)

                #---

                if (motionDetected):
                    filename = self._motionDetectedPrefixFilename + ".txt"
                else:
                    filename = self._motionDetectedPrefixFilename + "-debug.txt"
                filepath = self._motionDebugPath + filename

                time3 = time.time() - timeStart3

                with open(filepath, "w") as file:
                    file.write(
                        "Cam Motion Detector: [%d,%d] noiseLevel=%d noiseLevelForHistory=%d sensitivity=%d\n"
                        %
                        (self._detectionImageWidth, self._detectionImageHeight,
                         CamMotionDetector._noiseLevel,
                         CamMotionDetector._noiseLevelForHistory,
                         CamMotionDetector._sensitivity))
                    file.write(
                        "Motion Detection: {:.0f} fps (capture {:.0f} ms | processing {:.0f} ms |  dump {:.0f} ms)\n"
                        .format(CamMotionDetector._frame_processed_fps,
                                1000 * time1, 1000 * time2, 1000 * time3))

                    file.write(motion_message())

                FtpUploader.upload_move(self.remotePath, filename, filepath)

                #---

            #---

        time4 = time.time() - timeStart

        return motionDetected
예제 #4
0
    def process_motion(self, camera, stream, camMotionDetector):
        # As soon as we detect motion, split the recording to
        # record the frames "after" motion
        detectionTime = datetime.now()
        nowtime = detectionTime
        # To be safe, limit to 60s video
        startDetectionTime = time.time()
        endDetectionTime = startDetectionTime + 60
        camera_name = config.config['camera']['name']

        preFilename = "%s-%04d%02d%02d-%02d%02d%02d" % (
            camera_name, detectionTime.year, detectionTime.month,
            detectionTime.day, detectionTime.hour, detectionTime.minute,
            detectionTime.second)
        beforeFilename = preFilename + "-1.h264"
        afterFilename = preFilename + "-2.h264"
        mergeFilename = preFilename + ".mp4"

        beforeFilepath = self._storage_path + beforeFilename
        afterFilepath = self._storage_path + afterFilename
        mergeFilepath = self._storage_path + mergeFilename

        #log.info( "%s - Saved After Video to %s" % (progname, afterFilename))
        camera.split_recording(afterFilepath)

        #---

        # Always record at least 5s (or 15 frames @ 3fps) of video per event
        # Need to call detect_motion to keep feeding the yim file
        for i in range(15):
            camMotionDetector.detect_motion(camera, False)
            camera.wait_recording(0.2)

        # Wait until motion is no longer detected (+5s or 15 frames @ 3fps), then split
        # recording back to the in-memory circular buffer
        no_motion = 0
        while (no_motion < 15 and time.time() < endDetectionTime):
            if (camMotionDetector.detect_motion(camera, False)):
                no_motion = 0
            else:
                no_motion += 1
            camera.wait_recording(0.2)

        #---

        # Write the entire content of the circular buffer to disk. No need to
        # lock the stream here as we're definitely not writing to it
        # simultaneously
        #print( "%s - Saved Before Video to %s" % (filename))
        with io.open(beforeFilepath, 'wb') as output:
            for frame in stream.frames:
                if frame.header:
                    stream.seek(frame.position)
                    break
            while True:
                buf = stream.read1()
                if not buf:
                    break
                output.write(buf)
        # Wipe the circular stream once we're done
        stream.seek(0)
        stream.truncate()

        log.info('Motion stopped! no_motion=%d, elapseTime=%fs' %
                 (no_motion, (time.time() - startDetectionTime)))
        camera.split_recording(stream)

        #        LEDProcessor.red(True)

        remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month),
                      "%02d" % (nowtime.day))
        FtpUploader.merge_convert_and_upload_move(beforeFilepath,
                                                  afterFilepath, remotePath,
                                                  mergeFilename, mergeFilepath)

        log.info('Motion detected!')
예제 #5
0
    def detect_motion(self, camera, debug_detection):
        motionDetected = False

        timeStart = time.time()

        # ---

        if CamMotionDetector._frame_processed_count >= 10:
            CamMotionDetector._frame_processed_fps = CamMotionDetector._frame_processed_count / (
                timeStart - CamMotionDetector._frame_processed_start_time
            )
            CamMotionDetector._frame_processed_count = 0
            CamMotionDetector._frame_processed_start_time = timeStart
        else:
            CamMotionDetector._frame_processed_count += 1

        # ---

        # finish to dump previous ymi file before to process next dectection
        if CamMotionDetector._frame_before_ymi_dump < 0:
            pass
        elif CamMotionDetector._frame_before_ymi_dump > 0:
            CamMotionDetector._frame_before_ymi_dump -= 1
        else:
            # Dump images used for detection up to detection time

            filename = self._motionDetectedPrefixFilename + ".ymi"
            filepath = self._motionDebugPath + filename
            write_image_buffer(filepath)

            FtpUploader.upload_move(self.remotePath, filename, filepath)

            CamMotionDetector._frame_before_ymi_dump = -1

        # ---

        stream = io.BytesIO()
        camera.capture(
            stream,
            format="yuv",
            resize=(CamMotionDetector._detectionImageWidth, CamMotionDetector._detectionImageHeight),
            use_video_port=True,
        )
        stream.seek(0)

        time1 = time.time() - timeStart
        timeStart2 = time.time()

        if self._buffer1 is None:
            # self._buffer1 = bytearray(stream.getbuffer())
            self._buffer1 = stream.getbuffer()
        else:

            # --- Motion Detection -----------------------------------------------
            # Compare current_image to prior_image to detect motion.

            # Buffer packed 4 byte per pixel, line after line. (RGBA)(RGBA)
            # process on a copy improve performance by 30%. but we cannot modify image buffer anymore
            # self._buffer2 = bytearray(stream.getbuffer())
            self._buffer2 = stream.getbuffer()

            motionDetected = detect_motion(self._buffer1, self._buffer2)
            self._buffer1 = self._buffer2

            time2 = time.time() - timeStart2

            # self._counter_debug_dump += 1

            # Debug when threshold is reached
            # if (motionDetected or self._counter_debug_dump >= 10):
            if motionDetected and debug_detection:
                # self._counter_debug_dump = 0

                timeStart3 = time.time()

                nowtime = datetime.now()

                camera_name = config.config["camera"]["name"]

                self._motionDetectedPrefixFilename = "%s-%04d%02d%02d-%02d%02d%02d" % (
                    camera_name,
                    nowtime.year,
                    nowtime.month,
                    nowtime.day,
                    nowtime.hour,
                    nowtime.minute,
                    nowtime.second,
                )
                self.remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d/" % (nowtime.day))

                # ---
                # Schedule YMI file generation (if not yet scheduled)
                if CamMotionDetector._frame_before_ymi_dump < 0:
                    CamMotionDetector._frame_before_ymi_dump = 180

                # ---

                filename = self._motionDetectedPrefixFilename + ".tiff"
                filepath = self._motionDebugPath + filename
                img = Image.frombuffer(
                    "CMYK",
                    (self._detectionImageWidth, self._detectionImageHeight),
                    self._debugImageData,
                    "raw",
                    "CMYK",
                    0,
                    1,
                )
                img.save(filepath)

                FtpUploader.upload_move(self.remotePath, filename, filepath)

                # ---

                if motionDetected:
                    filename = self._motionDetectedPrefixFilename + ".txt"
                else:
                    filename = self._motionDetectedPrefixFilename + "-debug.txt"
                filepath = self._motionDebugPath + filename

                time3 = time.time() - timeStart3

                with open(filepath, "w") as file:
                    file.write(
                        "Cam Motion Detector: [%d,%d] noiseLevel=%d noiseLevelForHistory=%d sensitivity=%d\n"
                        % (
                            self._detectionImageWidth,
                            self._detectionImageHeight,
                            CamMotionDetector._noiseLevel,
                            CamMotionDetector._noiseLevelForHistory,
                            CamMotionDetector._sensitivity,
                        )
                    )
                    file.write(
                        "Motion Detection: {:.0f} fps (capture {:.0f} ms | processing {:.0f} ms |  dump {:.0f} ms)\n".format(
                            CamMotionDetector._frame_processed_fps, 1000 * time1, 1000 * time2, 1000 * time3
                        )
                    )

                    file.write(motion_message())

                FtpUploader.upload_move(self.remotePath, filename, filepath)

                # ---

            # ---

        time4 = time.time() - timeStart

        return motionDetected
예제 #6
0
    def run(self):
        try:
            log.info("CamProcessorServer Started")

            camera_name = config.config['camera']['name']

            with CamMotionDetector(self._storage_path) as camMotionDetector:

                # Take a shot at boot, them every hour on the hour
                log.info("Start After Boot Picture")
#                LEDProcessor.green(True)
                with picamera.PiCamera() as camera:
                    nowtime = datetime.now()
                    imageFilename = "%s-%04d%02d%02d-%02d%02d%02d-Boot.jpg" % (camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour, nowtime.minute, nowtime.second)
                    imageFilepath = self._periodic_path + imageFilename
                    camera.resolution = (2592, 1944)
#                    camera.hflip = True
#                    camera.vflip = True
                    #camera.exif_tags['EXIF.UserComment'] = b'Garden'
                    camera.start_preview()
                    # Camera warm-up time
                    time.sleep(2)
#                    LEDProcessor.green(False)
                    camera.capture(imageFilepath)
#                    LEDProcessor.green(True)

                    remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d" % (nowtime.day))
                    FtpUploader.upload_move(remotePath, imageFilename, imageFilepath)
#                LEDProcessor.green(False)

#                LEDProcessor.red(False)
#                LEDProcessor.blue(False)

                self.lastPictureTime = datetime.utcnow().hour;

                while not self._terminate:

                    log.info("Start Motion detection")

                    with picamera.PiCamera() as camera:

                        #camera.led = False
#                        LEDProcessor.camera(False)

                        camera.resolution = (1280, 720)
#                        camera.hflip = True
#                        camera.vflip = True
                        camera.framerate = 6
                        #camera.video_stabilization = True
                        stream = picamera.PiCameraCircularIO(camera, seconds=5)

                        camera.start_recording(stream, format='h264')

                        try:
                            while not self._terminate:
                                camera.wait_recording(0.2)
                                if camMotionDetector.detect_motion(camera, True):
                                    self.process_motion(camera, stream, camMotionDetector)

                                # 'datetime.utcnow().hour' take about 25 usec
                                # 'time.gmtime()[3]' take about 26 usec
                                utc_now_hour = datetime.utcnow().hour;
                                if (utc_now_hour != self.lastPictureTime):
                                    self.lastPictureTime = utc_now_hour
                                    break
                        except Exception as e:
                            log.exception("Motion detection")
                        finally:
                            camera.stop_recording()

                    if (self._terminate):
                        log.info("CamProcessorServer terminated %d" % (self._terminate))
                        break

                    # Take a shot at boot, them every hour on the hour
                    log.info("Start Periodic Picture")
#                    LEDProcessor.green(True)
                    with picamera.PiCamera() as camera:
                        nowtime = datetime.now()
                        log.info('Periodic Picture')

                        imageFilename = "%s-%04d%02d%02d-%02d0000.jpg" % (camera_name, nowtime.year, nowtime.month, nowtime.day, nowtime.hour)
                        imageFilepath = self._periodic_path + imageFilename
                        camera.resolution = (2592, 1944)
#                        camera.hflip = True
#                        camera.vflip = True
                        #camera.exif_tags['EXIF.UserComment'] = b'Garden'
                        camera.start_preview()
                        # Camera warm-up time
                        time.sleep(1)
#                        LEDProcessor.green(False)
                        camera.capture(imageFilepath)
#                        LEDProcessor.green(True)

                        remotePath = ('Periodic', "%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d" % (nowtime.day))
                        FtpUploader.upload_move(remotePath, imageFilename, imageFilepath)
#                    LEDProcessor.green(False)


        except EnvironmentError as e:
            log.exception("CamProcessorServer Daemon failed: %d (%s)" % (e.errno, e.strerror))
        except Exception as e:
            log.exception("CamProcessorServer Daemon failed (Exception)")
        finally:
            log.info("CamProcessorServer Daemon Exit.")
예제 #7
0
    def process_motion(self, camera, stream, camMotionDetector):
        # As soon as we detect motion, split the recording to
        # record the frames "after" motion
        detectionTime = datetime.now()
        nowtime = detectionTime
        # To be safe, limit to 60s video
        startDetectionTime = time.time()
        endDetectionTime = startDetectionTime + 60
        camera_name = config.config['camera']['name']

        preFilename = "%s-%04d%02d%02d-%02d%02d%02d" % (camera_name, detectionTime.year, detectionTime.month, detectionTime.day, detectionTime.hour, detectionTime.minute, detectionTime.second)
        beforeFilename = preFilename + "-1.h264"
        afterFilename = preFilename + "-2.h264"
        mergeFilename = preFilename + ".mp4"

        beforeFilepath = self._storage_path + beforeFilename
        afterFilepath = self._storage_path + afterFilename
        mergeFilepath = self._storage_path + mergeFilename

        #log.info( "%s - Saved After Video to %s" % (progname, afterFilename))
        camera.split_recording(afterFilepath)

        #---

        # Always record at least 5s (or 15 frames @ 3fps) of video per event
        # Need to call detect_motion to keep feeding the yim file
        for i in range(15):
            camMotionDetector.detect_motion(camera, False)
            camera.wait_recording(0.2)

        # Wait until motion is no longer detected (+5s or 15 frames @ 3fps), then split
        # recording back to the in-memory circular buffer
        no_motion = 0
        while(no_motion < 15 and time.time() < endDetectionTime):
            if (camMotionDetector.detect_motion(camera, False)):
                no_motion = 0
            else:
                no_motion += 1
            camera.wait_recording(0.2)


        #---

        # Write the entire content of the circular buffer to disk. No need to
        # lock the stream here as we're definitely not writing to it
        # simultaneously
        #print( "%s - Saved Before Video to %s" % (filename))
        with io.open(beforeFilepath, 'wb') as output:
            for frame in stream.frames:
                if frame.header:
                    stream.seek(frame.position)
                    break
            while True:
                buf = stream.read1()
                if not buf:
                    break
                output.write(buf)
        # Wipe the circular stream once we're done
        stream.seek(0)
        stream.truncate()

        log.info('Motion stopped! no_motion=%d, elapseTime=%fs' % (no_motion, (time.time() - startDetectionTime)))
        camera.split_recording(stream)

#        LEDProcessor.red(True)

        remotePath = ("%04d" % (nowtime.year), "%02d" % (nowtime.month), "%02d" % (nowtime.day))
        FtpUploader.merge_convert_and_upload_move(beforeFilepath, afterFilepath, remotePath, mergeFilename, mergeFilepath)

        log.info('Motion detected!')
예제 #8
0
    def run(self):

        service_list = []

        try:
            log.info("""

    ----------------------------
    ---  Picammory Starting  ---
    ----------------------------
""")

            os.chdir(os.path.expanduser('~/picammory/picammory/'))
            log.info("os.getcwd() = '%s'", os.getcwd())

            #---

            #            for gpio_pin in (5, 23, 24, 25):
            #                subprocess.call(['/usr/local/bin/gpio', 'export', str(gpio_pin), 'out'])

            #            wiringpi2.wiringPiSetupSys()

            #---

            config.config_load('picammory.ini')

            #---

            #            LEDProcessor.start()
            #            service_list.append(LEDProcessor)
            #
            #            LEDProcessor.blue(True)

            #---

            MailService.start()
            service_list.append(MailService)
            MailService.send_message('Picammory', 'Picammory Server Starting')

            #            LEDProcessor.green(True)

            #---

            FtpUploader.start()
            service_list.append(FtpUploader)

            #            LEDProcessor.red(True)

            #---

            log.info("Start Cam Processor")
            self.cam_processor = CamProcessor(
                os.path.expanduser('~/picammory_storage/'))
            service_list.append(self.cam_processor)

            #            LEDProcessor.blue(False)

            #---

            #            LEDProcessor.green(False)
            #            LEDProcessor.red(False)

            #--- Wait until one thread stop...
            stopped_service = None
            while (stopped_service is None):
                for service in service_list:
                    if not service.is_alive():
                        log.info("Service %s is dead", service)
                        stopped_service = service
                        break
                time.sleep(1)

        except EnvironmentError as e:
            log.exception("Picammory failed 1")
            MailService.send_message(
                "Picammory Error",
                "EnvironmentError: SprinklermoryServer failed: %d (%s)" %
                (e.errno, e.strerror))
        except Exception as e:
            log.exception("Picammory failed 2")
            MailService.send_message("Picammory Error",
                                     "Exception: Scheduler failed: %s" % (e))
        finally:
            for service in service_list:
                service.terminate()
            log.info('''

    ------------------------
    ---  Picammory Exit  ---
    ------------------------
''')

        sys.exit(1)