Skip to content

Commit

Permalink
initial commit of the process manager
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard Stanley committed Jan 14, 2018
1 parent 3a0afa1 commit aecfc95
Show file tree
Hide file tree
Showing 4 changed files with 330 additions and 0 deletions.
60 changes: 60 additions & 0 deletions rover/core/process-manager/deepstream.py
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"
145 changes: 145 additions & 0 deletions rover/core/process-manager/main.py
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()
27 changes: 27 additions & 0 deletions rover/core/process-manager/processes.json
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"
}

]
98 changes: 98 additions & 0 deletions rover/core/process-manager/setup.py
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()


0 comments on commit aecfc95

Please sign in to comment.