Files
2026-04-27 06:50:04 -04:00
..
2026-04-27 06:50:04 -04:00
2026-04-24 16:34:10 -04:00

lvx-flash

Apply declarative YAML settings profiles to an LVX6048 inverter via PI18.

Reuses the patched powermon install at ~/.local/share/uv/tools/powermon/ — the shebang in flash.py points there, so no extra setup is needed.

Commands

# 1. Snapshot the inverter's current settings into an editable profile.
./flash.py dump  --out profiles/current.yaml

# 2. Copy/edit. Preview the diff against the live device at any time.
./flash.py diff  --profile profiles/winter.yaml

# 3. Apply. The tool stops powermon.service for the duration, writes each
#    changed setting via the corresponding PI18 set command, verifies via
#    PIRI readback, and restarts powermon.service at the end.
./flash.py apply --profile profiles/winter.yaml --confirm

# 4. Compare two inverters live (for parallel setups). Exits 0 if identical,
#    1 if divergent. Useful as a quick "are the two in sync?" check.
./flash.py compare --device-a /dev/lvx6048-1 --device-b /dev/lvx6048-2

# 5. Runtime sync-check for paralleled units. Reads GS+FWS+MOD+VFW from each
#    and reports firmware mismatch, parallel-valid flag, active fault codes,
#    mode mismatch, AC voltage/frequency divergence. Exits 0 on pass, 1 on fail.
./flash.py sync-check --device-a /dev/lvx6048-1 --device-b /dev/lvx6048-2

Device selection on every subcommand:

  • --serial SN (default — uses SERIAL_UNIT_1 for single-device commands, SERIAL_UNIT_{1,2} for pairs) — globs /dev/hidraw* and picks the one whose PI18 ID matches. Resilient to cable moves.
  • --device PATH — explicit hidraw path, skips auto-resolution. Useful for probing an unknown unit.

The known-stack serials are hard-coded as SERIAL_UNIT_1 / SERIAL_UNIT_2 constants at the top of flash.py; edit them if a unit is replaced.

sync-check depends on the FWS / PGS additions to powermon/protocols/pi18.py; the --serial flow depends on the UsbPortConfig.serial_number field addition. Both are described in Install.md §5(d)(e).

Profile schema

All keys are optional. Only present keys are applied; the rest are left alone.

key range / enum PI18 setter
battery_type AGM | FLOODED | USER PBT
cutoff_voltage 40.0 48.0 V PSDV
stop_discharge_voltage 44.0 51.0 V BUCD (pair)
stop_charge_voltage 0 (full) or 48.0 58.0 V BUCD (pair)
bulk_voltage 48.0 58.4 V MCHGV (pair)
float_voltage 48.0 58.4 V (≤ bulk_voltage) MCHGV (pair)
max_charging_current 10, 20, 30, 40, 50, 60, 70, 80 A MCHGC
max_utility_charging_current 2, 10, 20, 30, 40, 50, 60, 70, 80 A MUCHGC
output_source_priority solar_utility_battery | solar_battery_utility POP
charger_priority solar_first | solar_and_utility | solar_only PCP
solar_power_priority battery_load_utility_ac | load_battery_utility PSP
grid_tie enabled | disabled PEI / PDI

Pair settings (BUCD, MCHGV) must have both halves present.

Safety

  • apply refuses to run without --confirm.
  • Range + consistency validation runs before any write. A failure aborts before touching the inverter.
  • Each write is followed by a PIRI readback that must match to within 0.05 V. A mismatch aborts.
  • Settings are applied in an order that's safe for a battery: cutoff → BUCD → MCHGV → currents → priorities → grid-tie mode.
  • powermon.service is stopped for the write window so the two processes don't fight over /dev/lvx6048-1, then restarted even if the run aborts.

Caveats

  • Parallel setups: PCP / MCHGC / MUCHGC are indexed by parallel unit (the tool sends unit 0 — master). Some firmware only accepts sets on the master; the slave mirrors silently.
  • PIRI reports max_charging_current as the effective combined (solar + AC) cap, which can exceed MCHGC's 80 A range. dump omits it with a comment when that happens.
  • Changing battery_type while the unit is actively charging is generally allowed by the firmware but not recommended.