forked from emlid/ReachView
-
Notifications
You must be signed in to change notification settings - Fork 1
/
server.py
executable file
·305 lines (232 loc) · 9.32 KB
/
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
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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
#!/usr/bin/python
# ReachView code is placed under the GPL license.
# Written by Egor Fedorov ([email protected])
# Copyright (c) 2015, Emlid Limited
# All rights reserved.
# If you are interested in using ReachView code as a part of a
# closed source project, please contact Emlid Limited ([email protected]).
# This file is part of ReachView.
# ReachView is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# ReachView is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with ReachView. If not, see <http://www.gnu.org/licenses/>.
from gevent import monkey
monkey.patch_all()
import time
import json
import os
import signal
import sys
from RTKLIB import RTKLIB
from port import changeBaudrateTo230400
from reach_tools import reach_tools, provisioner
print("Installing all required packages")
provisioner.provision_reach()
import reach_bluetooth.bluetoothctl
import reach_bluetooth.tcp_bridge
from threading import Thread
from flask import Flask, render_template, session, request, send_file
from flask.ext.socketio import SocketIO, emit, disconnect
from subprocess import check_output
app = Flask(__name__)
app.template_folder = "."
app.debug = False
app.config["SECRET_KEY"] = "secret!"
app.config["UPLOAD_FOLDER"] = "../logs"
socketio = SocketIO(app)
# bluetooth init
bluetoothctl = reach_bluetooth.bluetoothctl.Bluetoothctl()
bluetooth_bridge = reach_bluetooth.tcp_bridge.TCPtoRFCOMMBridge()
bluetooth_bridge.start()
# configure Ublox for 230400 baudrate!
changeBaudrateTo230400()
rtk = RTKLIB(socketio)
# at this point we are ready to start rtk in 2 possible ways: rover and base
# we choose what to do by getting messages from the browser
@socketio.on("start bluetooth scan", namespace="/test")
def start_bluetooth_scan():
print("Starting bluetooth scan")
bluetoothctl.start_scan()
socketio.emit("bluetooth scan started", namespace="/test")
@socketio.on("get discoverable bluetooth devices", namespace="/test")
def send_available_bluetooth_devices():
print("Sending available bluetooth devices")
devices = bluetoothctl.get_discoverable_devices()
print(devices)
socketio.emit("discoverable bluetooth devices", devices, namespace="/test")
@socketio.on("get paired bluetooth devices", namespace="/test")
def send_paired_bluetooth_devices():
print("Sending paired bluetooth devices")
devices = bluetoothctl.get_paired_devices()
print(devices)
socketio.emit("paired bluetooth devices", devices, namespace="/test")
@socketio.on("pair bluetooth device", namespace="/test")
def pair_bluetooth_device(device):
print("Pairing device " + str(device))
print("Pairing OK == " + str(bluetoothctl.pair(device["mac_address"])))
devices = bluetoothctl.get_paired_devices()
print("Updating paired devices: ")
print(devices)
socketio.emit("paired bluetooth devices", devices, namespace="/test")
devices = bluetoothctl.get_discoverable_devices()
print(devices)
socketio.emit("discoverable bluetooth devices", devices, namespace="/test")
@socketio.on("remove paired device", namespace="/test")
def remove_paired_device(device):
print("Removing paired device " + str(device))
print("Removed OK == " + str(bluetoothctl.remove(device["mac_address"])))
devices = bluetoothctl.get_paired_devices()
print("Updating paired devices: ")
print(devices)
socketio.emit("paired bluetooth devices", devices, namespace="/test")
devices = bluetoothctl.get_discoverable_devices()
print(devices)
socketio.emit("discoverable bluetooth devices", devices, namespace="/test")
@app.route("/")
def index():
rtk.logm.updateAvailableLogs()
return render_template("index.html", logs = rtk.logm.available_logs, system_status = reach_tools.getSystemStatus())
@app.route("/logs/download/<path:log_name>")
def downloadLog(log_name):
full_log_path = rtk.logm.log_path + "/" + log_name
return send_file(full_log_path, as_attachment = True)
#### Handle connect/disconnect events ####
@socketio.on("connect", namespace="/test")
def testConnect():
print("Browser client connected")
rtk.sendState()
@socketio.on("disconnect", namespace="/test")
def testDisconnect():
print("Browser client disconnected")
#### Log list handling ###
@socketio.on("get logs list", namespace="/test")
def getAvailableLogs():
print("DEBUG updating logs")
rtk.logm.updateAvailableLogs()
print("Updated logs list is " + str(rtk.logm.available_logs))
rtk.socketio.emit("available logs", rtk.logm.available_logs, namespace="/test")
#### rtkrcv launch/shutdown signal handling ####
@socketio.on("launch rover", namespace="/test")
def launchRover():
rtk.launchRover()
@socketio.on("shutdown rover", namespace="/test")
def shutdownRover():
rtk.shutdownRover()
#### rtkrcv start/stop signal handling ####
@socketio.on("start rover", namespace="/test")
def startRover():
rtk.startRover()
@socketio.on("stop rover", namespace="/test")
def stopRtkrcv():
rtk.stopRover()
#### str2str launch/shutdown handling ####
@socketio.on("launch base", namespace="/test")
def startBase():
rtk.launchBase()
@socketio.on("shutdown base", namespace="/test")
def stopBase():
rtk.shutdownBase()
#### str2str start/stop handling ####
@socketio.on("start base", namespace="/test")
def startBase():
rtk.startBase()
@socketio.on("stop base", namespace="/test")
def stopBase():
rtk.stopBase()
#### rtkrcv config handling ####
@socketio.on("read config rover", namespace="/test")
def readConfigRover(json):
rtk.readConfigRover(json)
@socketio.on("write config rover", namespace="/test")
def writeConfigRover(json):
rtk.writeConfigRover(json)
@socketio.on("write and load config rover", namespace="/test")
def writeAndLoadConfig(json):
rtk.writeConfigRover(json)
rtk.loadConfigRover(json.get("config_file_name", None))
#### str2str config handling ####
@socketio.on("read config base", namespace="/test")
def readConfigBase(json):
rtk.readConfigBase()
@socketio.on("write and load config base", namespace="/test")
def writeConfigBase(json):
rtk.writeConfigBase(json)
#### Free space handler
@socketio.on("get available space", namespace="/test")
def getAvailableSpace():
rtk.socketio.emit("available space", reach_tools.getFreeSpace(), namespace="/test")
#### Delete log button handler ####
@socketio.on("delete log", namespace="/test")
def deleteLog(json):
rtk.logm.deleteLog(json.get("name"))
#### Download and convert log handlers ####
@socketio.on("process log", namespace="/test")
def processLog(json):
log_name = json.get("name")
print("Got signal to process a log, name = " + str(log_name))
print("Path to log == " + rtk.logm.log_path + "/" + str(log_name))
raw_log_path = rtk.logm.log_path + "/" + log_name
rtk.processLogPackage(raw_log_path)
@socketio.on("cancel log conversion", namespace="/test")
def cancelLogConversion(json):
log_name = json.get("name")
raw_log_path = rtk.logm.log_path + "/" + log_name
rtk.cancelLogConversion(raw_log_path)
#### RINEX versioning ####
@socketio.on("read RINEX version", namespace="/test")
def readRINEXVersion():
rinex_version = rtk.logm.getRINEXVersion()
rtk.socketio.emit("current RINEX version", {"version": rinex_version}, namespace="/test")
@socketio.on("write RINEX version", namespace="/test")
def writeRINEXVersion(json):
rinex_version = json.get("version")
rtk.logm.setRINEXVersion(rinex_version)
#### Delete config ####
@socketio.on("delete config", namespace="/test")
def deleteLog(json):
log_name = json.get("name")
raw_log_path = rtk.logm.log_path + "/" + log_name
rtk.deleteConfig(json.get("name"))
#### Reset config to default ####
@socketio.on("reset config", namespace="/test")
def resetConfig(json):
rtk.resetConfigToDefault(json.get("name"))
#### Update ReachView ####
@socketio.on("update reachview", namespace="/test")
def updateReachView():
print("Got signal to update!!!")
print("Server interrupted by user to update!!")
rtk.shutdown()
bluetooth_bridge.stop()
socketio.server.stop()
os.execl("/home/reach/ReachView/update.sh", "", str(os.getpid()))
#### Device hardware functions ####
@socketio.on("reboot device", namespace="/test")
def rebootReach():
print("Rebooting...")
check_output("reboot")
@socketio.on("turn off wi-fi", namespace="/test")
def turnOffWiFi():
print("Turning off wi-fi")
check_output("rfkill block wlan", shell = True)
if __name__ == "__main__":
try:
socketio.run(app, host = "0.0.0.0", port = 80)
except KeyboardInterrupt:
print("Server interrupted by user!!")
# clean up broadcast and blink threads
rtk.server_not_interrupted = False
rtk.led.blinker_not_interrupted = False
rtk.waiting_for_single = False
if rtk.coordinate_thread is not None:
rtk.coordinate_thread.join()
if rtk.satellite_thread is not None:
rtk.satellite_thread.join()
if rtk.led.blinker_thread is not None:
rtk.led.blinker_thread.join()