#!/usr/bin/env bash # EG4 LifePower4 → Home Assistant monitoring — reproducible installer. # # Installs the eg4-battery daemon onto /usr/local/bin (uv handles deps via the # script's PEP-723 inline metadata), drops in the udev rule + systemd unit, # and seeds the config template. Idempotent: safe to re-run. # # Assumptions: # - Debian-family Linux with systemd # - `uv` on $PATH (https://docs.astral.sh/uv/) # - User has sudo # # After install, finish by editing: # ~/.config/eg4-battery/eg4-battery.yaml — bus.port, MQTT creds, pack addresses # then: # ./install.sh --dry-run — end-to-end smoke test (no HW needed) # sudo systemctl enable --now eg4-battery.service # journalctl -u eg4-battery.service -f set -euo pipefail BASE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DRY_RUN=0 for arg in "$@"; do [ "$arg" = "--dry-run" ] && DRY_RUN=1 done msg() { printf '\n\033[1;36m== %s ==\033[0m\n' "$*"; } # --- 1. dependency check --------------------------------------------------- msg "Checking prerequisites" command -v uv >/dev/null || { echo "uv not found — install from https://docs.astral.sh/uv/"; exit 1; } # --- 2. entry point -------------------------------------------------------- msg "Installing /usr/local/bin/eg4-battery" sudo install -m 755 "${BASE}/bin/eg4-battery" /usr/local/bin/eg4-battery # --- 3. udev rule ---------------------------------------------------------- msg "Installing udev rule (FTDI/CH340/CP210x → dialout)" sudo install -m 644 "${BASE}/etc/udev/rules.d/99-eg4-rs485.rules" /etc/udev/rules.d/99-eg4-rs485.rules sudo udevadm control --reload-rules sudo udevadm trigger --subsystem-match=tty # --- 4. systemd unit ------------------------------------------------------- msg "Installing systemd unit" sudo install -m 644 "${BASE}/etc/systemd/system/eg4-battery.service" /etc/systemd/system/eg4-battery.service sudo systemctl daemon-reload # --- 5. user config (only if not already present) -------------------------- msg "Installing config template" mkdir -p "${HOME}/.config/eg4-battery" dest="${HOME}/.config/eg4-battery/eg4-battery.yaml" if [ -e "$dest" ]; then echo " $dest already exists — not overwriting" else install -m 600 "${BASE}/config/eg4-battery.yaml.example" "$dest" echo " wrote $dest (mode 600) — edit bus.port, MQTT creds, pack addresses" fi # --- 6. smoke test --------------------------------------------------------- if [ "$DRY_RUN" = "1" ]; then msg "Dry-run: running one mock-bus cycle (no MQTT publish)" /usr/local/bin/eg4-battery -C "$dest" --dry-run echo echo "(above output is what would be published to MQTT under real run)" fi # --- 7. enable ------------------------------------------------------------- if grep -q '' "$dest" 2>/dev/null; then cat <