Merge branch 'master' of git+ssh://source.hacker.lu/var/repo/projects/syndilights
Conflicts: frameserver/defines.hmaster
commit
bffff1a33a
|
@ -0,0 +1,205 @@
|
|||
# Client program "cellular"
|
||||
|
||||
from socket import *
|
||||
import sys, time
|
||||
from math import *
|
||||
from random import randint
|
||||
from copy import deepcopy
|
||||
|
||||
# Set the socket parameters
|
||||
local_port = 5001
|
||||
|
||||
# UDP webserver port to bypass frameserver for testing
|
||||
remote_port = 4422
|
||||
# port to frameserver
|
||||
#remote_port = 4321
|
||||
|
||||
# TODO: autodetect interface address for remote application
|
||||
outgoing_if = "127.0.0.1"
|
||||
remote_host = "127.0.0.1"
|
||||
|
||||
# udp is the default for DGRAM
|
||||
UDPSock = socket(AF_INET, SOCK_DGRAM)
|
||||
|
||||
# we MUST bind, otherwise python will choose a different port for each
|
||||
# connection
|
||||
UDPSock.bind((outgoing_if, local_port))
|
||||
|
||||
# we will not use connections so we can keep working even if the server
|
||||
# goes down or refuses connection
|
||||
#UDPSock.connect((remote_host, remote_port))
|
||||
|
||||
# this is our handshake, weak certification
|
||||
hash = "s2l\n<8<18 " # 10 bytes
|
||||
|
||||
# plus 2 bytes below
|
||||
alpha = chr(255)
|
||||
z_buffer = chr(1) + "\n"
|
||||
|
||||
# frame of 2 dimensional array holding data [r,g,b,a]
|
||||
wdata = []
|
||||
# segment display, each segment holds 8 values of [r,g,b,a]
|
||||
sdata = []
|
||||
|
||||
# setup window area, channels and segments
|
||||
segwindows = 12
|
||||
segments = 8 # number of segments in a window (7 + period/dot/point)
|
||||
width = 12
|
||||
height = 8
|
||||
segchannels = 4 # RGBA
|
||||
|
||||
# timing elements
|
||||
# timer will hold the elapsed time in seconds
|
||||
timer = 0
|
||||
sleeptime = 100 # milliseconds
|
||||
frequency = 1000 / sleeptime # frames per second
|
||||
|
||||
# function resets map to zero
|
||||
def set_wdata(r, g, b):
|
||||
for x in xrange(width):
|
||||
wdata.append([0] * height)
|
||||
for y in xrange(height):
|
||||
# create an SRGBA array at each location
|
||||
# where S is the state, and RGBA is colour
|
||||
wdata[x][y] = [0, r, g, b, 1]
|
||||
|
||||
# function resets segment display
|
||||
def set_sdata(r, g, b):
|
||||
global sdata
|
||||
sdata = []
|
||||
|
||||
for s in xrange(segwindows):
|
||||
sdata.append([0] * segments)
|
||||
for seg in xrange(segments):
|
||||
# create an SRGBA array at each location
|
||||
# where S is the state, and RGBA is colour
|
||||
sdata[s][seg] = [0, r, g, b, 1]
|
||||
|
||||
# convert [r,g,b,a] to chr string
|
||||
def i2c(rgba):
|
||||
# ignore rgba[0] because it is the state
|
||||
return chr(int(rgba[1])) + chr(int(rgba[2])) + chr(int(rgba[3])) + chr(int(rgba[4]))
|
||||
|
||||
# function sends wdata and sdata state to server
|
||||
def send_update():
|
||||
#zero out the data buffer
|
||||
data = hash
|
||||
data = data + z_buffer
|
||||
|
||||
# write frame data
|
||||
for y in xrange(height):
|
||||
for x in xrange(width):
|
||||
data = data + i2c( wdata[x][y] )
|
||||
#print str(wdata[x][y]) + " ",
|
||||
#print "\n"
|
||||
data = data + "\n"
|
||||
|
||||
# write segment window displays
|
||||
for s in xrange(segwindows):
|
||||
for seg in xrange(segments):
|
||||
data = data + i2c( sdata[s][seg] )
|
||||
data = data + "\n"
|
||||
|
||||
# print data
|
||||
|
||||
# send the data packet to remote host
|
||||
UDPSock.sendto(data,(remote_host,remote_port))
|
||||
|
||||
# initialize map
|
||||
set_wdata(0,0,0)
|
||||
set_sdata(0,0,255)
|
||||
|
||||
# set start seed
|
||||
# get random location
|
||||
rx = randint(0, width - 1)
|
||||
ry = randint(0, height - 1)
|
||||
wdata[rx][ry] = [1,1,0,0,1]
|
||||
print "origin(" + str(rx) + "," + str(ry) + ")"
|
||||
|
||||
def has_active_neighb(x, y):
|
||||
# check the cell to the left
|
||||
if x > 0 and wdata[x - 1][y][0] > 0:
|
||||
return True
|
||||
# check the cell above
|
||||
if y > 0 and wdata[x][y - 1][0] > 0:
|
||||
return True
|
||||
# check the cell to the right
|
||||
if x < (width - 1) and wdata[x + 1][y][0] > 0:
|
||||
return True
|
||||
# check the cell below
|
||||
if y < (height - 1) and wdata[x][y + 1][0] > 0:
|
||||
return True
|
||||
|
||||
# main logic loop
|
||||
for t in range(60):
|
||||
|
||||
# push update to clients
|
||||
send_update()
|
||||
|
||||
# create CA buffer
|
||||
data_buffer = deepcopy(wdata)
|
||||
|
||||
for y in xrange(height):
|
||||
for x in xrange(width):
|
||||
# if cell is active, increase its rating/value
|
||||
if wdata[x][y][0] > 0:
|
||||
# change the state of the cell
|
||||
data_buffer[x][y][0] += 10
|
||||
|
||||
# assign stat to red colour
|
||||
data_buffer[x][y][1] = data_buffer[x][y][0]
|
||||
|
||||
# check we don't go too high
|
||||
if data_buffer[x][y][0] > 127:
|
||||
data_buffer[x][y][1] = 127
|
||||
# assign stat to green colour
|
||||
data_buffer[x][y][2] = data_buffer[x][y][0] - 127
|
||||
|
||||
if data_buffer[x][y][0] > 255:
|
||||
data_buffer[x][y][2] = 127
|
||||
# assign stat to blue colour
|
||||
data_buffer[x][y][3] = data_buffer[x][y][0] - 255
|
||||
|
||||
if data_buffer[x][y][0] > 383:
|
||||
data_buffer[x][y][3] = 127
|
||||
|
||||
set_sdata(0,0,0)
|
||||
# E
|
||||
sdata[0][0] = [0,255,0,0,1]
|
||||
sdata[0][3] = [0,255,0,0,1]
|
||||
sdata[0][4] = [0,255,0,0,1]
|
||||
sdata[0][5] = [0,255,0,0,1]
|
||||
sdata[0][6] = [0,255,0,0,1]
|
||||
# N
|
||||
sdata[1][2] = [0,255,0,0,1]
|
||||
sdata[1][4] = [0,255,0,0,1]
|
||||
sdata[1][5] = [0,255,0,0,1]
|
||||
sdata[1][6] = [0,255,0,0,1]
|
||||
# D
|
||||
sdata[2][1] = [0,255,0,0,1]
|
||||
sdata[2][2] = [0,255,0,0,1]
|
||||
sdata[2][3] = [0,255,0,0,1]
|
||||
sdata[2][4] = [0,255,0,0,1]
|
||||
sdata[2][6] = [0,255,0,0,1]
|
||||
|
||||
send_update()
|
||||
exit()
|
||||
|
||||
|
||||
# if not active, check if adjacent cell is active
|
||||
if wdata[x][y][0] == 0 and has_active_neighb(x, y):
|
||||
# activate and colour
|
||||
data_buffer[x][y][0] = 1
|
||||
data_buffer[x][y][1] = 1
|
||||
data_buffer[x][y][2] = 0
|
||||
data_buffer[x][y][3] = 0
|
||||
|
||||
|
||||
# set wdata to new buffer
|
||||
wdata = data_buffer
|
||||
|
||||
# wait to paint process next frame
|
||||
time.sleep(sleeptime/1000.0)
|
||||
|
||||
# close socket
|
||||
UDPSock.close()
|
|
@ -5,54 +5,83 @@
|
|||
<title>Web socket test</title>
|
||||
<script type="text/javascript">
|
||||
|
||||
var ws;
|
||||
var ws;
|
||||
var msg;
|
||||
|
||||
function sendMessage(){
|
||||
function sendMessage(){
|
||||
var message = document.getElementById('message').value;
|
||||
ws.send(message);
|
||||
}
|
||||
}
|
||||
|
||||
// this displays a standard frame
|
||||
// header: 10 bytes. must be "s2l\n<8<18 "
|
||||
// z buffer: 1 byte
|
||||
// CR \n: 1 byte
|
||||
headersize=12;
|
||||
function connection() {
|
||||
function connection() {
|
||||
ws = new WebSocket('ws://localhost:1234', 'echo-protocol');
|
||||
|
||||
ws.addEventListener("message", function(e) {
|
||||
|
||||
// TO DO
|
||||
// check size of data
|
||||
// if 800 then update both windows and 7-segment display
|
||||
// if only window data is sent, redraw only that
|
||||
// if only segment..
|
||||
// if unexpected size...
|
||||
|
||||
// header: 12 bytes.
|
||||
// 10 first bytes must be "s2l\n<8<18 "
|
||||
// z buffer: 1 byte
|
||||
// CR \n: 1 byte
|
||||
var headersize = 12;
|
||||
|
||||
// The data is the message from stdin of the server
|
||||
var frame = e.data;
|
||||
msg = frame;
|
||||
console.log("Data length received: " + frame.length);
|
||||
|
||||
// we got a frame here
|
||||
// the header is skipped (headersize)
|
||||
// we should test here if it's correct header
|
||||
// first the windows 8*(12*4+1) (8 rows of 12 windows with 4 valus plus a \n per row)
|
||||
for(y=0;y<8;y++)
|
||||
for(x=0;x<12;x++) {
|
||||
r=frame[headersize+y*(x*4+1)] // 4 because RGBA (we ignore A)
|
||||
g=frame[headersize+y*(x*4+1)]
|
||||
b=frame[headersize+y*(x*4+1)]
|
||||
//console.log("put on d="+d+" s="+s+" val="+r+","+g+","+b+"="+b.charCodeAt(0))
|
||||
//console.log(frame);
|
||||
|
||||
var width = 12;
|
||||
var height = 8;
|
||||
|
||||
for(y=0;y<height;y++) {
|
||||
for(x=0;x<width;x++) {
|
||||
// Determine r g b for this window x,y
|
||||
r = frame[headersize + (y * (width * 4 + 1)) + (x * 4 + 0)];
|
||||
g = frame[headersize + (y * (width * 4 + 1)) + (x * 4 + 1)];
|
||||
b = frame[headersize + (y * (width * 4 + 1)) + (x * 4 + 2)];
|
||||
|
||||
//console.log("RGB val=" + r.charCodeAt(0) + "," + g.charCodeAt(0) + "," + b.charCodeAt(0))
|
||||
lightWindow(x,y,r.charCodeAt(0),g.charCodeAt(0),b.charCodeAt(0));
|
||||
}
|
||||
// now the 7 segments display
|
||||
// it contains 12*(8*4+1) bytes for the 7 segments
|
||||
}
|
||||
|
||||
// now the 7 segment (8 actually) display
|
||||
// it contains 12*(8*4+1) bytes for the 8 segments
|
||||
// bytes012: color of segment0, display0
|
||||
// bytes456: color of segment1, display0
|
||||
// bytes89a: color of segment2, display0
|
||||
headersize+=8*(12*4+1)
|
||||
for(d=0;d<12;d++)
|
||||
for(s=0;s<8;s++) {
|
||||
r=frame[headersize+d*(8*4+1)+s*4+0] // 4 because RGBA (we ignore A)
|
||||
g=frame[headersize+d*(8*4+1)+s*4+1]
|
||||
b=frame[headersize+d*(8*4+1)+s*4+2]
|
||||
//console.log("put on d="+d+" s="+s+" val="+r+","+g+","+b+"="+b.charCodeAt(0))
|
||||
lightSegment(d,s,r.charCodeAt(0),g.charCodeAt(0),b.charCodeAt(0));
|
||||
var segments = 8;
|
||||
|
||||
// add all the display windows/frame data to header
|
||||
headersize += height * (width * 4 + 1);
|
||||
|
||||
for(d=0;d<width;d++) {
|
||||
for(s=0;s<segments;s++) {
|
||||
|
||||
//console.log(headersize + d * (segments * 4 + 1) + s * 4 + 0)
|
||||
// Determine r g b for this window d, segment s
|
||||
r = frame[headersize + d * (segments * 4 + 1) + s * 4 + 0];
|
||||
g = frame[headersize + d * (segments * 4 + 1) + s * 4 + 1];
|
||||
b = frame[headersize + d * (segments * 4 + 1) + s * 4 + 2];
|
||||
//console.log("Window " + d + ", segment " + s + "=" + r.charCodeAt(0) + "," + g.charCodeAt(0) + "," + b.charCodeAt(0));
|
||||
lightSegment(d, s, r.charCodeAt(0), g.charCodeAt(0), b.charCodeAt(0));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('connect_button').style.display = 'none';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
@ -73,6 +102,7 @@ headersize=12;
|
|||
context.fill();
|
||||
}
|
||||
function lightWindow(x,y,r,g,b) {
|
||||
//console.log(r + ',' + g + ',' + b);
|
||||
context.beginPath();
|
||||
context.rect(488+40.3*x, 265+87.4*y, 23, 34);
|
||||
context.fillStyle = 'rgb('+r+','+g+','+b+')';
|
||||
|
@ -152,7 +182,5 @@ var ascii2segments = new Array (
|
|||
// lightWindow(i,j,w) // switch on new window with brightness w
|
||||
|
||||
</script>
|
||||
<div>Received from server:</div>
|
||||
<div id='chatlog'></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
// byte windows 12*4 RGBA values '\n' repeated 8 times for the 8 rows
|
||||
// byte segments 8*4 RGBA values '\n' repeated 12 times for the top row
|
||||
|
||||
// set to true for debugging and seeing messages sent to server
|
||||
var verbose = false;
|
||||
|
||||
var count = 0;
|
||||
var clients = {};
|
||||
|
||||
|
@ -82,8 +85,11 @@ var sendTime = function () {
|
|||
};
|
||||
|
||||
server.on("message", function (msg, rinfo) {
|
||||
if( verbose ) {
|
||||
console.log("server got: " + msg + " from " +
|
||||
rinfo.address + ":" + rinfo.port);
|
||||
}
|
||||
|
||||
for(i in clients) {
|
||||
// Send a message to the client with the message
|
||||
clients[i].sendUTF(msg);
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
#define REMOTE_PORT 4422
|
||||
|
||||
|
||||
#define HASH "s2j\n8<18< "
|
||||
#define HASH "s2l\n<8<18 "
|
||||
// one byte number + 10 character hash plus newline
|
||||
#define HEADEROFFSET 12
|
||||
|
||||
// 12 windows per floor, 7 floors, Value:Alpha
|
||||
// 12 windows per floor, 8 floors, Value:Alpha
|
||||
#define WIDTH 12
|
||||
#define HEIGHT 7
|
||||
#define HEIGHT 8
|
||||
#define CHANNELS 4
|
||||
|
||||
#define WINDOWOFFSET (WIDTH*CHANNELS+1)*HEIGHT
|
||||
|
|
Loading…
Reference in New Issue