394 lines
20 KiB
Bash
Executable File
394 lines
20 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Smart Home Steam-TV-Box ISO Builder
|
|
# Target: builds a Debian live ISO on a Debian/Ubuntu build machine
|
|
#
|
|
# Drives `lb config && lb build` over hosts/steam-tv-box/live-build/ to produce the
|
|
# living-room gaming + media image:
|
|
# - greetd autologin straight into a kiosk Sway session (no greeter UI)
|
|
# - boots into STEAM BIG PICTURE and nothing else
|
|
# - native, local gaming: steam-installer + i386 multiarch + the full Mesa/Vulkan
|
|
# stack (this box has a real GPU; it is NOT the thin client's Steam Link streaming)
|
|
# - Prism Launcher (Minecraft), registered as a non-Steam game so it runs *through*
|
|
# Steam with Steam Input and the Steam Controller API live
|
|
# - a media session — Firefox (uBlock Origin + SponsorBlock), Spotify, mpv — that is
|
|
# launched LAZILY, the first time somebody leaves Big Picture
|
|
# - steamtv-agent (Python, systemd) — HA MQTT-discovery entities + swaymsg control
|
|
# - wayvnc for administration (password mandatory, fails closed)
|
|
#
|
|
# This script is also the single point that keeps configs/ (the human-edited source of
|
|
# truth, reviewed in git) in sync with live-build/config/includes.chroot/ (the
|
|
# generated tree that actually gets baked into the image). Never hand-edit anything
|
|
# under includes.chroot — it is wiped and regenerated on every run. The same now goes
|
|
# for live-build/config/preseed.cfg, which is generated from configs/installer/.
|
|
#
|
|
# Run as: sudo -E tools/build-steam-tv-box-iso.sh [hostname]
|
|
#
|
|
# Configuration comes from CoreSystemConfig.json — see tools/README.md.
|
|
|
|
set -euo pipefail
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# CONFIGURATION — comes from CoreSystemConfig.json, NOT from this file.
|
|
#
|
|
# sudo -E tools/build-steam-tv-box-iso.sh # the only steam-tv-box
|
|
# sudo -E tools/build-steam-tv-box-iso.sh <hostname> # a specific one, if several
|
|
# ---------------------------------------------------------------------------
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=lib/coreconfig.sh
|
|
source "${SCRIPT_DIR}/lib/coreconfig.sh"
|
|
|
|
core_select_kiosk "steam-tv-box" "${1:-}"
|
|
|
|
# CORE_KIOSK_DEBIAN_RELEASE is the per-kiosk `debian_release` override, falling back to
|
|
# household.debian_release when the kiosk does not set one. It exists mostly for this
|
|
# image: the household default is bookworm, whose Mesa (22.3) predates most of the
|
|
# driver work current titles depend on. Every other host here is a browser and a
|
|
# Python agent and does not care what Mesa it has; this one is the only machine in the
|
|
# project that renders anything demanding, and it is also the only one where being a
|
|
# release behind cannot be fixed later by editing a config file. Set
|
|
# "debian_release": "trixie" on this kiosk — see CoreSystemConfig.json.template.
|
|
DEBIAN_RELEASE="$CORE_KIOSK_DEBIAN_RELEASE"
|
|
KIOSK_USERNAME="$CORE_KIOSK_USERNAME"
|
|
IMAGE_HOSTNAME="$CORE_KIOSK_HOSTNAME"
|
|
KEYBOARD_LAYOUT="$CORE_KEYBOARD_LAYOUT"
|
|
ENABLE_INSTALLER="$CORE_KIOSK_ENABLE_INSTALLER"
|
|
MQTT_BROKER_HOST="$CORE_MQTT_BROKER_HOST"
|
|
MQTT_BROKER_PORT="$CORE_MQTT_BROKER_PORT"
|
|
MQTT_USERNAME="$CORE_MQTT_USERNAME"
|
|
MQTT_PASSWORD="$CORE_MQTT_PASSWORD"
|
|
SSH_AUTHORIZED_KEY="$CORE_SSH_AUTHORIZED_KEY"
|
|
STEAMTV_NAME="$CORE_KIOSK_FRIENDLY_NAME"
|
|
# The HA area this device physically sits in, from the kiosk's `room` in
|
|
# CoreSystemConfig.json. The agent publishes it as suggested_area so HA files the
|
|
# device in the right room by itself — see docs/rooms-and-endpoints.md.
|
|
STEAMTV_ROOM="${CORE_KIOSK_ROOM:-}"
|
|
HA_URL="$CORE_HA_URL"
|
|
# Which GPU is in this machine: amd | intel | nvidia. Read by 0300-steam.hook.chroot
|
|
# (to install the NVIDIA driver, or deliberately not to) and by kiosk-session (the
|
|
# wlroots cursor workaround). Guessing this wrong on an AMD box by installing the
|
|
# NVIDIA driver actively breaks it, which is why it is configuration and not detection.
|
|
GPU_VENDOR="${CORE_KIOSK_GPU_VENDOR:-amd}"
|
|
ENABLE_CEC="${CORE_KIOSK_ENABLE_CEC:-true}"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Paths
|
|
# ---------------------------------------------------------------------------
|
|
HOST_DIR="${CORE_REPO_ROOT}/hosts/steam-tv-box"
|
|
CONFIGS_DIR="${HOST_DIR}/configs"
|
|
AGENT_DIR="${HOST_DIR}/agent"
|
|
LIVE_BUILD_DIR="${HOST_DIR}/live-build"
|
|
INCLUDES="${LIVE_BUILD_DIR}/config/includes.chroot"
|
|
PACKAGE_LIST="${LIVE_BUILD_DIR}/config/package-lists/steam-tv-box.list.chroot"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Sanity checks
|
|
# ---------------------------------------------------------------------------
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo "Warning: not running as root. 'lb build' needs root to bootstrap and chroot,"
|
|
echo " and will fail partway through. Re-run with: sudo $0"
|
|
echo " Continuing anyway so you can at least regenerate includes.chroot..."
|
|
fi
|
|
|
|
if ! grep -qi "debian\|ubuntu" /etc/os-release; then
|
|
echo "Warning: live-build targets a Debian/Ubuntu build host. Proceeding anyway..."
|
|
fi
|
|
|
|
if ! command -v lb &> /dev/null; then
|
|
if [[ $EUID -eq 0 ]]; then
|
|
echo "--- Installing live-build ---"
|
|
apt-get update
|
|
apt-get install -y live-build
|
|
else
|
|
echo "live-build is not installed and this script is not running as root." >&2
|
|
echo " Install it first: sudo apt-get install live-build" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "--- live-build already installed, skipping ---"
|
|
fi
|
|
|
|
if [[ ! -f "$PACKAGE_LIST" ]]; then
|
|
echo "Missing package list: $PACKAGE_LIST" >&2
|
|
exit 1
|
|
fi
|
|
|
|
case "$GPU_VENDOR" in
|
|
amd|intel|nvidia) ;;
|
|
*)
|
|
echo "gpu_vendor is '${GPU_VENDOR}' — must be one of: amd, intel, nvidia." >&2
|
|
echo " Fix it on this kiosk in CoreSystemConfig.json and re-run." >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [[ "$DEBIAN_RELEASE" == "bookworm" ]]; then
|
|
echo "Note: building this image against bookworm. Its Mesa is 22.3, which is old for"
|
|
echo " a machine whose job is running games locally — expect missing Vulkan features"
|
|
echo " and poor performance in anything recent. Set \"debian_release\": \"trixie\" on"
|
|
echo " this kiosk in CoreSystemConfig.json unless you have a specific reason not to."
|
|
fi
|
|
|
|
echo
|
|
echo "=== Smart Home Steam-TV-Box ISO Builder ==="
|
|
echo "Debian release : $DEBIAN_RELEASE"
|
|
echo "Kiosk user : $KIOSK_USERNAME"
|
|
echo "Image hostname : $IMAGE_HOSTNAME"
|
|
echo "GPU vendor : $GPU_VENDOR"
|
|
echo "MQTT broker : ${MQTT_BROKER_HOST}:${MQTT_BROKER_PORT}"
|
|
echo "Home Assistant : $HA_URL"
|
|
echo "HDMI-CEC : $ENABLE_CEC"
|
|
echo "Debian installer : $ENABLE_INSTALLER"
|
|
echo "Keyboard layout : $KEYBOARD_LAYOUT"
|
|
echo
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. Regenerate includes.chroot from configs/ and agent/
|
|
# ---------------------------------------------------------------------------
|
|
echo "--- Regenerating $INCLUDES ---"
|
|
rm -rf "$INCLUDES"
|
|
mkdir -p \
|
|
"$INCLUDES/etc/greetd" \
|
|
"$INCLUDES/etc/wayvnc" \
|
|
"$INCLUDES/etc/steamtv-agent" \
|
|
"$INCLUDES/etc/firefox/policies" \
|
|
"$INCLUDES/etc/steamtv-firefox" \
|
|
"$INCLUDES/usr/local/bin" \
|
|
"$INCLUDES/opt/steamtv-agent" \
|
|
"$INCLUDES/home/${KIOSK_USERNAME}/.config/sway" \
|
|
"$INCLUDES/home/${KIOSK_USERNAME}/.config/mpv" \
|
|
"$INCLUDES/home/${KIOSK_USERNAME}/.ssh"
|
|
|
|
# @KIOSK_USERNAME@ and @KEYBOARD_LAYOUT@ are the only templated tokens in the configs.
|
|
# Everything else the hooks need is read at build time from /etc/steamtv-agent/
|
|
# config.env (written below), which live-build copies in via chroot_local-includes
|
|
# *before* it runs chroot_local-hooks — that ordering is what lets the hooks be plain
|
|
# scripts with no outer-shell variables of their own.
|
|
subst() {
|
|
sed -e "s/@KIOSK_USERNAME@/${KIOSK_USERNAME}/g" \
|
|
-e "s/@KEYBOARD_LAYOUT@/${KEYBOARD_LAYOUT}/g" "$1" > "$2"
|
|
}
|
|
|
|
subst "${CONFIGS_DIR}/greetd/config.toml" "$INCLUDES/etc/greetd/config.toml"
|
|
subst "${CONFIGS_DIR}/wayvnc/config" "$INCLUDES/etc/wayvnc/config"
|
|
subst "${CONFIGS_DIR}/sway/config" "$INCLUDES/home/${KIOSK_USERNAME}/.config/sway/config"
|
|
subst "${AGENT_DIR}/steamtv-agent.service" "$INCLUDES/opt/steamtv-agent/steamtv-agent.service"
|
|
|
|
install -m 0755 "${CONFIGS_DIR}/greetd/kiosk-session" "$INCLUDES/usr/local/bin/kiosk-session"
|
|
install -m 0755 "${CONFIGS_DIR}/wayvnc/start-wayvnc" "$INCLUDES/usr/local/bin/start-wayvnc"
|
|
# Bound to the remote's power/sleep buttons — see the Sway config's remote-control
|
|
# section for why those turn the display off rather than the machine.
|
|
install -m 0755 "${CONFIGS_DIR}/sway/display-toggle" "$INCLUDES/usr/local/bin/display-toggle"
|
|
|
|
# The session: the two halves of the leave-Big-Picture detection, the launchers they
|
|
# call, and the Steam shortcut registration that puts Prism inside Steam Input.
|
|
install -m 0755 "${CONFIGS_DIR}/session/steam-session" "$INCLUDES/usr/local/bin/steam-session"
|
|
install -m 0755 "${CONFIGS_DIR}/session/steam-big-picture" "$INCLUDES/usr/local/bin/steam-big-picture"
|
|
install -m 0755 "${CONFIGS_DIR}/session/steam-shortcut-prism" "$INCLUDES/usr/local/bin/steam-shortcut-prism"
|
|
install -m 0755 "${CONFIGS_DIR}/session/session-watcher" "$INCLUDES/usr/local/bin/session-watcher"
|
|
install -m 0755 "${CONFIGS_DIR}/session/media-session" "$INCLUDES/usr/local/bin/media-session"
|
|
install -m 0755 "${CONFIGS_DIR}/session/media-player" "$INCLUDES/usr/local/bin/media-player"
|
|
install -m 0755 "${CONFIGS_DIR}/session/spotify-launch" "$INCLUDES/usr/local/bin/spotify-launch"
|
|
install -m 0755 "${CONFIGS_DIR}/session/prism-launch" "$INCLUDES/usr/local/bin/prism-launch"
|
|
|
|
# fleet-bootstrap: fetch this machine's published monitoring script and run it. Opt-in —
|
|
# with no /etc/fleet-bootstrap.conf it exits 0 and does nothing.
|
|
install -m 0755 "${CORE_REPO_ROOT}/tools/fleet-bootstrap.sh" "$INCLUDES/usr/local/bin/fleet-bootstrap"
|
|
|
|
install -m 0644 "${CONFIGS_DIR}/mpv/mpv.conf" "$INCLUDES/home/${KIOSK_USERNAME}/.config/mpv/mpv.conf"
|
|
|
|
# Console (VT/TTY) keymap — separate from Sway's own xkb_layout above, since greetd
|
|
# briefly owns the console before Sway starts.
|
|
mkdir -p "$INCLUDES/etc/default"
|
|
cat > "$INCLUDES/etc/default/keyboard" <<EOF
|
|
XKBMODEL="pc105"
|
|
XKBLAYOUT="${KEYBOARD_LAYOUT}"
|
|
XKBVARIANT=""
|
|
XKBOPTIONS=""
|
|
|
|
BACKSPACE="guess"
|
|
EOF
|
|
|
|
# Firefox: the browsing window's launcher, plus the chrome/prefs template it copies
|
|
# into its profile at launch. policies.json (uBlock Origin, SponsorBlock — the
|
|
# "browser with ublock origin" half of the requirement) is global, not per-profile.
|
|
install -m 0755 "${CONFIGS_DIR}/firefox/web-browser" "$INCLUDES/usr/local/bin/web-browser"
|
|
install -m 0644 "${CONFIGS_DIR}/firefox/policies.json" "$INCLUDES/etc/firefox/policies/policies.json"
|
|
install -m 0644 "${CONFIGS_DIR}/firefox/userChrome.css" "$INCLUDES/etc/steamtv-firefox/userChrome.css"
|
|
install -m 0644 "${CONFIGS_DIR}/firefox/user.js" "$INCLUDES/etc/steamtv-firefox/user.js"
|
|
|
|
# Persistent audio-output template — steamtv_agent's runtime_state.py seeds a writable
|
|
# runtime copy from this on first boot (see its module docstring); the file here is
|
|
# read-only and never the one actually mutated.
|
|
install -m 0644 "${CONFIGS_DIR}/audio/audio-config.json" "$INCLUDES/etc/steamtv-agent/audio-config.json"
|
|
|
|
cp -r "${AGENT_DIR}/steamtv_agent" "$INCLUDES/opt/steamtv-agent/"
|
|
install -m 0644 "${AGENT_DIR}/requirements.txt" "$INCLUDES/opt/steamtv-agent/requirements.txt"
|
|
find "$INCLUDES/opt/steamtv-agent" -name '__pycache__' -type d -prune -exec rm -rf {} +
|
|
|
|
if [[ -n "$SSH_AUTHORIZED_KEY" ]]; then
|
|
echo "$SSH_AUTHORIZED_KEY" > "$INCLUDES/home/${KIOSK_USERNAME}/.ssh/authorized_keys"
|
|
chmod 600 "$INCLUDES/home/${KIOSK_USERNAME}/.ssh/authorized_keys"
|
|
echo " Baked an SSH authorized_keys entry for ${KIOSK_USERNAME}."
|
|
else
|
|
echo " No SSH_AUTHORIZED_KEY set — SSH admin access will not be possible on this image."
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. Runtime config, read by steamtv-agent, the sway session wrapper, and the hooks
|
|
# ---------------------------------------------------------------------------
|
|
echo "--- Writing /etc/steamtv-agent/config.env into includes.chroot ---"
|
|
cat > "$INCLUDES/etc/steamtv-agent/config.env" <<EOF
|
|
# Generated by tools/build-steam-tv-box-iso.sh — do not hand-edit
|
|
# here; change CoreSystemConfig.json at the repo root and rebuild.
|
|
KIOSK_USERNAME=${KIOSK_USERNAME}
|
|
STEAMTV_NAME=${STEAMTV_NAME}
|
|
STEAMTV_ROOM=${STEAMTV_ROOM}
|
|
|
|
MQTT_BROKER_HOST=${MQTT_BROKER_HOST}
|
|
MQTT_BROKER_PORT=${MQTT_BROKER_PORT}
|
|
MQTT_USERNAME=${MQTT_USERNAME}
|
|
MQTT_PASSWORD=${MQTT_PASSWORD}
|
|
|
|
HA_URL=${HA_URL}
|
|
|
|
GPU_VENDOR=${GPU_VENDOR}
|
|
ENABLE_CEC=${ENABLE_CEC}
|
|
EOF
|
|
chmod 0644 "$INCLUDES/etc/steamtv-agent/config.env"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. Generated preseed (only consulted when the installer is enabled)
|
|
# ---------------------------------------------------------------------------
|
|
sed -e "s/@KEYBOARD_LAYOUT@/${KEYBOARD_LAYOUT}/g" \
|
|
"${CONFIGS_DIR}/installer/preseed.cfg" > "${LIVE_BUILD_DIR}/config/preseed.cfg"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. lb config
|
|
# ---------------------------------------------------------------------------
|
|
cd "$LIVE_BUILD_DIR"
|
|
|
|
chmod +x config/hooks/normal/*.hook.chroot
|
|
|
|
if [[ -e .build ]]; then
|
|
echo "--- Previous build found, running 'lb clean' (package cache is kept) ---"
|
|
lb clean
|
|
fi
|
|
|
|
INSTALLER_MODE="none"
|
|
if [[ "$ENABLE_INSTALLER" == "true" ]]; then
|
|
INSTALLER_MODE="live"
|
|
fi
|
|
|
|
echo "--- Running lb config ---"
|
|
# live-build auto-discovers config/package-lists/*.list.chroot and
|
|
# config/hooks/normal/*.hook.chroot; there is no flag to point at them individually.
|
|
#
|
|
# --archive-areas: contrib is REQUIRED — steam-installer lives there and
|
|
# 0300-steam.hook.chroot fails without it, producing an image with no Steam on it.
|
|
# non-free is required for the NVIDIA driver (and is harmless on an AMD/Intel box,
|
|
# since nothing from it is installed unless gpu_vendor says so).
|
|
lb config \
|
|
--distribution "$DEBIAN_RELEASE" \
|
|
--architectures amd64 \
|
|
--linux-flavours amd64 \
|
|
--archive-areas "main contrib non-free non-free-firmware" \
|
|
--binary-images iso-hybrid \
|
|
--debian-installer "$INSTALLER_MODE" \
|
|
--iso-application "SmartestHome Steam TV Box" \
|
|
--iso-publisher "SmartestHome" \
|
|
--iso-volume "smarthome-steam-tv-box" \
|
|
--memtest none \
|
|
--bootappend-live "boot=live components quiet splash noautologin username=${KIOSK_USERNAME} hostname=${IMAGE_HOSTNAME}"
|
|
|
|
# noautologin: live-config would otherwise autologin its own account on tty1 and fight
|
|
# greetd for the VT (0200-greetd.hook.chroot masks getty@tty1 as a belt-and-braces
|
|
# second line of defence).
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 5. lb build
|
|
# ---------------------------------------------------------------------------
|
|
echo "--- Running lb build (this takes a while and needs network) ---"
|
|
echo " Longer than the other images: the i386 multiarch stack and Steam's"
|
|
echo " dependency chain are a few hundred extra packages."
|
|
lb build
|
|
|
|
ISO_PATH="$(find "$LIVE_BUILD_DIR" -maxdepth 1 -name '*.iso' -print -quit)"
|
|
ISO_PATH="${ISO_PATH:-${LIVE_BUILD_DIR}/live-image-amd64.hybrid.iso}"
|
|
ISO_PATH="$(core_publish_image "$ISO_PATH" "steam-tv-box" "$IMAGE_HOSTNAME")"
|
|
|
|
echo
|
|
echo "=== Done ==="
|
|
echo "ISO written to:"
|
|
echo " ${ISO_PATH}"
|
|
echo
|
|
echo "What's in it:"
|
|
echo " greetd : autologin as '${KIOSK_USERNAME}' straight into Sway on vt1"
|
|
echo " Boots to : Steam Big Picture, and nothing else"
|
|
echo " Steam : NATIVE (steam-installer + i386 multiarch) — games run on this"
|
|
echo " machine. This is not the thin client's Steam Link streaming."
|
|
echo " GPU stack : Mesa/Vulkan (${GPU_VENDOR}), 64- and 32-bit"
|
|
echo " Prism Launcher : Flathub, registered as a non-Steam game so it launches THROUGH"
|
|
echo " Steam with Steam Input / the Steam Controller API active"
|
|
echo " Media session : Firefox (uBlock Origin + SponsorBlock), Spotify, mpv —"
|
|
echo " started the FIRST TIME you leave Big Picture, not at boot"
|
|
echo " Sway : workspaces 1:steam / 2:games / 3:web / 4:media / 5:music"
|
|
echo " wayvnc : 0.0.0.0:5900, auth REQUIRED, refuses to start without a password"
|
|
echo " steamtv-agent : system service, MQTT ${MQTT_BROKER_HOST}:${MQTT_BROKER_PORT}"
|
|
echo " Audio output : HA select, persisted to audio-config.json"
|
|
echo " Keyboard layout : ${KEYBOARD_LAYOUT} (console + Sway)"
|
|
echo " Maintenance shell: Super+Shift+Ctrl+M opens a floating terminal locally"
|
|
echo
|
|
echo "Next steps:"
|
|
echo " 1. Write the ISO to a USB stick:"
|
|
echo " sudo dd if=${ISO_PATH} of=/dev/sdX bs=4M status=progress oflag=sync"
|
|
echo " (double-check /dev/sdX with 'lsblk' first — dd will happily eat the wrong disk)"
|
|
if [[ "$ENABLE_INSTALLER" != "true" ]]; then
|
|
echo " 2. NOTE: enable_installer is false, so this boots live — games would live in RAM"
|
|
echo " and vanish on reboot. For a real gaming box set \"enable_installer\": true on"
|
|
echo " this kiosk in CoreSystemConfig.json and rebuild, then install to the disk."
|
|
else
|
|
echo " 2. Boot the target machine and run the installer. Give /home its own large"
|
|
echo " partition (or mount a games disk at /home/${KIOSK_USERNAME}/Games) — a Steam"
|
|
echo " library and a few modpacks are hundreds of gigabytes."
|
|
fi
|
|
echo " 3. Confirm it lands in Big Picture with no login prompt, and that a gamepad is"
|
|
echo " recognised (that is steam-devices' udev rules doing their job)."
|
|
echo " 4. Check the box is actually accelerated before blaming any game — from the"
|
|
echo " maintenance shell (Super+Shift+Ctrl+M):"
|
|
echo " vulkaninfo | head -n 20 # should name your GPU, not llvmpipe"
|
|
echo " glxinfo -B # same"
|
|
echo " 5. SET THE WAYVNC PASSWORD — wayvnc will NOT be running until you do:"
|
|
echo " sudo sh -c 'openssl rand -base64 24 > /etc/wayvnc/wayvnc-password'"
|
|
echo " sudo chmod 600 /etc/wayvnc/wayvnc-password"
|
|
echo " sudo chown ${KIOSK_USERNAME}:${KIOSK_USERNAME} /etc/wayvnc/wayvnc-password"
|
|
echo " swaymsg reload"
|
|
echo " 6. Log into Steam on the TV. Until you do, Prism cannot be registered as a"
|
|
echo " non-Steam game (there is no user profile to register it in) and will fall"
|
|
echo " back to launching directly, without Steam Input. After the first login,"
|
|
echo " restart the session (or reboot) — steam-session registers the shortcut on"
|
|
echo " the way in, before Steam starts, because Steam overwrites shortcuts.vdf on"
|
|
echo " exit. Then confirm 'Prism Launcher' is in the Big Picture library and that"
|
|
echo " the pad works inside Minecraft."
|
|
echo " 7. Leave Big Picture and confirm the media session appears: Firefox on 3:web,"
|
|
echo " mpv on 4:media, Spotify on 5:music. Then go back into a game and confirm"
|
|
echo " they are NOT killed (that is deliberate — see configs/session/media-session)."
|
|
echo " 8. Confirm steamtv-agent connected and registered:"
|
|
echo " systemctl status steamtv-agent"
|
|
echo " In Home Assistant, a '${STEAMTV_NAME}' device should appear under the MQTT"
|
|
echo " integration with: Session (sensor), Mode (select), Screen (select), Launch"
|
|
echo " buttons for Steam/Prism/browser/player/Spotify, Stop media apps (button),"
|
|
echo " Audio output (select), Display (switch), Volume (number), Playback state"
|
|
echo " (sensor) and the transport buttons."
|
|
echo " 9. Set the audio output. On a TV box the right sink is usually HDMI, and if the"
|
|
echo " set was off at boot WirePlumber may have defaulted to a headphone jack with"
|
|
echo " nothing in it — the classic 'the game has no sound' report. Pick it in HA's"
|
|
echo " 'Audio output' select; the choice persists across reboots."
|
|
echo
|
|
echo "Then pull the power on the container host and re-check: the box must still boot"
|
|
echo "into Big Picture and play a game. steamtv-agent connects asynchronously and will"
|
|
echo "simply keep retrying."
|
|
echo
|
|
echo "Rebuilding later: edit hosts/steam-tv-box/configs/* or agent/*, then re-run this"
|
|
echo "script — includes.chroot is regenerated from them every time."
|