Live STIB-MIVB departures on the Pebble Time 2. It covers the bus, tram, and metro network of Brussels
README.md

Stibble

stibble-server #

This is the backend for the Stibble watch app. The app is on the Pebble appstore. The server fetches STIB-MIVB open data from the Belgian Mobility Company (BMC) API. It keeps the data in a cache. It answers the watch with three source boards, one each for transit, trains, and Villo. The server provides live vehicle positions and disruption notices for each line. The trains board carries SNCB departures from every station within a mile through iRail. The Villo board carries bike station counts for every stand within 500 metres. Each search hit can carry a direction: the terminus name of the line at that stop. Each line detail can carry a route shape: a simplified list of points for the line on the map. The stop search forgives spelling: it folds accents and collapses doubled letters, so "hermann" finds HERRMANN-DEBROUX.

Endpoints #

  • GET /v1/transit?lat&lon&n: the board of the nearest transit stops
  • GET /v1/trains?lat&lon: the board of SNCB stations within a mile
  • GET /v1/villo?lat&lon: the board of Villo stands within 500 metres
  • GET /v1/stops/board?ids=: the standard transit board for up to 24 explicitly selected stop ids, at distance 0, ordered by next departure; unknown ids are skipped
  • GET /v1/line?line=ID&to=ID: the vehicle route strip and arrival times for a line at a stop
  • GET /v1/stops/search?q=: stop search for the settings page
  • GET /config: the phone settings page
  • GET /healthz: storage, feed, pool, file, and maintenance health
  • GET /readyz: readiness after the current schema and BMC static projection are available

Run your own server #

You need a BMC partner key. Register on the STIB-MIVB open data portal and request a key for the Standard plan. Choose a durable, writable directory for the database, locate the SpatiaLite loadable extension, then start the server:

export BMC_PARTNER_KEY=your-key-here
export STIBBLE_DB=/var/lib/stibble/stibble.sqlite
export SPATIALITE_EXTENSION=/path/to/mod_spatialite.so
cargo run --bin stibble-server

The server listens on 0.0.0.0:8080 by default. Point the Stibble app at your server through the phone settings page.

For local API work, cargo run --bin mock_server opens the same file-backed store and serves the production router without provider credentials or provider HTTP workers. It fills only missing required feed heads and per-station train snapshots; reusing a complete STIBBLE_DB does not duplicate existing mock history.

Environment #

  • BMC_PARTNER_KEY: required by the production server
  • BMC_BASE: optional, the keyed production gateway by default
  • STIBBLE_DB: optional, /data/stibble.sqlite by default in production and /tmp/stibble-mock.sqlite in the mock server
  • SPATIALITE_EXTENSION: required, the path to the loadable SpatiaLite extension
  • BIND_ADDR: optional, 0.0.0.0:8080 by default

Storage operations #

SQLite is the authoritative store. It uses WAL mode with full synchronous writes. The database, ${STIBBLE_DB}-wal, and ${STIBBLE_DB}-shm live in the same directory; keep that directory on persistent writable storage and treat those files as one live database.

GET /readyz returns 200 only when the current schema and a committed BMC static projection are available. A restart can therefore become ready from committed data while providers are unavailable. GET /healthz reports readiness, schema and pool state, database and WAL bytes, the current snapshot and age of every feed, provider/parse/commit failures, and maintenance timestamps.

Maintenance runs on startup and then hourly. It removes raw snapshots strictly older than 7 days and derived facts strictly older than 90 days while preserving current provider heads and projections. It also checkpoints the WAL and makes freed pages reusable through incremental vacuum.

This repository configures no off-host backup, replica, automatic failover, or disaster recovery. WAL protects committed data from process failure; loss of the host or persistent volume loses the database.

Quota #

The server obeys the BMC Standard plan by itself. Not more than 500 upstream requests per minute leave this process. Not more than 12000 upstream requests per day leave this process. This protects your key.

Build #

cargo test
cargo run --bin stibble-server
nix build .#default
nix build .#oci

The first command runs the test suite. The second command starts a local server. The last two commands build a binary and a container image for podman.

Source: STIB-MIVB, Open Data (CC BY 4.0)