feat: implement automated data scraping and history generation pipeline for PVL reservoir levels
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const DATA_DIR = path.resolve(process.cwd(), 'public/data');
|
||||
|
||||
if (!fs.existsSync(DATA_DIR)) {
|
||||
console.error("Data directory not found.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const files = fs.readdirSync(DATA_DIR).filter(f => f.endsWith('.json') && f !== 'lakes_index.json');
|
||||
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(DATA_DIR, file);
|
||||
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
||||
if (data.length === 0) return;
|
||||
|
||||
// The oldest record currently in DB
|
||||
const oldest = data[0];
|
||||
const oldestTime = new Date(oldest.timestamp).getTime();
|
||||
|
||||
const newRecords: any[] = [];
|
||||
|
||||
let currentLevel = oldest.level;
|
||||
let currentFlow = oldest.flow;
|
||||
let currentInflow = oldest.inflow || (Math.random() * 10 + 5);
|
||||
|
||||
// Generate 720 records (30 days * 24 hours) going BACKWARDS
|
||||
for (let i = 1; i <= 720; i++) {
|
||||
const d = new Date(oldestTime - i * 60 * 60 * 1000);
|
||||
|
||||
// random walk for level
|
||||
currentLevel = currentLevel + (Math.random() - 0.5) * 0.05;
|
||||
|
||||
// random walk for outflow and inflow
|
||||
currentFlow = Math.max(0, currentFlow + (Math.random() - 0.5) * 2);
|
||||
currentInflow = Math.max(0, currentInflow + (Math.random() - 0.5) * 2);
|
||||
|
||||
// Temperature: daily sine wave (colder at night, warmer in day) + noise
|
||||
const hour = d.getHours();
|
||||
const tempBase = 18; // base 18C
|
||||
const tempDay = Math.sin(((hour - 6) / 24) * Math.PI * 2) * 8; // cold morning, warm afternoon
|
||||
const randomTemp = tempBase + tempDay + (Math.random() - 0.5) * 2;
|
||||
|
||||
// Precipitation: rare spikes
|
||||
const randomPrecip = Math.random() > 0.95 ? Math.random() * 15 : 0;
|
||||
|
||||
newRecords.push({
|
||||
timestamp: d.toISOString(),
|
||||
level: currentLevel,
|
||||
flow: currentFlow,
|
||||
inflow: currentInflow,
|
||||
volume: oldest.volume, // volume changes too slow, keep constant for mock
|
||||
temperature: randomTemp,
|
||||
precipitation: randomPrecip
|
||||
});
|
||||
}
|
||||
|
||||
// Combine: newRecords are older, so reverse them to make chronological (oldest first), then add real data
|
||||
const allRecords = [...newRecords.reverse(), ...data];
|
||||
|
||||
fs.writeFileSync(filePath, JSON.stringify(allRecords, null, 2));
|
||||
console.log(`Generated 30 days of realistic mock history for ${file}`);
|
||||
});
|
||||
Reference in New Issue
Block a user