Initial commit: Javis project

This commit is contained in:
Javis committed 2026-09-21 21:44:00 +02:00
commit 435c645f36
164 files changed
+35279

No files matched your search

+122
View File
@@ -0,0 +1,122 @@
#!/usr/bin/env bash
# One-shot Raspberry Pi installer for javis-slave (headless or with touch display).
#
# sudo ./setup-pi.sh # headless satellite (mic + speaker)
# sudo ./setup-pi.sh --gui # Pi with official touch display
# sudo ./setup-pi.sh --with-vad # also install silero-vad (+PyTorch, ~200 MB)
#
# Idempotent: re-running upgrades the venv and rewrites the service unit.
set -euo pipefail
INSTALL_DIR="${INSTALL_DIR:-/opt/javis-slave}"
SERVICE_USER="${SERVICE_USER:-${SUDO_USER:-pi}}"
WITH_GUI=0
WITH_VAD=0
for arg in "$@"; do
case "$arg" in
--gui) WITH_GUI=1 ;;
--with-vad) WITH_VAD=1 ;;
-h|--help) sed -n '2,9p' "$0"; exit 0 ;;
*) echo "unknown option: $arg" >&2; exit 2 ;;
esac
done
if [[ $EUID -ne 0 ]]; then
echo "Run with sudo (installs apt packages and a systemd unit)." >&2
exit 1
fi
SRC_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
echo "==> apt packages"
apt-get update -qq
# portaudio: sounddevice; libsndfile: soundfile; alsa-utils: amixer/aplay/arecord;
# libatomic1 + libopenblas: onnxruntime/numpy wheels on aarch64.
apt-get install -y -qq python3 python3-venv python3-dev libportaudio2 libsndfile1 \
alsa-utils libatomic1 libopenblas0 rsync
if [[ $WITH_GUI -eq 1 ]]; then
# Qt platform plugin deps for PySide6 wheels on Raspberry Pi OS + colour emoji
# glyphs used by the orb/buttons (🎤 🔊 ⚙).
apt-get install -y -qq libxcb-cursor0 libxkbcommon-x11-0 libegl1 libgl1 libglib2.0-0 \
libfontconfig1 libdbus-1-3 fonts-noto-color-emoji
fi
echo "==> copying to ${INSTALL_DIR}"
mkdir -p "$INSTALL_DIR"
if [[ "$SRC_DIR" != "$INSTALL_DIR" ]]; then
rsync -a --delete --exclude .venv --exclude config --exclude '__pycache__' \
"$SRC_DIR"/ "$INSTALL_DIR"/
fi
mkdir -p "$INSTALL_DIR/config"
chown -R "$SERVICE_USER":"$SERVICE_USER" "$INSTALL_DIR"
echo "==> python venv"
extras=""
[[ $WITH_GUI -eq 1 ]] && extras="gui"
[[ $WITH_VAD -eq 1 ]] && extras="${extras:+$extras,}vad"
sudo -u "$SERVICE_USER" bash -c "
set -e
cd '$INSTALL_DIR'
[[ -x .venv/bin/python ]] || python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip wheel
if [[ -n '$extras' ]]; then .venv/bin/python -m pip install -e '.[$extras]'; else .venv/bin/python -m pip install -e .; fi
# Pre-download openWakeWord ONNX models so the service works offline later.
.venv/bin/python -c 'from openwakeword.utils import download_models; download_models()' || true
"
echo "==> permissions (audio, backlight)"
usermod -aG audio,video "$SERVICE_USER"
cat > /etc/udev/rules.d/90-javis-backlight.rules <<'EOF'
# Let members of 'video' set the display brightness (javis-slave /mcp/v1/brightness).
SUBSYSTEM=="backlight", ACTION=="add", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
EOF
udevadm control --reload-rules || true
# Passwordless power control for the service user (only the exact commands used).
cat > /etc/sudoers.d/javis-slave <<EOF
$SERVICE_USER ALL=(root) NOPASSWD: /usr/bin/systemctl suspend, /usr/sbin/shutdown
EOF
chmod 0440 /etc/sudoers.d/javis-slave
echo "==> systemd unit"
sed -e "s|^User=.*|User=$SERVICE_USER|" \
-e "s|/opt/javis-slave|$INSTALL_DIR|g" \
"$INSTALL_DIR/javis-slave.service" > /etc/systemd/system/javis-slave.service
systemctl daemon-reload
if [[ $WITH_GUI -eq 1 ]]; then
# With a display the touch UI runs in the user's desktop session (kiosk),
# not as a system service — both would fight over the microphone.
systemctl disable javis-slave.service >/dev/null 2>&1 || true
AUTOSTART_DIR="$(getent passwd "$SERVICE_USER" | cut -d: -f6)/.config/autostart"
sudo -u "$SERVICE_USER" mkdir -p "$AUTOSTART_DIR"
cat > "$AUTOSTART_DIR/javis-slave.desktop" <<EOF
[Desktop Entry]
Type=Application
Name=Javis Slave
Exec=env JAVIS_SLAVE_CONFIG_DIR=$INSTALL_DIR/config $INSTALL_DIR/.venv/bin/python -m javis_slave --kiosk
X-GNOME-Autostart-enabled=true
EOF
chown "$SERVICE_USER":"$SERVICE_USER" "$AUTOSTART_DIR/javis-slave.desktop"
else
systemctl enable javis-slave.service
fi
cat <<EOF
Done. Next steps:
1. Find your audio devices:
sudo -u $SERVICE_USER JAVIS_SLAVE_CONFIG_DIR=$INSTALL_DIR/config \\
$INSTALL_DIR/.venv/bin/python -m javis_slave --list-devices
2. Pair with the master (generate a code in its Devices tab), e.g.:
sudo -u $SERVICE_USER JAVIS_SLAVE_CONFIG_DIR=$INSTALL_DIR/config \\
$INSTALL_DIR/.venv/bin/python -m javis_slave --headless \\
--input-device 1 --output-device 0 --pair 192.168.1.10:8765 123456 --name Kueche
Press Ctrl+C once you hear the wake chime working, then:
EOF
if [[ $WITH_GUI -eq 1 ]]; then
echo " 3. Reboot (or log out/in): the touch UI autostarts in kiosk mode."
echo " Manual start: $INSTALL_DIR/.venv/bin/python -m javis_slave --kiosk"
else
echo " 3. sudo systemctl start javis-slave"
echo " journalctl -u javis-slave -f"
fi