Infer a limited history chart from state object (#19176)

* Infer a limited history chart from state object

* bugfix

* bugfix

* minor fixes from feedback
This commit is contained in:
karwosts 2024-02-28 10:20:56 -05:00 committed by GitHub
parent 94f74308d8
commit dd98ec771d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 60 additions and 18 deletions

View File

@ -111,7 +111,7 @@ export class StateHistoryChartLine extends LitElement {
config: this.hass.config,
},
},
suggestedMin: this.startTime,
min: this.startTime,
suggestedMax: this.endTime,
ticks: {
maxRotation: 0,

View File

@ -114,7 +114,7 @@ export class StateHistoryChartTimeline extends LitElement {
config: this.hass.config,
},
},
suggestedMin: this.startTime,
min: this.startTime,
suggestedMax: this.endTime,
ticks: {
autoSkip: true,

View File

@ -233,16 +233,32 @@ export class StateHistoryCharts extends LitElement {
new Date().getTime() - 60 * 60 * this.hoursToShow * 1000
);
} else {
this._computedStartTime = new Date(
(this.historyData?.timeline ?? []).reduce(
(minTime, stateInfo) =>
Math.min(
minTime,
new Date(stateInfo.data[0].last_changed).getTime()
),
new Date().getTime()
)
let minTimeAll = (this.historyData?.timeline ?? []).reduce(
(minTime, stateInfo) =>
Math.min(
minTime,
new Date(stateInfo.data[0].last_changed).getTime()
),
new Date().getTime()
);
minTimeAll = (this.historyData?.line ?? []).reduce(
(minTimeLine, line) =>
Math.min(
minTimeLine,
line.data.reduce(
(minTimeData, data) =>
Math.min(
minTimeData,
new Date(data.states[0].last_changed).getTime()
),
minTimeLine
)
),
minTimeAll
);
this._computedStartTime = new Date(minTimeAll);
}
}
}

View File

@ -205,7 +205,9 @@ export class TimelineController extends BarController {
const y = vScale.getPixelForValue(this.index);
const xStart = iScale.getPixelForValue(data.start.getTime());
const xStart = iScale.getPixelForValue(
Math.max(iScale.min, data.start.getTime())
);
const xEnd = iScale.getPixelForValue(data.end.getTime());
const width = xEnd - xStart;

View File

@ -49,7 +49,7 @@ export class TimeLineScale extends TimeScale {
max = isFinite(max) && !isNaN(max) ? max : +adapter.endOf(Date.now(), unit);
// Make sure that max is strictly higher than min (required by the lookup table)
this.min = Math.min(min, max - 1);
this.max = Math.max(min + 1, max);
this.min = adapter.parse(options.min, this) ?? Math.min(min, max - 1);
this.max = adapter.parse(options.max, this) ?? Math.max(min + 1, max);
}
}

View File

@ -81,7 +81,7 @@ export interface EntityHistoryState {
/** attributes */
a: { [key: string]: any };
/** last_changed; if set, also applies to lu */
lc: number;
lc?: number;
/** last_updated */
lu: number;
}
@ -419,17 +419,37 @@ const BLANK_UNIT = " ";
export const computeHistory = (
hass: HomeAssistant,
stateHistory: HistoryStates,
entityIds: string[],
localize: LocalizeFunc,
sensorNumericalDeviceClasses: string[],
splitDeviceClasses = false
): HistoryResult => {
const lineChartDevices: { [unit: string]: HistoryStates } = {};
const timelineDevices: TimelineEntity[] = [];
if (!stateHistory) {
const localStateHistory: HistoryStates = {};
// Create a limited history from stateObj if entity has no recorded history.
const allEntities = new Set([...entityIds, ...Object.keys(stateHistory)]);
allEntities.forEach((entity) => {
if (entity in stateHistory) {
localStateHistory[entity] = stateHistory[entity];
} else if (hass.states[entity]) {
localStateHistory[entity] = [
{
s: hass.states[entity].state,
a: hass.states[entity].attributes,
lu: new Date(hass.states[entity].last_updated).getTime() / 1000,
},
];
}
});
if (!localStateHistory) {
return { line: [], timeline: [] };
}
Object.keys(stateHistory).forEach((entityId) => {
const stateInfo = stateHistory[entityId];
Object.keys(localStateHistory).forEach((entityId) => {
const stateInfo = localStateHistory[entityId];
if (stateInfo.length === 0) {
return;
}

View File

@ -228,6 +228,7 @@ export class MoreInfoHistory extends LitElement {
this._stateHistory = computeHistory(
this.hass!,
combinedHistory,
[this.entityId],
this.hass!.localize,
sensorNumericDeviceClasses
);

View File

@ -433,6 +433,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
this._statisticsHistory = computeHistory(
this.hass,
statsHistoryStates,
[],
this.hass.localize,
sensorNumericDeviceClasses,
true
@ -472,6 +473,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
this._stateHistory = computeHistory(
this.hass,
history,
entityIds,
this.hass.localize,
sensorNumericDeviceClasses,
true

View File

@ -120,6 +120,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
this._stateHistory = computeHistory(
this.hass!,
combinedHistory,
this._entityIds,
this.hass!.localize,
sensorNumericDeviceClasses,
this._config?.split_device_classes