From: Calin Crisan Date: Sun, 29 Sep 2013 09:48:00 +0000 (+0300) Subject: added motionctl code X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=2bebde8cfd2fff3eff76848aa49f3f184dd3053d;p=motioneye-debian added motionctl code --- diff --git a/.gitignore b/.gitignore index 704a437..9f3f340 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.log *.pyc *.bak +*.pid .project .pydevproject *.conf diff --git a/motioneye.py b/motioneye.py index f3414f2..f62efd4 100644 --- a/motioneye.py +++ b/motioneye.py @@ -25,6 +25,7 @@ def _configure_signals(): signal.signal(signal.SIGINT, bye_handler) signal.signal(signal.SIGTERM, bye_handler) + signal.signal(signal.SIGCHLD, signal.SIG_IGN) def _configure_logging(): @@ -40,9 +41,9 @@ def _start_server(): if __name__ == '__main__': - _configure_signals() - _configure_logging() - _start_server() +# _configure_signals() +# _configure_logging() +# _start_server() # import config # main_config = config.get_main() @@ -52,3 +53,6 @@ if __name__ == '__main__': # #config.set_camera(1, data) # config.rem_camera(1) + import motionctl + + motionctl.start() diff --git a/settings.py b/settings.py index 6eeb272..4e348a6 100644 --- a/settings.py +++ b/settings.py @@ -5,8 +5,10 @@ import sys PROJECT_PATH = os.path.dirname(sys.argv[0]) -CONF_PATH = os.path.join(PROJECT_PATH, 'conf') -RUN_PATH = PROJECT_PATH +#CONF_PATH = os.path.join(PROJECT_PATH, 'conf') +CONF_PATH = '/media/data/projects/motioneye/conf/' +RUN_PATH = '/media/data/projects/motioneye/' +#RUN_PATH = PROJECT_PATH DEBUG = True LOG_LEVEL = logging.DEBUG diff --git a/src/motionctl.py b/src/motionctl.py index 0ee23ec..507f584 100644 --- a/src/motionctl.py +++ b/src/motionctl.py @@ -1,19 +1,25 @@ +import errno import os.path +import signal import subprocess +import time import settings def find_program(): try: - return subprocess.check_output('which motion', shell=True) + return subprocess.check_output('which motion', shell=True).strip() except subprocess.CalledProcessError: # not found return None def start(): + if running(): + raise Exception('motion is already running') + program = find_program() if not program: raise Exception('motion executable could not be found') @@ -23,18 +29,84 @@ def start(): motion_pid_path = os.path.join(settings.RUN_PATH, 'motion.pid') args = [program, - '-c', motion_config_path, - '-n', - '-p', motion_pid_path] - + '-c', motion_config_path, + '-n'] + log_file = open(motion_log_path, 'w') - subprocess.Popen(args, stdout=log_file, stderr=log_file) + process = subprocess.Popen(args, stdout=log_file, stderr=log_file, close_fds=True, + cwd=settings.RUN_PATH) + + # wait 2 seconds to see that the process has successfully started + for i in xrange(20): # @UnusedVariable + time.sleep(0.1) + exit_code = process.poll() + if exit_code is not None and exit_code != 0: + raise Exception('motion failed to start') + + pid = process.pid + + # write the pid to file + with open(motion_pid_path, 'w') as f: + f.write(str(pid) + '\n') def stop(): - pass - + if not running(): + raise Exception('motion is not running') + + pid = _get_pid() + if pid is not None: + try: + # send the TERM signal once + os.kill(pid, signal.SIGTERM) + + # wait 5 seconds for the process to exit + for i in xrange(50): # @UnusedVariable + time.sleep(0.1) + os.kill(pid, 0) + + # send the KILL signal once + os.kill(pid, signal.SIGKILL) + + # wait 2 seconds for the process to exit + for i in xrange(20): # @UnusedVariable + time.sleep(0.1) + os.kill(pid, 0) + + # the process still did not exit + raise Exception('could not terminate the motion process') + + except OSError as e: + if e.errno != errno.ESRCH: + raise + def running(): - pass + pid = _get_pid() + if pid is None: + return False + + try: + os.kill(pid, 0) + + # the process is running + return True + + except OSError as e: + if e.errno != errno.ESRCH: + raise + + return False + + +def _get_pid(): + motion_pid_path = os.path.join(settings.RUN_PATH, 'motion.pid') + + # read the pid from file + try: + with open(motion_pid_path, 'r') as f: + return int(f.readline().strip()) + + except IOError, ValueError: + return None