Compare commits

...

5 commits

10 changed files with 228 additions and 30 deletions

3
.gitignore vendored
View file

@ -2,3 +2,6 @@ src/**/__pycache__
src/venv src/venv
src/modules/navigationd/*.png src/modules/navigationd/*.png
src/modules/navigationd/cache src/modules/navigationd/cache
src/logs
src/cache
key.secret

View file

@ -3,8 +3,15 @@
Software for the K.A.T.I.E. Software for the K.A.T.I.E.
## Components ## Components
### Nightserver
nightserver.py - The central API that the frontend recieves data from. Also serves the frontend itself. 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. ### Vitalsd
- modules/vitalsd/ - Vitals Daemon. Obtains vitals information and POSTs to nightserver.
- modules/vitalsd/
modules/navigationd/ - Navigation Daemon. Obtains navigation data and POSTs to nightserver. ### Navigationd
modules/navigationd/ - Navigation Daemon. Obtains navigation data from gpsd and POSTs to nightserver.
### Musicd
modules/musicd/ - Music Daemon. Simply speaking, plays music.

View file

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
export FLASK_APP=nightserver.py export FLASK_APP=nightserver.py
flask run flask run --host=0.0.0.0

View file

@ -31,14 +31,16 @@ def disconnectCyberware():
except: except:
print("Cannot disconnect Cyberware.") print("Cannot disconnect Cyberware.")
gpsdData = None def getMapImage(distance, gpsdData):
def getMapImage(distance):
ox.settings.use_cache = True ox.settings.use_cache = True
# We don't want to send any data if we don't have a fix.
if(gpsdData.lat == 0 and gpsdData.lon == 0): if(gpsdData.lat == 0 and gpsdData.lon == 0):
point = (42.352593, -83.2640164) return
#point = (42.352593, -83.2640164)
point = (gpsdData.lat, gpsdData.lon)
try: try:
G = ox.graph_from_point(point, dist=distance, dist_type="bbox", network_type="drive") G = ox.graph_from_point(point, dist=distance, dist_type="bbox", network_type="drive")
@ -62,17 +64,20 @@ def getMapImage(distance):
# #
# G = ox.graph_from_bbox(bbox=bbox, network_type="drive_service") # G = ox.graph_from_bbox(bbox=bbox, network_type="drive_service")
def sendLocation(): def sendLocation(gpsdData):
try: # We don't want to hit the API if we don't have a fix.
#request = requests.post(urlLocation, json={ 'x': gpsdData.lat, 'y': gpsdData.lon, 'z': gpsdData.alt, 'o': gpsdData.track }) if(gpsdData.lat != 0 and gpsdData.lon !=0):
request = requests.post(urlLocation, json={ 'x': None, 'y': None, 'z': None, 'o': None, 'uuid': uuid }) try:
except: request = requests.post(urlLocation, json={ 'x': gpsdData.lat, 'y': gpsdData.lon, 'z': gpsdData.alt, 'o': None, 'uuid': uuid })
print('Could not contact NightCall') except:
print('Could not contact NightCall')
def sendMapImage(): def sendMapImage():
try: try:
files = { 'image': open(uuid+".png", 'rb') } files = { 'image': open(uuid+".png", 'rb') }
request = requests.post(urlImage, files=files) request = requests.post(urlImage, files=files)
except FileNotFoundError: # Occurs if we don't have a fix yet.
return
except: except:
print("Could not contact NightCall") print("Could not contact NightCall")
@ -90,11 +95,10 @@ while continueFlag:
try: try:
gpsdData = gpsd.get_current() gpsdData = gpsd.get_current()
except gpsd.NoFixError: except gpsd.NoFixError:
gpsdData = None print("No GPS fix!")
print("No GPS fix yet! Using default coordinates.")
getMapImage(1000) getMapImage(1000, gpsdData)
sendLocation() sendLocation(gpsdData)
sendMapImage() sendMapImage()
#print(packet.position()) #print(packet.position())
@ -106,4 +110,8 @@ print("Removing Cyberware")
disconnectCyberware() disconnectCyberware()
print("Cleaning up") print("Cleaning up")
os.remove(uuid+".png")
try:
os.remove(uuid+".png")
except:
print("No minimap image was ever made. GPS probably never had a fix.")

View file

@ -0,0 +1,42 @@
import subprocess
import requests
import sys
from flask import jsonify
from cyberwareAbs import Cyberware
class AggregatorRecv(Cyberware):
uuid = None
def __init__(self):
print("GadgetBridge Aggregator Reciever started")
print("[WARN] GadgetBridge Aggregator not implemented")
# def sendValue(self, url, jsonRequest):
# try:
# oldJson = json.loads(jsonRequest)
# uuidJson = {'uuid': self.uuid}
# oldJson.update(uuidJson)
# jsonWithUuid = json.dumps(oldJson)
#
# request = requests.post(url, json=jsonWithUuid)
#
# except:
# print(self.apiFailMsg)
# return 2 # 2 = No API contact.
#
# if request.status_code > 399:
# return 3 # 3 = API refused request.
#
# if request.status_code > 299:
# return 4 # 4 = API encountered an internal error.
#
# return 0 # 0 = Success
def sendAll(self):
o=0
def connectCyberware(self):
o=0
def disconnectCyberware(self):
o=0

View file

@ -0,0 +1,23 @@
[enabled]
Infinitime = false
AggregatorRecv = false
; You should not edit any capabilities variables unless you know what you're doing.
[infinitime]
capabilities = [
"vitals/heartrate",
"vitals/steps",
"cyberware/battery"
]
priority = 999
[aggregatorRecv]
capabilities = [
"vitals/heartrate",
"vitals/steps",
"battery",
"vitals/bodytemp",
"vitals/oxygen",
"cyberware/battery"
]
priority = 0

View file

@ -0,0 +1,56 @@
import subprocess
import requests
import sys
from flask import jsonify
from abc import ABC,abstractmethod
class Cyberware(ABC):
# I'll expand this as necessary
urlBase = "http://localhost:5000/"
ENDPOINTS = {
"heartrate":urlBase+"api/vitals/heartrate",
"steps":urlBase+"api/vitals/steps",
"bodytemp":urlBase+"api/vitals/bodytemp",
"oxygen":urlBase+"api/vitals/oxygen",
"battery":urlBase+"api/vitals/battery",
"add":urlBase+"api/cyberware/add",
"remove":urlBase+"api/cyberware/remove"
}
def sendValue(self, url, jsonRequest):
try:
oldJson = json.loads(jsonRequest)
uuidJson = {'uuid': self.uuid}
oldJson.update(uuidJson)
jsonWithUuid = json.dumps(oldJson)
request = requests.post(url, json=jsonWithUuid)
except:
print(self.apiFailMsg)
return 2 # 2 = No API contact.
if request.status_code > 399:
return 3 # 3 = API refused request.
if request.status_code > 299:
return 4 # 4 = API encountered an internal error.
return 0 # 0 = Success
@property
@abstractmethod
def uuid(self):
pass
@abstractmethod
def sendAll(self):
pass
@abstractmethod
def connectCyberware(self):
pass
@abstractmethod
def disconnectCyberware(self):
pass

View file

@ -1,3 +1,6 @@
# TODO: Rewrite this file to use the CyberwareAbs abstract class.
# works as-is but man do I have nightmares knowing this file looks like this.
import subprocess import subprocess
import requests import requests
import sys import sys
@ -160,6 +163,11 @@ class Infinitime:
print(self.apiFailMsg) print(self.apiFailMsg)
self.uuid = None self.uuid = None
def sendAll(self):
self.sendHeartrate()
self.sendSteps()
self.sendBattery()
# while True: # while True:
# try: # try:
# heartrate = getHeartrate() # heartrate = getHeartrate()

View file

@ -1,25 +1,54 @@
from infinitime import Infinitime from infinitime import Infinitime
from aggregatorRecv import AggregatorRecv
import time import time
import configparser
import json
pinetimeEnabled = True config = configparser.ConfigParser()
config.read('config.ini')
pinetimeEnabled = config.getboolean('enabled','Infinitime')
aggregatorEnabled = config.getboolean('enabled', 'AggregatorRecv')
enabled = []
if(pinetimeEnabled): if(pinetimeEnabled):
pinetime = Infinitime() pinetime = Infinitime()
capabilities = json.loads(config.get('infinitime','capabilities'))
enabled.append(pinetime)
pinetime.connectCyberware() pinetime.connectCyberware()
if(aggregatorEnabled):
aggregator = AggregatorRecv()
capabilities = json.loads(config.get('aggregatorRecv','capabilities'))
enabled.append(aggregator)
aggregator.connectCyberware()
continueFlag = True continueFlag = True
#while continueFlag:
# try:
# if(pinetimeEnabled):
# pinetime.sendHeartrate()
# pinetime.sendSteps()
# pinetime.sendHeartrate()
#
# time.sleep(1)
# except KeyboardInterrupt:
# print("Stopping vitalsd")
# continueFlag = False
#
#if(pinetimeEnabled):
# pinetime.disconnectCyberware()
while continueFlag: while continueFlag:
try: try:
if(pinetimeEnabled): for c in enabled:
pinetime.sendHeartrate() c.sendAll()
pinetime.sendSteps()
pinetime.sendHeartrate()
time.sleep(1) time.sleep(1)
except KeyboardInterrupt: except KeyboardInterrupt:
print("Stopping vitalsd") print("Stopping vitalsd")
continueFlag = False continueFlag = False
if(pinetimeEnabled): for c in enabled:
pinetime.disconnectCyberware() c.disconnectCyberware()

View file

@ -153,7 +153,7 @@
} }
/* ------------------------------------- */ /* ------------------------------------- */
/* Below are all center elements - Comms, Popup, and Info */ /* Below are all center elements - Interactions (music, messages, etc), Popup, and Info */
#centerElements { #centerElements {
flex-grow: 2; flex-grow: 2;
@ -162,13 +162,29 @@
/*border: 1px solid #0FF; TODO: Remove this later */ /*border: 1px solid #0FF; TODO: Remove this later */
} }
#commsPanel { /* Interactions panel (music, messages, etc) */
#interactionPanel {
width: 20%; width: 20%;
/*flex-grow: 1;*/ /*flex-grow: 1;*/
margin-left: 2px; margin-left: 2px;
/*border: 1px solid #F00; TODO: Remove this later */ /*border: 1px solid #F00; TODO: Remove this later */
} }
#commsPanel {
width: 100%;
height: 100%;
display: none;
border: 1px solid #00F; /* TODO: Remove this later */
}
#musicPanel {
width: 100%;
height: 100%;
display: none;
border: 1px solid #0F0; /* TODO: Remove this later */
}
#popupPanel { #popupPanel {
flex-grow: 2; flex-grow: 2;
margin-left: 2px; margin-left: 2px;
@ -226,8 +242,14 @@
</div> </div>
</div> </div>
<div id="centerElements"> <div id="centerElements">
<div id="commsPanel"> <div id="interactionPanel">
<!--<p>Comms</p>--> <div id="commsPanel">
<p>Comms</p>
</div>
<div id="musicPanel">
<p>Music</p>
</div>
<!--<p>Interactions</p>-->
</div> </div>
<div id="popupPanel"> <div id="popupPanel">
<!--<p>Popup</p>--> <!--<p>Popup</p>-->