#!/bin/bash # Installs Paperwall on this machine, in place. Standalone -- doesn't require # InkyPi to be installed. If InkyPi (or anything else) happens to already be # running against the same panel, this stops it, since two processes can't # both drive the same SPI display. # # Run this ON the Pi, from wherever you copied the project folder to (e.g. # via SFTP): `sudo bash install.sh` set -euo pipefail # Resolve the real directory this script lives in, even through symlinks. SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd) SOURCE=$(readlink "$SOURCE") [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" done APP_DIR=$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd) VENV_DIR="$APP_DIR/venv" SERVICE_NAME="paperwall.service" SERVICE_TARGET="/etc/systemd/system/$SERVICE_NAME" CONFIG_TXT="/boot/firmware/config.txt" [ -f "$CONFIG_TXT" ] || CONFIG_TXT="/boot/config.txt" step() { echo -e "\n==> $1"; } check_permissions() { if [ "$EUID" -ne 0 ]; then echo "ERROR: run with sudo (sudo bash install.sh)" >&2 exit 1 fi } install_system_dependencies() { step "Installing system dependencies (python3-venv, lgpio/spidev build deps)" apt-get update -qq apt-get install -y -qq python3-venv python3-pip python3-dev liblgpio-dev swig } enable_spi_i2c() { step "Enabling SPI/I2C in $CONFIG_TXT" if [ ! -f "$CONFIG_TXT" ]; then echo " WARNING: $CONFIG_TXT not found -- enable SPI/I2C manually for your platform." >&2 return fi if grep -qE '^\s*dtparam=spi=on' "$CONFIG_TXT"; then echo " SPI already enabled." else sed -i -E 's/^#?\s*dtparam=spi=.*/dtparam=spi=on/' "$CONFIG_TXT" grep -qE '^\s*dtparam=spi=on' "$CONFIG_TXT" || echo "dtparam=spi=on" >> "$CONFIG_TXT" echo " SPI enabled (reboot required)." fi # This panel uses both SPI chip-select lines. if ! grep -qE '^\s*dtoverlay=spi0-2cs' "$CONFIG_TXT"; then echo "dtoverlay=spi0-2cs" >> "$CONFIG_TXT" echo " Added dtoverlay=spi0-2cs (reboot required)." fi if grep -qE '^\s*dtparam=i2c_arm=on' "$CONFIG_TXT"; then echo " I2C already enabled." else sed -i -E 's/^#?\s*dtparam=i2c_arm=.*/dtparam=i2c_arm=on/' "$CONFIG_TXT" grep -qE '^\s*dtparam=i2c_arm=on' "$CONFIG_TXT" || echo "dtparam=i2c_arm=on" >> "$CONFIG_TXT" echo " I2C enabled (reboot required)." fi } create_venv() { step "Creating Python virtual environment at $VENV_DIR" python3 -m venv "$VENV_DIR" "$VENV_DIR/bin/python" -m pip install --upgrade -q pip "$VENV_DIR/bin/python" -m pip install -q -r "$APP_DIR/requirements.txt" -r "$APP_DIR/requirements-pi.txt" echo " done." } stop_conflicting_services() { step "Checking for other software already driving this panel" if systemctl list-unit-files inkypi.service >/dev/null 2>&1 && systemctl is-active --quiet inkypi.service; then systemctl disable --now inkypi.service echo " Stopped and disabled inkypi.service (left installed, not removed)." else echo " Nothing else running against the panel." fi } install_service() { step "Installing $SERVICE_NAME" sed \ -e "s#{{APP_DIR}}#$APP_DIR#g" \ -e "s#{{PYTHON}}#$VENV_DIR/bin/python3#g" \ "$APP_DIR/paperwall.service.template" > "$SERVICE_TARGET" systemctl daemon-reload systemctl enable --now "$SERVICE_NAME" echo " installed and started." } show_status() { step "Status" sleep 2 systemctl status "$SERVICE_NAME" --no-pager -l | head -15 || true ip_address=$(hostname -I | awk '{print $1}') echo echo "Web UI: http://$ip_address:8080 (or http://$(hostname).local:8080)" echo "Logs: journalctl -u $SERVICE_NAME -f" echo "Remove: sudo bash uninstall.sh" if grep -qE '^\s*dtoverlay=spi0-2cs' "$CONFIG_TXT" 2>/dev/null; then echo echo "NOTE: if SPI/I2C were just newly enabled above, reboot for that to take effect:" echo " sudo reboot" fi } check_permissions install_system_dependencies enable_spi_i2c create_venv stop_conflicting_services install_service show_status