diff --git a/light8/dmxserver.py b/light8/dmxserver.py --- a/light8/dmxserver.py +++ b/light8/dmxserver.py @@ -42,36 +42,53 @@ class XMLRPCServe(xmlrpc.XMLRPC): self.combinedlevels=[] # list of levels, after max'ing the clients self.clientschanged=1 # have clients sent anything since the last send? self.options=options + self.lastupdate=0 # time of last dmx send + self.laststatsprint=0 # time + + # desired seconds between sendlevels() calls + self.calldelay=1/options.updates_per_sec print "starting parport connection" self.parportdmx=ParportDMX() self.parportdmx.golive() - # start the loop - self.updatefreq=Updatefreq() + self.updatefreq=Updatefreq() # freq of actual dmx sends self.num_unshown_updates=None self.lastshownlevels=None + # start the loop self.sendlevels() + + # the other loop + self.purgeclients() - def purgeclients(self): """forget about any clients who haven't sent levels in a while - (5 seconds)""" + (5 seconds). this runs in a loop""" + + purge_age=10 # seconds + + reactor.callLater(1,self.purgeclients) + now=time.time() for cid,lastseen in self.lastseen.items(): - if lastseenself.laststatsprint+2: + self.laststatsprint=time.time() self.printstats() - - self.sendlevels_dmx() + if self.clientschanged or time.time()>self.lastupdate+1: + self.lastupdate=time.time() + self.sendlevels_dmx() + + self.clientschanged=0 # clear the flag + def calclevels(self): """combine all the known client levels into self.combinedlevels""" self.combinedlevels=[] @@ -101,7 +123,6 @@ class XMLRPCServe(xmlrpc.XMLRPC): x=max(x,cl) self.combinedlevels.append(x) - def printlevels(self): """write all the levels to stdout""" print "Levels:","".join(["% 2d "%(x*100) for @@ -110,7 +131,7 @@ class XMLRPCServe(xmlrpc.XMLRPC): def printstats(self): """print the clock, freq, etc, with a \r at the end""" - sys.stdout.write("dmxserver up at %s, [server %s] "% + sys.stdout.write("dmxserver up at %s, [polls %s] "% (time.strftime("%H:%M:%S"), str(self.updatefreq), )) @@ -119,7 +140,6 @@ class XMLRPCServe(xmlrpc.XMLRPC): sys.stdout.write("\r") sys.stdout.flush() - def sendlevels_dmx(self): """output self.combinedlevels to dmx, and keep the updates/sec stats""" # they'll get divided by 100 @@ -133,11 +153,13 @@ class XMLRPCServe(xmlrpc.XMLRPC): def xmlrpc_outputlevels(self,cid,levellist): """send a unique id for your client (name+pid maybe), then the variable-length dmx levellist (scaled 0..1)""" - self.clientlevels[cid]=levellist - self.clientschanged=1 - if cid not in self.lastseen: - print "hello new client %s" % cid - self.clientfreq[cid]=Updatefreq() + if levellist!=self.clientlevels.get(cid,[]): + self.clientlevels[cid]=levellist + self.clientschanged=1 + if cid not in self.lastseen: + print "hello new client %s" % cid + self.clientfreq[cid]=Updatefreq() + self.lastseen[cid]=time.time() self.clientfreq[cid].update() return "ok" @@ -146,8 +168,12 @@ parser=OptionParser() parser.add_option("-f","--fast-updates",action='store_true', help=('display all dmx output to stdout instead ' 'of the usual reduced output')) +parser.add_option("-r","--updates-per-sec",type='float',default=20, + help=('dmx output frequency')) (options,songfiles)=parser.parse_args() +print options + print "starting xmlrpc server on port 8030" reactor.listenTCP(8030,server.Site(XMLRPCServe(options))) reactor.run()