# HG changeset patch # User drewp # Date 2003-06-14 14:59:09 # Node ID f2f73a2171e6693e8aeb42d37151092ee4bf6e23 # Parent e7b531d10cf91cd757ae4f3fc10481fcad06b8d2 many adjustments to the loops and timing many adjustments to the loops and timing now sends the hardware updates only when clients change, but at least 1Hz new option to adjust the rate of the loop that considers sending changes (if the lights have changed) 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()