diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2d6f36 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +*.py[cod] + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg +lib +lib64 + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +nosetests.xml + +# Translations +*.mo + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject diff --git a/osc2cam/osc2cam/main.py b/osc2cam/osc2cam/main.py index 3eef933..6ae3454 100644 --- a/osc2cam/osc2cam/main.py +++ b/osc2cam/osc2cam/main.py @@ -2,129 +2,155 @@ # -*- coding: utf-8 -*- import argparse -import ConfigParser -import os.path -import random import re -import select -import serial -import socket import sys -import time -import struct -import datetime +import httplib from chaosc.simpleOSCServer import SimpleOSCServer -try: - from chaosc.c_osc_lib import * -except ImportError as e: - print(e) - from chaosc.osc_lib import * - - class OSC2CamServer(SimpleOSCServer): """OSC filtering/transcoding middleware """ def __init__(self, args, cams): - """ctor for filter server + """ctor for a osc udp 2 ptz ip cam bridge - starts the server, loads scene filters and transcoders and chooses - the request handler, which is one of - forward only, forward and dump, dump only. + starts the server, creates http connections to specified cams - :param result: return value of argparse.parse_args - :type result: namespace object + :param args: return value of argparse.parse_args + :type args: namespace object + + :param cams: return value of argparse.parse_args + :type cams: list of 2 item tuples """ - d = datetime.now().strftime("%x %X") - print "%s: starting up chaosc_filter-%s..." % (d, chaosc._version.__version__) - print "%s: binding to %s:%r" % (d, "0.0.0.0", args.own_port) - SimpleOSCServer.__init__(self, ("0.0.0.0", args.own_port)) + SimpleOSCServer.__init__(self, ("", args.port)) - self.set_url = "http:///cgi-bin/admin/" - self.get_url = "http:///cgi-bin/view/" - self.ptz_ctl_url = "http://myserver/cgi-bin/operator/ptzset" - self.ptz_config_url = "http://myserver/cgi-bin/operator/ptzconfig" - self.connections = [socket.create_connection(cam) for cam in cams] + self.set_url = "/cgi-bin/admin/" + self.get_url = "/cgi-bin/view/" + self.ptz_ctl_url = "/cgi-bin/operator/ptzset" + self.ptz_config_url = "/cgi-bin/operator/ptzconfig" + self.connections = [httplib.HTTPConnection(host, port) for host, port in cams] self.resetCams() def resetCams(self): + """ configures each ip cam""" + for connection in self.connections: - connection.sendall("%sparam?action=update&Image.I0.MJPEG.Resolution=640x480" % self.set_url) - connection.sendall("%sparam?action=update&Image.I0.Appearance.Compression=75" % self.set_url) - connection.sendall("%sparam?action=update&Image.I0.MJPEG.FPS=25" % self.set_url) + connection.request("GET", "%sparam?action=update&Image.I0.MJPEG.Resolution=640x480" % self.set_url) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason + connection.request("GET", "%sparam?action=update&Image.I0.Appearance.Compression=75" % self.set_url) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason + connection.request("GET", "%sparam?action=update&Image.I0.MJPEG.FPS=25" % self.set_url) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason - def moveCam(self, cam_id, args): + def move_cam(self, cam_id, args): + """ moves given ip cam""" + direction = args[0] if direction in ("home", "up", "down", "left", "right", "upleft", "upright", "downleft", "downright", "repeat", "stop"): - self.connections[cam_id].sendall("%s?move=%s" % (self.ptz_ctl_url, direction)) + connection = self.connections[cam_id] + connection.request("GET", "%s?move=%s" % (self.ptz_ctl_url, direction)) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason - def useCamPreset(self, cam_id, args): + def use_cam_preset(self, cam_id, args): + """ says given ip cam to use a predefined position preset""" + presetno = args[0] - self.connections[cam_id].sendall("%s?gotoserverpresetno=%d" % (self.ptz_ctl_url, presetno)) + connection = self.connections[cam_id] + connection.request("GET", "%s?gotoserverpresetno=%d" % (self.ptz_ctl_url, presetno)) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason - def setCamPreset(self, cam_id, args): + def set_cam_preset(self, cam_id, args): + """ saves the actual position of given ip cam to a preset""" + presetno = args[0] - self.connections[cam_id].sendall("%s?setserverpresetno=%d&home=yes" % (self.ptz_config_url, presetno)) + connection = self.connections[cam_id] + connection.request("GET", "%s?setserverpresetno=%d&home=yes" % (self.ptz_config_url, presetno)) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason - def zoomCam(self, cam_id, args): + def zoom_cam(self, cam_id, args): + """ tells given ip cam to zoom in or out""" + direction = None arg = args[0] if arg == "out": direction = 0 elif arg == "in": direction = 1 - self.connections[cam_id].sendall("%s?%szoom=%s" % (self.ptz_ctl_url, direction)) + connection = self.connections[cam_id] + connection.request("GET", "%s?zoom=%s" % (self.ptz_ctl_url, direction)) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason - def toggleNightView(self, cam_id, args): + def toggle_night_view(self, cam_id, args): + """ toggles the night view function of given ip cam""" + arg = args[0] state = None if arg == "on": state = "auto" else: state = "off" - connection.sendall("%sparam?action=update&Image.I0.Appearance.NightMode=%s" % (self.set_url, state)) + + connection = self.connections[cam_id] + connection.request("GET", "%sparam?action=update&Image.I0.Appearance.NightMode=%s" % (self.set_url, state)) + conn_result = connection.getresponse() + print conn_result.status, conn_result.reason def dispatchMessage(self, osc_address, typetags, args, packet, client_address): - m = re.compile("/(.*?)/(\d+)/(.*?)") - res = m.match(osc_address) + """ dispatches parsed osc messages to the ip cam command methods""" + rule = re.compile("^/(.*?)/(\d+)/(.*?)$") + res = rule.match(osc_address) if res: - dust, cam_id, command + _, cam_id, command = res.groups() + cam_id = int(cam_id) if command == "moveCam": - self.moveCam(cam_id, args) - elif osc_address == "/setCamPreset": - self.setCamPreset(cam_id, args) - elif osc_address == "/useCamPreset": - self.useCamPreset(cam_id, args) - elif osc_address == "zoomCam": - self.zoomCam(cam_id, args) - elif osc_address == "toggleNightView": - self.toggleNightView(cam_id, args) + self.move_cam(cam_id, args) + elif command == "setCamPreset": + self.set_cam_preset(cam_id, args) + elif command == "useCamPreset": + self.use_cam_preset(cam_id, args) + elif command == "zoomCam": + self.zoom_cam(cam_id, args) + elif command == "toggleNightView": + self.toggle_night_view(cam_id, args) def main(): - parser = argparse.ArgumentParser(prog='psychose_actor') - parser.add_argument('-o', "--own_host", required=True, - type=str, help='my host') - parser.add_argument('-r', "--own_port", required=True, + parser = argparse.ArgumentParser(prog='osc2cam') + parser.add_argument('-p', "--port", required=True, type=int, help='my port') args = parser.parse_args(sys.argv[1:]) cams = [ - "192.168.1.51", - "192.168.1.52", - "192.168.1.53" + ("192.168.1.51", args.port + 1), + ("192.168.1.52", args.port + 2), + ("192.168.1.53", args.port + 3), ] + cams = [ + ("localhost", args.port + 1), + ("localhost", args.port + 2), + ("localhost", args.port + 3), + ] + + server = OSC2CamServer(args, cams) + server.serve_forever() +