Use backend for day month stats in energy dashboard (#10728)

pull/10745/head
Bram Kragten 2021-11-30 18:22:06 +01:00 committed by GitHub
parent d5fc751da6
commit fd6785b593
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 239 additions and 836 deletions

View File

@ -82,6 +82,9 @@ export const mockEnergy = (hass: MockHomeAssistant) => {
],
}));
hass.mockWS("energy/info", () => ({ cost_sensors: [] }));
hass.mockWS("energy/fossil_energy_consumption", ({ period }) => ({
start: period === "month" ? 500 : period === "day" ? 20 : 5,
}));
const todayString = format(startOfToday(), "yyyy-MM-dd");
const tomorrowString = format(startOfTomorrow(), "yyyy-MM-dd");
hass.mockWS(

View File

@ -1,4 +1,10 @@
import { addHours, differenceInHours, endOfDay } from "date-fns";
import {
addDays,
addHours,
addMonths,
differenceInHours,
endOfDay,
} from "date-fns";
import { HassEntity } from "home-assistant-js-websocket";
import { StatisticValue } from "../../../src/data/history";
import { MockHomeAssistant } from "../../../src/fake_data/provide_hass";
@ -70,6 +76,7 @@ const generateMeanStatistics = (
id: string,
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number
) => {
@ -84,6 +91,7 @@ const generateMeanStatistics = (
statistics.push({
statistic_id: id,
start: currentDate.toISOString(),
end: currentDate.toISOString(),
mean,
min: mean - Math.random() * maxDiff,
max: mean + Math.random() * maxDiff,
@ -92,7 +100,12 @@ const generateMeanStatistics = (
sum: null,
});
lastVal = mean;
currentDate = addHours(currentDate, 1);
currentDate =
period === "day"
? addDays(currentDate, 1)
: period === "month"
? addMonths(currentDate, 1)
: addHours(currentDate, 1);
}
return statistics;
};
@ -101,6 +114,7 @@ const generateSumStatistics = (
id: string,
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number
) => {
@ -115,6 +129,7 @@ const generateSumStatistics = (
statistics.push({
statistic_id: id,
start: currentDate.toISOString(),
end: currentDate.toISOString(),
mean: null,
min: null,
max: null,
@ -122,7 +137,12 @@ const generateSumStatistics = (
state: initValue + sum,
sum,
});
currentDate = addHours(currentDate, 1);
currentDate =
period === "day"
? addDays(currentDate, 1)
: period === "month"
? addMonths(currentDate, 1)
: addHours(currentDate, 1);
}
return statistics;
};
@ -131,6 +151,7 @@ const generateCurvedStatistics = (
id: string,
start: Date,
end: Date,
_period: "5minute" | "hour" | "day" | "month" = "hour",
initValue: number,
maxDiff: number,
metered: boolean
@ -149,6 +170,7 @@ const generateCurvedStatistics = (
statistics.push({
statistic_id: id,
start: currentDate.toISOString(),
end: currentDate.toISOString(),
mean: null,
min: null,
max: null,
@ -167,11 +189,38 @@ const generateCurvedStatistics = (
const statisticsFunctions: Record<
string,
(id: string, start: Date, end: Date) => StatisticValue[]
(
id: string,
start: Date,
end: Date,
period: "5minute" | "hour" | "day" | "month"
) => StatisticValue[]
> = {
"sensor.energy_consumption_tarif_1": (id: string, start: Date, end: Date) => {
"sensor.energy_consumption_tarif_1": (
id: string,
start: Date,
end: Date,
period = "hour"
) => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const morningEnd = new Date(start.getTime() + 10 * 60 * 60 * 1000);
const morningLow = generateSumStatistics(id, start, morningEnd, 0, 0.7);
const morningLow = generateSumStatistics(
id,
start,
morningEnd,
period,
0,
0.7
);
const eveningStart = new Date(start.getTime() + 20 * 60 * 60 * 1000);
const morningFinalVal = morningLow.length
? morningLow[morningLow.length - 1].sum!
@ -180,6 +229,7 @@ const statisticsFunctions: Record<
id,
morningEnd,
eveningStart,
period,
morningFinalVal,
0
);
@ -187,39 +237,71 @@ const statisticsFunctions: Record<
id,
eveningStart,
end,
period,
morningFinalVal,
0.7
);
return [...morningLow, ...empty, ...eveningLow];
},
"sensor.energy_consumption_tarif_2": (id: string, start: Date, end: Date) => {
"sensor.energy_consumption_tarif_2": (
id: string,
start: Date,
end: Date,
period = "hour"
) => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const morningEnd = new Date(start.getTime() + 9 * 60 * 60 * 1000);
const eveningStart = new Date(start.getTime() + 20 * 60 * 60 * 1000);
const highTarif = generateSumStatistics(
id,
morningEnd,
eveningStart,
period,
0,
0.3
);
const highTarifFinalVal = highTarif.length
? highTarif[highTarif.length - 1].sum!
: 0;
const morning = generateSumStatistics(id, start, morningEnd, 0, 0);
const morning = generateSumStatistics(id, start, morningEnd, period, 0, 0);
const evening = generateSumStatistics(
id,
eveningStart,
end,
period,
highTarifFinalVal,
0
);
return [...morning, ...highTarif, ...evening];
},
"sensor.energy_production_tarif_1": (id, start, end) =>
generateSumStatistics(id, start, end, 0, 0),
"sensor.energy_production_tarif_1_compensation": (id, start, end) =>
generateSumStatistics(id, start, end, 0, 0),
"sensor.energy_production_tarif_2": (id, start, end) => {
"sensor.energy_production_tarif_1": (id, start, end, period = "hour") =>
generateSumStatistics(id, start, end, period, 0, 0),
"sensor.energy_production_tarif_1_compensation": (
id,
start,
end,
period = "hour"
) => generateSumStatistics(id, start, end, period, 0, 0),
"sensor.energy_production_tarif_2": (id, start, end, period = "hour") => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const productionStart = new Date(start.getTime() + 9 * 60 * 60 * 1000);
const productionEnd = new Date(start.getTime() + 21 * 60 * 60 * 1000);
const dayEnd = new Date(endOfDay(productionEnd));
@ -227,6 +309,7 @@ const statisticsFunctions: Record<
id,
productionStart,
productionEnd,
period,
0,
0.15,
true
@ -234,18 +317,43 @@ const statisticsFunctions: Record<
const productionFinalVal = production.length
? production[production.length - 1].sum!
: 0;
const morning = generateSumStatistics(id, start, productionStart, 0, 0);
const morning = generateSumStatistics(
id,
start,
productionStart,
period,
0,
0
);
const evening = generateSumStatistics(
id,
productionEnd,
dayEnd,
period,
productionFinalVal,
0
);
const rest = generateSumStatistics(id, dayEnd, end, productionFinalVal, 1);
const rest = generateSumStatistics(
id,
dayEnd,
end,
period,
productionFinalVal,
1
);
return [...morning, ...production, ...evening, ...rest];
},
"sensor.solar_production": (id, start, end) => {
"sensor.solar_production": (id, start, end, period = "hour") => {
if (period !== "hour") {
return generateSumStatistics(
id,
start,
end,
period,
0,
period === "day" ? 17 : 504
);
}
const productionStart = new Date(start.getTime() + 7 * 60 * 60 * 1000);
const productionEnd = new Date(start.getTime() + 23 * 60 * 60 * 1000);
const dayEnd = new Date(endOfDay(productionEnd));
@ -253,6 +361,7 @@ const statisticsFunctions: Record<
id,
productionStart,
productionEnd,
period,
0,
0.3,
true
@ -260,19 +369,32 @@ const statisticsFunctions: Record<
const productionFinalVal = production.length
? production[production.length - 1].sum!
: 0;
const morning = generateSumStatistics(id, start, productionStart, 0, 0);
const morning = generateSumStatistics(
id,
start,
productionStart,
period,
0,
0
);
const evening = generateSumStatistics(
id,
productionEnd,
dayEnd,
period,
productionFinalVal,
0
);
const rest = generateSumStatistics(id, dayEnd, end, productionFinalVal, 2);
const rest = generateSumStatistics(
id,
dayEnd,
end,
period,
productionFinalVal,
2
);
return [...morning, ...production, ...evening, ...rest];
},
"sensor.grid_fossil_fuel_percentage": (id, start, end) =>
generateMeanStatistics(id, start, end, 35, 1.3),
};
export const mockHistory = (mockHass: MockHomeAssistant) => {
@ -347,7 +469,7 @@ export const mockHistory = (mockHass: MockHomeAssistant) => {
mockHass.mockWS("history/list_statistic_ids", () => []);
mockHass.mockWS(
"history/statistics_during_period",
({ statistic_ids, start_time, end_time }, hass) => {
({ statistic_ids, start_time, end_time, period }, hass) => {
const start = new Date(start_time);
const end = end_time ? new Date(end_time) : new Date();
@ -355,7 +477,7 @@ export const mockHistory = (mockHass: MockHomeAssistant) => {
statistic_ids.forEach((id: string) => {
if (id in statisticsFunctions) {
statistics[id] = statisticsFunctions[id](id, start, end);
statistics[id] = statisticsFunctions[id](id, start, end, period);
} else {
const entityState = hass.states[id];
const state = entityState ? Number(entityState.state) : 1;
@ -365,6 +487,7 @@ export const mockHistory = (mockHass: MockHomeAssistant) => {
id,
start,
end,
period,
state,
state * (state > 80 ? 0.01 : 0.05)
)
@ -372,6 +495,7 @@ export const mockHistory = (mockHass: MockHomeAssistant) => {
id,
start,
end,
period,
state,
state * (state > 80 ? 0.05 : 0.1)
);

View File

@ -1,5 +1,6 @@
import {
addHours,
differenceInDays,
endOfToday,
endOfYesterday,
startOfToday,
@ -191,6 +192,27 @@ export const saveEnergyPreferences = async (
return newPrefs;
};
export interface FossilEnergyConsumption {
[date: string]: number;
}
export const getFossilEnergyConsumption = async (
hass: HomeAssistant,
startTime: Date,
energy_statistic_ids: string[],
co2_statistic_id: string,
endTime?: Date,
period: "5minute" | "hour" | "day" | "month" = "hour"
) =>
hass.callWS<FossilEnergyConsumption>({
type: "energy/fossil_energy_consumption",
start_time: startTime.toISOString(),
end_time: endTime?.toISOString(),
energy_statistic_ids,
co2_statistic_id,
period,
});
interface EnergySourceByType {
grid?: GridSourceTypeEnergyPreference[];
solar?: SolarSourceTypeEnergyPreference[];
@ -209,6 +231,7 @@ export interface EnergyData {
stats: Statistics;
co2SignalConfigEntry?: ConfigEntry;
co2SignalEntity?: string;
fossilEnergyConsumption?: FossilEnergyConsumption;
}
const getEnergyData = async (
@ -246,12 +269,9 @@ const getEnergyData = async (
}
}
const consumptionStatIDs: string[] = [];
const statIDs: string[] = [];
if (co2SignalEntity !== undefined) {
statIDs.push(co2SignalEntity);
}
for (const source of prefs.energy_sources) {
if (source.type === "solar") {
statIDs.push(source.stat_energy_from);
@ -278,6 +298,7 @@ const getEnergyData = async (
// grid source
for (const flowFrom of source.flow_from) {
consumptionStatIDs.push(flowFrom.stat_energy_from);
statIDs.push(flowFrom.stat_energy_from);
if (flowFrom.stat_cost) {
statIDs.push(flowFrom.stat_cost);
@ -299,7 +320,44 @@ const getEnergyData = async (
}
}
const stats = await fetchStatistics(hass!, addHours(start, -1), end, statIDs); // Subtract 1 hour from start to get starting point data
const dayDifference = differenceInDays(end || new Date(), start);
// Subtract 1 hour from start to get starting point data
const startMinHour = addHours(start, -1);
const stats = await fetchStatistics(
hass!,
startMinHour,
end,
statIDs,
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
);
let fossilEnergyConsumption: FossilEnergyConsumption | undefined;
if (co2SignalEntity !== undefined) {
fossilEnergyConsumption = await getFossilEnergyConsumption(
hass!,
start,
consumptionStatIDs,
co2SignalEntity,
end,
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
);
}
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.toISOString(),
end: startMinHour.toISOString(),
sum: 0,
state: 0,
});
}
});
const data = {
start,
@ -309,6 +367,7 @@ const getEnergyData = async (
stats,
co2SignalConfigEntry,
co2SignalEntity,
fossilEnergyConsumption,
};
return data;

View File

@ -1,4 +1,3 @@
import { addDays, addMonths, startOfDay, startOfMonth } from "date-fns";
import { HassEntity } from "home-assistant-js-websocket";
import { computeStateDisplay } from "../common/entity/compute_state_display";
import { computeStateDomain } from "../common/entity/compute_state_domain";
@ -63,6 +62,7 @@ export interface Statistics {
export interface StatisticValue {
statistic_id: string;
start: string;
end: string;
last_reset: string | null;
max: number | null;
mean: number | null;
@ -350,7 +350,7 @@ export const fetchStatistics = (
startTime: Date,
endTime?: Date,
statistic_ids?: string[],
period: "hour" | "5minute" = "hour"
period: "5minute" | "hour" | "day" | "month" = "hour"
) =>
hass.callWS<Statistics>({
type: "history/statistics_during_period",
@ -428,151 +428,3 @@ export const statisticsHaveType = (
stats: StatisticValue[],
type: StatisticType
) => stats.some((stat) => stat[type] !== null);
// Merge the growth of multiple sum statistics into one
const mergeSumGrowthStatistics = (stats: StatisticValue[][]) => {
const result = {};
stats.forEach((stat) => {
if (stat.length === 0) {
return;
}
let prevSum: number | null = null;
stat.forEach((statVal) => {
if (statVal.sum === null) {
return;
}
if (prevSum === null) {
prevSum = statVal.sum;
return;
}
const growth = statVal.sum - prevSum;
if (statVal.start in result) {
result[statVal.start] += growth;
} else {
result[statVal.start] = growth;
}
prevSum = statVal.sum;
});
});
return result;
};
/**
* Get the growth of a statistic over the given period while applying a
* per-period percentage.
*/
export const calculateStatisticsSumGrowthWithPercentage = (
percentageStat: StatisticValue[],
sumStats: StatisticValue[][]
): number | null => {
let sum: number | null = null;
if (sumStats.length === 0 || percentageStat.length === 0) {
return null;
}
const sumGrowthToProcess = mergeSumGrowthStatistics(sumStats);
percentageStat.forEach((percentageStatValue) => {
const sumGrowth = sumGrowthToProcess[percentageStatValue.start];
if (sumGrowth === undefined) {
return;
}
if (sum === null) {
sum = sumGrowth * (percentageStatValue.mean! / 100);
} else {
sum += sumGrowth * (percentageStatValue.mean! / 100);
}
});
return sum;
};
export const reduceSumStatisticsByDay = (
values: StatisticValue[]
): StatisticValue[] => {
if (!values?.length) {
return [];
}
const result: StatisticValue[] = [];
if (
values.length > 1 &&
new Date(values[0].start).getDate() === new Date(values[1].start).getDate()
) {
// add init value if the first value isn't end of previous period
result.push({
...values[0]!,
start: startOfDay(addDays(new Date(values[0].start), -1)).toISOString(),
});
}
let lastValue: StatisticValue;
let prevDate: number | undefined;
for (const value of values) {
const date = new Date(value.start).getDate();
if (prevDate === undefined) {
prevDate = date;
}
if (prevDate !== date) {
// Last value of the day
result.push({
...lastValue!,
start: startOfDay(new Date(lastValue!.start)).toISOString(),
});
prevDate = date;
}
lastValue = value;
}
// Add final value
result.push({
...lastValue!,
start: startOfDay(new Date(lastValue!.start)).toISOString(),
});
return result;
};
export const reduceSumStatisticsByMonth = (
values: StatisticValue[]
): StatisticValue[] => {
if (!values?.length) {
return [];
}
const result: StatisticValue[] = [];
if (
values.length > 1 &&
new Date(values[0].start).getMonth() ===
new Date(values[1].start).getMonth()
) {
// add init value if the first value isn't end of previous period
result.push({
...values[0]!,
start: startOfMonth(
addMonths(new Date(values[0].start), -1)
).toISOString(),
});
}
let lastValue: StatisticValue;
let prevMonth: number | undefined;
for (const value of values) {
const month = new Date(value.start).getMonth();
if (prevMonth === undefined) {
prevMonth = month;
}
if (prevMonth !== month) {
// Last value of the month
result.push({
...lastValue!,
start: startOfMonth(new Date(lastValue!.start)).toISOString(),
});
prevMonth = month;
}
lastValue = value;
}
// Add final value
result.push({
...lastValue!,
start: startOfMonth(new Date(lastValue!.start)).toISOString(),
});
return result;
};

View File

@ -13,10 +13,7 @@ import {
energySourcesByType,
getEnergyDataCollection,
} from "../../../../data/energy";
import {
calculateStatisticsSumGrowth,
calculateStatisticsSumGrowthWithPercentage,
} from "../../../../data/history";
import { calculateStatisticsSumGrowth } from "../../../../data/history";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import type { HomeAssistant } from "../../../../types";
import { createEntityNotFoundWarning } from "../../components/hui-warning";
@ -90,19 +87,13 @@ class HuiEnergyCarbonGaugeCard
value = 100;
}
if (
this._data.co2SignalEntity in this._data.stats &&
totalGridConsumption
) {
const highCarbonEnergy =
calculateStatisticsSumGrowthWithPercentage(
this._data.stats[this._data.co2SignalEntity],
types
.grid![0].flow_from.map(
(flow) => this._data!.stats![flow.stat_energy_from]
)
.filter(Boolean)
) || 0;
if (this._data.fossilEnergyConsumption && totalGridConsumption) {
const highCarbonEnergy = this._data.fossilEnergyConsumption
? Object.values(this._data.fossilEnergyConsumption).reduce(
(sum, a) => sum + a,
0
)
: 0;
const totalSolarProduction = types.solar
? calculateStatisticsSumGrowth(

View File

@ -6,7 +6,7 @@ import {
ScatterDataPoint,
} from "chart.js";
import { getRelativePosition } from "chart.js/helpers";
import { addHours } from "date-fns";
import { addHours, differenceInDays } from "date-fns";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators";
@ -155,13 +155,19 @@ export class HuiEnergyDevicesGraphCard
);
private async _getStatistics(energyData: EnergyData): Promise<void> {
const dayDifference = differenceInDays(
energyData.end || new Date(),
energyData.start
);
this._data = await fetchStatistics(
this.hass,
addHours(energyData.start, -1),
energyData.end,
energyData.prefs.device_consumption.map(
(device) => device.stat_consumption
)
),
dayDifference > 35 ? "month" : dayDifference > 2 ? "day" : "hour"
);
const data: Array<ChartDataset<"bar", ParsedDataType<"bar">>["data"]> = [];

View File

@ -24,10 +24,7 @@ import {
getEnergyDataCollection,
getEnergyGasUnit,
} from "../../../../data/energy";
import {
calculateStatisticsSumGrowth,
calculateStatisticsSumGrowthWithPercentage,
} from "../../../../data/history";
import { calculateStatisticsSumGrowth } from "../../../../data/history";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";
import { LovelaceCard } from "../../types";
@ -209,19 +206,11 @@ class HuiEnergyDistrubutionCard
// This fallback is used in the demo
let electricityMapUrl = "https://www.electricitymap.org";
if (
this._data.co2SignalEntity &&
this._data.co2SignalEntity in this._data.stats
) {
if (this._data.co2SignalEntity && this._data.fossilEnergyConsumption) {
// Calculate high carbon consumption
const highCarbonEnergy = calculateStatisticsSumGrowthWithPercentage(
this._data.stats[this._data.co2SignalEntity],
types
.grid![0].flow_from.map(
(flow) => this._data!.stats[flow.stat_energy_from]
)
.filter(Boolean)
);
const highCarbonEnergy = Object.values(
this._data.fossilEnergyConsumption
).reduce((sum, a) => sum + a, 0);
const co2State = this.hass.states[this._data.co2SignalEntity];

View File

@ -41,10 +41,6 @@ import {
} from "../../../../common/number/format_number";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { FrontendLocaleData } from "../../../../data/translation";
import {
reduceSumStatisticsByMonth,
reduceSumStatisticsByDay,
} from "../../../../data/history";
import { formatTime } from "../../../../common/datetime/format_time";
@customElement("hui-energy-gas-graph-card")
@ -247,11 +243,6 @@ export class HuiEnergyGasGraphCard
.getPropertyValue("--energy-gas-color")
.trim();
const dayDifference = differenceInDays(
energyData.end || new Date(),
energyData.start
);
gasSources.forEach((source, idx) => {
const data: ChartDataset<"bar" | "line">[] = [];
const entity = this.hass.states[source.stat_energy_from];
@ -268,16 +259,7 @@ export class HuiEnergyGasGraphCard
// Process gas consumption data.
if (source.stat_energy_from in energyData.stats) {
const stats =
dayDifference > 35
? reduceSumStatisticsByMonth(
energyData.stats[source.stat_energy_from]
)
: dayDifference > 2
? reduceSumStatisticsByDay(
energyData.stats[source.stat_energy_from]
)
: energyData.stats[source.stat_energy_from];
const stats = energyData.stats[source.stat_energy_from];
for (const point of stats) {
if (point.sum === null) {

View File

@ -42,10 +42,6 @@ import {
} from "../../../../common/number/format_number";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { FrontendLocaleData } from "../../../../data/translation";
import {
reduceSumStatisticsByMonth,
reduceSumStatisticsByDay,
} from "../../../../data/history";
import { formatTime } from "../../../../common/datetime/format_time";
@customElement("hui-energy-solar-graph-card")
@ -274,16 +270,7 @@ export class HuiEnergySolarGraphCard
// Process solar production data.
if (source.stat_energy_from in energyData.stats) {
const stats =
dayDifference > 35
? reduceSumStatisticsByMonth(
energyData.stats[source.stat_energy_from]
)
: dayDifference > 2
? reduceSumStatisticsByDay(
energyData.stats[source.stat_energy_from]
)
: energyData.stats[source.stat_energy_from];
const stats = energyData.stats[source.stat_energy_from];
for (const point of stats) {
if (point.sum === null) {

View File

@ -27,10 +27,6 @@ import {
import "../../../../components/chart/ha-chart-base";
import "../../../../components/ha-card";
import { EnergyData, getEnergyDataCollection } from "../../../../data/energy";
import {
reduceSumStatisticsByDay,
reduceSumStatisticsByMonth,
} from "../../../../data/history";
import { FrontendLocaleData } from "../../../../data/translation";
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../../types";
@ -298,11 +294,6 @@ export class HuiEnergyUsageGraphCard
}
}
const dayDifference = differenceInDays(
energyData.end || new Date(),
energyData.start
);
this._start = energyData.start;
this._end = energyData.end || endOfToday();
@ -368,12 +359,7 @@ export class HuiEnergyUsageGraphCard
const totalStats: { [start: string]: number } = {};
const sets: { [statId: string]: { [start: string]: number } } = {};
statIds!.forEach((id) => {
const stats =
dayDifference > 35
? reduceSumStatisticsByMonth(energyData.stats[id])
: dayDifference > 2
? reduceSumStatisticsByDay(energyData.stats[id])
: energyData.stats[id];
const stats = energyData.stats[id];
if (!stats) {
return;
}

View File

@ -1,576 +0,0 @@
import { assert } from "chai";
import { calculateStatisticsSumGrowthWithPercentage } from "../../src/data/history";
describe("calculateStatisticsSumGrowthWithPercentage", () => {
it("Returns null if not enough values", async () => {
assert.strictEqual(
calculateStatisticsSumGrowthWithPercentage([], []),
null
);
});
it("Returns null if not enough sum stat values", async () => {
assert.strictEqual(
calculateStatisticsSumGrowthWithPercentage(
[
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: 75,
mean: 50,
min: 25,
sum: null,
state: null,
},
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: 100,
mean: 75,
min: 50,
sum: null,
state: null,
},
],
[]
),
null
);
});
it("Returns null if not enough percentage stat values", async () => {
assert.strictEqual(
calculateStatisticsSumGrowthWithPercentage(
[],
[
[
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T04:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 50,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 100,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 200,
state: null,
},
],
]
),
null
);
});
it("Returns a percentage of the growth", async () => {
assert.strictEqual(
calculateStatisticsSumGrowthWithPercentage(
[
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: 75,
mean: 50,
min: 25,
sum: null,
state: null,
},
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: 100,
mean: 75,
min: 50,
sum: null,
state: null,
},
],
[
[
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T04:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 50,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 100,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 200,
state: null,
},
],
[
{
statistic_id: "sensor.off_peak_consumption",
start: "2021-07-28T04:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 50,
state: null,
},
{
statistic_id: "sensor.off_peak_consumption",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 100,
state: null,
},
{
statistic_id: "sensor.off_peak_consumption",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 200,
state: null,
},
],
]
),
200
);
});
it("It ignores sum data that doesnt match start", async () => {
assert.strictEqual(
calculateStatisticsSumGrowthWithPercentage(
[
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: 75,
mean: 50,
min: 25,
sum: null,
state: null,
},
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: 100,
mean: 75,
min: 50,
sum: null,
state: null,
},
],
[
[
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T04:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 50,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T04:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 50,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 100,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 200,
state: null,
},
],
]
),
100
);
});
it("It ignores percentage data that doesnt match start", async () => {
assert.strictEqual(
calculateStatisticsSumGrowthWithPercentage(
[
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T04:00:00Z",
last_reset: null,
max: 25,
mean: 25,
min: 25,
sum: null,
state: null,
},
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: 75,
mean: 50,
min: 25,
sum: null,
state: null,
},
{
statistic_id: "sensor.carbon_intensity",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: 100,
mean: 75,
min: 50,
sum: null,
state: null,
},
],
[
[
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T04:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 50,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T05:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 100,
state: null,
},
{
statistic_id: "sensor.peak_consumption",
start: "2021-07-28T07:00:00Z",
last_reset: null,
max: null,
mean: null,
min: null,
sum: 200,
state: null,
},
],
]
),
100
);
});
it("Returns a percentage of the growth", async () => {
assert.strictEqual(
calculateStatisticsSumGrowthWithPercentage(
[
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T06:00:00.000Z",
mean: 10,
min: 10,
max: 10,
last_reset: "1970-01-01T00:00:00+00:00",
state: 10,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T07:00:00.000Z",
mean: 20,
min: 20,
max: 20,
last_reset: "1970-01-01T00:00:00+00:00",
state: 20,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T08:00:00.000Z",
mean: 30,
min: 30,
max: 30,
last_reset: "1970-01-01T00:00:00+00:00",
state: 30,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T09:00:00.000Z",
mean: 40,
min: 40,
max: 40,
last_reset: "1970-01-01T00:00:00+00:00",
state: 40,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T10:00:00.000Z",
mean: 50,
min: 50,
max: 50,
last_reset: "1970-01-01T00:00:00+00:00",
state: 50,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T11:00:00.000Z",
mean: 60,
min: 60,
max: 60,
last_reset: "1970-01-01T00:00:00+00:00",
state: 60,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T12:00:00.000Z",
mean: 70,
min: 70,
max: 70,
last_reset: "1970-01-01T00:00:00+00:00",
state: 70,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T13:00:00.000Z",
mean: 80,
min: 80,
max: 80,
last_reset: "1970-01-01T00:00:00+00:00",
state: 80,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T14:00:00.000Z",
mean: 90,
min: 90,
max: 90,
last_reset: "1970-01-01T00:00:00+00:00",
state: 90,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T15:00:00.000Z",
mean: 100,
min: 100,
max: 100,
last_reset: "1970-01-01T00:00:00+00:00",
state: 100,
sum: null,
},
{
statistic_id: "sensor.grid_fossil_fuel_percentage",
start: "2021-08-03T16:00:00.000Z",
mean: 110,
min: 110,
max: 110,
last_reset: "1970-01-01T00:00:00+00:00",
state: 120,
sum: null,
},
],
[
[
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T06:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 10,
sum: 10,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T07:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 20,
sum: 20,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T08:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 30,
sum: 30,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T09:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 40,
sum: 40,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T10:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 50,
sum: 50,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T11:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 60,
sum: 60,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T12:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 70,
sum: 70,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T13:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 80,
sum: 80,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T14:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 90,
sum: 90,
},
{
statistic_id: "sensor.energy_consumption_tarif_1",
start: "2021-08-03T15:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 100,
sum: 100,
},
],
[
{
statistic_id: "sensor.energy_consumption_tarif_2",
start: "2021-08-03T15:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 10,
sum: 10,
},
{
statistic_id: "sensor.energy_consumption_tarif_2",
start: "2021-08-03T16:00:00.000Z",
mean: null,
min: null,
max: null,
last_reset: "1970-01-01T00:00:00+00:00",
state: 20,
sum: 20,
},
],
]
),
65
);
});
});