Files
shaggy-solar/LVX6048/install.sh

127 lines
6.4 KiB
Bash
Raw Normal View History

2026-04-24 16:34:10 -04:00
#!/usr/bin/env bash
# LVX6048 → Home Assistant monitoring — reproducible installer.
#
# Installs powermon + our patches, drops in udev rule / systemd units / resolver
# script / powermon configs, and starts the services. Idempotent: safe to re-run.
#
# Assumptions:
# - Debian-family Linux (Raspberry Pi OS, Ubuntu) with systemd
# - `uv` is installed and on $PATH (https://docs.astral.sh/uv/)
# - User has sudo
# - MQTT broker reachable (edit config/powermon/*.yaml first if the broker IP /
# credentials aren't yet in place)
#
# After install, finish by editing:
# ~/.config/powermon/powermon{,2}.yaml — MQTT broker + credentials
# /usr/local/sbin/lvx-resolve-links — SERIAL_UNIT_1 / SERIAL_UNIT_2
# lvx-flash/flash.py — SERIAL_UNIT_1 / SERIAL_UNIT_2
# then:
# sudo systemctl restart lvx-resolve-links powermon.service powermon2.service
set -euo pipefail
PINNED_POWERMON="1.0.18" # version we developed/tested patches against
BASE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
msg() { printf '\n\033[1;36m== %s ==\033[0m\n' "$*"; }
# --- 1. powermon -----------------------------------------------------------
msg "Installing powermon ${PINNED_POWERMON} via uv"
command -v uv >/dev/null || { echo "uv not found — install from https://docs.astral.sh/uv/"; exit 1; }
uv tool install --with bleak "powermon==${PINNED_POWERMON}"
POWERMON_VENV="${HOME}/.local/share/uv/tools/powermon"
POWERMON_SITE="$(ls -d "${POWERMON_VENV}"/lib/python*/site-packages/powermon)"
POWERMON_PY="${POWERMON_VENV}/bin/python"
[ -d "$POWERMON_SITE" ] || { echo "could not locate powermon site-packages under ${POWERMON_VENV}"; exit 1; }
# --- 2. powermon patches ---------------------------------------------------
msg "Applying powermon patches into ${POWERMON_SITE}"
install -m 644 "${BASE}/powermon-patches/pi18.py" "${POWERMON_SITE}/protocols/pi18.py"
install -m 644 "${BASE}/powermon-patches/port_config_model.py" "${POWERMON_SITE}/configmodel/port_config_model.py"
install -m 644 "${BASE}/powermon-patches/ports_init.py" "${POWERMON_SITE}/ports/__init__.py"
install -m 644 "${BASE}/powermon-patches/usbport.py" "${POWERMON_SITE}/ports/usbport.py"
install -m 644 "${BASE}/powermon-patches/mqttbroker.py" "${POWERMON_SITE}/libs/mqttbroker.py"
2026-04-26 08:49:05 -04:00
install -m 644 "${BASE}/powermon-patches/hass.py" "${POWERMON_SITE}/outputformats/hass.py"
2026-04-24 16:34:10 -04:00
# --- 3. udev (LVX6048 hidraw → dialout perms) ------------------------------
msg "Installing udev rule"
sudo install -m 644 "${BASE}/etc/udev/rules.d/99-lvx6048.rules" /etc/udev/rules.d/99-lvx6048.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --subsystem-match=hidraw
# --- 4. resolver script (serial → /dev/lvx6048-N symlinks) -----------------
msg "Installing /usr/local/sbin/lvx-resolve-links (shebang → ${POWERMON_PY})"
TMP_RESOLVER="$(mktemp)"
trap 'rm -f "$TMP_RESOLVER"' EXIT
awk -v py="${POWERMON_PY}" 'NR==1 { print "#!" py; next } { print }' \
"${BASE}/bin/lvx-resolve-links" > "$TMP_RESOLVER"
sudo install -m 755 "$TMP_RESOLVER" /usr/local/sbin/lvx-resolve-links
# --- 5. systemd units + drop-ins -------------------------------------------
msg "Installing systemd units"
sudo install -m 644 "${BASE}/etc/systemd/system/lvx-resolve-links.service" /etc/systemd/system/
sudo install -m 644 "${BASE}/etc/systemd/system/lvx-resolve-links.timer" /etc/systemd/system/
2026-04-27 06:50:04 -04:00
sudo install -m 644 "${BASE}/etc/systemd/system/lvx-control.service" /etc/systemd/system/
2026-04-24 16:34:10 -04:00
sudo install -m 644 "${BASE}/etc/systemd/system/powermon.service" /etc/systemd/system/
sudo install -m 644 "${BASE}/etc/systemd/system/powermon2.service" /etc/systemd/system/
sudo mkdir -p /etc/systemd/system/powermon.service.d /etc/systemd/system/powermon2.service.d
sudo install -m 644 "${BASE}/etc/systemd/system/powermon.service.d/10-resolver.conf" \
/etc/systemd/system/powermon.service.d/10-resolver.conf
sudo install -m 644 "${BASE}/etc/systemd/system/powermon2.service.d/10-resolver.conf" \
/etc/systemd/system/powermon2.service.d/10-resolver.conf
sudo systemctl daemon-reload
2026-04-27 06:50:04 -04:00
# --- 5b. lvx-control script (HA → powermon adhoc bridge) -------------------
msg "Installing /usr/local/bin/lvx-control (shebang → ${POWERMON_PY})"
TMP_CONTROL="$(mktemp)"
trap 'rm -f "$TMP_RESOLVER" "$TMP_CONTROL"' EXIT
awk -v py="${POWERMON_PY}" 'NR==1 { print "#!" py; next } { print }' \
"${BASE}/lvx-control/lvx-control" > "$TMP_CONTROL"
sudo install -m 755 "$TMP_CONTROL" /usr/local/bin/lvx-control
2026-04-24 16:34:10 -04:00
# --- 6. user configs (only if not already deployed; don't clobber creds) ---
msg "Installing powermon configs (skipping existing files — edit creds manually if new)"
mkdir -p "${HOME}/.config/powermon"
for f in powermon.yaml powermon2.yaml; do
dest="${HOME}/.config/powermon/${f}"
if [ -e "$dest" ]; then
echo " $dest already exists — not overwriting"
else
install -m 600 "${BASE}/config/powermon/${f}" "$dest"
echo " wrote $dest (mode 600) — edit MQTT credentials before enabling services"
fi
done
# --- 7. enable services ----------------------------------------------------
msg "Enabling services"
sudo systemctl enable --now lvx-resolve-links.service lvx-resolve-links.timer
2026-04-24 16:34:10 -04:00
# Only auto-start powermon services if credentials look real (no placeholder present)
if grep -q '<MQTT_PASSWORD>' "${HOME}/.config/powermon/powermon.yaml" 2>/dev/null; then
cat <<EOF
Credentials in ~/.config/powermon/powermon.yaml still contain a placeholder.
Edit that file + powermon2.yaml, then:
sudo systemctl enable --now powermon.service powermon2.service
journalctl -u powermon.service -u powermon2.service -f
EOF
else
sudo systemctl enable --now powermon.service powermon2.service
sleep 3
systemctl --no-pager status powermon.service powermon2.service | head -30
fi
2026-04-27 06:50:04 -04:00
# lvx-control reads broker creds from ~/.config/powermon/powermon.yaml, so it
# only needs to start once that file has real credentials.
if ! grep -q '<MQTT_PASSWORD>' "${HOME}/.config/powermon/powermon.yaml" 2>/dev/null; then
sudo systemctl enable --now lvx-control.service
fi
2026-04-24 16:34:10 -04:00
msg "Done"
echo "Next steps (if any of these don't match your hardware, edit and restart):"
echo " - /usr/local/sbin/lvx-resolve-links : SERIAL_UNIT_1 / SERIAL_UNIT_2"
echo " - ${BASE}/lvx-flash/flash.py : SERIAL_UNIT_1 / SERIAL_UNIT_2"
echo " - to re-probe after a cable move : sudo systemctl restart lvx-resolve-links.service powermon.service powermon2.service"