summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dashboard_website/db.py122
1 files changed, 90 insertions, 32 deletions
diff --git a/dashboard_website/db.py b/dashboard_website/db.py
index 1bc1f3c..e1c5970 100644
--- a/dashboard_website/db.py
+++ b/dashboard_website/db.py
@@ -1,34 +1,37 @@
# stores and manages clue DB
# also manages currently available bike teams
-from datastructs import *
-import router
-import csv, time
+import csv
from threading import Thread
+import router
+from datastructs import *
+
# constants
-CLUE_MIN_DISTANCE = 0.1 # minimum distance between clue and bike to be considered valid visitation
+CLUE_MIN_DISTANCE = 0.1 # minimum distance between clue and bike to be considered valid visitation
# variables
-homeBase = Point(42.340226, -71.088395) # krentzman, can be changed on dashboard
+homeBase = Point(42.340226, -71.088395) # krentzman, can be changed on dashboard
clues = []
bikes = []
clusters = []
-routes = {"clusters" : [], "cluster_times" : {}, "individual_routes" : []} #geojson polylines, both between all the clusters
+routes = {"clusters": [], "cluster_times": {},
+ "individual_routes": []} # geojson polylines, both between all the clusters
assigned_clues = []
clues_last_changed = time.time()
home_last_changed = time.time()
-routes_last_changed = time.time()
+routes_last_changed = time.time()
currently_updating = False
-startup = False #
+startup = False #
+
# called every time a node is added
# a bike is added/removed
# determines/assigns clusters, and assigns routes to bikes
-def updateRoutes_background(): # run in thread due to long runtime
+def updateRoutes_background(): # run in thread due to long runtime
global currently_updating, routes_last_changed, routes
print("Calculating clusters...")
- routes = {"clusters" : [], "cluster_times" : {}, "individual_routes" : []} # reset
+ routes = {"clusters": [], "cluster_times": {}, "individual_routes": []} # reset
clusters, paths, times = router.getClusters(bikes, clues, homeBase)
routes['individual_routes'] = paths.copy()
routes['cluster_times'] = times
@@ -36,33 +39,39 @@ def updateRoutes_background(): # run in thread due to long runtime
for i in range(len(bikes)):
if bikes[i].status == "ACTIVE":
routes['individual_routes'][i] = router.getRouteHDPolyline(bikes[i], clusters[i][0])
-
+
routes_last_changed = time.time()
print("Finished calculating clusters/routes.")
currently_updating = False
-def updateRoutes(): # if necessary
+
+def updateRoutes(): # if necessary
global currently_updating
if not currently_updating:
currently_updating = True
t = Thread(target=updateRoutes_background)
t.start()
+
# interface functions
def getTime():
return time.time()
+
def getHomeBaseJSON(timestamp):
if timestamp < 0 or home_last_changed - timestamp > 0:
return homeBase.toJSON()
return False
+
def setHomeBase(latitude, longitude):
homeBase.setCoords(latitude, longitude)
home_last_changed = time.time()
+
def getBikeCluePair(team_name):
- b = None; c = None
+ b = None;
+ c = None
for bike in bikes:
if bike.name == team_name:
b = bike
@@ -72,7 +81,7 @@ def getBikeCluePair(team_name):
break
break
return b, c
-
+
def getRoutesJSON(timestamp):
if timestamp < 0 or routes_last_changed - timestamp > 0:
@@ -82,28 +91,31 @@ def getRoutesJSON(timestamp):
def deleteBike(team_name):
for bike in bikes:
- if bike.name == team_name: # already exists
+ if bike.name == team_name: # already exists
bike.disable()
updateRoutes()
- return 0 # OK
- return 4 # bike does not exist
+ return 0 # OK
+ return 4 # bike does not exist
+
def addBike(team_name, latitude, longitude):
for bike in bikes:
- if bike.name == team_name: # already exists
- return 4 # already exists
+ if bike.name == team_name: # already exists
+ return 4 # already exists
newBike = Bike(latitude, longitude, team_name, "ACTIVE")
bikes.append(newBike)
updateRoutes()
return 0
+
def pingBike(team_name, latitude, longitude):
for bike in bikes:
if bike.name == team_name:
bike.ping()
bike.setCoords(latitude, longitude)
return 0
- return 4 # team not found
+ return 4 # team not found
+
def getBikesJSON():
global bikes
@@ -119,11 +131,13 @@ def getCluesJSON(timestamp):
return [x.toJSON() for x in clues]
return False
+
def addClue(clue_name, clue_info, longitude, latitude, visited="UNVISITED"):
newClue = Clue(latitude, longitude, clue_name, clue_info, visited)
clues.append(newClue)
clues_last_changed = time.time()
+
def deleteClue(clue_name):
for i, clue in enumereate(clues):
if clue.name == clue_name:
@@ -132,38 +146,40 @@ def deleteClue(clue_name):
updateRoutes()
break
+
def visitClue(clue_name):
for clue in clues:
if clue.name == clue_name:
if clue.status == "VISITED":
- return 3 # already visited
+ return 3 # already visited
clue.visit()
clues_last_changed = time.time()
- #updateRoutes()
- return 0 # OK
- return 2 # no clue found
+ # updateRoutes()
+ return 0 # OK
+ return 2 # no clue found
+
def visitClueTeam(team_name, clue_name):
b = None
for bike in bikes:
- if bike.name == team_name:
+ if bike.name == team_name:
b = bike
else:
- return 4 # team not found
+ return 4 # team not found
c = None
for clue in clues:
if clue.name == clue_name:
c = clue
if c.status == "VISITED":
- return 6 # already visited
- break # continue
+ return 6 # already visited
+ break # continue
else:
- return 5 # clue not found
-
+ return 5 # clue not found
+
# if visited clue is the expected one (current target)
if clue_name == b.target_name:
if c.distanceTo(b) < CLUE_MIN_DISTANCE:
- return 3 # too far away
+ return 3 # too far away
b.visitTarget()
clues_last_changed = time.time()
return 0
@@ -172,13 +188,55 @@ def visitClueTeam(team_name, clue_name):
c.visit()
clues_last_changed = time.time()
+
+def load(filename=None):
+ """
+ Loads all clues from a CSV file
+ :param filename: name of CSV file
+ :return: None
+ """
+ # if there is no filename, wipe all clues
+ if filename is None:
+ clues.clear()
+
+ # otherwise, load from file
+ with open(filename, newline='') as f:
+ csvreader = csv.reader(f, delimiter=',', quotechar='"')
+
+ # skip header row
+ next(csvreader)
+
+ for row in csvreader:
+ name = row[0]
+ latitude = row[1]
+ longitude = row[2]
+ info = row[3]
+ status = row[4]
+
+ clues.append(Clue(latitude, longitude, name, info, status))
+
+
+def save():
+ """
+ Writes all clues to a csv file
+ :return: a CSV file with all clues
+ """
+ with open("savefile.csv", 'w', newline='') as f:
+ csvwriter = csv.writer(f, delimiter=',', quotechar='"')
+ # add a header row
+ csvwriter.writerow(["name", "latitude", "longitude", "info", "status"])
+ for clue in clues:
+ csvwriter.writerow([clue.name, clue.latitude, clue.longitude, clue.info, clue.status])
+
+
# junk for testing
with open("all_clues.csv", newline='') as f:
csvreader = csv.reader(f, delimiter=',', quotechar='"')
i = 1
for row in csvreader:
coords = row[1].split(",")
- coords[0] = float(coords[0]); coords[1] = float(coords[1]);
+ coords[0] = float(coords[0]);
+ coords[1] = float(coords[1]);
newClue = Clue(coords[0], coords[1], f"Clue #{i}", row[0], "UNVISITED" if i < 100 else "VISITED")
clues.append(newClue)