-
Notifications
You must be signed in to change notification settings - Fork 60
/
Copy pathhttp_accel_server.py
156 lines (128 loc) · 4.61 KB
/
http_accel_server.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
# Based on: https://blog.anvileight.com/posts/simple-python-http-server/
import os
import argparse
import json
import threading
import time
from io import BytesIO
from functools import partial
from http.server import HTTPServer, BaseHTTPRequestHandler
# Settings
DEFUALT_PORT = 1337
NUM_FILE_CHARS = 4 # 10^NUM files (e.g. 2 chars = 100 files)
# Global flag
server_ready = 0
file_num = 0
################################################################################
# Functions
# Decode string to JSON and save measurements in a file
def parseSamples(json_str, dir, file_num):
# Create a browsable JSON document
json_doc = json.loads(json_str)
# Find next filename
print('finding file')
cnt = file_num
print('starting with', cnt)
while cnt < 10**NUM_FILE_CHARS:
file_name = str(cnt).zfill(NUM_FILE_CHARS) + '.csv'
file_path = os.path.join(dir, file_name)
if not os.path.exists(file_path):
break
cnt += 1
if cnt >= 10**NUM_FILE_CHARS:
print('ERROR: Directory full')
return file_num
# Write to file
print('Creating file:', file_path)
with open(file_path, mode='w', encoding='utf-8') as f:
num_meas = len(json_doc['x'])
print('Writing samples', num_meas)
try:
for i in range(0, num_meas):
f.write(str(json_doc['x'][i]) + ', ')
f.write(str(json_doc['y'][i]) + ', ')
f.write(str(json_doc['z'][i]))
f.write('\n')
except Exception as e:
print('ERROR: Cannot write to file.', str(e))
return file_num
return cnt
# Handler class for HTTP requests
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def __init__(self, dir, *args, **kwargs):
self.dir = dir
self.file_num = 0
super().__init__(*args, **kwargs)
def do_GET(self):
# Tell client if server is ready for a new sample
self.send_response(200)
self.end_headers()
self.wfile.write(str(server_ready).encode())
def do_POST(self):
# Not a fan of this, but I couldn't find a better way to store a
# value between calls of a callback
global file_num
# Read message
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
# Respond with 204 "no content" status code
self.send_response(204)
self.end_headers()
# Decode JSON and save to file
print('giving:', file_num)
file_num = parseSamples(body.decode('ascii'),
self.dir,
file_num)
print('ret:', file_num)
# Server thread
class ServerThread(threading.Thread):
def __init__(self, *args, **kwargs):
super(ServerThread, self).__init__(*args, **kwargs)
self._stop_event = threading.Event()
def stop(self):
self._stop_event.set()
def is_stopped(self):
return self._stop_event.is_set()
################################################################################
# Main
# Parse arguments
parser = argparse.ArgumentParser(description='Server that saves data from' +
'IoT sensor node.')
parser.add_argument('-d', action='store', dest='out_dir', type=str,
required=True, help='Directory where samples are stored')
parser.add_argument('-p', action='store', dest='port', type=int,
default=DEFUALT_PORT, help='Port number for server')
parser.add_argument('-t', action='store', dest='record_time', type=float,
default=0, help='Time (in seconds) to record samples ' +
'(0 = run forever)')
args = parser.parse_args()
out_dir = args.out_dir
port = args.port
record_time = args.record_time
# If directory does not exist, create it
if not os.path.exists(out_dir):
os.mkdir(out_dir)
# Create server
handler = partial(SimpleHTTPRequestHandler, out_dir)
server = HTTPServer(('', port), handler)
server_addr = server.socket.getsockname()
print('Server running at: ' + str(server_addr[0]) + ':' +
str(server_addr[1]))
# Create thread running server
server_thread = ServerThread(name='server_daemon',
target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
# Store samples for given time
server_ready = 1
rec_timestamp = time.time()
if record_time == 0:
while True:
pass
else:
while time.time() < rec_timestamp + record_time:
pass
print('Server shutting down')
server.shutdown()
server_thread.stop()
server_thread.join()