async function run() { // No-op: manual mode is event-driven via set.demand → forwardDemand, // not tick-driven. } async function forwardDemand(ctx, demand) { const { machineGroups, machines, unitPolicy, logger } = ctx; logger?.info?.(`Manual demand forwarded: ${demand}`); if (machineGroups && Object.keys(machineGroups).length > 0) { const groupDemand = unitPolicy.convert(demand, 'm3/h', 'm3/s', 'manual demand to machineGroups'); await Promise.all( Object.values(machineGroups).map((group) => group.handleInput('parent', groupDemand).catch((err) => { logger?.error?.(`Failed to forward demand to group: ${err.message}`); }) ) ); } if (machines && Object.keys(machines).length > 0) { const perMachine = demand / Object.keys(machines).length; for (const machine of Object.values(machines)) { try { await machine.handleInput('parent', 'execMovement', perMachine); } catch (err) { logger?.error?.(`Failed to forward demand to machine: ${err.message}`); } } } // Neither a group nor a direct machine is registered, so the operator's // demand silently goes nowhere. Surface it — the usual cause is a dropped // Port 2 parent↔child registration after a partial redeploy. const noGroups = !machineGroups || Object.keys(machineGroups).length === 0; const noMachines = !machines || Object.keys(machines).length === 0; if (noGroups && noMachines) { logger?.warn?.( `Manual demand ${demand} not forwarded — no machine group or machine is registered to this pumping station. ` + `Check the parent↔child Port 2 registration (redeploy/restart fully to restore it).` ); } } module.exports = { name: 'manual', run, forwardDemand, };