· 7 years ago · Jan 18, 2018, 07:08 PM
1process.title = 'prancer_sensorServer';
2
3var floorPort = 6000;
4var floorIP = '192.168.11.2';
5var startupPacket = Buffer.from("55d50902", "hex");
6var otherStartupPacket = Buffer.from("55d50905000000004000", "hex");
7
8var net = require('net');
9var winston = require('winston');
10var WebSocketClient = require('websocket').client;
11
12var clientWS = new WebSocketClient();
13clientWS.connect('ws://localhost:1337/');
14// var clientWS = new WebSocketClient('ws://localhost:1337/', 'echo-protocol');
15var socketOutput = "yassssssssssssssssssss";
16
17var FPS = 30;
18var frameRateDelay = FPS / 1000;
19
20
21
22
23clientWS.on('connectFailed', function(error) {
24 console.log('websocket connection error: ' + error.toString());
25});
26
27clientWS.on('connect', function(connection) {
28 console.log('webSocket client connected');
29 connection.on('error', function(error) {
30 console.log("connection error: " + error.toString());
31 });
32 connection.on('close', function() {
33 console.log('echo-protocol connection closed');
34 });
35 connection.on('message', function(message) {
36 if (message.type === 'utf8') {
37 //console.log("Received: '" + message.utf8Data + "'");
38 // we really don't need this functionality, commenting it to keep just in case
39 }
40 });
41
42 function sendData() {
43 if (connection.connected) {
44 connection.sendUTF(socketOutput);
45 setTimeout(sendData, frameRateDelay);
46 console.log('sendData()');
47 }
48 }
49 sendData();
50});
51
52
53
54
55
56
57//these aren't used yet.
58var touchBytes;
59var controlBytes;
60var thatGoodGood;
61var allThatGoodShit;
62
63//the header format has a 2 count on the 4th byte on handshake replies,
64//this variable allows us to avoid counting a handshake packet as a frame data packet.
65// TODO see if there's a more intelligent way to handle this issue. maybe examine full header packets instead of just 4th byte?
66var handshaking = false;
67
68
69var idleTicks = 0;
70
71//on the first handshake we don't have the same bytes
72var firstRun = true;
73
74//idleticker counting up in case we don't receive data from the processor box
75//the box seems to stop short of sending a full 16 packet frame occasionally
76//so we manually retrigger it when that happens.
77function idleTicker() {
78 idleTicks += 1;
79 console.log('idleTicker incremented to ' + idleTicks);
80
81 if(idleTicks >= 3) {
82 client.write(otherStartupPacket);
83 idleTicks = 0;
84 }
85
86}
87
88function sleep(millis) {
89 var start = new Date().getTime();
90 for(var i = 0; i< 1e7; i++) {
91 if((new Date().getTime() - start) > millis) {
92 break;
93 }
94 }
95}
96
97//count the idle ticker up at a rate of roughly 20fps
98setInterval(idleTicker, 500000);
99
100winston.configure({
101 transports: [
102 new (winston.transports.File) ({ filename: 'prancerlogger.log'})
103 ]
104});
105
106var client = net.connect(floorPort, floorIP, function() {
107 console.log("connecting");
108 client.write(startupPacket);
109
110});
111client.on('error', function(ex) {
112 console.log("handled error");
113 console.log(ex);
114});
115
116client.on('connect', function(){
117 console.log("connected to socket");
118 // client.write(startupPacket);
119 client.write(startupPacket);
120 handshaking = true;
121});
122
123
124function zeroFiller(binData, width) {
125 width -= binData.toString().length;
126 if( width>0) {
127 return new Array( width + (/\./.test(binData) ? 2 : 1)).join('0')+binData;
128 }
129 return binData + "";
130}
131
132function zeroFillerTwo(binData) { //turn a smol hex byte into a big boye binary octet string
133 var n = binData.toString(2);
134 n = "00000000".substr(n.length)+n;
135 return n;
136}
137
138function willItBlend(data) { //this function will check to see if the incoming packet has a sensor data header
139 //that is the question!
140 if(data[0] == 56 && data[1] == d5 && data[2] == 09) {
141 //that's touch data smoke, don't breathe it
142 var theGoodShit = new Array(data.slice(3,1027)); //this is the full packet worth of data, but it's not all good necessarily...
143 return theGoodShit; //but we'll deal with that later
144 }
145}
146
147
148// this is a per-tile function that we feed the two hex bytes and
149// get back the spatially mapped array of bits we actually want
150// so that touchdesigner doesn't have to fiddle fuck around with remapping the bits
151function unFuckThatGoodShit(oneFitty, twoFitty) {
152 var badShit = zeroFillerTwo(oneFitty.toString(2), 8); //first byte into a full octet string
153 var moreBadShit = zeroFillerTwo(twoFitty.toString(2), 8); //second byte into a full octet string
154 var allTheBadShit = [].concat(badShit, moreBadShit); //glue them together
155 allTheBadShit = allTheBadShit.split(""); //and then split them so we can remap
156 var unFuckedShit
157 unFuckedShit[0] = allTheBadShit[4];
158 unFuckedShit[1] = allTheBadShit[5];
159 unFuckedShit[2] = allTheBadShit[0]; //big ugly hard-coded remap
160 unFuckedShit[3] = allTheBadShit[1]; //not my fault the MCTRL 510 spits out data like this
161 unFuckedShit[4] = allTheBadShit[6];
162 unFuckedShit[5] = allTheBadShit[7];
163 unFuckedShit[6] = allTheBadShit[2];
164 unFuckedShit[7] = allTheBadShit[3];
165 unFuckedShit[8] = allTheBadShit[8];
166 unFuckedShit[9] = allTheBadShit[9];
167 unFuckedShit[10] = allTheBadShit[12];
168 unFuckedShit[11] = allTheBadShit[13];
169 unFuckedShit[12] = allTheBadShit[10];
170 unFuckedShit[13] = allTheBadShit[11];
171 unFuckedShit[14] = allTheBadShit[14];
172 unFuckedShit[15] = allTheBadShit[15];
173 return unFuckedShit; //return an array of bit strings that represent a single remapped tile
174}
175
176
177// // here we iterate through the big master bit list
178// function stringItAllOut(erryThang) {
179// var strungOut = "";
180// for(i=0; i < erryThang.length; i++) {
181// strungOut = strungOut + zeroFillerTwo(erryThang[i].toString(2), 8);
182// }
183// strungOut = strungOut.split("");
184// return strungOut;
185// }
186
187
188
189client.on('data', function(data) {
190 if(firstRun == true) {
191 client.write(otherStartupPacket);
192 firstRun = false;
193 }
194
195 if(willItBlend(data)) {
196 thatGoodGood = willItBlend(data);
197 }
198
199 var numTiles = 32; // per packet
200 var tileData = new Array(numTiles);
201 var tileRaw = new Array(numTiles * 2);
202
203 for(var i=0; i<numTiles; i++) {
204 j = i+1;
205 tileRaw[2*i] = thatGoodGood[32*i];
206 tileRaw[(2*i)+1] = thatGoodGood[1 + (32*i)];
207
208 }
209
210 for(var i = 0; i < numTiles; i++) {
211 tileData.push(unFuckThatGoodShit(tileRaw[2*i], tileRaw[2*i+1]));
212 }
213
214 tileString = tileString + tileData.toString(); //idk
215 // tileString = tileString + tileData.toString(); //idk
216
217
218
219 //reset the idleTicker count as we've hit a frame successfully
220 idleTicks = 0;
221
222 // };
223
224 // winston.log('info', data.toString('hex'))};
225 if(data[3] == 15) {
226 // client.write(otherStartupPacket);
227 // console.log('FRAME');
228 socketOutput = tileString;
229 client.write(startupPacket);
230
231 console.log('16th packet, trying handshake');
232 handshaking = true;
233
234
235 };
236
237 // if(data[3] == 2 && data[0] == 85) {
238 if(data[3] == 2 && handshaking == true) {
239 console.log('handshake reciprocated, commanding');
240 client.write(otherStartupPacket);
241 handshaking = false;
242
243 }
244
245 // client.write(otherStartupPacket);
246
247 // console.log('how bout dat binary ' + dataBuf[0].toString(2) + dataBuf[1].toString(2));
248 // winston.log('info', 'received data, winston logging it. check it out: ' + JSON.stringify(data));
249 // winston.log('info', 'incoming data : ' + dataBuf.toString('hex'));
250
251 // client.write(startupPacket);
252
253})