Compare commits
1 commit
main
...
Execute_Sc
Author | SHA1 | Date | |
---|---|---|---|
|
f13e5daa32 |
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,6 +2,3 @@ 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
|
|
||||||
|
|
11
README.md
11
README.md
|
@ -3,15 +3,8 @@
|
||||||
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.
|
||||||
|
|
||||||
### Vitalsd
|
modules/vitalsd/ - Vitals Daemon. Obtains vitals information and POSTs to nightserver.
|
||||||
- modules/vitalsd/ - Vitals Daemon. Obtains vitals information and POSTs to nightserver.
|
|
||||||
- modules/vitalsd/
|
|
||||||
|
|
||||||
### Navigationd
|
modules/navigationd/ - Navigation Daemon. Obtains navigation data and POSTs to nightserver.
|
||||||
modules/navigationd/ - Navigation Daemon. Obtains navigation data from gpsd and POSTs to nightserver.
|
|
||||||
|
|
||||||
### Musicd
|
|
||||||
modules/musicd/ - Music Daemon. Simply speaking, plays music.
|
|
||||||
|
|
|
@ -1,3 +1,32 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# Environment variables:
|
||||||
|
# NIGHTSRV_DEV_BIND_ALL - Makes flask bind to 0.0.0.0. Useful if you want to server to other devices for development reasons. NIGHTSRV_DEV_BIND_ALL=1
|
||||||
|
# NIGHTSRV_BLACKLIST_MODULES - Blacklist modules from being run. Should be a python file (i.e. vitalsd.py). Example: NIGHTSRV_BLACKLIST_MODULES=vitalsd.py navigationd.py
|
||||||
|
|
||||||
export FLASK_APP=nightserver.py
|
export FLASK_APP=nightserver.py
|
||||||
flask run --host=0.0.0.0
|
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
|
||||||
|
MODULES_DIR="$(dirname "$(readlink -f "$0")")/modules"
|
||||||
|
|
||||||
|
MODULES=( $MODULES_DIR/* )
|
||||||
|
|
||||||
|
if [ "$NIGHTSRV_DEV_BIND_ALL" == "1" ]; then
|
||||||
|
echo "WARNING - NIGHTSRV_DEV_BIND_ALL is set to bind to 0.0.0.0. This is insecure and should only be used for development reasons."
|
||||||
|
flask run --host=0.0.0.0 &>logs/nightserver.log
|
||||||
|
else
|
||||||
|
echo "Normal flask start"
|
||||||
|
flask run &>logs/nightserver.log
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Sleep for a bit to let flask init"
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
#echo "Starting modules."
|
||||||
|
#for MODULE in $MODULES
|
||||||
|
#do
|
||||||
|
# echo $MODULE
|
||||||
|
# MODULEFILE_PARSE=($(echo $MODULE | tr "/" "\n"))
|
||||||
|
# echo $MODULEFILE_PARSE
|
||||||
|
# MODULEFILE_LEN=${#MODULEFILE[@]}
|
||||||
|
# echo $MOFULEFILE_LEN
|
||||||
|
# MODULEFILE=${MODULEFILE[$MODULEFILE_LEN-1]}
|
||||||
|
#done
|
||||||
|
|
|
@ -31,16 +31,14 @@ def disconnectCyberware():
|
||||||
except:
|
except:
|
||||||
print("Cannot disconnect Cyberware.")
|
print("Cannot disconnect Cyberware.")
|
||||||
|
|
||||||
def getMapImage(distance, gpsdData):
|
gpsdData = None
|
||||||
|
|
||||||
|
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):
|
||||||
return
|
point = (42.352593, -83.2640164)
|
||||||
#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")
|
||||||
|
@ -64,20 +62,17 @@ def getMapImage(distance, gpsdData):
|
||||||
#
|
#
|
||||||
# G = ox.graph_from_bbox(bbox=bbox, network_type="drive_service")
|
# G = ox.graph_from_bbox(bbox=bbox, network_type="drive_service")
|
||||||
|
|
||||||
def sendLocation(gpsdData):
|
def sendLocation():
|
||||||
# We don't want to hit the API if we don't have a fix.
|
try:
|
||||||
if(gpsdData.lat != 0 and gpsdData.lon !=0):
|
#request = requests.post(urlLocation, json={ 'x': gpsdData.lat, 'y': gpsdData.lon, 'z': gpsdData.alt, 'o': gpsdData.track })
|
||||||
try:
|
request = requests.post(urlLocation, json={ 'x': None, 'y': None, 'z': None, 'o': None, 'uuid': uuid })
|
||||||
request = requests.post(urlLocation, json={ 'x': gpsdData.lat, 'y': gpsdData.lon, 'z': gpsdData.alt, 'o': None, 'uuid': uuid })
|
except:
|
||||||
except:
|
print('Could not contact NightCall')
|
||||||
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")
|
||||||
|
|
||||||
|
@ -95,10 +90,11 @@ while continueFlag:
|
||||||
try:
|
try:
|
||||||
gpsdData = gpsd.get_current()
|
gpsdData = gpsd.get_current()
|
||||||
except gpsd.NoFixError:
|
except gpsd.NoFixError:
|
||||||
print("No GPS fix!")
|
gpsdData = None
|
||||||
|
print("No GPS fix yet! Using default coordinates.")
|
||||||
|
|
||||||
getMapImage(1000, gpsdData)
|
getMapImage(1000)
|
||||||
sendLocation(gpsdData)
|
sendLocation()
|
||||||
sendMapImage()
|
sendMapImage()
|
||||||
|
|
||||||
#print(packet.position())
|
#print(packet.position())
|
||||||
|
@ -110,8 +106,4 @@ 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.")
|
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
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
|
|
|
@ -1,23 +0,0 @@
|
||||||
[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
|
|
|
@ -1,56 +0,0 @@
|
||||||
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
|
|
|
@ -1,6 +1,3 @@
|
||||||
# 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
|
||||||
|
@ -163,11 +160,6 @@ 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()
|
||||||
|
|
|
@ -1,54 +1,25 @@
|
||||||
from infinitime import Infinitime
|
from infinitime import Infinitime
|
||||||
from aggregatorRecv import AggregatorRecv
|
|
||||||
import time
|
import time
|
||||||
import configparser
|
|
||||||
import json
|
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
pinetimeEnabled = True
|
||||||
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:
|
||||||
for c in enabled:
|
if(pinetimeEnabled):
|
||||||
c.sendAll()
|
pinetime.sendHeartrate()
|
||||||
|
pinetime.sendSteps()
|
||||||
|
pinetime.sendHeartrate()
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("Stopping vitalsd")
|
print("Stopping vitalsd")
|
||||||
continueFlag = False
|
continueFlag = False
|
||||||
|
|
||||||
for c in enabled:
|
if(pinetimeEnabled):
|
||||||
c.disconnectCyberware()
|
pinetime.disconnectCyberware()
|
||||||
|
|
|
@ -153,7 +153,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------- */
|
/* ------------------------------------- */
|
||||||
/* Below are all center elements - Interactions (music, messages, etc), Popup, and Info */
|
/* Below are all center elements - Comms, Popup, and Info */
|
||||||
|
|
||||||
#centerElements {
|
#centerElements {
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
|
@ -162,29 +162,13 @@
|
||||||
/*border: 1px solid #0FF; TODO: Remove this later */
|
/*border: 1px solid #0FF; TODO: Remove this later */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interactions panel (music, messages, etc) */
|
#commsPanel {
|
||||||
|
|
||||||
#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;
|
||||||
|
@ -242,14 +226,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="centerElements">
|
<div id="centerElements">
|
||||||
<div id="interactionPanel">
|
<div id="commsPanel">
|
||||||
<div id="commsPanel">
|
<!--<p>Comms</p>-->
|
||||||
<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>-->
|
||||||
|
|
Loading…
Reference in a new issue