Productivity
tabussen
Västerbotten & Umeå public transport trip planner.
---
name: tabussen
description: Västerbotten & Umeå public transport trip planner (Tabussen/Ultra). Plans bus journeys using ResRobot API. Supports stops, addresses, coordinates, regional and local routes throughout Västerbotten county.
license: MIT
compatibility: Requires curl, jq. Works with Claude Code and compatible agents.
metadata:
author: simskii
version: "1.0.0"
region: sweden-vasterbotten
---
# Tabussen Trip Planner
Plan public transport journeys in Västerbotten, Sweden - including Umeå local traffic (Ultra) and regional routes (Länstrafiken Västerbotten).
## Overview
This skill uses the **ResRobot API** (Trafiklab) to provide journey planning for Tabussen/Ultra. ResRobot is Sweden's national public transport API covering all operators including Länstrafiken Västerbotten.
**Coverage:**
- Ultra (Umeå local bus traffic)
- Länstrafiken Västerbotten (regional buses)
- Connections to/from other Swedish regions
- Train connections where applicable
## Commands
### 1. Search Location
Search for stops, stations, or points of interest.
```bash
./search-location.sh <query> [limit]
```
| Argument | Description |
|----------|-------------|
| `query` | Location name to search for (append `?` for fuzzy search) |
| `limit` | Number of results to show (default: 5, max: 10) |
**Output includes:**
- `ID` - The stop identifier (use this in journey search)
- `Name` - Official name of the stop
- `Coordinates` - Latitude, longitude
- `Weight` - Traffic volume indicator (higher = more traffic)
**Search tips:**
- Use `?` suffix for fuzzy/partial matching: `"Vasaplan?"`
- Exact search without `?`: `"Vasaplan"`
- Include municipality for precision: `"Umeå Vasaplan"`
### 2. Journey Search
Plan a journey between two locations using their IDs.
```bash
./journey.sh <from-id> <to-id> [datetime] [mode]
```
| Argument | Description |
|----------|-------------|
| `from-id` | Origin stop ID (from search) |
| `to-id` | Destination stop ID |
| `datetime` | Optional: `"18:30"`, `"tomorrow 09:00"`, `"2026-01-28 14:00"` |
| `mode` | Optional: `"depart"` (default) or `"arrive"` |
**Coordinate-based search:**
```bash
./journey.sh "63.825#20.263" <to-id> [datetime] [mode]
```
Use `lat#lon` format for coordinates (WGS84 decimal degrees).
---
## Understanding User Time Intent
Before searching, understand what the user wants:
### Intent Types
| User Says | Intent | How to Query |
|-----------|--------|--------------|
| "now", "next bus", "how do I get to" | **Travel Now** | No datetime parameter |
| "in 30 minutes", "in 1 hour" | **Depart Later** | Calculate time, use `depart` mode |
| "around 15:00", "sometime afternoon" | **Around Time** | Query with offset (see below) |
| "arrive by 18:00", "need to be there at 9" | **Arrive By** | Use `arrive` mode |
| "tomorrow morning", "on Friday at 10" | **Future Time** | Use specific datetime |
### Handling "Around Time" Queries
When user wants options "around" a time, query 15-30 minutes earlier to show options before and after:
```bash
# User: "I want to travel around 15:00"
# Query at 14:30 to get options spanning 14:30-16:00+
./journey.sh ... "14:30" depart
```
### Relative Time Calculations
Convert relative times to absolute:
| User Says | Current: 14:00 | Query Time |
|-----------|----------------|------------|
| "in 30m" | -> | "14:30" |
| "in 1h" | -> | "15:00" |
| "in 2 hours" | -> | "16:00" |
---
## LLM Response Formatting
When presenting journey results to users, use these emojis and formatting guidelines.
### Emoji Reference
| Emoji | Use For |
|-------|---------|
| `bus` | Bus (Tabussen/Ultra) |
| `train` | Train |
| `walk` | Walking segment |
| `clock` | Time/duration |
| `clock1` | Departure time |
| `goal` | Arrival time |
| `pin` | Stop/station |
| `house` | Origin (home/start) |
| `target` | Destination |
| `warning` | Delay or disruption |
| `check` | On time |
| `arrows_counterclockwise` | Transfer/change |
### Response Structure
**Always include these key elements from the tool output:**
1. **When to leave** - The actual time user needs to start (including walking)
2. **Walking segments** - Distance and time for any walking
3. **Transport departure** - When the bus actually leaves
4. **Arrival time** - When user reaches destination
5. **Line number and direction** - Which bus to take
### Example Response Format
**For a simple direct journey:**
```
**Leave now** from Vasaplan
**Vasaplan** -> **Universitetet**
Bus 1 (mot Mariehem) departs 09:07
Arrives 09:18 at Universitetet
Total: 11 min
```
**For a journey with transfer:**
```
**Leave at 08:45**
Walk 300m to Vasaplan (~4 min)
**Vasaplan** -> **Umeå C** -> **Skellefteå**
**Leg 1:**
Bus 1 departs 08:51
Arrives Umeå C 09:05
Transfer at Umeå C (15 min)
**Leg 2:**
Bus 100 (mot Skellefteå) departs 09:20
Arrives Skellefteå busstation 11:45
Total: 3h | 1 change
```
### Walking Segment Details
**Always show walking details:**
- Distance in meters
- Include walking in the "leave time" calculation
- Walk time estimate: ~100m per minute (normal walking speed)
### Presenting Multiple Options
When showing journey options, make timing crystal clear:
```
I found 3 options for you:
**Option 1 - Leave now (09:00)** Recommended
Walk 5 min -> Bus 1 at 09:07 -> arrives 09:25
Total: 25 min
**Option 2 - Leave in 15m (09:15)**
Walk 5 min -> Bus 1 at 09:22 -> arrives 09:40
Total: 25 min
**Option 3 - Leave in 30m (09:30)**
Walk 5 min -> Bus 8 at 09:37 -> arrives 09:48
Total: 18 min | Faster but later departure
Which works best for you?
```
---
## LLM Workflow: How to Plan a Trip
Follow this workflow when a user asks for a trip:
### Step 1: Understand Time Intent
Parse what the user wants:
- **"How do I get to..."** -> Travel now
- **"I need to be there at 18:00"** -> Arrive mode
- **"Sometime around 3pm"** -> Query 14:30, show range
- **"In about an hour"** -> Calculate from current time
### Step 2: Search for Both Locations
Search for origin and destination separately:
```bash
./search-location.sh "Vasaplan?"
./search-location.sh "Universitetet?"
```
### Step 3: Validate Search Results
**Check each result carefully:**
1. **Exact or close match?** - If the name matches what the user asked for, proceed.
2. **Multiple results returned?** - The script shows up to 10 matches. If the first result isn't clearly correct, ask the user to confirm.
3. **Name significantly different?** - If user asked for "university" and result shows "Umeå Universitet", confirm with user.
4. **No results found?** - Try alternative strategies (see below).
### Step 4: Handle Ambiguous or Failed Searches
**When results don't match or are ambiguous, ask clarifying questions:**
```
I searched for "centrum" and found multiple locations:
1. Umeå Vasaplan (central bus hub)
2. Skellefteå centrum
3. Lycksele centrum
Which one did you mean?
```
**When no results are found, try these strategies:**
1. **Try with city name:**
```bash
# If "Storgatan 10" fails, try:
./search-location.sh "Storgatan 10, Umeå?"
```
2. **Try common variations:**
```bash
# "Universitetet" -> "Umeå universitet"
# "Sjukhuset" -> "NUS" or "Norrlands universitetssjukhus"
```
3. **Use fuzzy search (add ?):**
```bash
./search-location.sh "univ?"
```
### Step 5: Execute Journey Search
Once you have confirmed IDs for both locations:
```bash
./journey.sh <from-id> <to-id> [datetime] [mode]
```
### Step 6: Format Response
Use the formatting guide above to present results clearly. **Always use actual numbers from the tool output - never estimate or speculate.**
---
## Query Formatting Rules
**The search API is sensitive to formatting. Follow these rules:**
### Common Stop Names in Umeå
| User Says | Search For |
|-----------|------------|
| "Vasaplan", "centrum" | `"Umeå Vasaplan?"` |
| "Universitetet", "uni" | `"Umeå universitet?"` |
| "NUS", "sjukhuset" | `"Norrlands universitetssjukhus?"` |
| "Ikea" | `"IKEA Umeå?"` |
| "Flygplatsen" | `"Umeå Airport?"` |
| "Järnvägsstationen", "tåget" | `"Umeå centralstation?"` |
### Regional Destinations
| Destination | Search For |
|-------------|------------|
| Skellefteå | `"Skellefteå busstation?"` |
| Lycksele | `"Lycksele busstation?"` |
| Vindeln | `"Vindeln station?"` |
| Robertsfors | `"Robertsfors centrum?"` |
| Holmsund | `"Holmsund centrum?"` |
### Street Addresses
Include city name for better accuracy:
```bash
./search-location.sh "Storgatan 25, Umeå?"
./search-location.sh "Kungsgatan 10, Skellefteå?"
```
---
## Examples
### Example 1: Travel Now (Umeå Local)
User: "How do I get from Vasaplan to NUS?"
```bash
./search-location.sh "Umeå Vasaplan"
./search-location.sh "NUS?"
./journey.sh 740020116 740023840
```
**Response:**
```
**Leave now** from Vasaplan
**Vasaplan** -> **Universitetssjukhuset**
Bus 8 (mot Lyktvägen) departs 11:01
Arrives 11:06
Total: 5 min | Direct, no changes
```
### Example 2: Regional Journey
User: "I need to get to Skellefteå from Umeå tomorrow at 8"
```bash
./search-location.sh "Umeå Vasaplan"
./search-location.sh "Skellefteå?"
./journey.sh 740020116 740000053 "tomorrow 08:00"
```
**Response:**
```
**Depart tomorrow at 08:04** from Vasaplan
Walk 766m to Umeå Busstation (~11 min)
**Umeå Busstation** -> **Skellefteå busstation**
Bus 20 (Länstrafik mot Haparanda) departs 08:15
Arrives 10:40 at Skellefteå busstation
Total: 2h 36min | Direct (with walk)
```
### Example 3: Arrive By Time
User: "I need to be at NUS by 08:00 tomorrow"
```bash
./search-location.sh "Umeå Vasaplan"
./search-location.sh "NUS?"
./journey.sh 740020116 740023840 "tomorrow 08:00" arrive
```
**Response:**
```
**Arrive by 08:00** at NUS
**Vasaplan** -> **Universitetssjukhuset**
Bus 9 departs **07:51**
Arrives **07:56** - 4 min buffer
Leave Vasaplan by 07:51 to arrive on time!
```
### Example 4: From Address/Coordinates
User: "I'm at Storgatan 50 in Umeå, how do I get to IKEA?"
```bash
./search-location.sh "Storgatan 50, Umeå?"
# If no resul
... (truncated)
productivity
By
Comments
Sign in to leave a comment