Files
2025-12-02 16:27:21 +00:00

343 lines
9.9 KiB
Plaintext

# 🚨 CRITICAL ISSUES DIAGNOSIS & FIX PLAN
## For Tomorrow's Presentation
---
## 📊 ISSUE 1: Availability Starting at 100% Then Dropping
### Root Cause
**The calculation is CORRECT, but the time accumulation logic is flawed.**
#### How It Works Now:
1. Machine cycles function runs every time it receives input (sensor polls)
2. When `trackingEnabled = true`:
- If machine state = 1: adds time to `operatingTime`
- If machine state = 0: adds time to `downtime`
3. Availability = operatingTime / (operatingTime + downtime)
#### Why It Starts at 100%:
- Initially: operatingTime = 10s, downtime = 0s
- Availability = 10/10 = 100% ✓
#### Why It Drops to 50%, 40%, etc.:
- Machine state = 0 (idle between cycles, or actual stops)
- Downtime accumulates: 10s, 20s, 30s...
- Availability = 10/(10+30) = 25% ❌
### The Problem:
**Every idle moment (state=0) counts as downtime**, even if it's just waiting for the next cycle. This is technically accurate if you want to track "machine utilization", but NOT accurate for OEE availability.
### Correct OEE Availability Formula:
**Availability = Run Time / Planned Production Time**
Where:
- Run Time = time actually producing (cycles completing)
- Planned Production Time = total time MINUS planned stops (breaks, maintenance)
### Current Implementation Error:
We're treating ALL state=0 time as downtime, but we should ONLY count:
1. Unplanned stops (machine malfunction, material shortage, etc.)
2. NOT idle time between cycles
3. NOT planned stops (lunch, breaks, maintenance)
---
## 📊 ISSUE 2: START Button Doesn't Affect Work Order Progress
### Root Cause
**The START button IS working, but the complex session logic might be interfering.**
#### Flow Trace:
1. User clicks START in Home dashboard
2. Home Template sends `{ action: "start" }`
3. Message goes: Home Template → link out 2 → link in 2 → Work Order buttons
4. Work Order buttons case "start" executes
5. Sets `trackingEnabled = true` ✓
6. Creates new session in database ✓
### Potential Issues:
1. **Session creation might be failing** (database error silently swallowed)
2. **trackingEnabled is being set, but then immediately cleared** somewhere
3. **Machine cycles isn't receiving proper input** to trigger cycles
### Diagnosis Needed:
Check if:
- `trackingEnabled` global variable is actually `true` after clicking START
- Machine cycles function is being triggered (check debug log)
- Cycles are being counted (check `cycleCount` global variable)
---
## 📊 ISSUE 3: Stop Prompt Not Showing
### Root Cause
**WIRING ERROR: Stop prompt message not reaching the UI.**
#### Current Flow (BROKEN):
1. User clicks STOP
2. Work Order buttons case "stop" executes
3. Sets `msg._mode = "stop-prompt"`
4. Returns on output 2
5. Output 2 is wired to: `f6ad294bc02618c9` (MySQL node) ❌
#### Should Be:
1. User clicks STOP
2. Work Order buttons case "stop" executes
3. Sets `msg._mode = "stop-prompt"`
4. Returns on output 2
5. Output 2 should go to: Stop Reason UI Template ✓
#### Additional Issue:
The Stop Reason UI Template (ID: `94afa68639264697`) is wired to output back to Work Order buttons, BUT Work Order buttons output 2 doesn't go to it!
**This is a circular dependency that wasn't properly wired:**
- STOP button → Work Order buttons → Stop Reason UI → Work Order buttons (with reason)
---
## 🎯 COMPREHENSIVE FIX PLAN
### Priority 1: Fix Stop Prompt (CRITICAL for presentation)
**Impact: HIGH | Complexity: LOW | Time: 5 minutes**
#### Actions:
1. Add a Switch node after Work Order buttons output 2
2. Route `_mode == "stop-prompt"` to Stop Reason UI
3. Route other messages (refresh, etc.) to existing MySQL node
4. Ensure Stop Reason UI output goes back to Work Order buttons
#### Side Effects:
- None - this is just fixing broken wiring
#### Roadblocks:
- None anticipated
---
### Priority 2: Fix Availability Calculation (CRITICAL for presentation)
**Impact: HIGH | Complexity: MEDIUM | Time: 15 minutes**
#### Option A: Track Only Unplanned Downtime (RECOMMENDED)
**Pros:**
- Accurate OEE calculation
- Planned stops don't affect availability
- Aligns with industry standard
**Cons:**
- Requires stop categorization to work (Priority 1 must be done first)
#### Implementation:
1. Modify Machine cycles to NOT accumulate downtime during state=0
2. ONLY accumulate downtime from stop_events where `affects_availability = 1`
3. Query database in KPI calculation:
```javascript
// Get unplanned downtime from database
const unplannedDowntime = await getUnplannedDowntime(workOrderId);
availability = operatingTime / (operatingTime + unplannedDowntime);
```
#### Option B: Ignore State=0 Between Cycles (SIMPLER but less accurate)
**Pros:**
- Quick fix
- No database queries needed
**Cons:**
- Won't track actual unplanned stops accurately
- Defeats the purpose of stop categorization
#### Implementation:
1. Remove downtime accumulation from Machine cycles
2. Set availability = 100% while tracking is enabled
3. (Not recommended - loses valuable data)
#### Side Effects:
- Historical data won't be affected (already in database)
- Going forward, availability will be calculated differently
#### Roadblocks:
- None, but requires database queries (Option A)
---
### Priority 3: Simplify START/STOP Logic (MEDIUM priority)
**Impact: MEDIUM | Complexity: LOW | Time: 10 minutes**
#### Current Issue:
The START/STOP cases have complex session management that might be causing issues.
#### Actions:
1. Keep the complex logic BUT add better error handling
2. Add debug logging to track what's happening
3. Ensure `trackingEnabled` is set correctly
#### OR (simpler):
1. Strip out session management from START/STOP
2. Make START/STOP ONLY control `trackingEnabled`
3. Move session management to work order start/complete only
#### Recommended Approach:
**Keep session management, but add safeguards:**
```javascript
case "start": {
// Simpler version - just enable tracking
const now = Date.now();
if (!global.get("productionStartTime")) {
global.set("productionStartTime", now);
global.set("operatingTime", 0);
global.set("downtime", 0);
}
global.set("trackingEnabled", true);
global.set("lastUpdateTime", now);
node.warn("[START] Tracking enabled");
return [null, null, null, null, null];
}
```
#### Side Effects:
- Sessions won't be created on START/STOP (only on work order start/complete)
- Simpler = fewer failure points
#### Roadblocks:
- None
---
### Priority 4: Fix Work Order Progress Display (LOW priority)
**Impact: LOW | Complexity: LOW | Time: 5 minutes**
#### Issue:
User says "START/STOP made no difference on work order advance"
#### Diagnosis:
- Work order progress IS updating (you said cycles are counting)
- Likely the UI isn't refreshing to show the update
#### Actions:
1. Check if cycle updates are reaching "Back to UI" function
2. Verify Home Template is receiving `activeWorkOrder` updates
3. Add forced refresh after each cycle
#### Side Effects:
- None
#### Roadblocks:
- None
---
## 🚀 IMPLEMENTATION ORDER FOR TOMORROW
### Phase 1: CRITICAL FIXES (30 minutes)
1. **Fix Stop Prompt Wiring** (5 min)
- Add Switch node
- Wire stop-prompt to Stop Reason UI
2. **Fix Availability Calculation** (15 min)
- Remove downtime accumulation from state=0
- Track downtime only from stop_events
- Update KPI calculation to query database
3. **Simplify START/STOP** (10 min)
- Remove complex session logic
- Just enable/disable tracking
### Phase 2: TESTING (15 minutes)
1. Test stop prompt shows when clicking STOP
2. Test availability stays high (>95%) during normal operation
3. Test START/STOP enables/disables cycle counting
4. Test unplanned stop reduces availability
5. Test planned stop does NOT reduce availability
### Phase 3: VALIDATION (15 minutes)
1. Run full work order from start to finish
2. Verify KPIs are accurate
3. Document any remaining issues
---
## 📋 DETAILED FIX SCRIPTS
### Fix 1: Stop Prompt Wiring
```python
# Add switch node between Work Order buttons output 2 and destinations
# Route stop-prompt to Stop Reason UI
# Route others to MySQL
```
### Fix 2: Availability Calculation
```javascript
// In KPI Calculation function:
// Query unplanned downtime from database
const unplannedDowntimeSql = `
SELECT COALESCE(SUM(duration), 0) as downtime
FROM stop_events
WHERE work_order_id = '${activeOrder.id}'
AND affects_availability = 1
AND resume_time IS NOT NULL;
`;
// Use this instead of global.get("downtime")
```
### Fix 3: Simplified START/STOP
```javascript
case "start": {
const now = Date.now();
if (!global.get("productionStartTime")) {
global.set("productionStartTime", now);
global.set("operatingTime", 0);
global.set("downtime", 0);
}
global.set("trackingEnabled", true);
global.set("lastUpdateTime", now);
return [null, null, null, null, null];
}
case "stop": {
// Show prompt first
msg._mode = "stop-prompt";
return [null, msg, null, null, null];
}
// Then after prompt response:
case "stop-reason": {
// Disable tracking after reason selected
global.set("trackingEnabled", false);
// ... rest of logic
}
```
---
## ⚠️ RISKS & MITIGATION
### Risk 1: Database Queries Slow Down KPI Updates
**Mitigation:** Cache downtime value, update every 30 seconds instead of every 5
### Risk 2: Breaking Existing Functionality
**Mitigation:** Create backup before changes, test each fix individually
### Risk 3: Running Out of Time
**Mitigation:** Prioritize fixes - do Priority 1 & 2 only if time is short
---
## ✅ SUCCESS CRITERIA FOR TOMORROW
1. **Stop button shows prompt** ✓
2. **Availability stays >90% during production** ✓
3. **START button enables cycle counting** ✓
4. **STOP button disables cycle counting** ✓
5. **Unplanned stops reduce availability** ✓
6. **Planned stops do NOT reduce availability** ✓
7. **Quality affected by scrap** ✓ (already working)
8. **OEE calculated correctly** ✓
---
**Ready to implement? Let's start with Priority 1.**