fix: added energy-management

This commit is contained in:
Willem Serruys
2026-08-19 18:35:47 +02:00
parent fece1603e7
commit 53fa112aa8
38 changed files with 6060 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
import type { PowerSample, QuarterHourStatus } from "../types.js";
export const BLOCK_DURATION_MS = 15 * 60 * 1000;
export function blockStartFor(timestampMs: number): number {
return Math.floor(timestampMs / BLOCK_DURATION_MS) * BLOCK_DURATION_MS;
}
/**
* Computes the running and projected average power for the current 15-minute
* billing block, given a step-function reading of power samples (each sample
* holds until the next one arrives). Samples outside the current block are
* ignored; if the block has no samples yet, power is assumed to be 0 so far.
*/
export function computeQuarterHourStatus(
samples: PowerSample[],
nowMs: number,
targetW: number,
): QuarterHourStatus {
const blockStartMs = blockStartFor(nowMs);
const blockEndMs = blockStartMs + BLOCK_DURATION_MS;
const relevant = samples
.filter((s) => s.timestampMs >= blockStartMs && s.timestampMs <= nowMs)
.sort((a, b) => a.timestampMs - b.timestampMs);
let energyWms = 0;
let cursorMs = blockStartMs;
let cursorWatts = relevant.length > 0 ? relevant[0].watts : 0;
for (const sample of relevant) {
energyWms += cursorWatts * (sample.timestampMs - cursorMs);
cursorMs = sample.timestampMs;
cursorWatts = sample.watts;
}
energyWms += cursorWatts * (nowMs - cursorMs);
const elapsedMs = nowMs - blockStartMs;
const runningAverageW = elapsedMs > 0 ? energyWms / elapsedMs : 0;
const remainingMs = blockEndMs - nowMs;
const projectedEnergyWms = energyWms + cursorWatts * remainingMs;
const projectedAverageW = projectedEnergyWms / BLOCK_DURATION_MS;
return {
blockStartMs,
blockEndMs,
elapsedFractionOfBlock: elapsedMs / BLOCK_DURATION_MS,
runningAverageW,
projectedAverageW,
targetW,
overTarget: projectedAverageW > targetW,
};
}