Skip to content

Commit

Permalink
r3
Browse files Browse the repository at this point in the history
added update interval
added readme
apply pep8 format
  • Loading branch information
alatas committed Sep 10, 2018
1 parent c1babe2 commit c6a6dc5
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 119 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ ENV api_key= \
onmin=30 \
offhour=20 \
offmin=30 \
update_interval=6 \
HTTP_PROXY=$all_proxy \
HTTPS_PROXY=$all_proxy

Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Google Traffic Screen [![Build Status](https://travis-ci.org/alatas/google-traffic-screen.svg?branch=master)](https://travis-ci.org/alatas/google-traffic-screen)
It's a project that can display the latest traffic information based on an origin location to multiple different locations. It uses Google Distance Matrix API. You need a valid GoogleMaps API key to query the latest information.

Now, It's only available as docker image only

## Quick Start
```
docker pull alatas/google-traffic-display
docker run -ti -p 80:80 -e "api_key=your google maps api key" alatas/google-traffic-display
```
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ services:
- language=en
- units=imperial
- traffic_model=best_guess
- update_interval=6 #update interval in min
- all_proxy= #set proxy
ports:
- "80:80"
Expand Down
268 changes: 149 additions & 119 deletions googletrafficscreen.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,157 +14,187 @@
import googlemaps


class Location:
def __init__(self, name, address):
self.name = name
self.address = address
self.distance = "",
self.eta = "",
self.level = 0,
self.speed = 0
class Location(object):

def __init__(self, name, address):
self.name = name
self.address = address
self.distance = "",
self.eta = "",
self.level = 0,
self.speed = 0


def copydefaults():
if not os.path.isfile('www/index.html'):
print 'default index file copied'
copyfile('www/default-index.html', 'www/index.html')
if not os.path.isfile('www/index.html'):
print 'default index file copied'
copyfile('www/default-index.html', 'www/index.html')

if not os.path.isfile('www/locations.json'):
print 'default locations copied'
copyfile('www/default-locations.json', 'www/locations.json')
if not os.path.isfile('www/locations.json'):
print 'default locations copied'
copyfile('www/default-locations.json', 'www/locations.json')


def loadlocations():
with open('locations.json', 'r') as output:
print 'locations loaded'
return json.loads(output.read(), encoding='utf8')
with open('www/locations.json', 'r') as output:
locs = json.loads(output.read(), encoding='utf8')['locations']
print 'locations loaded'
return [
Location(loc['name'].encode('utf-8').strip(),
loc['address'].encode('utf-8').strip()) for loc in locs
]


def loadorigin():
with open('www/locations.json', 'r') as output:
loc = json.loads(output.read(), encoding='utf8')['origin']
return {
"name": loc['name'].encode('utf-8').strip(),
"address": loc['address'].encode('utf-8').strip()
}


def savesettings():
with open('settings.json', 'w') as input:
input.write(json.dumps(settings))
print 'settings saved'
with open('www/settings.json', 'w') as inp:
inp.write(json.dumps(SETTINGS))
print 'settings saved'


def startwebserver():
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", 80), Handler)
print 'serving at port 80'
httpd.serve_forever()
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", 80), handler)
print 'serving at port 80'
httpd.serve_forever()


def isonduty():
now = datetime.now().time()
if ontime <= offtime:
return ontime <= now < offtime
else:
return ontime <= now or now < offtime
now = datetime.now().time()
if ON_TIME <= OFF_TIME:
return ON_TIME <= now < OFF_TIME
else:
return ON_TIME <= now or now < OFF_TIME


def run():
while True:
if not isonduty():
print "out of working hours"
else:
try:
pagesize = 25 # max size for free developer account
origins = [settings['origin']['address']]
alldestinations = [dest.address for dest in locations]
pageddestinations = [alldestinations[i:i+pagesize]
for i in range(0, len(alldestinations), pagesize)]

for page, destinations in enumerate(pageddestinations):
ret = gmaps.distance_matrix(origins, destinations, mode=settings['params']['mode'], language=settings['params']['language'],
units=settings['params']['units'], departure_time=datetime.now(), traffic_model=settings['params']['traffic_model'])

for i, element in enumerate(ret['rows'][0]['elements']):
locationItem = locations[(pagesize * page) + i]

if element['status'] == 'OK':
updateelement(element, locationItem)
else:
resetelement(locationItem)

with open('data.json', 'w') as output:
output.write(json.dumps(
[obj.__dict__ for obj in locations]))

print 'data.json file updated {0}/{1}\n'.format(
page+1, len(pageddestinations))
except Exception as e:
print 'Error when getting data from google\n{0}'.format(str(e))
time.sleep(60)

print 'sleeping for 3 min'
time.sleep(3 * 60)


def resetelement(locationItem):
locationItem.distance = "..."
locationItem.eta = 0
locationItem.speed = 0
locationItem.level = 0
print '{0} couldn''t updated'.format(locationItem.name)


def updateelement(element, locationItem):
distance_km = float(element['distance']['value']) / 1000
duration_hr = float(element['duration_in_traffic']['value']) / 3600

locationItem.distance = element['distance']['text']
locationItem.eta = element['duration_in_traffic']['value']
locationItem.speed = int(round(distance_km / duration_hr, 0))
locationItem.level = findlevel(
locationItem.speed, int(element['distance']['value']))
print '{0} updated {1} km - {2} km/h'.format(
locationItem.name, distance_km, locationItem.speed)
while True:
if not isonduty():
print "out of working hours"
else:
try:
pagesize = 25 # max size for free developer account
origins = [SETTINGS['origin']['address']]
alldestinations = [dest.address for dest in LOCATIONS]
pageddestinations = [
alldestinations[i:i + pagesize]
for i in range(0, len(alldestinations), pagesize)
]

for page, destinations in enumerate(pageddestinations):
ret = GMAPS.distance_matrix(
origins,
destinations,
mode=SETTINGS['params']['mode'],
language=SETTINGS['params']['language'],
units=SETTINGS['params']['units'],
departure_time=datetime.now(),
traffic_model=SETTINGS['params']['traffic_model'])

for i, element in enumerate(ret['rows'][0]['elements']):
locationitem = LOCATIONS[(pagesize * page) + i]

if element['status'] == 'OK':
updateelement(element, locationitem)
else:
resetelement(locationitem)

with open('data.json', 'w') as output:
output.write(json.dumps([obj.__dict__ for obj in LOCATIONS]))

print 'data.json file updated {0}/{1}\n'.format(
page + 1, len(pageddestinations))
except Exception as e:
print 'Error when getting data from google\n{0}'.format(str(e.message))
time.sleep(60)

print 'sleeping for %d min' % UPDATE_INTERVAL
time.sleep(UPDATE_INTERVAL * 60)


def resetelement(locationitem):
locationitem.distance = "..."
locationitem.eta = 0
locationitem.speed = 0
locationitem.level = 0
print '{0} couldn''t updated'.format(locationitem.name)


def updateelement(element, locationitem):
distance_km = float(element['distance']['value']) / 1000
duration_hr = float(element['duration_in_traffic']['value']) / 3600

locationitem.distance = element['distance']['text']
locationitem.eta = element['duration_in_traffic']['value']
locationitem.speed = int(round(distance_km / duration_hr, 0))
locationitem.level = findlevel(locationitem.speed,
int(element['distance']['value']))
print '{0} updated {1} km - {2} km/h'.format(locationitem.name, distance_km,
locationitem.speed)


def findlevel(speed, distance):
level1 = 6 * math.log(0.000984982 * distance)
level2 = 12 * math.log(0.000984982 * distance)
level3 = 17 * math.log(0.000984982 * distance)
if speed <= level1:
return "1"
elif speed <= level2:
return "2"
elif speed <= level3:
return "3"
else:
return "4"
level1 = 6 * math.log(0.000984982 * distance)
level2 = 12 * math.log(0.000984982 * distance)
level3 = 17 * math.log(0.000984982 * distance)
if speed <= level1:
return "1"
elif speed <= level2:
return "2"
elif speed <= level3:
return "3"
else:
return "4"


def startupdate():
thread = threading.Thread(target=run)
thread.daemon = True
thread.start()
thread = threading.Thread(target=run)
thread.daemon = True
thread.start()


copydefaults()
os.chdir('www')
gmaps = googlemaps.Client(key=os.environ['api_key'])

locations = loadlocations()
settings = {"origin": locations['origin'], "params": {"mode": os.environ['mode'],
"language": os.environ['language'],
"units": os.environ['units'],
"traffic_model": os.environ['traffic_model'],
"onhour": os.environ['onhour'],
"onmin": os.environ['onmin'],
"offhour": os.environ['offhour'],
"offmin": os.environ['offmin']}}

GMAPS = googlemaps.Client(key=os.environ['api_key'])

LOCATIONS = loadlocations()
SETTINGS = {
"origin": loadorigin(),
"params": {
"mode": os.environ['mode'],
"language": os.environ['language'],
"units": os.environ['units'],
"traffic_model": os.environ['traffic_model'],
"onhour": os.environ['onhour'],
"onmin": os.environ['onmin'],
"offhour": os.environ['offhour'],
"offmin": os.environ['offmin'],
"update_interval": os.environ["update_interval"]
}
}

savesettings()
locations = [Location(loc['name'].encode('utf-8').strip(), loc['address'].encode('utf-8').strip())
for loc in locations['locations']]

ontime = time2(int(settings['params']['onhour']),
int(settings['params']['onmin']))
offtime = time2(int(settings['params']['offhour']),
int(settings['params']['offmin']))
ON_TIME = time2(
int(SETTINGS['params']['onhour']), int(SETTINGS['params']['onmin']))
OFF_TIME = time2(
int(SETTINGS['params']['offhour']), int(SETTINGS['params']['offmin']))

print 'working hours is between {0} -> {1}'.format(ontime, offtime)
print '{0} locations are loaded'.format(len(locations))
UPDATE_INTERVAL = int(SETTINGS['params']['update_interval'])

print 'working hours is between {0} -> {1}'.format(ON_TIME, OFF_TIME)
print '{0} locations are loaded'.format(len(LOCATIONS))
print 'starting server and updater'

os.chdir('www')

startupdate()
startwebserver()

0 comments on commit c6a6dc5

Please sign in to comment.