mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
make the first time install script more inclusive of user actions
This commit is contained in:
Submodule LEDMatrix.wiki updated: a01c72e156...8d2c143954
18
README.md
18
README.md
@@ -246,18 +246,14 @@ sudo nano /boot/firmware/config.txt
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
9. Run the first_time_install.sh with
|
||||
9. First-time installation (recommended)
|
||||
|
||||
```bash
|
||||
chmod +x first_time_install.sh
|
||||
```
|
||||
then
|
||||
|
||||
```bash
|
||||
sudo ./first_time_install.sh
|
||||
```
|
||||
|
||||
to ensure all the permissions are correct.
|
||||
This single script installs services, dependencies, configures permissions and sudoers, and validates the setup.
|
||||
|
||||
-----------------------------------------------------------------------------------
|
||||
|
||||
@@ -882,9 +878,9 @@ sudo ./stop_display.sh
|
||||
|
||||
-----------------------------------------------------------------------------------
|
||||
|
||||
## Web Interface Installation
|
||||
## Web Interface Installation (V2)
|
||||
|
||||
The LEDMatrix system includes a web interface that allows you to control and configure the display remotely. The web interface runs on port 5001 and provides real-time display preview, configuration management, and on-demand display controls.
|
||||
The LEDMatrix system includes Web Interface V2 that runs on port 5001 and provides real-time display preview, configuration management, and on-demand display controls.
|
||||
|
||||
### Installing the Web Interface Service
|
||||
|
||||
@@ -1277,7 +1273,7 @@ For `display_controller.py` and `stop_display.sh`, ensure their file permissions
|
||||
|
||||
## Web Interface V2 (simplified quick start)
|
||||
|
||||
### 1) un the helper (does the above and starts the server):
|
||||
### 1) Run the helper (does the above and starts the server):
|
||||
```
|
||||
python3 start_web_v2.py
|
||||
```
|
||||
@@ -1287,9 +1283,9 @@ python3 start_web_v2.py
|
||||
python web_interface_v2.py
|
||||
```
|
||||
|
||||
### 3) Autostart (optional)
|
||||
### 3) Autostart (recommended)
|
||||
Set `"web_display_autostart": true` in `config/config.json`.
|
||||
Ensure your systemd service (or launcher) calls `start_web_conditionally.py`.
|
||||
Ensure your systemd service calls `start_web_conditionally.py` (installed by `install_service.sh`).
|
||||
|
||||
### 4) Permissions (optional but recommended)
|
||||
- Add the service user to `systemd-journal` for viewing logs without sudo.
|
||||
|
||||
@@ -3,15 +3,44 @@
|
||||
# LED Matrix First-Time Installation Script
|
||||
# This script handles the complete setup for a new LED Matrix installation
|
||||
|
||||
set -e
|
||||
set -Eeuo pipefail
|
||||
|
||||
# Global state for nicer error messages
|
||||
CURRENT_STEP="initialization"
|
||||
|
||||
# Error handler for friendlier failures
|
||||
on_error() {
|
||||
local exit_code=$?
|
||||
local line_no=${1:-unknown}
|
||||
echo "✗ An error occurred during: $CURRENT_STEP (line $line_no, exit $exit_code)" >&2
|
||||
if [ -n "${LOG_FILE:-}" ]; then
|
||||
echo "See the log for details: $LOG_FILE" >&2
|
||||
echo "-- Last 50 lines from log --" >&2
|
||||
tail -n 50 "$LOG_FILE" >&2 || true
|
||||
fi
|
||||
echo "\nCommon fixes:" >&2
|
||||
echo "- Ensure the Pi is online (try: ping -c1 8.8.8.8)." >&2
|
||||
echo "- If you saw an APT lock error: wait a minute, close other installers, then run: sudo dpkg --configure -a" >&2
|
||||
echo "- Re-run this script. It is safe to run multiple times." >&2
|
||||
exit "$exit_code"
|
||||
}
|
||||
trap 'on_error $LINENO' ERR
|
||||
|
||||
echo "=========================================="
|
||||
echo "LED Matrix First-Time Installation Script"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Get the actual user who invoked sudo
|
||||
if [ -n "$SUDO_USER" ]; then
|
||||
# Show device model if available (helps users confirm they're on a Raspberry Pi)
|
||||
if [ -r /proc/device-tree/model ]; then
|
||||
DEVICE_MODEL=$(tr -d '\0' </proc/device-tree/model)
|
||||
echo "Detected device: $DEVICE_MODEL"
|
||||
else
|
||||
echo "⚠ Could not detect Raspberry Pi model (continuing anyway)"
|
||||
fi
|
||||
|
||||
# Get the actual user who invoked sudo (set after we ensure sudo below)
|
||||
if [ -n "${SUDO_USER:-}" ]; then
|
||||
ACTUAL_USER="$SUDO_USER"
|
||||
else
|
||||
ACTUAL_USER=$(whoami)
|
||||
@@ -28,53 +57,149 @@ echo "User home directory: $USER_HOME"
|
||||
echo "Project directory: $PROJECT_ROOT_DIR"
|
||||
echo ""
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
echo "✓ Running as root (required for installation)"
|
||||
else
|
||||
echo "✗ This script must be run as root (use sudo)"
|
||||
echo "Usage: sudo ./first_time_install.sh"
|
||||
exit 1
|
||||
# Check if running as root; if not, try to elevate automatically for novices
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo "This script needs administrator privileges. Attempting to re-run with sudo..."
|
||||
exec sudo -E env LEDMATRIX_ELEVATED=1 bash "$0" "$@"
|
||||
fi
|
||||
echo "✓ Running as root (required for installation)"
|
||||
|
||||
# Initialize logging
|
||||
LOG_DIR="$PROJECT_ROOT_DIR/logs"
|
||||
mkdir -p "$LOG_DIR"
|
||||
LOG_FILE="$LOG_DIR/first_time_install_$(date +%Y%m%d_%H%M%S).log"
|
||||
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||
echo "Logging to: $LOG_FILE"
|
||||
|
||||
# Args and options (novice-friendly defaults)
|
||||
ASSUME_YES=${LEDMATRIX_ASSUME_YES:-0}
|
||||
SKIP_SOUND=${LEDMATRIX_SKIP_SOUND:-0}
|
||||
SKIP_PERF=${LEDMATRIX_SKIP_PERF:-0}
|
||||
SKIP_REBOOT_PROMPT=${LEDMATRIX_SKIP_REBOOT_PROMPT:-0}
|
||||
|
||||
usage() {
|
||||
cat <<USAGE
|
||||
Usage: sudo ./first_time_install.sh [options]
|
||||
|
||||
Options:
|
||||
-y, --yes Proceed without interactive confirmations
|
||||
--force-rebuild Force rebuild of rpi-rgb-led-matrix even if present
|
||||
--skip-sound Skip sound module configuration
|
||||
--skip-perf Skip performance tweaks (isolcpus/audio)
|
||||
--no-reboot-prompt Do not prompt for reboot at the end
|
||||
-h, --help Show this help message and exit
|
||||
|
||||
Environment variables (same effect as flags):
|
||||
LEDMATRIX_ASSUME_YES=1, RPI_RGB_FORCE_REBUILD=1, LEDMATRIX_SKIP_SOUND=1,
|
||||
LEDMATRIX_SKIP_PERF=1, LEDMATRIX_SKIP_REBOOT_PROMPT=1
|
||||
USAGE
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-y|--yes) ASSUME_YES=1 ;;
|
||||
--force-rebuild) RPI_RGB_FORCE_REBUILD=1 ;;
|
||||
--skip-sound) SKIP_SOUND=1 ;;
|
||||
--skip-perf) SKIP_PERF=1 ;;
|
||||
--no-reboot-prompt) SKIP_REBOOT_PROMPT=1 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "Unknown option: $1"; usage; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Helpers
|
||||
retry() {
|
||||
local attempt=1
|
||||
local max_attempts=3
|
||||
local delay_seconds=5
|
||||
while true; do
|
||||
"$@" && return 0
|
||||
local status=$?
|
||||
if [ $attempt -ge $max_attempts ]; then
|
||||
echo "✗ Command failed after $attempt attempts: $*"
|
||||
return $status
|
||||
fi
|
||||
echo "⚠ Command failed (attempt $attempt/$max_attempts). Retrying in ${delay_seconds}s: $*"
|
||||
attempt=$((attempt+1))
|
||||
sleep "$delay_seconds"
|
||||
done
|
||||
}
|
||||
|
||||
apt_update() { retry apt update; }
|
||||
apt_install() { retry apt install -y "$@"; }
|
||||
apt_remove() { apt-get remove -y "$@" || true; }
|
||||
|
||||
check_network() {
|
||||
if command -v ping >/dev/null 2>&1; then
|
||||
if ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
if curl -Is --max-time 5 http://deb.debian.org >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
echo "✗ No internet connectivity detected."
|
||||
echo "Please connect your Raspberry Pi to the internet and re-run this script."
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "This script will perform the following steps:"
|
||||
echo "1. Install system dependencies"
|
||||
echo "2. Fix cache permissions"
|
||||
echo "3. Install main LED Matrix service"
|
||||
echo "4. Install web interface service"
|
||||
echo "5. Configure web interface permissions"
|
||||
echo "6. Configure passwordless sudo access"
|
||||
echo "7. Set up proper file ownership"
|
||||
echo "8. Test the installation"
|
||||
echo "4. Install Python project dependencies (requirements.txt)"
|
||||
echo "5. Build and install rpi-rgb-led-matrix and test import"
|
||||
echo "6. Install web interface dependencies"
|
||||
echo "7. Install web interface service"
|
||||
echo "8. Configure web interface permissions"
|
||||
echo "9. Configure passwordless sudo access"
|
||||
echo "10. Set up proper file ownership"
|
||||
echo "11. Configure sound module to avoid conflicts"
|
||||
echo "12. Apply performance optimizations"
|
||||
echo "13. Test the installation"
|
||||
echo ""
|
||||
|
||||
# Ask for confirmation
|
||||
read -p "Do you want to proceed with the installation? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Installation cancelled."
|
||||
exit 0
|
||||
if [ "$ASSUME_YES" = "1" ]; then
|
||||
echo "Non-interactive mode: proceeding with installation."
|
||||
else
|
||||
read -p "Do you want to proceed with the installation? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Installation cancelled."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
CLEAR='
|
||||
'
|
||||
CURRENT_STEP="Install system dependencies"
|
||||
echo "Step 1: Installing system dependencies..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Ensure network is available before APT operations
|
||||
check_network
|
||||
|
||||
# Update package list
|
||||
apt update
|
||||
apt_update
|
||||
|
||||
# Install required system packages
|
||||
echo "Installing Python packages and dependencies..."
|
||||
apt install -y python3-pip python3-venv python3-dev python3-pil python3-pil.imagetk
|
||||
apt_install python3-pip python3-venv python3-dev python3-pil python3-pil.imagetk build-essential python3-setuptools python3-wheel cython3
|
||||
|
||||
# Install additional system dependencies that might be needed
|
||||
echo "Installing additional system dependencies..."
|
||||
apt install -y git curl wget unzip
|
||||
apt_install git curl wget unzip
|
||||
|
||||
echo "✓ System dependencies installed"
|
||||
echo ""
|
||||
|
||||
CURRENT_STEP="Fix cache permissions"
|
||||
echo "Step 2: Fixing cache permissions..."
|
||||
echo "----------------------------------"
|
||||
|
||||
@@ -92,21 +217,83 @@ else
|
||||
fi
|
||||
echo ""
|
||||
|
||||
CURRENT_STEP="Install main LED Matrix service"
|
||||
echo "Step 3: Installing main LED Matrix service..."
|
||||
echo "---------------------------------------------"
|
||||
|
||||
# Run the main service installation
|
||||
# Run the main service installation (idempotent)
|
||||
if [ -f "$PROJECT_ROOT_DIR/install_service.sh" ]; then
|
||||
echo "Running main service installation..."
|
||||
bash "$PROJECT_ROOT_DIR/install_service.sh"
|
||||
echo "✓ Main LED Matrix service installed"
|
||||
else
|
||||
echo "✗ Main service installation script not found"
|
||||
echo "✗ Main service installation script not found at $PROJECT_ROOT_DIR/install_service.sh"
|
||||
echo "Please ensure you are running this script from the project root: $PROJECT_ROOT_DIR"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "Step 4: Installing web interface dependencies..."
|
||||
CURRENT_STEP="Install project Python dependencies"
|
||||
echo "Step 4: Installing Python project dependencies..."
|
||||
echo "-----------------------------------------------"
|
||||
|
||||
# Install main project Python dependencies
|
||||
cd "$PROJECT_ROOT_DIR"
|
||||
if [ -f "$PROJECT_ROOT_DIR/requirements.txt" ]; then
|
||||
python3 -m pip install --break-system-packages -r "$PROJECT_ROOT_DIR/requirements.txt"
|
||||
else
|
||||
echo "⚠ requirements.txt not found; skipping main dependency install"
|
||||
fi
|
||||
|
||||
echo "✓ Project Python dependencies installed"
|
||||
echo ""
|
||||
|
||||
CURRENT_STEP="Build and install rpi-rgb-led-matrix"
|
||||
echo "Step 5: Building and installing rpi-rgb-led-matrix..."
|
||||
echo "-----------------------------------------------------"
|
||||
|
||||
# If already installed and not forcing rebuild, skip expensive build
|
||||
if python3 -c 'from rgbmatrix import RGBMatrix, RGBMatrixOptions' >/dev/null 2>&1 && [ "${RPI_RGB_FORCE_REBUILD:-0}" != "1" ]; then
|
||||
echo "rgbmatrix Python package already available; skipping build (set RPI_RGB_FORCE_REBUILD=1 to force rebuild)."
|
||||
else
|
||||
# Build and install rpi-rgb-led-matrix Python bindings
|
||||
if [ -d "$PROJECT_ROOT_DIR/rpi-rgb-led-matrix-master" ]; then
|
||||
pushd "$PROJECT_ROOT_DIR/rpi-rgb-led-matrix-master" >/dev/null
|
||||
echo "Building rpi-rgb-led-matrix Python bindings..."
|
||||
make build-python PYTHON=$(which python3)
|
||||
cd bindings/python
|
||||
echo "Installing rpi-rgb-led-matrix Python package..."
|
||||
python3 setup.py install
|
||||
popd >/dev/null
|
||||
else
|
||||
echo "✗ rpi-rgb-led-matrix-master directory not found at $PROJECT_ROOT_DIR"
|
||||
echo "You can clone it with: git submodule update --init --recursive (if applicable)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Running rgbmatrix import test..."
|
||||
if python3 - <<'PY'
|
||||
from importlib.metadata import version, PackageNotFoundError
|
||||
try:
|
||||
from rgbmatrix import RGBMatrix, RGBMatrixOptions
|
||||
try:
|
||||
print("Success! rgbmatrix version:", version('rgbmatrix'))
|
||||
except PackageNotFoundError:
|
||||
print("Success! rgbmatrix installed (version unknown)")
|
||||
except Exception as e:
|
||||
raise SystemExit(f"rgbmatrix import failed: {e}")
|
||||
PY
|
||||
then
|
||||
echo "✓ rpi-rgb-led-matrix installed and verified"
|
||||
else
|
||||
echo "✗ rpi-rgb-led-matrix import test failed"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
CURRENT_STEP="Install web interface dependencies"
|
||||
echo "Step 6: Installing web interface dependencies..."
|
||||
echo "------------------------------------------------"
|
||||
|
||||
# Install web interface dependencies
|
||||
@@ -119,30 +306,54 @@ if [ -f "$PROJECT_ROOT_DIR/install_dependencies_apt.py" ]; then
|
||||
python3 "$PROJECT_ROOT_DIR/install_dependencies_apt.py"
|
||||
else
|
||||
echo "Using pip to install dependencies..."
|
||||
python3 -m pip install --break-system-packages -r requirements_web_v2.txt
|
||||
|
||||
# Install rgbmatrix module from local source
|
||||
echo "Installing rgbmatrix module..."
|
||||
python3 -m pip install --break-system-packages -e rpi-rgb-led-matrix-master/bindings/python
|
||||
if [ -f "$PROJECT_ROOT_DIR/requirements_web_v2.txt" ]; then
|
||||
python3 -m pip install --break-system-packages -r requirements_web_v2.txt
|
||||
else
|
||||
echo "⚠ requirements_web_v2.txt not found; skipping web dependency install"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "✓ Web interface dependencies installed"
|
||||
echo ""
|
||||
|
||||
echo "Step 5: Configuring web interface permissions..."
|
||||
CURRENT_STEP="Install web interface service"
|
||||
echo "Step 7: Installing web interface service..."
|
||||
echo "-------------------------------------------"
|
||||
|
||||
if [ -f "$PROJECT_ROOT_DIR/install_web_service.sh" ]; then
|
||||
bash "$PROJECT_ROOT_DIR/install_web_service.sh"
|
||||
# Ensure systemd sees any new/changed unit files
|
||||
systemctl daemon-reload || true
|
||||
echo "✓ Web interface service installed"
|
||||
else
|
||||
echo "⚠ install_web_service.sh not found; skipping web service installation"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
CURRENT_STEP="Configure web interface permissions"
|
||||
echo "Step 8: Configuring web interface permissions..."
|
||||
echo "------------------------------------------------"
|
||||
|
||||
# Add user to required groups
|
||||
# Add user to required groups (idempotent)
|
||||
echo "Adding user to systemd-journal group..."
|
||||
usermod -a -G systemd-journal "$ACTUAL_USER"
|
||||
if id -nG "$ACTUAL_USER" | grep -qw systemd-journal; then
|
||||
echo "User $ACTUAL_USER already in systemd-journal"
|
||||
else
|
||||
usermod -a -G systemd-journal "$ACTUAL_USER"
|
||||
fi
|
||||
|
||||
echo "Adding user to adm group..."
|
||||
usermod -a -G adm "$ACTUAL_USER"
|
||||
if id -nG "$ACTUAL_USER" | grep -qw adm; then
|
||||
echo "User $ACTUAL_USER already in adm"
|
||||
else
|
||||
usermod -a -G adm "$ACTUAL_USER"
|
||||
fi
|
||||
|
||||
echo "✓ User added to required groups"
|
||||
echo ""
|
||||
|
||||
echo "Step 6: Configuring passwordless sudo access..."
|
||||
CURRENT_STEP="Configure passwordless sudo access"
|
||||
echo "Step 9: Configuring passwordless sudo access..."
|
||||
echo "------------------------------------------------"
|
||||
|
||||
# Create sudoers configuration for the web interface
|
||||
@@ -175,15 +386,21 @@ $ACTUAL_USER ALL=(ALL) NOPASSWD: $BASH_PATH $PROJECT_ROOT_DIR/start_display.sh
|
||||
$ACTUAL_USER ALL=(ALL) NOPASSWD: $BASH_PATH $PROJECT_ROOT_DIR/stop_display.sh
|
||||
EOF
|
||||
|
||||
# Install the sudoers file
|
||||
cp /tmp/ledmatrix_web_sudoers "$SUDOERS_FILE"
|
||||
chmod 440 "$SUDOERS_FILE"
|
||||
rm /tmp/ledmatrix_web_sudoers
|
||||
if [ -f "$SUDOERS_FILE" ] && cmp -s /tmp/ledmatrix_web_sudoers "$SUDOERS_FILE"; then
|
||||
echo "Sudoers configuration already up to date"
|
||||
rm /tmp/ledmatrix_web_sudoers
|
||||
else
|
||||
echo "Installing/updating sudoers configuration..."
|
||||
cp /tmp/ledmatrix_web_sudoers "$SUDOERS_FILE"
|
||||
chmod 440 "$SUDOERS_FILE"
|
||||
rm /tmp/ledmatrix_web_sudoers
|
||||
fi
|
||||
|
||||
echo "✓ Passwordless sudo access configured"
|
||||
echo ""
|
||||
|
||||
echo "Step 7: Setting proper file ownership..."
|
||||
CURRENT_STEP="Set proper file ownership"
|
||||
echo "Step 10: Setting proper file ownership..."
|
||||
echo "----------------------------------------"
|
||||
|
||||
# Set ownership of project files to the user
|
||||
@@ -199,7 +416,100 @@ fi
|
||||
echo "✓ File ownership configured"
|
||||
echo ""
|
||||
|
||||
echo "Step 8: Testing the installation..."
|
||||
CURRENT_STEP="Sound module configuration"
|
||||
echo "Step 11: Sound module configuration..."
|
||||
echo "-------------------------------------"
|
||||
|
||||
# Remove services that may interfere with LED matrix timing
|
||||
echo "Removing potential conflicting services (bluetooth and others)..."
|
||||
if [ "$SKIP_SOUND" = "1" ]; then
|
||||
echo "Skipping sound module configuration as requested (--skip-sound)."
|
||||
elif apt_remove bluez bluez-firmware pi-bluetooth triggerhappy pigpio; then
|
||||
echo "✓ Unnecessary services removed (or not present)"
|
||||
else
|
||||
echo "⚠ Some packages could not be removed; continuing"
|
||||
fi
|
||||
|
||||
# Blacklist onboard sound module (idempotent)
|
||||
BLACKLIST_FILE="/etc/modprobe.d/blacklist-rgb-matrix.conf"
|
||||
if [ -f "$BLACKLIST_FILE" ] && grep -q '^blacklist snd_bcm2835\b' "$BLACKLIST_FILE"; then
|
||||
echo "snd_bcm2835 already blacklisted in $BLACKLIST_FILE"
|
||||
else
|
||||
echo "Ensuring snd_bcm2835 is blacklisted in $BLACKLIST_FILE..."
|
||||
mkdir -p "/etc/modprobe.d"
|
||||
if [ -f "$BLACKLIST_FILE" ]; then
|
||||
cp "$BLACKLIST_FILE" "$BLACKLIST_FILE.bak" 2>/dev/null || true
|
||||
fi
|
||||
# Append once (don't clobber existing unrelated content)
|
||||
if [ -f "$BLACKLIST_FILE" ]; then
|
||||
echo "blacklist snd_bcm2835" >> "$BLACKLIST_FILE"
|
||||
else
|
||||
printf "blacklist snd_bcm2835\n" > "$BLACKLIST_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update initramfs if available
|
||||
if command -v update-initramfs >/dev/null 2>&1; then
|
||||
echo "Updating initramfs..."
|
||||
update-initramfs -u
|
||||
else
|
||||
echo "update-initramfs not found; skipping"
|
||||
fi
|
||||
|
||||
echo "✓ Sound module configuration applied"
|
||||
echo ""
|
||||
|
||||
CURRENT_STEP="Apply performance optimizations"
|
||||
echo "Step 12: Applying performance optimizations..."
|
||||
echo "---------------------------------------------"
|
||||
|
||||
# Prefer /boot/firmware on newer Raspberry Pi OS, fall back to /boot on older
|
||||
CMDLINE_FILE="/boot/firmware/cmdline.txt"
|
||||
CONFIG_FILE="/boot/firmware/config.txt"
|
||||
if [ ! -f "$CMDLINE_FILE" ]; then CMDLINE_FILE="/boot/cmdline.txt"; fi
|
||||
if [ ! -f "$CONFIG_FILE" ]; then CONFIG_FILE="/boot/config.txt"; fi
|
||||
|
||||
# Append isolcpus=3 to cmdline if not present (idempotent)
|
||||
if [ "$SKIP_PERF" = "1" ]; then
|
||||
echo "Skipping performance optimizations as requested (--skip-perf)."
|
||||
elif [ -f "$CMDLINE_FILE" ]; then
|
||||
if grep -q '\bisolcpus=3\b' "$CMDLINE_FILE"; then
|
||||
echo "isolcpus=3 already present in $CMDLINE_FILE"
|
||||
else
|
||||
echo "Adding isolcpus=3 to $CMDLINE_FILE..."
|
||||
cp "$CMDLINE_FILE" "$CMDLINE_FILE.bak" 2>/dev/null || true
|
||||
# Ensure single-line cmdline gets the flag once, with a leading space
|
||||
sed -i '1 s/$/ isolcpus=3/' "$CMDLINE_FILE"
|
||||
fi
|
||||
else
|
||||
echo "✗ $CMDLINE_FILE not found; skipping isolcpus optimization"
|
||||
fi
|
||||
|
||||
# Ensure dtparam=audio=off in config.txt (idempotent)
|
||||
if [ "$SKIP_PERF" = "1" ]; then
|
||||
: # skipped
|
||||
elif [ -f "$CONFIG_FILE" ]; then
|
||||
if grep -q '^dtparam=audio=off\b' "$CONFIG_FILE"; then
|
||||
echo "Onboard audio already disabled in $CONFIG_FILE"
|
||||
elif grep -q '^dtparam=audio=on\b' "$CONFIG_FILE"; then
|
||||
echo "Disabling onboard audio in $CONFIG_FILE..."
|
||||
cp "$CONFIG_FILE" "$CONFIG_FILE.bak" 2>/dev/null || true
|
||||
sed -i 's/^dtparam=audio=on\b/dtparam=audio=off/' "$CONFIG_FILE"
|
||||
else
|
||||
echo "Adding dtparam=audio=off to $CONFIG_FILE..."
|
||||
cp "$CONFIG_FILE" "$CONFIG_FILE.bak" 2>/dev/null || true
|
||||
printf "\n# Disable onboard audio for LED matrix performance\n" >> "$CONFIG_FILE"
|
||||
echo "dtparam=audio=off" >> "$CONFIG_FILE"
|
||||
fi
|
||||
else
|
||||
echo "✗ $CONFIG_FILE not found; skipping audio disable"
|
||||
fi
|
||||
|
||||
echo "✓ Performance optimizations applied"
|
||||
echo ""
|
||||
|
||||
CURRENT_STEP="Test the installation"
|
||||
echo "Step 13: Testing the installation..."
|
||||
echo "----------------------------------"
|
||||
|
||||
# Test sudo access
|
||||
@@ -233,6 +543,20 @@ else
|
||||
fi
|
||||
|
||||
echo ""
|
||||
if [ "$SKIP_REBOOT_PROMPT" = "1" ]; then
|
||||
echo "Skipping reboot prompt as requested (--no-reboot-prompt)."
|
||||
elif [ "$ASSUME_YES" = "1" ]; then
|
||||
echo "Non-interactive mode: rebooting now to apply changes..."
|
||||
reboot
|
||||
else
|
||||
read -p "A reboot is recommended to apply kernel and audio changes. Reboot now? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "Rebooting now..."
|
||||
reboot
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "Installation Complete!"
|
||||
echo "=========================================="
|
||||
|
||||
@@ -96,18 +96,26 @@ sudo nano /boot/firmware/config.txt
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
9. Run the first_time_install.sh with
|
||||
```
|
||||
9. Run the first_time_install.sh
|
||||
```bash
|
||||
chmod +x first_time_install.sh
|
||||
sudo ./first_time_install.sh
|
||||
```
|
||||
to ensure all the permissions are correct.
|
||||
|
||||
10. Then run
|
||||
This handles dependency setup, service installation, permissions, and sudoers configuration.
|
||||
|
||||
10. Web Interface (V2)
|
||||
|
||||
- If `"web_display_autostart": true` is set in `config/config.json` (recommended), the web interface will be started by the installed service.
|
||||
- Access the web UI at:
|
||||
```
|
||||
sudo python start_web_conditionally.py
|
||||
http://your-pi-ip:5001
|
||||
```
|
||||
to start the web ui and download the r
|
||||
- To launch manually instead of using the service:
|
||||
```bash
|
||||
python3 start_web_v2.py
|
||||
```
|
||||
This installs any missing dependencies and starts `web_interface_v2.py` on port 5001.
|
||||
-----------------------------------------------------------------------------------
|
||||
|
||||
## Configuration
|
||||
@@ -17,7 +17,7 @@ The web interface provides:
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- LEDMatrix system already installed and configured
|
||||
- LEDMatrix system already installed and configured (or run `first_time_install.sh` first)
|
||||
- Python 3.7+ installed
|
||||
- Network access to the Raspberry Pi
|
||||
|
||||
|
||||
@@ -38,6 +38,10 @@ Detailed documentation for each display manager and their configuration options.
|
||||
- [General Troubleshooting](WIKI_TROUBLESHOOTING.md)
|
||||
- [MiLB Troubleshooting](MILB_TROUBLESHOOTING.md)
|
||||
|
||||
## 🚀 Install & Quick Start
|
||||
- [Installation Guide](INSTALLATION_GUIDE.md)
|
||||
- [Quick Start](WIKI_QUICK_START.md)
|
||||
|
||||
---
|
||||
|
||||
## Quick Navigation
|
||||
|
||||
@@ -2,6 +2,23 @@
|
||||
|
||||
Get your LEDMatrix system up and running in minutes! This guide covers the essential steps to get your display working.
|
||||
|
||||
## Fast Path (Recommended)
|
||||
|
||||
If this is a brand new install, you can run the all-in-one installer and then use the web UI:
|
||||
|
||||
```bash
|
||||
chmod +x first_time_install.sh
|
||||
sudo ./first_time_install.sh
|
||||
```
|
||||
|
||||
Then open the web UI at:
|
||||
|
||||
```
|
||||
http://your-pi-ip:5001
|
||||
```
|
||||
|
||||
The steps below document the manual process for advanced users.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Hardware Requirements
|
||||
@@ -219,7 +236,23 @@ sudo ./start_display.sh
|
||||
sudo ./stop_display.sh
|
||||
```
|
||||
|
||||
## Step 8: Add More Features
|
||||
## Step 8: Web Interface (V2)
|
||||
|
||||
### 8.1 Start the web interface manually (optional)
|
||||
```bash
|
||||
python3 start_web_v2.py
|
||||
```
|
||||
|
||||
### 8.2 Autostart the web interface (recommended)
|
||||
Set `"web_display_autostart": true` in `config/config.json`.
|
||||
The installed `ledmatrix-web.service` will call `start_web_conditionally.py` to start the web UI on boot.
|
||||
|
||||
Access the web interface at:
|
||||
```
|
||||
http://your-pi-ip:5001
|
||||
```
|
||||
|
||||
## Step 9: Add More Features
|
||||
|
||||
### 8.1 Enable Stocks
|
||||
Edit `config/config.json`:
|
||||
|
||||
30
wiki/_Sidebar.md
Normal file
30
wiki/_Sidebar.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## LEDMatrix Wiki
|
||||
|
||||
- [Home](WIKI_HOME.md)
|
||||
|
||||
### Get Started
|
||||
- [Quick Start](WIKI_QUICK_START.md)
|
||||
- [Installation Guide](INSTALLATION_GUIDE.md)
|
||||
|
||||
### Configure & Use
|
||||
- [Configuration Guide](WIKI_CONFIGURATION.md)
|
||||
- [Display Managers](WIKI_DISPLAY_MANAGERS.md)
|
||||
- [Web Interface Installation](WEB_INTERFACE_INSTALLATION.md)
|
||||
- [Web Interface V2 Enhancements](WEB_INTERFACE_V2_ENHANCED_SUMMARY.md)
|
||||
|
||||
### Features
|
||||
- [News Manager](NEWS_MANAGER_README.md)
|
||||
- [Custom RSS Feeds](CUSTOM_FEEDS_GUIDE.md)
|
||||
- [Dynamic Duration (Overview)](dynamic_duration.md)
|
||||
- [Dynamic Duration Guide](DYNAMIC_DURATION_GUIDE.md)
|
||||
- [Dynamic Duration (Stocks)](DYNAMIC_DURATION_STOCKS_IMPLEMENTATION.md)
|
||||
|
||||
### Performance & Caching
|
||||
- [Cache Strategy](CACHE_STRATEGY.md)
|
||||
- [Cache Management](cache_management.md)
|
||||
|
||||
### Troubleshooting
|
||||
- [General Troubleshooting](WIKI_TROUBLESHOOTING.md)
|
||||
- [MiLB Troubleshooting](MILB_TROUBLESHOOTING.md)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user