MVP
This commit is contained in:
191
modified_machine_cycles.js
Normal file
191
modified_machine_cycles.js
Normal file
@@ -0,0 +1,191 @@
|
||||
// ===== MACHINE CYCLES FUNCTION (MODIFIED WITH DB PERSISTENCE) =====
|
||||
|
||||
const current = Number(msg.payload) || 0;
|
||||
|
||||
let zeroStreak = flow.get("zeroStreak") || 0;
|
||||
zeroStreak = current === 0 ? zeroStreak + 1 : 0;
|
||||
flow.set("zeroStreak", zeroStreak);
|
||||
|
||||
const prev = flow.get("lastMachineState") ?? 0;
|
||||
flow.set("lastMachineState", current);
|
||||
|
||||
global.set("machineOnline", true); // force ONLINE for now
|
||||
|
||||
let productionRunning = !!global.get("productionStarted");
|
||||
let stateChanged = false;
|
||||
|
||||
if (current === 1 && !productionRunning) {
|
||||
productionRunning = true;
|
||||
stateChanged = true;
|
||||
} else if (current === 0 && zeroStreak >= 2 && productionRunning) {
|
||||
productionRunning = false;
|
||||
stateChanged = true;
|
||||
}
|
||||
|
||||
global.set("productionStarted", productionRunning);
|
||||
|
||||
const stateMsg = stateChanged
|
||||
? {
|
||||
_mode: "production-state",
|
||||
machineOnline: true,
|
||||
productionStarted: productionRunning
|
||||
}
|
||||
: null;
|
||||
|
||||
const activeOrder = global.get("activeWorkOrder");
|
||||
const cavities = Number(global.get("moldActive") || 0);
|
||||
if (!activeOrder || !activeOrder.id || cavities <= 0) {
|
||||
// We still want to pass along any state change even if there's no active WO.
|
||||
return [null, stateMsg, null]; // Added third output for DB sync
|
||||
}
|
||||
|
||||
// Check if tracking is enabled (START button clicked)
|
||||
const trackingEnabled = !!global.get("trackingEnabled");
|
||||
if (!trackingEnabled) {
|
||||
// Cycles are happening but we're not tracking them yet
|
||||
return [null, stateMsg, null];
|
||||
}
|
||||
|
||||
// only count rising edges (0 -> 1) for production totals
|
||||
if (prev === 1 || current !== 1) {
|
||||
// *** NEW: Sync to DB on state changes (throttled) ***
|
||||
if (stateChanged) {
|
||||
const dbSyncMsg = createDbSyncMessage(false); // throttled sync
|
||||
return [null, stateMsg, dbSyncMsg];
|
||||
}
|
||||
return [null, stateMsg, null];
|
||||
}
|
||||
|
||||
let cycles = Number(global.get("cycleCount") || 0) + 1;
|
||||
global.set("cycleCount", cycles);
|
||||
|
||||
// ===== PHASE 2: OPERATING TIME TRACKING =====
|
||||
// Track actual operating time between cycles
|
||||
const now = Date.now();
|
||||
const lastCycleTime = global.get("lastCycleTime");
|
||||
|
||||
if (lastCycleTime) {
|
||||
const deltaMs = now - lastCycleTime;
|
||||
const deltaSec = deltaMs / 1000;
|
||||
const currentOperatingTime = global.get("operatingTime") || 0;
|
||||
global.set("operatingTime", currentOperatingTime + deltaSec);
|
||||
}
|
||||
|
||||
global.set("lastCycleTime", now);
|
||||
|
||||
// Auto-prompt for scrap when target is reached
|
||||
const scrapPromptIssuedFor = global.get("scrapPromptIssuedFor");
|
||||
if (cycles === Number(activeOrder.target) && scrapPromptIssuedFor !== activeOrder.id) {
|
||||
// Mark that we've prompted for this work order to prevent repeated prompts
|
||||
global.set("scrapPromptIssuedFor", activeOrder.id);
|
||||
|
||||
// Send scrap prompt message
|
||||
const scrapPromptMsg = {
|
||||
_mode: "scrap-prompt",
|
||||
payload: {
|
||||
workOrderId: activeOrder.id,
|
||||
cycles: cycles,
|
||||
target: activeOrder.target,
|
||||
message: `Target of ${activeOrder.target} cycles reached. Do you have scrap parts to report?`
|
||||
}
|
||||
};
|
||||
|
||||
// *** NEW: Sync to DB when target is reached (forced) ***
|
||||
const dbSyncMsg = createDbSyncMessage(true); // forced sync
|
||||
return [scrapPromptMsg, stateMsg, dbSyncMsg];
|
||||
}
|
||||
|
||||
// *** NEW: Sync to DB on each cycle (throttled) ***
|
||||
const dbSyncMsg = createDbSyncMessage(false); // throttled sync
|
||||
return [null, stateMsg, dbSyncMsg];
|
||||
|
||||
// ========================================
|
||||
// HELPER FUNCTION: Create DB Sync Message
|
||||
// ========================================
|
||||
function createDbSyncMessage(forceUpdate) {
|
||||
const now = Date.now();
|
||||
const lastSync = flow.get("lastSessionSync") || 0;
|
||||
|
||||
// Throttle: only sync every 5 seconds unless forced
|
||||
if (!forceUpdate && (now - lastSync) < 5000) {
|
||||
return null;
|
||||
}
|
||||
|
||||
flow.set("lastSessionSync", now);
|
||||
|
||||
const sessionId = global.get("currentSessionId") || "session_" + Date.now();
|
||||
global.set("currentSessionId", sessionId);
|
||||
|
||||
const activeOrder = global.get("activeWorkOrder");
|
||||
const activeOrderId = activeOrder ? activeOrder.id : null;
|
||||
const activeOrderData = activeOrder ? JSON.stringify(activeOrder) : null;
|
||||
|
||||
const sessionData = {
|
||||
session_id: sessionId,
|
||||
production_start_time: global.get("productionStartTime") || null,
|
||||
operating_time: global.get("operatingTime") || 0,
|
||||
last_update_time: now,
|
||||
tracking_enabled: global.get("trackingEnabled") ? 1 : 0,
|
||||
cycle_count: global.get("cycleCount") || 0,
|
||||
active_work_order_id: activeOrderId,
|
||||
active_work_order_data: activeOrderData,
|
||||
machine_online: global.get("machineOnline") ? 1 : 0,
|
||||
production_started: global.get("productionStarted") ? 1 : 0,
|
||||
last_cycle_time: global.get("lastCycleTime") || null,
|
||||
last_machine_state: flow.get("lastMachineState") || 0,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
is_active: 1
|
||||
};
|
||||
|
||||
// Escape single quotes in JSON data
|
||||
const escapedOrderData = sessionData.active_work_order_data
|
||||
? sessionData.active_work_order_data.replace(/'/g, "''")
|
||||
: null;
|
||||
|
||||
// Create upsert query
|
||||
const query = `
|
||||
INSERT INTO session_state (
|
||||
session_id, production_start_time, operating_time, last_update_time,
|
||||
tracking_enabled, cycle_count, active_work_order_id, active_work_order_data,
|
||||
machine_online, production_started, last_cycle_time, last_machine_state,
|
||||
created_at, updated_at, is_active
|
||||
) VALUES (
|
||||
'${sessionData.session_id}',
|
||||
${sessionData.production_start_time},
|
||||
${sessionData.operating_time},
|
||||
${sessionData.last_update_time},
|
||||
${sessionData.tracking_enabled},
|
||||
${sessionData.cycle_count},
|
||||
${sessionData.active_work_order_id ? "'" + sessionData.active_work_order_id + "'" : "NULL"},
|
||||
${escapedOrderData ? "'" + escapedOrderData + "'" : "NULL"},
|
||||
${sessionData.machine_online},
|
||||
${sessionData.production_started},
|
||||
${sessionData.last_cycle_time},
|
||||
${sessionData.last_machine_state},
|
||||
${sessionData.created_at},
|
||||
${sessionData.updated_at},
|
||||
${sessionData.is_active}
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
production_start_time = VALUES(production_start_time),
|
||||
operating_time = VALUES(operating_time),
|
||||
last_update_time = VALUES(last_update_time),
|
||||
tracking_enabled = VALUES(tracking_enabled),
|
||||
cycle_count = VALUES(cycle_count),
|
||||
active_work_order_id = VALUES(active_work_order_id),
|
||||
active_work_order_data = VALUES(active_work_order_data),
|
||||
machine_online = VALUES(machine_online),
|
||||
production_started = VALUES(production_started),
|
||||
last_cycle_time = VALUES(last_cycle_time),
|
||||
last_machine_state = VALUES(last_machine_state),
|
||||
updated_at = VALUES(updated_at),
|
||||
is_active = VALUES(is_active);
|
||||
`;
|
||||
|
||||
return {
|
||||
_mode: "session-sync",
|
||||
topic: query,
|
||||
sessionData: sessionData
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user