From 68c1d8f443421ca0fdc7dbd7562ff0d4cf5aa4ac Mon Sep 17 00:00:00 2001 From: lalpert Date: Sun, 20 Feb 2011 18:05:59 -0500 Subject: Added C5Sign-Leah to make rain --- config/C5Sign-Leah.xml | 301 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 config/C5Sign-Leah.xml diff --git a/config/C5Sign-Leah.xml b/config/C5Sign-Leah.xml new file mode 100644 index 0000000..dc7305e --- /dev/null +++ b/config/C5Sign-Leah.xml @@ -0,0 +1,301 @@ + + + + + gaussmap + + + + layouts/C5SignLayout.xml + + + + pixelmappers.C5SignMapper + + simplemap + 20 + + + + pixelmappers.GaussianMapper + + gaussmap + 4 + 0.1 + 1 + 1 + + + + pixelmappers.C5SignMapper + + c5signmapper + 20 + + + + + + renderers/C5Renderer.xml + + + + + inputs.ParametricLocationInput + + random_top + center + top + random.random() + 0 + 500 + + + + inputs.OSCInput + + osc + 1234 + 10 + + + + inputs.UDPInput + + udp + 3344 + 50 + + + + inputs.ContinuousCenterInput + + center + 700 + + + + + + + touchosc + + behaviors.TouchOSC + + + behaviors/PixelDecay.xml + + .001 + + + + + behaviors.XYMove + + xymove + 0 + 2 + + + + + behaviors.ModifyParam + + modifyY + Sensor + YStep + {val}+.5 + + + + + behaviors.BehaviorChain + + point_move + + xymove + modifyY + recursivedecay + + + + + behaviors.BehaviorChain + + falling_points + + random_top + + + colorchange + mover + slowdecay + + {'mover':'point_move'} + True + + + + + behaviors.BehaviorChain + + OSCTouchChase + + osc + + + touchosc + decay + + gaussmap + False + + + + behaviors/PixelDecay.xml + + + behaviors/SingleFrame.xml + + + behaviors.RestrictLocation + + xbounce + {val}*-1 + XStep + {x}<2 or {x}>48 + + + + behaviors.RestrictLocation + + ybounce + {val}*-1 + YStep + {y}<2 or {y}>24 + + + + behaviors.BehaviorChain + + movebounce + + xymove + ybounce + xbounce + longrecursivedecay + + + + + behaviors.TimeSwitch + + main + + centerleft + center + + {'scanningbars':10} + {'scanningbars':'centerleft'} + + False + + + + behaviors.DebugBehavior + + debug + 0 + + pygamekey + udp + + + + + behaviors.AllPixels + + square + 20 + + + + behaviors/LoopAndDie.xml + + + behaviors/LoopAndDie.xml + + + behaviors/RandomColor.xml + + + (0,0,255) + + + + + + behaviors.BehaviorChain + + runcolordecay + + colorchanger + mover + + decay + + {'mover':'movebounce'} + False + gaussmap + + + + behaviors.ResponseMover + + mover + + + + behaviors.ModifyParam + + incrinner + {val}+.6 + innercircleRadius + + + + behaviors.ModifyParam + + incrouter + {val}+.6 + outercircleRadius + + + + behaviors.BehaviorChain + + circle_expand + + innercircle + outercircle + incrinner + incrouter + recursivedecay + + + + + behaviors.BehaviorChain + + expandingcircles + + colorchange + mover + decay + + + {'mover':'circle_expand'} + + + + -- cgit v1.2.3 From 868c8206ac18e07f4e9d2eae32ec804344e31f2b Mon Sep 17 00:00:00 2001 From: Merritt Boyd Date: Sun, 20 Feb 2011 18:27:52 -0500 Subject: Websocket renderer and basic page server. --- config/C5Sign-websocket.xml | 9 +++ renderers/Websocket.xml | 10 ++++ renderers/WebsocketRenderer.py | 128 +++++++++++++++++++++++++++++++++++++++++ web/smootlight.html | 107 ++++++++++++++++++++++++++++++++++ 4 files changed, 254 insertions(+) create mode 100644 config/C5Sign-websocket.xml create mode 100644 renderers/Websocket.xml create mode 100644 renderers/WebsocketRenderer.py create mode 100644 web/smootlight.html diff --git a/config/C5Sign-websocket.xml b/config/C5Sign-websocket.xml new file mode 100644 index 0000000..549da07 --- /dev/null +++ b/config/C5Sign-websocket.xml @@ -0,0 +1,9 @@ + + config/C5Sign.xml + + + renderers/Websocket.xml + + + + diff --git a/renderers/Websocket.xml b/renderers/Websocket.xml new file mode 100644 index 0000000..6cf2e1f --- /dev/null +++ b/renderers/Websocket.xml @@ -0,0 +1,10 @@ + + renderers.WebsocketRenderer + + websocketrenderer + localhost + web/smootlight.html + 8081 + 8000 + + diff --git a/renderers/WebsocketRenderer.py b/renderers/WebsocketRenderer.py new file mode 100644 index 0000000..1a431fe --- /dev/null +++ b/renderers/WebsocketRenderer.py @@ -0,0 +1,128 @@ +from operationscore.Renderer import * +import util.TimeOps as timeops +import util.ComponentRegistry as compReg +import threading, socket, re, struct, hashlib, json, webbrowser + +class WebsocketRenderer(Renderer): + """Renders frame data over a websocket.""" + + def initRenderer(self): + self.hostname = self.argDict['Hostname'] + self.orig_port = int(self.argDict['SourcePort']) + self.port = int(self.argDict['Port']) + + self.clients = [] + self.clients_lock = threading.Lock() + + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.sock.bind(('', self.port)) + self.sock.listen(1) + + self.connection_thread = threading.Thread(target=self.handle_connections) + self.connection_thread.daemon = True + self.connection_thread.start() + + self.serve_thread = threading.Thread(target=self.serve_page) + self.serve_thread.daemon = True + self.serve_thread.start() + + webbrowser.open('http://'+self.hostname+':'+str(self.orig_port)) + + def serve_page(self): + page = open(self.argDict['Page']).read() + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind(('', self.orig_port)) + sock.listen(1) + + while True: + client, addr = sock.accept() + req = client.recv(4096) + client.send('HTTP/1.0 200 Found\r\n') + client.send('Content-type: text/html\r\n\r\n') + client.send(page) + client.close() + + def handle_connections(self): + while True: + client, addr = self.sock.accept() + print 'Accepted websocket connection from %s' % str(addr) + header = '' + while not re.search("\r?\n\r?\n.{8}", header): # Receive headers + 8 bytes data + header += client.recv(1024) + + key1 = re.search("Sec-WebSocket-Key1: (.*)$", header, re.M).group(1) + key2 = re.search("Sec-WebSocket-Key2: (.*)$", header, re.M).group(1) + + data = header[-8:] + + key1n = int(re.sub("[^\d]", '', key1)) + key1ns = key1.count(' ') + n1 = key1n // key1ns + + key2n = int(re.sub("[^\d]", '', key2)) + key2ns = key2.count(' ') + n2 = key2n // key2ns + + s = struct.pack("!II", n1, n2) + data + respkey = hashlib.md5(s).digest() + + if self.orig_port == 80: + origin = 'http://'+self.hostname + else: + origin = 'http://'+self.hostname+':'+str(self.orig_port) + + resp = \ + "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" + \ + "Upgrade: WebSocket\r\n" + \ + "Connection: Upgrade\r\n" + \ + "Sec-WebSocket-Origin:"+ origin + "\r\n" + \ + "Sec-WebSocket-Location: ws://"+self.hostname+":"+ \ + str(self.port)+"/\r\n" + \ + "Sec-WebSocket-Protocol: ledweb\r\n\r\n" + \ + respkey + "\r\n" + + client.send(resp) + self.clients_lock.acquire() + self.clients.append(client) + self.clients_lock.release() + + def render(self, lightSystem, currentTime=timeops.time()): + json_frame = [] + + for light in lightSystem: + loc = light.location + c = light.state(currentTime) + cs = 'rgb('+str(c[0])+','+str(c[1])+','+str(c[2])+')' + + json_frame.append((loc, cs)) + + size = compReg.getComponent('Screen').getSize() + + json_data = json.dumps(dict(status='ok', size=size, frame=json_frame)) + self.client_push(json_data) + + def client_push(self, data): + self.clients_lock.acquire() + dead_clients = [] + for i in range(len(self.clients)): + try: + self.clients[i].send("\x00") + self.clients[i].send(data) + self.clients[i].send("\xff") + except socket.error: + dead_clients.append(i) + + for i in range(len(dead_clients)): + self.close_sock(self.clients[dead_clients[i]-i]) + del self.clients[dead_clients[i]-i] + self.clients_lock.release() + + def close_sock(self, s): + try: + c.shutdown(socket.SHUT_RDWR) + c.close() + except Exception: + pass + \ No newline at end of file diff --git a/web/smootlight.html b/web/smootlight.html new file mode 100644 index 0000000..5b64a28 --- /dev/null +++ b/web/smootlight.html @@ -0,0 +1,107 @@ + + +SmootLight + + + + + +
+
+ + \ No newline at end of file -- cgit v1.2.3 From fd13edeeb2f277ee78af6d8ced1fba81a67ed1ba Mon Sep 17 00:00:00 2001 From: lalpert Date: Sun, 20 Feb 2011 18:32:10 -0500 Subject: Made C5Sign-pygame use Leah, added import random, mae rain faster --- config/C5Sign-Leah.xml | 6 +++--- config/C5Sign-pygame.xml | 2 +- inputs/ParametricLocationInput.py | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/config/C5Sign-Leah.xml b/config/C5Sign-Leah.xml index dc7305e..94fda27 100644 --- a/config/C5Sign-Leah.xml +++ b/config/C5Sign-Leah.xml @@ -48,7 +48,7 @@ top random.random() 0 - 500 + 100 @@ -94,7 +94,7 @@ xymove 0 - 2 + .5 @@ -104,7 +104,7 @@ modifyY Sensor YStep - {val}+.5 + {val}+.1 diff --git a/config/C5Sign-pygame.xml b/config/C5Sign-pygame.xml index 2040642..d08e14c 100644 --- a/config/C5Sign-pygame.xml +++ b/config/C5Sign-pygame.xml @@ -14,5 +14,5 @@ - config/C5Sign.xml + config/C5Sign-Leah.xml diff --git a/inputs/ParametricLocationInput.py b/inputs/ParametricLocationInput.py index e817a9d..7c7e968 100644 --- a/inputs/ParametricLocationInput.py +++ b/inputs/ParametricLocationInput.py @@ -1,6 +1,7 @@ import util.TimeOps as clock import util.ComponentRegistry as compReg import util.Strings as Strings +import random from operationscore.Input import * class ParametricLocationInput(Input): """Takes three arguments: xEquation, yEquation, and useClock where -- cgit v1.2.3