1
0
mirror of https://github.com/home-assistant/frontend.git synced 2025-12-19 18:28:42 +00:00

New energy calculation formula (#25242)

* New energy calculation

* more tests and stricter tests. change priority order
This commit is contained in:
karwosts
2025-04-30 09:47:51 -07:00
committed by GitHub
parent 221bc732fb
commit f8d706277d
2 changed files with 234 additions and 105 deletions

View File

@@ -14,6 +14,47 @@ import {
} from "../../src/data/energy";
import type { HomeAssistant } from "../../src/types";
const checkConsumptionResult = (
input: {
from_grid: number | undefined;
to_grid: number | undefined;
solar: number | undefined;
to_battery: number | undefined;
from_battery: number | undefined;
},
exact = true
): {
grid_to_battery: number;
battery_to_grid: number;
solar_to_battery: number;
solar_to_grid: number;
used_solar: number;
used_grid: number;
used_battery: number;
used_total: number;
} => {
const result = computeConsumptionSingle(input);
if (exact) {
assert.equal(
result.used_total,
result.used_solar + result.used_battery + result.used_grid
);
assert.equal(
input.to_grid || 0,
result.solar_to_grid + result.battery_to_grid
);
assert.equal(
input.to_battery || 0,
result.grid_to_battery + result.solar_to_battery
);
assert.equal(
input.solar || 0,
result.solar_to_battery + result.solar_to_grid + result.used_solar
);
}
return result;
};
describe("Energy Short Format Test", () => {
// Create default to not have to specify a not relevant TimeFormat over and over again.
const defaultLocale: FrontendLocaleData = {
@@ -88,7 +129,7 @@ describe("Energy Usage Calculation Tests", () => {
it("Consuming Energy From the Grid", () => {
[0, 5, 1000].forEach((x) => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: x,
to_grid: undefined,
solar: undefined,
@@ -101,6 +142,7 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 0,
used_grid: x,
used_battery: 0,
used_total: x,
solar_to_battery: 0,
solar_to_grid: 0,
}
@@ -108,61 +150,78 @@ describe("Energy Usage Calculation Tests", () => {
});
});
it("Solar production, consuming some and returning the remainder to grid.", () => {
[2.99, 3, 10, 100].forEach((s) => {
(
[
[2.99, false], // unsolveable : solar < to_grid
[3, true],
[10, true],
[100, true],
] as any
).forEach(([s, exact]) => {
assert.deepEqual(
computeConsumptionSingle({
from_grid: 0,
to_grid: 3,
solar: s,
to_battery: undefined,
from_battery: undefined,
}),
checkConsumptionResult(
{
from_grid: 0,
to_grid: 3,
solar: s,
to_battery: undefined,
from_battery: undefined,
},
exact
),
{
grid_to_battery: 0,
battery_to_grid: 0,
used_solar: Math.max(0, s - 3),
used_solar: Math.min(s, Math.max(0, s - 3)),
used_grid: 0,
used_battery: 0,
used_total: s - 3,
solar_to_battery: 0,
solar_to_grid: 3,
solar_to_grid: Math.min(3, s),
}
);
});
});
it("Solar production with simultaneous grid consumption. Excess solar returned to the grid.", () => {
[
[0, 0],
[3, 0],
[0, 3],
[5, 4],
[4, 5],
[10, 3],
[3, 7],
[3, 7.1],
].forEach(([from_grid, to_grid]) => {
(
[
[0, 0, true],
[3, 0, true],
[0, 3, true],
[5, 4, true],
[4, 5, true],
[10, 3, true],
[3, 7, true],
[3, 7.1, false], // unsolveable: to_grid > solar
] as any
).forEach(([from_grid, to_grid, exact]) => {
assert.deepEqual(
computeConsumptionSingle({
from_grid,
to_grid,
solar: 7,
to_battery: undefined,
from_battery: undefined,
}),
checkConsumptionResult(
{
from_grid,
to_grid,
solar: 7,
to_battery: undefined,
from_battery: undefined,
},
exact
),
{
grid_to_battery: 0,
battery_to_grid: 0,
used_solar: Math.max(0, 7 - to_grid),
used_grid: from_grid,
used_grid: from_grid - Math.max(0, to_grid - 7),
used_total: from_grid - to_grid + 7,
used_battery: 0,
solar_to_battery: 0,
solar_to_grid: to_grid,
solar_to_grid: Math.min(7, to_grid),
}
);
});
});
it("Charging the battery from the grid", () => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 0,
solar: 0,
@@ -175,6 +234,7 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 0,
used_grid: 2,
used_battery: 0,
used_total: 2,
solar_to_battery: 0,
solar_to_grid: 0,
}
@@ -182,7 +242,7 @@ describe("Energy Usage Calculation Tests", () => {
});
it("Consuming from the grid and battery simultaneously", () => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 0,
solar: 0,
@@ -195,6 +255,7 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 0,
used_grid: 5,
used_battery: 5,
used_total: 10,
solar_to_battery: 0,
solar_to_grid: 0,
}
@@ -202,7 +263,7 @@ describe("Energy Usage Calculation Tests", () => {
});
it("Consuming some battery and returning some battery to the grid", () => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 0,
to_grid: 4,
solar: 0,
@@ -215,15 +276,15 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 0,
used_grid: 0,
used_battery: 1,
used_total: 1,
solar_to_battery: 0,
solar_to_grid: 0,
}
);
});
/* Fails
it("Charging and discharging the battery to/from the grid in the same interval.", () => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 1,
solar: 0,
@@ -234,15 +295,18 @@ describe("Energy Usage Calculation Tests", () => {
grid_to_battery: 3,
battery_to_grid: 1,
used_solar: 0,
used_grid: 1,
used_grid: 2,
used_battery: 0,
used_total: 2,
solar_to_battery: 0,
solar_to_grid: 0,
}
);
}); */
/* Test does not pass, battery is not really correct when solar is not present
});
it("Charging the battery with no solar sensor.", () => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 0,
solar: undefined,
@@ -255,13 +319,15 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 0,
used_grid: 2,
used_battery: 0,
used_total: 2,
solar_to_battery: 0,
solar_to_grid: 0,
}
);
}); */
/* Test does not pass
});
it("Discharging battery to grid while also consuming from grid.", () => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 4,
solar: 0,
@@ -274,14 +340,16 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 0,
used_grid: 5,
used_battery: 0,
used_total: 5,
solar_to_grid: 0,
solar_to_battery: 0,
}
);
});
*/
it("Grid, solar, and battery", () => {
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 3,
solar: 7,
@@ -294,12 +362,13 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 1,
used_grid: 5,
used_battery: 0,
used_total: 6,
solar_to_battery: 3,
solar_to_grid: 3,
}
);
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 3,
solar: 7,
@@ -308,16 +377,17 @@ describe("Energy Usage Calculation Tests", () => {
}),
{
grid_to_battery: 0,
battery_to_grid: 0,
used_solar: 1,
battery_to_grid: 3,
used_solar: 4,
used_grid: 5,
used_battery: 10,
used_battery: 7,
used_total: 16,
solar_to_battery: 3,
solar_to_grid: 3,
solar_to_grid: 0,
}
);
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 2,
to_grid: 7,
solar: 7,
@@ -325,17 +395,18 @@ describe("Energy Usage Calculation Tests", () => {
from_battery: 1,
}),
{
grid_to_battery: 1,
battery_to_grid: 0,
grid_to_battery: 0,
battery_to_grid: 1,
used_solar: 0,
used_grid: 1,
used_battery: 1,
solar_to_battery: 0,
solar_to_grid: 7,
used_grid: 2,
used_battery: 0,
used_total: 2,
solar_to_battery: 1,
solar_to_grid: 6,
}
);
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 2,
to_grid: 7,
solar: 9,
@@ -344,17 +415,17 @@ describe("Energy Usage Calculation Tests", () => {
}),
{
grid_to_battery: 0,
battery_to_grid: 0,
used_solar: 1,
battery_to_grid: 1,
used_solar: 2,
used_grid: 2,
used_battery: 1,
used_battery: 0,
used_total: 4,
solar_to_battery: 1,
solar_to_grid: 7,
solar_to_grid: 6,
}
);
/* Test does not pass
assert.deepEqual(
computeConsumptionSingle({
checkConsumptionResult({
from_grid: 5,
to_grid: 3,
solar: 1,
@@ -367,8 +438,48 @@ describe("Energy Usage Calculation Tests", () => {
used_solar: 0,
used_grid: 5,
used_battery: 0,
used_total: 5,
solar_to_battery: 0,
solar_to_grid: 1,
}
);
assert.deepEqual(
checkConsumptionResult({
from_grid: 6,
to_grid: 0,
solar: 3,
to_battery: 6,
from_battery: 6,
}),
{
grid_to_battery: 3,
battery_to_grid: 0,
used_solar: 0,
used_grid: 3,
used_battery: 6,
solar_to_battery: 3,
solar_to_grid: 0,
used_total: 9,
}
);
assert.deepEqual(
checkConsumptionResult({
from_grid: 0,
to_grid: 1,
solar: 1,
to_battery: 1,
from_battery: 1,
}),
{
grid_to_battery: 0,
battery_to_grid: 1,
used_solar: 0,
used_grid: 0,
used_battery: 0,
solar_to_battery: 1,
solar_to_grid: 0,
used_total: 0,
}
);
*/
});
});