Initial commit, 90% there
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// ============================================================================
|
||||
// KPI CALCULATION Function
|
||||
// Purpose: Calculate OEE, Availability, Performance, Quality metrics
|
||||
// Triggered by: Timer (every 5 seconds) or on cycle updates
|
||||
// ============================================================================
|
||||
|
||||
// Get current global variables
|
||||
const activeOrder = global.get("activeWorkOrder");
|
||||
const cycleCount = global.get("cycleCount") || 0;
|
||||
const trackingEnabled = global.get("trackingEnabled") || false;
|
||||
const operatingTime = global.get("operatingTime") || 0; // seconds
|
||||
const downtime = global.get("downtime") || 0; // seconds
|
||||
const productionStartTime = global.get("productionStartTime");
|
||||
|
||||
// If no active order or not tracking, send zeros
|
||||
if (!activeOrder || !activeOrder.id || !trackingEnabled || !productionStartTime) {
|
||||
msg.payload = {
|
||||
oee: 0,
|
||||
availability: 0,
|
||||
performance: 0,
|
||||
quality: 0
|
||||
};
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Extract work order data
|
||||
const targetQty = Number(activeOrder.target) || 0;
|
||||
const goodParts = Number(activeOrder.good) || 0;
|
||||
const scrapParts = Number(activeOrder.scrap) || 0;
|
||||
const totalProduced = goodParts + scrapParts;
|
||||
const theoreticalCycleTime = Number(activeOrder.cycleTime || activeOrder.theoreticalCycleTime || 0);
|
||||
|
||||
// ============================================================================
|
||||
// AVAILABILITY = Operating Time / (Operating Time + Downtime)
|
||||
// ============================================================================
|
||||
let availability = 0;
|
||||
const totalTime = operatingTime + downtime;
|
||||
|
||||
if (totalTime > 0) {
|
||||
availability = (operatingTime / totalTime) * 100;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// PERFORMANCE = (Actual Production / Theoretical Production) * 100
|
||||
// Theoretical Production = Operating Time / Theoretical Cycle Time
|
||||
// ============================================================================
|
||||
let performance = 0;
|
||||
|
||||
if (theoreticalCycleTime > 0 && operatingTime > 0) {
|
||||
const theoreticalProduction = operatingTime / theoreticalCycleTime;
|
||||
if (theoreticalProduction > 0) {
|
||||
performance = (cycleCount / theoreticalProduction) * 100;
|
||||
}
|
||||
}
|
||||
|
||||
// Cap performance at 100% (can't exceed theoretical max)
|
||||
performance = Math.min(performance, 100);
|
||||
|
||||
// ============================================================================
|
||||
// QUALITY = Good Parts / Total Parts Produced
|
||||
// ============================================================================
|
||||
let quality = 0;
|
||||
|
||||
if (totalProduced > 0) {
|
||||
quality = (goodParts / totalProduced) * 100;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// OEE = Availability × Performance × Quality (as decimals)
|
||||
// ============================================================================
|
||||
const oee = (availability / 100) * (performance / 100) * (quality / 100) * 100;
|
||||
|
||||
// ============================================================================
|
||||
// OUTPUT: Send KPIs to Home template
|
||||
// ============================================================================
|
||||
msg.topic = "kpiUpdate";
|
||||
msg.payload = {
|
||||
oee: Math.round(oee),
|
||||
availability: Math.round(availability),
|
||||
performance: Math.round(performance),
|
||||
quality: Math.round(quality)
|
||||
};
|
||||
|
||||
return msg;
|
||||
Reference in New Issue
Block a user