diff --git a/bin/dmxserver b/bin/dmxserver --- a/bin/dmxserver +++ b/bin/dmxserver @@ -34,6 +34,17 @@ from light9.io import ParportDMX, UsbDMX from light9.updatefreq import Updatefreq from light9 import networking +from txzmq import ZmqEndpoint, ZmqFactory, ZmqPullConnection, ZmqRequestTimeoutError +import json + +def startZmq(port, outputlevels): + zf = ZmqFactory() + e = ZmqEndpoint('bind', 'tcp://*:%s' % port) + s = ZmqPullConnection(zf, e) + def onPull(message): + msg = json.loads(message[0]) + outputlevels(msg['clientid'], msg['levellist']) + s.onPull = onPull class ReceiverApplication(object): """ @@ -248,6 +259,8 @@ print "starting xmlrpc server on port %s xmlrpcServe = XMLRPCServe(options) reactor.listenTCP(port,server.Site(xmlrpcServe)) +startZmq(networking.dmxServerZmq.port, xmlrpcServe.xmlrpc_outputlevels) + oscApp = ReceiverApplication(9051, xmlrpcServe) reactor.run() diff --git a/light9/dmxclient.py b/light9/dmxclient.py --- a/light9/dmxclient.py +++ b/light9/dmxclient.py @@ -5,6 +5,10 @@ dmxclient.outputlevels(..) client id is formed from sys.argv[0] and the PID. """ import xmlrpclib, os, sys, socket, time, logging +from twisted.internet import defer +from txzmq import ZmqEndpoint, ZmqFactory, ZmqPushConnection +import json + from light9 import networking _dmx=None log = logging.getLogger('dmxclient') @@ -13,6 +17,15 @@ procname = os.path.basename(sys.argv[0]) procname = procname.replace('.py', '') _id = "%s-%s-%s" % (procname, socket.gethostname(), os.getpid()) +class TwistedZmqClient(object): + def __init__(self, service): + zf = ZmqFactory() + e = ZmqEndpoint('connect', 'tcp://%s:%s' % (service.host, service.port)) + self.conn = ZmqPushConnection(zf, e) + + def send(self, clientid, levellist): + self.conn.push(json.dumps({'clientid': clientid, 'levellist': levellist})) + def outputlevels(levellist,twisted=0,clientid=_id): """present a list of dmx channel levels, each scaled from 0..1. list can be any length- it will apply to the first len() dmx @@ -28,8 +41,7 @@ def outputlevels(levellist,twisted=0,cli if not twisted: _dmx = xmlrpclib.Server(url) else: - from twisted.web.xmlrpc import Proxy - _dmx = Proxy(url) + _dmx = TwistedZmqClient(networking.dmxServerZmq) if not twisted: try: @@ -41,14 +53,9 @@ def outputlevels(levellist,twisted=0,cli log.error("outputlevels had xml fault: %s" % e) time.sleep(1) else: - def err(error): - log.error("dmx server error talking to %s: %s", - networking.dmxServer.url, error.getErrorMessage()) - time.sleep(1) - d = _dmx.callRemote('outputlevels', clientid, levellist) - d.addErrback(err) - return d - + _dmx.send(clientid, levellist) + return defer.succeed(None) + dummy = os.getenv('DMXDUMMY') if dummy: print "dmxclient: DMX is in dummy mode." diff --git a/light9/effecteval/effectloop.py b/light9/effecteval/effectloop.py --- a/light9/effecteval/effectloop.py +++ b/light9/effecteval/effectloop.py @@ -98,7 +98,7 @@ class EffectLoop(object): if self.currentPlaying: t += max(0, now - self.songTimeFetch) return t - + @inlineCallbacks def sendLevels(self): t1 = time.time() diff --git a/light9/networking.py b/light9/networking.py --- a/light9/networking.py +++ b/light9/networking.py @@ -37,6 +37,7 @@ class ServiceAddress(object): curveCalc = ServiceAddress(L9['curveCalc']) dmxServer = ServiceAddress(L9['dmxServer']) +dmxServerZmq = ServiceAddress(L9['dmxServerZmq']) effectEval = ServiceAddress(L9['effectEval']) keyboardComposer = ServiceAddress(L9['keyboardComposer']) musicPlayer = ServiceAddress(L9['musicPlayer']) diff --git a/makefile b/makefile --- a/makefile +++ b/makefile @@ -51,7 +51,7 @@ gst_packages: sudo aptitude install python-gi gir1.2-gst-plugins-base-1.0 libgirepository-1.0-1 gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-pulseaudio packages: - sudo aptitude install coffeescript freemind normalize-audio audacity python-pygoocanvas python-pygame gir1.2-goocanvas-2.0-9 libffi-dev tix + sudo aptitude install coffeescript freemind normalize-audio audacity python-pygoocanvas python-pygame gir1.2-goocanvas-2.0-9 libffi-dev tix libzmq3 raspberry_pi_virtualenv: mkdir -p env_pi diff --git a/pydeps b/pydeps --- a/pydeps +++ b/pydeps @@ -26,3 +26,5 @@ pyserial==2.7 scales==1.0.9 statprof==0.1.2 +txzmq==0.7.4 + diff --git a/show/dance2014/networking.n3 b/show/dance2014/networking.n3 --- a/show/dance2014/networking.n3 +++ b/show/dance2014/networking.n3 @@ -7,6 +7,7 @@ sh:netHome :patchReceiverUpdateHost "localhost"; :curveCalc ; :dmxServer ; + :dmxServerZmq ; :effectEval ; :keyboardComposer ; :musicPlayer ;