Remove calculation of change from frontend (#16477)

This commit is contained in:
Erik Montnemery 2023-05-11 10:17:12 +02:00 committed by GitHub
parent d66ca0467e
commit 72403f4276
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 55 additions and 170 deletions

View File

@ -32,12 +32,7 @@ import {
import type { HomeAssistant } from "../../types";
import "./ha-chart-base";
export type ExtendedStatisticType = StatisticType | "change";
export const supportedStatTypeMap: Record<
ExtendedStatisticType,
StatisticType
> = {
export const supportedStatTypeMap: Record<StatisticType, StatisticType> = {
mean: "mean",
min: "min",
max: "max",
@ -46,15 +41,6 @@ export const supportedStatTypeMap: Record<
change: "sum",
};
export const statTypeMap: Record<ExtendedStatisticType, StatisticType> = {
mean: "mean",
min: "min",
max: "max",
sum: "sum",
state: "state",
change: "sum",
};
@customElement("statistics-chart")
class StatisticsChart extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -72,7 +58,7 @@ class StatisticsChart extends LitElement {
@property({ attribute: false }) public endTime?: Date;
@property({ type: Array }) public statTypes: Array<ExtendedStatisticType> = [
@property({ type: Array }) public statTypes: Array<StatisticType> = [
"sum",
"min",
"mean",
@ -358,7 +344,7 @@ class StatisticsChart extends LitElement {
: this.statTypes;
sortedTypes.forEach((type) => {
if (statisticsHaveType(stats, statTypeMap[type])) {
if (statisticsHaveType(stats, type)) {
const band = drawBands && (type === "min" || type === "max");
statTypes.push(type);
statDataSets.push({
@ -391,7 +377,6 @@ class StatisticsChart extends LitElement {
let prevDate: Date | null = null;
// Process chart data.
let firstSum: number | null | undefined = null;
let prevSum: number | null | undefined = null;
stats.forEach((stat) => {
const startDate = new Date(stat.start);
if (prevDate === startDate) {
@ -408,13 +393,6 @@ class StatisticsChart extends LitElement {
} else {
val = (stat.sum || 0) - firstSum;
}
} else if (type === "change") {
if (prevSum === null || prevSum === undefined) {
prevSum = stat.sum;
return;
}
val = (stat.sum || 0) - prevSum;
prevSum = stat.sum;
} else {
val = stat[type];
}

View File

@ -1,8 +1,6 @@
import {
addDays,
addHours,
addMilliseconds,
addMonths,
differenceInDays,
endOfToday,
endOfYesterday,
@ -389,9 +387,6 @@ const getEnergyData = async (
const period =
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour";
// Subtract 1 hour from start to get starting point data
const startMinHour = addHours(start, -1);
const lengthUnit = hass.config.unit_system.length || "";
const energyUnits: StatisticsUnitConfiguration = {
energy: "kWh",
@ -402,26 +397,14 @@ const getEnergyData = async (
};
const _energyStats: Statistics | Promise<Statistics> = energyStatIds.length
? fetchStatistics(
hass!,
startMinHour,
end,
energyStatIds,
period,
energyUnits,
["sum"]
)
? fetchStatistics(hass!, start, end, energyStatIds, period, energyUnits, [
"change",
])
: {};
const _waterStats: Statistics | Promise<Statistics> = waterStatIds.length
? fetchStatistics(
hass!,
startMinHour,
end,
waterStatIds,
period,
waterUnits,
["sum"]
)
? fetchStatistics(hass!, start, end, waterStatIds, period, waterUnits, [
"change",
])
: {};
let statsCompare;
@ -431,35 +414,27 @@ const getEnergyData = async (
let _waterStatsCompare: Statistics | Promise<Statistics> = {};
if (compare) {
if (dayDifference > 27 && dayDifference < 32) {
// When comparing a month, we want to start at the begining of the month
startCompare = addMonths(start, -1);
} else {
startCompare = addDays(start, (dayDifference + 1) * -1);
}
const compareStartMinHour = addHours(startCompare, -1);
endCompare = addMilliseconds(start, -1);
if (energyStatIds.length) {
_energyStatsCompare = fetchStatistics(
hass!,
compareStartMinHour,
start,
endCompare,
energyStatIds,
period,
energyUnits,
["sum"]
["change"]
);
}
if (waterStatIds.length) {
_waterStatsCompare = fetchStatistics(
hass!,
compareStartMinHour,
start,
endCompare,
waterStatIds,
period,
waterUnits,
["sum"]
["change"]
);
}
}
@ -522,19 +497,6 @@ const getEnergyData = async (
});
}
Object.values(stats).forEach((stat) => {
// if the start of the first value is after the requested period, we have the first data point, and should add a zero point
if (stat.length && new Date(stat[0].start) > startMinHour) {
stat.unshift({
...stat[0],
start: startMinHour.getTime(),
end: startMinHour.getTime(),
sum: 0,
state: 0,
});
}
});
const data: EnergyData = {
start,
end,

View File

@ -2,7 +2,7 @@ import { computeStateName } from "../common/entity/compute_state_name";
import { HaDurationData } from "../components/ha-duration-input";
import { HomeAssistant } from "../types";
export type StatisticType = "state" | "sum" | "min" | "max" | "mean";
export type StatisticType = "change" | "state" | "sum" | "min" | "max" | "mean";
export interface Statistics {
[statisticId: string]: StatisticValue[];
@ -11,6 +11,7 @@ export interface Statistics {
export interface StatisticValue {
start: number;
end: number;
change?: number | null;
last_reset?: number | null;
max?: number | null;
mean?: number | null;
@ -91,6 +92,7 @@ export interface StatisticsUnitConfiguration {
}
const statisticTypes = [
"change",
"last_reset",
"max",
"mean",
@ -196,18 +198,24 @@ export const clearStatistics = (hass: HomeAssistant, statistic_ids: string[]) =>
export const calculateStatisticSumGrowth = (
values: StatisticValue[]
): number | null => {
if (!values || values.length < 2) {
let growth: number | null = null;
if (!values) {
return null;
}
const endSum = values[values.length - 1].sum;
if (endSum === null || endSum === undefined) {
return null;
for (const value of values) {
if (value.change === null || value.change === undefined) {
continue;
}
if (growth === null) {
growth = value.change;
} else {
growth += value.change;
}
}
const startSum = values[0].sum;
if (startSum === null || startSum === undefined) {
return endSum;
}
return endSum - startSum;
return growth;
};
export const calculateStatisticsSumGrowth = (

View File

@ -6,7 +6,7 @@ import {
ScatterDataPoint,
} from "chart.js";
import { getRelativePosition } from "chart.js/helpers";
import { addHours, differenceInDays } from "date-fns/esm";
import { differenceInDays } from "date-fns/esm";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
import { customElement, property, query, state } from "lit/decorators";
@ -181,8 +181,6 @@ export class HuiEnergyDevicesGraphCard
const period =
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour";
const startMinHour = addHours(energyData.start, -1);
const lengthUnit = this.hass.config.unit_system.length || "";
const units: StatisticsUnitConfiguration = {
energy: "kWh",
@ -191,53 +189,26 @@ export class HuiEnergyDevicesGraphCard
const data = await fetchStatistics(
this.hass,
startMinHour,
energyData.start,
energyData.end,
devices,
period,
units,
["sum"]
["change"]
);
Object.values(data).forEach((stat) => {
// if the start of the first value is after the requested period, we have the first data point, and should add a zero point
if (stat.length && new Date(stat[0].start) > startMinHour) {
stat.unshift({
...stat[0],
start: startMinHour.getTime(),
end: startMinHour.getTime(),
sum: 0,
state: 0,
});
}
});
let compareData: Statistics | undefined;
if (energyData.startCompare && energyData.endCompare) {
const startCompareMinHour = addHours(energyData.startCompare, -1);
compareData = await fetchStatistics(
this.hass,
startCompareMinHour,
energyData.startCompare,
energyData.endCompare,
devices,
period,
units,
["sum"]
["change"]
);
Object.values(compareData).forEach((stat) => {
// if the start of the first value is after the requested period, we have the first data point, and should add a zero point
if (stat.length && new Date(stat[0].start) > startMinHour) {
stat.unshift({
...stat[0],
start: startCompareMinHour.getTime(),
end: startCompareMinHour.getTime(),
sum: 0,
state: 0,
});
}
});
}
const chartData: Array<ChartDataset<"bar", ParsedDataType<"bar">>["data"]> =

View File

@ -345,7 +345,6 @@ export class HuiEnergyGasGraphCard
? rgb2hex(lab2rgb(modifiedColor))
: gasColor;
let prevValue: number | null = null;
let prevStart: number | null = null;
const gasConsumptionData: ScatterDataPoint[] = [];
@ -355,24 +354,18 @@ export class HuiEnergyGasGraphCard
const stats = statistics[source.stat_energy_from];
for (const point of stats) {
if (point.sum === null || point.sum === undefined) {
continue;
}
if (prevValue === null || prevValue === undefined) {
prevValue = point.sum;
if (point.change === null || point.change === undefined) {
continue;
}
if (prevStart === point.start) {
continue;
}
const value = point.sum - prevValue;
const date = new Date(point.start);
gasConsumptionData.push({
x: date.getTime(),
y: value,
y: point.change,
});
prevStart = point.start;
prevValue = point.sum;
}
}

View File

@ -365,7 +365,6 @@ export class HuiEnergySolarGraphCard
? rgb2hex(lab2rgb(modifiedColor))
: solarColor;
let prevValue: number | null = null;
let prevStart: number | null = null;
const solarProductionData: ScatterDataPoint[] = [];
@ -375,24 +374,18 @@ export class HuiEnergySolarGraphCard
const stats = statistics[source.stat_energy_from];
for (const point of stats) {
if (point.sum === null || point.sum === undefined) {
continue;
}
if (prevValue === null || prevValue === undefined) {
prevValue = point.sum;
if (point.change === null || point.change === undefined) {
continue;
}
if (prevStart === point.start) {
continue;
}
const value = point.sum - prevValue;
const date = new Date(point.start);
solarProductionData.push({
x: date.getTime(),
y: value,
y: point.change,
});
prevStart = point.start;
prevValue = point.sum;
}
}

View File

@ -478,16 +478,11 @@ export class HuiEnergyUsageGraphCard
}
const set = {};
let prevValue: number;
stats.forEach((stat) => {
if (stat.sum === null || stat.sum === undefined) {
if (stat.change === null || stat.change === undefined) {
return;
}
if (prevValue === undefined) {
prevValue = stat.sum;
return;
}
const val = stat.sum - prevValue;
const val = stat.change;
// Get total of solar and to grid to calculate the solar energy used
if (sum) {
totalStats[stat.start] =
@ -496,7 +491,6 @@ export class HuiEnergyUsageGraphCard
if (add && !(stat.start in set)) {
set[stat.start] = val;
}
prevValue = stat.sum;
});
sets[id] = set;
});

View File

@ -343,7 +343,6 @@ export class HuiEnergyWaterGraphCard
? rgb2hex(lab2rgb(modifiedColor))
: waterColor;
let prevValue: number | null = null;
let prevStart: number | null = null;
const waterConsumptionData: ScatterDataPoint[] = [];
@ -353,24 +352,18 @@ export class HuiEnergyWaterGraphCard
const stats = statistics[source.stat_energy_from];
for (const point of stats) {
if (point.sum === null || point.sum === undefined) {
continue;
}
if (prevValue === null || prevValue === undefined) {
prevValue = point.sum;
if (point.change === null || point.change === undefined) {
continue;
}
if (prevStart === point.start) {
continue;
}
const value = point.sum - prevValue;
const date = new Date(point.start);
waterConsumptionData.push({
x: date.getTime(),
y: value,
y: point.change,
});
prevStart = point.start;
prevValue = point.sum;
}
}

View File

@ -9,10 +9,6 @@ import {
} from "lit";
import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import {
ExtendedStatisticType,
statTypeMap,
} from "../../../components/chart/statistics-chart";
import "../../../components/ha-card";
import {
fetchStatistics,
@ -20,6 +16,7 @@ import {
getStatisticMetadata,
Statistics,
StatisticsMetaData,
StatisticType,
} from "../../../data/recorder";
import { HomeAssistant } from "../../../types";
import { findEntities } from "../common/find-entities";
@ -74,7 +71,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard {
private _interval?: number;
private _statTypes?: Array<ExtendedStatisticType>;
private _statTypes?: Array<StatisticType>;
public disconnectedCallback() {
super.disconnectedCallback();
@ -124,7 +121,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard {
if (typeof config.stat_types === "string") {
this._statTypes = [config.stat_types];
} else if (!config.stat_types) {
this._statTypes = ["state", "sum", "min", "max", "mean"];
this._statTypes = ["change", "state", "sum", "min", "max", "mean"];
} else {
this._statTypes = config.stat_types;
}
@ -261,7 +258,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard {
this._entities,
this._config!.period,
unitconfig,
this._statTypes?.map((stat_type) => statTypeMap[stat_type])
this._statTypes
);
} catch (err) {
this._statistics = undefined;

View File

@ -1,4 +1,4 @@
import { Statistic } from "../../../data/recorder";
import { Statistic, StatisticType } from "../../../data/recorder";
import { ActionConfig, LovelaceCardConfig } from "../../../data/lovelace";
import { FullCalendarView, TranslationDict } from "../../../types";
import { Condition } from "../common/validate-condition";
@ -10,7 +10,6 @@ import {
LovelaceRowConfig,
} from "../entity-rows/types";
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
import { ExtendedStatisticType } from "../../../components/chart/statistics-chart";
import { HaDurationData } from "../../../components/ha-duration-input";
import { LovelaceTileFeatureConfig } from "../tile-features/types";
@ -310,7 +309,7 @@ export interface StatisticsGraphCardConfig extends LovelaceCardConfig {
unit?: string;
days_to_show?: number;
period?: "5minute" | "hour" | "day" | "month";
stat_types?: ExtendedStatisticType | ExtendedStatisticType[];
stat_types?: StatisticType | StatisticType[];
chart_type?: "line" | "bar";
hide_legend?: boolean;
}

View File

@ -24,11 +24,7 @@ import { ensureArray } from "../../../../common/array/ensure-array";
import { fireEvent } from "../../../../common/dom/fire_event";
import type { LocalizeFunc } from "../../../../common/translations/localize";
import { deepEqual } from "../../../../common/util/deep-equal";
import {
ExtendedStatisticType,
statTypeMap,
supportedStatTypeMap,
} from "../../../../components/chart/statistics-chart";
import { supportedStatTypeMap } from "../../../../components/chart/statistics-chart";
import "../../../../components/entity/ha-statistics-picker";
import "../../../../components/ha-form/ha-form";
import type { HaFormSchema } from "../../../../components/ha-form/types";
@ -38,6 +34,7 @@ import {
isExternalStatistic,
StatisticsMetaData,
statisticsMetaHasType,
StatisticType,
} from "../../../../data/recorder";
import type { HomeAssistant } from "../../../../types";
import type { StatisticsGraphCardConfig } from "../../cards/types";
@ -86,7 +83,7 @@ const stat_types = [
"sum",
"state",
"change",
] as ExtendedStatisticType[];
] as StatisticType[];
@customElement("hui-statistics-graph-card-editor")
export class HuiStatisticsGraphCardEditor
@ -253,7 +250,7 @@ export class HuiStatisticsGraphCardEditor
(stat_type) =>
stat_type !== "change" &&
this._metaDatas?.every((metaData) =>
statisticsMetaHasType(metaData, statTypeMap[stat_type])
statisticsMetaHasType(metaData, stat_type)
)
);
const data = {
@ -324,7 +321,7 @@ export class HuiStatisticsGraphCardEditor
if (config.stat_types && config.entities.length) {
config.stat_types = ensureArray(config.stat_types).filter((stat_type) =>
metadata!.every((metaData) =>
statisticsMetaHasType(metaData, statTypeMap[stat_type])
statisticsMetaHasType(metaData, stat_type)
)
);
if (!config.stat_types.length) {