diff --git a/GUI/server/odrive_server.py b/GUI/server/odrive_server.py
index 717c5f40..9f8b15d1 100644
--- a/GUI/server/odrive_server.py
+++ b/GUI/server/odrive_server.py
@@ -24,21 +24,21 @@ CORS(app, support_credentials=True)
Payload.max_decode_packets = 100
socketio = SocketIO(app, cors_allowed_origins="*", async_mode = "threading")
-def get_all_odrives():
+def get_odrive():
globals()['odrives'] = []
globals()['odrives'].append(odrive.find_any())
globals()['odrives'][0].__channel__._channel_broken.subscribe(lambda: handle_disconnect())
+ print("odrives found")
+ socketio.emit('odrive-found')
def handle_disconnect():
- print("lost odrive, attempting to reconnect")
- # synchronizing flag for connect/disconnect
- globals()['inUse'] = True
- globals()['odrives'] = []
- while len(globals()['odrives']) == 0:
- get_all_odrives()
- time.sleep(0.1)
- globals()['inUse'] = False
- print("reconnected!")
+ print("lost odrive, emitting disconnect event to client")
+ socketio.emit('odrive-disconnected')
+
+@socketio.on('findODrives')
+def getODrives(message):
+ print("looking for odrive")
+ get_odrive()
@socketio.on('enableSampling')
def enableSampling(message):
@@ -193,8 +193,6 @@ def callFunc(odrives, keyList):
print("fcn call failed")
if __name__ == "__main__":
- # sleep to allow time for background.js to register event callbacks for stdout,stderr
- time.sleep(3)
print("args from python: " + str(sys.argv[1:0]))
#print(sys.argv[1:])
# try to import based on command line arguments or config file
@@ -212,11 +210,11 @@ if __name__ == "__main__":
globals()['inUse'] = False
# busy wait for connection
- while len(globals()['odrives']) == 0:
- print("looking for odrives...")
- get_all_odrives()
+ #while len(globals()['odrives']) == 0:
+ # print("looking for odrives...")
+ # get_odrive()
- print("found odrives!")
- globals()['connected'] = True
+ #print("found odrives!")
+ #globals()['connected'] = True
socketio.run(app, host='0.0.0.0', port=5000)
diff --git a/GUI/src/App.vue b/GUI/src/App.vue
index b0de8945..3e5eaf3f 100644
--- a/GUI/src/App.vue
+++ b/GUI/src/App.vue
@@ -46,6 +46,8 @@
style="display: none"
/>
+
+
@@ -63,6 +65,9 @@
:axis="axis.name"
:odrives="odrives"
>
+
+ ODrive:{{ODriveConnected}}
+
@@ -133,6 +138,22 @@ export default {
currentDash: function () {
return this.$store.state.currentDash;
},
+ ODriveConnected: function () {
+ // if server and odrive disconnected, disconnected
+ // if server connected and odrive disco, connecting
+ // if server and odrive connected, connected
+ let ret;
+ if (this.$store.state.serverConnected && this.$store.state.ODriveConnected) {
+ ret = "connected";
+ }
+ else if (this.$store.state.serverConnected && !this.$store.state.ODriveConnected) {
+ ret = "connecting...";
+ }
+ else {
+ ret = "disconnected";
+ }
+ return ret;
+ }
},
methods: {
changeDash(dashName) {
@@ -234,6 +255,19 @@ export default {
// send stop command to odrives
// behavior on reset?
},
+ emitFindODrives() {
+ socketio.sendEvent({
+ type: "findODrives",
+ data: {},
+ });
+ },
+ killServer() {
+ window.ipcRenderer.send('kill-server');
+ },
+ startServer() {
+ window.ipcRenderer.send('start-server');
+ this.$store.dispatch("setServerAddress", "http://127.0.0.1:5000");
+ }
},
created() {
// on app creation, set the address to the default
@@ -247,6 +281,7 @@ export default {
window.ipcRenderer.on('server-stderr', (event, arg) => {
this.$store.commit('logServerMessage', arg);
});
+ window.ipcRenderer.send('start-server');
}
},
};
@@ -356,4 +391,10 @@ button {
margin-left: auto;
}
+.odrive-status {
+ margin-left: auto;
+ font-family: "Roboto Mono", monospace;
+ padding: 5px 10px;
+}
+
diff --git a/GUI/src/background.js b/GUI/src/background.js
index 5fde0c34..368b01ef 100644
--- a/GUI/src/background.js
+++ b/GUI/src/background.js
@@ -104,7 +104,7 @@ app.on('ready', async () => {
}
}
createWindow()
- // Spawn the python server
+ // Figure out correct path and arguments to launch python server
let scriptFilename = path.join(app.getAppPath(), '../server', 'odrive_server.py');
const args = process.argv;
let effectiveCommand = [];
@@ -119,15 +119,22 @@ app.on('ready', async () => {
effectiveCommand.push(arg);
}
}
- var python = spawn(getPyCmd(), effectiveCommand);
- python.stdout.on('data',function(data) {
- console.log(data.toString('utf8'));
- win.webContents.send('server-stdout', String(data.toString('utf8')));
- });
- python.stderr.on('data',function(data) {
- console.log(data.toString('utf8'));
- win.webContents.send('server-stderr', String(data.toString('utf8')));
- });
+ var python;
+ // launch python server on event from renderer process (gui) and pipe stdout/stderr to it
+ ipcMain.on('start-server', () => {
+ python = spawn(getPyCmd(), effectiveCommand);
+ python.stdout.on('data',function(data) {
+ console.log(data.toString('utf8'));
+ win.webContents.send('server-stdout', String(data.toString('utf8')));
+ });
+ python.stderr.on('data',function(data) {
+ console.log(data.toString('utf8'));
+ win.webContents.send('server-stderr', String(data.toString('utf8')));
+ });
+ })
+ ipcMain.on('kill-server', () => {
+ python.kill('SIGINT');
+ })
})
// Exit cleanly on request from parent process in development mode.
diff --git a/GUI/src/lib/odrive_utils.js b/GUI/src/lib/odrive_utils.js
index 20eb82c4..9d64d91d 100644
--- a/GUI/src/lib/odrive_utils.js
+++ b/GUI/src/lib/odrive_utils.js
@@ -24,10 +24,12 @@ export function getReadonly(path) {
}
export function fetchParam(path) {
- socketio.sendEvent({
- type: "getProperty",
- data: {path: path},
- });
+ if (store.state.serverConnected){
+ socketio.sendEvent({
+ type: "getProperty",
+ data: {path: path},
+ });
+ }
}
export function putVal(path, value) {
diff --git a/GUI/src/store.js b/GUI/src/store.js
index 33721655..2bd55814 100644
--- a/GUI/src/store.js
+++ b/GUI/src/store.js
@@ -21,6 +21,7 @@ export default new Vuex.Store({
axes: Array,
odriveServerAddress: String,
serverConnected: Boolean,
+ ODriveConnected: false,
serverOutput: [],
dashboards: [
{
@@ -157,6 +158,9 @@ export default new Vuex.Store({
setServerStatus(state, val) {
state.serverConnected = val;
},
+ setODriveConnected(state, val) {
+ state.ODriveConnected = val;
+ },
removeCtrlFromDash(state, obj) {
// obj is {dash: dashID, path: control path}
for (const dash of state.dashboards) {
@@ -306,9 +310,20 @@ export default new Vuex.Store({
callback: () => {
context.commit("setServerStatus", true);
console.log('connected to server');
- context.dispatch("getOdrives");
+ //context.dispatch("getOdrives");
+ socketio.sendEvent({
+ type: "findODrives",
+ });
}
});
+ socketio.addEventListener({
+ type: "odrive-found",
+ callback: () => {
+ console.log("odrive-found recieved from server");
+ context.commit("setODriveConnected", true);
+ context.dispatch("getOdrives");
+ }
+ })
socketio.addEventListener({
type: "disconnect",
callback: () => {
@@ -348,6 +363,17 @@ export default new Vuex.Store({
context.commit('updateOdriveProp', JSON.parse(retmsg));
}
});
+ socketio.addEventListener({
+ type: "odrive-disconnected",
+ callback: () => {
+ console.log("odrive disconnected");
+ context.commit("setODriveConnected", false);
+ console.log("restarting server...");
+ window.ipcRenderer.send('kill-server');
+ window.ipcRenderer.send('start-server');
+ context.dispatch('setServerAddress', context.state.odriveServerAddress);
+ }
+ })
}
}
})
\ No newline at end of file