From ha-nova
Analyzes Home Assistant energy data including consumption, solar, battery, grid costs, and per-device usage. Edits Energy dashboard sources and tracked devices via HA NOVA Relay.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ha-nova:energyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Analysis (read-only):
Analysis (read-only):
energy/validate)Config (gated writes):
energy/save_prefsNot in scope:
ha-nova:dashboard)ha-nova:history)ha-nova:maintenanceha-nova:helper, type integration)Verify relay CLI: ha-nova relay health
If this fails: ha-nova setup
File-based requests: ha-nova relay ws --data-file <payload-file>; --out <result-file> for large responses. WS body: .data (skills/ha-nova/relay-api.md → Standard Envelope).
Schemas, KPI formulas, and analysis recipes: skills/energy/energy-reference.md — read it before any config write or KPI computation.
WS {"type":"energy/get_prefs"} → sources + tracked devices. Error ERR_NOT_FOUND ("No prefs") means the dashboard was never configured — offer initial setup instead of failing. Report grouped: sources first (grid/solar/battery/gas/water), then devices (count + notable entries). Run WS {"type":"energy/validate"} in the same pass; its issue lists are parallel to config order — map every issue to its source/device and name the concrete fix (issue table in the reference).
Resolve statistic IDs from prefs, then query recorder/statistics_during_period with types:["change"] and units:{"energy":"kWh"} over a bounded window (default: last 30 days). Follow the statistics contract in the reference exactly: HA-local day boundaries (weeks start Monday), ms-epoch timestamps, missing buckets count as 0, negative change is legal, 5minute period only reaches back ~10 days.
Compute KPIs with the formulas in the reference so numbers match the HA UI; label documented approximations as such. Present cost figures as estimates — HA cost math never equals the utility bill (standing charges, VAT, official metering).
Never: diff raw total_increasing states (use statistics change), report peak watts from energy-only statistics (only hourly averages exist — say so), present a partial day/month as a complete period (label it and compare like-for-like), or rebuild an EV manager's session history (evcc and similar expose their own statistics entities — read those).
energy/get_prefs immediately before composing the save — never reuse an earlier read.flow_from present = legacy nested; flat keys = HA 2026.3+). Emit the same generation; never mix. With no existing grid source to detect from, pick by HA version (GET /api/config → version; 2026.3+ = flat, else legacy). Preserve every field you do not edit verbatim, including unknown keys (power_config, stat_soc, name).save_prefs replaces the entire list for every key present — send only the top-level keys you touched, each as its complete list (canonical payload in the reference).energy/save_prefs (fails unless the App's configured HA token has admin rights).get_prefs (the save response echoes the new prefs — still re-read), confirm the invariant and that every untouched entry is deep-equal to the fresh pre-save read, then run energy/validate — a successful save does NOT prove the config works (dangling statistic IDs are accepted silently). Mention that other open dashboard tabs need a reload.Initial setup after ERR_NOT_FOUND: treat every list as empty — compose only the keys being populated (count before = 0) and continue at step 4.
Write guards (schema details in the reference):
cost_adjustment_day (default 0); at most one of entity_energy_price/number_energy_price per direction: in the ID) unless stat_cost is already set — HA 2026.4+ rejects the savestat_cost — leave it null with a price field set and HA creates the cost sensor itself; resolve actual cost statistics via energy/info → cost_sensorsincluded_in_stat must reference a stat_consumption present in the same list, without cycles — HA does not validate thisrecorder/list_statistic_ids), should belong to a live entity (validate reports entity_not_defined otherwise), and must meet the sensor prerequisites in the issue tableERR_NOT_FOUND on get_prefs: unconfigured dashboard, not a failure.skills/ha-nova/relay-api.md → Error Handling.Apply skills/ha-nova/output-rules.md.
Energy / StatusPlanned changeOptionsVerificationNext stepUse stable localized slot labels in this order; omit empty slots. Rankings as compact tables — never raw JSON.
skills/ha-nova/write-safety.md).save_prefs while answering an analysis question.npx claudepluginhub markusleben/ha-nova --plugin ha-novaScans a codebase for architectural friction, presents candidates as a visual HTML report with before/after diagrams, and guides you through deepening refactors.