86 lines
2.6 KiB
JavaScript
86 lines
2.6 KiB
JavaScript
|
|
/**
|
||
|
|
* Dispatches inbound control actions (execSequence / execMovement /
|
||
|
|
* flowMovement / emergencyStop / enter|exitMaintenance / statusCheck)
|
||
|
|
* to the state machine and motion helpers on the host.
|
||
|
|
*
|
||
|
|
* Behaviour mirrors the original specificClass.handleInput exactly:
|
||
|
|
* - actions are lower-cased
|
||
|
|
* - mode/source gating runs first
|
||
|
|
* - flow-setpoints are unit-converted (output -> canonical) before
|
||
|
|
* calcCtrl + setpoint
|
||
|
|
* - thrown errors are caught + logged (no re-throw) so a misbehaving
|
||
|
|
* parent never crashes the FSM
|
||
|
|
*/
|
||
|
|
|
||
|
|
class FlowController {
|
||
|
|
constructor(ctx) {
|
||
|
|
if (!ctx || !ctx.host) {
|
||
|
|
throw new Error('FlowController: ctx.host is required');
|
||
|
|
}
|
||
|
|
this.host = ctx.host;
|
||
|
|
this.logger = ctx.logger || ctx.host.logger;
|
||
|
|
}
|
||
|
|
|
||
|
|
async handle(source, action, parameter) {
|
||
|
|
const host = this.host;
|
||
|
|
|
||
|
|
if (typeof action !== 'string') {
|
||
|
|
this.logger.error('Action must be string');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
action = action.toLowerCase();
|
||
|
|
|
||
|
|
if (!host.isValidActionForMode(action, host.currentMode)) return;
|
||
|
|
if (!host.isValidSourceForMode(source, host.currentMode)) return;
|
||
|
|
|
||
|
|
this.logger.info(
|
||
|
|
`Handling input from source '${source}' with action '${action}' in mode '${host.currentMode}'.`,
|
||
|
|
);
|
||
|
|
|
||
|
|
try {
|
||
|
|
switch (action) {
|
||
|
|
case 'execsequence':
|
||
|
|
return await host.executeSequence(parameter);
|
||
|
|
|
||
|
|
case 'execmovement':
|
||
|
|
return await host.setpoint(parameter);
|
||
|
|
|
||
|
|
case 'entermaintenance':
|
||
|
|
case 'exitmaintenance':
|
||
|
|
return await host.executeSequence(parameter);
|
||
|
|
|
||
|
|
case 'flowmovement': {
|
||
|
|
const canonicalFlowSetpoint = host._convertUnitValue(
|
||
|
|
parameter,
|
||
|
|
host.unitPolicy.output.flow,
|
||
|
|
host.unitPolicy.canonical.flow,
|
||
|
|
'flowmovement setpoint',
|
||
|
|
);
|
||
|
|
const pos = host.calcCtrl(canonicalFlowSetpoint);
|
||
|
|
return await host.setpoint(pos);
|
||
|
|
}
|
||
|
|
|
||
|
|
case 'emergencystop':
|
||
|
|
this.logger.warn(`Emergency stop activated by '${source}'.`);
|
||
|
|
return await host.executeSequence('emergencystop');
|
||
|
|
|
||
|
|
case 'statuscheck':
|
||
|
|
this.logger.info(
|
||
|
|
`Status Check: Mode = '${host.currentMode}', Source = '${source}'.`,
|
||
|
|
);
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
this.logger.warn(`Action '${action}' is not implemented.`);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
this.logger.debug(`Action '${action}' successfully executed`);
|
||
|
|
return { status: true, feedback: `Action '${action}' successfully executed.` };
|
||
|
|
} catch (error) {
|
||
|
|
this.logger.error(`Error handling input: ${error}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
module.exports = FlowController;
|