#!/bin/sh # irlmap.live installer for BELABOX (or any Linux box that uses ModemManager). # Made by irlmap.live. Not part of, affiliated with or endorsed by the BELABOX project. # # Sends the GPS position from your modem to irlmap.live every 2 seconds. # # Install: curl -fsSL https://irlmap.live/install/belabox.sh | sudo sh # With token: curl -fsSL https://irlmap.live/install/belabox.sh | sudo sh -s -- in_yourtoken # Remove: curl -fsSL https://irlmap.live/install/belabox.sh | sudo sh -s -- --uninstall # # What it installs: # /etc/irlmap-gps.conf your token (readable by root only) # /usr/local/bin/irlmap-gps the sender # /etc/systemd/system/irlmap-gps.service starts it at boot, restarts it if it stops set -eu URL="https://irlmap.live" CONF="/etc/irlmap-gps.conf" BIN="/usr/local/bin/irlmap-gps" UNIT="/etc/systemd/system/irlmap-gps.service" say() { printf '%s\n' "$*"; } step() { printf '\n\033[1m==> %s\033[0m\n' "$*"; } die() { printf '\n\033[31mError:\033[0m %s\n' "$*" >&2; exit 1; } # Questions come from the terminal even though the script itself arrives through a pipe. ask() { printf '%s' "$1" >/dev/tty read -r REPLY /dev/null || true rm -f "$UNIT" "$BIN" "$CONF" systemctl daemon-reload 2>/dev/null || true say "irlmap.live GPS sender removed." exit 0 fi say "" say "irlmap.live GPS installer" say "Sends your modem's GPS to irlmap.live. Only used while you're live on Twitch." # ---------------------------------------------------------------- checks [ "$(id -u)" -eq 0 ] || die "Run it with sudo: curl -fsSL $URL/install/belabox.sh | sudo sh" command -v mmcli >/dev/null 2>&1 || die "mmcli (ModemManager) wasn't found. This installer needs a modem managed by ModemManager, which is what BELABOX uses." command -v curl >/dev/null 2>&1 || die "curl wasn't found. Install it first (apt install curl)." # ---------------------------------------------------------------- find a GPS modem step "Looking for a modem with GPS" GPS_MODEM="" for m in $(mmcli -L 2>/dev/null | sed -n 's|.*/Modem/\([0-9]*\).*|\1|p'); do name=$(mmcli -L 2>/dev/null | sed -n "s|.*/Modem/$m \(.*\)|\1|p") if mmcli -m "$m" --location-status 2>/dev/null | grep -q 'gps-raw'; then say " Modem $m: $name (has GPS)" [ -n "$GPS_MODEM" ] || GPS_MODEM="$m" else say " Modem $m: $name (no GPS)" fi done [ -n "$GPS_MODEM" ] || die "None of your modems report GPS support. Check that the modem has a GNSS receiver, or send GPS from your phone instead: $URL/guides/phone-gps-irl-stream" # ---------------------------------------------------------------- token step "Your ingest token" TOKEN="${1:-}" if [ -z "$TOKEN" ]; then say "Find it on $URL/settings under \"GPS apps and devices\". It starts with in_" ask "Paste your ingest token: " TOKEN=$(printf '%s' "$REPLY" | tr -d '[:space:]') fi case "$TOKEN" in in_?*) ;; *) die "That doesn't look like an ingest token. It should start with in_" ;; esac # An empty post is accepted by a valid token and rejected (401) by anything else. code=$(curl -s -o /dev/null -w '%{http_code}' -m 10 -X POST "$URL/ingest" \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{}' || true) case "$code" in 200) say " Token works." ;; 401) die "irlmap.live doesn't know that token. Copy it again from $URL/settings (it changes if you rotate it)." ;; *) die "Couldn't reach irlmap.live (HTTP $code). Check the box has internet and try again." ;; esac # ---------------------------------------------------------------- install step "Installing" mkdir -p "$(dirname "$CONF")" "$(dirname "$BIN")" "$(dirname "$UNIT")" umask 077 printf 'TOKEN=%s\nURL=%s\n' "$TOKEN" "$URL" > "$CONF" umask 022 cat > "$BIN" <<'SENDER' #!/bin/sh # irlmap.live GPS sender. Reads the modem's GPS through ModemManager and posts it every 2 s. # Settings live in /etc/irlmap-gps.conf. Installed by https://irlmap.live/install/belabox.sh . /etc/irlmap-gps.conf MODEM="" n=0 # Modem numbers change when a modem resets, so look the GPS modem up again whenever needed. find_modem() { for m in $(mmcli -L 2>/dev/null | sed -n 's|.*/Modem/\([0-9]*\).*|\1|p'); do if mmcli -m "$m" --location-status 2>/dev/null | grep -q 'gps-raw'; then MODEM="$m"; return 0; fi done MODEM="" return 1 } while true; do if [ -z "$MODEM" ] || [ $((n % 30)) -eq 0 ]; then # Find the modem and (re)enable GPS about once a minute: a modem reset turns it off again. if find_modem; then mmcli -m "$MODEM" --location-enable-gps-raw --location-enable-gps-nmea >/dev/null 2>&1 || true fi fi n=$((n + 1)) if [ -n "$MODEM" ]; then LOC=$(mmcli -m "$MODEM" --location-get 2>/dev/null || true) LAT=$(echo "$LOC" | sed -n 's/.*latitude: *\([-0-9.]*\).*/\1/p' | head -1) LON=$(echo "$LOC" | sed -n 's/.*longitude: *\([-0-9.]*\).*/\1/p' | head -1) ALT=$(echo "$LOC" | sed -n 's/.*altitude: *\([-0-9.]*\).*/\1/p' | head -1) if [ -n "$LAT" ] && [ -n "$LON" ]; then BODY="{\"lat\":$LAT,\"lon\":$LON" [ -n "$ALT" ] && BODY="$BODY,\"alt\":$ALT" BODY="$BODY}" curl -s -m 5 -X POST "$URL/ingest" -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" -d "$BODY" >/dev/null 2>&1 || true fi else MODEM="" fi sleep 2 done SENDER chmod 755 "$BIN" cat > "$UNIT" <<'UNITFILE' [Unit] Description=Send GPS to irlmap.live After=ModemManager.service network-online.target Wants=network-online.target [Service] ExecStart=/usr/local/bin/irlmap-gps Restart=always RestartSec=10 [Install] WantedBy=multi-user.target UNITFILE mmcli -m "$GPS_MODEM" --location-enable-gps-raw --location-enable-gps-nmea >/dev/null 2>&1 || true mmcli -m "$GPS_MODEM" --location-set-gps-refresh-rate=1 >/dev/null 2>&1 || true systemctl daemon-reload systemctl enable --now irlmap-gps >/dev/null 2>&1 || systemctl restart irlmap-gps say " Service irlmap-gps installed and running." # ---------------------------------------------------------------- first fix step "Waiting for a GPS fix (up to 2 minutes, it helps to be outside)" i=0 while [ $i -lt 24 ]; do LOC=$(mmcli -m "$GPS_MODEM" --location-get 2>/dev/null || true) LAT=$(echo "$LOC" | sed -n 's/.*latitude: *\([-0-9.]*\).*/\1/p' | head -1) if [ -n "$LAT" ]; then say " Got a fix. Your position is being sent to irlmap.live." break fi i=$((i + 1)) printf '.' sleep 5 done if [ $i -ge 24 ]; then say "" say " No fix yet. That's normal indoors. The service keeps trying in the background." say " Satellites visible but never a position? See \"Sees satellites but never gets a position\"" say " on $URL/guides/belabox-gps-setup" fi say "" say "Done. Locations only count while you're live on Twitch, so the service can run all the time." say "Check it's arriving under Settings on $URL (the green connection check)." say "Status: systemctl status irlmap-gps Remove: curl -fsSL $URL/install/belabox.sh | sudo sh -s -- --uninstall"