From 6d95a59ca09752a554ed94d37e29dc8058188b52 Mon Sep 17 00:00:00 2001 From: Tom Carpenter Date: Thu, 19 Mar 2026 09:33:51 +0000 Subject: [PATCH] Skip plotting state value on statistic graph if units mismatch (#30214) * Use isExternalStatistic helper for consistency * Remove redundant if condition We have `band = drawBands && ...`, so there is no point checking if `drawBands` is true inside `if (band && ...)`. * Skip plotting state value on statistic graph if units mismatch For example plotting a *F sensor on a *C chart - statistic data will be converted to *C, but the state value will still be in *F so the displayed point is wrong. Similarly if plotting a kW sensor on a W chart, the same is true - statistics get converted to W by recorder, but the state value would still be in kW. In other words the plotted state point is complete nonsense. If the units of the statistic state don't match the units of the graph, we should not be displaying the value on the graph. * Remove redundant this.unit check Co-authored-by: Petar Petrov --------- Co-authored-by: Petar Petrov --- src/components/chart/statistics-chart.ts | 55 +++++++++++++----------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/src/components/chart/statistics-chart.ts b/src/components/chart/statistics-chart.ts index 604cd09c2c..b48b815373 100644 --- a/src/components/chart/statistics-chart.ts +++ b/src/components/chart/statistics-chart.ts @@ -27,6 +27,7 @@ import { getDisplayUnit, getStatisticLabel, getStatisticMetadata, + isExternalStatistic, statisticsHaveType, } from "../../data/recorder"; import type { ECOption } from "../../resources/echarts/echarts"; @@ -398,7 +399,23 @@ export class StatisticsChart extends LitElement { endTime = new Date(); } - let unit: string | undefined | null; + // Try to determine chart unit if it has not already been set explicitly + if (!this.unit) { + let unit: string | undefined | null; + statisticsData.forEach(([statistic_id, _stats]) => { + const meta = statisticsMetaData?.[statistic_id]; + const statisticUnit = getDisplayUnit(this.hass, statistic_id, meta); + if (unit === undefined) { + unit = statisticUnit; + } else if (unit !== null && unit !== statisticUnit) { + // Clear unit if not all statistics have same unit + unit = null; + } + }); + if (unit) { + this.unit = unit; + } + } const names = this.names || {}; statisticsData.forEach(([statistic_id, stats]) => { @@ -408,18 +425,6 @@ export class StatisticsChart extends LitElement { name = getStatisticLabel(this.hass, statistic_id, meta); } - if (!this.unit) { - if (unit === undefined) { - unit = getDisplayUnit(this.hass, statistic_id, meta); - } else if ( - unit !== null && - unit !== getDisplayUnit(this.hass, statistic_id, meta) - ) { - // Clear unit if not all statistics have same unit - unit = null; - } - } - // array containing [value1, value2, etc] let prevValues: (number | null)[][] | null = null; let prevEndTime: Date | undefined; @@ -543,7 +548,7 @@ export class StatisticsChart extends LitElement { (series as LineSeriesOption).areaStyle = undefined; } else { series.stackOrder = "seriesAsc"; - if (drawBands && type === bandTop) { + if (type === bandTop) { (series as LineSeriesOption).areaStyle = { color: color + "3F", }; @@ -623,13 +628,19 @@ export class StatisticsChart extends LitElement { }); } - // Append current state if viewing recent data + // Check if we need to display most recent data. Allow 10m of leeway for "now", + // because stats are 5 minute aggregated const now = new Date(); - // allow 10m of leeway for "now", because stats are 5 minute aggregated - const isUpToNow = now.getTime() - endTime.getTime() <= 600000; - if (isUpToNow) { - // Skip external statistics (they have ":" in the ID) - if (!statistic_id.includes(":")) { + const displayCurrentState = now.getTime() - endTime.getTime() <= 600000; + + // Show current state if required, and units match (or are unknown) + const statisticUnit = getDisplayUnit(this.hass, statistic_id, meta); + if ( + displayCurrentState && + (!this.unit || !statisticUnit || this.unit === statisticUnit) + ) { + // Skip external statistics + if (!isExternalStatistic(statistic_id)) { const stateObj = this.hass.states[statistic_id]; if (stateObj) { const currentValue = parseFloat(stateObj.state); @@ -670,10 +681,6 @@ export class StatisticsChart extends LitElement { Array.prototype.push.apply(legendData, statLegendData); }); - if (unit) { - this.unit = unit; - } - legendData.forEach(({ id, name, color, borderColor }) => { // Add an empty series for the legend totalDataSets.push({