feat: implement automated data scraping and history generation pipeline for PVL reservoir levels
This commit is contained in:
@@ -9,6 +9,10 @@ interface DataRecord {
|
||||
timestamp: string;
|
||||
level: number;
|
||||
flow: number;
|
||||
inflow?: number;
|
||||
volume?: number;
|
||||
temperature?: number | null;
|
||||
precipitation?: number | null;
|
||||
}
|
||||
|
||||
// Parse date from DD.MM.YYYY HH:MM to ISO
|
||||
@@ -46,6 +50,8 @@ async function scrapeLake(lakeId: string, oid: string, internalId: string) {
|
||||
|
||||
let currentInflow = 0;
|
||||
let currentVolume = 0;
|
||||
let currentTemp: number | null = null;
|
||||
let currentPrecip: number | null = null;
|
||||
|
||||
$('table').each((i, tbl) => {
|
||||
const text = $(tbl).text();
|
||||
@@ -55,6 +61,14 @@ async function scrapeLake(lakeId: string, oid: string, internalId: string) {
|
||||
const valStr = $(r).find('td').eq(1).text().trim().replace(/\s/g, '').replace(',', '.');
|
||||
if (label.includes('Přítok')) currentInflow = parseFloat(valStr) || 0;
|
||||
if (label.includes('Objem')) currentVolume = parseFloat(valStr) || 0;
|
||||
if (label.includes('Teplota')) {
|
||||
const v = parseFloat(valStr);
|
||||
if (!isNaN(v)) currentTemp = v;
|
||||
}
|
||||
if (label.includes('Srážky')) {
|
||||
const v = parseFloat(valStr);
|
||||
if (!isNaN(v)) currentPrecip = v;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -97,6 +111,8 @@ async function scrapeLake(lakeId: string, oid: string, internalId: string) {
|
||||
// Apply current values to the latest record
|
||||
records[0].inflow = currentInflow;
|
||||
records[0].volume = currentVolume;
|
||||
if (currentTemp !== null) records[0].temperature = currentTemp;
|
||||
if (currentPrecip !== null) records[0].precipitation = currentPrecip;
|
||||
}
|
||||
|
||||
let existingData: DataRecord[] = [];
|
||||
@@ -113,6 +129,23 @@ async function scrapeLake(lakeId: string, oid: string, internalId: string) {
|
||||
return new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime();
|
||||
});
|
||||
|
||||
// Propagate previous values if missing (user requested)
|
||||
let lastKnownTemp: number | null = null;
|
||||
let lastKnownPrecip: number | null = null;
|
||||
mergedData.forEach(item => {
|
||||
if (item.temperature !== undefined && item.temperature !== null) {
|
||||
lastKnownTemp = item.temperature;
|
||||
} else if (lastKnownTemp !== null) {
|
||||
item.temperature = lastKnownTemp;
|
||||
}
|
||||
|
||||
if (item.precipitation !== undefined && item.precipitation !== null) {
|
||||
lastKnownPrecip = item.precipitation;
|
||||
} else if (lastKnownPrecip !== null) {
|
||||
item.precipitation = lastKnownPrecip;
|
||||
}
|
||||
});
|
||||
|
||||
fs.mkdirSync(path.dirname(DATA_FILE), { recursive: true });
|
||||
fs.writeFileSync(DATA_FILE, JSON.stringify(mergedData, null, 2), 'utf-8');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user