feat(waybar): add more train portals to the on-board info widget

This commit is contained in:
etwas 2025-07-22 16:21:55 +02:00
parent 6d749d0248
commit b7a8552f2b
Signed by: etwas
SSH key fingerprint: SHA256:bHhIeAdn/2k9jmOs6+u6ox98VYmoHUN3HfnpV2w8Ws0
9 changed files with 266 additions and 2 deletions

View file

@ -29,6 +29,8 @@
"network"
"battery"
"custom/icestats"
"custom/thalysstats"
"custom/oebbstats"
"clock"
"tray"
];
@ -40,8 +42,24 @@
};
"custom/icestats" = {
exec = ./src/ice_fetch.sh;
exec-if = ./src/ice_presence.sh;
exec = ./src/icestats/ice_fetch.sh;
exec-if = ./src/icestats/ice_presence.sh;
interval = 1;
tooltip = true;
return-type = "json";
};
"custom/thalysstats" = {
exec = ./src/thalysstats/thalys_fetch.sh;
exec-if = ./src/thalysstats/thalys_presence.sh;
interval = 1;
tooltip = true;
return-type = "json";
};
"custom/oebbstats" = {
exec = ./src/oebbstats/oebb_fetch.sh;
exec-if = ./src/oebbstats/oebb_presence.sh;
interval = 1;
tooltip = true;
return-type = "json";

View file

@ -0,0 +1,87 @@
# Fetch the JSON data from the ÖBB API
decoded_data=$(curl -s https://railnet.oebb.at/assets/media/fis/combined.json)
# Check if the decoded data is valid JSON
if ! echo "$decoded_data" | jq empty 2>/dev/null; then
echo "{\"text\": \"N/A\", \"alt\": \"Speed data not available\", \"tooltip\": \"\", \"class\": \"unavailable\", \"percentage\": 0}"
exit 1
fi
# Extract the speed value from latestStatus
speed=$(echo "$decoded_data" | jq -r '.latestStatus.speed // empty')
# Check if the speed value is empty or null
if [ -z "$speed" ] || [ "$speed" = "null" ]; then
echo "{\"text\": \"N/A\", \"alt\": \"Speed data not available\", \"tooltip\": \"\", \"class\": \"unavailable\", \"percentage\": 0}"
exit 1
fi
# Extract train information
train_type=$(echo "$decoded_data" | jq -r '.trainType')
line_number=$(echo "$decoded_data" | jq -r '.lineNumber')
trip_number=$(echo "$decoded_data" | jq -r '.tripNumber')
# Get next stop information
next_stop_name=$(echo "$decoded_data" | jq -r '.nextStation.name.de')
next_stop_arrival_scheduled=$(echo "$decoded_data" | jq -r '.nextStation.arrival.scheduled')
next_stop_arrival_forecast=$(echo "$decoded_data" | jq -r '.nextStation.arrival.forecast')
# Calculate delay if forecast exists
delay_minutes=""
if [ "$next_stop_arrival_forecast" != "null" ] && [ "$next_stop_arrival_forecast" != "" ]; then
# Convert times to minutes for calculation
scheduled_minutes=$(echo "$next_stop_arrival_scheduled" | awk -F: '{print ($1 * 60) + $2}')
forecast_minutes=$(echo "$next_stop_arrival_forecast" | awk -F: '{print ($1 * 60) + $2}')
delay=$((forecast_minutes - scheduled_minutes))
if [ $delay -gt 0 ]; then
delay_minutes="+${delay}"
elif [ $delay -lt 0 ]; then
delay_minutes="${delay}"
fi
fi
# Get distance information
distance_from_current=$(echo "$decoded_data" | jq -r '.latestStatus.distance.meters // 0')
next_station_distance=$(echo "$decoded_data" | jq -r '.nextStation.distanceFromPrevious // 0')
remaining_distance=$((next_station_distance - distance_from_current))
distance_km=$(echo "scale=2; $remaining_distance/1000" | bc)
# Use forecast time if available, otherwise scheduled time
display_time="$next_stop_arrival_scheduled"
if [ "$next_stop_arrival_forecast" != "null" ] && [ "$next_stop_arrival_forecast" != "" ]; then
display_time="$next_stop_arrival_forecast"
fi
# Get current and destination stations
current_station=$(echo "$decoded_data" | jq -r '.currentStation.name.de // "Unknown"')
destination=$(echo "$decoded_data" | jq -r '.destination.de // .destination.all // "Unknown"')
# Create the tooltip text
tooltip="${train_type} ${line_number} (${trip_number})\n"
tooltip+="From: ${current_station}\n"
tooltip+="To: ${destination}\n\n"
tooltip+="Next stop: ${next_stop_name}\n"
if [ -n "$delay_minutes" ]; then
tooltip+="${display_time} (${delay_minutes} min) - ${distance_km} km"
else
tooltip+="${display_time} - ${distance_km} km"
fi
# Create the display text
if [ -n "$delay_minutes" ]; then
text="${speed} km/h - ${display_time} (${delay_minutes})"
else
text="${speed} km/h - ${display_time}"
fi
alt="Current speed"
class="oebbstats"
percentage=0
# Create the JSON object
json_output="{\"text\": \"${text}\", \"alt\": \"${alt}\", \"tooltip\": \"${tooltip}\", \"class\": \"${class}\", \"percentage\": ${percentage}}"
# Print the JSON object
echo "$json_output"

View file

@ -0,0 +1,6 @@
SSID=$(iwconfig wlp1s0 | grep ESSID | sed -e 's/.*ESSID:"\(.*\)"/\1/' | xargs)
if [[ $SSID == "OEBB" ]]; then
exit 0
else
exit 1
fi

View file

@ -0,0 +1,100 @@
# TODO: Get speed from somewhere!!!
# Fetch the JSON data from the API
# The URL is hardcoded, but could be passed as an argument
trip_data=$(curl -s "https://wifi.sncf/router/api/train/details")
# Check if trip_data is empty or does not contain valid JSON
if [ -z "$trip_data" ] || ! echo "$trip_data" | jq -e . > /dev/null 2>&1; then
# Output a standard error message in JSON format if data is unavailable
echo "{\"text\": \"N/A\", \"alt\": \"Train data not available\", \"tooltip\": \"Could not retrieve train information.\", \"class\": \"unavailable\", \"percentage\": 0}"
exit 1
fi
# Extract general trip information
train_number=$(echo "$trip_data" | jq -r '.number')
# The train type (e.g., TGV) is not explicitly in the JSON, so we'll use a generic title or assume TGV
train_type="TGV"
# Find the next stop
# We iterate through the stops and find the first one with an arrival time in the future.
next_stop_info=""
current_time_epoch=$(date +%s)
# The `jq` command below processes the 'stops' array.
# - `to_entries` converts the array to key-value pairs.
# - `map(...)` processes each stop.
# - `select(...)` filters for the stops that are in the future.
# - `sort_by(.value.realDate)` sorts them by arrival time.
# - `first` gets the very next stop.
# - `// empty` handles the case where no future stops are found.
next_stop_info=$(echo "$trip_data" | jq -r '
.stops | to_entries | map(
select(
(.value.realDate | fromdateiso8601) > now
)
) | sort_by(.value.realDate) | first | .value // empty
')
# Check if a next stop was found
if [ -z "$next_stop_info" ]; then
# If no next stop is found, it might be the last stop. Let's get the last stop from the list.
last_stop_info=$(echo "$trip_data" | jq -r '.stops[-1]')
stop_label=$(echo "$last_stop_info" | jq -r '.label')
echo "{\"text\": \"Approaching ${stop_label}\", \"alt\": \"Final destination\", \"tooltip\": \"Train is approaching its final destination: ${stop_label}\", \"class\": \"final-stop\", \"percentage\": 100}"
exit 0
fi
# Extract details for the next stop
next_stop_name=$(echo "$next_stop_info" | jq -r '.label')
next_stop_arrival_iso=$(echo "$next_stop_info" | jq -r '.realDate')
next_stop_delay=$(echo "$next_stop_info" | jq -r '.delay') # in minutes
delay_reason=$(echo "$next_stop_info" | jq -r '.delayReason')
# Format the arrival time to HH:MM
next_stop_arrival_time=$(date -d "$next_stop_arrival_iso" +"%H:%M")
# Extract progress information from the first stop in the array
progress_info=$(echo "$trip_data" | jq -r '.stops[0].progress')
percentage=$(echo "$progress_info" | jq -r '.progressPercentage')
# Round the percentage to an integer
percentage_int=$(printf "%.0f" "$percentage")
# --- Construct the output strings ---
# Build the main text string
text="Progress: ${percentage_int}% - Next: ${next_stop_name} ${next_stop_arrival_time}"
if [ "$next_stop_delay" -gt 0 ]; then
text+=" (+${next_stop_delay}')"
fi
# Build the tooltip string
tooltip="${train_type} ${train_number}\n\n"
tooltip+="Next stop: ${next_stop_name}\n"
tooltip+="Arrival: ${next_stop_arrival_time}"
if [ "$next_stop_delay" -gt 0 ]; then
tooltip+=" (+${next_stop_delay}')"
fi
if [ -n "$delay_reason" ] && [ "$delay_reason" != "null" ]; then
tooltip+="\nReason: ${delay_reason}"
fi
# Set alt text and class
alt="Train ${train_number} progress"
class="sncfstats"
# --- Create and print the final JSON object ---
# Using jq to safely construct the JSON output
jq -n \
--arg text "$text" \
--arg alt "$alt" \
--arg tooltip "$tooltip" \
--arg class "$class" \
--argjson percentage "$percentage_int" \
'{text: $text, alt: $alt, tooltip: $tooltip, class: $class, percentage: $percentage}'

View file

@ -0,0 +1,45 @@
api_response=$(curl -s "https://www.ombord.info/api/jsonp/position/?_=$(date +%s%3N)")
# Check if the API call returned any data. If not, exit gracefully.
if [ -z "$api_response" ]; then
echo '{"text": "", "tooltip": "Failed to fetch Thalys data", "class": "unavailable"}'
exit 1
fi
speed_ms=$(echo "$api_response" | tr -d '();' | jq -r '.speed // "null"')
# Check if the extracted speed value is null or empty.
if [ "$speed_ms" == "null" ] || [ -z "$speed_ms" ]; then
echo '{"text": "N/A", "tooltip": "Speed data not available", "class": "unavailable"}'
exit 1
fi
# Bash does not handle floating-point arithmetic, so we use `bc` (Basic Calculator).
# 1. Convert speed from meters per second (m/s) to kilometers per hour (km/h) by multiplying by 3.6.
# 2. `scale=0` tells bc to output with zero decimal places (i.e., as an integer).
# 3. The `/ 1` at the end ensures that the rounding is applied correctly.
speed_kmh=$(echo "scale=0; $speed_ms * 3.6 / 1" | bc)
# --- Waybar JSON Output ---
# The main text displayed on the bar.
text="${speed_kmh} km/h"
# A more descriptive text that appears on hover.
tooltip="Current speed: ${speed_kmh} km/h"
# A CSS class for custom styling in your Waybar `style.css`.
class="thalysstats"
# The percentage value, often used for progress bars or circular indicators.
# We'll set it to 0 as it's not applicable here, but it's good practice to include it.
percentage=0
# Print the final JSON object.
# Using `printf` is a safer way to format strings containing variables than `echo`.
printf '{"text": "%s", "tooltip": "%s", "class": "%s", "percentage": %d}\n' \
"$text" \
"$tooltip" \
"$class" \
"$percentage"

View file

@ -0,0 +1,6 @@
SSID=$(iwconfig wlp1s0 | grep ESSID | sed -e 's/.*ESSID:"\(.*\)"/\1/' | xargs)
if [[ $SSID == "EurostarTrainsWiFi" ]]; then
exit 0
else
exit 1
fi

View file

@ -66,6 +66,8 @@
#pulseaudio,
#temperature,
#icestats,
#thalysstats,
#oebbstats,
#tray {
padding-left: 10px;
padding-right: 10px;