Verified TransJakarta realtime stack: anonymous MQTT bus feed (wss://mqtt.tj.co.id:8084/mqtt), guest REST API (tijeapi.transjakarta.co.id), official GTFS. Cross-capture verification vs third-party tracker, connection recipes, snapshot tool.
2 KiB
2 KiB
Methodology — how this was verified
Repeatable procedure (executed Oct 11–12, 2026). Tools: curl, node (packages ws, mqtt), jq.
Steps
- Map the target: fetch the site's HTML + JS bundles with curl; read the CSP header (
connect-srcnames allowed WebSocket endpoints); grep bundles for protocol strings → found oyenza's own WS (/api/live) and its message types (hello/feed/snap/delta). - Find static-data citations:
static.jsonreferenced the official GTFS zip URL → static layer source identified. - Find the upstream: search GitHub for projects in the same ecosystem (
tj-live,open-tj) → they document the REST + MQTT + GTFS stack. - Simultaneous cross-capture:
oyenza-ws.mjs— WS client onwss://transit.oyenza.com/api/livemqtt-cap.mjs/mqtt-long.mjs— MQTT client onwss://mqtt.tj.co.id:8084/mqtt, subscribing/mobile_armada/#- Analysis with
compare.mjs/compare2.mjs(ID sets, field agreement, position deltas),seg1.mjs(topic segments),mqtt-rate.mjs(rate profile).
- Decode the topic grid: four
POST /v1/busprobes at ±0.1° offsets → index-shift mapping (≈0.01°/unit). - Cadence check: re-connect to oyenza's WS and record delta intervals (
oy2.mjs) → exactly ~3.00 s.
Key results
- 1,794 common buses; 100% trip/route ID match; median position delta 8.9 m; p90 42 m; 97.8% fleet overlap (75 s window).
- Broker: ~2,000+ retained messages instantly on subscribe; per-bus refresh ~8–75 s in samples.
- oyenza deltas: 3000–3013 ms gaps, ~1,000 position records each.
Artifacts
- All scripts + raw captures archived at
workspace/transjakarta-live-captures/(4.6 MB): oyenza page + bundles, oyenza WS captures, MQTT captures, comparison outputs, rate profiles, tije REST responses (guest token redacted). - Scratch copies live under
~/.hermes/profiles/research/cache/scratch/oyenza/(auto-pruned after ~24 h idle — use the archive instead). - Reusable snapshot tool: transjakarta-live-data/scripts/tj-snapshot.mjs