From fdeb37147a51059f33d6f605a6c16a711d076ca0 Mon Sep 17 00:00:00 2001 From: Calin Crisan Date: Sat, 5 Oct 2013 18:00:53 +0300 Subject: [PATCH] various improvements --- doc/todo.txt | 3 ++- src/config.py | 33 ++++++++++++++++++---------- src/handlers.py | 24 +++++++++++++++++++- static/js/main.js | 56 +++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 98 insertions(+), 18 deletions(-) diff --git a/doc/todo.txt b/doc/todo.txt index 3b57167..7c4343b 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -20,4 +20,5 @@ -> add a previewer for movies -> add a previewer for snapshots -> add a motioneye.svg icon --> other todos \ No newline at end of file +-> other todos +-> add a messaging mechanism diff --git a/src/config.py b/src/config.py index 52d1028..ad7921e 100644 --- a/src/config.py +++ b/src/config.py @@ -7,6 +7,7 @@ import re from collections import OrderedDict import settings +import v4l2ctl _CAMERA_CONFIG_FILE_NAME = 'thread-%(id)s.conf' @@ -268,8 +269,16 @@ def add_camera(device): data = OrderedDict() data['@name'] = 'Camera' + str(camera_id) data['@proto'] = proto + data['@enabled'] = True data['videodevice'] = device + # find a suitable resolution + for (w, h) in v4l2ctl.list_resolutions(device): + if w > 300: + data['width'] = w + data['height'] = h + break + # write the configuration to file set_camera(camera_id, data) @@ -473,14 +482,14 @@ def _set_default_motion_camera(data): data.setdefault('@proto', 'v4l2') data.setdefault('videodevice', '') data.setdefault('lightswitch', 0) - data.setdefault('auto_brightness', False) - data.setdefault('brightness', 0) - data.setdefault('contrast', 0) - data.setdefault('saturation', 0) - data.setdefault('hue', 0) + data.setdefault('auto_brightness', True) + data.setdefault('brightness', 127) + data.setdefault('contrast', 127) + data.setdefault('saturation', 127) + data.setdefault('hue', 127) data.setdefault('width', 352) data.setdefault('height', 288) - data.setdefault('framerate', 1) + data.setdefault('framerate', 5) data.setdefault('rotate', 0) data.setdefault('@storage_device', 'local-disk') @@ -492,12 +501,12 @@ def _set_default_motion_camera(data): data.setdefault('webcam_localhost', False) data.setdefault('webcam_port', 8080) - data.setdefault('webcam_maxrate', 1) + data.setdefault('webcam_maxrate', 5) data.setdefault('webcam_quality', 75) data.setdefault('webcam_motion', False) - data.setdefault('text_left', '') - data.setdefault('text_right', '') + data.setdefault('text_left', data['@name']) + data.setdefault('text_right', '%Y-%m-%d\\n%T') data.setdefault('text_double', False) data.setdefault('text_changes', False) @@ -507,8 +516,8 @@ def _set_default_motion_camera(data): data.setdefault('noise_level', 32) data.setdefault('gap', 60) - data.setdefault('pre_capture', 0) - data.setdefault('post_capture', 0) + data.setdefault('pre_capture', 5) + data.setdefault('post_capture', 5) data.setdefault('output_all', False) data.setdefault('output_normal', False) @@ -520,7 +529,7 @@ def _set_default_motion_camera(data): data.setdefault('motion_movies', False) data.setdefault('ffmpeg_variable_bitrate', 14) - data.setdefault('movie_filename', '') + data.setdefault('movie_filename', '%Y-%m-%d-%H-%M-%S') data.setdefault('ffmpeg_cap_new', False) data.setdefault('@preserve_movies', 0) diff --git a/src/handlers.py b/src/handlers.py index abc589e..117154a 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -217,14 +217,27 @@ class ConfigHandler(BaseHandler): camera_id, data = config.add_camera(device) data['@id'] = camera_id + data['@enabled'] = True - self.finish_json(data) + if motionctl.running(): + motionctl.stop() + + if config.has_enabled_cameras(): + motionctl.start() + + self.finish_json(self._camera_dict_to_ui(data)) def rem_camera(self, camera_id): logging.debug('removing camera %(id)s' % {'id': camera_id}) config.rem_camera(camera_id) + if motionctl.running(): + motionctl.stop() + + if config.has_enabled_cameras(): + motionctl.start() + def _main_ui_to_dict(self, ui): return { '@enabled': ui.get('enabled', True), @@ -523,6 +536,11 @@ class ConfigHandler(BaseHandler): class SnapshotHandler(BaseHandler): def get(self, camera_id, op, filename=None): + if camera_id is not None: + camera_id = int(camera_id) + if camera_id not in config.get_camera_ids(): + raise HTTPError(404, 'no such camera') + if op == 'current': self.current(camera_id) @@ -545,10 +563,14 @@ class SnapshotHandler(BaseHandler): def list(self, camera_id): logging.debug('listing snapshots for camera %(id)s' % {'id': camera_id}) + + # TODO implement me def download(self, camera_id, filename): logging.debug('downloading snapshot %(filename)s of camera %(id)s' % { 'filename': filename, 'id': camera_id}) + + # TODO implement me class MovieHandler(BaseHandler): diff --git a/static/js/main.js b/static/js/main.js index 0f39a61..d1e6416 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -217,7 +217,8 @@ function initUI() { else { $('#videoDeviceSelect')[0].selectedIndex = -1; } - $('#videoDeviceSelect').change(); + + updateConfigUi(); } else { fetchCurrentCameraConfig(); @@ -252,6 +253,25 @@ function initUI() { /* whenever the window is resized, * if a modal dialog is visible, it should be repositioned */ $(window).resize(updateModalDialogPosition); + + /* remove camera button */ + $('div.button.rem-camera-button').click(function () { + var cameraId = $('#videoDeviceSelect').val(); + if (cameraId == null || cameraId === 'add') { + runAlertDialog('No camera to remove!'); + return; + } + + var deviceName = $('#videoDeviceSelect').find('option[value=' + cameraId + ']').text(); + + runConfirmDialog('Remove device ' + deviceName + '?', function () { + showProgress(); + ajax('POST', '/config/' + cameraId + '/rem/', null, function () { + hideApply(); + fetchCurrentConfig(); + }); + }); + }); } @@ -300,6 +320,11 @@ function updateConfigUi() { objs.not($('#motionEyeSwitch').parents('div').get(0)).each(markHide); } + if ($('#videoDeviceSelect').find('option').length < 2) { /* no camera configured */ + $('#videoDeviceSwitch').parent().each(markHide); + $('#videoDeviceSwitch').parent().nextAll('div.settings-section-title, table.settings').each(markHide); + } + /* advanced settings */ var showAdvanced = $('#showAdvancedSwitch').get(0).checked; if (!showAdvanced) { @@ -747,15 +772,17 @@ function fetchCurrentConfig() { } videoDeviceSelect.append(''); - if (cameras.length > 1) { + if (cameras.length > 0) { videoDeviceSelect[0].selectedIndex = 0; fetchCurrentCameraConfig(); } else { videoDeviceSelect[0].selectedIndex = -1; + // TODO if admin, set a message saying that the user should add a camera } recreateCameraFrames(cameras); + updateConfigUi(); }); }); } @@ -815,7 +842,11 @@ function runAlertDialog(message) { runModalDialog({title: message, buttons: 'ok'}); } -function runAddCameraDialog(devices) { +function runConfirmDialog(message, onYes) { + runModalDialog({title: message, buttons: 'yesno', onYes: onYes}); +} + +function runAddCameraDialog() { var content = $('' + '' + @@ -891,7 +922,23 @@ function runAddCameraDialog(devices) { buttons: 'okcancel', content: content, onOk: function () { + var fullDevice; + if (deviceSelect.val() == 'remote') { + fullDevice = 'http://' + usernameEntry.val() + ':' + passwordEntry.val() + '@' + hostEntry + ':' + portEntry; + } + else { + fullDevice = 'v4l2://' + deviceSelect.val(); + } + + showProgress(); + ajax('POST', '/config/add/?device=' + fullDevice, null, function (data) { + hideApply(); + var addCameraOption = $('#videoDeviceSelect').find('option[value=add]'); + addCameraOption.before(''); + $('#videoDeviceSelect').val(data.id).change(); + recreateCameraFrames(); + }); } }); }); @@ -1035,12 +1082,13 @@ function doCloseCamera(cameraId) { showProgress(); ajax('GET', '/config/' + cameraId + '/get/', null, function (data) { data['enabled'] = false; + data['restart'] = true; ajax('POST', '/config/' + cameraId + '/set/', data, function () { endProgress(); /* if the current camera in the settings panel is the closed camera, * we refresh its settings and update the UI */ - if (isSettingsOpen() && ($('#videoDeviceSelect').val() === '' + cameraId)) { + if ($('#videoDeviceSelect').val() === '' + cameraId) { fetchCurrentCameraConfig(); } }); -- 2.39.5