예제 #1
0
    def apply_settings(self, section):
        # Initialise
        controls = self.camera.get_controls()
        self.camera.start_video_capture()

        # Read all camera controls defined in the config file
        for setting in _settings_map:
            value = get_config_option(self.config, section, setting)
            if value is not None:
                asi_control_name, asi_setting_name = _settings_map[setting]
                default_value = controls[asi_control_name]['DefaultValue']
                control_type = getattr(zwoasi, asi_setting_name)
                logger.debug('set control value %s (%s) to %s', setting,
                             asi_setting_name, value)
                if value == 'auto':
                    self.camera.set_control_value(control_type,
                                                  default_value,
                                                  auto=True)
                else:
                    # Cast value to same type as default_value
                    self.camera.set_control_value(control_type,
                                                  type(default_value)(value),
                                                  auto=False)

        image_type = get_config_option(self.config, section, 'image_type')
        if image_type is not None:
            logger.debug('set image type to %s', image_type)
            self.camera.set_image_type(
                getattr(zwoasi, 'ASI_IMG_' + image_type.upper()))
예제 #2
0
 def get_next_file(self, section):
     while True:
         pattern = get_config_option(self.config, section, 'images')
         files = glob.glob(pattern)
         if not files:
             # raise Exception('no files matched %s', pattern)
             yield None
         for f in sorted(files):
             yield f
예제 #3
0
    def apply_settings(self, section):
        # Stop any previous recordings
        self.stop_recording()

        self.use_video_port = get_config_option(self.config,
                                                section,
                                                'use_video_port',
                                                get='getboolean')
        if self.use_video_port:
            self.splitter_port = get_config_option(self.config,
                                                   section,
                                                   'splitter_port',
                                                   0,
                                                   get='getint')

        # Fractions
        framerate = get_config_option(self.config, section, 'framerate')
        if framerate is not None:
            logger.debug('setting framerate=%s', str(framerate))
            self.camera.framerate = fraction_or_float(framerate)

        # Booleans
        for k in ('hflip', 'image_denoise', 'vflip', 'video_denoise'):
            val = get_config_option(self.config, section, k, get='getboolean')
            if val is not None:
                logger.debug('setting %s=%s', k, 'true' if val else 'false')
                setattr(self.camera, k, val)

        # Ints
        for k in ('brightness', 'contrast', 'exposure_compensation', 'iso',
                  'rotation', 'saturation', 'sensor_mode', 'sharpness',
                  'shutter_speed'):
            val = get_config_option(self.config, section, k, get='getint')
            if val is not None:
                logger.debug('setting %s=%d', k, val)
                setattr(self.camera, k, val)

        # Strings
        for k in ('awb_mode', 'drc_strength', 'exposure_mode', 'meter_mode',
                  'resolution', 'still_stats'):
            val = get_config_option(self.config, section, k)
            if val is not None:
                logger.debug('setting %s=%s', k, val)
                setattr(self.camera, k, val)

        awb_gains = get_config_option(self.config, section, 'awb_gains')
        if awb_gains:
            awb_gains = awb_gains.split()
            if len(awb_gains) == 1:
                self.camera.awb_gains = fraction_or_float(awb_gains[0])
            else:
                # awb_gains = (Fraction(*map(int, awb_gains[0])), Fraction(*map(int, awb_gains[0])))
                self.camera.awb_gains = (fraction_or_float(awb_gains[0]),
                                         fraction_or_float(awb_gains[1]))

        if self.use_video_port:
            self.camera.start_recording(NullStream(),
                                        format='rgb',
                                        splitter_port=self.splitter_port + 1)
예제 #4
0
def run_camera(forced_schedule):
    global config
    global camera
    global sampling_interval

    # This should be called after dropping root privileges because
    # it uses safe_eval to convert strings to numbers or
    # lists (not guaranteed safe!)
    #camera = cameralogger.get_camera(config)
    #cameralogger.init_camera(camera, config)

    camera_type = config.get('camera', 'type')
    logger.debug('camera type: %s', camera_type)

    Camera = getattr(
        importlib.import_module('cameralogger.' + camera_type.lower()),
        'Camera')
    camera = Camera(config)
    camera_settings = cameralogger.get_config_option(config, 'camera',
                                                     'settings')
    if camera_settings:
        camera.apply_settings(camera_settings)

    signal.signal(signal.SIGTERM, stop_handler)
    signal.signal(signal.SIGINT, stop_handler)

    try:
        get_log_file_for_time(time.time(), log_filename)
        logger.info('Starting sampling thread')

        do_every(camera, config, forced_schedule, cameralogger.process_tasks)
        while take_images:
            time.sleep(2)

        # Wait until all other threads have (or should have)
        # completed
        try:
            sampling_interval_lock.acquire(True)
            si = sampling_interval
        finally:
            sampling_interval_lock.release()

        for n in range(int(round(si)) + 1):
            if threading.activeCount() == 1:
                break
            time.sleep(1)
    except (KeyboardInterrupt, SystemExit):
        raise
    except Exception:
        get_log_file_for_time(time.time(), log_filename)
        logger.error(traceback.format_exc())
        time.sleep(5)
예제 #5
0
def do_every(camera, config, forced_schedule, worker_func, iterations=0):
    global sampling_interval
    if iterations != 1:
        # Identify current operating condition to find the actions to do and sampling interval
        schedule, schedule_info = cameralogger.get_schedule(
            config, forced_schedule)
        logger.info('using schedule %s', schedule)
        logger.info('schedule info: %s', repr(schedule_info))
        # Schedule the next worker thread. Aim to start at the next
        # multiple of sampling interval. Take current time, add 1.25
        # of the interval and then find the nearest
        # multiple. Calculate delay required.
        now = time.time()
        interval = cameralogger.get_config_option(
            config,
            schedule,
            'sampling_interval',
            fallback_section='common',
            default=default_sampling_interval,
            get='getfloat')
        delay = round_to(now + (1.25 * interval), interval) - now
        # Avoid lockups by many threads piling up. Impose a minimum delay
        if delay < 0.1:
            delay = 0.1
        t = threading.Timer(delay, do_every, [
            camera, config, forced_schedule, worker_func,
            0 if iterations == 0 else iterations - 1
        ])
        t.daemon = True
        t.start()

        # Check if the schedule has changed, if so apply any new settings. To access last_schedule and camera
        # the camera_lock must be acquired
        if config.has_option(schedule, 'camera_settings'):
            if camera_lock.acquire(False):
                try:
                    global last_schedule
                    logger.debug('camera_lock: acquired lock')
                    if schedule != last_schedule:
                        settings_section = config.get(schedule,
                                                      'camera_settings')
                        if not config.has_section(settings_section):
                            logger.error(
                                'cannot apply camera settings for schedule %s: section %s does not exist',
                                schedule, settings_section)
                            raise Exception('missing section %s' %
                                            settings_section)

                        if last_schedule is not None and settings_section == config.get(
                                last_schedule, 'camera_settings'):
                            # No action needed
                            logger.debug(
                                'schedule changed but camera settings unchanged'
                            )
                        else:
                            logger.debug(
                                'schedule changed, applying new settings for %s from section %s',
                                schedule, settings_section)
                            camera.apply_settings(settings_section)
                        last_schedule = schedule  # Update last, after settings have been applied
                finally:
                    camera_lock.release()
                    logging.debug('camera_lock: released lock')
            else:
                logger.error('camera_lock: could not acquire lock')

        # Update the global sampling_interval so that cancel_sampling_threads knows how long to wait.
        # This could be attempted by multiple capture threads so must use a lock. Don't wait for the lock to be
        # available.
        if sampling_interval_lock.acquire(False):
            try:
                logger.debug('sampling_interval_lock: acquired lock')
                sampling_interval = interval
            finally:
                logging.debug('sampling_interval_lock: released lock')
                sampling_interval_lock.release()
        else:
            logger.error('sampling_interval_lock: could not acquire lock')

    try:
        worker_func(camera, config, schedule, schedule_info)
    except (KeyboardInterrupt, SystemExit):
        raise
    except Exception:
        get_log_file_for_time(time.time(), log_filename)
        logger.error(traceback.format_exc())