Initial commit of SOP Monitoring Dashboard
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
const xlsx = require('xlsx');
|
||||
const { Client } = require('pg');
|
||||
const path = require('path');
|
||||
|
||||
const filePath = path.join(__dirname, '..', 'Consolidated_report_v2_with_feed-names (1).xlsx');
|
||||
|
||||
const client = new Client({
|
||||
user: 'admin',
|
||||
host: 'localhost',
|
||||
database: 'sop_monitoring',
|
||||
password: 'password',
|
||||
port: 5432,
|
||||
});
|
||||
|
||||
function parseDuration(durationStr) {
|
||||
if (!durationStr) return 0;
|
||||
const hMatch = durationStr.match(/(\d+)h/);
|
||||
const mMatch = durationStr.match(/(\d+)m/);
|
||||
const sMatch = durationStr.match(/(\d+)s/);
|
||||
|
||||
let seconds = 0;
|
||||
if (hMatch) seconds += parseInt(hMatch[1]) * 3600;
|
||||
if (mMatch) seconds += parseInt(mMatch[1]) * 60;
|
||||
if (sMatch) seconds += parseInt(sMatch[1]);
|
||||
return seconds;
|
||||
}
|
||||
|
||||
function parseCellEvents(cellText, cameraZone, startTime, endTime, totalDuration) {
|
||||
if (!cellText) return [];
|
||||
const events = [];
|
||||
const blocks = cellText.split(/\r?\n---\r?\n/);
|
||||
|
||||
for (const block of blocks) {
|
||||
const lines = block.split(/\r?\n/);
|
||||
if (lines.length === 0) continue;
|
||||
|
||||
let eventDesc = lines[0];
|
||||
let state = 'Active';
|
||||
let stateDuration = totalDuration;
|
||||
|
||||
if (lines.length > 1) {
|
||||
const stateMatch = lines[1].match(/(Active|Waste|Idle|Load waiting|Start point):\s*(.*)/i);
|
||||
if (stateMatch) {
|
||||
let stateText = stateMatch[1];
|
||||
if (stateText.toLowerCase() === 'load waiting') state = 'Load waiting';
|
||||
else if (stateText.toLowerCase() === 'waste') state = 'Waste';
|
||||
else if (stateText.toLowerCase() === 'idle') state = 'Idle';
|
||||
else if (stateText.toLowerCase() === 'start point') state = 'Active';
|
||||
else state = 'Active';
|
||||
|
||||
if (stateText.toLowerCase() !== 'start point') {
|
||||
stateDuration = parseDuration(stateMatch[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.push({
|
||||
start_time: startTime,
|
||||
end_time: endTime,
|
||||
duration_seconds: totalDuration,
|
||||
camera_zone: cameraZone,
|
||||
event_description: eventDesc.trim(),
|
||||
state,
|
||||
state_duration_seconds: stateDuration
|
||||
});
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
async function run() {
|
||||
await client.connect();
|
||||
|
||||
// Create table if not exists (in case it wasn't created yet)
|
||||
await client.query('DROP TABLE IF EXISTS events;');
|
||||
await client.query(`
|
||||
CREATE TABLE IF NOT EXISTS events (
|
||||
id SERIAL PRIMARY KEY,
|
||||
changeover_id VARCHAR(100),
|
||||
changeover_date DATE,
|
||||
start_time TIME,
|
||||
end_time TIME,
|
||||
duration_seconds INTEGER,
|
||||
camera_zone VARCHAR(50),
|
||||
event_description TEXT,
|
||||
state VARCHAR(50),
|
||||
state_duration_seconds INTEGER
|
||||
);
|
||||
`);
|
||||
await client.query('TRUNCATE TABLE events RESTART IDENTITY;');
|
||||
|
||||
const wb = xlsx.readFile(filePath);
|
||||
const sheet = wb.Sheets['Time Matrix'];
|
||||
const data = xlsx.utils.sheet_to_json(sheet, { header: 1, raw: false, dateNF: 'yyyy-mm-dd hh:mm:ss' });
|
||||
|
||||
// Start from row index 8 (skipping headers in the new file format)
|
||||
let allEvents = [];
|
||||
|
||||
for (let i = 8; i < data.length; i++) {
|
||||
const row = data[i];
|
||||
|
||||
let startTime = row[1];
|
||||
let endTime = row[2];
|
||||
let durationStr = row[4];
|
||||
|
||||
if (!startTime || !endTime) continue; // Skip empty rows
|
||||
|
||||
// Handle "0s / start marker"
|
||||
let totalDuration = row[3] ? parseInt(row[3]) : parseDuration(durationStr);
|
||||
|
||||
// CO
|
||||
if (row[5]) allEvents.push(...parseCellEvents(row[5], 'CO', startTime, endTime, totalDuration));
|
||||
// Mill
|
||||
if (row[6]) allEvents.push(...parseCellEvents(row[6], 'Mill', startTime, endTime, totalDuration));
|
||||
// Conveyor
|
||||
if (row[7]) allEvents.push(...parseCellEvents(row[7], 'Conveyor', startTime, endTime, totalDuration));
|
||||
}
|
||||
|
||||
const changeoverId = 'CO-DEMO-1';
|
||||
const changeoverDate = '2026-07-28';
|
||||
|
||||
for (const ev of allEvents) {
|
||||
try {
|
||||
await client.query(
|
||||
`INSERT INTO events (changeover_id, changeover_date, start_time, end_time, duration_seconds, camera_zone, event_description, state, state_duration_seconds)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
||||
[changeoverId, changeoverDate, ev.start_time, ev.end_time, ev.duration_seconds, ev.camera_zone, ev.event_description, ev.state, ev.state_duration_seconds]
|
||||
);
|
||||
} catch(err) {
|
||||
console.error("Error inserting:", ev, err);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Inserted ${allEvents.length} events into the database.`);
|
||||
await client.end();
|
||||
}
|
||||
|
||||
run().catch(console.error);
|
||||
Reference in New Issue
Block a user