Added support for maintenance tracking in hours. "getMaintenanceTimeHours" default in output of machine now

This commit is contained in:
znetsixe
2025-11-05 15:47:05 +01:00
parent 9610e7138d
commit 9ada6e2acd
4 changed files with 79 additions and 24 deletions

View File

@@ -245,10 +245,6 @@
{ {
"value": "fysicalControl", "value": "fysicalControl",
"description": "Controlled via physical buttons or switches; ignores external automated commands." "description": "Controlled via physical buttons or switches; ignores external automated commands."
},
{
"value": "maintenance",
"description": "No active control from auto, virtual, or fysical sources."
} }
], ],
"description": "The operational mode of the machine." "description": "The operational mode of the machine."
@@ -260,7 +256,7 @@
"type": "object", "type": "object",
"schema":{ "schema":{
"auto": { "auto": {
"default": ["statusCheck", "execMovement", "execSequence", "emergencyStop"], "default": ["statusCheck", "execMovement", "execSequence", "emergencyStop","enterMaintenance"],
"rules": { "rules": {
"type": "set", "type": "set",
"itemType": "string", "itemType": "string",
@@ -268,7 +264,7 @@
} }
}, },
"virtualControl": { "virtualControl": {
"default": ["statusCheck", "execMovement", "execSequence", "emergencyStop"], "default": ["statusCheck", "execMovement", "execSequence", "emergencyStop","exitMaintenance"],
"rules": { "rules": {
"type": "set", "type": "set",
"itemType": "string", "itemType": "string",
@@ -276,19 +272,12 @@
} }
}, },
"fysicalControl": { "fysicalControl": {
"default": ["statusCheck", "emergencyStop"], "default": ["statusCheck", "emergencyStop","enterMaintenance","exitMaintenance"],
"rules": { "rules": {
"type": "set", "type": "set",
"itemType": "string", "itemType": "string",
"description": "Actions allowed in fysicalControl mode." "description": "Actions allowed in fysicalControl mode."
} }
},
"maintenance": {
"default": ["statusCheck"],
"rules": {
"type": "set",
"itemType": "string",
"description": "Actions allowed in maintenance mode."
} }
} }
}, },
@@ -327,7 +316,6 @@
}, },
"description": "Information about valid command sources recognized by the machine." "description": "Information about valid command sources recognized by the machine."
} }
}
}, },
"source": { "source": {
"default": "parent", "default": "parent",
@@ -386,6 +374,22 @@
"itemType": "string", "itemType": "string",
"description": "Sequence of states for booting up the machine." "description": "Sequence of states for booting up the machine."
} }
},
"entermaintenance":{
"default": ["stopping","coolingdown","idle","maintenance"],
"rules": {
"type": "set",
"itemType": "string",
"description": "Sequence of states if the machine is running to put it in maintenance state"
}
},
"exitmaintenance":{
"default": ["off","idle"],
"rules": {
"type": "set",
"itemType": "string",
"description": "Sequence of states if the machine is running to put it in maintenance state"
}
} }
} }
}, },

View File

@@ -52,6 +52,10 @@ class state{
return this.stateManager.getRunTimeHours(); return this.stateManager.getRunTimeHours();
} }
getMaintenanceTimeHours(){
return this.stateManager.getMaintenanceTimeHours();
}
async moveTo(targetPosition) { async moveTo(targetPosition) {

View File

@@ -205,6 +205,10 @@
{ {
"value": "off", "value": "off",
"description": "Machine is off." "description": "Machine is off."
},
{
"value": "maintenance",
"description": "Machine locked for inspection or repair; automatic control disabled."
} }
], ],
"description": "Current state of the machine." "description": "Current state of the machine."
@@ -216,7 +220,7 @@
"type": "object", "type": "object",
"schema": { "schema": {
"idle": { "idle": {
"default": ["starting", "off","emergencystop"], "default": ["starting", "off","emergencystop","maintenance"],
"rules":{ "rules":{
"type": "set", "type": "set",
"itemType": "string", "itemType": "string",
@@ -280,7 +284,7 @@
} }
}, },
"off": { "off": {
"default": ["idle","emergencystop"], "default": ["idle","emergencystop","maintenance"],
"rules":{ "rules":{
"type": "set", "type": "set",
"itemType": "string", "itemType": "string",
@@ -288,12 +292,20 @@
} }
}, },
"emergencystop": { "emergencystop": {
"default": ["idle","off"], "default": ["idle","off","maintenance"],
"rules":{ "rules":{
"type": "set", "type": "set",
"itemType": "string", "itemType": "string",
"description": "Allowed transitions from emergency stop state." "description": "Allowed transitions from emergency stop state."
} }
},
"maintenance": {
"default": ["maintenance","idle","off"],
"rules":{
"type": "set",
"itemType": "string",
"description": "Allowed transitions for maintenance mode"
}
} }
}, },
"description": "Allowed transitions between states." "description": "Allowed transitions between states."

View File

@@ -48,10 +48,14 @@ class stateManager {
// Define valid transitions (can be extended dynamically if needed) // Define valid transitions (can be extended dynamically if needed)
this.validTransitions = config.state.allowedTransitions; this.validTransitions = config.state.allowedTransitions;
// NEW: Initialize runtime tracking //runtime tracking
this.runTimeHours = 0; // cumulative runtime in hours this.runTimeHours = 0; // cumulative runtime in hours
this.runTimeStart = null; // timestamp when active state began this.runTimeStart = null; // timestamp when active state began
//maintenance tracking
this.maintenanceTimeStart = null; //timestamp when active state began
this.maintenanceTimeHours = 0; //cumulative
// Define active states (runtime counts only in these states) // Define active states (runtime counts only in these states)
this.activeStates = config.state.activeStates; this.activeStates = config.state.activeStates;
} }
@@ -73,8 +77,9 @@ class stateManager {
); //go back early and reject promise ); //go back early and reject promise
} }
// NEW: Handle runtime tracking based on active states //Time tracking based on active states
this.handleRuntimeTracking(newState); this.handleRuntimeTracking(newState);
this.handleMaintenancetimeTracking(newState);
const transitionDuration = this.transitionTimes[this.currentState] || 0; // Default to 0 if no transition time const transitionDuration = this.transitionTimes[this.currentState] || 0; // Default to 0 if no transition time
this.logger.debug( this.logger.debug(
@@ -100,7 +105,7 @@ class stateManager {
} }
handleRuntimeTracking(newState) { handleRuntimeTracking(newState) {
// NEW: Handle runtime tracking based on active states //Handle runtime tracking based on active states
const wasActive = this.activeStates.has(this.currentState); const wasActive = this.activeStates.has(this.currentState);
const willBeActive = this.activeStates.has(newState); const willBeActive = this.activeStates.has(newState);
if (wasActive && !willBeActive && this.runTimeStart) { if (wasActive && !willBeActive && this.runTimeStart) {
@@ -120,6 +125,28 @@ class stateManager {
} }
} }
handleMaintenancetimeTracking(newState) {
//is this maintenance time ?
const wasActive = (this.currentState == "maintenance"? true:false);
const willBeActive = ( newState == "maintenance" ? true:false );
if (wasActive && this.maintenanceTimeStart) {
// stop runtime timer and accumulate elapsed time
const elapsed = (Date.now() - this.maintenanceTimeStart) / 3600000; // hours
this.maintenanceTimeHours += elapsed;
this.maintenanceTimeStart = null;
this.logger.debug(
`Maintenance timer stopped; elapsed=${elapsed.toFixed(
3
)}h, total=${this.maintenanceTimeHours.toFixed(3)}h.`
);
} else if (willBeActive && !this.runTimeStart) {
// starting new runtime
this.maintenanceTimeStart = Date.now();
this.logger.debug("Runtime timer started.");
}
}
isValidTransition(newState) { isValidTransition(newState) {
this.logger.debug( this.logger.debug(
`Check 1 Transition valid ? From ${ `Check 1 Transition valid ? From ${
@@ -150,7 +177,6 @@ class stateManager {
return this.descriptions[state] || "No description available."; return this.descriptions[state] || "No description available.";
} }
// NEW: Getter to retrieve current cumulative runtime (active time) in hours.
getRunTimeHours() { getRunTimeHours() {
// If currently active add the ongoing duration. // If currently active add the ongoing duration.
let currentElapsed = 0; let currentElapsed = 0;
@@ -159,6 +185,15 @@ class stateManager {
} }
return this.runTimeHours + currentElapsed; return this.runTimeHours + currentElapsed;
} }
getMaintenanceTimeHours() {
// If currently active add the ongoing duration.
let currentElapsed = 0;
if (this.maintenanceTimeStart) {
currentElapsed = (Date.now() - this.maintenanceTimeStart) / 3600000;
}
return this.maintenanceTimeHours + currentElapsed;
}
} }
module.exports = stateManager; module.exports = stateManager;