mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Remove calculation of change from frontend (#16477)
This commit is contained in:
parent
d66ca0467e
commit
72403f4276
@ -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];
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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 = (
|
||||
|
@ -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"]> =
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
});
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user