From e069875432119e6aa0c2a70d8d23f17b297a7525 Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Mon, 5 May 2025 10:09:16 -0700 Subject: [PATCH] Add energy hourly calculations to CSV report (#25315) --- src/panels/energy/ha-panel-energy.ts | 120 +++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 7 deletions(-) diff --git a/src/panels/energy/ha-panel-energy.ts b/src/panels/energy/ha-panel-energy.ts index 7bf69dbc23..cb63510b66 100644 --- a/src/panels/energy/ha-panel-energy.ts +++ b/src/panels/energy/ha-panel-energy.ts @@ -22,11 +22,14 @@ import type { DeviceConsumptionEnergyPreference, } from "../../data/energy"; import { + computeConsumptionData, getEnergyDataCollection, getEnergyGasUnit, getEnergyWaterUnit, + getSummedData, } from "../../data/energy"; import { fileDownload } from "../../util/file_download"; +import type { StatisticValue } from "../../data/recorder"; const ENERGY_LOVELACE_CONFIG: LovelaceConfig = { views: [ @@ -177,18 +180,20 @@ class PanelEnergy extends LitElement { const csv: string[] = []; csv[0] = headers; - const processStat = function (stat: string, type: string, unit: string) { + const processCsvRow = function ( + id: string, + type: string, + unit: string, + data: StatisticValue[] + ) { let n = 0; const row: string[] = []; - if (!stats[stat]) { - return; - } - row.push(stat); + row.push(id); row.push(type); row.push(unit.normalize("NFKD")); times.forEach((t) => { - if (n < stats[stat].length && stats[stat][n].start === t) { - row.push((stats[stat][n].change ?? "").toString()); + if (n < data.length && data[n].start === t) { + row.push((data[n].change ?? "").toString()); n++; } else { row.push(""); @@ -197,6 +202,14 @@ class PanelEnergy extends LitElement { csv.push(row.join(",") + "\n"); }; + const processStat = function (stat: string, type: string, unit: string) { + if (!stats[stat]) { + return; + } + + processCsvRow(stat, type, unit, stats[stat]); + }; + const currency = this.hass.config.currency; const printCategory = function ( @@ -335,6 +348,99 @@ class PanelEnergy extends LitElement { printCategory("device_consumption", devices, electricUnit); + const { summedData, compareSummedData: _ } = getSummedData( + energyData.state + ); + const { consumption, compareConsumption: __ } = computeConsumptionData( + summedData, + undefined + ); + + const processConsumptionData = function ( + type: string, + unit: string, + data: Record + ) { + const data2: StatisticValue[] = []; + + Object.entries(data).forEach(([t, value]) => { + data2.push({ + start: Number(t), + end: NaN, + change: value, + }); + }); + + processCsvRow("", type, unit, data2); + }; + + const hasSolar = !!solar_productions.length; + const hasBattery = !!battery_ins.length; + const hasGridReturn = !!grid_productions.length; + const hasGridSource = !!grid_consumptions.length; + + if (hasGridSource) { + processConsumptionData( + "calculated_consumed_grid", + electricUnit, + consumption.used_grid + ); + if (hasBattery) { + processConsumptionData( + "calculated_grid_to_battery", + electricUnit, + consumption.grid_to_battery + ); + } + } + if (hasGridReturn && hasBattery) { + processConsumptionData( + "calculated_battery_to_grid", + electricUnit, + consumption.battery_to_grid + ); + } + if (hasBattery) { + processConsumptionData( + "calculated_consumed_battery", + electricUnit, + consumption.used_battery + ); + } + + if (hasSolar) { + processConsumptionData( + "calculated_consumed_solar", + electricUnit, + consumption.used_solar + ); + if (hasBattery) { + processConsumptionData( + "calculated_solar_to_battery", + electricUnit, + consumption.solar_to_battery + ); + } + if (hasGridReturn) { + processConsumptionData( + "calculated_solar_to_grid", + electricUnit, + consumption.solar_to_grid + ); + } + } + + if ( + (hasGridSource ? 1 : 0) + (hasSolar ? 1 : 0) + (hasBattery ? 1 : 0) > + 1 + ) { + processConsumptionData( + "calculated_total_consumption", + electricUnit, + consumption.used_total + ); + } + const blob = new Blob(csv, { type: "text/csv", });