92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
import { lakesConfig } from './lakesConfig';
|
|
|
|
interface DataRecord {
|
|
timestamp: string;
|
|
level: number;
|
|
flow: number;
|
|
}
|
|
|
|
const lakes = lakesConfig.map(lake => {
|
|
const [internalId, oid] = lake.id.split('|');
|
|
const DATA_FILE = path.resolve(`public/data/${internalId}.json`);
|
|
|
|
let currentLevel = 0;
|
|
let currentFlow = 0;
|
|
let sparkline: number[] = Array(12).fill(0);
|
|
|
|
let capacity = 0;
|
|
let volume = 0;
|
|
let inflow = 0;
|
|
|
|
if (fs.existsSync(DATA_FILE)) {
|
|
try {
|
|
const data: any[] = JSON.parse(fs.readFileSync(DATA_FILE, 'utf-8'));
|
|
if (data.length > 0) {
|
|
// Find latest valid record or just the last record
|
|
const lastValidLevelData = [...data].reverse().find(d => d.level !== null && !isNaN(d.level));
|
|
const lastValidFlowData = [...data].reverse().find(d => d.flow !== null && !isNaN(d.flow) && d.flow > 0);
|
|
|
|
currentLevel = lastValidLevelData ? lastValidLevelData.level : 0;
|
|
currentFlow = lastValidFlowData ? lastValidFlowData.flow : 0;
|
|
|
|
// Take up to 12 last records for sparkline
|
|
const recentData = data.slice(-12);
|
|
sparkline = recentData.map(d => (d.flow === null || isNaN(d.flow) ? 0 : d.flow));
|
|
|
|
// Pad with zeros if less than 12
|
|
while (sparkline.length < 12) {
|
|
sparkline.unshift(0);
|
|
}
|
|
|
|
const latest = data[data.length - 1];
|
|
if (latest.volume && latest.volume > 0) {
|
|
volume = latest.volume;
|
|
}
|
|
if (latest.inflow !== undefined) {
|
|
inflow = latest.inflow;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
console.error(`Error reading data for ${internalId}`, e);
|
|
}
|
|
}
|
|
|
|
if (lake.minLevel && lake.maxLevel && currentLevel > 0) {
|
|
const percentage = ((currentLevel - lake.minLevel) / (lake.maxLevel - lake.minLevel)) * 100;
|
|
capacity = Math.max(0, Math.min(100, Math.round(percentage * 10) / 10)); // Round to 1 decimal place
|
|
if (volume === 0) {
|
|
volume = Number(((capacity / 100) * (lake.maxVolume || 0)).toFixed(1));
|
|
}
|
|
} else {
|
|
if (volume === 0) volume = lake.maxVolume || 0;
|
|
}
|
|
|
|
let storageDiff = 0;
|
|
if (lake.storageLevel && currentLevel > 0) {
|
|
storageDiff = Number((currentLevel - lake.storageLevel).toFixed(2));
|
|
}
|
|
|
|
return {
|
|
id: lake.id,
|
|
name: lake.text.replace('VD ', '').split('-')[0].trim(),
|
|
river: lake.text.includes('-') ? lake.text.split('-')[1].trim() : '',
|
|
priority: lake.priority || false,
|
|
level: currentLevel.toFixed(2),
|
|
capacity: capacity,
|
|
storageDiff: storageDiff,
|
|
inflow: inflow.toFixed(1),
|
|
outflow: currentFlow.toFixed(1),
|
|
volume: volume,
|
|
maxVolume: lake.maxVolume || 0,
|
|
lat: lake.coords[0],
|
|
lng: lake.coords[1],
|
|
sparkline
|
|
};
|
|
});
|
|
|
|
const outputPath = path.resolve(process.cwd(), 'public/data/lakes_index.json');
|
|
fs.writeFileSync(outputPath, JSON.stringify(lakes, null, 2));
|
|
console.log('Real lakes index generated:', lakes.length);
|