forked from jappel/leistungsbilanz-ts
89 lines
3.5 KiB
TypeScript
89 lines
3.5 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import { calculateDistributionBoardLoads } from "../src/domain/calculations/distribution-board-load-calculation.js";
|
|
|
|
const board = (
|
|
id: string,
|
|
simultaneityFactor: number,
|
|
feedingDistributionBoardId: string | null = null,
|
|
feedingCircuitId: string | null = null
|
|
) => ({
|
|
id,
|
|
name: id,
|
|
boardNumber: id.toUpperCase(),
|
|
simultaneityFactor,
|
|
feedingDistributionBoardId,
|
|
feedingCircuitId,
|
|
});
|
|
|
|
describe("distribution-board load calculation", () => {
|
|
it("rolls recursive demand into the selected feeder circuit exactly once", () => {
|
|
const result = calculateDistributionBoardLoads({
|
|
boards: [
|
|
board("nshv", 0.8),
|
|
board("uv1", 0.5, "nshv", "nshv-out"),
|
|
board("uv2", 0.25, "uv1", "uv1-out"),
|
|
],
|
|
circuits: [
|
|
{ id: "nshv-out", distributionBoardId: "nshv", rows: [{ activePowerKw: 2, cosPhi: 1 }] },
|
|
{ id: "uv1-out", distributionBoardId: "uv1", rows: [{ activePowerKw: 4, cosPhi: 0.8 }] },
|
|
{ id: "uv2-load", distributionBoardId: "uv2", rows: [{ activePowerKw: 8, cosPhi: 0.8 }] },
|
|
],
|
|
});
|
|
|
|
assert.deepEqual(result.boards.get("uv2"), {
|
|
distributionBoardId: "uv2",
|
|
activePowerBeforeSimultaneityKw: 8,
|
|
apparentPowerBeforeSimultaneityKva: 10,
|
|
demandActivePowerKw: 2,
|
|
demandApparentPowerKva: 2.5,
|
|
cosPhi: 0.8,
|
|
});
|
|
assert.equal(result.circuits.get("uv1-out")?.activePowerKw, 6);
|
|
assert.equal(result.boards.get("uv1")?.demandActivePowerKw, 3);
|
|
assert.equal(result.circuits.get("nshv-out")?.activePowerKw, 5);
|
|
assert.equal(result.boards.get("nshv")?.demandActivePowerKw, 4);
|
|
assert.equal(result.circuits.get("nshv-out")?.downstreamBoards.length, 1);
|
|
});
|
|
|
|
it("combines apparent power for multiple child boards on one circuit", () => {
|
|
const result = calculateDistributionBoardLoads({
|
|
boards: [board("main", 1), board("a", 1, "main", "out"), board("b", 1, "main", "out")],
|
|
circuits: [
|
|
{ id: "out", distributionBoardId: "main", rows: [] },
|
|
{ id: "a-load", distributionBoardId: "a", rows: [{ activePowerKw: 2, cosPhi: 0.5 }] },
|
|
{ id: "b-load", distributionBoardId: "b", rows: [{ activePowerKw: 2, cosPhi: 1 }] },
|
|
],
|
|
});
|
|
const feeder = result.circuits.get("out")!;
|
|
assert.equal(feeder.activePowerKw, 4);
|
|
assert.equal(feeder.apparentPowerKva, 6);
|
|
assert.equal(feeder.cosPhi, 2 / 3);
|
|
assert.deepEqual(feeder.downstreamBoards.map((entry) => entry.distributionBoardId), ["a", "b"]);
|
|
});
|
|
|
|
it("keeps a board-only hierarchy relation out of load rollup", () => {
|
|
const result = calculateDistributionBoardLoads({
|
|
boards: [board("main", 1), board("child", 1, "main", null)],
|
|
circuits: [
|
|
{ id: "main-load", distributionBoardId: "main", rows: [{ activePowerKw: 1, cosPhi: 1 }] },
|
|
{ id: "child-load", distributionBoardId: "child", rows: [{ activePowerKw: 5, cosPhi: 1 }] },
|
|
],
|
|
});
|
|
assert.equal(result.boards.get("main")?.demandActivePowerKw, 1);
|
|
assert.equal(result.boards.get("child")?.demandActivePowerKw, 5);
|
|
});
|
|
|
|
it("rejects cycles defensively", () => {
|
|
assert.throws(
|
|
() => calculateDistributionBoardLoads({
|
|
boards: [board("a", 1, "b", "b-out"), board("b", 1, "a", "a-out")],
|
|
circuits: [
|
|
{ id: "a-out", distributionBoardId: "a", rows: [] },
|
|
{ id: "b-out", distributionBoardId: "b", rows: [] },
|
|
],
|
|
}),
|
|
/cycle/
|
|
);
|
|
});
|
|
});
|