Docs: reflect this session's findings across the repo
- top-level README.md (new): system overview, subsystem map, skills pointer, notable findings. - eg4battery README/NOTES: 3 -> 6 packs (pack 6 oddball 0x01/115200); SoC drift + calibration section; closed-loop comms evaluated and rejected (loses per-pack telemetry, no native protocol, doesn't fix drift); how to force a grid charge via output-priority SUB. - LVX6048 README: closed-loop pending item -> resolved decision; new "SoC calibration & known firmware quirks" section (POP single-digit/POP01, MCHGC charge-lock, re_discharge=re-discharge can't exceed float, PIRI lag, powermon adhoc wedge); skills pointer. - lvx-control README: POP encoding fix, POP crc-but-applies quirk, verify-by- behavior, grid-charge-via-SUB usage. - troubleshoot-inverter skill: corrected the stale "dead string per inverter" claim — both strings healthy; low PV is tilt/heat/shade/curtailment. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -148,7 +148,11 @@ come from decoding the Comm1/Comm2 hub bus instead (a future mode).
|
||||
|
||||
### Adapters
|
||||
|
||||
On this host, three USB-FTDI adapters are plugged into the three packs' RS485 ports:
|
||||
On this host there are now **6 packs**, each with its own USB-FTDI adapter on its
|
||||
RS485 port. The config of record (all 6 `packs:` entries with their `/dev/serial/
|
||||
by-id/...` paths, addresses, and bauds) is `~/.config/eg4-battery/eg4-battery.yaml`
|
||||
and the example at `config/eg4-battery.yaml.example`. Packs 1–5 are addr `0x40` @
|
||||
9600; **pack 6** is the odd one, addr `0x01` @ 115200. First three (historical):
|
||||
|
||||
| Adapter ID | Pack | `/dev/serial/by-id/...` |
|
||||
|------------------|----------------|--------------------------------------------------------|
|
||||
@@ -156,12 +160,34 @@ On this host, three USB-FTDI adapters are plugged into the three packs' RS485 po
|
||||
| A994XGUY | bat2 (RS485) | `usb-FTDI_FT232R_USB_UART_A994XGUY-if00-port0` |
|
||||
| A994XMBR | bat3 (RS485) | `usb-FTDI_FT232R_USB_UART_A994XMBR-if00-port0` |
|
||||
|
||||
Each pack gets polled on its own bus → no shared-bus arbitration, no master/slave coordination needed, pack Modbus address is 0x40 for all of them.
|
||||
Each pack gets polled on its own bus → no shared-bus arbitration, no master/slave coordination needed.
|
||||
|
||||
## LVX6048 compatibility (still true)
|
||||
|
||||
LVX6048 BMS port protocols: `PYL` (Pylontech), `LIb` (MPP LIO), `WEC` (WECO), `SOL` (Soltaro), `VSC` (Pylontech-CAN), `USE` (voltage-only). **No native EG4 LP4V2 support.** For inverter↔battery comms, set `P05/P14 = USE` and manage charge profile via `lvx-flash`. See DIY Solar Forum threads 67496 & 96019, LVX6048WP manual §9-2.
|
||||
|
||||
### Closed-loop BMS comms — evaluated, NOT recommended (2026-06)
|
||||
|
||||
Going closed-loop (daisy-chain packs → master CAN → inverter) was assessed and
|
||||
**rejected** for this install:
|
||||
1. **No native protocol** — would rely on the LP4V2 emulating Pylontech-CAN; unverified.
|
||||
2. **Loses per-pack monitoring** — closed-loop needs the inter-pack Comm daisy-chain,
|
||||
which silences slave packs' RS485 ports (see "RS485 only works standalone" above).
|
||||
The 6-FTDI per-pack/per-cell telemetry — our best diagnostic — collapses to
|
||||
master-only. Bad trade.
|
||||
3. **Doesn't fix the real pain (SoC drift)** — closed-loop just forwards the BMS's own
|
||||
(drifted) SoC to the inverter. The cure is a periodic full charge (see eg4battery
|
||||
README §"SoC drift & calibration"), doable open-loop today.
|
||||
|
||||
### Forcing a full GRID charge (for calibration on a cloudy day)
|
||||
|
||||
The lever is the inverter's **output priority**, NOT the voltage thresholds: switch
|
||||
POP to **SUB** (`solar_utility_battery`) so the inverter runs loads off grid AND
|
||||
charges the bank to full from grid+solar; pair with `charger_priority=solar_and_utility`.
|
||||
Revert to `solar_battery_utility` + `solar_first` when done. Both via lvx-control.
|
||||
(Raising `re_discharge`/`stop_charge_voltage` does NOT work — firmware NAKs it.)
|
||||
Automated + safety-monitored + auto-reverting in `../.claude/skills/lib/grid-cal-monitor`.
|
||||
|
||||
## Bring-up checklist (when a new pack goes live)
|
||||
|
||||
1. Wire: plug USB-FTDI adapter (stock pin-1-2 cable) into the pack's **RS485** port.
|
||||
|
||||
@@ -5,8 +5,9 @@ RS-485 and publishes per-pack telemetry to MQTT with HA auto-discovery.
|
||||
|
||||
## Status: live
|
||||
|
||||
All 3 packs publishing in `modbus_per_pack` mode, each on its own FTDI
|
||||
RS-485 adapter. Per pack, ~70 named entities + 136 raw `register_NN` series:
|
||||
All **6 packs** publishing in `modbus_per_pack` mode, each on its own FTDI
|
||||
RS-485 adapter (packs 1–5 at addr `0x40`/9600; pack 6 is an oddball at addr
|
||||
`0x01`/115200). Per pack, ~70 named entities + 136 raw `register_NN` series:
|
||||
|
||||
```
|
||||
lifepower4_1_pack_voltage 52.56 V (16 cells × 3.285 V)
|
||||
@@ -41,6 +42,18 @@ Set by `bus.mode` in `~/.config/eg4-battery/eg4-battery.yaml`:
|
||||
See [`NOTES.md`](./NOTES.md) for architecture, register map, LVX6048
|
||||
compatibility findings, and bring-up checklist.
|
||||
|
||||
## SoC drift & calibration
|
||||
|
||||
The per-pack BMS SoC is coulomb-counted and **drifts** because the conservative
|
||||
LVX6048 charge profile rarely drives a true full charge, so the counters never
|
||||
re-anchor to 100% (observed 8–70% spread across packs at an identical resting
|
||||
voltage — they're all physically at the same charge; the spread is pure drift).
|
||||
Fix is a periodic **full charge to absorption**, which re-anchors every pack to
|
||||
100%. Automated by the `calibration-charge` skill (solar-only, or grid-assisted
|
||||
via output-priority SUB on a cloudy day) — see
|
||||
[`../.claude/skills/calibration-charge/`](../.claude/skills/calibration-charge/)
|
||||
and `../.claude/skills/lib/grid-cal-monitor`.
|
||||
|
||||
## What's in the box
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user