Initial commit, 90% there
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
|
||||
with open('/home/mdares/.node-red/flows.json', 'r') as f:
|
||||
flows = json.load(f)
|
||||
|
||||
# New Format Graph Data function that handles KPI history data
|
||||
new_format_func = '''// Format Graph Data for KPI charts
|
||||
|
||||
// Check if we have KPI history data (from global context)
|
||||
if (msg.topic === "kpiHistory" && msg.payload) {
|
||||
const kpiData = msg.payload;
|
||||
|
||||
// Extract arrays
|
||||
const oeeHist = kpiData.oee || [];
|
||||
const availHist = kpiData.availability || [];
|
||||
const perfHist = kpiData.performance || [];
|
||||
const qualHist = kpiData.quality || [];
|
||||
|
||||
// Build labels and data arrays
|
||||
const labels = [];
|
||||
const oeeData = [];
|
||||
const availData = [];
|
||||
const perfData = [];
|
||||
const qualData = [];
|
||||
|
||||
// Use OEE timestamps as primary (they should all be the same length)
|
||||
oeeHist.forEach((point, index) => {
|
||||
const timestamp = new Date(point.timestamp);
|
||||
labels.push(timestamp.toLocaleString());
|
||||
|
||||
oeeData.push(point.value || 0);
|
||||
availData.push(availHist[index]?.value || 0);
|
||||
perfData.push(perfHist[index]?.value || 0);
|
||||
qualData.push(qualHist[index]?.value || 0);
|
||||
});
|
||||
|
||||
msg.graphData = {
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{ label: 'OEE %', data: oeeData },
|
||||
{ label: 'Availability %', data: availData },
|
||||
{ label: 'Performance %', data: perfData },
|
||||
{ label: 'Quality %', data: qualData }
|
||||
]
|
||||
};
|
||||
|
||||
node.warn(`[GRAPH DATA] Formatted ${labels.length} KPI history points`);
|
||||
|
||||
delete msg.topic;
|
||||
delete msg.payload;
|
||||
return msg;
|
||||
}
|
||||
|
||||
// Legacy support: work_orders query data (if needed)
|
||||
const rows = msg.payload || [];
|
||||
|
||||
if (!Array.isArray(rows) || rows.length === 0) {
|
||||
msg.graphData = {
|
||||
labels: [],
|
||||
datasets: [
|
||||
{ label: 'OEE %', data: [] },
|
||||
{ label: 'Availability %', data: [] },
|
||||
{ label: 'Performance %', data: [] },
|
||||
{ label: 'Quality %', data: [] }
|
||||
]
|
||||
};
|
||||
delete msg.topic;
|
||||
delete msg.payload;
|
||||
return msg;
|
||||
}
|
||||
|
||||
// If we have work_orders data, format it (though we won't use this path anymore)
|
||||
const labels = [];
|
||||
const goodData = [];
|
||||
const scrapData = [];
|
||||
const efficiencyData = [];
|
||||
const qualityData = [];
|
||||
|
||||
rows.forEach(row => {
|
||||
const timestamp = new Date(row.updated_at);
|
||||
labels.push(timestamp.toLocaleString());
|
||||
|
||||
const good = Number(row.good_parts) || 0;
|
||||
const scrap = Number(row.scrap_parts) || 0;
|
||||
const target = Number(row.target_quantity) || 0;
|
||||
|
||||
goodData.push(good);
|
||||
scrapData.push(scrap);
|
||||
|
||||
let eff = (row.progress_percent != null)
|
||||
? Number(row.progress_percent)
|
||||
: (target > 0 ? (good / target) * 100 : 0);
|
||||
efficiencyData.push(Math.min(eff, 100));
|
||||
|
||||
const total = good + scrap;
|
||||
const quality = total > 0 ? (good / total) * 100 : 100;
|
||||
qualityData.push(quality);
|
||||
});
|
||||
|
||||
msg.graphData = {
|
||||
labels: labels,
|
||||
datasets: [
|
||||
{ label: 'OEE %', data: efficiencyData }, // Use efficiency as fallback
|
||||
{ label: 'Availability %', data: [] },
|
||||
{ label: 'Performance %', data: [] },
|
||||
{ label: 'Quality %', data: qualityData }
|
||||
]
|
||||
};
|
||||
|
||||
delete msg.topic;
|
||||
delete msg.payload;
|
||||
|
||||
return msg;'''
|
||||
|
||||
# Update Format Graph Data function
|
||||
for node in flows:
|
||||
if node.get('id') == 'format_graph_data_node_id':
|
||||
node['func'] = new_format_func
|
||||
print("✓ Updated Format Graph Data function to handle KPI data")
|
||||
break
|
||||
|
||||
with open('/home/mdares/.node-red/flows.json', 'w') as f:
|
||||
json.dump(flows, f, indent=4)
|
||||
|
||||
print("✓ flows.json updated")
|
||||
Reference in New Issue
Block a user