[ { "id": "ea088d9e256f2e4a", "type": "tab", "label": "Raspi", "disabled": false, "info": "", "env": [] }, { "id": "ea803f6a2965854b", "type": "mqtt-broker", "name": "Broker fuera casa", "broker": "mqtt.maliountech.com.mx", "port": "1883", "clientid": "raspi-maquina1", "autoConnect": true, "usetls": false, "protocolVersion": 4, "keepalive": "30", "cleansession": false, "autoUnsubscribe": true, "birthTopic": "", "birthQos": "0", "birthRetain": "false", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closeQos": "0", "closeRetain": "false", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willRetain": "false", "willPayload": "", "willMsg": {}, "userProps": "", "sessionExpiry": "" }, { "id": "615493954251cda9", "type": "ui_tab", "name": "Home", "icon": "dashboard", "disabled": false, "hidden": true }, { "id": "6fe5cca8f548047a", "type": "ui_group", "name": "HMI Dashboard", "tab": "615493954251cda9", "order": 1, "disp": false, "width": "25", "collapse": false, "className": "" }, { "id": "044327e0d3d61535", "type": "ui_base", "theme": { "name": "theme-light", "lightTheme": { "default": "#0094CE", "baseColor": "#0094CE", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", "edited": true, "reset": false }, "darkTheme": { "default": "#097479", "baseColor": "#097479", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", "edited": false }, "customTheme": { "name": "Untitled Theme 1", "default": "#4B7930", "baseColor": "#4B7930", "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" }, "themeState": { "base-color": { "default": "#0094CE", "value": "#0094CE", "edited": false }, "page-titlebar-backgroundColor": { "value": "#0094CE", "edited": false }, "page-backgroundColor": { "value": "#fafafa", "edited": false }, "page-sidebar-backgroundColor": { "value": "#ffffff", "edited": false }, "group-textColor": { "value": "#1bbfff", "edited": false }, "group-borderColor": { "value": "#ffffff", "edited": false }, "group-backgroundColor": { "value": "#ffffff", "edited": false }, "widget-textColor": { "value": "#111111", "edited": false }, "widget-backgroundColor": { "value": "#0094ce", "edited": false }, "widget-borderColor": { "value": "#ffffff", "edited": false }, "base-font": { "value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" } }, "angularTheme": { "primary": "indigo", "accents": "blue", "warn": "red", "background": "grey", "palette": "light" } }, "site": { "name": "Node-RED Dashboard", "hideToolbar": "false", "allowSwipe": "false", "lockMenu": "false", "allowTempTheme": "true", "dateFormat": "DD/MM/YYYY", "sizes": { "sx": 48, "sy": 48, "gx": 6, "gy": 6, "cx": 6, "cy": 6, "px": 0, "py": 0 } } }, { "id": "c195f94afd7183e6", "type": "ui_template", "z": "ea088d9e256f2e4a", "group": "6fe5cca8f548047a", "name": "HMI Dashboard Template", "order": 0, "width": "25", "height": "25", "format": "\n\n\n\n \n \n Industrial HMI Dashboard\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
Current Work Order
\n
\n
\n
Work Order
\n
\n
\n
\n
SKU
\n
\n
\n
\n
Cycle Time
\n
\n
\n
\n
\n
\n
0%
\n
\n
\n
\n
\n\n \n
\n
\n
Good Parts
\n
0
\n
\n
\n
Scrap Parts
\n
0
\n
\n
\n
\n \n Online\n \n
\n
\n \n Running\n \n
\n
\n
\n\n \n
\n \n
\n
\n
\n\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 \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
IDSKUDescriptionTarget QtyCompletedProgressStatusDue Date
WO-2024-001SKU-ABC123Plastic Housing - Black20001200\n
\n
\n
\n
In Progress2024-10-15
WO-2024-002SKU-DEF456Cover Panel - White15000\n
\n
\n
\n
Pending2024-10-20
WO-2024-003SKU-GHI789Mounting Bracket - Grey800800\n
\n
\n
\n
Completed2024-09-28
\n
\n
\n
\n\n \n
\n
\n
\n
\n ⚠️\n Report Issue\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\n
Recent Reports
\n
\n

No recent reports

\n
\n
\n
\n
\n\n \n
\n
\n
\n
\n 📊\n Machine Status & Analytics\n
\n
\n
\n
\n
OEE Trend (Last Hour)
\n
\n \n
\n
\n
\n
Production Rate
\n
\n \n
\n
\n
\n
Quality Metrics
\n
\n \n
\n
\n
\n
Machine State Timeline
\n
\n \n
\n
\n
\n
\n
\n\n \n
\n
\n
\n
\n 🔔\n Notifications\n
\n \n
\n
\n
\n \n
\n \n
\n
Machine Started
\n
2 minutes ago
\n
\n Info\n
\n
\n \n
\n
Work Order Progress: 75%
\n
5 minutes ago
\n
\n Update\n
\n
\n \n
\n
Quality Alert: Scrap rate increasing
\n
15 minutes ago
\n
\n Warning\n
\n
\n
\n
\n
\n\n \n
\n
\n
\n
\n \n Help & Documentation\n
\n
\n
\n
\n
Quick Start Guide
\n

\n Dashboard View: Main HMI showing real-time machine data, OEE metrics,\n and production counters.

\n Navigation: Use the sidebar on the left to switch between different\n views.

\n Real-time Updates: All data updates automatically from global values.\n

\n
\n\n
\n
Troubleshooting
\n

\n No Data Showing:
\n • Check Node-RED is running
\n • Verify function nodes are generating data
\n • Check browser console (F12)

\n Slow Updates:
\n • Check Node-RED performance
\n • Restart Node-RED flow\n

\n
\n\n
\n
Keyboard Shortcuts
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
F11Toggle Fullscreen
F12Developer Console
Ctrl+RRefresh Dashboard
\n
\n\n
\n
System Information
\n

\n Version: 1.0.0
\n Data Source: Node-RED Global Values
\n Update Rate: 1 second
\n Browser: \n

\n
\n
\n
\n
\n\n \n
\n
\n
\n
\n ⚙️\n Settings\n
\n
\n
\n
\n
Display Settings
\n
\n \n \n
\n
\n \n \n
\n
\n\n
\n
Connection Settings
\n
\n \n \n
\n
\n \n
\n \n Connected\n
\n
\n
\n\n
\n
Data Settings
\n
\n \n \n
\n \n
\n\n
\n
System Actions
\n
\n \n \n \n
\n
\n
\n
\n
\n\n
\n
\n\n \n\n\n", "storeOutMessages": true, "fwdInMessages": true, "resendOnRefresh": true, "templateScope": "local", "className": "", "x": 700, "y": 320, "wires": [ [] ] }, { "id": "d9407fca93d82949", "type": "function", "z": "ea088d9e256f2e4a", "name": "Machine status function", "func": "// Get previous state\nconst previousStatus = global.get(\"machine_status\") || {\n state: 'Running',\n isOnline: true,\n isRunning: true\n};\n\nlet state = previousStatus.state;\n\n// Random transitions\nif (Math.random() < 0.5) {\n state = state === 'Running' ? 'Stopped' : 'Running';\n}\n\n// Create status data\nconst statusData = {\n state: state,\n isOnline: state !== 'Error',\n isRunning: state === 'Running',\n timestamp: new Date().toISOString()\n};\n\n// Store in global\nglobal.set(\"machine_status\", statusData);\n\n// Send to UI\nmsg.payload = statusData;\nmsg.topic = \"pimsa/maquina1/status\";\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 470, "y": 120, "wires": [ [ "aaf07ca380495b06", "c195f94afd7183e6" ] ] }, { "id": "547062128fa6337a", "type": "inject", "z": "ea088d9e256f2e4a", "name": "Machine Data Timer", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "1", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 140, "y": 300, "wires": [ [ "d9407fca93d82949", "207fdc449918affd", "031c7ccb3125177b", "2a35e2907dc04de0" ] ] }, { "id": "4f66d69c5bce7ba0", "type": "mqtt out", "z": "ea088d9e256f2e4a", "name": "MQTT Out - Work Order", "topic": "pimsa/erp/workorder/current", "qos": "1", "retain": "true", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "ea803f6a2965854b", "x": 810, "y": 540, "wires": [] }, { "id": "aaf07ca380495b06", "type": "mqtt out", "z": "ea088d9e256f2e4a", "name": "MQTT Out - Machine Status", "topic": "pimsa/maquina1/status", "qos": "1", "retain": "true", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "ea803f6a2965854b", "x": 820, "y": 100, "wires": [] }, { "id": "fee4e024db51e661", "type": "mqtt out", "z": "ea088d9e256f2e4a", "name": "MQTT Out - Machine OEE", "topic": "pimsa/maquina1/oee", "qos": "0", "retain": "false", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "ea803f6a2965854b", "x": 800, "y": 260, "wires": [] }, { "id": "12c37a80895dcc3e", "type": "mqtt out", "z": "ea088d9e256f2e4a", "name": "MQTT Out - Production", "topic": "pimsa/maquina1/production", "qos": "1", "retain": "false", "respTopic": "", "contentType": "", "userProps": "", "correl": "", "expiry": "", "broker": "ea803f6a2965854b", "x": 810, "y": 400, "wires": [] }, { "id": "207fdc449918affd", "type": "function", "z": "ea088d9e256f2e4a", "name": "OEE Function", "func": "// OEE Function\nconst oeeData = {\n oee: 85 + Math.random() * 15,\n availability: 90 + Math.random() * 10,\n performance: 80 + Math.random() * 20,\n quality: 95 + Math.random() * 5,\n timestamp: new Date().toISOString()\n};\n\n// Store in global context (NEW!)\nglobal.set(\"oeeData\", oeeData);\n\nmsg.payload = oeeData;\nmsg.topic = \"pimsa/maquina1/oee\";\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 440, "y": 260, "wires": [ [ "fee4e024db51e661", "c195f94afd7183e6" ] ] }, { "id": "031c7ccb3125177b", "type": "function", "z": "ea088d9e256f2e4a", "name": "Production Function", "func": "// Production Function with Auto-Reset for Demo\nconst targetQty = 2000;\n\n// Initialize or get current values\nlet goodParts = context.get('goodParts') || 100; // Start at 100 instead of 1200\nlet scrapParts = context.get('scrapParts') || 5;\n\n// Increment production\ngoodParts += Math.floor(Math.random() * 3) + 1;\nscrapParts += Math.floor(Math.random() * 2);\n\n// Calculate progress\nconst progress = Math.min(100, (goodParts / targetQty) * 100);\n\n// Auto-reset when reaching 100% (for continuous demo)\nif (goodParts >= targetQty) {\n goodParts = 100; // Reset to beginning\n scrapParts = 5;\n node.warn(\"Production cycle completed! Resetting for next work order...\");\n}\n\n// Save updated values\ncontext.set('goodParts', goodParts);\ncontext.set('scrapParts', scrapParts);\n\n// Create production data object\nconst productionData = {\n goodParts: goodParts,\n scrapParts: scrapParts,\n totalParts: goodParts + scrapParts,\n progress: progress,\n cycleTime: (45 + Math.random() * 10).toFixed(1) + \"s\",\n timestamp: new Date().toISOString()\n};\n\n// Store in global context (NEW!)\nglobal.set(\"productionData\", productionData);\n\nmsg.payload = productionData;\nmsg.topic = \"pimsa/maquina1/production\";\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 460, "y": 400, "wires": [ [ "12c37a80895dcc3e", "c195f94afd7183e6" ] ] }, { "id": "2a35e2907dc04de0", "type": "function", "z": "ea088d9e256f2e4a", "name": "Work Order Function", "func": "// Work Order Function\nconst workOrder = {\n id: 'WO-2024-001',\n sku: 'SKU-ABC123',\n description: 'Plastic Housing - Black',\n targetQty: 2000,\n dueDate: '2024-10-15'\n};\n\n// Create work order data object\nconst workOrderData = {\n workOrder: workOrder.id,\n sku: workOrder.sku,\n description: workOrder.description,\n targetQty: workOrder.targetQty,\n completedQty: context.get('goodParts') || 1200,\n dueDate: workOrder.dueDate,\n timestamp: new Date().toISOString()\n};\n\n// Store in global context (NEW!)\nglobal.set(\"workOrderData\", workOrderData);\n\nmsg.payload = workOrderData;\nmsg.topic = \"pimsa/erp/workorder/current\";\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 460, "y": 540, "wires": [ [ "4f66d69c5bce7ba0", "c195f94afd7183e6" ] ] }, { "id": "global_data_reader", "type": "function", "z": "ea088d9e256f2e4a", "name": "Global Data Reader", "func": "// Read all global values and send to template\nconst globalData = {\n machine_status: global.get(\"machine_status\") || {},\n oeeData: global.get(\"oeeData\") || {},\n productionData: global.get(\"productionData\") || {},\n workOrderData: global.get(\"workOrderData\") || {}\n};\n\n// Create a script that will update the dashboard\nconst updateScript = `\n window.globalData = ${JSON.stringify(globalData)};\n if (window.app && window.app.updateFromGlobalValues) {\n window.app.updateFromGlobalValues();\n }\n`;\n\n// Send the update script to the template\nmsg.payload = updateScript;\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 500, "y": 320, "wires": [ [ "c195f94afd7183e6" ] ] } ]