Permalink
Browse files

Eta feature (#183)

Add a history endpoint to allow calculation of ETA estimates
  • Loading branch information...
Fvaguirre authored and jlyon1 committed Jan 29, 2019
1 parent bd2b437 commit 9e118b310624b2713b810799ddb358b62408eb03
@@ -0,0 +1,25 @@
# ETA Feature Checklist

## Goal 1: History Endpoint
* Code was written last semester
* Waiting on a merge

## Goal 2: Python Implementation
* Implement algorithms in python to make sure it works
### Subgoals
1. Decide on heuristic(s) to choose historical data to use in average velocity calculations (day of the week, shuttle id, etc)
2. Write python script to pull historical data from history endpoint (json and parsing), implement with heuristic(s) in Mind
3. Implement Graph data structure for Stops and routes
4. Implement distance calculations for stops into Graph
5. Implement average velocity calculations into Graph (live velocity and historically average velocity calculated by heuristic)
6. Use above distance and average velocity to assign stop nodes with ETAs

## Goal 3: Test
* Test that python implementation 'works'
* Develop test cases

## Goal 4: Port to Go
* Eventually

## Goal 5: Test
* Test. again.
@@ -0,0 +1,84 @@
import urllib.request
import datetime as dt
import json

MAX_TIME_DIFFERENCE_MIN = 10

def response(url):
return urllib.request.urlopen(url)

def loadJSON(response):
return json.loads(response.read())

def time_in_range(start, end, x):
"""Return true if x is in the range [start, end]"""
if start <= end:
return start <= x <= end
else:
return start <= x or x <= end

def getAvgVelocity(data, route_id, current_time, weekday):
totalVelocity = 0
count = 0
for i in data:
for j in i:
dataArrayTime = j["time"].split(":")
dataHour = int(dataArrayTime[0].split("T")[1])
dataMin = int(dataArrayTime[1])
dataTime = dt.time(dataHour, dataMin, 0)

dataArrayDay = dataArrayTime[0].split('-')
dataYear = int(dataArrayDay[0])
dataMonth = int(dataArrayDay[1])
dataDay = int(dataArrayDay[2].split('T')[0])

day = dt.date(dataYear, dataMonth, dataDay)
dataWeekday = day.weekday()


start = dt.time(current_time.hour, current_time.minute, current_time.second)
tmp_startDate = dt.datetime.combine(dt.date(1,1,1), start)

start = tmp_startDate - dt.timedelta(minutes=MAX_TIME_DIFFERENCE_MIN)
start = start.time()


end = tmp_startDate + dt.timedelta(minutes=MAX_TIME_DIFFERENCE_MIN)
end = end.time()


if j["route_id"] == route_id and dataWeekday == weekday and time_in_range(start, end, dataTime):
totalVelocity += j["speed"]
count += 1
else:
continue
return totalVelocity/count


if __name__ == '__main__':
# Get what day of the week it is today
targetWeekday = dt.datetime.today().weekday()
targetWeekday = 2
# Get what the current time is now
targetTime = dt.datetime.now().time()
targetTime = dt.time(22, 45, 50)


# Specify which route you want to calculate the average velocity for
targetRoute = 20


# Currently on localhost
url = "http://localhost:8080/history"

response = urllib.request.urlopen(url)
data = json.loads(response.read())

# print(len(data))
# for i in data:
# for j in i:
# print(j["time"].split(":"))
# print(i)

print(getAvgVelocity(data, 1, targetTime, targetWeekday))

@@ -73,6 +73,11 @@ func New(cfg Config, ms shuttletracker.ModelService, msg shuttletracker.MessageS
r.Get("/", api.UpdatesHandler)
})

//Hisory
r.Route("/history", func(r chi.Router) {
r.Get("/", api.HistoryHandler)
})

// Admin message
r.Route("/adminMessage", func(r chi.Router) {
r.Get("/", api.AdminMessageHandler)
@@ -115,3 +115,36 @@ func (api *API) UpdatesHandler(w http.ResponseWriter, r *http.Request) {
// Convert updates to JSON
WriteJSON(w, updates) // it's good to take some REST in our server :)
}

// HistoryHandler returns the last 30 days worth of updates for all enabled vehicles
func (api *API) HistoryHandler(w http.ResponseWriter, r *http.Request){
vehicles, err := api.ms.EnabledVehicles()
if err != nil {
log.WithError(err).Error("Unable to get enabled vehicles")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

history := make([][]*shuttletracker.Location, 0, len(vehicles))
for _, vehicle := range vehicles {
since := time.Now().Add(time.Minute * -43200)
vehicleUpdates, err := api.ms.LocationsSince(vehicle.ID, since)
if err != nil{
log.WithError(err).Error("Unable to get last vehicle update.")
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if len(vehicleUpdates) > 0 {
history = append(history, vehicleUpdates)
}
}

writerErr := WriteJSON(w, history)
//Errcheck complaining
if writerErr != nil{
http.Error(w, writerErr.Error(), http.StatusInternalServerError)
}



}
Binary file not shown.

This file was deleted.

Oops, something went wrong.
Binary file not shown.
Oops, something went wrong.

0 comments on commit 9e118b3

Please sign in to comment.