Native Home Assistant consumption accounting and monthly cost reports.
Energy Report creates a resilient energy ledger from an existing cumulative energy sensor, an instantaneous power sensor or both. It preserves consumption across meter resets and replacements, closes monthly periods and produces compact notifications plus portable annual CSV archives.
| Field | Current state |
|---|---|
| Maturity | π’ Stable |
| Production use | β Validated |
| Recommended for production | β Yes |
| Setup difficulty | π’ Beginner |
| Documentation | β Complete |
| Current version | 1.0.0 |
| Minimum Home Assistant | 2026.8.0 |
| Local tests | β 31 tests |
| Import and export validation | β Complete |
| Notification validation | β Complete |
| Multi-instance validation | β Complete |
Important
During migration, keep only one system authoritative for monthly accounting and notifications. Import approved history, establish the Energy Report source baseline and disable the previous reporting workflow after validation.
Energy Report provides one reusable Home Assistant integration for consumption accounting that remains independent from the lifetime of a physical meter. It combines native config entries, entities, versioned storage, robust scheduling and provider-neutral notifications in a single device-oriented workflow.
Energy Report is installed and managed as a HACS custom integration. Each configured consumption ledger is represented as one Home Assistant device that groups its energy, cost, forecast, tariff, diagnostic and report entities. It therefore appears with regular integrations instead of dispersing its configuration among Home Assistant Helpers or YAML files.
The integration consumes existing Home Assistant sensor entities. It does not communicate directly with Shelly hardware, MQTT brokers, cloud APIs or electricity providers.
- β‘ Native cumulative-energy accounting.
- π Trapezoidal integration of instantaneous power.
- π Optional dual-source verification and continuity.
- π§© Multiple independent Energy Report instances.
- π₯οΈ Guided configuration, advanced options and explicit source replacement.
- πΎ Versioned ledger independent from the device lifetime counter.
- π Reset detection without subtracting or losing recorded consumption.
- π‘οΈ Plausibility checks based on elapsed time and configured maximum power.
- π Timezone-aware monthly close with startup catch-up.
- π Current month, previous month and current year entities.
- πΆ Modifiable tariff, current cost and month-end projections.
- π¬ One selectable Home Assistant notification entity or group per instance.
- π Native button to send or resend the latest closed monthly report, including imported history.
- ποΈ Atomic annual CSV archives with a documented public schema.
- π₯ Native CSV upload with transactional preview and explicit conflict handling.
- π©Ί Native diagnostics with measured, reconstructed and incomplete data quality.
- π English and Italian UI translations.
- π¦ HACS-ready repository layout.
Energy Report intentionally handles positive consumption only. Solar production, grid export, batteries, time-of-use tariffs, fixed charges and cross-instance aggregation are not part of version 1.0.0.
Energy Report is prepared as a custom HACS repository:
The button opens Energy Report directly as a custom integration repository in HACS. Alternatively, add it manually:
- Open HACS in Home Assistant.
- Open the top-right menu and select Custom repositories.
- Add
https://github.com/issu-lab/energy-report. - Select Integration as the repository type.
- Download Energy Report.
- Restart Home Assistant.
- Open Settings β Devices & services β Add integration.
- Search for Energy Report.
Energy Report uses numeric versions without GitHub pre-release suffixes: 0.0.x identifies alpha development, 0.x beta development and 1.x stable releases. HACS therefore follows regular version tags without requiring its pre-release switch.
For local validation before publication, copy custom_components/energy_report into the Home Assistant custom_components directory and restart Home Assistant.
Enter a unique instance name, such as Home, and choose one strategy:
Cumulative energyInstantaneous powerEnergy with power verification
The original name creates a stable archive directory. Changing the displayed name later does not move historical files.
Select the entities required by the chosen mode. Energy Report accepts only sensors with coherent Home Assistant metadata:
| Source | Device class | State class | Units |
|---|---|---|---|
| Cumulative energy | energy |
total or total_increasing |
Wh, kWh, MWh |
| Instantaneous power | power |
measurement |
W, kW, MW |
Unknown, unavailable, non-numeric, non-finite and negative readings never enter accounting.
Enter the tariff per kWh and select one existing notify entity. A Home Assistant notification group can be selected as one destination. Energy Report can send a clearly labelled test notification before completing setup.
The initial wizard intentionally keeps plausibility, timeout and scheduling values out of the main path. They remain available from the integration's Configure action.
| Setting | Default |
|---|---|
| Tariff | 0.240 per kWh |
| Maximum plausible power | 10.0 kW |
| Cumulative-source timeout | 15 minutes |
| Monthly report hour | 08:00 |
| Forecast minimum age | 3 complete days |
| Forecast minimum coverage | 80% |
The currency and timezone come from Home Assistant.
Changing the tariff recalculates the whole open month. Closed months remain immutable.
This strategy reads positive differences between successive lifetime-energy values. The hardware value is only a source baseline; the internal Energy Report ledger remains authoritative.
When the source decreases, Energy Report treats the change as a meter reset:
- the recorded month and year totals remain unchanged;
- the reset is counted in diagnostics;
- the new value becomes the source baseline;
- only later positive increments are added.
A positive jump is evaluated against elapsed time and maximum plausible power. An implausible increment is excluded and diagnosed instead of being silently accepted or hidden behind a fixed kWh threshold.
This strategy integrates power over time using the trapezoidal rule. The resulting energy is labelled reconstructed from power, because its accuracy depends on source update frequency and availability.
The integration never claims that reconstructed energy is identical to a hardware cumulative counter. Coverage and gaps remain visible in entities, CSV archives and monthly reports.
Dual mode gives each source a distinct responsibility:
- cumulative energy provides normal accounting increments;
- power maintains an independent shadow total for comparison;
- when the cumulative source becomes unavailable or stale, power provides reconstructed continuity;
- when cumulative energy returns, it establishes a fresh baseline so the outage interval cannot be counted twice.
Power-derived and meter-derived energy are always kept distinguishable. The integration reports deviation and data quality rather than automatically declaring one physical sensor faulty.
Use the integration's Reconfigure action when a Shelly or another meter is replaced, renamed or deliberately changed.
The replacement flow validates the new entity, preserves the ledger, records the source change and establishes a fresh baseline. The absolute value already present on the new device is never added to historical consumption.
Changing an entity ID through an undocumented storage edit is unsupported.
The previous month closes on the first day at 08:00 by default, using the Home Assistant timezone. If Home Assistant is offline at that time, overdue native periods close at startup. Missing sources never postpone closure.
Storage and CSV finalization happen before external notification delivery. A delivery failure creates a persistent Home Assistant notification and remains visible in diagnostics.
Notification text automatically follows the language configured in Home Assistant. English is used as the fallback when a translation is unavailable.
Example compact report:
β‘ ENERGY REPORT Β· Home
π
07/2026
π Consumption: 183.65 kWh
βοΈ Previous month: +12.30 kWh Β· +7.2%
π Annual total: 1146.80 kWh
β
Data coverage: 100.0%
πΆ Tariff: 0.2800 EUR/kWh
π° Total cost: 51.42 EUR
Reconstructed consumption appears only when present. Coverage problems, unquantified gaps and excluded increments are placed after tariff and total cost as explicit warnings.
The Send or resend latest report button uses the newest consolidated record, including an imported closed month. It does not recalculate the month, change storage or duplicate CSV rows. Import itself never sends notifications automatically.
Each configured instance creates:
- current-month energy and cost;
- month-end energy and cost forecasts;
- current-year energy and cost;
- previous-month energy and cost;
- modifiable tariff;
- send-or-resend-latest-report button;
- disabled-by-default diagnostic sensor.
Forecasts use the average rate of the covered current-month interval. They remain unavailable during the first three complete days and when coverage is below 80%.
Every instance owns a stable directory:
/config/energy_report/<instance-id>/energy-report-2026.csv
Home Assistant's versioned store is authoritative. Annual CSV files are portable derived archives, rewritten atomically from that state and intended for external backup or spreadsheet use.
The exact ordered schema is:
schema_version,record_status,year,month,period_start,period_end,measured_kwh,reconstructed_kwh,total_kwh,coverage_percent,unknown_duration_minutes,excluded_kwh,tariff_per_kwh,currency,total_cost,data_quality,origin,snapshot_at,closed_atOperational annual archives contain closed records only. From Configure β Export CSV history, the current-year backup also includes the open month with a fresh snapshot_at; the previous-year backup contains closed months. The resulting instance-specific file is downloaded through an authenticated Home Assistant endpoint and can be reimported with the same CSV importer.
The documented template is available in examples/history-import.csv.
Import rules:
- use ISO timestamps and a decimal point;
- use
closedfor consolidated months; - include at most one
openrecord for the current month; - keep all values non-negative and internally consistent;
- for an open current-month row, set
snapshot_atto the timestamp represented by its totals; - open Configure β Import CSV history;
- verify the target instance name and stable ID, choose the CSV from the device running the browser and review the preview;
- if the current month conflicts, explicitly keep Energy Report data, safely merge non-overlapping periods or replace it with the CSV snapshot;
- confirm only when all category counts are correct.
The complete file is validated before state changes. Missing months are imported, identical months are ignored and conflicting closed months are rejected because they are immutable. A safe merge is offered only when the timezone-aware CSV snapshot_at is not later than the Home Assistant config-entry creation time: the CSV balance is then added to consumption collected natively after activation, while the current hardware baselines remain in place. Replacement remains an explicit alternative; it stores a backup and resets baselines. Imported records do not send notifications. Schema version 1 remains accepted for closed-history migration, but safe current-month merging requires schema version 2.
The importer is provider-neutral: source-specific conversion remains outside the integration, while the resulting monthly records use the documented public CSV format.
The disabled-by-default diagnostic sensor reports:
- source mode and data quality;
- measured and reconstructed current-month energy;
- power shadow total and percentage deviation;
- coverage;
- resets, source changes and anomalous jumps;
- cumulative-source gap state;
- last valid energy and power timestamps;
- last closed report and notification outcome;
- latest actionable error.
Downloadable diagnostics include the current accounting record and annual totals. They exclude source entity IDs and the configured notification target.
Run the dependency-free accounting tests:
python3 -m unittest discover -s tests -vValidate Python and JSON syntax:
python3 -m compileall custom_components tests
python3 -m json.tool custom_components/energy_report/manifest.jsonRebuild banner and social-preview assets from their SVG sources:
source/build-assets.shThe canonical iSSU footer and integration icons are reused unchanged from the other iSSU repositories and are deliberately not reconstructed by that script.
The GitHub workflow also runs HACS validation and Hassfest.
Detailed design and verification contracts are available in:
Before cutover:
- export or record the available monthly consumption history;
- reconstruct the Energy Report CSV and review every row;
- install Energy Report without deleting the original evidence;
- import the approved closed months and optional current-month balance;
- establish the native integration baseline;
- compare the old and new values during a controlled observation window;
- stop the previous monthly report only after validation;
- keep rollback evidence until the first native monthly close succeeds.
Do not run two independent systems as authoritative monthly ledgers after cutover.
- HACS and Hassfest validation run in the GitHub workflow.
- Power integration accuracy depends on update frequency and source availability.
- Consumption-only accounting does not model photovoltaic production or export.
- Negative energy flows are unsupported.
- Time-of-use tariffs, fixed charges and progressive pricing are unsupported.
- Closed months are intentionally immutable.
- Instances are independent and cannot be aggregated by Energy Report 1.0.0.
- Legacy notification services that do not expose a
notifyentity remain usable only for migrated entries until a notification entity is selected. - The initial compatibility baseline is Home Assistant 2026.8 or newer.
Released under the MIT License.
