mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
Share energy sum calculation across all cards (#25184)
This commit is contained in:
parent
8901c1fb31
commit
6464c2b602
@ -782,12 +782,19 @@ export const getEnergyWaterUnit = (hass: HomeAssistant): string =>
|
|||||||
export const energyStatisticHelpUrl =
|
export const energyStatisticHelpUrl =
|
||||||
"/docs/energy/faq/#troubleshooting-missing-entities";
|
"/docs/energy/faq/#troubleshooting-missing-entities";
|
||||||
|
|
||||||
interface EnergySumData {
|
export interface EnergySumData {
|
||||||
to_grid?: Record<number, number>;
|
to_grid?: Record<number, number>;
|
||||||
from_grid?: Record<number, number>;
|
from_grid?: Record<number, number>;
|
||||||
to_battery?: Record<number, number>;
|
to_battery?: Record<number, number>;
|
||||||
from_battery?: Record<number, number>;
|
from_battery?: Record<number, number>;
|
||||||
solar?: Record<number, number>;
|
solar?: Record<number, number>;
|
||||||
|
total: {
|
||||||
|
to_grid?: number;
|
||||||
|
from_grid?: number;
|
||||||
|
to_battery?: number;
|
||||||
|
from_battery?: number;
|
||||||
|
solar?: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EnergyConsumptionData {
|
interface EnergyConsumptionData {
|
||||||
@ -860,29 +867,30 @@ const getSummedDataPartial = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const summedData: EnergySumData = {};
|
const summedData: EnergySumData = { total: {} };
|
||||||
Object.entries(statIds).forEach(([key, subStatIds]) => {
|
Object.entries(statIds).forEach(([key, subStatIds]) => {
|
||||||
const totalStats: Record<number, number> = {};
|
const totalStats: Record<number, number> = {};
|
||||||
const sets: Record<string, Record<number, number>> = {};
|
const sets: Record<string, Record<number, number>> = {};
|
||||||
|
let sum = 0;
|
||||||
subStatIds!.forEach((id) => {
|
subStatIds!.forEach((id) => {
|
||||||
const stats = compare ? data.statsCompare[id] : data.stats[id];
|
const stats = compare ? data.statsCompare[id] : data.stats[id];
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const set = {};
|
const set = {};
|
||||||
stats.forEach((stat) => {
|
stats.forEach((stat) => {
|
||||||
if (stat.change === null || stat.change === undefined) {
|
if (stat.change === null || stat.change === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const val = stat.change;
|
const val = stat.change;
|
||||||
// Get total of solar and to grid to calculate the solar energy used
|
sum += val;
|
||||||
totalStats[stat.start] =
|
totalStats[stat.start] =
|
||||||
stat.start in totalStats ? totalStats[stat.start] + val : val;
|
stat.start in totalStats ? totalStats[stat.start] + val : val;
|
||||||
});
|
});
|
||||||
sets[id] = set;
|
sets[id] = set;
|
||||||
});
|
});
|
||||||
summedData[key] = totalStats;
|
summedData[key] = totalStats;
|
||||||
|
summedData.total[key] = sum;
|
||||||
});
|
});
|
||||||
|
|
||||||
return summedData;
|
return summedData;
|
||||||
|
@ -11,10 +11,9 @@ import "../../../../components/ha-svg-icon";
|
|||||||
import "../../../../components/ha-tooltip";
|
import "../../../../components/ha-tooltip";
|
||||||
import type { EnergyData } from "../../../../data/energy";
|
import type { EnergyData } from "../../../../data/energy";
|
||||||
import {
|
import {
|
||||||
energySourcesByType,
|
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
|
getSummedData,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
|
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import { createEntityNotFoundWarning } from "../../components/hui-warning";
|
import { createEntityNotFoundWarning } from "../../components/hui-warning";
|
||||||
@ -92,14 +91,9 @@ class HuiEnergyCarbonGaugeCard
|
|||||||
</hui-warning>`;
|
</hui-warning>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefs = this._data.prefs;
|
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
||||||
const types = energySourcesByType(prefs);
|
|
||||||
|
|
||||||
const totalGridConsumption =
|
const totalGridConsumption = summedData.total.from_grid ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.grid![0].flow_from.map((flow) => flow.stat_energy_from)
|
|
||||||
) ?? 0;
|
|
||||||
|
|
||||||
let value: number | undefined;
|
let value: number | undefined;
|
||||||
|
|
||||||
@ -111,18 +105,9 @@ class HuiEnergyCarbonGaugeCard
|
|||||||
)
|
)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
const totalSolarProduction = types.solar
|
const totalSolarProduction = summedData.total.solar ?? 0;
|
||||||
? calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.solar.map((source) => source.stat_energy_from)
|
|
||||||
) || 0
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
const totalGridReturned =
|
const totalGridReturned = summedData.total.to_grid ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.grid![0].flow_to.map((flow) => flow.stat_energy_to)
|
|
||||||
) || 0;
|
|
||||||
|
|
||||||
const totalEnergyConsumed =
|
const totalEnergyConsumed =
|
||||||
totalGridConsumption +
|
totalGridConsumption +
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
getEnergyGasUnit,
|
getEnergyGasUnit,
|
||||||
getEnergyWaterUnit,
|
getEnergyWaterUnit,
|
||||||
formatConsumptionShort,
|
formatConsumptionShort,
|
||||||
|
getSummedData,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
|
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
@ -109,11 +110,9 @@ class HuiEnergyDistrubutionCard
|
|||||||
const hasWater = types.water !== undefined;
|
const hasWater = types.water !== undefined;
|
||||||
const hasReturnToGrid = hasConsumption && types.grid![0].flow_to.length > 0;
|
const hasReturnToGrid = hasConsumption && types.grid![0].flow_to.length > 0;
|
||||||
|
|
||||||
const totalFromGrid =
|
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
const totalFromGrid = summedData.total.from_grid ?? 0;
|
||||||
types.grid![0].flow_from.map((flow) => flow.stat_energy_from)
|
|
||||||
) ?? 0;
|
|
||||||
|
|
||||||
let waterUsage: number | null = null;
|
let waterUsage: number | null = null;
|
||||||
if (hasWater) {
|
if (hasWater) {
|
||||||
@ -136,37 +135,21 @@ class HuiEnergyDistrubutionCard
|
|||||||
let totalSolarProduction: number | null = null;
|
let totalSolarProduction: number | null = null;
|
||||||
|
|
||||||
if (hasSolarProduction) {
|
if (hasSolarProduction) {
|
||||||
totalSolarProduction =
|
totalSolarProduction = summedData.total.solar ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.solar!.map((source) => source.stat_energy_from)
|
|
||||||
) || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let totalBatteryIn: number | null = null;
|
let totalBatteryIn: number | null = null;
|
||||||
let totalBatteryOut: number | null = null;
|
let totalBatteryOut: number | null = null;
|
||||||
|
|
||||||
if (hasBattery) {
|
if (hasBattery) {
|
||||||
totalBatteryIn =
|
totalBatteryIn = summedData.total.to_battery ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
totalBatteryOut = summedData.total.from_battery ?? 0;
|
||||||
this._data.stats,
|
|
||||||
types.battery!.map((source) => source.stat_energy_to)
|
|
||||||
) || 0;
|
|
||||||
totalBatteryOut =
|
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.battery!.map((source) => source.stat_energy_from)
|
|
||||||
) || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let returnedToGrid: number | null = null;
|
let returnedToGrid: number | null = null;
|
||||||
|
|
||||||
if (hasReturnToGrid) {
|
if (hasReturnToGrid) {
|
||||||
returnedToGrid =
|
returnedToGrid = summedData.total.to_grid ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.grid![0].flow_to.map((flow) => flow.stat_energy_to)
|
|
||||||
) || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let solarConsumption: number | null = null;
|
let solarConsumption: number | null = null;
|
||||||
|
@ -9,12 +9,11 @@ import "../../../../components/ha-gauge";
|
|||||||
import type { LevelDefinition } from "../../../../components/ha-gauge";
|
import type { LevelDefinition } from "../../../../components/ha-gauge";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
import "../../../../components/ha-tooltip";
|
import "../../../../components/ha-tooltip";
|
||||||
import type {
|
import type { EnergyData } from "../../../../data/energy";
|
||||||
EnergyData,
|
import {
|
||||||
GridSourceTypeEnergyPreference,
|
getEnergyDataCollection,
|
||||||
|
getSummedData,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { getEnergyDataCollection } from "../../../../data/energy";
|
|
||||||
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
|
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import type { LovelaceCard } from "../../types";
|
import type { LovelaceCard } from "../../types";
|
||||||
@ -75,27 +74,17 @@ class HuiEnergyGridGaugeCard
|
|||||||
"ui.panel.lovelace.cards.energy.loading"
|
"ui.panel.lovelace.cards.energy.loading"
|
||||||
)}`;
|
)}`;
|
||||||
}
|
}
|
||||||
|
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
||||||
const prefs = this._data.prefs;
|
|
||||||
const gridSource = prefs.energy_sources.find(
|
|
||||||
(src) => src.type === "grid"
|
|
||||||
) as GridSourceTypeEnergyPreference | undefined;
|
|
||||||
|
|
||||||
let value: number | undefined;
|
let value: number | undefined;
|
||||||
|
|
||||||
if (!gridSource) {
|
if (!("from_grid" in summedData.total)) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const consumedFromGrid = calculateStatisticsSumGrowth(
|
const consumedFromGrid = summedData.total.from_grid ?? 0;
|
||||||
this._data.stats,
|
|
||||||
gridSource.flow_from.map((flow) => flow.stat_energy_from)
|
|
||||||
);
|
|
||||||
|
|
||||||
const returnedToGrid = calculateStatisticsSumGrowth(
|
const returnedToGrid = summedData.total.to_grid ?? 0;
|
||||||
this._data.stats,
|
|
||||||
gridSource.flow_to.map((flow) => flow.stat_energy_to)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (consumedFromGrid !== null && returnedToGrid !== null) {
|
if (consumedFromGrid !== null && returnedToGrid !== null) {
|
||||||
if (returnedToGrid > consumedFromGrid) {
|
if (returnedToGrid > consumedFromGrid) {
|
||||||
|
@ -8,9 +8,9 @@ import type { EnergyData } from "../../../../data/energy";
|
|||||||
import {
|
import {
|
||||||
energySourcesByType,
|
energySourcesByType,
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
|
getSummedData,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import {
|
import {
|
||||||
calculateStatisticsSumGrowth,
|
|
||||||
calculateStatisticSumGrowth,
|
calculateStatisticSumGrowth,
|
||||||
getStatisticLabel,
|
getStatisticLabel,
|
||||||
} from "../../../../data/recorder";
|
} from "../../../../data/recorder";
|
||||||
@ -80,6 +80,7 @@ class HuiEnergySankeyCard
|
|||||||
|
|
||||||
const prefs = this._data.prefs;
|
const prefs = this._data.prefs;
|
||||||
const types = energySourcesByType(prefs);
|
const types = energySourcesByType(prefs);
|
||||||
|
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
||||||
|
|
||||||
const computedStyle = getComputedStyle(this);
|
const computedStyle = getComputedStyle(this);
|
||||||
|
|
||||||
@ -98,11 +99,7 @@ class HuiEnergySankeyCard
|
|||||||
nodes.push(homeNode);
|
nodes.push(homeNode);
|
||||||
|
|
||||||
if (types.grid) {
|
if (types.grid) {
|
||||||
const totalFromGrid =
|
const totalFromGrid = summedData.total.from_grid ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.grid![0].flow_from.map((flow) => flow.stat_energy_from)
|
|
||||||
) ?? 0;
|
|
||||||
|
|
||||||
nodes.push({
|
nodes.push({
|
||||||
id: "grid",
|
id: "grid",
|
||||||
@ -125,11 +122,7 @@ class HuiEnergySankeyCard
|
|||||||
|
|
||||||
// Add solar if available
|
// Add solar if available
|
||||||
if (types.solar) {
|
if (types.solar) {
|
||||||
const totalSolarProduction =
|
const totalSolarProduction = summedData.total.solar ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.solar.map((source) => source.stat_energy_from)
|
|
||||||
) || 0;
|
|
||||||
|
|
||||||
nodes.push({
|
nodes.push({
|
||||||
id: "solar",
|
id: "solar",
|
||||||
@ -155,16 +148,8 @@ class HuiEnergySankeyCard
|
|||||||
|
|
||||||
if (types.battery) {
|
if (types.battery) {
|
||||||
// Add battery source
|
// Add battery source
|
||||||
const totalBatteryOut =
|
const totalBatteryOut = summedData.total.from_battery ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
const totalBatteryIn = summedData.total.to_battery ?? 0;
|
||||||
this._data.stats,
|
|
||||||
types.battery.map((source) => source.stat_energy_from)
|
|
||||||
) || 0;
|
|
||||||
const totalBatteryIn =
|
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.battery.map((source) => source.stat_energy_to)
|
|
||||||
) || 0;
|
|
||||||
const netBattery = totalBatteryOut - totalBatteryIn;
|
const netBattery = totalBatteryOut - totalBatteryIn;
|
||||||
const netBatteryOut = Math.max(netBattery, 0);
|
const netBatteryOut = Math.max(netBattery, 0);
|
||||||
const netBatteryIn = Math.max(-netBattery, 0);
|
const netBatteryIn = Math.max(-netBattery, 0);
|
||||||
@ -209,11 +194,7 @@ class HuiEnergySankeyCard
|
|||||||
|
|
||||||
// Add grid return if available
|
// Add grid return if available
|
||||||
if (types.grid && types.grid[0].flow_to) {
|
if (types.grid && types.grid[0].flow_to) {
|
||||||
const totalToGrid =
|
const totalToGrid = summedData.total.to_grid ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.grid[0].flow_to.map((flow) => flow.stat_energy_to)
|
|
||||||
) ?? 0;
|
|
||||||
|
|
||||||
nodes.push({
|
nodes.push({
|
||||||
id: "grid_return",
|
id: "grid_return",
|
||||||
|
@ -10,10 +10,9 @@ import "../../../../components/ha-svg-icon";
|
|||||||
import "../../../../components/ha-tooltip";
|
import "../../../../components/ha-tooltip";
|
||||||
import type { EnergyData } from "../../../../data/energy";
|
import type { EnergyData } from "../../../../data/energy";
|
||||||
import {
|
import {
|
||||||
energySourcesByType,
|
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
|
getSummedData,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
|
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import type { LovelaceCard } from "../../types";
|
import type { LovelaceCard } from "../../types";
|
||||||
@ -75,56 +74,35 @@ class HuiEnergySelfSufficiencyGaugeCard
|
|||||||
)}`;
|
)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefs = this._data.prefs;
|
|
||||||
const types = energySourcesByType(prefs);
|
|
||||||
|
|
||||||
// The strategy only includes this card if we have a grid.
|
// The strategy only includes this card if we have a grid.
|
||||||
const hasConsumption = true;
|
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
||||||
|
|
||||||
const hasSolarProduction = types.solar !== undefined;
|
const hasSolarProduction = summedData.solar !== undefined;
|
||||||
const hasBattery = types.battery !== undefined;
|
const hasBattery =
|
||||||
const hasReturnToGrid = hasConsumption && types.grid![0].flow_to.length > 0;
|
summedData.to_battery !== undefined ||
|
||||||
|
summedData.from_battery !== undefined;
|
||||||
|
const hasReturnToGrid = summedData.to_grid !== undefined;
|
||||||
|
|
||||||
const totalFromGrid =
|
const totalFromGrid = summedData.total.from_grid ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.grid![0].flow_from.map((flow) => flow.stat_energy_from)
|
|
||||||
) ?? 0;
|
|
||||||
|
|
||||||
let totalSolarProduction: number | null = null;
|
let totalSolarProduction: number | null = null;
|
||||||
|
|
||||||
if (hasSolarProduction) {
|
if (hasSolarProduction) {
|
||||||
totalSolarProduction =
|
totalSolarProduction = summedData.total.solar ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.solar!.map((source) => source.stat_energy_from)
|
|
||||||
) || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let totalBatteryIn: number | null = null;
|
let totalBatteryIn: number | null = null;
|
||||||
let totalBatteryOut: number | null = null;
|
let totalBatteryOut: number | null = null;
|
||||||
|
|
||||||
if (hasBattery) {
|
if (hasBattery) {
|
||||||
totalBatteryIn =
|
totalBatteryIn = summedData.total.to_battery ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
totalBatteryOut = summedData.total.from_battery ?? 0;
|
||||||
this._data.stats,
|
|
||||||
types.battery!.map((source) => source.stat_energy_to)
|
|
||||||
) || 0;
|
|
||||||
totalBatteryOut =
|
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.battery!.map((source) => source.stat_energy_from)
|
|
||||||
) || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let returnedToGrid: number | null = null;
|
let returnedToGrid: number | null = null;
|
||||||
|
|
||||||
if (hasReturnToGrid) {
|
if (hasReturnToGrid) {
|
||||||
returnedToGrid =
|
returnedToGrid = summedData.total.to_grid ?? 0;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.grid![0].flow_to.map((flow) => flow.stat_energy_to)
|
|
||||||
) || 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let solarConsumption: number | null = null;
|
let solarConsumption: number | null = null;
|
||||||
|
@ -9,10 +9,9 @@ import "../../../../components/ha-gauge";
|
|||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
import type { EnergyData } from "../../../../data/energy";
|
import type { EnergyData } from "../../../../data/energy";
|
||||||
import {
|
import {
|
||||||
energySourcesByType,
|
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
|
getSummedData,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { calculateStatisticsSumGrowth } from "../../../../data/recorder";
|
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import type { LovelaceCard } from "../../types";
|
import type { LovelaceCard } from "../../types";
|
||||||
@ -74,23 +73,14 @@ class HuiEnergySolarGaugeCard
|
|||||||
)}`;
|
)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const prefs = this._data.prefs;
|
const { summedData, compareSummedData: _ } = getSummedData(this._data);
|
||||||
const types = energySourcesByType(prefs);
|
if (!("solar" in summedData.total)) {
|
||||||
|
|
||||||
if (!types.solar) {
|
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const totalSolarProduction =
|
const totalSolarProduction = summedData.total.solar;
|
||||||
calculateStatisticsSumGrowth(
|
|
||||||
this._data.stats,
|
|
||||||
types.solar.map((source) => source.stat_energy_from)
|
|
||||||
) || 0;
|
|
||||||
|
|
||||||
const productionReturnedToGrid = calculateStatisticsSumGrowth(
|
const productionReturnedToGrid = summedData.total.to_grid ?? null;
|
||||||
this._data.stats,
|
|
||||||
types.grid![0].flow_to.map((flow) => flow.stat_energy_to)
|
|
||||||
);
|
|
||||||
|
|
||||||
let value: number | undefined;
|
let value: number | undefined;
|
||||||
|
|
||||||
|
@ -14,8 +14,11 @@ import { getEnergyColor } from "./common/color";
|
|||||||
import { formatNumber } from "../../../../common/number/format_number";
|
import { formatNumber } from "../../../../common/number/format_number";
|
||||||
import "../../../../components/chart/ha-chart-base";
|
import "../../../../components/chart/ha-chart-base";
|
||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
import type { EnergyData } from "../../../../data/energy";
|
import type { EnergyData, EnergySumData } from "../../../../data/energy";
|
||||||
import { getEnergyDataCollection } from "../../../../data/energy";
|
import {
|
||||||
|
getEnergyDataCollection,
|
||||||
|
getSummedData,
|
||||||
|
} from "../../../../data/energy";
|
||||||
import type { Statistics, StatisticsMetaData } from "../../../../data/recorder";
|
import type { Statistics, StatisticsMetaData } from "../../../../data/recorder";
|
||||||
import { getStatisticLabel } from "../../../../data/recorder";
|
import { getStatisticLabel } from "../../../../data/recorder";
|
||||||
import type { FrontendLocaleData } from "../../../../data/translation";
|
import type { FrontendLocaleData } from "../../../../data/translation";
|
||||||
@ -279,11 +282,14 @@ export class HuiEnergyUsageGraphCard
|
|||||||
this._compareStart = energyData.startCompare;
|
this._compareStart = energyData.startCompare;
|
||||||
this._compareEnd = energyData.endCompare;
|
this._compareEnd = energyData.endCompare;
|
||||||
|
|
||||||
|
const { summedData, compareSummedData } = getSummedData(energyData);
|
||||||
|
|
||||||
if (energyData.statsCompare) {
|
if (energyData.statsCompare) {
|
||||||
datasets.push(
|
datasets.push(
|
||||||
...this._processDataSet(
|
...this._processDataSet(
|
||||||
energyData.statsCompare,
|
energyData.statsCompare,
|
||||||
energyData.statsMetadata,
|
energyData.statsMetadata,
|
||||||
|
compareSummedData!,
|
||||||
statIds,
|
statIds,
|
||||||
colorIndices,
|
colorIndices,
|
||||||
computedStyles,
|
computedStyles,
|
||||||
@ -308,6 +314,7 @@ export class HuiEnergyUsageGraphCard
|
|||||||
...this._processDataSet(
|
...this._processDataSet(
|
||||||
energyData.stats,
|
energyData.stats,
|
||||||
energyData.statsMetadata,
|
energyData.statsMetadata,
|
||||||
|
summedData,
|
||||||
statIds,
|
statIds,
|
||||||
colorIndices,
|
colorIndices,
|
||||||
computedStyles,
|
computedStyles,
|
||||||
@ -325,6 +332,7 @@ export class HuiEnergyUsageGraphCard
|
|||||||
private _processDataSet(
|
private _processDataSet(
|
||||||
statistics: Statistics,
|
statistics: Statistics,
|
||||||
statisticsMetaData: Record<string, StatisticsMetaData>,
|
statisticsMetaData: Record<string, StatisticsMetaData>,
|
||||||
|
summedData: EnergySumData,
|
||||||
statIdsByCat: {
|
statIdsByCat: {
|
||||||
to_grid?: string[] | undefined;
|
to_grid?: string[] | undefined;
|
||||||
from_grid?: string[] | undefined;
|
from_grid?: string[] | undefined;
|
||||||
@ -352,24 +360,11 @@ export class HuiEnergyUsageGraphCard
|
|||||||
used_battery?: Record<string, Record<number, number>>;
|
used_battery?: Record<string, Record<number, number>>;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
const summedData: {
|
|
||||||
to_grid?: Record<number, number>;
|
|
||||||
from_grid?: Record<number, number>;
|
|
||||||
to_battery?: Record<number, number>;
|
|
||||||
from_battery?: Record<number, number>;
|
|
||||||
solar?: Record<number, number>;
|
|
||||||
} = {};
|
|
||||||
|
|
||||||
Object.entries(statIdsByCat).forEach(([key, statIds]) => {
|
Object.entries(statIdsByCat).forEach(([key, statIds]) => {
|
||||||
const sum = [
|
|
||||||
"solar",
|
|
||||||
"to_grid",
|
|
||||||
"from_grid",
|
|
||||||
"to_battery",
|
|
||||||
"from_battery",
|
|
||||||
].includes(key);
|
|
||||||
const add = !["solar", "from_battery"].includes(key);
|
const add = !["solar", "from_battery"].includes(key);
|
||||||
const totalStats: Record<number, number> = {};
|
if (!add) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const sets: Record<string, Record<number, number>> = {};
|
const sets: Record<string, Record<number, number>> = {};
|
||||||
statIds!.forEach((id) => {
|
statIds!.forEach((id) => {
|
||||||
const stats = statistics[id];
|
const stats = statistics[id];
|
||||||
@ -383,23 +378,13 @@ export class HuiEnergyUsageGraphCard
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const val = stat.change;
|
const val = stat.change;
|
||||||
// Get total of solar and to grid to calculate the solar energy used
|
if (!(stat.start in set)) {
|
||||||
if (sum) {
|
|
||||||
totalStats[stat.start] =
|
|
||||||
stat.start in totalStats ? totalStats[stat.start] + val : val;
|
|
||||||
}
|
|
||||||
if (add && !(stat.start in set)) {
|
|
||||||
set[stat.start] = val;
|
set[stat.start] = val;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
sets[id] = set;
|
sets[id] = set;
|
||||||
});
|
});
|
||||||
if (sum) {
|
combinedData[key] = sets;
|
||||||
summedData[key] = totalStats;
|
|
||||||
}
|
|
||||||
if (add) {
|
|
||||||
combinedData[key] = sets;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const grid_to_battery = {};
|
const grid_to_battery = {};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user