add controls to lvx

This commit is contained in:
2026-04-27 06:50:04 -04:00
parent 00ab311d92
commit 04720c3b92
14 changed files with 856 additions and 39 deletions

View File

@@ -17,6 +17,7 @@ LVX6048/
│ ├── udev/rules.d/99-lvx6048.rules
│ └── systemd/system/
│ ├── lvx-resolve-links.service
│ ├── lvx-control.service
│ ├── powermon.service
│ ├── powermon2.service
│ ├── powermon.service.d/10-resolver.conf
@@ -38,7 +39,18 @@ LVX6048/
├── lvx-flash/ ← settings-profile CLI
│ ├── flash.py ← dump / diff / apply / compare / sync-check
│ ├── README.md
│ └── profiles/current.yaml
│ └── profiles/
│ ├── current.yaml ← legacy snapshot
│ └── eg4-lp4-v2.yaml ← canonical EG4 LP4 v2 LiFePO4 bank profile
├── lvx-control/ ← HA → powermon adhoc command bridge
│ ├── lvx-control ← single-file Python daemon
│ └── README.md ← supported actions / topic layout
├── homeassistant/ ← HA-side control entities + dashboard
│ ├── mqtt_controls.yaml ← selects + numbers for the controls
│ ├── lovelace_controls.yaml ← dashboard view
│ └── README.md
└── smoketest/ ← adhoc test configs (one-off powermon -C usage)
├── console.yaml
@@ -108,7 +120,7 @@ sudo systemctl start lvx-resolve-links.service powermon.service powermon2.servic
┌──────────────────────────────────┐
│ Home Assistant Mosquitto broker │
│ ~29 auto-discovered sensors/unit │
│ ~23 auto-discovered sensors/unit │
└──────────────────────────────────┘
```
@@ -118,10 +130,16 @@ 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
## Cable moves and inverter power-cycles
Identification is PI18-serial-based, so moving USB cables between hub ports
never requires config edits. After any cable shuffle:
never requires config edits. The udev rule fires `lvx-resolve-links` and
restarts both powermon services automatically whenever a matching hidraw
device appears (`ACTION=="add"`), so a cable shuffle or inverter power-cycle
recovers on its own — no manual `systemctl restart` needed in the common case.
If recovery looks stuck (e.g. a unit was off long enough that its hidraw
disappeared but the new one didn't trigger the rule for some reason):
```bash
sudo systemctl restart lvx-resolve-links.service powermon.service powermon2.service
@@ -137,18 +155,50 @@ and update the two `SERIAL_UNIT_*` constants in:
then restart the three services.
## Next steps / not done
## Status — done / pending
- **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.
**Done (2026-04-26):**
- **Parallel commissioning.** Both inverters operationally paralleled and
load-sharing on a 3× EG4 LP4 v2 bank. See `2026-04-26-parallel.md`.
- **Main-CPU firmware parity.** Both units now at main 06306. Slave-CPU
firmware still differs (06126 / 06021) but is benign: cluster handshake
completes, current sharing is symmetric, no faults. The vendor's
`LVX6048 FW63.06.zip` includes a `dsp.hex` slave bin if version parity
is ever desired for cosmetic reasons.
- **Hot-plug recovery.** udev rule auto-restarts the resolver + powermon
services when an inverter re-enumerates. Resolver also has a retry loop
to handle the brief race when both units come up nearly together.
- **`parallel_instance_number` decoder.** Replaced upstream's misleading
2-value flag with a proper instance-index decoder (0 = master, 1+ =
slaves) in both GS and PGS. `flash.py sync-check` updated to match.
- **MOD code 06.** Added "Charge" mapping (was crashing sync-check).
Educated guess on the label — revisit if it shows up in unrelated states.
- **Battery profile.** `lvx-flash/profiles/eg4-lp4-v2.yaml` captures the
conservative open-loop LFP policy in use (USER mode, 56.4 V bulk,
54.0 V float, 48.0 V cutoff, 60 A MCHGC).
- **HA remote control.** `lvx-control` daemon bridges HA-friendly MQTT
topics (`solar/control/lvx6048/<action>`) to powermon's adhoc-command
queue, mirroring every change to both inverters in lock-step. Day-to-day
controls (POP / PCP / PSP / MCHGC / MUCHGC) exposed; risky setters
(battery thresholds, type, output mode, factory reset) deliberately not.
Companion HA configs live in `homeassistant/`.
**Pending / nice-to-have:**
- **PGS field layout.** The LVX6048-specific 30-field PGS response is only
partially named in `powermon-patches/pi18.py` — fields 4, 1322, 2328,
and 30 are still exposed as raw strings. Now that the cluster is actually
paralleled, more of these fields produce meaningful values; worth a
second pass to identify them by comparing PGS0 vs PGS1 captures from
master and slave.
- **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.
- **Closed-loop BMS comms.** Currently open-loop — inverters estimate SoC
from voltage, batteries don't push real-time SoC / charge limits to the
inverter. Closed-loop would give better SoC accuracy and dynamic CC
tapering near full. Path is the dedicated CAN port on the master pack →
inverter BMS port (separate cable from the inter-pack daisy-chain).
Deferred.