Real-time Norwegian public transport departures using Entur's API. Built for a physical SSD1322 256x64 OLED display powered by a Raspberry Pi Zero 2 W, with support for a web interface that can be embedded in Home Assistant or any browser.
- Real-time departures for multiple stops (trams, buses, trains, ferries, airports etc.)
- Delay detection with visual indicators
- Clean, minimalist display design
- Web interface for browsers and iFrames
- Hardware OLED support for physical displays
Perfect for testing API or embedding in dashboards like Home Assistant.
# Configure your stops
cp config/config.template.json config/config.json
# Start the web server
cd web && python3 -m http.server 8080Open http://localhost:8080 in your browser.
This will require soldering, wiring knowledge and is not plug and play.
For physical hardware setup, see the OLED Setup Guide.
Quick version:
# Enable SPI on Raspberry Pi
sudo raspi-config # Interface Options → SPI → Yes
# Install dependencies
python3 -m venv oled-env
source oled-env/bin/activate
pip install requests Pillow luma.oled luma.core smbus2
# Run the display
python3 oled.pyTest OLED graphics on your development machine using the emulator.
python3 -m venv oled-env
source oled-env/bin/activate
pip install requests Pillow luma.emulator
python3 oled.pyOn Python 3.14 there is no pygame wheel yet, so pip builds it without SDL_image and the emulator fails to load its PNGs (File is not a Windows BMP file). Swap it for the community fork: pip uninstall pygame && pip install pygame-ce.
Copy the template and edit config/config.json:
cp config/config.template.json config/config.jsonBasic configuration:
{
"stops": [
{
"id": "NSR:StopPlace:12345",
"name": "StopName",
"type": "tram",
"description": "Main tram stop"
}
],
"api": {
"clientName": "your-client-name",
"timeout": 10
},
"settings": {
"numberOfDepartures": 3,
"refreshInterval": 30000,
"timezone": "Europe/Oslo"
},
"display": {
"maxRows": 3,
"showRealtime": true,
"showDelayIndicator": true
}
}See config.template.json for all available options and descriptions.
- Visit Entur's stop place search
- Search for your stop
- Copy the
NSR:StopPlaceID from the URL or stop details
- Display: SSD1322 256x64 OLED (grayscale)
- Computer: Raspberry Pi Zero 2 W (or any Pi with GPIO)
- Interface: 4-wire SPI
For complete hardware setup, wiring diagrams, and troubleshooting, see:
- OLED Setup Guide - Hardware preparation and software installation
- Wiring Guide - Pin connections and SPI configuration
Add to your dashboard configuration:
type: iframe
url: http://<raspberry-pi-ip>:8080
aspect_ratio: 100%To run the OLED display on boot, create /etc/systemd/system/departure-board.service:
[Unit]
Description=Departure Board OLED Display
After=network-online.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/departure-board
ExecStart=/home/pi/departure-board/oled-env/bin/python3 /home/pi/departure-board/oled.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable departure-board
sudo systemctl start departure-board- Python 3.10+
- Python packages:
requests- API callsPillow- Image renderingluma.oled+luma.core- OLED display driver (hardware)luma.emulator- Display emulator (development)smbus2- I²C support (hardware)