-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmock_mega.py
executable file
·187 lines (167 loc) · 7.36 KB
/
mock_mega.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/usr/bin/python
import select, socket, random, struct, sys, time
from shows import *
# declare global variables with bogus values
remote = None
server = None
mega_number = None
node_number = None
loop_start_time_msec = None
unix_epoch_msec = None # unix time this process started
epoch_msec = None # process start time as received from brain
network_data = None
def now_sec(when_msec):
return long((epoch_msec + when_msec) / 1000)
def millis():
return long(time.time() * 1000.0 - unix_epoch_msec)
def process_commands():
global network_data, node_number
while len(network_data) > 0:
print 'mega', mega_number, 'looking at', repr(network_data)
size = 1
command = network_data[0:1]
if command == 'b':
size += 54
if len(network_data) >= size:
print 'beat:', repr(network_data)
else:
print 'command', command, 'needs', size, 'bytes but only', len(network_data), 'available'
break
elif command == 'n' or command == 'p':
size += 1 # unsigned 8-bit integer
if len(network_data) >= size:
parameter = struct.unpack_from('>B', network_data, 1)[0]
if command == 'n':
node_number = parameter
print 'mega', mega_number, 'is node %u' % node_number
elif command == 'p':
print 'new program %u' % parameter
else:
print 'mega', mega_number, 'neither n nor p'
else:
print 'command', command, 'needs', size, 'bytes but only', len(network_data), 'available'
break
elif command == 'a':
size += 1 # unsigned 8-bit integer
if len(network_data) >= size:
size += struct.unpack_from('>B', network_data, 1)[0]
if len(network_data) >= size:
print 'mega', mega_number, 'audio', repr(network_data[2:size])
else:
print 'command', command, 'needs', size, 'bytes but only', len(network_data), 'available'
break
else:
print 'command', command, 'needs', size, 'bytes but only', len(network_data), 'available'
break
elif command == 'r':
global remote
print 'mega', mega_number, 'closing %s:%d' % remote.getsockname(), 'to %s:%d' % remote.getpeername()
remote.close()
remote = None
network_data = None
time.sleep(10)
break
elif command == 's':
number_of_colors = 3 * NUM_COLORS_PER_PALETTE
size += NUM_PARAMETERS + number_of_colors
if len(network_data) >= size:
start = 1
params = list(struct.unpack_from('>%uB' % NUM_PARAMETERS, network_data, start))
start += NUM_PARAMETERS
colors = list(struct.unpack_from('>%uB' % number_of_colors, network_data, start))
print 'show params', repr(params), 'colors', repr(colors)
else:
print 'command', command, 'needs', size, 'bytes but only', len(network_data), 'available'
break
elif command == 't':
global epoch_msec
size += 8 # unsigned 64-bit integer
if len(network_data) >= size:
epoch_msec = struct.unpack_from('>Q', network_data, 1)[0] / 1000 - loop_start_time_msec
print 'mega', mega_number, 'time set at %u seconds' % now_sec(millis())
else:
print 'command', command, 'needs', size, 'bytes but only', len(network_data), 'available'
break
else:
print 'mega', mega_number, 'received unknown command', repr(command)
remote.sendall('beat, beat, we got the beat yeah we got the beat friend')
network_data = network_data[size:]
def setup():
global epoch_msec, mega_number, network_data, remote, server, unix_epoch_msec
unix_epoch_msec = time.time() * 1000.0
epoch_msec = long(0)
mega_number = random.randint(100, 199)
if len(sys.argv) == 2:
try:
n = int(sys.argv[1])
except:
print 'not a node number:', sys.argv[1]
else:
if 0 <= n and n < 6:
mega_number = 200 + n # mega 200-205 -> node 0-5
else:
print 'node number', n, 'must be 0-5'
server = ('localhost', 3528)
remote = None
network_data = None
last_beat_msec = int(time.time() * 1000.0)
def loop():
global last_beat_msec, loop_start_time_msec, network_data, remote
loop_start_time_msec = None
try:
if remote:
# print node_number
timeout_sec = 5.0 + (last_beat_msec / 1000.0) - time.time()
if timeout_sec <= 0:
timeout_sec = 0.01
readable, writable, oops = select.select([remote], [], [], timeout_sec)
if len(writable) > 0:
print 'ignoring unexpected writable file descriptor(s)'
if len(oops) > 0:
print 'ignoring unexpected file descriptor(s) in exceptional state'
if len(readable) > 0:
if len(readable) != 1:
print 'expected exactly 1 readable file descriptor instead of', len(readable)
message = remote.recv(1024)
if message:
loop_start_time_msec = millis()
network_data += message
process_commands()
else:
print 'mega', mega_number, 'closing %s:%d' % remote.getsockname(), 'to %s:%d' % remote.getpeername()
remote.close()
remote = None
network_data = None
time.sleep(10)
elif node_number != None:
last_beat_msec = int(time.time() * 1000.0)
channel_data = [ random.randint(10,80), random.randint(100,200), random.randint(100,200), random.randint(100,200), random.randint(100,200), random.randint(100,200), random.randint(100,200),
random.randint(100,200), random.randint(100,200), random.randint(100,200), random.randint(100,200), random.randint(100,200), random.randint(100,200), random.randint(100,200) ]
for channel in range(0, len(channel_data)):
channel_data[channel] += random.randint(0, 9)
time.sleep(0.1)
remote.sendall(struct.pack('>cBQ14B', 'c', node_number, last_beat_msec, *channel_data)) # send channel data
else:
try:
time.sleep(random.random())
remote = socket.create_connection(server)
network_data = ''
print 'mega', mega_number, 'connected %s:%d' % remote.getsockname(), 'to %s:%d' % remote.getpeername()
remote.sendall(struct.pack('>cBB', 'm', mega_number, 126))
except:
print 'mega', mega_number, sys.exc_value, 'by %s:%d' % server
time.sleep(10)
except KeyboardInterrupt:
raise
except:
print 'mega', mega_number, sys.exc_value, 'by %s:%d' % server
time.sleep(1)
setup()
while 1:
try:
loop()
except KeyboardInterrupt:
break
if remote:
remote.close()
print '\nmega', mega_number, 'over and out'