diff --git a/.gitignore b/.gitignore index c4fcb21..8b6401a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ src/**/__pycache__ +src/venv diff --git a/README.md b/README.md index 75b2844..93951a3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ # nightui -Software for the K.A.T.I.E. \ No newline at end of file +Software for the K.A.T.I.E. + +## Components +nightserver.py - The central API that the frontend recieves data from. Also serves the frontend itself. + +modules/vitalsd/ - Vitals Daemon. Obtains vitals information and POSTs to nightserver. + +modules/navigationd/ - Navigation Daemon. Obtains navigation data and POSTs to nightserver. diff --git a/src/modules/navigationd/navigationd.py b/src/modules/navigationd/navigationd.py new file mode 100644 index 0000000..e69de29 diff --git a/src/modules/navigationd/requirements.txt b/src/modules/navigationd/requirements.txt new file mode 100644 index 0000000..fada3fb --- /dev/null +++ b/src/modules/navigationd/requirements.txt @@ -0,0 +1 @@ +pygarmin diff --git a/src/modules/vitalsd/requirements.txt b/src/modules/vitalsd/requirements.txt new file mode 100644 index 0000000..30692b7 --- /dev/null +++ b/src/modules/vitalsd/requirements.txt @@ -0,0 +1,2 @@ +flask +requests diff --git a/src/modules/vitalsd/vitalsd.py b/src/modules/vitalsd/vitalsd.py new file mode 100644 index 0000000..12dac72 --- /dev/null +++ b/src/modules/vitalsd/vitalsd.py @@ -0,0 +1,60 @@ +import subprocess +import time +import requests +from flask import jsonify + +heartrateCmd = ['itctl', 'get', 'heart'] +stepsCmd = ['itctl', 'get', 'steps'] +batteryCmd = ['itctl', 'get', 'battery'] + +def getHeartrate(): + proc = subprocess.Popen(heartrateCmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + o, e = proc.communicate() + + if(proc.returncode != 0): + return -1 # Inform that cyberware is inoperative + o = o.decode("utf-8") + bpm = o.split(' ') + return bpm[0] + +def getSteps(): + proc = subprocess.Popen(stepsCmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + o, e = proc.communicate() + + if(proc.returncode != 0): + return -1 # Inform that cyberware is inoperative + o = o.decode("utf-8") + steps = o.split(' ') + return steps[0] + +def getBattery(): + proc = subprocess.Popen(batteryCmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + o, e = proc.communicate() + + if(proc.returncode != 0): + return -1 # Inform that cyberware is inoperative + o = o.decode("utf-8") + battery = o.split('%') + return battery[0] + +heartrate = 0 +steps = 0 +battery = 0 + +urlBase = 'http://localhost:5000' +urlHeartrate = urlBase + '/api/vitals/heartrate' +urlSteps = urlBase + '/api/fitness/steps' +#urlBattery = urlBase + # Cyberware management not yet implemented + +while True: + try: + heartrate = getHeartrate() + steps = getSteps() + #battery = getBattery() + + requests.post(urlHeartrate, json={ 'heartrate': heartrate } ) + requests.post(urlSteps, json={ 'steps': steps }) + except: + print("An exception occured. TODO: Exception report to frontend.") + + time.sleep(1) diff --git a/src/nightserver.py b/src/nightserver.py index 2cfeb2f..26e471a 100644 --- a/src/nightserver.py +++ b/src/nightserver.py @@ -2,9 +2,9 @@ from flask import Flask, render_template, jsonify, request app = Flask(__name__) # Vitals -vitalsHeartrate = 0 -vitalsOxygen = 0 -vitalsBodytemp = 0.0 +vitalsHeartrate = -1 +vitalsOxygen = -1 +vitalsBodytemp = -1.0 @app.route('/api/vitals/heartrate') def getVitalsHeartrate(): @@ -56,6 +56,62 @@ def getVitals(): returnArr = [ { 'heartrate': vitalsHeartrate, 'oxygen': vitalsOxygen, 'bodytemp': vitalsBodytemp } ] return jsonify(returnArr) +@app.route('/api/vitals', methods=['POST']) +def setVitals(): + global vitalsHeartrate + global vitalsOxygen + global vitalsBodytemp + + json = request.get_json() + try: + # This is a bit ugly but its just how I'm checking that everything is there without setting variables if the json is incorrect + tempH = json['heartrate'] + tempO = json['oxygen'] + tempB = json['bodytemp'] + vitalsHeartrate = tempH + vitalsOxygen = tempO + vitalsBodytemp = tempB + except: + return 'Incorrect usage.\nUsage: { heartrate: INT, oxygen: INT, bodytemp: FLOAT }\n', 400 + return 'Information set successfully', 204 + +# Fitness +fitnessSteps = -1 + +@app.route('/api/fitness/steps') +def getSteps(): + return getFitness() # This is the same for now. + +@app.route('/api/fitness/steps', methods=['POST']) +def setFitnessSteps(): + global fitnessSteps + json = request.get_json() + try: + vitalsBodytemp = json['steps'] + except: + return 'Incorrect usage.\nUsage: { steps: INT }\n', 400 + return 'Information set successfully', 204 + + +@app.route('/api/fitness') +def getFitness(): + returnArr = [ { 'steps': fitnessSteps } ] + return jsonify(returnArr) + +@app.route('/api/fitness', methods=['POST']) +def setFitness(): + global fitnessSteps + json = request.get_json() + try: + vitalsBodytemp = json['steps'] + except: + return 'Incorrect usage.\nUsage: { steps: INT }\n', 400 + return 'Information set successfully', 204 + + +# Cyberware management +#@app.route('/api/cyberware/add', methods=['POST']) +#def addCyberware @app.route('/') diff --git a/src/requirements-all.txt b/src/requirements-all.txt new file mode 100644 index 0000000..abebce5 --- /dev/null +++ b/src/requirements-all.txt @@ -0,0 +1,2 @@ +flask +pygarmin diff --git a/src/requirements.txt b/src/requirements.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/src/requirements.txt @@ -0,0 +1 @@ +flask