mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-19 18:28:42 +00:00
New solar-consumed-gauge algorithm (#25326)
* New solar-consumed-gauge algorithm * update tests * Apply suggestion * reduce duplicate code
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
import {
|
||||
computeConsumptionSingle,
|
||||
formatConsumptionShort,
|
||||
calculateSolarConsumedGauge,
|
||||
} from "../../src/data/energy";
|
||||
import type { HomeAssistant } from "../../src/types";
|
||||
|
||||
@@ -506,3 +507,266 @@ describe("Energy Usage Calculation Tests", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Self-consumed solar gauge tests", () => {
|
||||
it("no battery", () => {
|
||||
const hasBattery = false;
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
total: {},
|
||||
timestamps: [0],
|
||||
}),
|
||||
undefined
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 0,
|
||||
},
|
||||
total: {
|
||||
solar: 0,
|
||||
},
|
||||
timestamps: [0],
|
||||
}),
|
||||
undefined
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 1,
|
||||
"1": 3,
|
||||
},
|
||||
total: {
|
||||
solar: 4,
|
||||
},
|
||||
timestamps: [0, 1],
|
||||
}),
|
||||
100
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 1,
|
||||
"1": 3,
|
||||
},
|
||||
to_grid: {
|
||||
"1": 1,
|
||||
},
|
||||
total: {
|
||||
solar: 4,
|
||||
to_grid: 1,
|
||||
},
|
||||
timestamps: [0, 1],
|
||||
}),
|
||||
75
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 1,
|
||||
"1": 3,
|
||||
},
|
||||
to_grid: {
|
||||
"0": 1,
|
||||
"1": 3,
|
||||
},
|
||||
total: {
|
||||
solar: 4,
|
||||
to_grid: 4,
|
||||
},
|
||||
timestamps: [0, 1],
|
||||
}),
|
||||
0
|
||||
);
|
||||
});
|
||||
it("with battery", () => {
|
||||
const hasBattery = true;
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
total: {},
|
||||
timestamps: [0],
|
||||
}),
|
||||
undefined
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 0,
|
||||
},
|
||||
total: {
|
||||
solar: 0,
|
||||
},
|
||||
timestamps: [0],
|
||||
}),
|
||||
undefined
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 1,
|
||||
"1": 3,
|
||||
},
|
||||
total: {
|
||||
solar: 4,
|
||||
},
|
||||
timestamps: [0, 1],
|
||||
}),
|
||||
100
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 1,
|
||||
"1": 3,
|
||||
},
|
||||
to_grid: {
|
||||
"1": 1,
|
||||
},
|
||||
total: {
|
||||
solar: 4,
|
||||
},
|
||||
timestamps: [0, 1],
|
||||
}),
|
||||
75
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"10": 1,
|
||||
},
|
||||
to_grid: {
|
||||
"0": 1,
|
||||
"1": 1,
|
||||
"2": 1,
|
||||
"3": 1,
|
||||
},
|
||||
from_battery: {
|
||||
"0": 1,
|
||||
"1": 1,
|
||||
"2": 1,
|
||||
"3": 1,
|
||||
},
|
||||
total: {
|
||||
solar: 1,
|
||||
},
|
||||
timestamps: [0, 1, 2, 3, 10],
|
||||
}),
|
||||
// As the battery is discharged from unknown source, it does not affect solar production number.
|
||||
100
|
||||
);
|
||||
assert.deepEqual(
|
||||
calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 10,
|
||||
},
|
||||
to_battery: {
|
||||
"0": 10,
|
||||
},
|
||||
to_grid: {
|
||||
"1": 3,
|
||||
"3": 1,
|
||||
},
|
||||
from_battery: {
|
||||
"1": 3,
|
||||
"2": 2,
|
||||
"3": 2,
|
||||
"4": 3,
|
||||
"5": 100, // Unknown source, not counted
|
||||
},
|
||||
total: {
|
||||
solar: 10,
|
||||
},
|
||||
timestamps: [0, 1, 2, 3, 4, 5],
|
||||
}),
|
||||
// As the battery is discharged from unknown source, it does not affect solar production number.
|
||||
60
|
||||
);
|
||||
});
|
||||
it("complex battery/solar/grid", () => {
|
||||
const hasBattery = true;
|
||||
|
||||
const value = calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"1": 6,
|
||||
"2": 0,
|
||||
"3": 7,
|
||||
},
|
||||
to_battery: {
|
||||
"1": 5,
|
||||
"2": 5,
|
||||
"3": 7,
|
||||
},
|
||||
to_grid: {
|
||||
"0": 5,
|
||||
"10": 1,
|
||||
"11": 1,
|
||||
"12": 5,
|
||||
"13": 3,
|
||||
},
|
||||
from_grid: {
|
||||
"2": 5,
|
||||
},
|
||||
from_battery: {
|
||||
"0": 5,
|
||||
"10": 3,
|
||||
"11": 4,
|
||||
"12": 5,
|
||||
"13": 5,
|
||||
},
|
||||
total: {
|
||||
// Total is mostly don't care when hasBattery, only hourly values are used
|
||||
solar: 13,
|
||||
},
|
||||
timestamps: [0, 1, 2, 3, 10, 11, 12, 13],
|
||||
});
|
||||
// "1" - consumed 1 solar, 5 sent to battery
|
||||
// "10" - consumed 2/3 of solar energy stored in battery
|
||||
// "11" - consumed 3/4 of solar energy stored in battery
|
||||
// "12" - skipped as this is energy from grid, not counted
|
||||
// "13" - consumed 2/5 of solar energy stored in battery
|
||||
const expectedNumerator = 1 + 2 + 3 + 0 + 2; // 8
|
||||
const expectedDenominator = 1 + 3 + 4 + 0 + 5; // 13
|
||||
assert.equal(
|
||||
Math.round(value!),
|
||||
Math.round((expectedNumerator / expectedDenominator) * 100)
|
||||
);
|
||||
});
|
||||
|
||||
it("complex battery/solar/grid #2", () => {
|
||||
const hasBattery = true;
|
||||
const value = calculateSolarConsumedGauge(hasBattery, {
|
||||
solar: {
|
||||
"0": 100,
|
||||
"2": 100,
|
||||
},
|
||||
to_battery: {
|
||||
"0": 100,
|
||||
"1": 100,
|
||||
"2": 100,
|
||||
},
|
||||
to_grid: {
|
||||
"10": 50,
|
||||
},
|
||||
from_grid: {
|
||||
"1": 100,
|
||||
},
|
||||
from_battery: {
|
||||
"10": 300,
|
||||
},
|
||||
total: {
|
||||
solar: 200,
|
||||
to_battery: 300,
|
||||
to_grid: 50,
|
||||
from_grid: 100,
|
||||
from_battery: 300,
|
||||
},
|
||||
timestamps: [0, 1, 2, 10],
|
||||
});
|
||||
const expectedNumerator = 200 - 50;
|
||||
const expectedDenominator = 200; // ignoring 100 from grid
|
||||
assert.equal(
|
||||
Math.round(value!),
|
||||
Math.round((expectedNumerator / expectedDenominator) * 100)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user