From 6bfcd8a348962f0357372f4e74c286f93e6eec26 Mon Sep 17 00:00:00 2001 From: makefu Date: Wed, 6 Dec 2017 13:52:53 +0100 Subject: setup.py: init --- __init__.py | 0 ampel.py | 141 ------------------ ampel/__init__.py | 0 ampel/ampel.py | 141 ++++++++++++++++++ ampel/fade.py | 78 ++++++++++ ampel/google-muell.py | 111 ++++++++++++++ ampel/muell.py | 62 ++++++++ ampel/vvs_efa/README.md | 61 ++++++++ ampel/vvs_efa/VVS_EFA.py | 358 ++++++++++++++++++++++++++++++++++++++++++++++ ampel/vvs_efa/__init__.py | 0 fade.py | 78 ---------- google-muell.py | 111 -------------- muell.py | 62 -------- setup.py | 33 +++++ vvs_efa/README.md | 61 -------- vvs_efa/VVS_EFA.py | 358 ---------------------------------------------- vvs_efa/__init__.py | 0 17 files changed, 844 insertions(+), 811 deletions(-) delete mode 100644 __init__.py delete mode 100755 ampel.py create mode 100644 ampel/__init__.py create mode 100755 ampel/ampel.py create mode 100755 ampel/fade.py create mode 100755 ampel/google-muell.py create mode 100755 ampel/muell.py create mode 100644 ampel/vvs_efa/README.md create mode 100644 ampel/vvs_efa/VVS_EFA.py create mode 100644 ampel/vvs_efa/__init__.py delete mode 100755 fade.py delete mode 100755 google-muell.py delete mode 100755 muell.py create mode 100644 setup.py delete mode 100644 vvs_efa/README.md delete mode 100644 vvs_efa/VVS_EFA.py delete mode 100644 vvs_efa/__init__.py diff --git a/__init__.py b/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/ampel.py b/ampel.py deleted file mode 100755 index 976bdd8..0000000 --- a/ampel.py +++ /dev/null @@ -1,141 +0,0 @@ -#! /usr/bin/env python3 -#! nix-shell -i python3 -p python3 python35Packages.docopt python35Packages.paho-mqtt -""" usage: ampel [options] NUMLEDS - - --mqtt-server=HOST path to mqtt server [Default: 192.168.8.11] - --influx-server=HOST path to influxdb server [Default: 192.168.8.11] - --no-mqtt disable mqtt connections for debugging - --no-influx disable sending stats to influxdb - -NUMLEDS is the number of leds to output data for (--add-empty does not count in here) - -13 22 24 26 28 -|-----------|----|----|----| -BLUE GR YEL RED BLUE - EEN LOW -""" -from docopt import docopt -from influxdb import InfluxDBClient -from fade import calc_chain -import time -from time import sleep -import json -import sys -from datetime import datetime, timedelta -import requests -import logging as log -log.basicConfig(level=log.INFO) - -import paho.mqtt.client as mqtt - -thalesplatz = "5003035" -ditzingen = "5007000" - -red = timedelta(minutes=2) -orange = timedelta(minutes=3) -yellow = timedelta(minutes=4) -green = timedelta(minutes=6) -maxtime = timedelta(minutes=15) - - -def fetch_data(): - from datetime import datetime as dt - from vvs_efa import VVS_EFA - efa = VVS_EFA.EFA() - now = dt.now() - conns = efa.get_next_connections( - "Ditzingen Thalesplatz", - "Hauptbahnhof (tief)", - now, - True) - for dep in conns: - if now < dep.time_of_departure: - return dep.time_of_departure - - -def main(): - args = docopt(__doc__) - db = "telegraf" - numleds = int(args['NUMLEDS']) - mqtt_server = args["--mqtt-server"] - influx_server = args["--influx-server"] - no_mqtt = args["--no-mqtt"] - no_influx = args["--no-influx"] - - t = fetch_data() - if not no_mqtt: - log.info("Starting MQTT") - mq = mqtt.Client() - mq.connect(mqtt_server,1883,60) - mq.loop_start() - pub = lambda topic,data: mq.publish(topic,data) - else: - pub = lambda topic,data: log.info("topic: {}\ndata: {}".format(topic,data)) - if not no_influx: - log.info("preparing influxdb") - client = InfluxDBClient(host=influx_server, port=8086, database=db) - msg = { - "measurement": "seconds_to_bus", - "tags": { - "": "thalesplatz" - }, - "time": "2009-11-10T23:00:00Z", - "fields": { - "value": 0.64 - } - } - - sendstat = lambda secs: client.write_points([ { - "measurement": "seconds_to_bus", - "tags": { "station": "thalesplatz" }, - "fields": { "value": secs } }]) - else: - log.info("No influx") - sendstat = lambda secs: log.info("stat {} -> {} secs".format(datetime.now().replace(microsecond=0).isoformat(),secs)) - - val = 0.0 - step = 0.01 - oldstate = state = None - while True: - ret = [] - now = datetime.now() - - - if now > t: - t = fetch_data() - - delta = t - now - sendstat(delta.seconds + delta.days*86400) - deltastr = str(delta).split('.', 2)[0] - - if not ( (t - maxtime) < now < t): - log.info("Bus too far away - {}".format(deltastr)) - ret = calc_chain(3,val) - ret.insert(0,[0,0,0]) - pub("/leds/nodemcu-switcher/set",json.dumps(ret)) - val += step % 1 - else: - log.info("{}:{:02d} -> {}:{:02d} delta: {}".format( - now.hour,now.minute,t.hour,t.minute,deltastr)) - if (t-red) < now < t: - state = "red" - ret = [[255,0,0]] * 4 - elif (t-orange) < now < t: - state = "orange" - ret = [[255,128,0]] * 4 - elif (t-yellow) < now < t: - state = "yellow" - ret = [[255,255,0]] * 4 - elif (t-green) < now < t: - state = "green" - ret = [[0,255,0]] * 4 - else: - state = "blue" - ret = [[0,0,255]] * 4 - if oldstate != state: - oldstate = state - pub("/leds/nodemcu-switcher/set",json.dumps(ret)) - sleep(1) - -if __name__ == "__main__": - main() diff --git a/ampel/__init__.py b/ampel/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ampel/ampel.py b/ampel/ampel.py new file mode 100755 index 0000000..effec24 --- /dev/null +++ b/ampel/ampel.py @@ -0,0 +1,141 @@ +#! /usr/bin/env python3 +#! nix-shell -i python3 -p python3 python35Packages.docopt python35Packages.paho-mqtt +""" usage: ampel [options] NUMLEDS + + --mqtt-server=HOST path to mqtt server [Default: 192.168.8.11] + --influx-server=HOST path to influxdb server [Default: 192.168.8.11] + --no-mqtt disable mqtt connections for debugging + --no-influx disable sending stats to influxdb + +NUMLEDS is the number of leds to output data for (--add-empty does not count in here) + +13 22 24 26 28 +|-----------|----|----|----| +BLUE GR YEL RED BLUE + EEN LOW +""" +from docopt import docopt +from influxdb import InfluxDBClient +from ampel.fade import calc_chain +import time +from time import sleep +import json +import sys +from datetime import datetime, timedelta +import requests +import logging as log +log.basicConfig(level=log.INFO) + +import paho.mqtt.client as mqtt + +thalesplatz = "5003035" +ditzingen = "5007000" + +red = timedelta(minutes=2) +orange = timedelta(minutes=3) +yellow = timedelta(minutes=4) +green = timedelta(minutes=6) +maxtime = timedelta(minutes=15) + + +def fetch_data(): + from datetime import datetime as dt + from vvs_efa import VVS_EFA + efa = VVS_EFA.EFA() + now = dt.now() + conns = efa.get_next_connections( + "Ditzingen Thalesplatz", + "Hauptbahnhof (tief)", + now, + True) + for dep in conns: + if now < dep.time_of_departure: + return dep.time_of_departure + + +def main(): + args = docopt(__doc__) + db = "telegraf" + numleds = int(args['NUMLEDS']) + mqtt_server = args["--mqtt-server"] + influx_server = args["--influx-server"] + no_mqtt = args["--no-mqtt"] + no_influx = args["--no-influx"] + + t = fetch_data() + if not no_mqtt: + log.info("Starting MQTT") + mq = mqtt.Client() + mq.connect(mqtt_server,1883,60) + mq.loop_start() + pub = lambda topic,data: mq.publish(topic,data) + else: + pub = lambda topic,data: log.info("topic: {}\ndata: {}".format(topic,data)) + if not no_influx: + log.info("preparing influxdb") + client = InfluxDBClient(host=influx_server, port=8086, database=db) + msg = { + "measurement": "seconds_to_bus", + "tags": { + "": "thalesplatz" + }, + "time": "2009-11-10T23:00:00Z", + "fields": { + "value": 0.64 + } + } + + sendstat = lambda secs: client.write_points([ { + "measurement": "seconds_to_bus", + "tags": { "station": "thalesplatz" }, + "fields": { "value": secs } }]) + else: + log.info("No influx") + sendstat = lambda secs: log.info("stat {} -> {} secs".format(datetime.now().replace(microsecond=0).isoformat(),secs)) + + val = 0.0 + step = 0.01 + oldstate = state = None + while True: + ret = [] + now = datetime.now() + + + if now > t: + t = fetch_data() + + delta = t - now + sendstat(delta.seconds + delta.days*86400) + deltastr = str(delta).split('.', 2)[0] + + if not ( (t - maxtime) < now < t): + log.info("Bus too far away - {}".format(deltastr)) + ret = calc_chain(3,val) + ret.insert(0,[0,0,0]) + pub("/leds/nodemcu-switcher/set",json.dumps(ret)) + val += step % 1 + else: + log.info("{}:{:02d} -> {}:{:02d} delta: {}".format( + now.hour,now.minute,t.hour,t.minute,deltastr)) + if (t-red) < now < t: + state = "red" + ret = [[255,0,0]] * 4 + elif (t-orange) < now < t: + state = "orange" + ret = [[255,128,0]] * 4 + elif (t-yellow) < now < t: + state = "yellow" + ret = [[255,255,0]] * 4 + elif (t-green) < now < t: + state = "green" + ret = [[0,255,0]] * 4 + else: + state = "blue" + ret = [[0,0,255]] * 4 + if oldstate != state: + oldstate = state + pub("/leds/nodemcu-switcher/set",json.dumps(ret)) + sleep(1) + +if __name__ == "__main__": + main() diff --git a/ampel/fade.py b/ampel/fade.py new file mode 100755 index 0000000..8aea815 --- /dev/null +++ b/ampel/fade.py @@ -0,0 +1,78 @@ +#! /usr/bin/env python3 +#! nix-shell -i python3 -p python3 python35Packages.docopt +""" usage: run [options] NUMLEDS (loop [--skip-unchanged] [STEP] [DELAY]|single STARTVAL) + + --add-empty essentially add a single empty led in front, does not count into NUMLEDS + + --mode=TYPE mode of fading (Default: chain) + --output=TYPE output type, either json or raw (Default: json) + --skip-unchanged if the value in the loop is unchanged, skip the output + +running with loop this script essentially becomes a generator which outputs the +next value each "DELAY" +single returns a single output with STARTVAL as starting point for the first led + +NUMLEDS is the number of leds to output data for (--add-empty does not count in here) +STEP defaults to 0.01 +DELAY defaults to 1 second + +""" +from docopt import docopt +import time +from colorsys import hsv_to_rgb +import json +import sys + +def calc_chain(numleds,val): + divisor = 1.0 / numleds + ret = [] + for i in range(numleds): + v = float(divisor * i + val) % 1 + r,g,b = hsv_to_rgb(v,0.9,1) + ret.append([int(r*255), + int(g*255), + int(b*255)]) + return ret + +def calc_single(numleds,val): + ret = [] + for i in range(numleds): + r,g,b = hsv_to_rgb(val,1,1) + ret.append([int(r*255), + int(g*255), + int(b*255)]) + return ret + +def main(): + args = docopt(__doc__) + numleds = int(args['NUMLEDS']) + mode = args['--mode'] + step = float(args['STEP'] or 0.01) + delay = float(args['DELAY'] or 1) + val = float(args['STARTVAL'] or 0) + last = [] + while True: + if mode == "chain": + ret = calc_chain(numleds,val) + elif mode == "single": + ret = calc_single(numleds,val) + + if args['--add-empty']: + ret.insert(0,[0,0,0]) + + # early serialization makes comparsion easy + ret = json.dumps(ret) + if not (args['--skip-unchanged'] and last == ret): + last = ret + print(ret) + sys.stdout.flush() + if args['single']: + break + else: + val += step % 1 + time.sleep(delay) + + + +if __name__ == "__main__": + main() diff --git a/ampel/google-muell.py b/ampel/google-muell.py new file mode 100755 index 0000000..b3652cb --- /dev/null +++ b/ampel/google-muell.py @@ -0,0 +1,111 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i python3 -p python3 python36Packages.docopt python36Packages.requests2 python36Packages.google_api_python_client python36Packages.dateutil +""" usage: google-muell [options] + + --esp=HOST esp8266 ip [Default: 192.168.1.23] + --client-secrets=FILE Path to client secrets file (from application) [Default: licht-kalender-secrets.json] + --credential-path=PATH Path to newly generated (or existing) credentials [Default: licht-creds.json] + --sleepval=SEC seconds to sleep [Default: 900] + +you can create the client-secrets by creating a new google application, create +oauth2 token and download it ( url here) + +""" +from docopt import docopt +from fade import calc_chain +import time +from time import sleep +import json +import sys +from datetime import datetime, timedelta +import requests + +import httplib2 +from dateutil.parser import parse +from apiclient import discovery +from oauth2client import client +from oauth2client import tools +from oauth2client.file import Storage +SCOPES = 'https://www.googleapis.com/auth/calendar.readonly' +APPLICATION_NAME = 'licht-kalender-client' + +colormap = { + "8": [ 128,128,128 ], # grey + "9": [ 0,0,0 ], # blue + "11": [ 0,0,0 ],# true red + "4": [ 0,0,0 ], # light red + "3": [ 0,0,0 ], # purple + } + +def get_creds(secrets_file,credential_path): + ''' + provide a cred_dir where the credentials would be stored to + ''' + import argparse + flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args() + + store = Storage(credential_path) + credentials = store.get() + if not credentials or credentials.invalid: + flow = client.flow_from_clientsecrets(secrets_file, SCOPES) + flow.user_agent = APPLICATION_NAME + credentials = tools.run_flow(flow, store, flags) + print('Storing new credentials to ' + credential_path) + else: + print('Using existing valid credentials ' + credential_path) + + return credentials + +def next_date(credentials): + http = credentials.authorize(httplib2.Http()) + service = discovery.build('calendar', 'v3', http=http) + + #page_token = None + #while True: + # calendar_list = service.calendarList().list( + # pageToken=page_token).execute() + # for calendar_list_entry in calendar_list['items']: + # print("{} - {}".format(calendar_list_entry['id'],calendar_list_entry['summary'])) + # page_token = calendar_list.get('nextPageToken') + # if not page_token: + # break + + + now = datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time + print('Getting the upcoming 10 events') + eventsResult = service.events().list( + calendarId='o56ig681gla2a5vupm4vgiv7tc@group.calendar.google.com', timeMin=now, maxResults=10, singleEvents=True, + orderBy='startTime').execute() + events = eventsResult.get('items', []) + for event in events: + start = parse(event['start'].get('dateTime', event['start'].get('date'))) + if 'dateTime' in event['end']: + end = parse(event['end']['dateTime']) + else: + end = parse(event['end']['date']) + timedelta(days=1) - timedelta(seconds=1) + + if start < datetime.now() < end: + print("event is active now") + print(start,end, event) + + + pass + + +def to_payload(arr): + return {"r":arr[0],"g":arr[1],"b":arr[2]} + +def main(): + args = docopt(__doc__) + client_secrets = args['--client-secrets'] + sleepval = float(args["--sleepval"]) + esp = args["--esp"] + cred_path = args["--credential-path"] + creds = get_creds(client_secrets,cred_path) + while True: + t = next_date(creds) + requests.get("http://{}/color".format(esp),params=to_payload(t)) + sleep(sleepval) + +if __name__ == "__main__": + main() diff --git a/ampel/muell.py b/ampel/muell.py new file mode 100755 index 0000000..3b84f02 --- /dev/null +++ b/ampel/muell.py @@ -0,0 +1,62 @@ +#! /usr/bin/env nix-shell +#! nix-shell -i python3 -p python3 python35Packages.docopt python35Packages.requests2 +""" usage: ampel [options] TIMEFILE + + --esp=HOST esp8266 ip [Default: 192.168.1.23] + --sleepval=SEC seconds to sleep [Default: 900] + +TIMEFILE refers to a json file which contains all the dates where the bus +drives + +""" +from docopt import docopt +from fade import calc_chain +import time +from time import sleep +import json +import sys +from datetime import datetime, timedelta +import requests + +# time before the day +timebefore = timedelta(hours=24) + +colors = { + "gelber_sack": [ 255,255,0 ], + "orchis": [ 45, 255, 0 ], + "papiermuell": [ 0,0,255 ], + "restmuell": [ 0, 255, 15 ], + "kehrwoche": [ 226, 96, 255 ], + "fallback": [ 66, 220, 244] +} + +def next_date(now,db): + # now = datetime.now() + for e in db: #times are sorted + name = list(e.keys())[0] + times = e[name] + for time in times: + y,m,d = [ int(i) for i in time.split("-") ] + t = datetime.now().replace(year=y,month=m,day=d, + hour=9,minute=0,second=0,microsecond=0) + if (t - timebefore) < now < t: + return name + return "fallback" + +def to_payload(arr): + return {"r":arr[0],"g":arr[1],"b":arr[2]} + +def main(): + args = docopt(__doc__) + times = json.load(open(args['TIMEFILE'])) + sleepval = float(args["--sleepval"]) + esp = args["--esp"] + while True: + now = datetime.now() + t = next_date(now,times) + print(t) + requests.get("http://{}/color".format(esp),params=to_payload(colors[t])) + sleep(sleepval) + +if __name__ == "__main__": + main() diff --git a/ampel/vvs_efa/README.md b/ampel/vvs_efa/README.md new file mode 100644 index 0000000..0dae508 --- /dev/null +++ b/ampel/vvs_efa/README.md @@ -0,0 +1,61 @@ +##VVS API Wrapper + +This was created for easy access to the VVS EFA (Elektronische Fahrplanauskunft) in Python. + +### Example + +```python +# coding: utf-8 +import datetime as dt +from vvs_efa import VVS_EFA + +vvs_efa = VVS_EFA.EFA() +connections = vvs_efa.get_next_connections("Stadtbibliothek", "Feuersee", dt.datetime(2015, 7, 7, 7, 20), True) + + +print connections[0].origin.name +print connections[0].destination.name +print connections[0].time_of_departure.strftime("%d.%m.%Y - %H:%M") + " - " + connections[0].time_of_arrival.strftime("%d.%m.%Y - %H:%M") +print str(connections[0].fare) + "€ / " + str(connections[0].zones) + " Zone(n)" +print "" +for leg in connections[0].legs: + print leg.time_of_departure.strftime("%H:%M") + " - " + leg.time_of_arrival.strftime("%H:%M") + ": " + print leg.origin.name + " - " + leg.destination.name + " ("+ leg.line + ")" + "\n" + + +charlottenplatz = VVS_EFA.Stop("Charlottenplatz") +charlottenplatz_departures = charlottenplatz.get_next_connections(dt.datetime(2015, 7, 9, 18, 10), True) + +print charlottenplatz_departures[0].stop_id +print charlottenplatz_departures[0].stop_name +print charlottenplatz_departures[0].scheduled_datetime.strftime("%d.%m.%Y - %H:%M") +print charlottenplatz_departures[0].realtime_datetime.strftime("%d.%m.%Y - %H:%M") +print charlottenplatz_departures[0].serving_line.key +print charlottenplatz_departures[0].serving_line.number +print charlottenplatz_departures[0].serving_line.direction +print charlottenplatz_departures[0].serving_line.direction_from +print charlottenplatz_departures[0].serving_line.line_type + +``` + +results in: + +``` +Stuttgart, Stadtbibliothek +Stuttgart, Feuersee +06.07.2015 - 07:20 - 06.07.2015 - 07:31 +2.3€ / 2 Zone(n) +07:20 - 07:22: Stadtbibliothek - Hauptbf (A.-Klett-Pl.) (U12) +07:24 - 07:28: Hauptbf (Arnulf-Klett-Platz) - Stuttgart Hauptbahnhof (tief) () +07:28 - 07:31: Stuttgart Hauptbahnhof (tief) - Feuersee (S6) + +5006075 +Charlottenplatz +09.07.2015 - 18:05 +09.07.2015 - 18:11 +143 +43 +Feuersee +Killesberg +Bus +``` diff --git a/ampel/vvs_efa/VVS_EFA.py b/ampel/vvs_efa/VVS_EFA.py new file mode 100644 index 0000000..3a3ca3d --- /dev/null +++ b/ampel/vvs_efa/VVS_EFA.py @@ -0,0 +1,358 @@ +# coding: utf-8 + +import datetime as dt +import requests +import pytz +class EFA(object): + + def __init__(self): + + pass + + @classmethod + def convert_name_to_id(cls, name, mobile=False): + if name.strip() != "": #check if string is empty -> return None + if mobile: + request_url = "http://m.vvs.de/jqm/controller/XSLT_STOPFINDER_REQUEST" + parameters = {} + parameters["name_sf"] = name + parameters["language"] = "de" + parameters["stateless"] = "1" + parameters["locationServerActive"] = "1" + parameters["anyObjFilter_sf"] = "0" + parameters["anyMaxSizeHitList"] = "500" + parameters["outputFormat"] = "JSON" + parameters["SpEncId"] = "0" + parameters["type_sf"] = "any" + parameters["anySigWhenPerfectNoOtherMatches"] = "1" + parameters["convertAddressesITKernel2LocationServer"] = "1" + parameters["convertCoord2LocationServer"] = "1" + parameters["convertCrossingsITKernel2LocationServer"] = "1" + parameters["convertStopsPTKernel2LocationServer"] = "1" + parameters["convertPOIsITKernel2LocationServer"] = "1" + parameters["tryToFindLocalityStops"] = "1" + parameters["w_objPrefAl"] = "12" + parameters["w_regPrefAm"] = "1" + + else: + request_url = "http://www2.vvs.de/vvs/XSLT_STOPFINDER_REQUEST" + parameters = {} + parameters["suggest_macro"] = "vvs" + parameters["name_sf"] = name + + req = requests.post(request_url, parameters) + + points = req.json()["stopFinder"]["points"] + + + best_point_index = 0 + + if len(points) > 1: + for index, point in enumerate(points): + if point["best"] == "1": + best_point_index = index + break + + return points[best_point_index]["stateless"] + + elif len(points) == 1: + return points["point"]["stateless"] #if one point found (no array to iterate!) -> directly return + + else: + return None #no points found -> return None + + else: + return None + + + def get_next_connections(self, origin, destination, datetime, departure, search_by_name = True): + + """Get connections for parameter set: + origin: name of origin + destination: name of destination + time: datetime object of departure/arrival + departure: boolean --> true: time of departure; false: time of arrival + search_by_name: boolean --> true: search by name; false: search by id""" + + if search_by_name: + id_origin = self.convert_name_to_id(origin) + id_destination = self.convert_name_to_id(destination) + if id_origin == None: + raise TypeError('Origin not valid or not found.') + if id_destination == None: + raise TypeError('Destination not valid or not found.') + + else: + id_origin = origin + id_destination = destination + + request_url = "http://m.vvs.de/jqm/controller/XSLT_TRIP_REQUEST2" + + parameters = {} + + #parameters["genC"] = "1" + #parameters["itOptionsActive"] = "1" + #parameters["locationServerActive"] = "1" + #parameters["ptOptionsActive"] = "1" + parameters["stateless"] = "1" + parameters["name_origin"] = id_origin + parameters["name_destination"] = id_destination + parameters["type_destination"] = "any" + parameters["type_origin"] = "any" + parameters["use_realtime"] = "1" + parameters["itdTime"] = datetime.strftime("%H%M") #"2105" + parameters["date"] = datetime.strftime("%Y%m%d") #"20141216" + + if departure: + parameters["itdTripDateTimeDepArr"] = "dep" + else: + parameters["itdTripDateTimeDepArr"] = "arr" + + parameters["routeType"] = "LEASTTIME" + parameters["changeSpeed"] = "normal" + + #parameters["includedMeans"] = "checkbox" #does only work when inclMOT_x set + #parameters["inclMOT_0"] = "1" + #parameters["inclMOT_1"] = "1" + #parameters["inclMOT_2"] = "1" + #parameters["inclMOT_3"] = "1" + #parameters["inclMOT_4"] = "1" + #parameters["inclMOT_5"] = "1" + #parameters["inclMOT_6"] = "1" + #parameters["inclMOT_7"] = "1" + #parameters["inclMOT_8"] = "1" + #parameters["inclMOT_9"] = "1" + #parameters["inclMOT_10"] = "1" + #parameters["inclMOT_11"] = "1" + #parameters["inclMOT_12"] = "1" + #parameters["inclMOT_13"] = "1" + #parameters["inclMOT_14"] = "1" + #parameters["inclMOT_15"] = "1" + #parameters["inclMOT_16"] = "1" + #parameters["inclMOT_17"] = "1" + + parameters["outputFormat"] = "JSON" + + #parameters["SpEncId"] = "0" + #parameters["anySigWhenPerfectNoOtherMatches"] = "1" + #parameters["convertStopsPTKernel2LocationServer"] = "1" + #parameters["convertPOIsITKernel2LocationServer"] = "1" + #parameters["verifyAnyLocViaLocServer"] = "1" + #parameters["w_objPrefAl"] = "12" + #parameters["w_regPrefAm"] = "1" + #parameters["calcOneDirection"] = "1" #if not set, first trip is last trip before date/time for departure, else first trip after date/time + #parameters["searchLimitMinutes"] = "360" + + + req = requests.post(request_url, parameters) + + data = req.json() + trips = data["trips"] + trip_objs = [] + + if trips != None: + for trip in trips: + #Trip attributes + #trip_duration = trip["duration"] + trip_fare = float(trip["itdFare"]["fares"]["fare"]["fareAdult"]) + trip_zones = abs(int(trip["itdFare"]["tariffZones"]["tariffZone"]["toPR"]) - int(trip["itdFare"]["tariffZones"]["tariffZone"]["fromPR"])) + trip_origin = Location(name = data["origin"]["points"]["point"]["name"], loc_id = data["origin"]["points"]["point"]["stateless"], loc_type = data["origin"]["points"]["point"]["anyType"]) + trip_destination = Location(name = data["destination"]["points"]["point"]["name"], loc_id = data["destination"]["points"]["point"]["stateless"], loc_type = data["destination"]["points"]["point"]["anyType"]) + + #print "Dauer: %s \nPreis: %s\n" % (trip_duration, trip_fare) + + trip_legs = [] + for leg in trip["legs"]: + origin = Location(name=leg["points"][0]["name"], loc_id=leg["points"][0]["ref"]["id"]) + destination = Location(name=leg["points"][1]["name"], loc_id=leg["points"][1]["ref"]["id"]) + + origin_realtime_date = leg["points"][0]["dateTime"]["rtDate"] #17.12.2014 + origin_realtime_time = leg["points"][0]["dateTime"]["rtTime"] #16:35 + + destination_realtime_date = leg["points"][1]["dateTime"]["rtDate"] + destination_realtime_time = leg["points"][1]["dateTime"]["rtTime"] + berlin = pytz.timezone('Europe/Berlin') + origin_departure_real_datetime = berlin.localize( + dt.datetime.strptime(origin_realtime_date + "-" + + origin_realtime_time, + "%d.%m.%Y-%H:%M")).replace(tzinfo=None) + destination_arrival_real_datetime = berlin.localize( + dt.datetime.strptime(destination_realtime_date + "-" + + destination_realtime_time, + "%d.%m.%Y-%H:%M")).replace(tzinfo=None) + + duration = leg["timeMinute"] + mode = leg["mode"]["product"] + line = leg["mode"]["number"] + direction = leg["mode"]["destination"] + + l = Leg(origin, destination, origin_departure_real_datetime, destination_arrival_real_datetime, mode, line, direction) + + trip_legs.append(l) + + #print "%s-%s: (%s min)\n %s - %s" %(origin_departure_real_time, destination_arrival_real_time, duration, origin, destination) + + + trip_time_of_departure = trip_legs[0].time_of_departure + trip_time_of_arrival = trip_legs[-1].time_of_arrival + + trip_obj = Trip(trip_origin, trip_destination, trip_time_of_departure, trip_time_of_arrival, trip_legs, trip_fare, trip_zones) + trip_objs.append(trip_obj) + + else: + raise ValueError("No trips found") + + + return trip_objs + + +class Trip(object): + + def __init__(self, origin, destination, time_of_departure, time_of_arrival, legs, fare, zones): + """origin: location object of origin + destination: location object of destination + time_of_departure: datetime object of trip departure time / date + time_of_arrival: datetime object of trip arrival time / date + legs: list of Leg objects + fare: fare of trip (float) + zones: number of zones travelled (int)""" + + self.origin = origin + self.destination = destination + self.time_of_departure = time_of_departure + self.time_of_arrival = time_of_arrival + self.legs = legs + self.fare = fare + self.zones = zones + + + +class Leg(object): + + def __init__(self, origin, destination, time_of_departure, time_of_arrival, mode, line, direction): + """origin: leg origin (station / address / etc.) + destination: leg destination (station / address / etc.) + time_of_departure: departure datetime object + time_of_arrival: arrival datetime object + mode: mode of transportation (U-Bahn / S-Bahn / Bus / Walking) + line: U-Bahn / S-Bahn / Bus Line + direction: ulitmate destination of U-Bahn / S-Bahn / Bus Line""" + + self.origin = origin + self.destination = destination + self.time_of_departure = time_of_departure + self.time_of_arrival = time_of_arrival + self.mode = mode + self.line = line + self.direction = direction + + +class Location(object): + + def __init__(self, name, loc_id, loc_type="any"): + """type: type of location (station / address / etc.) + name: full name of location + id: id of location""" + + self.loc_type = loc_type + self.name = name + self.loc_id = loc_id + + +class Stop(object): + + def __init__(self, name): + self.id = VVS_EFA.convert_name_to_id(name) + if self.id == None: + raise TypeError("Station could not be found.") + + def get_next_connections(self, datetime, departure, limit=20): + + """datetime: datetime object of time & date + departure: boolean, true -> time of departure, false --> time of arrival + limit: int, limit of results fetched, default: 20""" + + if self.id != None: + + parameters = {} + + parameters["deleteAssignedStops_dm"] = "1" + parameters["itOptionsActive"] = "1" + parameters["limit"] = str(limit) + parameters["locationServerActive"] = "1" + parameters["mode"] = "direct" + parameters["name_dm"] = self.id + parameters["ptOptionsActive"] = "1" + parameters["stateless"] = "1" + parameters["type_dm"] = "stop" + parameters["useAllStops"] = "1" + parameters["useRealtime"] = "1" + parameters["itdTime"] = datetime.strftime("%H%M") + parameters["itdDate"] = datetime.strftime("%Y%m%d") + + if departure: + parameters["itdTripDateTimeDepArr"] = "dep" + else: + parameters["itdTripDateTimeDepArr"] = "arr" + + parameters["outputFormat"] = "JSON" + parameters["SpEncId"] = "0" + parameters["anySigWhenPerfectNoOtherMatches"] = "1" + parameters["convertStopsPTKernel2LocationServer"] = "1" + parameters["convertPOIsITKernel2LocationServer"] = "1" + parameters["verifyAnyLocViaLocServer"] = "1" + parameters["w_objPrefAl"] = "12" + parameters["w_regPrefAm"] = "1" + + request_url = "http://m.vvs.de/jqm/controller/XSLT_DM_REQUEST" + req = requests.post(request_url, parameters) + data = req.json() + + departure_list = data["departureList"] + connections = [] + for list_entry in departure_list: + serving_line_data = list_entry["servingLine"] + serving_line = ServingLine(serving_line_data["key"], serving_line_data["number"], serving_line_data["direction"], + serving_line_data["directionFrom"], serving_line_data["name"]) + + stop_id = list_entry["stopID"] + stop_name = list_entry["stopName"] + scheduled_datetime = dt.datetime(int(list_entry["dateTime"]["year"]), int(list_entry["dateTime"]["month"]), + int(list_entry["dateTime"]["day"]), int(list_entry["dateTime"]["hour"]), int(list_entry["dateTime"]["minute"])) + + try: #check if realtime info available + realtime_datetime = dt.datetime(int(list_entry["realDateTime"]["year"]), int(list_entry["realDateTime"]["month"]), + int(list_entry["realDateTime"]["day"]), int(list_entry["realDateTime"]["hour"]), int(list_entry["realDateTime"]["minute"])) + + except: #if not: return None for realtime_datetime + realtime_datetime = None + + connection = Connection(stop_id, stop_name, scheduled_datetime, realtime_datetime, serving_line) + connections.append(connection) + + return connections + + else: + return None + + + +class Connection(object): + """docstring for Connection""" + def __init__(self, stop_id, stop_name, scheduled_datetime, realtime_datetime, serving_line): + """realtime_datetime: datetime object of projected departure/arrival. None if not available""" + self.stop_id = stop_id + self.stop_name = stop_name + self.scheduled_datetime = scheduled_datetime + self.realtime_datetime = realtime_datetime + self.serving_line = serving_line + + +class ServingLine(object): + """docstring for ServingLine""" + def __init__(self, key, number, direction, direction_from, line_type): + self.key = key + self.number = number + self.direction = direction + self.direction_from = direction_from + self.line_type = line_type diff --git a/ampel/vvs_efa/__init__.py b/ampel/vvs_efa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/fade.py b/fade.py deleted file mode 100755 index 8aea815..0000000 --- a/fade.py +++ /dev/null @@ -1,78 +0,0 @@ -#! /usr/bin/env python3 -#! nix-shell -i python3 -p python3 python35Packages.docopt -""" usage: run [options] NUMLEDS (loop [--skip-unchanged] [STEP] [DELAY]|single STARTVAL) - - --add-empty essentially add a single empty led in front, does not count into NUMLEDS - - --mode=TYPE mode of fading (Default: chain) - --output=TYPE output type, either json or raw (Default: json) - --skip-unchanged if the value in the loop is unchanged, skip the output - -running with loop this script essentially becomes a generator which outputs the -next value each "DELAY" -single returns a single output with STARTVAL as starting point for the first led - -NUMLEDS is the number of leds to output data for (--add-empty does not count in here) -STEP defaults to 0.01 -DELAY defaults to 1 second - -""" -from docopt import docopt -import time -from colorsys import hsv_to_rgb -import json -import sys - -def calc_chain(numleds,val): - divisor = 1.0 / numleds - ret = [] - for i in range(numleds): - v = float(divisor * i + val) % 1 - r,g,b = hsv_to_rgb(v,0.9,1) - ret.append([int(r*255), - int(g*255), - int(b*255)]) - return ret - -def calc_single(numleds,val): - ret = [] - for i in range(numleds): - r,g,b = hsv_to_rgb(val,1,1) - ret.append([int(r*255), - int(g*255), - int(b*255)]) - return ret - -def main(): - args = docopt(__doc__) - numleds = int(args['NUMLEDS']) - mode = args['--mode'] - step = float(args['STEP'] or 0.01) - delay = float(args['DELAY'] or 1) - val = float(args['STARTVAL'] or 0) - last = [] - while True: - if mode == "chain": - ret = calc_chain(numleds,val) - elif mode == "single": - ret = calc_single(numleds,val) - - if args['--add-empty']: - ret.insert(0,[0,0,0]) - - # early serialization makes comparsion easy - ret = json.dumps(ret) - if not (args['--skip-unchanged'] and last == ret): - last = ret - print(ret) - sys.stdout.flush() - if args['single']: - break - else: - val += step % 1 - time.sleep(delay) - - - -if __name__ == "__main__": - main() diff --git a/google-muell.py b/google-muell.py deleted file mode 100755 index b3652cb..0000000 --- a/google-muell.py +++ /dev/null @@ -1,111 +0,0 @@ -#! /usr/bin/env nix-shell -#! nix-shell -i python3 -p python3 python36Packages.docopt python36Packages.requests2 python36Packages.google_api_python_client python36Packages.dateutil -""" usage: google-muell [options] - - --esp=HOST esp8266 ip [Default: 192.168.1.23] - --client-secrets=FILE Path to client secrets file (from application) [Default: licht-kalender-secrets.json] - --credential-path=PATH Path to newly generated (or existing) credentials [Default: licht-creds.json] - --sleepval=SEC seconds to sleep [Default: 900] - -you can create the client-secrets by creating a new google application, create -oauth2 token and download it ( url here) - -""" -from docopt import docopt -from fade import calc_chain -import time -from time import sleep -import json -import sys -from datetime import datetime, timedelta -import requests - -import httplib2 -from dateutil.parser import parse -from apiclient import discovery -from oauth2client import client -from oauth2client import tools -from oauth2client.file import Storage -SCOPES = 'https://www.googleapis.com/auth/calendar.readonly' -APPLICATION_NAME = 'licht-kalender-client' - -colormap = { - "8": [ 128,128,128 ], # grey - "9": [ 0,0,0 ], # blue - "11": [ 0,0,0 ],# true red - "4": [ 0,0,0 ], # light red - "3": [ 0,0,0 ], # purple - } - -def get_creds(secrets_file,credential_path): - ''' - provide a cred_dir where the credentials would be stored to - ''' - import argparse - flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args() - - store = Storage(credential_path) - credentials = store.get() - if not credentials or credentials.invalid: - flow = client.flow_from_clientsecrets(secrets_file, SCOPES) - flow.user_agent = APPLICATION_NAME - credentials = tools.run_flow(flow, store, flags) - print('Storing new credentials to ' + credential_path) - else: - print('Using existing valid credentials ' + credential_path) - - return credentials - -def next_date(credentials): - http = credentials.authorize(httplib2.Http()) - service = discovery.build('calendar', 'v3', http=http) - - #page_token = None - #while True: - # calendar_list = service.calendarList().list( - # pageToken=page_token).execute() - # for calendar_list_entry in calendar_list['items']: - # print("{} - {}".format(calendar_list_entry['id'],calendar_list_entry['summary'])) - # page_token = calendar_list.get('nextPageToken') - # if not page_token: - # break - - - now = datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time - print('Getting the upcoming 10 events') - eventsResult = service.events().list( - calendarId='o56ig681gla2a5vupm4vgiv7tc@group.calendar.google.com', timeMin=now, maxResults=10, singleEvents=True, - orderBy='startTime').execute() - events = eventsResult.get('items', []) - for event in events: - start = parse(event['start'].get('dateTime', event['start'].get('date'))) - if 'dateTime' in event['end']: - end = parse(event['end']['dateTime']) - else: - end = parse(event['end']['date']) + timedelta(days=1) - timedelta(seconds=1) - - if start < datetime.now() < end: - print("event is active now") - print(start,end, event) - - - pass - - -def to_payload(arr): - return {"r":arr[0],"g":arr[1],"b":arr[2]} - -def main(): - args = docopt(__doc__) - client_secrets = args['--client-secrets'] - sleepval = float(args["--sleepval"]) - esp = args["--esp"] - cred_path = args["--credential-path"] - creds = get_creds(client_secrets,cred_path) - while True: - t = next_date(creds) - requests.get("http://{}/color".format(esp),params=to_payload(t)) - sleep(sleepval) - -if __name__ == "__main__": - main() diff --git a/muell.py b/muell.py deleted file mode 100755 index 3b84f02..0000000 --- a/muell.py +++ /dev/null @@ -1,62 +0,0 @@ -#! /usr/bin/env nix-shell -#! nix-shell -i python3 -p python3 python35Packages.docopt python35Packages.requests2 -""" usage: ampel [options] TIMEFILE - - --esp=HOST esp8266 ip [Default: 192.168.1.23] - --sleepval=SEC seconds to sleep [Default: 900] - -TIMEFILE refers to a json file which contains all the dates where the bus -drives - -""" -from docopt import docopt -from fade import calc_chain -import time -from time import sleep -import json -import sys -from datetime import datetime, timedelta -import requests - -# time before the day -timebefore = timedelta(hours=24) - -colors = { - "gelber_sack": [ 255,255,0 ], - "orchis": [ 45, 255, 0 ], - "papiermuell": [ 0,0,255 ], - "restmuell": [ 0, 255, 15 ], - "kehrwoche": [ 226, 96, 255 ], - "fallback": [ 66, 220, 244] -} - -def next_date(now,db): - # now = datetime.now() - for e in db: #times are sorted - name = list(e.keys())[0] - times = e[name] - for time in times: - y,m,d = [ int(i) for i in time.split("-") ] - t = datetime.now().replace(year=y,month=m,day=d, - hour=9,minute=0,second=0,microsecond=0) - if (t - timebefore) < now < t: - return name - return "fallback" - -def to_payload(arr): - return {"r":arr[0],"g":arr[1],"b":arr[2]} - -def main(): - args = docopt(__doc__) - times = json.load(open(args['TIMEFILE'])) - sleepval = float(args["--sleepval"]) - esp = args["--esp"] - while True: - now = datetime.now() - t = next_date(now,times) - print(t) - requests.get("http://{}/color".format(esp),params=to_payload(colors[t])) - sleep(sleepval) - -if __name__ == "__main__": - main() diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..cfbb372 --- /dev/null +++ b/setup.py @@ -0,0 +1,33 @@ +from setuptools import setup + +import sys + +setup( + name='ampel', + version='0.2.3', + + description='uses the ampel', + long_description=open("README.md").read(), + license='WTFPL', + url='http://localhost/', + download_url='http://localhost/', + + author='makefu', + author_email='github.com@syntax-fehler.de', + + packages=['ampel'], + entry_points={ + 'console_scripts' : [ 'ampel = ampel.ampel:main' ], + }, + install_requires= [ + 'requests','docopt','influxdb', 'paho-mqtt','pytz' + ], + classifiers=[ + "Natural Language :: English", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: Implementation :: CPython", + ], +) + diff --git a/vvs_efa/README.md b/vvs_efa/README.md deleted file mode 100644 index 0dae508..0000000 --- a/vvs_efa/README.md +++ /dev/null @@ -1,61 +0,0 @@ -##VVS API Wrapper - -This was created for easy access to the VVS EFA (Elektronische Fahrplanauskunft) in Python. - -### Example - -```python -# coding: utf-8 -import datetime as dt -from vvs_efa import VVS_EFA - -vvs_efa = VVS_EFA.EFA() -connections = vvs_efa.get_next_connections("Stadtbibliothek", "Feuersee", dt.datetime(2015, 7, 7, 7, 20), True) - - -print connections[0].origin.name -print connections[0].destination.name -print connections[0].time_of_departure.strftime("%d.%m.%Y - %H:%M") + " - " + connections[0].time_of_arrival.strftime("%d.%m.%Y - %H:%M") -print str(connections[0].fare) + "€ / " + str(connections[0].zones) + " Zone(n)" -print "" -for leg in connections[0].legs: - print leg.time_of_departure.strftime("%H:%M") + " - " + leg.time_of_arrival.strftime("%H:%M") + ": " - print leg.origin.name + " - " + leg.destination.name + " ("+ leg.line + ")" + "\n" - - -charlottenplatz = VVS_EFA.Stop("Charlottenplatz") -charlottenplatz_departures = charlottenplatz.get_next_connections(dt.datetime(2015, 7, 9, 18, 10), True) - -print charlottenplatz_departures[0].stop_id -print charlottenplatz_departures[0].stop_name -print charlottenplatz_departures[0].scheduled_datetime.strftime("%d.%m.%Y - %H:%M") -print charlottenplatz_departures[0].realtime_datetime.strftime("%d.%m.%Y - %H:%M") -print charlottenplatz_departures[0].serving_line.key -print charlottenplatz_departures[0].serving_line.number -print charlottenplatz_departures[0].serving_line.direction -print charlottenplatz_departures[0].serving_line.direction_from -print charlottenplatz_departures[0].serving_line.line_type - -``` - -results in: - -``` -Stuttgart, Stadtbibliothek -Stuttgart, Feuersee -06.07.2015 - 07:20 - 06.07.2015 - 07:31 -2.3€ / 2 Zone(n) -07:20 - 07:22: Stadtbibliothek - Hauptbf (A.-Klett-Pl.) (U12) -07:24 - 07:28: Hauptbf (Arnulf-Klett-Platz) - Stuttgart Hauptbahnhof (tief) () -07:28 - 07:31: Stuttgart Hauptbahnhof (tief) - Feuersee (S6) - -5006075 -Charlottenplatz -09.07.2015 - 18:05 -09.07.2015 - 18:11 -143 -43 -Feuersee -Killesberg -Bus -``` diff --git a/vvs_efa/VVS_EFA.py b/vvs_efa/VVS_EFA.py deleted file mode 100644 index 3a3ca3d..0000000 --- a/vvs_efa/VVS_EFA.py +++ /dev/null @@ -1,358 +0,0 @@ -# coding: utf-8 - -import datetime as dt -import requests -import pytz -class EFA(object): - - def __init__(self): - - pass - - @classmethod - def convert_name_to_id(cls, name, mobile=False): - if name.strip() != "": #check if string is empty -> return None - if mobile: - request_url = "http://m.vvs.de/jqm/controller/XSLT_STOPFINDER_REQUEST" - parameters = {} - parameters["name_sf"] = name - parameters["language"] = "de" - parameters["stateless"] = "1" - parameters["locationServerActive"] = "1" - parameters["anyObjFilter_sf"] = "0" - parameters["anyMaxSizeHitList"] = "500" - parameters["outputFormat"] = "JSON" - parameters["SpEncId"] = "0" - parameters["type_sf"] = "any" - parameters["anySigWhenPerfectNoOtherMatches"] = "1" - parameters["convertAddressesITKernel2LocationServer"] = "1" - parameters["convertCoord2LocationServer"] = "1" - parameters["convertCrossingsITKernel2LocationServer"] = "1" - parameters["convertStopsPTKernel2LocationServer"] = "1" - parameters["convertPOIsITKernel2LocationServer"] = "1" - parameters["tryToFindLocalityStops"] = "1" - parameters["w_objPrefAl"] = "12" - parameters["w_regPrefAm"] = "1" - - else: - request_url = "http://www2.vvs.de/vvs/XSLT_STOPFINDER_REQUEST" - parameters = {} - parameters["suggest_macro"] = "vvs" - parameters["name_sf"] = name - - req = requests.post(request_url, parameters) - - points = req.json()["stopFinder"]["points"] - - - best_point_index = 0 - - if len(points) > 1: - for index, point in enumerate(points): - if point["best"] == "1": - best_point_index = index - break - - return points[best_point_index]["stateless"] - - elif len(points) == 1: - return points["point"]["stateless"] #if one point found (no array to iterate!) -> directly return - - else: - return None #no points found -> return None - - else: - return None - - - def get_next_connections(self, origin, destination, datetime, departure, search_by_name = True): - - """Get connections for parameter set: - origin: name of origin - destination: name of destination - time: datetime object of departure/arrival - departure: boolean --> true: time of departure; false: time of arrival - search_by_name: boolean --> true: search by name; false: search by id""" - - if search_by_name: - id_origin = self.convert_name_to_id(origin) - id_destination = self.convert_name_to_id(destination) - if id_origin == None: - raise TypeError('Origin not valid or not found.') - if id_destination == None: - raise TypeError('Destination not valid or not found.') - - else: - id_origin = origin - id_destination = destination - - request_url = "http://m.vvs.de/jqm/controller/XSLT_TRIP_REQUEST2" - - parameters = {} - - #parameters["genC"] = "1" - #parameters["itOptionsActive"] = "1" - #parameters["locationServerActive"] = "1" - #parameters["ptOptionsActive"] = "1" - parameters["stateless"] = "1" - parameters["name_origin"] = id_origin - parameters["name_destination"] = id_destination - parameters["type_destination"] = "any" - parameters["type_origin"] = "any" - parameters["use_realtime"] = "1" - parameters["itdTime"] = datetime.strftime("%H%M") #"2105" - parameters["date"] = datetime.strftime("%Y%m%d") #"20141216" - - if departure: - parameters["itdTripDateTimeDepArr"] = "dep" - else: - parameters["itdTripDateTimeDepArr"] = "arr" - - parameters["routeType"] = "LEASTTIME" - parameters["changeSpeed"] = "normal" - - #parameters["includedMeans"] = "checkbox" #does only work when inclMOT_x set - #parameters["inclMOT_0"] = "1" - #parameters["inclMOT_1"] = "1" - #parameters["inclMOT_2"] = "1" - #parameters["inclMOT_3"] = "1" - #parameters["inclMOT_4"] = "1" - #parameters["inclMOT_5"] = "1" - #parameters["inclMOT_6"] = "1" - #parameters["inclMOT_7"] = "1" - #parameters["inclMOT_8"] = "1" - #parameters["inclMOT_9"] = "1" - #parameters["inclMOT_10"] = "1" - #parameters["inclMOT_11"] = "1" - #parameters["inclMOT_12"] = "1" - #parameters["inclMOT_13"] = "1" - #parameters["inclMOT_14"] = "1" - #parameters["inclMOT_15"] = "1" - #parameters["inclMOT_16"] = "1" - #parameters["inclMOT_17"] = "1" - - parameters["outputFormat"] = "JSON" - - #parameters["SpEncId"] = "0" - #parameters["anySigWhenPerfectNoOtherMatches"] = "1" - #parameters["convertStopsPTKernel2LocationServer"] = "1" - #parameters["convertPOIsITKernel2LocationServer"] = "1" - #parameters["verifyAnyLocViaLocServer"] = "1" - #parameters["w_objPrefAl"] = "12" - #parameters["w_regPrefAm"] = "1" - #parameters["calcOneDirection"] = "1" #if not set, first trip is last trip before date/time for departure, else first trip after date/time - #parameters["searchLimitMinutes"] = "360" - - - req = requests.post(request_url, parameters) - - data = req.json() - trips = data["trips"] - trip_objs = [] - - if trips != None: - for trip in trips: - #Trip attributes - #trip_duration = trip["duration"] - trip_fare = float(trip["itdFare"]["fares"]["fare"]["fareAdult"]) - trip_zones = abs(int(trip["itdFare"]["tariffZones"]["tariffZone"]["toPR"]) - int(trip["itdFare"]["tariffZones"]["tariffZone"]["fromPR"])) - trip_origin = Location(name = data["origin"]["points"]["point"]["name"], loc_id = data["origin"]["points"]["point"]["stateless"], loc_type = data["origin"]["points"]["point"]["anyType"]) - trip_destination = Location(name = data["destination"]["points"]["point"]["name"], loc_id = data["destination"]["points"]["point"]["stateless"], loc_type = data["destination"]["points"]["point"]["anyType"]) - - #print "Dauer: %s \nPreis: %s\n" % (trip_duration, trip_fare) - - trip_legs = [] - for leg in trip["legs"]: - origin = Location(name=leg["points"][0]["name"], loc_id=leg["points"][0]["ref"]["id"]) - destination = Location(name=leg["points"][1]["name"], loc_id=leg["points"][1]["ref"]["id"]) - - origin_realtime_date = leg["points"][0]["dateTime"]["rtDate"] #17.12.2014 - origin_realtime_time = leg["points"][0]["dateTime"]["rtTime"] #16:35 - - destination_realtime_date = leg["points"][1]["dateTime"]["rtDate"] - destination_realtime_time = leg["points"][1]["dateTime"]["rtTime"] - berlin = pytz.timezone('Europe/Berlin') - origin_departure_real_datetime = berlin.localize( - dt.datetime.strptime(origin_realtime_date + "-" + - origin_realtime_time, - "%d.%m.%Y-%H:%M")).replace(tzinfo=None) - destination_arrival_real_datetime = berlin.localize( - dt.datetime.strptime(destination_realtime_date + "-" + - destination_realtime_time, - "%d.%m.%Y-%H:%M")).replace(tzinfo=None) - - duration = leg["timeMinute"] - mode = leg["mode"]["product"] - line = leg["mode"]["number"] - direction = leg["mode"]["destination"] - - l = Leg(origin, destination, origin_departure_real_datetime, destination_arrival_real_datetime, mode, line, direction) - - trip_legs.append(l) - - #print "%s-%s: (%s min)\n %s - %s" %(origin_departure_real_time, destination_arrival_real_time, duration, origin, destination) - - - trip_time_of_departure = trip_legs[0].time_of_departure - trip_time_of_arrival = trip_legs[-1].time_of_arrival - - trip_obj = Trip(trip_origin, trip_destination, trip_time_of_departure, trip_time_of_arrival, trip_legs, trip_fare, trip_zones) - trip_objs.append(trip_obj) - - else: - raise ValueError("No trips found") - - - return trip_objs - - -class Trip(object): - - def __init__(self, origin, destination, time_of_departure, time_of_arrival, legs, fare, zones): - """origin: location object of origin - destination: location object of destination - time_of_departure: datetime object of trip departure time / date - time_of_arrival: datetime object of trip arrival time / date - legs: list of Leg objects - fare: fare of trip (float) - zones: number of zones travelled (int)""" - - self.origin = origin - self.destination = destination - self.time_of_departure = time_of_departure - self.time_of_arrival = time_of_arrival - self.legs = legs - self.fare = fare - self.zones = zones - - - -class Leg(object): - - def __init__(self, origin, destination, time_of_departure, time_of_arrival, mode, line, direction): - """origin: leg origin (station / address / etc.) - destination: leg destination (station / address / etc.) - time_of_departure: departure datetime object - time_of_arrival: arrival datetime object - mode: mode of transportation (U-Bahn / S-Bahn / Bus / Walking) - line: U-Bahn / S-Bahn / Bus Line - direction: ulitmate destination of U-Bahn / S-Bahn / Bus Line""" - - self.origin = origin - self.destination = destination - self.time_of_departure = time_of_departure - self.time_of_arrival = time_of_arrival - self.mode = mode - self.line = line - self.direction = direction - - -class Location(object): - - def __init__(self, name, loc_id, loc_type="any"): - """type: type of location (station / address / etc.) - name: full name of location - id: id of location""" - - self.loc_type = loc_type - self.name = name - self.loc_id = loc_id - - -class Stop(object): - - def __init__(self, name): - self.id = VVS_EFA.convert_name_to_id(name) - if self.id == None: - raise TypeError("Station could not be found.") - - def get_next_connections(self, datetime, departure, limit=20): - - """datetime: datetime object of time & date - departure: boolean, true -> time of departure, false --> time of arrival - limit: int, limit of results fetched, default: 20""" - - if self.id != None: - - parameters = {} - - parameters["deleteAssignedStops_dm"] = "1" - parameters["itOptionsActive"] = "1" - parameters["limit"] = str(limit) - parameters["locationServerActive"] = "1" - parameters["mode"] = "direct" - parameters["name_dm"] = self.id - parameters["ptOptionsActive"] = "1" - parameters["stateless"] = "1" - parameters["type_dm"] = "stop" - parameters["useAllStops"] = "1" - parameters["useRealtime"] = "1" - parameters["itdTime"] = datetime.strftime("%H%M") - parameters["itdDate"] = datetime.strftime("%Y%m%d") - - if departure: - parameters["itdTripDateTimeDepArr"] = "dep" - else: - parameters["itdTripDateTimeDepArr"] = "arr" - - parameters["outputFormat"] = "JSON" - parameters["SpEncId"] = "0" - parameters["anySigWhenPerfectNoOtherMatches"] = "1" - parameters["convertStopsPTKernel2LocationServer"] = "1" - parameters["convertPOIsITKernel2LocationServer"] = "1" - parameters["verifyAnyLocViaLocServer"] = "1" - parameters["w_objPrefAl"] = "12" - parameters["w_regPrefAm"] = "1" - - request_url = "http://m.vvs.de/jqm/controller/XSLT_DM_REQUEST" - req = requests.post(request_url, parameters) - data = req.json() - - departure_list = data["departureList"] - connections = [] - for list_entry in departure_list: - serving_line_data = list_entry["servingLine"] - serving_line = ServingLine(serving_line_data["key"], serving_line_data["number"], serving_line_data["direction"], - serving_line_data["directionFrom"], serving_line_data["name"]) - - stop_id = list_entry["stopID"] - stop_name = list_entry["stopName"] - scheduled_datetime = dt.datetime(int(list_entry["dateTime"]["year"]), int(list_entry["dateTime"]["month"]), - int(list_entry["dateTime"]["day"]), int(list_entry["dateTime"]["hour"]), int(list_entry["dateTime"]["minute"])) - - try: #check if realtime info available - realtime_datetime = dt.datetime(int(list_entry["realDateTime"]["year"]), int(list_entry["realDateTime"]["month"]), - int(list_entry["realDateTime"]["day"]), int(list_entry["realDateTime"]["hour"]), int(list_entry["realDateTime"]["minute"])) - - except: #if not: return None for realtime_datetime - realtime_datetime = None - - connection = Connection(stop_id, stop_name, scheduled_datetime, realtime_datetime, serving_line) - connections.append(connection) - - return connections - - else: - return None - - - -class Connection(object): - """docstring for Connection""" - def __init__(self, stop_id, stop_name, scheduled_datetime, realtime_datetime, serving_line): - """realtime_datetime: datetime object of projected departure/arrival. None if not available""" - self.stop_id = stop_id - self.stop_name = stop_name - self.scheduled_datetime = scheduled_datetime - self.realtime_datetime = realtime_datetime - self.serving_line = serving_line - - -class ServingLine(object): - """docstring for ServingLine""" - def __init__(self, key, number, direction, direction_from, line_type): - self.key = key - self.number = number - self.direction = direction - self.direction_from = direction_from - self.line_type = line_type diff --git a/vvs_efa/__init__.py b/vvs_efa/__init__.py deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3