diff --git a/LVX6048/2026-05-01.md b/LVX6048/2026-05-01.md new file mode 100644 index 0000000..b5c5c35 --- /dev/null +++ b/LVX6048/2026-05-01.md @@ -0,0 +1,140 @@ +# 2026-05-01 — fix 5-minute spikes on AC-output power time-series + +## Symptom + +On both inverters' apparent-power and active-power Influx series, a tall +rectangular spike to **exactly 6000 VA / 6000 W** appeared every ~5 minutes. +The spike was simultaneous on both units even though they are not paralleled +on AC output (and on this rig the AC outputs aren't even tied to a common +load), which ruled out any real-load mechanism. + +90-min sample (idle unit 2, baseline ~47 VA / ~0 W): + +| metric | spike value | spike count | inter-spike gap | +|-----------------------|---------------|-------------|-----------------| +| `VA` | **6000** (only) | 36 / 30 min | pairs ~3–5s, 298s between pairs | +| `W` | **6000** (only) | 12 / 30 min | same pattern | + +Unit 1 spiked at `:37:12 / :42:15 / :47:17 / …`, unit 2 at `:37:44 / :42:46 / …`. +Each cycle is exactly 5 min; the two daemons sit ~32 s out of phase, so on +charts binned > 1 min they look simultaneous. + +## Root cause + +`6000` is the LVX6048's **nameplate** apparent / active power. Two PI18 +commands return that field: + +- `GS` (every 5 s): live measurement +- `PIRI` (every 300 s): nameplate / configured rating + +In `powermon-patches/pi18.py` both fields share the same `description` +string (`"AC Output Apparent Power"`, `"AC Output Active Power"`). +Powermon's `outputformats/hass.py` slugifies `description` into the HA +entity_id with **no per-command namespace**, so both publish to: + +``` +homeassistant/sensor/lvx6048_X_ac_output_apparent_power/state +homeassistant/sensor/lvx6048_X_ac_output_active_power/state +``` + +Every 300 s when PIRI fires, the entity is written with `6000` for one +publish; the next GS (≤5 s later) restores the live value. HA's recorder +captures both → Influx records a 6000-valued sample tagged to the live +entity. Hence the periodic rectangular spike. + +The same collision exists for several other PIRI fields whose descriptions +duplicate live GS fields: + +- `AC Input Voltage` +- `AC Input Current` *(not in GS, but shadows the live current series via + PIRI's nameplate input rating)* +- `AC Output Voltage` +- `AC Output Frequency` +- `AC Output Current` +- `Battery Voltage` + +Same artifact, just less visible because nameplate values for those are +close to live values during steady-state operation. + +## Fix + +Add `excl_filter` to the `PIRI` command block in both powermon configs +(matches the existing pattern used on `GS` for dead/dummy fields). PIRI's +job in this stack is to publish *configured* thresholds — bulk/float +voltages, charging-current ceilings, source priorities, etc. The fields +that duplicate GS measurements provide no value and only corrupt the +recorder series. + +```yaml + - command: PIRI + trigger: + every: 300 + outputs: + - type: mqtt + topic: powermon/lvx6048_X/PIRI + format: + type: hass + discovery_prefix: homeassistant + entity_id_prefix: lvx6048_X + excl_filter: '^(ac_input_voltage|ac_input_current|ac_output_voltage|ac_output_frequency|ac_output_current|ac_output_apparent_power|ac_output_active_power|battery_voltage)$' +``` + +Applied to both `config/powermon/powermon.yaml` and `…/powermon2.yaml`, +and mirrored to the live `~/.config/powermon/` deploys. + +## Net effect + +| Metric | Before | After | +|-----------------------------------------|----------|-------| +| `VA` series spurious 6000 spikes / 5 min| 2/inverter| 0 | +| `W` series spurious 6000 spikes / 5 min| 2/inverter| 0 | +| PIRI fields published per inverter | 26 | 18 | +| PIRI fields kept (battery/charge/priority configs) | — | all retained | + +PIRI configuration entities (battery thresholds, MCHGC ceilings, output +priority, etc.) are unchanged — they continue to update every 300 s on +their own entity_ids. + +## Files touched + +``` +M LVX6048/config/powermon/powermon.yaml (excl_filter on PIRI) +M LVX6048/config/powermon/powermon2.yaml (same) +A LVX6048/2026-05-01.md (this file) +``` + +## How to verify + +```bash +sudo systemctl restart powermon.service powermon2.service + +# Watch one PIRI cycle (≤5 min) — apparent power should NOT publish a 6000: +mosquitto_sub -h 10.0.0.41 -u mqtt -P \ + -t 'homeassistant/sensor/lvx6048_+_ac_output_apparent_power/state' -W 360 + +# Or query Influx after one full cycle: +influx -host 10.0.0.41 -username homeassistant -password \ + -database homeassistant -execute " +SELECT count(\"value\") FROM \"VA\" +WHERE (\"entity_id\" = 'lvx6048_lvx6048_1_ac_output_apparent_power' + OR \"entity_id\" = 'lvx6048_lvx6048_2_ac_output_apparent_power') + AND \"value\" = 6000 + AND time > now() - 30m" +# Expect: count → 0 once the next two PIRI cycles have passed without spikes. +``` + +## Rollback + +```bash +git -C ~/solar checkout HEAD~1 -- LVX6048/config/powermon/ +cp ~/solar/LVX6048/config/powermon/powermon{,2}.yaml ~/.config/powermon/ +# (re-edit ~/.config/powermon/*.yaml to restore real MQTT_PASSWORD) +sudo systemctl restart powermon.service powermon2.service +``` + +## Upstream-fix candidate + +Cleaner (but invasive) alternative would patch `outputformats/hass.py` to +namespace entity_ids by command (e.g., `_settings_` infix for PIRI). Not +worth the patch maintenance — the `excl_filter` is one line per command +and survives powermon upgrades. diff --git a/LVX6048/config/powermon/powermon.yaml b/LVX6048/config/powermon/powermon.yaml index ddc4788..7328658 100644 --- a/LVX6048/config/powermon/powermon.yaml +++ b/LVX6048/config/powermon/powermon.yaml @@ -55,6 +55,11 @@ commands: type: hass discovery_prefix: homeassistant entity_id_prefix: lvx6048_1 + # Drop fields whose description (and therefore entity_id slug) shadows + # GS's live measurements. PIRI's values for these are nameplate / + # configured-rating, not live, so they overwrite the live series every + # 300s producing 6000 VA / 6000 W spikes (LVX6048 nameplate). + excl_filter: '^(ac_input_voltage|ac_input_current|ac_output_voltage|ac_output_frequency|ac_output_current|ac_output_apparent_power|ac_output_active_power|battery_voltage)$' - command: ET trigger: diff --git a/LVX6048/config/powermon/powermon2.yaml b/LVX6048/config/powermon/powermon2.yaml index 6510416..8673cca 100644 --- a/LVX6048/config/powermon/powermon2.yaml +++ b/LVX6048/config/powermon/powermon2.yaml @@ -52,6 +52,11 @@ commands: type: hass discovery_prefix: homeassistant entity_id_prefix: lvx6048_2 + # Drop fields whose description (and therefore entity_id slug) shadows + # GS's live measurements. PIRI's values for these are nameplate / + # configured-rating, not live, so they overwrite the live series every + # 300s producing 6000 VA / 6000 W spikes (LVX6048 nameplate). + excl_filter: '^(ac_input_voltage|ac_input_current|ac_output_voltage|ac_output_frequency|ac_output_current|ac_output_apparent_power|ac_output_active_power|battery_voltage)$' - command: ET trigger: