#!/usr/bin/env bash # Install the Reachy Web dashboard as a systemd service that starts at boot, # so http://.local:8042 is up the moment the robot is, no SSH needed. # # ./setup.sh # install + enable + start the boot service # ./setup.sh --uninstall # remove it # # Run it as your normal user (e.g. pollen), NOT as root: it calls sudo only for # the parts that need it (writing the unit, enabling it), and the dashboard must # run as you β€” your venv, your HOME, your HF session. set -euo pipefail SELF_DIR="$(cd "$(dirname "$0")" && pwd)" SERVICE="reachy-web.service" UNIT="/etc/systemd/system/$SERVICE" DAEMON_UNIT="reachy-mini-daemon.service" # Same test run.sh uses: the daemon's OWN systemd unit is the unambiguous marker # (not port 8000, which anything could hold); failing that, the robot's brain is # always a Raspberry Pi, a laptop is not. on_robot() { if command -v systemctl >/dev/null 2>&1 \ && systemctl cat "$DAEMON_UNIT" >/dev/null 2>&1; then return 0 fi grep -aqi "raspberry pi" /proc/device-tree/model 2>/dev/null } uninstall() { echo "πŸ—‘οΈ Removing $SERVICE…" sudo systemctl disable --now "$SERVICE" 2>/dev/null || true sudo rm -f "$UNIT" sudo systemctl daemon-reload echo "βœ… Done β€” the dashboard will no longer start at boot." } case "${1:-}" in --uninstall|-u|remove) uninstall; exit 0 ;; "" ) ;; * ) echo "usage: $0 [--uninstall]" >&2; exit 2 ;; esac if [ "$(id -u)" = 0 ]; then echo "❌ Run setup.sh as your normal user (e.g. pollen), not as root." >&2 echo " It will sudo the parts that need it. The dashboard must run as you." >&2 exit 1 fi if ! on_robot; then # Not detected as the robot. Don't just refuse β€” explain, and let the user # override (the detection can be wrong: a dev Pi, an unusual image). Default No. cat </dev/null /dev/null 2>&1 || ! command -v pw-record >/dev/null 2>&1; then echo "πŸ”Š Installing audio tools (pactl + pw-record, for the sound waveforms)…" sudo apt-get install -y pulseaudio-utils pipewire-bin 2>/dev/null \ || echo " (skipped: no apt or offline β€” install pulseaudio-utils pipewire-bin by hand)" fi # 1) build the venv + install deps ONCE, now, while we (probably) have internet β€” # so the boot service can skip the online reinstall every boot (a robot may # boot offline). run.sh --install-only does exactly the install, then stops. echo "🐍 Preparing the virtualenv and dependencies (once)…" REACHY_WEB_INSTALL_ONLY=1 "$SELF_DIR/run.sh" # 2) write the unit. It runs run.sh as you, after the network and the daemon # (soft: it still starts if the daemon unit is absent). Headless boot flags: # no browser, no reinstall, and DON'T wake the robot just because the Pi # powered on β€” leave it exactly as it is (the UI wakes it on demand). echo "πŸ“ Writing $UNIT…" sudo tee "$UNIT" >/dev/null <