- README: add 'What you'll need', overview, and a 'Prepare the Pi and get the code' step (git clone) so a non-expert can set up from a blank Pi; flag the non-'pi' default username gotcha. - Add config.example.yaml and install-ola.sh; update install.sh and the systemd unit for the env-file/OLA-from-source workflow. - Remove the local Home Assistant/Mosquitto test files from the repo and ignore config.yaml (holds the MQTT password).
149 lines
5.9 KiB
Bash
149 lines
5.9 KiB
Bash
#!/bin/bash
|
|
#
|
|
# install-ola.sh - Build and install the Open Lighting Architecture (OLA) from
|
|
# source on Debian/Raspbian. Verified on Raspberry Pi OS / Raspbian 13 (Trixie)
|
|
# on a single-core ARMv6 Pi (Pi Zero / Pi 1).
|
|
#
|
|
# OLA is not packaged for recent Debian/Raspbian releases, so we build the
|
|
# 0.10.9 release tag from git. This installs the build dependencies, the C++
|
|
# daemon (olad) and the Python client bindings (ola.ClientWrapper) that
|
|
# lutron-dmx-control.py needs when DMX is enabled.
|
|
#
|
|
# Usage (run as a normal user that can sudo, or as root):
|
|
# bash ./install-ola.sh
|
|
#
|
|
# Override the version, build location, or parallel-make jobs if needed:
|
|
# OLA_VERSION=0.10.9 BUILD_DIR=~/ola-build JOBS=4 bash ./install-ola.sh
|
|
#
|
|
# Build the OLA docs reference: https://www.openlighting.org/ola/linuxinstall/
|
|
|
|
set -e
|
|
|
|
OLA_VERSION="${OLA_VERSION:-0.10.9}"
|
|
BUILD_DIR="${BUILD_DIR:-$HOME/ola-build}"
|
|
OLA_REPO="${OLA_REPO:-https://github.com/OpenLightingProject/ola.git}"
|
|
|
|
# Use sudo only when we are not already root.
|
|
if [ "$(id -u)" -eq 0 ]; then
|
|
SUDO=""
|
|
else
|
|
SUDO="sudo"
|
|
if ! command -v sudo >/dev/null 2>&1; then
|
|
echo "This script needs root (apt + make install). Install sudo or run as root."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo "==> Installing build dependencies"
|
|
$SUDO apt-get update
|
|
# Dev packages pull in the matching runtime libraries automatically. The Python
|
|
# client bindings need python3-protobuf and python3-dev.
|
|
$SUDO apt-get install -y \
|
|
git build-essential libtool autoconf automake pkg-config \
|
|
bison flex make g++ \
|
|
libcppunit-dev uuid-dev zlib1g-dev libncurses5-dev \
|
|
protobuf-compiler libprotobuf-dev libprotoc-dev \
|
|
libmicrohttpd-dev libftdi1-dev libusb-1.0-0-dev \
|
|
libavahi-client-dev \
|
|
python3 python3-dev python3-protobuf python3-numpy
|
|
|
|
# On low-memory boards (e.g. the 512MB Pi Zero) the protobuf-heavy C++ files
|
|
# exhaust RAM and the compiler is OOM-killed. Add temporary swap for the build
|
|
# and remove it afterwards. Skipped when there is already plenty of RAM+swap.
|
|
SWAPFILE="/swapfile-ola-build"
|
|
ADDED_SWAP=0
|
|
mem_kb=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
|
|
swap_kb=$(awk '/SwapTotal/ {print $2}' /proc/meminfo)
|
|
LOW_MEM=0
|
|
if [ "$((mem_kb + swap_kb))" -lt 2097152 ]; then
|
|
LOW_MEM=1
|
|
if [ ! -f "$SWAPFILE" ]; then
|
|
echo "==> Low memory detected ($(((mem_kb + swap_kb) / 1024))MB RAM+swap); adding 2G temporary build swap"
|
|
$SUDO fallocate -l 2G "$SWAPFILE" || $SUDO dd if=/dev/zero of="$SWAPFILE" bs=1M count=2048
|
|
$SUDO chmod 600 "$SWAPFILE"
|
|
$SUDO mkswap "$SWAPFILE" >/dev/null
|
|
$SUDO swapon "$SWAPFILE"
|
|
ADDED_SWAP=1
|
|
fi
|
|
fi
|
|
|
|
# Pick the parallel-make job count. On a low-memory board, a full -j<cores> build
|
|
# of the protobuf-heavy C++ thrashes swap and can still get OOM-killed, so cap it
|
|
# (a single-core Pi is unaffected -- nproc is 1 there anyway). Override with JOBS=.
|
|
if [ -n "$JOBS" ]; then
|
|
:
|
|
elif [ "$LOW_MEM" -eq 1 ]; then
|
|
JOBS=$([ "$(nproc)" -gt 2 ] && echo 2 || nproc)
|
|
else
|
|
JOBS=$(nproc)
|
|
fi
|
|
|
|
cleanup_swap() {
|
|
if [ "$ADDED_SWAP" -eq 1 ]; then
|
|
echo "==> Removing temporary build swap"
|
|
$SUDO swapoff "$SWAPFILE" 2>/dev/null || true
|
|
$SUDO rm -f "$SWAPFILE"
|
|
fi
|
|
}
|
|
trap cleanup_swap EXIT
|
|
|
|
# If an already-configured tree exists, resume it instead of starting over -
|
|
# make picks up where it left off. Re-running after an interrupted build (the
|
|
# Pi is slow; the compile can take 1-2 hours) just continues.
|
|
if [ -f "$BUILD_DIR/Makefile" ] && [ -f "$BUILD_DIR/config.status" ]; then
|
|
echo "==> Found a configured build in $BUILD_DIR; resuming"
|
|
cd "$BUILD_DIR"
|
|
else
|
|
echo "==> Fetching OLA $OLA_VERSION into $BUILD_DIR"
|
|
if [ -d "$BUILD_DIR/.git" ]; then
|
|
git -C "$BUILD_DIR" fetch --depth 1 origin "refs/tags/$OLA_VERSION:refs/tags/$OLA_VERSION"
|
|
git -C "$BUILD_DIR" checkout -f "$OLA_VERSION"
|
|
else
|
|
rm -rf "$BUILD_DIR"
|
|
git clone --depth 1 --branch "$OLA_VERSION" "$OLA_REPO" "$BUILD_DIR"
|
|
fi
|
|
cd "$BUILD_DIR"
|
|
|
|
echo "==> Generating the build system (autoreconf)"
|
|
autoreconf -i
|
|
|
|
# --enable-python-libs: build/install the Python client (ola.ClientWrapper).
|
|
# --disable-fatal-warnings: OLA 0.10.9 predates GCC 14; without this the new
|
|
# default warnings are treated as errors (-Werror).
|
|
# --disable-osc: OLA 0.10.9's OSC plugin uses an old liblo API that
|
|
# no longer compiles against Trixie's liblo. We do
|
|
# not use OSC (DMX/sACN only), so disable it.
|
|
echo "==> Configuring"
|
|
PYTHON=python3 ./configure --enable-python-libs --disable-fatal-warnings --disable-osc
|
|
fi
|
|
|
|
echo "==> Building with -j$JOBS (this is slow on a single-core Pi; ~1-2 hours on a Pi Zero)"
|
|
make -j"$JOBS"
|
|
|
|
echo "==> Installing"
|
|
$SUDO make install
|
|
$SUDO ldconfig
|
|
|
|
# OLA installs its Python module to .../site-packages, but Debian's python3 only
|
|
# searches .../dist-packages, so 'import ola' fails out of the box. Link the
|
|
# installed package into the dist-packages dir that is actually on sys.path.
|
|
SITE_OLA=$(find /usr/local/lib/python3*/site-packages -maxdepth 1 -name ola -type d 2>/dev/null | head -1)
|
|
if [ -n "$SITE_OLA" ] && ! python3 -c "import ola" 2>/dev/null; then
|
|
PYDIR=$(dirname "$(dirname "$SITE_OLA")")
|
|
DIST="$PYDIR/dist-packages"
|
|
echo "==> Linking OLA Python module into $DIST (Debian dist-packages)"
|
|
$SUDO mkdir -p "$DIST"
|
|
$SUDO ln -sfn ../site-packages/ola "$DIST/ola"
|
|
fi
|
|
|
|
echo "==> Verifying"
|
|
olad --version || true
|
|
if python3 -c "import ola.ClientWrapper" 2>/dev/null; then
|
|
echo " Python bindings (ola.ClientWrapper) import OK"
|
|
else
|
|
echo " WARNING: 'import ola.ClientWrapper' failed - check the install log above."
|
|
fi
|
|
|
|
echo
|
|
echo "OLA $OLA_VERSION installed. olad lives at $(command -v olad 2>/dev/null || echo /usr/local/bin/olad)."
|
|
echo "Next: install.sh sets up the olad@<user> and lutron-dmx-control@<user> services."
|