From edfc33039bc5eea06a18fbf35c2a152a0d827ed2 Mon Sep 17 00:00:00 2001 From: Tom Carpenter Date: Mon, 2 Feb 2026 13:11:52 +0000 Subject: [PATCH] Merge Long Term Statistics for Power Sensors in Energy Dashboard (#29319) * Merge Long Term Statistics for Power Sensors in Energy Dashboard When using 5minute data for the power sources chart, data would be missing if the selected range was beyond the short term statistics limit. This change takes data from long term statistics and merges it in to the power sources data if the short term statistics doesn't extend far enough back for the selection. * Skip for zero-length power statistics Prevent out of bounds array access if power statistics has no entries. --- src/data/energy.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/data/energy.ts b/src/data/energy.ts index 9cb1afd732..7977557cfc 100644 --- a/src/data/energy.ts +++ b/src/data/energy.ts @@ -511,6 +511,15 @@ const getEnergyData = async ( "mean", ]) : {}; + // If power stats 5 minute data is selected, then also fetch hourly data which + // will be used to back-fill any missing data points in the 5 minute data when + // the requested range is beyond the limit of short term statistics. + const _powerStatsHour: Statistics | Promise = + powerStatIds.length && finePeriod === "5minute" + ? fetchStatistics(hass!, start, end, powerStatIds, "hour", powerUnits, [ + "mean", + ]) + : {}; const _waterStats: Statistics | Promise = waterStatIds.length ? fetchStatistics(hass!, start, end, waterStatIds, period, waterUnits, [ @@ -619,6 +628,7 @@ const getEnergyData = async ( const [ energyStats, powerStats, + powerStatsHour, waterStats, energyStatsCompare, waterStatsCompare, @@ -627,12 +637,44 @@ const getEnergyData = async ( ] = await Promise.all([ _energyStats, _powerStats, + _powerStatsHour, _waterStats, _energyStatsCompare, _waterStatsCompare, _fossilEnergyConsumption, _fossilEnergyConsumptionCompare, ]); + + // Back-fill any missing power statistics from hourly data if present + if (Object.keys(powerStatsHour).length) { + powerStatIds.forEach((powerId) => { + if (powerId in powerStatsHour) { + // If we have extra hourly power statistics for an ID, we may need to + // insert data into statistics + if (powerId in powerStats && powerStats[powerId].length) { + // We have 5-minute data. Only insert hourly values for time periods + // before the first 5-minute value. + const powerStatFirst = powerStats[powerId][0]; + const powerStatHour = powerStatsHour[powerId]; + let powerStatHourLast = 0; + for (const powerStat of powerStatHour) { + if (powerStat.end > powerStatFirst.start) { + break; + } + powerStatHourLast++; + } + powerStats[powerId] = [ + ...powerStatHour.slice(0, powerStatHourLast), + ...powerStats[powerId], + ]; + } else { + // There was no 5-minute data, so simply insert full hourly data + powerStats[powerId] = powerStatsHour[powerId]; + } + } + }); + } + const stats = { ...energyStats, ...waterStats, ...powerStats }; if (compare) { statsCompare = { ...energyStatsCompare, ...waterStatsCompare };