from collections import OrderedDict
import settings
-import v4l2ctl
_CAMERA_CONFIG_FILE_NAME = 'thread-%(id)s.conf'
camera_ids = get_camera_ids()
cameras = [get_camera(camera_id) for camera_id in camera_ids]
- return bool([c for c in cameras if c['@enabled']])
+ return bool([c for c in cameras if c['@enabled'] and c['@proto'] == 'v4l2'])
def get_camera(camera_id, as_lines=False):
def set_camera(camera_id, data):
# TODO use a cache
- if data.get('@proto') == 'v4l2':
+ if data['@proto'] == 'v4l2':
_set_default_motion_camera(data)
# set the enabled status in main config
main_config['thread'] = threads
+ del data['@enabled']
+ if '@id' in data:
+ del data['@id']
+
set_main(main_config)
# read the actual configuration from file
def add_camera(device_details):
# TODO use a cache
- device = device_details.get('device')
- proto = device_details.get('proto')
-
# determine the last camera id
camera_ids = get_camera_ids()
logging.info('adding new camera with id %(id)s...' % {'id': camera_id})
# add the default camera config
+ proto = device_details['proto']
+
data = OrderedDict()
- data['@name'] = 'Camera' + str(camera_id)
data['@proto'] = proto
- data['@enabled'] = True
-
- for k, v in device_details.items():
- data['@' + k] = v
+ data['@enabled'] = device_details.get('enabled', True)
if proto == 'v4l2':
- data['videodevice'] = device
- # find a suitable resolution
- for (w, h) in v4l2ctl.list_resolutions(device): # TODO move/copy this code to handler/get_config
- if w > 300:
- data['width'] = w
- data['height'] = h
- break
-
+ data['@name'] = 'Camera' + str(camera_id)
+ data['videodevice'] = device_details['device']
+ if 'width' in device_details:
+ data['width'] = device_details['width']
+ data['height'] = device_details['height']
+
+ else:
+ data['@host'] = device_details['host']
+ data['@port'] = device_details['port']
+ data['@username'] = device_details['username']
+ data['@password'] = device_details['password']
+ data['@remote_camera_id'] = device_details['remote_camera_id']
+ data['@enabled'] = device_details.get('enabled', True)
+
# write the configuration to file
set_camera(camera_id, data)
if camera_id:
logging.debug('getting config for camera %(id)s' % {'id': camera_id})
- camera_ids = config.get_camera_ids()
- if camera_id not in camera_ids:
+ if camera_id not in config.get_camera_ids():
raise HTTPError(404, 'no such camera')
camera_config = config.get_camera(camera_id)
if camera_config['@proto'] != 'v4l2':
try:
- remote_data = remote.get_config(
+ remote_ui_config = remote.get_config(
camera_config.get('@host'),
camera_config.get('@port'),
camera_config.get('@username'),
except Exception as e:
return self.finish_json({'error': unicode(e)})
-
- remote_data = self._camera_ui_to_dict(remote_data)
+
+ local_data = camera_config
+ camera_config = self._camera_ui_to_dict(remote_ui_config)
+ camera_config['@proto'] = local_data['@proto']
+ camera_config['@enabled'] = local_data['@enabled']
- camera_config.update(remote_data)
-
ui_config = self._camera_dict_to_ui(camera_config)
if camera_config['@proto'] == 'v4l2':
resolutions = v4l2ctl.list_resolutions(camera_config['videodevice'])
resolutions = [(str(w) + 'x' + str(h)) for (w, h) in resolutions]
ui_config['available_resolutions'] = resolutions
+
+ else:
+ ui_config['available_resolutions'] = remote_ui_config['available_resolutions']
self.finish_json(ui_config)
def set_config(self, camera_id):
try:
- data = json.loads(self.request.body)
+ ui_config = json.loads(self.request.body)
except Exception as e:
logging.error('could not decode json: %(msg)s' % {'msg': unicode(e)})
raise
- restart = bool(data.get('last'))
- if restart and motionctl.running():
- motionctl.stop()
-
- try:
- if camera_id:
- logging.debug('setting config for camera %(id)s' % {'id': camera_id})
-
- camera_ids = config.get_camera_ids()
- if camera_id not in camera_ids:
- raise HTTPError(404, 'no such camera')
+ if camera_id:
+ logging.debug('setting config for camera %(id)s' % {'id': camera_id})
+
+ camera_ids = config.get_camera_ids()
+ if camera_id not in camera_ids:
+ raise HTTPError(404, 'no such camera')
+
+ camera_config = config.get_camera(camera_id)
+ if camera_config['@proto'] == 'v4l2':
+ camera_config = self._camera_ui_to_dict(ui_config)
+ camera_config['@proto'] = 'v4l2'
+ config.set_camera(camera_id, camera_config)
- camera_config = config.get_camera(camera_id)
- if camera_config['@proto'] == 'v4l2':
- data = self._camera_ui_to_dict(data)
- config.set_camera(camera_id, data)
-
- else:
- remote.set_config(
- camera_config.get('@host'),
- camera_config.get('@port'),
- camera_config.get('@username'),
- camera_config.get('@password'),
- camera_config.get('@remote_camera_id'),
- data)
-
else:
- logging.debug('setting main config')
-
- try:
- data = json.loads(self.request.body)
-
- except Exception as e:
- logging.error('could not decode json: %(msg)s' % {'msg': unicode(e)})
-
- raise
-
- data = self._main_ui_to_dict(data)
- config.set_main(data)
+ remote.set_config(
+ camera_config.get('@host'),
+ camera_config.get('@port'),
+ camera_config.get('@username'),
+ camera_config.get('@password'),
+ camera_config.get('@remote_camera_id'),
+ ui_config)
- except:
- raise
-
- finally:
- if restart:
- if config.has_enabled_cameras():
- motionctl.start()
+ else:
+ logging.debug('setting main config')
+
+ main_config = self._main_ui_to_dict(ui_config)
+ config.set_main(main_config)
+
+ if not ui_config.get('norestart'):
+ motionctl.restart()
def set_preview(self, camera_id):
try:
username = self.get_argument('username', None)
password = self.get_argument('password', None)
- if host: # remote
+ if host: # remote listing
try:
cameras = remote.list_cameras(host, port, username, password)
else:
cameras = []
for camera_id in config.get_camera_ids():
- data = config.get_camera(camera_id)
- if data['@proto'] == 'v4l2':
- data = self._camera_dict_to_ui(data)
+ camera_config = config.get_camera(camera_id)
+ if camera_config['@proto'] == 'v4l2':
+ name = camera_config['@name']
- else:
- data = {
- 'name': data['@name']
- }
+ else: # remote camera
+ try:
+ remote_camera_config = remote.get_config(
+ camera_config.get('@host'),
+ camera_config.get('@port'),
+ camera_config.get('@username'),
+ camera_config.get('@password'),
+ camera_config.get('@remote_camera_id'))
+
+ except:
+ continue
- data['id'] = camera_id
- cameras.append(data)
+ name = remote_camera_config['name']
+
+ cameras.append({'name': name, 'id': camera_id})
self.finish_json({'cameras': cameras})
raise
- camera_id, data = config.add_camera(device_details)
+ proto = device_details['proto']
+ if proto == 'v4l2':
+ # find a suitable resolution
+ for (w, h) in v4l2ctl.list_resolutions(device_details['device']):
+ if w > 300:
+ device_details['width'] = w
+ device_details['height'] = h
+ break
+
+ camera_id, camera_config = config.add_camera(device_details)
+
+ if proto == 'v4l2':
+ motionctl.restart()
+
+ else:
+ try:
+ remote_ui_config = remote.get_config(
+ device_details.get('host'),
+ device_details.get('port'),
+ device_details.get('username'),
+ device_details.get('password'),
+ device_details.get('remote_camera_id'))
+
+ except Exception as e:
+ return self.finish_json({'error': unicode(e)})
+
+ local_data = camera_config
+ camera_config = self._camera_ui_to_dict(remote_ui_config)
+ camera_config['@enabled'] = local_data['@enabled']
+ camera_config['@proto'] = local_data['@proto']
- data['@id'] = camera_id
+ camera_config['@id'] = camera_id
- if motionctl.running() and data['@proto'] == 'v4l2':
- motionctl.stop()
+ ui_config = self._camera_dict_to_ui(camera_config)
- if config.has_enabled_cameras() and data['@proto'] == 'v4l2':
- motionctl.start()
-
- try:
- remote_data = remote.get_config(
- device_details.get('host'),
- device_details.get('port'),
- device_details.get('username'),
- device_details.get('password'),
- device_details.get('remote_camera_id'))
+ if camera_config['@proto'] == 'v4l2':
+ resolutions = v4l2ctl.list_resolutions(camera_config['videodevice'])
+ resolutions = [(str(w) + 'x' + str(h)) for (w, h) in resolutions]
+ ui_config['available_resolutions'] = resolutions
- except Exception as e:
- return self.finish_json({'error': unicode(e)})
-
- remote_data = self._camera_ui_to_dict(remote_data)
- remote_data.update(data)
+ else:
+ ui_config['available_resolutions'] = remote_ui_config['available_resolutions']
- self.finish_json(self._camera_dict_to_ui(remote_data))
+ self.finish_json(ui_config)
def rem_camera(self, camera_id):
logging.debug('removing camera %(id)s' % {'id': camera_id})
local = config.get_camera(camera_id).get('@proto') == 'v4l2'
config.rem_camera(camera_id)
- if motionctl.running() and local:
- motionctl.stop()
-
- if config.has_enabled_cameras() and local:
- motionctl.start()
+ if local:
+ motionctl.restart()
def _main_ui_to_dict(self, ui):
return {