Files
shaggy-solar/LVX6048/README.md
2026-04-24 16:34:10 -04:00

155 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LVX6048 → Home Assistant
Reproducible install package for monitoring 2× MPP Solar LVX6048 inverters over
USB-HID (PI18) via [`powermon`](https://github.com/jblance/powermon), publishing
to a Home Assistant MQTT broker with HA auto-discovery.
## What's in the box
```
LVX6048/
├── README.md ← start here
├── Install.md ← detailed walkthrough (what install.sh does)
├── Monitoring.md ← background / design notes
├── install.sh ← one-shot installer (idempotent, safe to re-run)
├── etc/ mirror of target system paths
│ ├── udev/rules.d/99-lvx6048.rules
│ └── systemd/system/
│ ├── lvx-resolve-links.service
│ ├── powermon.service
│ ├── powermon2.service
│ ├── powermon.service.d/10-resolver.conf
│ └── powermon2.service.d/10-resolver.conf
├── config/powermon/ lands at ~/.config/powermon/ (mode 600)
│ ├── powermon.yaml ← unit #1 — edit MQTT creds before deploying
│ └── powermon2.yaml ← unit #2 — edit MQTT creds before deploying
├── bin/
│ └── lvx-resolve-links ← installed as /usr/local/sbin/lvx-resolve-links
│ (install.sh rewrites the shebang to the uv-installed python)
├── powermon-patches/ ← drop-in files for the uv tool install
│ ├── README.md ← what each patch does + upgrade path
│ ├── pi18.py, usbport.py, mqttbroker.py,
│ └── port_config_model.py, ports_init.py
├── lvx-flash/ ← settings-profile CLI
│ ├── flash.py ← dump / diff / apply / compare / sync-check
│ ├── README.md
│ └── profiles/current.yaml
└── smoketest/ ← adhoc test configs (one-off powermon -C usage)
├── console.yaml
└── smoketest.yaml
```
## Quick start (reproducing on a fresh machine)
```bash
# 1. Clone / scp this folder into place (e.g. /home/<user>/solar/LVX6048)
cd ~/solar/LVX6048
# 2. Install uv if not already: https://docs.astral.sh/uv/
# 3. Run the installer
./install.sh
# 4. Edit the two things install.sh warns about:
# a. ~/.config/powermon/powermon{,2}.yaml — MQTT broker IP / user / password
# b. /usr/local/sbin/lvx-resolve-links — SERIAL_UNIT_1 / SERIAL_UNIT_2 (see below)
# lvx-flash/flash.py — same two constants
# 5. Capture each inverter's PI18 serial (with services stopped):
sudo systemctl stop lvx-resolve-links.service powermon.service powermon2.service
for d in /dev/hidraw0 /dev/hidraw1; do
TMP=$(mktemp --suffix=.yaml)
printf 'loop: once\ndevice:\n name: probe\n port: {type: usb, path: %s, protocol: PI18}\ncommands:\n - {command: ID, trigger: {loops: 1}}\n' "$d" > "$TMP"
echo "=== $d ==="
~/.local/bin/powermon -C "$TMP" 2>&1 | grep serial_number
rm -f "$TMP"; sleep 2
done
# Edit SERIAL_UNIT_{1,2} in /usr/local/sbin/lvx-resolve-links and lvx-flash/flash.py,
# then:
sudo systemctl start lvx-resolve-links.service powermon.service powermon2.service
```
## How the pieces fit together
```
┌─────────────────────────┐ ┌─────────────────────────┐
│ LVX6048 #1 (USB-HID) │ ──▶ │ /dev/hidraw{0|1} │
│ LVX6048 #2 (USB-HID) │ ──▶ │ (vid:pid 0665:5161) │
└─────────────────────────┘ └──────────┬──────────────┘
│ (99-lvx6048.rules → group=dialout)
┌──────────────────────────────────┐
│ lvx-resolve-links.service │
│ (oneshot, runs before powermon) │
│ │
│ probes each hidraw w/ PI18 ID │
│ creates /dev/lvx6048-{1,2} │
│ symlinks keyed to serial │
└──────────┬───────────────────────┘
│ After= / Requires=
┌──────────────────────────────────┐
│ powermon.service (unit #1) │
│ powermon2.service (unit #2) │
│ │
│ poll GS / MOD / PIRI / ET │
│ publish to HA auto-discovery │
│ topics under homeassistant/* │
└──────────┬───────────────────────┘
│ MQTT (port 1883)
┌──────────────────────────────────┐
│ Home Assistant Mosquitto broker │
│ ~29 auto-discovered sensors/unit │
└──────────────────────────────────┘
```
Separate from the monitoring pipeline, **`lvx-flash/`** is a manual settings
tool: dump the inverter's current config into a YAML profile, diff against a
target profile, apply changes safely (stops powermon, writes via PI18 setters,
verifies via PIRI readback). Also supports `compare` (diff live settings
between two inverters) and `sync-check` (verify parallel-stack health).
## Cable moves
Identification is PI18-serial-based, so moving USB cables between hub ports
never requires config edits. After any cable shuffle:
```bash
sudo systemctl restart lvx-resolve-links.service powermon.service powermon2.service
```
## Replacing an inverter
When a unit is swapped, capture its new PI18 serial (see step 5 of Quick start)
and update the two `SERIAL_UNIT_*` constants in:
- `/usr/local/sbin/lvx-resolve-links`
- `~/solar/LVX6048/lvx-flash/flash.py`
then restart the three services.
## Next steps / not done
- **Firmware parity:** on this dev stack, unit #1 is at main=06303/slave=06126
and unit #2 is at 06440/06021. Parallel operation requires matching firmware
(fault code 71 "Parallel version different") — the sync kit's cables are
wired correctly, but the inverters won't phase-lock until both CPUs match.
Firmware upload is not part of this package (MPP Solar Windows-only tool).
- **PGS field layout:** the LVX6048-specific 30-field PGS response layout is
only partially decoded in `powermon-patches/pi18.py`. The key fields
(parallel_valid, fault_code, grid_hz, ac_output_voltage) are named; the rest
are exposed as raw strings.
- **Control / set commands via HA:** PI18 setters (POP, PCP, MCHGC, MUCHGC, PF)
are implemented in `lvx-flash/flash.py` for offline use, but aren't exposed
as HA button/select entities. Deferred until monitoring has been stable for
at least a week and firmware parity is restored.