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

151 lines
5.4 KiB
Python

#!/usr/bin/env python3
import json
import uuid
# Read flows.json
with open('/home/mdares/.node-red/flows.json', 'r') as f:
flows = json.load(f)
# Function code for the new Progress Check Handler node
progress_handler_func = """// Handle DB result from start-work-order progress check
if (msg._mode === "start-check-progress") {
const order = flow.get("pendingWorkOrder");
if (!order || !order.id) {
node.error("No pending work order found", msg);
return [null, null];
}
// Get progress from DB query result
const dbRow = (Array.isArray(msg.payload) && msg.payload.length > 0) ? msg.payload[0] : null;
const cycleCount = dbRow ? (Number(dbRow.cycle_count) || 0) : 0;
const goodParts = dbRow ? (Number(dbRow.good_parts) || 0) : 0;
const targetQty = dbRow ? (Number(dbRow.target_qty) || 0) : (Number(order.target) || 0);
node.warn(`[PROGRESS-CHECK] WO ${order.id}: cycles=${cycleCount}, good=${goodParts}, target=${targetQty}`);
// Check if work order has existing progress
if (cycleCount > 0 || goodParts > 0) {
// Work order has progress - send prompt to UI
node.warn(`[PROGRESS-CHECK] Work order has existing progress - sending prompt to UI`);
const promptMsg = {
_mode: "resume-prompt",
topic: "resumePrompt",
payload: {
id: order.id,
sku: order.sku || "",
cycleCount: cycleCount,
goodParts: goodParts,
targetQty: targetQty,
progressPercent: targetQty > 0 ? Math.round((goodParts / targetQty) * 100) : 0,
// Include full order object for resume/restart actions
order: {...order, cycle_count: cycleCount, good_parts: goodParts}
}
};
return [null, promptMsg];
} else {
// No existing progress - proceed with normal start
node.warn(`[PROGRESS-CHECK] No existing progress - proceeding with normal start`);
// Simulate the original start-work-order behavior
const startMsg = {
_mode: "start",
startOrder: order,
topic: "UPDATE work_orders SET status = CASE WHEN work_order_id = ? THEN 'RUNNING' ELSE 'PENDING' END, updated_at = CASE WHEN work_order_id = ? THEN NOW() ELSE updated_at END WHERE status <> 'DONE'",
payload: [order.id, order.id]
};
global.set("activeWorkOrder", order);
global.set("cycleCount", 0);
flow.set("lastMachineState", 0);
global.set("scrapPromptIssuedFor", null);
return [startMsg, null];
}
}
// Pass through all other messages
return [msg, null];"""
# Create new Progress Check Handler function node
new_node_id = "progress_check_handler_node"
new_node = {
"id": new_node_id,
"type": "function",
"z": "cac3a4383120cb57",
"g": "b7ab5e0cc02b9508",
"name": "Progress Check Handler",
"func": progress_handler_func,
"outputs": 2,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1090,
"y": 340,
"wires": [
["578c92e75bf0f266"], # Output 1: To Refresh Trigger (for normal flow)
["f2bab26e27e2023d"] # Output 2: To Back to UI (for resume prompt)
]
}
# Update mariaDB node to output to Progress Check Handler instead of Refresh Trigger
for node in flows:
if node.get('id') == 'f6ad294bc02618c9' and node.get('name') == 'mariaDB':
# Change wires to point to new Progress Check Handler
node['wires'] = [[new_node_id]]
print(f"Updated mariaDB node to output to Progress Check Handler")
break
# Also update Refresh Trigger function to handle resume/restart modes
for node in flows:
if node.get('id') == '578c92e75bf0f266' and node.get('name') == 'Refresh Trigger':
# Update function to handle resume and restart modes
updated_refresh_func = """if (msg._mode === "start" || msg._mode === "complete" || msg._mode === "resume" || msg._mode === "restart") {
// Preserve original message for Back to UI (output 2)
const originalMsg = {...msg};
// Create select message for refreshing WO table (output 1)
msg._mode = "select";
msg.topic = "SELECT * FROM work_orders ORDER BY updated_at DESC;";
return [msg, originalMsg];
}
if (msg._mode === "cycle" || msg._mode === "production-state") {
return [null, msg];
}
if (msg._mode === "scrap-prompt") {
return [null, msg];
}
if (msg._mode === "restore-query") {
// Pass restore query results to Back to UI
return [null, msg];
}
if (msg._mode === "current-state") {
// Pass current state to Back to UI
return [null, msg];
}
if (msg._mode === "scrap-complete") {
// Preserve original message for Back to UI (output 2)
const originalMsg = {...msg};
// Create select message for refreshing WO table (output 1)
msg._mode = "select";
msg.topic = "SELECT * FROM work_orders ORDER BY updated_at DESC;";
return [msg, originalMsg];
}
return [null, msg];"""
node['func'] = updated_refresh_func
print(f"Updated Refresh Trigger function to handle resume/restart")
break
# Add the new node to flows
flows.append(new_node)
print(f"Added Progress Check Handler node")
# Write back to flows.json
with open('/home/mdares/.node-red/flows.json', 'w') as f:
json.dump(flows, f, indent=4)
print("flows.json updated successfully with Progress Check Handler")