From c467b065223337f84e62a30d9ced51433c12fe62 Mon Sep 17 00:00:00 2001 From: Marcelo Date: Wed, 26 Nov 2025 13:32:57 -0600 Subject: [PATCH] backup --- flows.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/flows.json b/flows.json index c248bb1..920cad0 100644 --- a/flows.json +++ b/flows.json @@ -399,7 +399,7 @@ "order": 0, "width": "25", "height": "25", - "format": "\n
\n \n\n
\n
\n
\n
\n
OEE
\n
0%
\n
\n
\n
Availability
\n
0%
\n
\n
\n
Performance
\n
0%
\n
\n
\n
Quality
\n
0%
\n
\n
\n\n
\n

Current Work Order

\n
\n
\n
Work Order ID
\n
 
\n
\n
\n
SKU
\n
 
\n
\n
\n
Cycle Time
\n
0
\n
\n
\n
\n
\n
0%
\n
\n
\n\n
\n
\n
Good Parts
\n
0
\n
out of 0
\n
\n\n
\n
MachineOFFLINE
\n
ProductionSTOPPED
\n
\n\n
\n \n
\n
\n
\n
\n
\n
\n
\n

Work Order Complete

\n

{{ scrapPrompt.orderId }}

\n

Produced {{ scrapPrompt.produced }} of {{ scrapPrompt.target }} pieces

\n\n
Were there any scrap parts?
\n\n \n
\n
{{ scrapPrompt.scrapCount || 0 }}
\n
{{ scrapPrompt.error }}
\n\n
\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n
\n\n
\n \n
\n
\n\n \n
\n \n \n
\n
\n
\n\n\n\n", + "format": "\n
\n \n\n
\n
\n
\n
\n
OEE
\n
0%
\n
\n
\n
Availability
\n
0%
\n
\n
\n
Performance
\n
0%
\n
\n
\n
Quality
\n
0%
\n
\n
\n\n
\n

Current Work Order

\n
\n
\n
Work Order ID
\n
 
\n
\n
\n
SKU
\n
 
\n
\n
\n
Cycle Time
\n
0
\n
\n
\n
\n
\n
0%
\n
\n
\n\n
\n
\n
Good Parts
\n
0
\n
out of 0
\n
\n\n
\n
MachineOFFLINE
\n
ProductionSTOPPED
\n
\n\n
\n \n
\n
\n
\n
\n
\n
\n
\n

Work Order Complete

\n

{{ scrapPrompt.orderId }}

\n

Produced {{ scrapPrompt.produced }} of {{ scrapPrompt.target }} pieces

\n\n
Were there any scrap parts?
\n\n \n
\n
{{ scrapPrompt.scrapCount || 0 }}
\n
{{ scrapPrompt.error }}
\n\n
\n \n \n \n\n \n \n \n\n \n \n \n\n \n \n \n
\n\n
\n \n
\n
\n\n \n
\n \n \n
\n
\n
\n\n\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, @@ -424,7 +424,7 @@ "order": 0, "width": "25", "height": "25", - "format": "\n
\n \n\n
\n
\n
\n

Alerts

\n
\n\n
\n \n \n \n
\n\n
\n
\n \n \n
\n
\n \n \n
\n \n
\n
\n
\n
\n\n\n", + "format": "\n
\n \n\n
\n
\n
\n

Alerts

\n
\n\n
\n \n \n \n
\n\n
\n
\n \n \n
\n
\n \n \n
\n \n
\n
\n
\n
\n\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, @@ -448,7 +448,7 @@ "order": 0, "width": "25", "height": "25", - "format": "\n
\n \n\n
\n
\n
\n

Graphs

\n
\n\n
\n
Time Range:
\n
\n \n \n \n \n \n
\n
\n\n\n
\n
\n

OEE – Last 24h

\n
\n
\n
\n

Availability – Last 7 days

\n
\n
\n
\n

Performance – Last 7 days

\n
\n
\n
\n

Quality – Last 7 days

\n
\n
\n
\n
\n
\n
\n\n\n\n\n\n", + "format": "\n
\n \n\n
\n
\n
\n

Graphs

\n
\n\n
\n
Time Range:
\n
\n \n \n \n \n \n
\n
\n\n\n
\n
\n

OEE \u2013 Last 24h

\n
\n
\n
\n

Availability \u2013 Last 7 days

\n
\n
\n
\n

Performance \u2013 Last 7 days

\n
\n
\n
\n

Quality \u2013 Last 7 days

\n
\n
\n
\n
\n
\n
\n\n\n\n\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, @@ -472,7 +472,7 @@ "order": 0, "width": "25", "height": "25", - "format": "\n
\n \n\n
\n
\n
\n

Help

\n
\n\n
\n

About this Dashboard

\n

This interface centralizes Overall Equipment Effectiveness metrics, real-time production details, and critical status indicators. Each tab follows a unified layout so operators can scan performance, alerts, and configuration without relearning navigation.

\n
\n\n
\n

How to Start / Stop Production

\n

Navigate to the Work Orders tab, select the required job, and use the primary controls to begin or end production. Always log the reason for stoppages using the Alerts tab, and confirm machine readiness before resuming. Follow your facility’s standard operating procedure for approvals and sign-off.

\n
\n
\n
\n
\n\n\n", + "format": "\n
\n \n\n
\n
\n
\n

Help

\n
\n\n
\n

About this Dashboard

\n

This interface centralizes Overall Equipment Effectiveness metrics, real-time production details, and critical status indicators. Each tab follows a unified layout so operators can scan performance, alerts, and configuration without relearning navigation.

\n
\n\n
\n

How to Start / Stop Production

\n

Navigate to the Work Orders tab, select the required job, and use the primary controls to begin or end production. Always log the reason for stoppages using the Alerts tab, and confirm machine readiness before resuming. Follow your facility\u2019s standard operating procedure for approvals and sign-off.

\n
\n
\n
\n
\n\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, @@ -496,7 +496,7 @@ "order": 0, "width": "25", "height": "25", - "format": "\n
\n \n\n
\n
\n
\n

Settings

\n
\n\n
\n

Mold Presets

\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n \n
\n

Select a manufacturer and mold from the dropdowns above.

\n

If you can't find the mold you're looking for, add a new one:

\n \n
\n \n \n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n
\n\n
\n

Mold Configuration

\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n\n
\n

Integrations

\n \n
\n
\n
\n
\n\n\n\n", + "format": "\n
\n \n\n
\n
\n
\n

Settings

\n
\n\n
\n

Mold Presets

\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n
\n \n
\n

Select a manufacturer and mold from the dropdowns above.

\n
\n\n \n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n
\n\n
\n

Mold Configuration

\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n\n
\n

Integrations

\n
\n
\n \n
\n
\n

Can't find the mold you're looking for?

\n \n
\n
\n
\n
\n
\n
\n\n\n\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, @@ -521,7 +521,7 @@ "order": 1, "width": "25", "height": "25", - "format": "\n
\n \n\n
\n
\n
\n

Work Orders

\n
\n \n \n \n \n \n
\n
\n\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
IDSKUTARGETGOODSCRAPPROGRESSSTATUSLAST UPDATE
\n
\n
0 items
\n
\n
\n
\n
\n\n\n", + "format": "\n
\n \n\n
\n
\n
\n

Work Orders

\n
\n \n \n \n \n \n
\n
\n\n
\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
IDSKUTARGETGOODSCRAPPROGRESSSTATUSLAST UPDATE
\n
\n
0 items
\n
\n
\n
\n
\n\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, @@ -624,7 +624,7 @@ "z": "cac3a4383120cb57", "g": "16bb591480852f51", "name": "1,0", - "func": "// Get current global value (default to 0 if not set)\nlet estado = global.get('Estado_maquina') || 0;\nlet stop = flow.get('stop') || false;\n\nif (stop) {\n // Manual stop active → force 0, don't reschedule\n global.set('Estado_maquina', 0);\n msg.payload = 0;\n node.send(msg);\n return;\n}\n\n// Toggle between 1 and 0\nestado = estado === 1 ? 0 : 1;\n\n// Update the global variable\nglobal.set('Estado_maquina', estado);\n\n// Send it out\nmsg.payload = estado;\nreturn msg;\n", + "func": "// Get current global value (default to 0 if not set)\nlet estado = global.get('Estado_maquina') || 0;\nlet stop = flow.get('stop') || false;\n\nif (stop) {\n // Manual stop active \u2192 force 0, don't reschedule\n global.set('Estado_maquina', 0);\n msg.payload = 0;\n node.send(msg);\n return;\n}\n\n// Toggle between 1 and 0\nestado = estado === 1 ? 0 : 1;\n\n// Update the global variable\nglobal.set('Estado_maquina', estado);\n\n// Send it out\nmsg.payload = estado;\nreturn msg;\n", "outputs": 1, "timeout": 0, "noerr": 0, @@ -816,7 +816,7 @@ "z": "cac3a4383120cb57", "g": "28c173789034639c", "name": "Process DB Results", - "func": "// Replace function in \"Process DB Results\" node\n\nconst originalTopic = msg._originalTopic || '';\nconst dbResults = Array.isArray(msg.payload) ? msg.payload : [];\n\nif (!originalTopic) {\n return null;\n}\n\n// IMPORTANT: Clear socketid to prevent loops back to sender\ndelete msg._socketid;\ndelete msg.socketid;\n\n// Manufacturers query → list for first dropdown\nif (originalTopic === 'getManufacturers') {\n const manufacturers = dbResults\n .map(row => row.manufacturer)\n .filter((mfg, index, arr) => mfg && arr.indexOf(mfg) === index)\n .sort();\n\n msg.topic = 'manufacturersList';\n msg.payload = manufacturers;\n\n node.status({ fill: 'green', shape: 'dot', text: `${manufacturers.length} manufacturers` });\n return msg;\n}\n\n// Preset lists (legacy load/search)\nif (originalTopic === 'loadMoldPresets' || originalTopic === 'searchMoldPresets') {\n const presets = dbResults.map(row => ({\n mold_name: row.mold_name || '',\n manufacturer: row.manufacturer || '',\n theoretical_cavities: Number(row.theoretical_cavities) || 0,\n functional_cavities: Number(row.functional_cavities) || 0\n }));\n\n msg.topic = 'moldPresetsList';\n msg.payload = presets;\n\n node.status({ fill: 'green', shape: 'dot', text: `${presets.length} presets found` });\n return msg;\n}\n\n// Molds for selected manufacturer\nif (originalTopic === 'getMoldsByManufacturer') {\n const presets = dbResults.map(row => ({\n mold_name: row.mold_name || '',\n manufacturer: row.manufacturer || '',\n theoretical_cavities: Number(row.theoretical_cavities) || 0,\n functional_cavities: Number(row.functional_cavities) || 0\n }));\n\n msg.topic = 'moldPresetsList';\n msg.payload = presets;\n\n node.status({ fill: 'blue', shape: 'dot', text: `${presets.length} molds for manufacturer` });\n return msg;\n}\n\n// Result of inserting a new mold\nif (originalTopic === 'addMoldPreset') {\n msg.topic = 'addMoldResult';\n msg.payload = {\n success: true,\n result: msg.payload\n };\n\n node.status({ fill: 'green', shape: 'dot', text: 'Mold added' });\n return msg;\n}\n\nnode.status({ fill: 'yellow', shape: 'ring', text: 'Unknown topic: ' + originalTopic });\nreturn null;", + "func": "// Replace function in \"Process DB Results\" node\n\nconst originalTopic = msg._originalTopic || '';\nconst dbResults = Array.isArray(msg.payload) ? msg.payload : [];\n\nif (!originalTopic) {\n return null;\n}\n\n// IMPORTANT: Clear socketid to prevent loops back to sender\ndelete msg._socketid;\ndelete msg.socketid;\n\n// Manufacturers query \u2192 list for first dropdown\nif (originalTopic === 'getManufacturers') {\n const manufacturers = dbResults\n .map(row => row.manufacturer)\n .filter((mfg, index, arr) => mfg && arr.indexOf(mfg) === index)\n .sort();\n\n msg.topic = 'manufacturersList';\n msg.payload = manufacturers;\n\n node.status({ fill: 'green', shape: 'dot', text: `${manufacturers.length} manufacturers` });\n return msg;\n}\n\n// Preset lists (legacy load/search)\nif (originalTopic === 'loadMoldPresets' || originalTopic === 'searchMoldPresets') {\n const presets = dbResults.map(row => ({\n mold_name: row.mold_name || '',\n manufacturer: row.manufacturer || '',\n theoretical_cavities: Number(row.theoretical_cavities) || 0,\n functional_cavities: Number(row.functional_cavities) || 0\n }));\n\n msg.topic = 'moldPresetsList';\n msg.payload = presets;\n\n node.status({ fill: 'green', shape: 'dot', text: `${presets.length} presets found` });\n return msg;\n}\n\n// Molds for selected manufacturer\nif (originalTopic === 'getMoldsByManufacturer') {\n const presets = dbResults.map(row => ({\n mold_name: row.mold_name || '',\n manufacturer: row.manufacturer || '',\n theoretical_cavities: Number(row.theoretical_cavities) || 0,\n functional_cavities: Number(row.functional_cavities) || 0\n }));\n\n msg.topic = 'moldPresetsList';\n msg.payload = presets;\n\n node.status({ fill: 'blue', shape: 'dot', text: `${presets.length} molds for manufacturer` });\n return msg;\n}\n\n// Result of inserting a new mold\nif (originalTopic === 'addMoldPreset') {\n msg.topic = 'addMoldResult';\n msg.payload = {\n success: true,\n result: msg.payload\n };\n\n node.status({ fill: 'green', shape: 'dot', text: 'Mold added' });\n return msg;\n}\n\nnode.status({ fill: 'yellow', shape: 'ring', text: 'Unknown topic: ' + originalTopic });\nreturn null;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -966,7 +966,7 @@ "z": "cac3a4383120cb57", "g": "b7ab5e0cc02b9508", "name": "Back to UI", - "func": "const mode = msg._mode || '';\nconst started = msg.startOrder || null;\nconst completed = msg.completeOrder || null;\n\ndelete msg._mode;\ndelete msg.startOrder;\ndelete msg.completeOrder;\ndelete msg.action;\ndelete msg.filename;\n\nif (mode === \"upload\") {\n msg.topic = \"uploadStatus\";\n msg.payload = { message: \"✅ Work orders uploaded successfully.\" };\n return [msg, null];\n}\n\nif (mode === \"select\") {\n const rawRows = Array.isArray(msg.payload) ? msg.payload : [];\n msg.topic = \"workOrdersList\";\n msg.payload = rawRows.map(row => ({\n id: row.work_order_id ?? row.id ?? \"\",\n sku: row.sku ?? \"\",\n target: Number(row.target_qty ?? row.target ?? 0),\n good: Number(row.good_parts ?? row.good ?? 0),\n scrap: Number(row.scrap_count ?? row.scrap ?? 0),\n progressPercent: Number(row.progress_percent ?? row.progress ?? 0),\n status: (row.status ?? \"PENDING\").toUpperCase(),\n lastUpdateIso: row.updated_at ?? row.last_update ?? null,\n cycleTime: Number(row.cycle_time ?? row.theoretical_cycle_time ?? 0)\n }));\n return [msg, null];\n}\n\nif (mode === \"start\") {\n const order = started || {};\n const homeMsg = {\n topic: \"activeWorkOrder\",\n payload: {\n id: order.id || \"\",\n sku: order.sku || \"\",\n target: Number(order.target) || 0,\n good: Number(order.good) || 0,\n scrap: Number(order.scrap) || 0,\n cycleTime: Number(order.cycleTime || order.theoreticalCycleTime || 0),\n progressPercent: Number(order.progressPercent) || 0,\n lastUpdateIso: order.lastUpdateIso || null\n }\n };\n return [null, homeMsg];\n}\n\nif (mode === \"complete\") {\n const homeMsg = { topic: \"activeWorkOrder\", payload: null };\n return [null, homeMsg];\n}\n\nif (mode === \"cycle\") {\n const cycle = msg.cycle || {};\n const workOrderMsg = {\n topic: \"workOrderCycle\",\n payload: {\n id: cycle.id || \"\",\n sku: cycle.sku || \"\",\n target: Number(cycle.target) || 0,\n good: Number(cycle.good) || 0,\n scrap: Number(cycle.scrap) || 0,\n progressPercent: Number(cycle.progressPercent) || 0,\n lastUpdateIso: cycle.lastUpdateIso || new Date().toISOString(),\n status: cycle.progressPercent >= 100 ? \"DONE\" : \"RUNNING\"\n }\n };\n\n const homeMsg = {\n topic: \"activeWorkOrder\",\n payload: {\n id: cycle.id || \"\",\n sku: cycle.sku || \"\",\n target: Number(cycle.target) || 0,\n good: Number(cycle.good) || 0,\n scrap: Number(cycle.scrap) || 0,\n cycleTime: Number(cycle.cycleTime) || 0,\n progressPercent: Number(cycle.progressPercent) || 0,\n lastUpdateIso: cycle.lastUpdateIso || new Date().toISOString()\n }\n };\n\n return [workOrderMsg, homeMsg];\n}\nif (mode === \"production-state\") {\n const homeMsg = {\n topic: \"machineStatus\",\n payload: {\n machineOnline: msg.machineOnline ?? true,\n productionStarted: !!msg.productionStarted\n }\n };\n return [null, homeMsg];\n}\nif (mode === \"scrap-prompt\") {\n const prompt = msg.scrapPrompt || {};\n const homeMsg = { topic: \"scrapPrompt\", payload: prompt };\n const tabMsg = { ui_control: { tab: \"Home\" } };\n\n // output1: nothing, output2: Home template, output3: Tab navigation\n return [null, homeMsg, tabMsg];\n}\n\nif (mode === \"scrap-complete\") {\n const homeMsg = { topic: \"activeWorkOrder\", payload: null };\n return [null, homeMsg];\n}\nreturn [null, null];", + "func": "const mode = msg._mode || '';\nconst started = msg.startOrder || null;\nconst completed = msg.completeOrder || null;\n\ndelete msg._mode;\ndelete msg.startOrder;\ndelete msg.completeOrder;\ndelete msg.action;\ndelete msg.filename;\n\nif (mode === \"upload\") {\n msg.topic = \"uploadStatus\";\n msg.payload = { message: \"\u2705 Work orders uploaded successfully.\" };\n return [msg, null];\n}\n\nif (mode === \"select\") {\n const rawRows = Array.isArray(msg.payload) ? msg.payload : [];\n msg.topic = \"workOrdersList\";\n msg.payload = rawRows.map(row => ({\n id: row.work_order_id ?? row.id ?? \"\",\n sku: row.sku ?? \"\",\n target: Number(row.target_qty ?? row.target ?? 0),\n good: Number(row.good_parts ?? row.good ?? 0),\n scrap: Number(row.scrap_count ?? row.scrap ?? 0),\n progressPercent: Number(row.progress_percent ?? row.progress ?? 0),\n status: (row.status ?? \"PENDING\").toUpperCase(),\n lastUpdateIso: row.updated_at ?? row.last_update ?? null,\n cycleTime: Number(row.cycle_time ?? row.theoretical_cycle_time ?? 0)\n }));\n return [msg, null];\n}\n\nif (mode === \"start\") {\n const order = started || {};\n const homeMsg = {\n topic: \"activeWorkOrder\",\n payload: {\n id: order.id || \"\",\n sku: order.sku || \"\",\n target: Number(order.target) || 0,\n good: Number(order.good) || 0,\n scrap: Number(order.scrap) || 0,\n cycleTime: Number(order.cycleTime || order.theoreticalCycleTime || 0),\n progressPercent: Number(order.progressPercent) || 0,\n lastUpdateIso: order.lastUpdateIso || null\n }\n };\n return [null, homeMsg];\n}\n\nif (mode === \"complete\") {\n const homeMsg = { topic: \"activeWorkOrder\", payload: null };\n return [null, homeMsg];\n}\n\nif (mode === \"cycle\") {\n const cycle = msg.cycle || {};\n const workOrderMsg = {\n topic: \"workOrderCycle\",\n payload: {\n id: cycle.id || \"\",\n sku: cycle.sku || \"\",\n target: Number(cycle.target) || 0,\n good: Number(cycle.good) || 0,\n scrap: Number(cycle.scrap) || 0,\n progressPercent: Number(cycle.progressPercent) || 0,\n lastUpdateIso: cycle.lastUpdateIso || new Date().toISOString(),\n status: cycle.progressPercent >= 100 ? \"DONE\" : \"RUNNING\"\n }\n };\n\n const homeMsg = {\n topic: \"activeWorkOrder\",\n payload: {\n id: cycle.id || \"\",\n sku: cycle.sku || \"\",\n target: Number(cycle.target) || 0,\n good: Number(cycle.good) || 0,\n scrap: Number(cycle.scrap) || 0,\n cycleTime: Number(cycle.cycleTime) || 0,\n progressPercent: Number(cycle.progressPercent) || 0,\n lastUpdateIso: cycle.lastUpdateIso || new Date().toISOString()\n }\n };\n\n return [workOrderMsg, homeMsg];\n}\nif (mode === \"production-state\") {\n const homeMsg = {\n topic: \"machineStatus\",\n payload: {\n machineOnline: msg.machineOnline ?? true,\n productionStarted: !!msg.productionStarted\n }\n };\n return [null, homeMsg];\n}\nif (mode === \"scrap-prompt\") {\n const prompt = msg.scrapPrompt || {};\n const homeMsg = { topic: \"scrapPrompt\", payload: prompt };\n const tabMsg = { ui_control: { tab: \"Home\" } };\n\n // output1: nothing, output2: Home template, output3: Tab navigation\n return [null, homeMsg, tabMsg];\n}\n\nif (mode === \"scrap-complete\") {\n const homeMsg = { topic: \"activeWorkOrder\", payload: null };\n return [null, homeMsg];\n}\nreturn [null, null];", "outputs": 3, "timeout": 0, "noerr": 0,