Files
time_to_leave/README.md
T
2026-05-09 09:30:52 +02:00

4.2 KiB
Raw Blame History

ÖBB Train Planner

Checks the ÖBB real-time schedule, picks the best train for your upcoming calendar events, and shows a live "leave by" countdown from your current location.

What's included

oebb-planner/
├── server/
│   ├── index.js        ← Node.js proxy server (ÖBB API + ICS parser)
│   └── package.json
├── oebb-planner.jsx    ← React front-end (use in Claude.ai artifacts or any React app)
└── README.md

Quick start

1 — Start the proxy server

The server bypasses ÖBB's CORS restrictions and parses ICS calendar files.

cd server
npm install
npm start
# → ÖBB Planner API running on http://localhost:3001

Requires Node.js ≥ 18 (uses built-in fetch and AbortSignal.timeout).
For development with auto-reload: npm run dev

2 — Open the React app

Paste oebb-planner.jsx into a Claude.ai artifact (or your own React app).
The app detects whether the server is online and shows a status indicator in the header.


Calendar integration

The app reads any standard ICS calendar. Only events that have a location field and fall within the next 14 days are imported.

Option A — ICS URL (Google Calendar, Outlook, Fastmail…)

  1. In the app, open the Calendar panel → ICS URL tab
  2. Paste your calendar's secret ICS address

Google Calendar:
Settings → click your calendar → scroll to "Secret address in iCal format" → copy the URL

Apple Calendar (iCloud):
Calendar app → right-click calendar → "Share Calendar" → enable public calendar → copy the URL
(change webcal:// to https:// or paste as-is — the server handles both)

Outlook:
Settings → View all Outlook settings → Calendar → Shared calendars → Publish → ICS link

Option B — Upload .ics file

Export your calendar as a .ics file from any app (File → Export in Apple Calendar, etc.) and upload it via the Upload File tab.


How the train matching works

  1. Your current GPS location is used to find the nearest ÖBB station (via the HAFAS LocGeoPos API).
  2. Each event's location field is used to search for the nearest destination station (LocMatch).
  3. The HAFAS TripSearch endpoint finds journeys departing up to 2 hours before your event.
  4. The "leave by" time = next catchable train departure 12 minutes (default walk time to station).
  5. Data refreshes automatically every 60 seconds.

Server endpoints

Method Path Description
POST /api/hafas Proxy to fahrplan.oebb.at/bin/mgate.exe
GET /api/calendar?url=<ics_url> Fetch & parse a remote ICS calendar
POST /api/calendar/parse Parse raw ICS content sent in request body
GET /api/health Liveness check

Customisation

Variable Location Default Description
WALK_MINS oebb-planner.jsx 12 Walk time from your location to origin station
PORT server/index.js 3001 Server port
horizonDays server/index.js 14 How far ahead to look for calendar events
PROXY oebb-planner.jsx http://localhost:3001 Server URL

Deploying beyond localhost

To run this on a server or share it with others:

  1. Set PORT via environment variable: PORT=8080 npm start
  2. Update PROXY in oebb-planner.jsx to your server's URL
  3. Restrict CORS in server/index.js if needed:
    app.use(cors({ origin: "https://your-app.example.com" }));
    

Troubleshooting

"Server offline" shown in the app
→ Make sure npm start is running in the server/ directory.

No trains found for an event
→ Check that the destination in your calendar event is a recognisable ÖBB station name
(e.g. "Graz Hbf", "Salzburg Hauptbahnhof"). Verbose postal addresses are trimmed automatically.

Calendar import returns 0 events
→ Only events with a LOCATION field set are imported. Make sure your events have a location
and fall within the next 14 days.

ÖBB returns errors
→ The HAFAS API occasionally changes. Check fahrplan.oebb.at is reachable from your server.