feat(setDemand): surface specificClass.setDemand(value, unit='%') + slim npm pack
Why: - pumpingStation level-based control was calling MGC.handleInput(percent) directly. handleInput expects canonical m³/s; a 1 % keep-alive arrived as 1 m³/s ≈ 3600 m³/h, the dispatcher clamped to dt.flow.max and the group ran at 100 %. The unit math already existed inside the set.demand command handler — but only that handler could reach it. What: - New public method `async setDemand(value, unit='%')` on MachineGroup (specificClass.js). Resolves the unit (`%` → interpolate against the dynamic-totals envelope, absolute units → convert(value)) and calls handleInput with canonical m³/s. Negative value remains the operator stop-all signal. Single source of truth for the percent → m³/s rule. - Refactor handlers.setDemand to parse the payload + apply mode gating and then delegate to source.setDemand. Drops the local `convert` import (now reached via the source). - Update commands.basic.test.js mock with a setDemand shim that mirrors the real method, so existing handleInput assertions still hold. Packaging: - Add .npmignore mirroring .gitignore plus dev-only trees (test/, wiki/, CLAUDE.md, …) so the published tarball stays small. - Extend .gitignore with the standard dev-artifact deny list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -65,9 +65,25 @@ function makeSource({
|
||||
if (handleInputResult instanceof Error) throw handleInputResult;
|
||||
return handleInputResult;
|
||||
},
|
||||
// Used by set.demand handler when unit is %: needs dt.flow + interpolation.
|
||||
// With min=0, max=100, the linear interpolation is identity so a bare
|
||||
// numeric demand round-trips through handleInput unchanged.
|
||||
// Mirror of the real specificClass.setDemand: resolves unit -> canonical
|
||||
// m³/s and forwards to handleInput. With dt.flow {min:0,max:100} the %
|
||||
// interpolation is identity, so a bare numeric demand round-trips through
|
||||
// handleInput unchanged — keeping the existing assertions stable.
|
||||
setDemand: async (value, unit = '%') => {
|
||||
const v = Number(value);
|
||||
if (!Number.isFinite(v)) return undefined;
|
||||
if (v < 0) { await source.turnOffAllMachines(); return undefined; }
|
||||
let canonical;
|
||||
if (unit === '%') {
|
||||
canonical = source.interpolation.interpolate_lin_single_point(
|
||||
v, 0, 100, dt.flow.min, dt.flow.max);
|
||||
} else {
|
||||
const { convert } = require('generalFunctions');
|
||||
canonical = convert(v).from(unit).to('m3/s');
|
||||
}
|
||||
return source.handleInput('parent', canonical);
|
||||
},
|
||||
// Retained for completeness — the mock setDemand uses these internally.
|
||||
calcDynamicTotals: () => dt,
|
||||
interpolation: {
|
||||
interpolate_lin_single_point: (x, ix, iy, ox, oy) => {
|
||||
|
||||
Reference in New Issue
Block a user