126 lines
4.2 KiB
Markdown
126 lines
4.2 KiB
Markdown
# Ö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.
|
||
|
||
```bash
|
||
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:
|
||
```js
|
||
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.
|