Hi all,
I’ve managed to integrate my local Public Transport in Germany (Bremen) through the OpenTripPlanner and API from the provider (VBN). This small tutorial should then work with small changes for any OpenTripPlanner Public Transport Entity.
My script filters all departures from your stop for certain methods and calculates the departure time in minutes. It gives the next 3 departures in a certain direction.
What you need:
- HABApp installed (e.g. through the openhabian menu option)
- python requests and pandas packages installed in the HABApp python virtual environment (tutorial below)
- URL to your OpenTripPlanner API provider
- Token for your OpenTripPlanner API provider
- Find your stop id (for me it is 1:000009014003) by doing a simple GET request to the connection API (see below)
Here is the code for otp_departures.py
#!/usr/bin/env python3
import datetime
import time
import requests
import json
from pandas import json_normalize
import pandas as pd
import HABApp
from HABApp.core.items import Item
class otp_departures(HABApp.Rule):
def __init__(self):
super().__init__()
# Run every minute
self.run_minutely(self.get_departure_times)
# The item the output will be sent to
self.output = HABApp.openhab.items.StringItem.get_item('Next3Trams')
def get_departure_times(self):
# VBN API Documentation
# https://www.vbn.de/service/entwicklerinfos/
# example request to VBN API for a full connection, use this to find your stop ID
# r=requests.get("http://gtfsr.vbn.de/api/routers/connect/plan?arriveBy=false&date=03-09-2021&fromPlace=53.xxxxxx,8.yyyyyy&toPlace=53.xxxxxx,8.yyyyyy&time=13:00:00&mode=WALK,TRANSIT&maxWalkDistance=300", headers={"Authorization":"YOURTOKEN","Host":"gtfsr.vbn.de"})
# print(r.content)
# OTP documentation
# http://dev.opentripplanner.org/apidoc/1.4.0/resource_IndexAPI.html#resource_IndexAPI_getStoptimesForStop_GET
# http://docs.opentripplanner.org/en/latest/Basic-Tutorial/
# My Stop: "Bremen Kirchweg","stopId":"1:000009014003"
# URL to get stop times: /otp/routers/{routerId}/index/stops/{stopId}/stoptimes
# Authorization to API: headers={"Authorization":"YOURTOKEN","Host":"gtfsr.vbn.de"})
# make the GET request
r=requests.get("http://gtfsr.vbn.de/api/routers/connect/index/stops/1:000009014003/stoptimes?detail=true&timeRange=7200&numberOfDepartures=20", headers={"Authorization":"YOURTOKEN"})
# convert to json object
json_obj = json.loads(r.content.decode('utf-8'))
# normalize json
df = json_normalize(json_obj,['times'])
# Filter out the unwanted destinations
df = df.query('headsign not in ["Arsten", "BSAG", "Huckelriede"]').reset_index()
# get current time
now = datetime.datetime.now()
# get time difference to UTC
diff = datetime.datetime.now() - datetime.datetime.utcnow()
# create column for departure time as readable string
df['departureTimeDT'] = pd.to_datetime(df['serviceDay']+df['realtimeDeparture'],unit='s')+diff
# sort entries by realtime arrival time (provided in epoch format)
df = df.sort_values(by=['departureTimeDT']).reset_index()
# optional: only keep next X departures
# df = df.iloc[:3]
# create column for departure time in HH:MM format
df['depTimeHHMM'] = df['departureTimeDT'].dt.strftime('%H:%M')
# create column for departure time in minutes from now
df['depInMin'] = ((df['departureTimeDT'] - now).dt.seconds/60).astype(int)
# drop unnecessary columns
df = df[['headsign','departureTimeDT','depTimeHHMM','depInMin']]
# create the string with next 3 departures, e.g. "1-11-21"
next3in1string = (str(df['depInMin'][0]) + "-" + str(df['depInMin'][1]) + "-" + str(df['depInMin'][2]))
#print(next3in1string)
# optional: create JSON of the remaining
#dfout = df.to_json(orient='index',date_format='iso')
#print(dfout)
#return next3in1string
# send the output to OH
self.output.oh_send_command(next3in1string)
otp_departures()
How to install packages in HABApp:
Make sure the HABApp venv directory is writable:
/opt/habapp $ ls -l
should say:
total 20
drwxrwxrwx 2 root root 4096 Feb 1 16:23 bin
drwxrwxrwx 2 root root 4096 Feb 1 16:22 include
drwxrwxrwx 3 root root 4096 Feb 1 16:22 lib
-rwxrwxrwx 1 root root 69 Mar 9 13:54 pyvenv.cfg
drwxrwxrwx 3 root root 4096 Feb 1 16:22 share
in case not, perform:
sudo chmod -R u=rwx,g=rwx,o=rwx /opt/habapp/
Then:
sudo systemctl stop habapp.service
cd /opt/habapp
source bin/activate
pip install requests
pip install pandas
deactivate
sudo systemctl restart habapp.service
Now you should be set!
I’m open to see your improvements and ideas or solutions for other providers!