-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial commit of the process manager
- Loading branch information
Richard Stanley
committed
Jan 14, 2018
1 parent
3a0afa1
commit aecfc95
Showing
4 changed files
with
330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
''' | ||
Richard Stanley | ||
TitanRover 2017 | ||
audstanley@gmail.com | ||
''' | ||
import requests | ||
import json | ||
|
||
roverIp = "localhost" # This ip will change periodically, | ||
# for now, this is the ip of the rover on openvpn | ||
|
||
def get(recordName): | ||
''' | ||
The get function will get the entire record "rover/" + recordName | ||
and returns the record as an object. | ||
Possible return Errors: | ||
If the record does not exists in DeepStream, returns "NO_RECORD" | ||
Else there is no connection to DeepStream, returns "NO_DEEPSTREAM" | ||
''' | ||
response = None | ||
if type(recordName) is not str: | ||
raise "Your argument needs to be a string when getting from deepstream" | ||
payload = {"body":[{"topic": "record", "action":"read", "recordName": "rover/" + recordName}]} | ||
request = requests.post('http://' + roverIp + ':4080', json=payload) | ||
if type(request.content) is bytes: | ||
response = json.loads(request.content.decode('utf-8')) | ||
elif type(request.content) is str: | ||
response = json.loads(request.content) | ||
|
||
if response["result"] == "SUCCESS": | ||
return response["body"][0]["data"] | ||
elif response["result"] == "FAILURE": | ||
return "NO_RECORD" | ||
else: | ||
return "NO_DEEPSTREAM" | ||
|
||
|
||
def post(obj, recordName): | ||
''' | ||
This function will post the object sen to the deepstream server. | ||
Arguments: | ||
obj: an object that you want to post to deepstream | ||
recordName: the name of the record that you want to post to | ||
''' | ||
if type(recordName) is not str: | ||
raise "Your second argument needs to be a string when setting data to deepstream" | ||
if type(obj) is not dict: | ||
raise "Your first argument needs to be a dict setting data to deepstream" | ||
payload = {"body":[{"topic": "record", "action":"write", "recordName": "rover/" + recordName, "data": obj}]} | ||
request = requests.post('http://' + roverIp + ':4080', json=payload) | ||
if request is not None: | ||
if type(request) is bytes: | ||
request = request.decode('utf-8') | ||
response = request.json() | ||
return response["result"] | ||
else: | ||
return "NO_DEEPSTREAM" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
from os import system | ||
from deepstream import get, post | ||
import sys | ||
from time import sleep | ||
import curses | ||
from threading import Thread | ||
global keyIn, screen, iftop, reach, imu | ||
iftop = {} | ||
reach = {} | ||
imu = {} | ||
keyIn = 0 | ||
screen = curses.initscr() | ||
curses.start_color() | ||
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK) | ||
curses.init_pair(2, curses.COLOR_RED, curses.COLOR_BLACK) | ||
curses.init_pair(3, curses.COLOR_YELLOW, curses.COLOR_BLACK) | ||
|
||
def get_param(prompt_string): | ||
screen.clear() | ||
screen.border(0) | ||
screen.addstr(2, 2, prompt_string) | ||
screen.refresh() | ||
input = screen.getstr(10, 10, 60) | ||
return input | ||
|
||
def execute_cmd(cmd_string): | ||
system("clear") | ||
a = system(cmd_string) | ||
print "" | ||
if a == 0: | ||
print "Command executed correctly" | ||
else: | ||
print "Command terminated with error" | ||
raw_input("Press enter") | ||
print "" | ||
|
||
def runWindow(): | ||
global keyIn, screen, iftop, imu, reach | ||
|
||
while keyIn != ord(chr(27)): | ||
screen = curses.initscr() | ||
screen.clear() | ||
screen.border(0) | ||
screen.addstr(1, 2, "Titan Rover CLI Process Manager", curses.color_pair(1)) | ||
screen.addstr(2, 6, "To restart a process, type the number of the listed process", curses.color_pair(2)) | ||
screen.addstr(4, 4, "Process List:") | ||
screen.addstr(6, 6, "1 - imu:") | ||
screen.addstr(9, 6, "2 - reach:") | ||
screen.addstr(12, 6, "3 - iftop: ") | ||
#screen.addstr(10, 6, str(keyIn)) | ||
|
||
|
||
if type(imu) == dict: | ||
if imu == {}: | ||
pass | ||
else: | ||
screen.addstr(6, 25, "Heading:") | ||
screen.addstr(7, 25, str(imu["heading"]).rjust(8), curses.color_pair(1)) | ||
screen.addstr(6, 41, "Pitch:") | ||
screen.addstr(7, 41, str(imu["pitch"]).rjust(8), curses.color_pair(1)) | ||
screen.addstr(6, 53, "Roll:") | ||
screen.addstr(7, 51, str(imu["roll"]).rjust(8), curses.color_pair(1)) | ||
screen.addstr(6, 61, "MagCal:") | ||
if imu["mag"] == 3: | ||
screen.addstr(7, 66, "yes", curses.color_pair(1)) | ||
else: | ||
screen.addstr(7, 66, "no", curses.color_pair(2)) | ||
elif type(imu) == str: | ||
screen.addstr(6, 25, str(imu), curses.color_pair(2)) | ||
|
||
if type(reach) == dict: | ||
if reach == {}: | ||
pass | ||
else: | ||
pass | ||
elif type(reach) == str: | ||
screen.addstr(9, 25, reach, curses.color_pair(2)) | ||
|
||
if type(iftop) == dict: | ||
if iftop == {}: | ||
screen.addstr(12, 25, "LOADING", curses.color_pair(2)) | ||
else: | ||
screen.addstr(12, 25, "IP Address:") | ||
screen.addstr(13, 25, iftop["ip"], curses.color_pair(1)) | ||
screen.addstr(12, 41, "Download:") | ||
screen.addstr(13, 41, str(iftop["download"]), curses.color_pair(1)) | ||
screen.addstr(12, 53, "Upload:") | ||
screen.addstr(13, 53, str(iftop["upload"]), curses.color_pair(1)) | ||
elif type(iftop) == str: | ||
screen.addstr(12, 25, iftop, curses.color_pair(2)) | ||
|
||
screen.refresh() | ||
|
||
if keyIn == ord("1"): | ||
get_param("what's up?") | ||
curses.endwin() | ||
if keyIn == ord("2"): | ||
pass | ||
if keyIn == ord("3"): | ||
pass | ||
|
||
curses.endwin() | ||
quit() | ||
|
||
def getDataFromDeepstream(): | ||
global keyIn, screen, iftop, reach, imu | ||
while True: | ||
try: | ||
iftop = get("speed") | ||
except: | ||
iftop = "NO_RECORD" | ||
sleep(.08) | ||
try: | ||
reach = get("reach") | ||
except: | ||
reach = "NO_RECORD" | ||
sleep(.08) | ||
try: | ||
imu = get("imu") | ||
except: | ||
imu = {} | ||
sleep(.08) | ||
if keyIn == ord(chr(27)): | ||
quit() | ||
|
||
|
||
|
||
def getCharFromUser(): | ||
global keyIn, screen | ||
while True: | ||
keyIn = screen.getch() | ||
if keyIn == ord(chr(27)): | ||
break | ||
sleep(.05) | ||
curses.endwin() | ||
quit() | ||
|
||
|
||
t1 = Thread(target=runWindow) | ||
t2 = Thread(target=getDataFromDeepstream) | ||
t3 = Thread(target=getCharFromUser) | ||
|
||
t1.start() | ||
t2.start() | ||
t3.start() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[ | ||
{ | ||
"path": "/TitanRover2018/rover/core/servers/ArduinoSocketServer/", | ||
"python": "python", | ||
"screenName": "mobility", | ||
"script": "mobility.py" | ||
}, | ||
{ | ||
"path": "/TitanRover2018/rover/core/servers/iftop/", | ||
"python": "python", | ||
"screenName": "speed", | ||
"script": "iftop.py" | ||
}, | ||
{ | ||
"path": "/TitanRover2018/rover/core/servers/iftop/", | ||
"python": "python", | ||
"screenName": "listening", | ||
"script": "listenToSpeedAndModeRecords.py" | ||
}, | ||
{ | ||
"path": "/TitanRover2018/rover/core/servers/reach/", | ||
"python": "python", | ||
"screenName": "reach", | ||
"script": "reach.py" | ||
} | ||
|
||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import sys | ||
import os | ||
from subprocess import Popen | ||
import subprocess | ||
import json | ||
from pprint import pprint | ||
|
||
class c: | ||
BLUE = '\033[34m' | ||
GREEN = '\033[32m' | ||
YELLOW = '\033[33m' | ||
CYAN = '\033[36m' | ||
MAGENTA = '\033[35' | ||
RED = '\033[31m' | ||
DEFAULT = '\033[0m' | ||
BOLD = '\033[1m' | ||
UNDERLINE = '\033[4m' | ||
|
||
|
||
processes = json.load(open('processes.json')) | ||
path = json.load(open('pathToTitanRover.json')) | ||
|
||
cronLinesFromProcesses = [] | ||
|
||
crontab = '/etc/crontab' | ||
|
||
if sys.platform != "linux": | ||
if sys.platform != "linux2": | ||
print("Your system: " + sys.platform) | ||
print(c.RED+"\nThis script was written ONLY for Linux OS."+c.DEFAULT) | ||
sys.exit() | ||
|
||
if os.getuid() is not 0: | ||
print(c.RED+"Please run script as sudo:\n\t"+c.YELLOW+"sudo python processMan.py\n"+c.DEFAULT) | ||
sys.exit() | ||
|
||
if path["path"] == None or path["path"][-1:] == "/": | ||
print(c.RED+"\nYou need to specify a path in the path.json file first.") | ||
print(" Otherwise, We cannot setup a startup process for you.") | ||
print(" an EXAMPLE of path.json might look like this:") | ||
print(c.YELLOW+" { \"path\": \"/home/audstanley/Documents\" }"+c.DEFAULT) | ||
print(c.BLUE+" Your path MUST point to where the TitanRover2018 Folder is.\n\n"+c.DEFAULT) | ||
print(c.BLUE+" and you MUST NOT leave a trailing slash in your path\n\n"+c.DEFAULT) | ||
sys.exit() | ||
else: | ||
# look to see if screen exists | ||
p1 = Popen([ "whereis", "screen" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] | ||
p2 = Popen([ "whereis", "iftop" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] | ||
p3 = Popen([ "whereis", "pip" ], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0] | ||
|
||
# automatically install dependencies if it does not exists. | ||
if p1[8:] == "": | ||
print(c.YELLOW+"Installing screen, Please wait..."+c.DEFAULT) | ||
Popen([ "sudo", "apt-get", "install", "screen", "-y"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() | ||
|
||
if p2[7:] == "": | ||
print(c.YELLOW+"Installing iftop, Please wait..."+c.DEFAULT) | ||
Popen([ "sudo", "apt-get", "install", "iftop", "-y"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() | ||
|
||
if p3[5:] == "": | ||
print(c.YELLOW+"Installing python-pip, Please wait..."+c.DEFAULT) | ||
Popen([ "sudo", "apt-get", "install", "python-pip", "-y"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() | ||
|
||
# install requests dependency, if not installed | ||
try: | ||
__import__("requests") | ||
except: | ||
print(c.YELLOW+"Installing requests for python, Please wait..."+c.DEFAULT) | ||
Popen([ "sudo", "apt-get", "install", "python-requests", "-y"], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() | ||
|
||
with open(crontab, 'r') as file: | ||
lines = file.readlines() | ||
|
||
file.close() | ||
|
||
cronLineA = "@reboot root cd" | ||
cronLineB = "&& screen -dmLS" | ||
cronLineC = "&& screen -S" | ||
cronLineD = "-X stuff \"" | ||
cronLineE = "\\015\";\n" | ||
|
||
for o in processes: | ||
# cronLineA path["path"] o["path"] cronLineB o["screenName"] cronLineC o["screenName"] cronLineD o["python"] o["script"] cronLineD | ||
# {@reboot root cd} {/home/audstanley/Documents} {/TitanRover2018/rover/core/servers/ArduinoSocketServer/} {&& /usr/bin/screen -dmLS } {mobility} {&& screen -S } {mobility} { -X stuff "} {python} {mobility.py} \015";\n | ||
cronLinesFromProcesses.append("{} {}{} {} {} {} {} {}{} {} {}".format(cronLineA, path["path"], o["path"], cronLineB, o["screenName"], cronLineC, o["screenName"], cronLineD , o["python"], o["script"], cronLineE)) | ||
# cA p1p2 cB oS cC oS cD oPoX cE | ||
print(cronLinesFromProcesses) | ||
if len(lines) > 1 and len(cronLinesFromProcesses) > 1: | ||
dif = [v for v in lines if v not in cronLinesFromProcesses] | ||
if len(dif) > 0: | ||
file = open(crontab, 'w') | ||
for i in dif: | ||
file.write(i) | ||
for i in cronLinesFromProcesses: | ||
file.write(i) | ||
file.close() | ||
|
||
|