Complete general functions
This commit is contained in:
131
helper/state/state.js
Normal file
131
helper/state/state.js
Normal file
@@ -0,0 +1,131 @@
|
||||
//load local dependencies
|
||||
const EventEmitter = require('events');
|
||||
const StateManager = require('./stateManager');
|
||||
const MovementManager = require('./movementManager');
|
||||
|
||||
//load all config modules
|
||||
const defaultConfig = require('./stateConfig.json');
|
||||
const ConfigUtils = require('../../../generalFunctions/helper/configUtils');
|
||||
|
||||
class state{
|
||||
constructor(config = {}, logger) {
|
||||
|
||||
this.emitter = new EventEmitter(); // Own EventEmitter
|
||||
this.configUtils = new ConfigUtils(defaultConfig);
|
||||
this.config = this.configUtils.initConfig(config);
|
||||
this.abortController = null; // new abort controller for aborting async tasks
|
||||
// Init after config is set
|
||||
this.logger = logger;
|
||||
|
||||
// Initialize StateManager for state handling
|
||||
this.stateManager = new StateManager(this.config,this.logger);
|
||||
this.movementManager = new MovementManager(this.config, this.logger, this.emitter);
|
||||
|
||||
this.delayedMove = null;
|
||||
this.mode = this.config.mode.current;
|
||||
|
||||
// Log initialization
|
||||
this.logger.info("State class initialized.");
|
||||
|
||||
}
|
||||
|
||||
// -------- Delegate State Management -------- //
|
||||
|
||||
getMoveTimeLeft() {
|
||||
return this.movementManager.timeleft;
|
||||
}
|
||||
|
||||
getCurrentState() {
|
||||
return this.stateManager.currentState;
|
||||
}
|
||||
|
||||
getStateDescription() {
|
||||
return this.stateManager.getStateDescription();
|
||||
}
|
||||
|
||||
// -------- Movement Methods -------- //
|
||||
getCurrentPosition() {
|
||||
return this.movementManager.getCurrentPosition();
|
||||
}
|
||||
|
||||
getRunTimeHours() {
|
||||
return this.stateManager.getRunTimeHours();
|
||||
}
|
||||
|
||||
async moveTo(targetPosition) {
|
||||
|
||||
// Check for invalid conditions and throw errors
|
||||
if (targetPosition === this.getCurrentPosition()) {
|
||||
this.logger.warn(`Target position=${targetPosition} is the same as the current position ${this.getCurrentPosition()}. Not executing move.`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.stateManager.getCurrentState() !== "operational") {
|
||||
if (this.config.mode.current === "auto") {
|
||||
this.delayedMove = targetPosition;
|
||||
this.logger.warn(`Saving setpoint=${targetPosition} to execute once back in 'operational' state.`);
|
||||
}
|
||||
else{
|
||||
this.logger.warn(`Not able to accept setpoint=${targetPosition} while not in ${this.stateManager.getCurrentState()} state`);
|
||||
}
|
||||
//return early
|
||||
return;
|
||||
}
|
||||
this.abortController = new AbortController();
|
||||
const { signal } = this.abortController;
|
||||
try {
|
||||
const newState = targetPosition < this.getCurrentPosition() ? "decelerating" : "accelerating";
|
||||
await this.transitionToState(newState,signal); // awaits transition
|
||||
await this.movementManager.moveTo(targetPosition,signal); // awaits moving
|
||||
this.emitter.emit("movementComplete", { position: targetPosition });
|
||||
await this.transitionToState("operational");
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
// -------- State Transition Methods -------- //
|
||||
|
||||
async transitionToState(targetState, signal) {
|
||||
|
||||
const fromState = this.getCurrentState();
|
||||
const position = this.getCurrentPosition();
|
||||
|
||||
try {
|
||||
|
||||
this.logger.debug(`Starting transition from ${fromState} to ${targetState}.`);
|
||||
const feedback = await this.stateManager.transitionTo(targetState,signal);
|
||||
this.logger.info(`Statemanager: ${feedback}`);
|
||||
|
||||
/* -- Auto pick setpoints in auto mode when operational--*/
|
||||
if (
|
||||
targetState === "operational" &&
|
||||
this.config.mode.current === "auto" &&
|
||||
this.delayedMove !== position &&
|
||||
this.delayedMove
|
||||
) {
|
||||
this.logger.info(`Automatically picking up on last requested setpoint ${this.delayedMove}`);
|
||||
//trigger move
|
||||
await this.moveTo(this.delayedMove,signal);
|
||||
this.delayedMove = null;
|
||||
|
||||
this.logger.info(`moveTo : ${feedback} `);
|
||||
}
|
||||
|
||||
this.logger.info(`State change to ${targetState} completed.`);
|
||||
this.emitter.emit('stateChange', targetState); // <-- Implement Here
|
||||
} catch (error) {
|
||||
if (
|
||||
error.message === "Transition aborted" ||
|
||||
error.message === "Movement aborted"
|
||||
) {
|
||||
throw error;
|
||||
}
|
||||
this.logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = state;
|
||||
|
||||
Reference in New Issue
Block a user