Spaces:
Running
Running
File size: 5,164 Bytes
256d8bf 0e2186b 256d8bf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | #!/usr/bin/env bash
# Install the Reachy Web dashboard as a systemd service that starts at boot,
# so http://<robot>.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 <<EOF
β οΈ This does not look like a Reachy robot: no $DAEMON_UNIT, and not a Raspberry Pi.
setup.sh installs a systemd service that launches the Reachy Web dashboard
at every boot. That is meant for the robot itself β installing it HERE would
add a boot service to THIS machine (and it needs systemd + sudo to work).
On a laptop you normally just run ./run.sh when you want the dashboard.
EOF
printf " Install the boot service here anyway? [y/N] "
reply=""
read -r reply 2>/dev/null </dev/tty || true # no controlling tty β stays No
case "$reply" in
y|Y|yes|YES|Yes) echo " β continuing." ;;
*) echo " β aborted, nothing changed."; exit 1 ;;
esac
fi
RUN_USER="$(id -un)"
# 0) audio tools for the sound waveforms and server-side listen. The daemon reads
# audio via the pulsectl PYTHON lib, so a robot can have a working sound stack
# yet no CLI tools β which audio.py needs. `pactl` (pulseaudio-utils) finds the
# mic/speaker; `pw-record` (pipewire-bin) is what actually CAPTURES (this robot
# is PipeWire and parec read nothing from its suspended sources). Best-effort.
if ! command -v pactl >/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 <<EOF
[Unit]
Description=Reachy Web dashboard
Documentation=https://huggingface.co/spaces/Domotick/reachy_web
After=network-online.target $DAEMON_UNIT
Wants=network-online.target $DAEMON_UNIT
[Service]
Type=simple
User=$RUN_USER
WorkingDirectory=$SELF_DIR
ExecStart=/usr/bin/env bash $SELF_DIR/run.sh
Restart=on-failure
RestartSec=5
Environment=REACHY_WEB_NO_BROWSER=1
Environment=REACHY_WEB_SKIP_INSTALL=1
Environment=REACHY_WEB_WAKE_ON_START=0
Environment=REACHY_WEB_SLEEP_ON_EXIT=0
[Install]
WantedBy=multi-user.target
EOF
# 3) enable at boot + start now
echo "π§ Enabling and starting the serviceβ¦"
sudo systemctl daemon-reload
sudo systemctl enable --now "$SERVICE"
echo
echo "β
Installed. The dashboard now starts at every boot, as $RUN_USER."
echo " status : systemctl status $SERVICE"
echo " logs : journalctl -u $SERVICE -f (or $SELF_DIR/logs/run.log)"
echo " stop : sudo systemctl stop $SERVICE"
echo " remove : $0 --uninstall"
echo
echo "It boots WITHOUT waking the robot (REACHY_WEB_WAKE_ON_START=0); wake it"
echo "from the UI, or set that to 1 in $UNIT if you want it awake on boot."
|