1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-04-02 00:27:49 +01:00

Fix sensor card graph not updating when value is unchanged (#29889)

This commit is contained in:
Petar Petrov
2026-02-27 16:41:54 +01:00
committed by Bram Kragten
parent aff1fedc9d
commit 7b8884f0fd

View File

@@ -6,6 +6,7 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { fireEvent } from "../../../common/dom/fire_event";
import { computeDomain } from "../../../common/entity/compute_domain";
import "../../../components/ha-spinner";
import type { HistoryStates } from "../../../data/history";
import { subscribeHistoryStatesTimeWindow } from "../../../data/history";
import type { HomeAssistant } from "../../../types";
import { findEntities } from "../common/find-entities";
@@ -66,6 +67,8 @@ export class HuiGraphHeaderFooter
private _error?: string;
private _history?: HistoryStates;
private _interval?: number;
private _subscribed?: Promise<(() => Promise<void>) | undefined>;
@@ -161,24 +164,8 @@ export class HuiGraphHeaderFooter
// Message came in before we had a chance to unload
return;
}
const width = this.clientWidth || this.offsetWidth;
// sample to 1 point per hour or 1 point per 5 pixels
const maxDetails = Math.max(
10,
this._config.detail! > 1
? Math.max(width / 5, this._config.hours_to_show!)
: this._config.hours_to_show!
);
const useMean = this._config.detail !== 2;
const { points } = coordinatesMinimalResponseCompressedState(
combinedHistory[this._config.entity],
width,
width / 5,
maxDetails,
{ minY: this._config.limits?.min, maxY: this._config.limits?.max },
useMean
);
this._coordinates = points;
this._history = combinedHistory;
this._computeCoordinates();
},
this._config.hours_to_show!,
[this._config.entity]
@@ -190,10 +177,63 @@ export class HuiGraphHeaderFooter
this._setRedrawTimer();
}
private _redrawGraph() {
if (this._coordinates) {
this._coordinates = [...this._coordinates];
private _computeCoordinates() {
if (!this._history || !this._config) {
return;
}
const entityHistory = this._history[this._config.entity];
if (!entityHistory?.length) {
return;
}
const width = this.clientWidth || this.offsetWidth;
// sample to 1 point per hour or 1 point per 5 pixels
const maxDetails = Math.max(
10,
this._config.detail! > 1
? Math.max(width / 5, this._config.hours_to_show!)
: this._config.hours_to_show!
);
const useMean = this._config.detail !== 2;
const { points } = coordinatesMinimalResponseCompressedState(
entityHistory,
width,
width / 5,
maxDetails,
{ minY: this._config.limits?.min, maxY: this._config.limits?.max },
useMean
);
this._coordinates = points;
}
private _redrawGraph() {
if (!this._history || !this._config?.hours_to_show) {
return;
}
const entityId = this._config.entity;
const entityHistory = this._history[entityId];
if (entityHistory?.length) {
const purgeBeforeTimestamp =
(Date.now() - this._config.hours_to_show * 60 * 60 * 1000) / 1000;
let purgedHistory = entityHistory.filter(
(entry) => entry.lu >= purgeBeforeTimestamp
);
if (purgedHistory.length !== entityHistory.length) {
if (
!purgedHistory.length ||
purgedHistory[0].lu !== purgeBeforeTimestamp
) {
// Preserve the last expired state as the start boundary
const lastExpiredState = {
...entityHistory[entityHistory.length - purgedHistory.length - 1],
};
lastExpiredState.lu = purgeBeforeTimestamp;
delete lastExpiredState.lc;
purgedHistory = [lastExpiredState, ...purgedHistory];
}
this._history = { ...this._history, [entityId]: purgedHistory };
}
}
this._computeCoordinates();
}
private _setRedrawTimer() {
@@ -211,6 +251,7 @@ export class HuiGraphHeaderFooter
this._subscribed.then((unsub) => unsub?.());
this._subscribed = undefined;
}
this._history = undefined;
}
protected updated(changedProps: PropertyValues) {