Initial commit, 90% there

This commit is contained in:
mdares
2025-12-02 16:27:21 +00:00
commit 755028af7e
7353 changed files with 1759505 additions and 0 deletions

View File

@@ -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;