Skip to content

A European timetable in your console

Sysadmin Python

If you want a properly geeky departure board for your train connections — on your own terminal, or on a wallboard at an event — you can have one in two commands.

This post is from 2013. fahrplan is a thin client over the public transport.opendata.ch API and has seen little development since; the API itself is unofficial and its response format has changed over the years. Note also that pip install into the system Python is refused on current distributions — use pipx or a virtual environment, as below.

fahrplan

The fahrplan command line tool queries the timetable API of the Swiss national railway company. Despite the name and the source, it is not limited to Switzerland: the SBB timetable covers a large part of the European network, so international connections work just as well.

Install it into a virtual environment, or with pipx so it lands on your PATH without touching the system Python:

pipx install fahrplan

fahrplan -h lists all options. The -f flag prints the full connection with every leg and change:

fahrplan -f from hamburg dammtor to ostermundigen
#  | Station                        | Platform | Date          | Time  | Duration |
-----------------------------------------------------------------------------------
1  | Hamburg Dammtor                | 4        | Mon, 30.12.13 | 20:05 | 12:11    |
   | Basel SBB                      | 5        | Tue, 31.12.13 | 06:47 |          |
   | ------------------------------ | -------- | ------------- | ----- |          |
   | Basel SBB                      | 6        | Tue, 31.12.13 | 06:59 |          |
   | Bern                           | 4        | Tue, 31.12.13 | 07:56 |          |
   | ------------------------------ | -------- | ------------- | ----- |          |
   | Bern                           | 3        | Tue, 31.12.13 | 08:12 |          |
   | Ostermundigen                  | 2        | Tue, 31.12.13 | 08:16 |          |

Turning It into a Board

watch re-runs the command on an interval and keeps the result on screen. Every 500 seconds:

watch -n 500 fahrplan from hamburg dammtor to ostermundigen

For a board people actually read departures off, something closer to a minute is more useful. Be considerate with the interval — it is a free API behind this.

Or Query the API Directly

If the tool no longer gives you what you need, there is not much to it: the API answers plain JSON, and jq can shape it into whatever your board should show.

curl -s 'https://transport.opendata.ch/v1/connections?from=Hamburg%20Dammtor&to=Ostermundigen' \
  | jq -r '.connections[] | "\(.from.departure[11:16]) → \(.to.arrival[11:16])  \(.duration)"'

Wrap that in watch the same way and you have a departure board with no dependencies beyond curl and jq.