Changeset - d5e99fee786d
[Not reviewed]
default
0 7 0
Drew Perttula - 10 years ago 2015-06-08 06:53:12
drewp@bigasterisk.com
twisted uses zmq (not xmlrpc) to send levels to dmxserver
Ignore-this: 78d627e1ff8c8e83b50ae099d373b8c1
6 files changed with 34 insertions and 10 deletions:
0 comments (0 inline, 0 general)
bin/dmxserver
Show inline comments
 
@@ -31,12 +31,23 @@ import run_local
 
import txosc.dispatch, txosc.async
 
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):
 
    """
 
    receive UDP OSC messages. address is /dmx/1 for dmx channel 1,
 
    arguments are 0-1 floats for that channel and any number of
 
    following channels.
 
@@ -245,10 +256,12 @@ if options.dummy:
 

	
 
port = networking.dmxServer.port
 
print "starting xmlrpc server on port %s" % port
 
xmlrpcServe = XMLRPCServe(options)
 
reactor.listenTCP(port,server.Site(xmlrpcServe))
 

	
 
startZmq(networking.dmxServerZmq.port, xmlrpcServe.xmlrpc_outputlevels)
 
                  
 
oscApp = ReceiverApplication(9051, xmlrpcServe)
 

	
 
reactor.run()
 

	
light9/dmxclient.py
Show inline comments
 
@@ -2,20 +2,33 @@
 
server. sending levels is now a simple call to
 
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')
 

	
 
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
 
    channels.
 

	
 
    if the server is not found, outputlevels will block for a
 
@@ -25,32 +38,26 @@ def outputlevels(levellist,twisted=0,cli
 

	
 
    if _dmx is None:
 
        url = networking.dmxServer.url
 
        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:
 
            _dmx.outputlevels(clientid, levellist)
 
        except socket.error, e:
 
            log.error("dmx server error %s, waiting" % e)
 
            time.sleep(1)
 
        except xmlrpclib.Fault,e:
 
            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."
 
    def outputlevels(*args, **kw):
 
        pass
light9/networking.py
Show inline comments
 
@@ -34,12 +34,13 @@ class ServiceAddress(object):
 
    
 
    def path(self, more):
 
        return self.url + str(more)
 

	
 
curveCalc = ServiceAddress(L9['curveCalc'])
 
dmxServer = ServiceAddress(L9['dmxServer'])
 
dmxServerZmq = ServiceAddress(L9['dmxServerZmq'])
 
effectEval = ServiceAddress(L9['effectEval'])
 
keyboardComposer = ServiceAddress(L9['keyboardComposer'])
 
musicPlayer = ServiceAddress(L9['musicPlayer'])
 
oscDmxServer = ServiceAddress(L9['oscDmxServer'])
 
picamserve = ServiceAddress(L9['picamserve'])
 
rdfdb = ServiceAddress(L9['rdfdb'])
makefile
Show inline comments
 
@@ -48,13 +48,13 @@ tkdnd_build:
 
bin/ascoltami2: gst_packages link_to_sys_packages
 

	
 
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
 
	virtualenv --system-site-packages env_pi
 

	
 
raspberry_pi_packages:
pydeps
Show inline comments
 
@@ -23,6 +23,8 @@ treq==0.2.1
 
mock==1.0.1
 
toposort==1.0
 
pyserial==2.7
 

	
 
scales==1.0.9
 
statprof==0.1.2
 
txzmq==0.7.4
 

	
show/dance2014/networking.n3
Show inline comments
 
@@ -4,12 +4,13 @@
 

	
 
show:dance2014 :networking sh:netHome .
 
sh:netHome
 
  :patchReceiverUpdateHost "localhost";
 
  :curveCalc        <http://dash:8060/>;
 
  :dmxServer        <http://dash:8030/>;
 
  :dmxServerZmq     <http://dash:8031/>;
 
  :effectEval       <http://dash:8070/>;
 
  :keyboardComposer <http://dash:8050/>;
 
  :musicPlayer      <http://dash:8040/>;
 
  :oscDmxServer     <udp://dash:9050/>;
 
  :picamserve       <http://10.2.0.3:8001/>;
 
  :rdfdb            <http://localhost:8051/>;
0 comments (0 inline, 0 general)