Deterministic TypeScript engine for sizing and evaluating portable power stations from configured device loads.
It models energy demand, continuous output, startup surge, runtime and technical compatibility as separate constraints. Extracted from the sizing engine behind PowerStationSelect.
- Calculates daily energy demand from estimated use or annual energy labels.
- Sizes capacity for a requested autonomy period.
- Separately calculates simultaneous running power and startup surge.
- Estimates runtime after conversion efficiency.
- Evaluates a station or validated modular system against those constraints.
- Builds modular systems only from explicit expansion rules.
The package is deterministic, offline and has no runtime dependencies.
Energy answers how long a load must be supplied; power answers whether it can be supplied at a moment in time. A duty cycle therefore changes estimated energy consumption, but does not reduce the simultaneous nominal wattage required from the output.
For estimated loads:
deviceDailyWh = watts × hours × quantity × dutyCycle
dailyWh = Σ deviceDailyWh
When energyMode is "annual", the annual label takes priority:
deviceDailyWh = max(annualKWh, 0) × 1000 / 365 × quantity
The extracted engine uses a 0.85 efficiency factor:
targetEnergyWh = dailyEnergyWh × autonomyDays
technicalMinimumWh = targetEnergyWh / 0.85
The recommended capacity applies the engine's 1.12 safety margin and rounds upward in 100 Wh increments. The API also exposes the unrounded recommended range and high-autonomy capacity.
Continuous output is independent of energy:
runningPowerW = Σ(watts × quantity)
recommendedContinuousOutputW = runningPowerW × 1.2
The canonical surge policy adds the largest same-group startup extra to simultaneous running power, rather than summing startup extras from unrelated device groups:
groupSurgeExtraW = watts × quantity × max(surgeMultiplier - 1, 0)
startEventW = runningPowerW + max(groupSurgeExtraW)
requiredSurgeW = max(recommendedContinuousOutputW, startEventW)
If a separate surge requirement exists and a station has no verified surge specification, compatibility returns surgeStatus: "unknown". Unknown is not treated as zero and does not pass technical compatibility.
usableCapacityWh = nominalCapacityWh × 0.85
runtimeHours = usableCapacityWh / dailyEnergyWh × 24
evaluateCompatibility returns individual results for continuous output, surge, target runtime and scenario fit.
technicallyCompatible requires continuous power, applicable surge validation and target runtime. fitsRecommendedScenario is deliberately separate: it checks whether nominal capacity reaches the selected planning target, not whether the system can physically operate the load.
buildValidatedSystem is the sole constructor for standalone and expanded configurations. It accepts only declared battery relationships and quantities, checks a declared maximum total capacity, and produces canonical ids such as station~battery~2.
Expansion batteries increase capacity. Output characteristics remain those of the base station unless an explicit expansion rule provides an override.
import {
buildValidatedSystem,
calculateRequirements,
evaluateCompatibility,
} from "powerstation-engine-core";
const requirements = calculateRequirements([
{ watts: 65, hours: 6, quantity: 1, dutyCycle: 0.8, surgeMultiplier: 1 },
{ watts: 700, hours: 1, quantity: 1, dutyCycle: 0.6, surgeMultiplier: 2.5 },
]);
const result = buildValidatedSystem(
{ stationId: "demo-station" },
{
stations: [
{ id: "demo-station", capacityWh: 1800, continuousOutputW: 1200, surgeOutputW: 2400 },
],
batteries: [],
},
);
if (result.ok) {
console.log(
evaluateCompatibility(result.system, {
dailyEnergyWh: requirements.totalEnergyWh,
targetCapacityWh: requirements.recommendedCapacityWh,
requiredContinuousOutputW: requirements.recommendedContinuousOutputW,
requiredSurgeOutputW: requirements.requiredSurgeOutputW,
autonomyDays: 1,
}),
);
}Run the included example with npm run example.
npm run typecheck
npm test
npm run buildTests cover energy, annual-label handling, continuous power, surge, runtime, compatibility, malformed modular ids, invalid quantities and maximum-capacity rules.
This repository contains the technical sizing and compatibility core only. It intentionally excludes application UI, product catalog data, product links, offers, ranking and purchase-oriented logic. The fixtures are generic demonstration data, not a commercial catalog.
This project is a small, standalone extraction of the sizing engine behind PowerStationSelect. It makes the model and its tested technical decisions inspectable without the surrounding application.