def _set_all_motion_detection(enable): import motionctl def on_set_config_response(error=None): if error is None: logging.debug("Saving motion detection failed") else: logging.debug("Motion detection saved successfully") def on_get_config_response(remote_ui_config=None, error=None): remote_ui_config["motion_detection"] = enable remote.set_config(local_config, remote_ui_config, on_set_config_response) for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.is_local_motion_camera(camera_config): local_config = config.get_camera(camera_id) remote.get_config(local_config, on_get_config_response) logging.debug( 'motion detection %s by config for remote camera with id %s' % (str(enable), camera_id)) elif not camera_config['@motion_detection']: logging.debug( 'motion detection %s by config for local camera with id %s' % (str(enable), camera_id)) motionctl.set_motion_detection(camera_id, enable) else: logging.error("Couldn't categorize camera with id %s" % camera_id)
def cleanup_media(media_type): logging.debug('cleaning up %(media_type)ss...' % {'media_type': media_type}) if media_type == 'picture': exts = _PICTURE_EXTS else: # media_type == 'movie' exts = _MOVIE_EXTS + ['.thumb'] for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.is_local_motion_camera(camera_config): continue preserve_media = camera_config.get('@preserve_%(media_type)ss' % {'media_type': media_type}, 0) if preserve_media == 0: continue # preserve forever still_images_enabled = bool(camera_config['picture_filename']) or bool(camera_config['snapshot_filename']) movies_enabled = bool(camera_config['ffmpeg_output_movies']) if media_type == 'picture' and not still_images_enabled: continue # only cleanup pictures for cameras with still images enabled elif media_type == 'movie' and not movies_enabled: continue # only cleanup movies for cameras with movies enabled preserve_moment = datetime.datetime.now() - datetime.timedelta(days=preserve_media) target_dir = camera_config.get('target_dir') if os.path.exists(target_dir): # create a sentinel file to make sure the target dir is never removed open(os.path.join(target_dir, '.keep'), 'w').close() _remove_older_files(target_dir, preserve_moment, exts=exts)
def make_next_movie_preview(): global _previewless_movie_files logging.debug('making preview for the next movie...') if _previewless_movie_files: (camera_config, path) = _previewless_movie_files.pop(0) make_movie_preview(camera_config, path) else: logging.debug('gathering movies without preview...') count = 0 for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue target_dir = camera_config['target_dir'] for (full_path, st) in _list_media_files(target_dir, _MOVIE_EXTS): # @UnusedVariable if os.path.exists(full_path + '.thumb'): continue logging.debug('found a movie without preview: %(path)s' % { 'path': full_path}) _previewless_movie_files.append((camera_config, full_path)) count += 1 logging.debug('found %(count)d movies without preview' % {'count': count}) if count: make_next_movie_preview()
def cleanup_media(media_type): logging.debug('cleaning up %(media_type)ss...' % {'media_type': media_type}) if media_type == 'picture': exts = _PICTURE_EXTS elif media_type == 'movie': exts = _MOVIE_EXTS + ['.thumb'] for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue preserve_media = camera_config.get('@preserve_%(media_type)ss' % {'media_type': media_type}, 0) if preserve_media == 0: return # preserve forever still_images_enabled = bool( ((camera_config['emulate_motion'] or camera_config['output_pictures']) and camera_config['picture_filename']) or (camera_config['snapshot_interval'] and camera_config['snapshot_filename'])) movies_enabled = camera_config['ffmpeg_output_movies'] if media_type == 'picture' and not still_images_enabled: continue # only cleanup pictures for cameras with still images enabled elif media_type == 'movie' and not movies_enabled: continue # only cleanup movies for cameras with movies enabled preserve_moment = datetime.datetime.now() - datetime.timedelta(days=preserve_media) target_dir = camera_config.get('target_dir') _remove_older_files(target_dir, preserve_moment, exts=exts)
def _disable_initial_motion_detection(): for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue if not camera_config['@motion_detection']: logging.debug('motion detection disabled by config for camera with id %s' % camera_id) set_motion_detection(camera_id, False)
def _check_ws(): # schedule the next call ioloop = tornado.ioloop.IOLoop.instance() ioloop.add_timeout(datetime.timedelta(seconds=10), _check_ws) if not motionctl.running(): return now = datetime.datetime.now() for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue working_schedule = camera_config.get('@working_schedule') motion_detection = camera_config.get('@motion_detection') working_schedule_type = camera_config.get( '@working_schedule_type') or 'outside' if not working_schedule: # working schedule disabled, motion detection left untouched continue if not motion_detection: # motion detection explicitly disabled continue now_during = _during_working_schedule(now, working_schedule) must_be_enabled = (now_during and working_schedule_type == 'during') or (not now_during and working_schedule_type == 'outside') currently_enabled = motionctl.get_motion_detection(camera_id) if currently_enabled is None: # could not detect current status logging.warn( 'skipping motion detection status update for camera with id %(id)s' % {'id': camera_id}) continue if currently_enabled and not must_be_enabled: logging.debug( 'must disable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type }) motionctl.set_motion_detection(camera_id, False) elif not currently_enabled and must_be_enabled: logging.debug( 'must enable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type }) motionctl.set_motion_detection(camera_id, True)
def _set_streameye_settings(camera_id, s): s = dict(s) s.setdefault('sePort', 8081) s.setdefault('seAuthMode', 'disabled') main_config = config.get_main() username = main_config['@normal_username'] password = main_config['@normal_password'] realm = 'motionEyeOS' logging.debug('writing streameye settings to %s' % STREAMEYE_CONF) lines = [ 'PORT="%s"' % s['sePort'], 'AUTH="%s"' % s['seAuthMode'], 'CREDENTIALS="%s:%s:%s"' % (username, password, realm) ] with open(STREAMEYE_CONF, 'w') as f: for line in lines: f.write(line + '\n') if 1 in config.get_camera_ids(): # a workaround to update the camera username and password # since we cannot call set_camera() from here if s['seAuthMode'] == 'basic': url = 'http://%s:%[email protected]:%s/' % (username, password, s['sePort']) else: url = 'http://127.0.0.1:%s/' % s['sePort'] if 1 in config._camera_config_cache: logging.debug('updating streaming authentication in config cache') config._camera_config_cache[1]['@url'] = url lines = config.get_camera(1, as_lines=True) for i, line in enumerate(lines): if line.startswith('# @url'): lines[i] = '# @url %s' % url config_file = os.path.join(settings.CONF_PATH, config._CAMERA_CONFIG_FILE_NAME % {'id': 1}) logging.debug( 'updating streaming authentication in camera config file %s' % config_file) with open(config_file, 'w') as f: for line in lines: f.write(line + '\n') logging.debug('restarting streameye') if os.system('streameye.sh restart'): logging.error('streameye restart failed')
def _check_ws(): # schedule the next call io_loop = IOLoop.instance() io_loop.add_timeout(datetime.timedelta(seconds=10), _check_ws) if not motionctl.running(): return def on_motion_detection_status(camera_id, must_be_enabled, working_schedule_type, enabled=None, error=None): if error: # could not detect current status return logging.warn("skipping motion detection status update for camera with id %(id)s" % {"id": camera_id}) if enabled and not must_be_enabled: logging.debug( "must disable motion detection for camera with id %(id)s (%(what)s working schedule)" % {"id": camera_id, "what": working_schedule_type} ) motionctl.set_motion_detection(camera_id, False) elif not enabled and must_be_enabled: logging.debug( "must enable motion detection for camera with id %(id)s (%(what)s working schedule)" % {"id": camera_id, "what": working_schedule_type} ) motionctl.set_motion_detection(camera_id, True) now = datetime.datetime.now() for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue working_schedule = camera_config.get("@working_schedule") motion_detection = camera_config.get("@motion_detection") working_schedule_type = camera_config.get("@working_schedule_type") or "outside" if not working_schedule: # working schedule disabled, motion detection left untouched continue if not motion_detection: # motion detection explicitly disabled continue now_during = _during_working_schedule(now, working_schedule) must_be_enabled = (now_during and working_schedule_type == "during") or ( not now_during and working_schedule_type == "outside" ) motionctl.get_motion_detection( camera_id, functools.partial(on_motion_detection_status, camera_id, must_be_enabled, working_schedule_type) )
def thread_id_to_camera_id(thread_id): # find the corresponding camera_id # (which can be different from thread_id) camera_ids = config.get_camera_ids() tid = 0 for cid in camera_ids: camera_config = config.get_camera(cid) if utils.local_motion_camera(camera_config): tid += 1 if tid == thread_id: return cid return None
def camera_id_to_thread_id(camera_id): # find the corresponding thread_id # (which can be different from camera_id) camera_ids = config.get_camera_ids() thread_id = 0 for cid in camera_ids: camera_config = config.get_camera(cid) if utils.local_motion_camera(camera_config): thread_id += 1 if cid == camera_id: return thread_id or None return None
def _set_streameye_settings(camera_id, s): s = dict(s) s.setdefault('sePort', 8081) s.setdefault('seAuthMode', 'disabled') main_config = config.get_main() username = main_config['@normal_username'] password = main_config['@normal_password'] realm = 'motionEyeOS' logging.debug('writing streameye settings to %s' % STREAMEYE_CONF) lines = [ 'PORT="%s"' % s['sePort'], 'AUTH="%s"' % s['seAuthMode'], 'CREDENTIALS="%s:%s:%s"' % (username, password, realm) ] with open(STREAMEYE_CONF, 'w') as f: for line in lines: f.write(line + '\n') if 1 in config.get_camera_ids(): # a workaround to update the camera username and password # since we cannot call set_camera() from here if s['seAuthMode'] == 'basic': url = 'http://%s:%[email protected]:%s/' % (username, password, s['sePort']) else: url = 'http://127.0.0.1:%s/' % s['sePort'] if 1 in config._camera_config_cache: logging.debug('updating streaming authentication in config cache') config._camera_config_cache[1]['@url'] = url lines = config.get_camera(1, as_lines=True) for i, line in enumerate(lines): if line.startswith('# @url'): lines[i] = '# @url %s' % url config_file = os.path.join(settings.CONF_PATH, config._CAMERA_CONFIG_FILE_NAME % {'id': 1}) logging.debug('updating streaming authentication in camera config file %s' % config_file) with open(config_file, 'w') as f: for line in lines: f.write(line + '\n') logging.debug('restarting streameye') if os.system('streameye.sh restart'): logging.error('streameye restart failed')
def make_media_folders(): import config config.get_main() # just to have main config already loaded camera_ids = config.get_camera_ids() for camera_id in camera_ids: camera_config = config.get_camera(camera_id) if 'target_dir' in camera_config: if not os.path.exists(camera_config['target_dir']): try: os.makedirs(camera_config['target_dir']) except Exception as e: logging.error('failed to create root media folder "%s" for camera with id %s: %s' % ( camera_config['target_dir'], camera_id, e))
def _check_ws(): # schedule the next call ioloop = tornado.ioloop.IOLoop.instance() ioloop.add_timeout(datetime.timedelta(seconds=10), _check_ws) if not motionctl.running(): return now = datetime.datetime.now() for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue working_schedule = camera_config.get('@working_schedule') motion_detection = camera_config.get('@motion_detection') working_schedule_type = camera_config.get('@working_schedule_type') or 'outside' if not working_schedule: # working schedule disabled, motion detection left untouched continue if not motion_detection: # motion detection explicitly disabled continue now_during = _during_working_schedule(now, working_schedule) must_be_enabled = (now_during and working_schedule_type == 'during') or (not now_during and working_schedule_type == 'outside') currently_enabled = motionctl.get_motion_detection(camera_id) if currently_enabled is None: # could not detect current status logging.warn('skipping motion detection status update for camera with id %(id)s' % {'id': camera_id}) continue if currently_enabled and not must_be_enabled: logging.debug('must disable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type}) motionctl.set_motion_detection(camera_id, False) elif not currently_enabled and must_be_enabled: logging.debug('must enable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type}) motionctl.set_motion_detection(camera_id, True)
def cleanup_media(media_type): logging.debug("cleaning up %(media_type)ss..." % {"media_type": media_type}) if media_type == "picture": exts = _PICTURE_EXTS elif media_type == "movie": exts = _MOVIE_EXTS + [".thumb"] for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue preserve_media = camera_config.get("@preserve_%(media_type)ss" % {"media_type": media_type}, 0) if preserve_media == 0: return # preserve forever still_images_enabled = bool( ( (camera_config["emulate_motion"] or camera_config["output_pictures"]) and camera_config["picture_filename"] ) or (camera_config["snapshot_interval"] and camera_config["snapshot_filename"]) ) movies_enabled = camera_config["ffmpeg_output_movies"] if media_type == "picture" and not still_images_enabled: continue # only cleanup pictures for cameras with still images enabled elif media_type == "movie" and not movies_enabled: continue # only cleanup movies for cameras with movies enabled preserve_moment = datetime.datetime.now() - datetime.timedelta(days=preserve_media) target_dir = camera_config.get("target_dir") if os.path.exists(target_dir): # create a sentinel file to make sure the target dir is never removed open(os.path.join(target_dir, ".keep"), "w").close() _remove_older_files(target_dir, preserve_moment, exts=exts)
def __init__(self): self.stopped=False for camera_id in config.get_camera_ids(): ODThread.img_todo[camera_id] = None ODThread.img_done[camera_id] = None #TF variables self.detection_graph = tf.Graph() with self.detection_graph.as_default(): od_graph_def = tf.GraphDef() with tf.gfile.GFile(ODThread.PATH_TO_GRAPH, 'rb') as fid: serialized_graph = fid.read() od_graph_def.ParseFromString(serialized_graph) tf.import_graph_def(od_graph_def, name='') self.label_map = label_map_util.load_labelmap(ODThread.PATH_TO_LABELS) self.categories = label_map_util.convert_label_map_to_categories(self.label_map, max_num_classes=ODThread.NUM_CLASSES, use_display_name=True) self.category_index = label_map_util.create_category_index(self.categories) self.sess = tf.Session(graph=self.detection_graph) self.proc_im = None
def cleanup_media(media_type): logging.debug('cleaning up %(media_type)ss...' % {'media_type': media_type}) if media_type == 'picture': exts = _PICTURE_EXTS elif media_type == 'movie': exts = _MOVIE_EXTS + ['.thumb'] for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue preserve_media = camera_config.get( '@preserve_%(media_type)ss' % {'media_type': media_type}, 0) if preserve_media == 0: return # preserve forever still_images_enabled = bool( ((camera_config['emulate_motion'] or camera_config['output_pictures']) and camera_config['picture_filename']) or (camera_config['snapshot_interval'] and camera_config['snapshot_filename'])) movies_enabled = camera_config['ffmpeg_output_movies'] if media_type == 'picture' and not still_images_enabled: continue # only cleanup pictures for cameras with still images enabled elif media_type == 'movie' and not movies_enabled: continue # only cleanup movies for cameras with movies enabled preserve_moment = datetime.datetime.now() - datetime.timedelta( days=preserve_media) target_dir = camera_config.get('target_dir') _remove_older_files(target_dir, preserve_moment, exts=exts)
def update(self): while True: if self.stopped: return od_active = False for camera_id in config.get_camera_ids(): #logging.debug('processing camera %s'%camera_id) camera_config = config.get_camera(camera_id) if camera_config['@motion_detection']: if motionctl.is_motion_detected(camera_id): #logging.debug(camera_config) #im_bytes = ODThread.img_todo[camera_id] im_bytes = mjpgclient.get_jpg(camera_id) #ODThread.img_todo[camera_id]=None if im_bytes is not None: # OD has been requested for this camera od_active = True im = self.bytes_to_np(im_bytes) self.process_image(im) if not od_active: time.sleep(ODThread.INACTIVE_SLEEP_TIME)
def _get_streameye_enabled(): global _streameye_enabled if _streameye_enabled is not None: return _streameye_enabled camera_ids = config.get_camera_ids(filter_valid=False) # filter_valid prevents infinte recursion if len(camera_ids) != 1: _streameye_enabled = False return False camera_config = config.get_camera(camera_ids[0], as_lines=True) # as_lines prevents infinte recursion camera_config = config._conf_to_dict(camera_config) if camera_config.get('@proto') != 'mjpeg': _streameye_enabled = False return False if '127.0.0.1:' not in camera_config.get('@url', ''): _streameye_enabled = False return False _streameye_enabled = True return True
def make_next_movie_preview(): global _previewless_movie_files logging.debug('making preview for the next movie...') if _previewless_movie_files: (camera_config, path) = _previewless_movie_files.pop(0) make_movie_preview(camera_config, path) else: logging.debug('gathering movies without preview...') count = 0 for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.local_motion_camera(camera_config): continue target_dir = camera_config['target_dir'] for (full_path, st) in _list_media_files(target_dir, _MOVIE_EXTS): # @UnusedVariable if os.path.exists(full_path + '.thumb'): continue logging.debug('found a movie without preview: %(path)s' % {'path': full_path}) _previewless_movie_files.append((camera_config, full_path)) count += 1 logging.debug('found %(count)d movies without preview' % {'count': count}) if count: make_next_movie_preview()
def _check_ws(): # schedule the next call io_loop = IOLoop.instance() io_loop.add_timeout(datetime.timedelta(seconds=10), _check_ws) if not motionctl.running(): return def on_motion_detection_status(camera_id, must_be_enabled, working_schedule_type, enabled=None, error=None): if error: # could not detect current status return logging.warn( 'skipping motion detection status update for camera with id %(id)s: %(error)s' % { 'id': camera_id, 'error': error }) if enabled and not must_be_enabled: logging.debug( 'must disable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type }) motionctl.set_motion_detection(camera_id, False) elif not enabled and must_be_enabled: logging.debug( 'must enable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type }) motionctl.set_motion_detection(camera_id, True) now = datetime.datetime.now() for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.is_local_motion_camera(camera_config): continue working_schedule = camera_config.get('@working_schedule') motion_detection = camera_config.get('@motion_detection') working_schedule_type = camera_config.get( '@working_schedule_type') or 'outside' geofence_enabled = camera_config.get('@geofence_enabled') ips = camera_config.get('@geofence_ips') if not working_schedule: # working schedule disabled, motion detection left untouched continue if not motion_detection: # motion detection explicitly disabled continue must_be_enabled = True now_during = True if working_schedule: now_during = _during_working_schedule(now, working_schedule) if geofence_enabled and (now_during or working_schedule_type != 'outside'): for ip in ips.split(','): try: ip = ip.strip() socket.inet_aton(ip) except socket.error as e: logging.warning('geofence ip error: \'%s\' msg: %s' % (ip, e.message)) continue try: subprocess.check_call(['ping', '-c1', ip], stdout=open(os.devnull, 'w')) must_be_enabled = False break except: pass motionctl.get_motion_detection( camera_id, functools.partial(on_motion_detection_status, camera_id, must_be_enabled, working_schedule_type))
def _set_streameye_enabled(enabled): global _streameye_enabled if enabled: logging.debug('removing all cameras from cache') config._camera_config_cache = {} config._camera_ids_cache = [] logging.debug('disabling all cameras in motion.conf') cmd = 'sed -r -i "s/^camera (.*)/#camera \\1/" /data/etc/motion.conf &>/dev/null' if os.system(cmd): logging.error('failed to disable cameras in motion.conf') logging.debug('renaming camera files') for name in os.listdir(settings.CONF_PATH): if re.match('^camera-\d+.conf$', name): os.rename(os.path.join(settings.CONF_PATH, name), os.path.join(settings.CONF_PATH, name + '.bak')) logging.debug('adding simple mjpeg camera') streameye_settings = _get_streameye_settings(1) main_config = config.get_main() device_details = { 'proto': 'mjpeg', 'host': '127.0.0.1', 'port': streameye_settings['sePort'], 'username': '', 'password': '', 'scheme': 'http', 'path': '/' } if streameye_settings['seAuthMode'] == 'basic': device_details['username'] = main_config['@normal_username'] device_details['password'] = main_config['@normal_password'] _streameye_enabled = True config._additional_structure_cache = {} camera_config = config.add_camera(device_details) # call set_camera again so that the streamEye-related defaults are saved config.set_camera(camera_config['@id'], camera_config) _set_motioneye_add_remove_cameras(False) else: # disabled logging.debug('removing simple mjpeg camera') for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if camera_config.get('@proto') == 'mjpeg': config.rem_camera(camera_id) logging.debug('renaming camera files') for name in os.listdir(settings.CONF_PATH): if re.match('^camera-\d+.conf.bak$', name): os.rename(os.path.join(settings.CONF_PATH, name), os.path.join(settings.CONF_PATH, name[:-4])) _streameye_enabled = False config.invalidate() logging.debug('enabling all cameras') for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) camera_config['@enabled'] = True config.set_camera(camera_id, camera_config) _set_motioneye_add_remove_cameras(True)
def _set_streameye_enabled(enabled): global _streameye_enabled if enabled: logging.debug('removing all cameras from cache') config._camera_config_cache = {} config._camera_ids_cache = [] logging.debug('disabling all cameras in motion.conf') cmd = 'sed -r -i "s/^thread (.*)/#thread \1/" /data/etc/motion.conf &>/dev/null' if os.system(cmd): logging.error('failed to disable cameras in motion.conf') logging.debug('renaming thread files') for name in os.listdir(settings.CONF_PATH): if re.match('^thread-\d+.conf$', name): os.rename(os.path.join(settings.CONF_PATH, name), os.path.join(settings.CONF_PATH, name + '.bak')) logging.debug('adding simple mjpeg camera') streameye_settings = _get_streameye_settings(1) main_config = config.get_main() device_details = { 'proto': 'mjpeg', 'host': '127.0.0.1', 'port': streameye_settings['sePort'], 'username': '', 'password': '', 'scheme': 'http', 'uri': '/' } if streameye_settings['seAuthMode'] == 'basic': device_details['username'] = main_config['@normal_username'] device_details['password'] = main_config['@normal_password'] _streameye_enabled = True config._additional_structure_cache = {} camera_config = config.add_camera(device_details) # call set_camera again so that the streamEye-related defaults are saved config.set_camera(camera_config['@id'], camera_config) _set_motioneye_add_remove_cameras(False) else: # disabled logging.debug('removing simple mjpeg camera') for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if camera_config.get('@proto') == 'mjpeg': config.rem_camera(camera_id) logging.debug('renaming thread files') for name in os.listdir(settings.CONF_PATH): if re.match('^thread-\d+.conf.bak$', name): os.rename(os.path.join(settings.CONF_PATH, name), os.path.join(settings.CONF_PATH, name[:-4])) _streameye_enabled = False config.invalidate() logging.debug('enabling all cameras') for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) camera_config['@enabled'] = True config.set_camera(camera_id, camera_config) _set_motioneye_add_remove_cameras(True)
def _check_ws(): # schedule the next call io_loop = IOLoop.instance() io_loop.add_timeout(datetime.timedelta(seconds=10), _check_ws) if not motionctl.running(): return def on_motion_detection_status(camera_id, must_be_enabled, working_schedule_type, enabled=None, error=None): if error: # could not detect current status return logging.warn( 'skipping motion detection status update for camera with id %(id)s: %(error)s' % { 'id': camera_id, 'error': error }) if enabled and not must_be_enabled: logging.debug( 'must disable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type }) motionctl.set_motion_detection(camera_id, False) elif not enabled and must_be_enabled: logging.debug( 'must enable motion detection for camera with id %(id)s (%(what)s working schedule)' % { 'id': camera_id, 'what': working_schedule_type }) motionctl.set_motion_detection(camera_id, True) now = datetime.datetime.now() for camera_id in config.get_camera_ids(): camera_config = config.get_camera(camera_id) if not utils.is_local_motion_camera(camera_config): continue working_schedule = camera_config.get('@working_schedule') motion_detection = camera_config.get('@motion_detection') working_schedule_type = camera_config.get( '@working_schedule_type') or 'outside' if not working_schedule: # working schedule disabled, motion detection left untouched continue if not motion_detection: # motion detection explicitly disabled continue now_during = _during_working_schedule(now, working_schedule) must_be_enabled = ((now_during and working_schedule_type == 'during') or (not now_during and working_schedule_type == 'outside')) motionctl.get_motion_detection( camera_id, functools.partial(on_motion_detection_status, camera_id, must_be_enabled, working_schedule_type))