-
Notifications
You must be signed in to change notification settings - Fork 0
/
Prod_Prediction_Ticker.py
126 lines (114 loc) · 4.42 KB
/
Prod_Prediction_Ticker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import platform
import os
import http.client, urllib.request, urllib.parse, urllib.error, json, time
import pandas as pd
from PIL import ImageFont # image
from PIL import Image # image
from PIL import ImageDraw # image
### Inputs
# Station code the board will display
board_station = 'E03' # U-street station is defualt. Use get_stations() function to find the station code for your line/station
# WMATA API key
api_key = open("WMATA_API_KEY.txt", "r")
WMATA_KEY = api_key.read()
headers = {
'api_key': WMATA_KEY
}
### Functions
# Get station data from API
def get_stations(line_code):
# params
params = urllib.parse.urlencode({
'LineCode': line_code
})
# hit api
try:
conn = http.client.HTTPSConnection('api.wmata.com')
conn.request("GET", "/Rail.svc/json/jStations?%s" % params, "{body}", headers)
response = conn.getresponse()
data = response.read()
return(json.loads(data))
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
# Get predictions from api
def get_preds(StationCode):
# params
params = {
'StationCodes': StationCode
}
# hit api
try:
conn = http.client.HTTPSConnection('api.wmata.com')
conn.request("GET", "/StationPrediction.svc/json/GetPrediction/" + params['StationCodes'] ,"{body}", headers)
response = conn.getresponse()
data = response.read()
return(json.loads(data))
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
# Control font switches between debuging on mac and raspberrypi
def get_font():
platform_name = platform.system()
if platform_name == 'Linux': # raspberry pi os
font = ImageFont.truetype('FreeMono.ttf', 8)
elif platform_name =='Darwin': # mac os
font = ImageFont.truetype("Arial.ttf",15)
return(font)
### Lookups
# lookup table for spelling changes. Do this so text fits on screen at 8pt font
line_lookup = {'Brnch Av' : 'BrchAv',
'Ft.Tottn' : 'Ft.Ttn',
'Glenmont' : 'Glnmnt',
'Shady Gr' : 'ShdyGr',
'NewCrltn' : 'NwCrtn',
'Wiehle' : 'Wiehle',
'Largo' : 'Largo',
'Vienna' : 'Vienna',
'Grnbelt' : 'Grnblt',
'Hntingtn' : 'Hntngn'}
# lookup table for boarding and arriving code changes
code_lookup = {'ARR' : 'A',
'BRD' : 'B'}
### Run program
lines_to_print = 3 # anything less than 4 will fit
while True:
# get preds
pred_data = get_preds(board_station)['Trains']
# check if data is present. If not make blank screen
if len(pred_data) == 0:
img=Image.new("RGBA", (64,32),(0,0,0)) # mode, size, color
draw = ImageDraw.Draw(img)
img.save("Prod_Board_Photo.png")
# if data is present, print on screen
else:
pred_keys = pred_data[0].keys()
pred_df = pd.DataFrame(pred_data, columns = pred_keys) # convert to pd df
# intialize list
board_text = []
# print between 1 and 3 lines depending on number of trains
lines_avail = pred_df.shape[0]
if lines_avail < 3:
lines_to_print = lines_avail
for i in range(0,lines_to_print):
# change names based on lookup to fit nicely on the board
if pred_df['Destination'][i] in list(line_lookup.keys()):
pred_df['Destination'][i] = line_lookup[pred_df['Destination'][i]]
# change ARR code to fit on board
if pred_df['Min'][i] == 'ARR':
pred_df['Min'][i] = code_lookup[pred_df['Min'][i]]
# change BRD code to fit on board
elif pred_df['Min'][i] == 'BRD':
pred_df['Min'][i] = code_lookup[pred_df['Min'][i]]
# build text string
text = pred_df['Line'][i] + '|' + pred_df['Destination'][i] + '|' + pred_df['Min'][i]
# retain
print(text)
board_text.append(text)
# create image through PIL
img=Image.new("RGBA", (64,32),(0,0,0)) # mode, size, color
draw = ImageDraw.Draw(img) # draw blank image
draw.text((1, 0), '\n'.join(board_text) ,(255,255,255), font = get_font()) # add text to image
draw = ImageDraw.Draw(img) # redraw image with text
img.save("Prod_Board_Photo.png") # save image
time.sleep(10) # sleep 10 seconds before refresh