Skip to content

Commit

Permalink
Infer a limited history chart from state object (#19176)
Browse files Browse the repository at this point in the history
* Infer a limited history chart from state object

* bugfix

* bugfix

* minor fixes from feedback
  • Loading branch information
karwosts authored Feb 28, 2024
1 parent 94f7430 commit dd98ec7
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/components/chart/state-history-chart-line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/components/chart/state-history-chart-timeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
34 changes: 25 additions & 9 deletions src/components/chart/state-history-charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/components/chart/timeline-chart/timeline-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions src/components/chart/timeline-chart/timeline-scale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
28 changes: 24 additions & 4 deletions src/data/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions src/dialogs/more-info/ha-more-info-history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ export class MoreInfoHistory extends LitElement {
this._stateHistory = computeHistory(
this.hass!,
combinedHistory,
[this.entityId],
this.hass!.localize,
sensorNumericDeviceClasses
);
Expand Down
2 changes: 2 additions & 0 deletions src/panels/history/ha-panel-history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
this._statisticsHistory = computeHistory(
this.hass,
statsHistoryStates,
[],
this.hass.localize,
sensorNumericDeviceClasses,
true
Expand Down Expand Up @@ -472,6 +473,7 @@ class HaPanelHistory extends SubscribeMixin(LitElement) {
this._stateHistory = computeHistory(
this.hass,
history,
entityIds,
this.hass.localize,
sensorNumericDeviceClasses,
true
Expand Down
1 change: 1 addition & 0 deletions src/panels/lovelace/cards/hui-history-graph-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit dd98ec7

Please sign in to comment.