comparison light8/dmxserver.py @ 116:9ddea0c614ee

much prettier stdout, including a clock (so you can tell the server's running) much prettier stdout, including a clock (so you can tell the server's running) and channel updates only when the levels change, and throttled to every 100 updates even then.
author drewp
date Fri, 13 Jun 2003 06:15:28 +0000
parents afbdae5e1359
children 2c25a69c084d
comparison
equal deleted inserted replaced
115:f0e27aa8f0f5 116:9ddea0c614ee
1 #!/usr/bin/python
1 """ 2 """
2 3
3 this is the only process to talk to the dmx hardware. other clients 4 this is the only process to talk to the dmx hardware. other clients
4 can connect to this server and present dmx output, and this server 5 can connect to this server and present dmx output, and this server
5 will max ('pile-on') all the client requests. 6 will max ('pile-on') all the client requests.
14 a length-n list of 0..1 levels which will represent the channel 15 a length-n list of 0..1 levels which will represent the channel
15 values for the n first dmx channels. 16 values for the n first dmx channels.
16 17
17 server is port 8030; xmlrpc method is called outputlevels(pid,levellist). 18 server is port 8030; xmlrpc method is called outputlevels(pid,levellist).
18 19
20
21 todo:
22 save dmx on quit and restore on restart
23 if parport fails, run in dummy mode (and make an option for that too)
19 """ 24 """
20 25
21 from __future__ import division 26 from __future__ import division
22 from twisted.internet import reactor 27 from twisted.internet import reactor
23 from twisted.web import xmlrpc, server 28 from twisted.web import xmlrpc, server
24 29 import sys,time
25 import sys
26 sys.path.append("../light8")
27 from io import ParportDMX 30 from io import ParportDMX
28 31
29 class XMLRPCServe(xmlrpc.XMLRPC): 32 class XMLRPCServe(xmlrpc.XMLRPC):
30 def __init__(self): 33 def __init__(self):
34
35 xmlrpc.XMLRPC.__init__(self)
36
31 self.clientlevels={} # clientPID : list of levels 37 self.clientlevels={} # clientPID : list of levels
32 self.combinedlevels=[] # list of levels, after max'ing the clients 38 self.combinedlevels=[] # list of levels, after max'ing the clients
33 self.clientschanged=1 # have clients sent anything since the last send? 39 self.clientschanged=1 # have clients sent anything since the last send?
34 40
35 print "starting parport connection" 41 print "starting parport connection"
36 self.parportdmx=ParportDMX() 42 self.parportdmx=ParportDMX()
37 self.parportdmx.golive() 43 self.parportdmx.golive()
38 44
39 # start the loop 45 # start the loop
40 self.numupdates=0 46 self.num_unshown_updates=None
41 self.sendlevels() 47 self.sendlevels()
48
42 49
43 def sendlevels(self): 50 def sendlevels(self):
44 reactor.callLater(.02,self.sendlevels) 51 reactor.callLater(.02,self.sendlevels)
45 if self.clientschanged: 52 if self.clientschanged:
46 # recalc levels 53 # recalc levels
54 oldlevels=self.combinedlevels[:]
47 self.combinedlevels=[] 55 self.combinedlevels=[]
48 for chan in range(0,self.parportdmx.dimmers): 56 for chan in range(0,self.parportdmx.dimmers):
49 x=0 57 x=0
50 for clientlist in self.clientlevels.values(): 58 for clientlist in self.clientlevels.values():
51 if len(clientlist)>chan: 59 if len(clientlist)>chan:
52 x=max(x,clientlist[chan]) 60 x=max(x,clientlist[chan])
53 self.combinedlevels.append(x) 61 self.combinedlevels.append(x)
54 62
55 self.numupdates=self.numupdates+1 63 if self.num_unshown_updates is None or (self.combinedlevels!=oldlevels and
56 if (self.numupdates%200)==0: 64 self.num_unshown_updates>10):
57 print self.combinedlevels 65 self.num_unshown_updates=0
58 66 print "Levels:","".join(["% 2d "%x for x in self.combinedlevels])
67 else:
68 self.num_unshown_updates+=1
69
70 if (self.num_unshown_updates-1)%100==0:
71 sys.stdout.write("dmxserver up at %s \r"%time.strftime("%H:%M:%S"))
72 sys.stdout.flush()
59 # now send combinedlevels (they'll get divided by 100) 73 # now send combinedlevels (they'll get divided by 100)
60 self.parportdmx.sendlevels([l*100 for l in self.combinedlevels]) 74 if self.parportdmx:
75 self.parportdmx.sendlevels([l*100 for l in self.combinedlevels])
61 76
62 def xmlrpc_echo(self,x): 77 def xmlrpc_echo(self,x):
63 return x 78 return x
64 79
65 def xmlrpc_outputlevels(self,pid,levellist): 80 def xmlrpc_outputlevels(self,pid,levellist):
66 self.clientlevels[pid]=levellist 81 self.clientlevels[pid]=levellist
67 self.clientschanged=1 82 self.clientschanged=1
68 return "ok" 83 return "ok"
69 84
70 print "starting server on 8030" 85 print "starting xmlrpc server on port 8030"
71 reactor.listenTCP(8030,server.Site(XMLRPCServe())) 86 reactor.listenTCP(8030,server.Site(XMLRPCServe()))
72 reactor.run() 87 reactor.run()
73 88