Changeset - f2f73a2171e6
[Not reviewed]
default
0 1 0
drewp - 22 years ago 2003-06-14 14:59:09

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)
1 file changed with 45 insertions and 19 deletions:
0 comments (0 inline, 0 general)
light8/dmxserver.py
Show inline comments
 
@@ -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 lastseen<now-5:
 
                print "forgetting client %s (no activity for 5sec)" % cid
 
            if lastseen<now-purge_age:
 
                print ("forgetting client %s (no activity for %s sec)" %
 
                       (cid,purge_age))
 
                del self.clientlevels[cid]
 
                del self.lastseen[cid]
 
                del self.clientfreq[cid]
 
        
 
    def sendlevels(self):
 
        reactor.callLater(1/20,self.sendlevels)
 
        
 
        """sends to dmx if levels have changed, or if we havent sent
 
        in a while"""
 

	
 
        reactor.callLater(self.calldelay,self.sendlevels)
 

	
 
        if self.clientschanged:
 
            # recalc levels
 

	
 
            self.purgeclients()
 
            self.calclevels()
 
         
 
            if (self.num_unshown_updates is None or # first time
 
@@ -84,11 +101,16 @@ class XMLRPCServe(xmlrpc.XMLRPC):
 
            else:
 
                self.num_unshown_updates+=1
 

	
 
        if (self.num_unshown_updates-1)%50==0:
 
        if time.time()>self.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()
0 comments (0 inline, 0 general)