#!/usr/bin/env python3 import json with open('/home/mdares/.node-red/flows.json', 'r') as f: flows = json.load(f) for node in flows: if node.get('id') == 'f3a4b5c6d7e8f9a0' and node.get('name') == 'Graphs Template': template = node.get('format', '') # Add handler for "chartsData" format (from Record KPI History) # Find the $watch section and add the handler after the graphData check old_watch = """ if (msg.graphData) { createCharts(scope.selectedRange, msg.graphData); }""" new_watch = """ // Handle graphData format (from Fetch/Format Graph Data) if (msg.graphData) { createCharts(scope.selectedRange, msg.graphData); } // Handle chartsData format (from Record KPI History) if (msg.topic === 'chartsData' && msg.payload) { var kpiData = msg.payload; // Build labels and data arrays from KPI history var labels = []; var oeeData = []; var availData = []; var perfData = []; var qualData = []; var oeeHist = kpiData.oee || []; oeeHist.forEach(function(point, index) { var timestamp = new Date(point.timestamp); labels.push(timestamp.toLocaleTimeString()); oeeData.push(point.value || 0); availData.push((kpiData.availability[index] && kpiData.availability[index].value) || 0); perfData.push((kpiData.performance[index] && kpiData.performance[index].value) || 0); qualData.push((kpiData.quality[index] && kpiData.quality[index].value) || 0); }); var graphData = { labels: labels, datasets: [ { label: 'OEE %', data: oeeData }, { label: 'Availability %', data: availData }, { label: 'Performance %', data: perfData }, { label: 'Quality %', data: qualData } ] }; createCharts(scope.selectedRange, graphData); }""" template = template.replace(old_watch, new_watch) node['format'] = template print("✓ Added chartsData handler to Graphs Template") print(" - Now handles both graphData and chartsData message formats") break with open('/home/mdares/.node-red/flows.json', 'w') as f: json.dump(flows, f, indent=4) print("✓ flows.json updated")