Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
![](assets/full-logo.png)

**A replica, near real-time, miniature UK railway station train departure sign based upon a Raspberry Pi Zero and 256x64 SPI OLED display(s). Uses the publicly available [OpenLDBWS API by National Rail Enquiries](https://www.nationalrail.co.uk/).**
**A replica, near real-time, miniature UK railway station train departure sign based upon a Raspberry Pi Zero and 256x64 SPI OLED display(s). Uses the publicly available [OpenLDBWS API by National Rail Enquiries](https://www.nationalrail.co.uk/) and the [TfL Unified API](https://api.tfl.gov.uk/) for London Underground / DLR arrivals.**

## Highlights

- **See local departures**: Display the depatures from your local station at home for up to date train information.
- **London Underground & DLR**: Switch to `tube` mode to show live TfL arrivals — no API key required.
- **3D-printable cases**: Print your own miniature case to keep everything tidy - both desktop and 'hanging' style available.
- **Dual display support**: Run two displays each showing departures from different platforms from a single Raspberry Pi.

Expand Down
4 changes: 4 additions & 0 deletions balena.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,15 @@ data:
- raspberrypi3
applicationEnvironmentVariables:
- TZ: Europe/London
- mode: nationalrail
- departureStation: PAD
- outOfHoursName: London Paddington
- numericPlatformsOnly: false
- refreshTime: 120
- apiKey: UPDATE_ME
- tflAppKey: null
- tubeLine: null
- tubeDirection: null
- operatingHours: 8-22
- screenBlankHours: 1-6
- screenRotation: 2
Expand Down
2 changes: 1 addition & 1 deletion docs/01-getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ This project is designed to run using a Raspberry Pi Zero W or Zero 2 W and ther

- Software to flash an SD card ([balenaEtcher](https://balena.io/etcher))
- A free [balenaCloud](https://balena.io/cloud) account
- A free [National Rail Enquiries OpenLDBWS API](http://realtime.nationalrail.co.uk/OpenLDBWSRegistration) account
- A free [National Rail Enquiries OpenLDBWS API](http://realtime.nationalrail.co.uk/OpenLDBWSRegistration) account (only needed for National Rail departures; not required if you only want London Underground / DLR arrivals)
- (optional) A download of this project
- (optional) The [balena CLI tools](https://github.com/balena-io/balena-cli/blob/master/INSTALL.md)

Expand Down
26 changes: 24 additions & 2 deletions docs/04-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ These environment variables are specified using the [balenaCloud dashboard](http

| Key | Example Value
|----------------------------------|----------
|`apiKey` **(REQUIRED)** | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` (OpenLDBWS API key)
|`apiKey` **(REQUIRED for National Rail)** | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` (OpenLDBWS API key)
|`mode` | `nationalrail` (default) for National Rail departures, or `tube` for live London Underground / DLR arrivals from the TfL Unified API
|`TZ` | `Europe/London`, will default to UTC if not set ([timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones))
|`departureStation` | `PAD` ([station code](https://www.nationalrail.co.uk/stations_destinations/48541.aspx))
|`departureStation` | `PAD` ([station code](https://www.nationalrail.co.uk/stations_destinations/48541.aspx)) in National Rail mode, or a TfL StopPoint / Naptan id such as `940GZZLUKSX` in tube mode
|`destinationStation` | `HWV` ([station code](https://www.nationalrail.co.uk/stations_destinations/48541.aspx)) [optional] Filters trains shown to only those that call at this station. This can be multiple stations seperated by a comma. eg. PAD, KGX, STP
|`timeOffset` | `5` [optional] (Time offset, in minutes, for the departure board. Can be used to see into the future (positive value) or past (negative value). Set 5 if you live 5 min from the station and want to hide departures that are too soon to catch)
|`refreshTime` | `120` (seconds between data refresh)
Expand All @@ -31,6 +32,27 @@ These environment variables are specified using the [balenaCloud dashboard](http
| `targetFPS` | `20` (Frame rate regulator FPS target; 0 disables the regulator, which will increase FPS on constrained CPU, but will run the CPU hot at 100%.)
| `debug` | `False` (Display debugging information; `True` shows the debug info permanently, any integer `>1` will show instead of the splash screen for that number of seconds)

## London Underground / DLR (tube mode)

Set `mode` to `tube` to show live London Underground, DLR, London Overground and Elizabeth line arrivals from the free [TfL Unified API](https://api.tfl.gov.uk/) instead of National Rail departures. The `apiKey` is not required in this mode.

| Key | Example Value
|-----|----------
| `mode` | `tube`
| `departureStation` | `940GZZLUKSX` (a TfL StopPoint / Naptan id; look one up via the [TfL StopPoint search](https://api.tfl.gov.uk/StopPoint/Search/King%27s%20Cross))
| `tflAppKey` | `xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` [optional] a TfL application key, which raises the API rate limits. Not required, but recommended for always-on displays
| `tubeLine` | `Northern` [optional] restricts the board to a single line, since a station can serve several. The value matches the TfL line name, so it also works for DLR (`DLR`), the Elizabeth line (`Elizabeth line`) and the newer named Overground lines (`Mildmay`, `Windrush`, `Lioness`, `Suffragette`, `Weaver`, `Liberty`)
| `tubeDirection` | `southbound` [optional] restricts the board to a single direction. Accepts the TfL direction (`inbound` / `outbound`) or a compass word (`westbound` / `eastbound` / `northbound` / `southbound`). For example, at Camden Town (`940GZZLUCTN`) on the `Northern` line, `southbound` shows both branches interleaved by arrival time — trains towards `Morden via Bank` alongside `Kennington via CX` and `Battersea via CX` (CX = Charing Cross)

Notes for tube mode:

- TfL provides live arrival predictions rather than a fixed timetable, so departures are ordered by how soon each train arrives and all services show as `On time`.
- The Underground does not expose downstream calling points, so the scrolling line beneath the first departure shows its platform and live train location instead (e.g. "Southbound - Platform 2 -- Between Camden Town and Euston").
- **Branch lines** (e.g. Northern, District, Metropolitan): both branches are shown interleaved in arrival order and are told apart by their destination text (e.g. "Morden via Bank" vs "Morden via Charing Cross"). Leave `tubeDirection` set to a single value to keep both branches.
- **DLR, London Overground and the Elizabeth line**: their platforms are not labelled with a compass direction (you'll see `Platform 1`, `Platform Unknown` etc.), so a compass `tubeDirection` such as `southbound` will match nothing and leave the board blank. Use `inbound` / `outbound` instead, or leave `tubeDirection` blank. For example, Acton Central (`910GACTNCTL`) on the `Mildmay` line reports `Platform 1` / `Platform 2` with `outbound` trains towards Richmond and `inbound` trains towards Willesden Junction.
- **Circle line** (and other loop / terminating services): TfL often reports no direction at all for these, so any `tubeDirection` filter will hide them. Leave `tubeDirection` blank on the Circle line.
- `destinationStation` filtering and `timeOffset` only apply to National Rail mode.

If using two screens the following line needs to be added into /boot/config.txt which is achieved by using the 'Define DT overlays' option within the Device configuration screen on balenaCloud: `spi1-3cs`

![](images/overlays.png)
Expand Down
14 changes: 13 additions & 1 deletion src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ def loadConfig():
data["firstDepartureBold"] = False
data["hoursPattern"] = re.compile("^((2[0-3]|[0-1]?[0-9])-(2[0-3]|[0-1]?[0-9]))$")

# data source mode: "nationalrail" (default) or "tube" (TfL Underground/DLR live arrivals)
data["mode"] = (os.getenv("mode") or "nationalrail").strip().lower()

data["journey"]["departureStation"] = os.getenv("departureStation") or "PAD"

data["journey"]["destinationStation"] = os.getenv("destinationStation") or ""
Expand All @@ -58,8 +61,17 @@ def loadConfig():
data["journey"]["screen1Platform"] = parsePlatformData(os.getenv("screen1Platform"))
data["journey"]["screen2Platform"] = parsePlatformData(os.getenv("screen2Platform"))
data["journey"]["numericPlatformsOnly"] = os.getenv("numericPlatformsOnly", "False").lower() == "true"


# optional: restrict tube mode to a single line (e.g. "Victoria"), as a stop can serve several
data["journey"]["tubeLine"] = os.getenv("tubeLine") or ""

# optional: restrict tube mode to one direction. Accepts the TfL direction
# ("inbound"/"outbound") or a compass word ("westbound"/"eastbound"/etc.)
data["journey"]["tubeDirection"] = os.getenv("tubeDirection") or ""

data["api"]["apiKey"] = os.getenv("apiKey") or None
# optional TfL application key (raises rate limits in tube mode; not required)
data["api"]["tflAppKey"] = os.getenv("tflAppKey") or None
data["api"]["operatingHours"] = os.getenv("operatingHours") or ""

data["showDepartureNumbers"] = False
Expand Down
Loading