fix 5min spikes
This commit is contained in:
140
LVX6048/2026-05-01.md
Normal file
140
LVX6048/2026-05-01.md
Normal file
@@ -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 <pass> \
|
||||
-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 <pass> \
|
||||
-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.
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user