#!/bin/bash # Route 5 smart monitor — determines direction by time of day, launches background watcher # Usage: bash monitor.sh [channel_id] # Before 11 AM CST → Eastbound (morning commute) # After 11 AM CST → Westbound (evening commute) set -eo pipefail CHANNEL="${1:-1467247377743347953}" TU_URL="https://data.texas.gov/download/mqtr-wwpy/application%2Fjson" STATE_DIR="/home/node/.openclaw/workspace/skills/capmetro-monitor/memory" mkdir -p "$STATE_DIR" NOW=$(date +%s) CST_HOUR=$(TZ=America/Chicago date +%H) if [ "$CST_HOUR" -lt 11 ]; then DIRECTION=0 DIR_NAME="Eastbound" FIRST_STOP="5854" FIRST_STOP_NAME="Anderson/Northcross" USER_STOP="964" USER_STOP_NAME="Woodrow/Choquette" TRAVEL_FIRST_TO_USER=446 # 7m26s WALK_LEAD=0 # already near stop else DIRECTION=1 DIR_NAME="Westbound" FIRST_STOP="4606" FIRST_STOP_NAME="Tannehill/Webberville" USER_STOP="5499" USER_STOP_NAME="6th/West" TRAVEL_FIRST_TO_USER=2384 # 39m44s WALK_LEAD=900 # 15 min walk from office HOME_STOP="1072" HOME_STOP_NAME="Woodrow/Dwyce" TRAVEL_USER_TO_HOME=1344 # 22m24s fi # Find next departure from first stop TU=$(curl -sL --max-time 10 "$TU_URL" 2>/dev/null) NEXT=$(echo "$TU" | jq --arg dir "$DIRECTION" --arg fs "$FIRST_STOP" --arg now "$NOW" ' [.entity[] | select(.tripUpdate.trip.routeId == "5" and (.tripUpdate.trip.directionId | tostring) == $dir) | { tripId: .tripUpdate.trip.tripId, depart: ([.tripUpdate.stopTimeUpdate[] | select(.stopId == $fs) | (.departure.time // .arrival.time)] | .[0]) } ] | [.[] | select(.depart != null and (.depart | tonumber) > ($now | tonumber))] | sort_by(.depart | tonumber) | .[0]' 2>/dev/null) TRIP_ID=$(echo "$NEXT" | jq -r '.tripId // empty') DEPART_TS=$(echo "$NEXT" | jq -r '.depart // empty') if [ -z "$TRIP_ID" ] || [ -z "$DEPART_TS" ]; then echo '{"ok":false,"error":"No upcoming Route 5 departures found"}' exit 1 fi DEPART_CST=$(TZ=America/Chicago date -d "@$DEPART_TS" +"%I:%M %p" 2>/dev/null) MINS_AWAY=$(( (DEPART_TS - NOW) / 60 )) # Export config for the watcher export DIRECTION DIR_NAME FIRST_STOP FIRST_STOP_NAME USER_STOP USER_STOP_NAME export TRAVEL_FIRST_TO_USER WALK_LEAD TRIP_ID DEPART_TS CHANNEL export HOME_STOP HOME_STOP_NAME TRAVEL_USER_TO_HOME echo "{\"ok\":true,\"direction\":\"$DIR_NAME\",\"tripId\":\"$TRIP_ID\",\"firstStopDepart\":\"$DEPART_CST\",\"minsUntilDepart\":$MINS_AWAY,\"userStop\":\"$USER_STOP_NAME\"}" # Kill any existing watcher PID_FILE="$STATE_DIR/watcher.pid" if [ -f "$PID_FILE" ]; then OLD_PID=$(cat "$PID_FILE" 2>/dev/null) if [ -n "$OLD_PID" ] && kill -0 "$OLD_PID" 2>/dev/null; then kill "$OLD_PID" 2>/dev/null || true fi rm -f "$PID_FILE" fi # Dynamic timeout: time until departure + 5 min buffer for delays WAIT_SECS=$(( DEPART_TS - NOW + 300 )) [ "$WAIT_SECS" -lt 900 ] && WAIT_SECS=900 # minimum 15 min # Calculate MAX_POLLS for the watcher (poll every 20s) export MAX_POLLS=$(( WAIT_SECS / 20 )) SCRIPT_DIR="$(dirname "$0")" nohup timeout "$WAIT_SECS" bash "$SCRIPT_DIR/watch-departure-v2.sh" > /dev/null 2>&1 & echo $! > "$PID_FILE"