GPS from a BELABOX
If one of the modems in your BELABOX has GPS, you can use it as your location source and leave your phone out of it. One command sets it up.
BELABOX is a separate open-source project (belabox.net). This installer is made by irlmap.live, not by the BELABOX team, and isn’t endorsed by them. It only uses ModemManager, which BELABOX already ships with, and doesn’t change anything in BELABOX itself.
What you need
- A modem with a GNSS receiver. Most LTE modules people put in bonding setups have one (Quectel EM and EP series, Sierra Wireless, Dell DW5821e / Foxconn T77W968 and plenty of others).
- A GPS-capable antenna on the right port. On a lot of M.2 modems GPS shares the diversity port (labelled AUX or DIV), not the main one. Use a passive antenna, unless you know your modem powers active ones.
- SSH access to your BELABOX.
Install it
SSH into your BELABOX and run this. It asks for your ingest token, which you’ll find under Settings → GPS apps and devices once you’re logged in.
curl -fsSL https://irlmap.live/install/belabox.sh | sudo shSSH into your BELABOX and run this. Your ingest token is already in it, so there’s nothing to type.
curl -fsSL https://irlmap.live/install/belabox.sh | sudo sh -s -- in_your_ingest_tokenThe installer:
- Finds the modem that has GPS (if you have several, it picks the one that supports it).
- Checks your token with irlmap.live before changing anything.
- Installs a small service that reads the position every two seconds and sends it. It starts at boot and restarts itself if it ever stops.
- Waits for the first GPS fix and tells you whether it got one.
Afterwards, the connection check under Settings turns green as soon as a location arrives. To remove it again:
curl -fsSL https://irlmap.live/install/belabox.sh | sudo sh -s -- --uninstall
No fix?
The first fix can take a couple of minutes. Indoors it often never comes, so test by a window or outside. The service keeps trying in the background, so you don’t need to run the installer again.
You can watch what the modem sees with mmcli -m any --location-get.
Good to know
- You can leave it running all the time. Anything sent while you’re not live on Twitch gets discarded, so it doesn’t matter that the box is on before and after your stream.
- BELABOX sometimes resets a modem when a link drops, which switches GPS off and can change the modem’s number. The service finds the modem again and turns GPS back on every minute, so it recovers by itself.
- Your token is stored in
/etc/irlmap-gps.conf, readable by root only. If you rotate it in Settings, run the installer again with the new one.
The script
It’s good practice to read a script before you pipe it into sudo sh. Here’s the whole thing, or download it.
#!/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/tty || REPLY=""
}
# ---------------------------------------------------------------- uninstall
if [ "${1:-}" = "--uninstall" ]; then
[ "$(id -u)" -eq 0 ] || die "Run it with sudo."
systemctl disable --now irlmap-gps 2>/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"Doing it by hand
Prefer to set it up yourself? These are the same steps the installer runs. First switch on GPS in ModemManager (replace 0 with your modem’s number from mmcli -L):
mmcli -m 0 --location-enable-gps-raw --location-enable-gps-nmea
mmcli -m 0 --location-set-gps-refresh-rate=1
Then save this as /usr/local/bin/irlmap-gps.sh with your own token in it:
#!/bin/sh
# Sends the modem's GPS position to irlmap.live every 2 seconds.
TOKEN="in_your_ingest_token"
MODEM="any"
n=0
while true; do
# Modems sometimes get reset when a link drops, which turns GPS off again.
# Re-enable it every minute so that never matters.
if [ $((n % 30)) -eq 0 ]; then
mmcli -m "$MODEM" --location-enable-gps-raw --location-enable-gps-nmea >/dev/null 2>&1
fi
n=$((n + 1))
LOC=$(mmcli -m "$MODEM" --location-get 2>/dev/null)
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 https://irlmap.live/ingest \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$BODY" >/dev/null
fi
sleep 2
done
And make it a service:
chmod +x /usr/local/bin/irlmap-gps.sh
cat > /etc/systemd/system/irlmap-gps.service <<'EOF'
[Unit]
Description=Send GPS to irlmap.live
After=ModemManager.service network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/irlmap-gps.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now irlmap-gps
Try it on your next stream
Free, and it takes about five minutes to set up.