Four Skill-tool skills under .claude/skills/ that let an agent monitor and
troubleshoot the install (2x LVX6048, 6x EG4 LifePower4, OpenEVSE), grounded
in the real MQTT/HA topology rather than generic advice:
- solar-health-check : whole-system sweep + cross-checks + R/Y/G verdict,
incl. cross-unit "silently-dead inverter" detection
- troubleshoot-inverter: FWS fault decode, parallel sync, USB link recovery
- troubleshoot-battery : per-pack imbalance vs SoC-counter-drift, RS485 silence
- power-usage : PV/load/grid/battery balance + EVSE sessions
Shared lib:
- solar-snapshot : live MQTT capture (creds from powermon.yaml, no hardcoding)
- ha-history : HA recorder lookback (token from ~/.config/ha/token)
REFERENCE.md documents topology, real HA entity_ids (doubled slug), known
issues, and a safe-remediation-only action policy (restarts yes; setters no).
Action boundary: diagnose + restart wedged daemons / recover USB links;
never touches inverter/battery setters or flash.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
72 lines
3.8 KiB
Markdown
72 lines
3.8 KiB
Markdown
---
|
||
name: power-usage
|
||
description: >-
|
||
Analyze where the power is going across the install — load vs PV generation vs
|
||
grid vs battery flow, plus EVSE charging sessions. Use when the user asks "why is
|
||
my battery draining / how much am I using / where are the watts going / is the car
|
||
charging / what's my solar production / power consumption", or wants an energy
|
||
balance or breakdown. Read-only; this skill measures and explains, it does not
|
||
change anything.
|
||
---
|
||
|
||
# power-usage
|
||
|
||
## 0. Load context
|
||
Shell cwd is the repo root; anchor paths there:
|
||
```bash
|
||
ROOT="$(git rev-parse --show-toplevel)"; SNAP="$ROOT/.claude/skills/lib/solar-snapshot"
|
||
```
|
||
Read `$ROOT/.claude/skills/REFERENCE.md` for entity names. Key sign conventions: pack
|
||
`pack_current` is signed (**+ = charging, − = discharging**); inverter
|
||
`mppt*_input_power` is PV in (W); `ac_output_active_power` is load out (W).
|
||
|
||
## 1. Instantaneous energy balance
|
||
```bash
|
||
# Generation (PV) + load, per inverter:
|
||
"$SNAP" -w 10 -g 'lvx6048_[12]_(mppt1_input_power|mppt2_input_power|ac_output_active_power|grid_voltage|device_mode)/' 'homeassistant/sensor/+/state'
|
||
# Battery flow, per pack (sum the pack_power = V×I yourself):
|
||
"$SNAP" -w 16 -g 'lifepower4_[1-6]_(pack_voltage|pack_current|soc)/' 'homeassistant/sensor/+/state'
|
||
# EV charger:
|
||
"$SNAP" -w 8 'openevse/status' 'openevse/power' 'openevse/amp' 'openevse/voltage' 'openevse/session_energy'
|
||
```
|
||
Then state the balance in words:
|
||
- **PV in** = sum of all `mppt*_input_power`.
|
||
- **Battery** = sum of (pack_voltage × pack_current) over 6 packs. Negative total =
|
||
discharging (load exceeds PV+grid); positive = charging.
|
||
- **Load out** = sum of inverter `ac_output_active_power`.
|
||
- **EVSE** = `openevse/power` — and the EVSE load is a *subset* of total load, so a
|
||
draining battery with the car plugged usually explains itself here.
|
||
- **Grid**: `device_mode` Bypass/Line means grid is carrying/supplementing; Battery
|
||
mode means running off the bank. The LVX6048 has no clean grid-power entity, so
|
||
infer grid = load − PV − battery_discharge.
|
||
|
||
Sanity: PV + grid + battery_discharge ≈ load (within metering noise). A big residual
|
||
means one feed is mis-reported — note it (e.g. the known `lvx6048_1_battery_voltage`
|
||
~10 V glitch will corrupt any pack-power math that uses the *inverter's* battery
|
||
reading; always use the **pack** entities for battery flow).
|
||
|
||
## 2. "Why is the battery draining?"
|
||
Walk the chain: is PV low (night/shade/§5 of troubleshoot-inverter dead string)? Is
|
||
load high (check `ac_output_active_power` and EVSE `power`)? Is the inverter in
|
||
Battery mode instead of using grid (`device_mode`)? Pin the drain on the largest
|
||
negative contributor and say which.
|
||
|
||
## 3. EVSE sessions
|
||
```bash
|
||
"$SNAP" -w 10 'openevse/status' 'openevse/state' 'openevse/session_energy' 'openevse/total_energy' 'openevse/vehicle' 'openevse/pilot' 'openevse/max_current'
|
||
```
|
||
- `status` active = charging; sleeping/disabled = not drawing. `vehicle` = plugged.
|
||
- `session_energy` (Wh) this plug-in; `pilot`/`max_current` = the current cap the
|
||
EVSE is signalling. Idle EVSE publishes little — a short empty capture is normal.
|
||
- For history/trends (daily kWh, past sessions), the data lives in **Home Assistant's
|
||
recorder**, not on MQTT — direct the user to the HA Energy dashboard /
|
||
`sensor.openevse_total_day|week|month`. PI18 has no per-day inverter energy
|
||
(memory `project_lvx6048_no_daily_energy_query`); only `ET` lifetime Wh exists.
|
||
|
||
## 4. Report
|
||
Give the live balance (PV / load / battery / grid / EVSE, with numbers and signs),
|
||
the headline ("you're pulling X W from the bank because load Y W > PV Z W, car is
|
||
taking W W"), and point at HA recorder for anything historical. This skill never
|
||
changes settings — if the answer is "shift charging to solar hours" etc., suggest it
|
||
as advice, don't actuate.
|