diff --git a/README.md b/README.md
index 6722df1..2153992 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ npm run data:update
```
Tento příkaz provede dvě věci:
-1. `npm run scrape`: Otevře stránky povodí pro všech 12 přehrad, přečte tabulky s historickými měřeními a najde "Aktuální hodnoty", odkud vytáhne exaktní **přítok, objem, srážky a teplotu**. Tato data inteligentně sloučí s tvojí lokální databází (`public/data/*.json`). Pokud Povodí aktuálně počasí neposkytuje, skript zrecykluje tvou dřívější uloženou hodnotu, aby se graf "nerozbil".
+1. `npm run scrape`: Otevře stránky povodí pro všech **53 nádrží a říčních stanic**, přečte tabulky s historickými měřeními a najde "Aktuální hodnoty", odkud vytáhne exaktní **přítok, odtok, objem, srážky a teplotu**. Tato data inteligentně sloučí s tvojí lokální databází (`public/data/*.json`) a automaticky doplňuje chybějící hodnoty přítoku/objemu z minula, aby graf neměl výpadky k nule.
2. `npm run build-index`: Zaktualizuje hlavní indexový soubor `lakes_index.json`, který aplikace využívá pro vykreslení rychlých náhledů (např. v levém menu nebo na mapě).
---
@@ -56,17 +56,26 @@ Pokud ti běží počítač (nebo domácí server/Raspberry Pi) nepřetržitě,
### Možnost B: Pomocí GitHub Actions (Pro Produkci)
Až projekt nahraješ na GitHub, můžeš si vytvořit workflow soubor (např. `.github/workflows/scrape.yml`), který bude skript spouštět na serverech GitHubu zdarma každou hodinu, a výsledné `.json` soubory automaticky commitne a publikuje na web.
-### Možnost C: Jednoduchý integrovaný spouštěč (Nejlehčí)
-Pokud nechceš řešit složitý systémový crontab, napsal jsem pro tebe přímo do Node.js malý spouštěč. Stačí si otevřít další okno terminálu a napsat:
+### Možnost C: Jednoduchý integrovaný spouštěč (Doporučeno pro vývoj)
+Pokud nechceš řešit složitý systémový crontab, je v projektu připraven inteligentní plánovač. Stačí si otevřít další okno terminálu a napsat:
```bash
-npm run data:watch 10
+npm run data:watch
```
-Tento příkaz ihned provede první stažení a následně bude aplikaci automaticky aktualizovat **každých 10 minut** (číslo na konci si můžeš libovolně přepsat podle toho, jak často chceš stahovat). Skript poběží, dokud okno terminálu nezavřeš.
+Tento příkaz provede okamžitou aktualizaci a poté automaticky spouští stahování vždy 7 minut po každém 10minutovém kroku (např. 18:07, 18:17, 18:27...). Tento posun zaručuje, že Povodí už stihlo na svůj web nahrát nová data a nestahuješ staré hodnoty.
---
+## 🛠️ Oprava chyb v historii (Zuby / Nuly v grafu)
+
+Pokud ti aplikace delší dobu neběžela (např. při vypnutém počítači) a následně došlo k doplnění dat z historie, mohly se v grafech přítoku a objemu objevit falešné propady k nule (zuby). Pro vyčištění celé historie a dopočítání těchto bodů z posledních známých hodnot spusť:
+
+```bash
+npm run data:fix
+```
+Tento skript projde všechny datové JSON soubory, detekuje anomálie/nuly a opraví je.
+
## 📁 Struktura klíčových datových složek
-* `/scripts/lakesConfig.ts` - Tady najdeš definici všech 12 sledovaných přehrad (včetně jejich ID pro Povodí Vltavy, GPS souřadnic, maximálních objemů a stavebních kót). Sem můžeš přidávat nové přehrady.
+* `/scripts/lakesConfig.ts` - Tady najdeš definici všech **53 sledovaných nádrží a řek** (včetně jejich ID pro Povodí Vltavy, GPS souřadnic, maximálních objemů a stavebních kót). Sem můžeš přidávat nové stanice.
* `/public/data/` - Zde se ukládají vygenerovaná JSON data. V produkci musí být tyto soubory přístupné jako statické assety.
-* `/src/components/` - Obsahuje samotné vizuální karty, Leaflet mapu a detailní `LakeDetail.tsx` (kde se vykresluje hydrologický a meteorologický graf přes Recharts).
+* `/src/components/` - Obsahuje samotné vizuální karty, Leaflet mapu a detailní `LakeDetail.tsx` (kde se vykresluje hydrologický a meteorologický graf přes Recharts s automatickým čištěním chyb a senzorických úletů).
diff --git a/package.json b/package.json
index bfaf6ba..5ba5e87 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"build-index": "tsx scripts/buildIndex.ts",
"data:update": "npm run scrape && npm run build-index",
"data:watch": "tsx scripts/watchData.ts",
+ "data:fix": "tsx scripts/fix_lake_inflows.ts",
"test": "vitest run",
"test:watch": "vitest",
"coverage": "vitest run --coverage"
diff --git a/public/data/BEBE.json b/public/data/BEBE.json
index ba55352..b432063 100644
--- a/public/data/BEBE.json
+++ b/public/data/BEBE.json
@@ -2317,5 +2317,14 @@
"volume": 0,
"temperature": 26,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:10:00.000Z",
+ "level": 96,
+ "flow": 8.667,
+ "inflow": 0,
+ "volume": 0,
+ "temperature": 26,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/BEPL.json b/public/data/BEPL.json
index 6bd1b60..8f919de 100644
--- a/public/data/BEPL.json
+++ b/public/data/BEPL.json
@@ -2207,5 +2207,14 @@
"volume": 0,
"temperature": 25.5,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:30:00.000Z",
+ "level": 90,
+ "flow": 4.745,
+ "inflow": 0,
+ "volume": 0,
+ "temperature": 25.5,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/BIBI.json b/public/data/BIBI.json
index 6913ddc..1ac160e 100644
--- a/public/data/BIBI.json
+++ b/public/data/BIBI.json
@@ -8220,7 +8220,7 @@
"timestamp": "2026-06-08T17:30:00.000Z",
"level": 463.42,
"flow": 0,
- "inflow": 6.048207396473533,
+ "inflow": 0,
"volume": 0,
"temperature": 23.7,
"precipitation": 0
diff --git a/public/data/CPDR.json b/public/data/CPDR.json
index 9bcac08..8f5343d 100644
--- a/public/data/CPDR.json
+++ b/public/data/CPDR.json
@@ -8886,7 +8886,7 @@
"timestamp": "2026-06-08T17:30:00.000Z",
"level": 416.72,
"flow": 0,
- "inflow": 7.8121741402451015,
+ "inflow": 0,
"volume": 0.09,
"temperature": 23.8,
"precipitation": 0
diff --git a/public/data/CPZA.json b/public/data/CPZA.json
index fb4aa11..b5f4ab1 100644
--- a/public/data/CPZA.json
+++ b/public/data/CPZA.json
@@ -8859,7 +8859,7 @@
"timestamp": "2026-06-08T17:30:00.000Z",
"level": 448.81,
"flow": 0,
- "inflow": 4.662341665814382,
+ "inflow": 0,
"volume": 0.67,
"temperature": 23.8,
"precipitation": 0
diff --git a/public/data/CRSO.json b/public/data/CRSO.json
index 68f2d57..2b9cd86 100644
--- a/public/data/CRSO.json
+++ b/public/data/CRSO.json
@@ -8076,7 +8076,7 @@
"timestamp": "2026-06-08T17:00:00.000Z",
"level": 580.99,
"flow": 0,
- "inflow": 9.58165824042722,
+ "inflow": 0,
"volume": 0.03,
"temperature": 23,
"precipitation": 0
diff --git a/public/data/HEVR.json b/public/data/HEVR.json
index 1b7cf33..8a2b6b8 100644
--- a/public/data/HEVR.json
+++ b/public/data/HEVR.json
@@ -8939,7 +8939,7 @@
{
"timestamp": "2026-06-08T17:10:00.000Z",
"level": 407.64,
- "flow": 0,
+ "flow": 0.2,
"inflow": 0.4,
"volume": 0.14,
"temperature": 23,
@@ -8953,5 +8953,14 @@
"volume": 0.14,
"temperature": 22.3,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:30:00.000Z",
+ "level": 407.64,
+ "flow": 0,
+ "inflow": 0.4,
+ "volume": 0.14,
+ "temperature": 22.3,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/KLDP.json b/public/data/KLDP.json
index f4f7509..e201093 100644
--- a/public/data/KLDP.json
+++ b/public/data/KLDP.json
@@ -8202,7 +8202,7 @@
"timestamp": "2026-06-08T17:00:00.000Z",
"level": 632.76,
"flow": 0,
- "inflow": 10.515147444523139,
+ "inflow": 0,
"volume": 0,
"temperature": 21.7,
"precipitation": 0
diff --git a/public/data/KLHP.json b/public/data/KLHP.json
index c874f6a..0a869a8 100644
--- a/public/data/KLHP.json
+++ b/public/data/KLHP.json
@@ -8202,7 +8202,7 @@
"timestamp": "2026-06-08T17:00:00.000Z",
"level": 635.7,
"flow": 0,
- "inflow": 5.418107522688602,
+ "inflow": 0,
"volume": 0,
"temperature": 22,
"precipitation": 0
diff --git a/public/data/LUBE.json b/public/data/LUBE.json
index 973d021..1c26713 100644
--- a/public/data/LUBE.json
+++ b/public/data/LUBE.json
@@ -2245,5 +2245,14 @@
"volume": 0,
"temperature": 24,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:30:00.000Z",
+ "level": 82,
+ "flow": 2.666,
+ "inflow": 0,
+ "volume": 0,
+ "temperature": 24,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/OPOB.json b/public/data/OPOB.json
index 7a34ca6..657b33a 100644
--- a/public/data/OPOB.json
+++ b/public/data/OPOB.json
@@ -8751,7 +8751,7 @@
"timestamp": "2026-06-08T17:20:00.000Z",
"level": 563.66,
"flow": 0.02,
- "inflow": 0.01,
+ "inflow": 0,
"volume": 0.46,
"temperature": 22.3,
"precipitation": 0
diff --git a/public/data/OTPI.json b/public/data/OTPI.json
index b99f54a..51584db 100644
--- a/public/data/OTPI.json
+++ b/public/data/OTPI.json
@@ -2252,5 +2252,14 @@
"volume": 0,
"temperature": 24.9,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:30:00.000Z",
+ "level": 43,
+ "flow": 4.73,
+ "inflow": 0,
+ "volume": 0,
+ "temperature": 24.9,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/OTSU.json b/public/data/OTSU.json
index 40abf75..3d9ff0e 100644
--- a/public/data/OTSU.json
+++ b/public/data/OTSU.json
@@ -2317,5 +2317,14 @@
"volume": 0,
"temperature": 23,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:10:00.000Z",
+ "level": 25,
+ "flow": 2.95,
+ "inflow": 0,
+ "volume": 0,
+ "temperature": 23,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/PPPI.json b/public/data/PPPI.json
index 3874fcd..07fe164 100644
--- a/public/data/PPPI.json
+++ b/public/data/PPPI.json
@@ -8103,7 +8103,7 @@
"timestamp": "2026-06-08T16:20:00.000Z",
"level": 670.52,
"flow": 0,
- "inflow": 8.227779864526358,
+ "inflow": 0,
"volume": 0,
"temperature": 21.8,
"precipitation": 0
diff --git a/public/data/SAPI.json b/public/data/SAPI.json
index 0574112..9cd198e 100644
--- a/public/data/SAPI.json
+++ b/public/data/SAPI.json
@@ -8922,7 +8922,7 @@
"timestamp": "2026-06-08T17:30:00.000Z",
"level": 575.7,
"flow": 0.02,
- "inflow": 11.662041143485649,
+ "inflow": 0,
"volume": 1.06,
"temperature": 21.4,
"precipitation": 0
diff --git a/public/data/SAZR.json b/public/data/SAZR.json
index f9ba61b..73fae6c 100644
--- a/public/data/SAZR.json
+++ b/public/data/SAZR.json
@@ -2270,5 +2270,14 @@
"volume": 0,
"temperature": 24,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:10:00.000Z",
+ "level": 68,
+ "flow": 1.452,
+ "inflow": 0,
+ "volume": 0,
+ "temperature": 24,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/SCHU.json b/public/data/SCHU.json
index 96d5321..e65ecee 100644
--- a/public/data/SCHU.json
+++ b/public/data/SCHU.json
@@ -8926,5 +8926,14 @@
"volume": 0.1,
"temperature": 23.6,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:30:00.000Z",
+ "level": 0,
+ "flow": 0.06,
+ "inflow": 0.07,
+ "volume": 0.1,
+ "temperature": 23.6,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/SPKA.json b/public/data/SPKA.json
index 1fe7734..9bf09f3 100644
--- a/public/data/SPKA.json
+++ b/public/data/SPKA.json
@@ -8913,7 +8913,7 @@
"timestamp": "2026-06-08T17:20:00.000Z",
"level": 668.4,
"flow": 0,
- "inflow": 10.98258553088203,
+ "inflow": 0,
"volume": 0.39,
"temperature": 23.8,
"precipitation": 0
diff --git a/public/data/SPNE.json b/public/data/SPNE.json
index 64b2ec0..70d7b51 100644
--- a/public/data/SPNE.json
+++ b/public/data/SPNE.json
@@ -8634,7 +8634,7 @@
"timestamp": "2026-06-08T17:20:00.000Z",
"level": 385.01,
"flow": 0.02,
- "inflow": 6.257864375579982,
+ "inflow": 0,
"volume": 0.84,
"temperature": 22.5,
"precipitation": 0
diff --git a/public/data/SPZH.json b/public/data/SPZH.json
index 63c1db0..9fc4920 100644
--- a/public/data/SPZH.json
+++ b/public/data/SPZH.json
@@ -8904,7 +8904,7 @@
"timestamp": "2026-06-08T17:20:00.000Z",
"level": 678.6,
"flow": 0,
- "inflow": 8.204576504122992,
+ "inflow": 0,
"volume": 0.16,
"temperature": 20.6,
"precipitation": 0
diff --git a/public/data/STST.json b/public/data/STST.json
index 8f6ec22..d633880 100644
--- a/public/data/STST.json
+++ b/public/data/STST.json
@@ -8958,7 +8958,7 @@
"timestamp": "2026-06-08T17:20:00.000Z",
"level": 588.39,
"flow": 0.08,
- "inflow": 8.36186446216757,
+ "inflow": 0,
"volume": 0.32,
"temperature": 23,
"precipitation": 0
diff --git a/public/data/SVSV.json b/public/data/SVSV.json
index 91e247f..e23c781 100644
--- a/public/data/SVSV.json
+++ b/public/data/SVSV.json
@@ -8913,7 +8913,7 @@
"timestamp": "2026-06-08T17:30:00.000Z",
"level": 0,
"flow": 0.05,
- "inflow": 8.055084527934373,
+ "inflow": 0,
"volume": 0.41,
"temperature": 21.4,
"precipitation": 0
diff --git a/public/data/VLCH.json b/public/data/VLCH.json
index 082942a..db62b15 100644
--- a/public/data/VLCH.json
+++ b/public/data/VLCH.json
@@ -2243,5 +2243,14 @@
"volume": 0,
"temperature": 26.1,
"precipitation": 0
+ },
+ {
+ "timestamp": "2026-06-08T17:30:00.000Z",
+ "level": 46,
+ "flow": 53.88,
+ "inflow": 0,
+ "volume": 0,
+ "temperature": 26.1,
+ "precipitation": 0
}
]
\ No newline at end of file
diff --git a/public/data/VLHN.json b/public/data/VLHN.json
index 1ce7cc5..5c55457 100644
--- a/public/data/VLHN.json
+++ b/public/data/VLHN.json
@@ -9219,7 +9219,7 @@
"timestamp": "2026-06-08T17:20:00.000Z",
"level": 369.61,
"flow": 15.18,
- "inflow": 11.42,
+ "inflow": 0,
"volume": 19.77,
"temperature": 24.4,
"precipitation": 0
diff --git a/public/data/lakes_index.json b/public/data/lakes_index.json
index 333d336..71186aa 100644
--- a/public/data/lakes_index.json
+++ b/public/data/lakes_index.json
@@ -69,7 +69,7 @@
"level": "369.61",
"capacity": 93.7,
"storageDiff": -0.49,
- "inflow": "11.4",
+ "inflow": "0.0",
"outflow": "15.2",
"volume": 19.77,
"maxVolume": 21.1,
@@ -658,7 +658,7 @@
"level": "670.52",
"capacity": 80.2,
"storageDiff": -0.88,
- "inflow": "8.2",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 1.3,
"maxVolume": 1.6,
@@ -751,7 +751,7 @@
"level": "588.39",
"capacity": 32,
"storageDiff": -0.21,
- "inflow": "8.4",
+ "inflow": "0.0",
"outflow": "0.1",
"volume": 0.32,
"maxVolume": 1,
@@ -813,7 +813,7 @@
"level": "580.99",
"capacity": 2.1,
"storageDiff": -1.22,
- "inflow": "9.6",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0.03,
"maxVolume": 1.4,
@@ -841,9 +841,9 @@
"name": "Humenice",
"river": "",
"priority": false,
- "level": "534.70",
+ "level": "0.00",
"capacity": 12.5,
- "storageDiff": -1.3,
+ "storageDiff": 0,
"inflow": "0.1",
"outflow": "0.1",
"volume": 0.1,
@@ -852,7 +852,6 @@
"lat": 48.784,
"lng": 14.735,
"sparkline": [
- 534.69,
534.69,
0,
534.69,
@@ -863,7 +862,8 @@
0,
534.69,
534.69,
- 534.7
+ 534.7,
+ 0
],
"type": "lake"
},
@@ -875,7 +875,7 @@
"level": "0.00",
"capacity": 34.2,
"storageDiff": 0,
- "inflow": "8.1",
+ "inflow": "0.0",
"outflow": "0.1",
"volume": 0.41,
"maxVolume": 1.2,
@@ -906,7 +906,7 @@
"level": "575.70",
"capacity": 70.7,
"storageDiff": -0.9,
- "inflow": "11.7",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 1.06,
"maxVolume": 1.5,
@@ -968,7 +968,7 @@
"level": "448.81",
"capacity": 100,
"storageDiff": 0.02,
- "inflow": "4.7",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0.67,
"maxVolume": 0.5,
@@ -999,7 +999,7 @@
"level": "463.42",
"capacity": 4.6,
"storageDiff": -0.61,
- "inflow": "6.0",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0,
"maxVolume": 0.3,
@@ -1030,7 +1030,7 @@
"level": "668.40",
"capacity": 100,
"storageDiff": 0,
- "inflow": "11.0",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0.39,
"maxVolume": 0.3,
@@ -1061,7 +1061,7 @@
"level": "385.01",
"capacity": 100,
"storageDiff": 0.01,
- "inflow": "6.3",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0.84,
"maxVolume": 0.4,
@@ -1092,7 +1092,7 @@
"level": "678.60",
"capacity": 80,
"storageDiff": 0,
- "inflow": "8.2",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0.16,
"maxVolume": 0.2,
@@ -1123,7 +1123,7 @@
"level": "632.76",
"capacity": 4.4,
"storageDiff": -0.13,
- "inflow": "10.5",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0,
"maxVolume": 0.5,
@@ -1154,7 +1154,7 @@
"level": "635.70",
"capacity": 0,
"storageDiff": -0.66,
- "inflow": "5.4",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0,
"maxVolume": 0.7,
@@ -1185,7 +1185,7 @@
"level": "416.72",
"capacity": 90,
"storageDiff": 0.04,
- "inflow": "7.8",
+ "inflow": "0.0",
"outflow": "0.0",
"volume": 0.09,
"maxVolume": 0.1,
@@ -1213,18 +1213,17 @@
"name": "Praha - Malá Chuchle",
"river": "Vltava",
"priority": false,
- "level": "49.00",
+ "level": "46.00",
"capacity": 0,
"storageDiff": 0,
"inflow": "0.0",
- "outflow": "60.9",
+ "outflow": "53.9",
"volume": 0,
"maxVolume": 0,
"navigationForbidden": false,
"lat": 50.0294,
"lng": 14.3986,
"sparkline": [
- 45,
46,
46,
47,
@@ -1235,7 +1234,8 @@
47,
47,
46,
- 49
+ 49,
+ 46
],
"type": "river"
},
@@ -1279,14 +1279,13 @@
"capacity": 0,
"storageDiff": 0,
"inflow": "0.0",
- "outflow": "8.6",
+ "outflow": "8.7",
"volume": 0,
"maxVolume": 0,
"navigationForbidden": false,
"lat": 49.9642,
"lng": 14.0792,
"sparkline": [
- 100,
100,
99,
99,
@@ -1297,6 +1296,7 @@
96,
96,
96,
+ 96,
96
],
"type": "river"
@@ -1341,14 +1341,13 @@
"capacity": 0,
"storageDiff": 0,
"inflow": "0.0",
- "outflow": "4.8",
+ "outflow": "4.7",
"volume": 0,
"maxVolume": 0,
"navigationForbidden": false,
"lat": 49.3083,
"lng": 14.1436,
"sparkline": [
- 41,
44,
45,
45,
@@ -1359,6 +1358,7 @@
45,
45,
44,
+ 43,
43
],
"type": "river"
@@ -1383,9 +1383,9 @@
25,
25,
25,
+ 26,
+ 26,
25,
- 26,
- 26,
25,
25,
25,
@@ -1399,18 +1399,17 @@
"name": "Bechyně",
"river": "Lužnice",
"priority": false,
- "level": "81.00",
+ "level": "82.00",
"capacity": 0,
"storageDiff": 0,
"inflow": "0.0",
- "outflow": "2.6",
+ "outflow": "2.7",
"volume": 0,
"maxVolume": 0,
"navigationForbidden": false,
"lat": 49.2931,
"lng": 14.4758,
"sparkline": [
- 82,
80,
79,
82,
@@ -1421,7 +1420,8 @@
85,
84,
83,
- 81
+ 81,
+ 82
],
"type": "river"
},
@@ -1589,7 +1589,7 @@
"capacity": 0,
"storageDiff": 0,
"inflow": "0.0",
- "outflow": "4.6",
+ "outflow": "4.7",
"volume": 0,
"maxVolume": 0,
"navigationForbidden": false,
@@ -1603,10 +1603,10 @@
87,
87,
87,
- 87,
88,
89,
89,
+ 90,
90
],
"type": "river"
diff --git a/src/components/LakeDetail.tsx b/src/components/LakeDetail.tsx
index 9768cfa..138b52f 100644
--- a/src/components/LakeDetail.tsx
+++ b/src/components/LakeDetail.tsx
@@ -121,12 +121,34 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
.catch(err => console.error(err));
const internalId = lakeId ? lakeId.split('|')[0] : 'VLL1';
+ const staticConfig = lakesConfig.find(l => l.id.split('|')[0] === internalId);
fetch(`/data/${internalId}.json?t=${Date.now()}`)
.then(res => res.json())
.then(json => {
+ let lastValidLevel: number | null = null;
const formattedData = json.map((item: any) => {
const outflow = item.flow === null || isNaN(item.flow) ? 0 : item.flow;
+ let level = item.level === null || isNaN(item.level) ? 0 : item.level;
+
+ // Outlier/sensor glitch detection
+ if (level > 0) {
+ if (staticConfig && staticConfig.minLevel && staticConfig.maxLevel) {
+ const minAllowed = staticConfig.minLevel - 5;
+ const maxAllowed = staticConfig.maxLevel + 5;
+ if (level < minAllowed || level > maxAllowed) {
+ // Glitch detected, fallback to last known valid level
+ level = lastValidLevel !== null ? lastValidLevel : (staticConfig.minLevel + staticConfig.maxLevel) / 2;
+ } else {
+ lastValidLevel = level;
+ }
+ } else {
+ lastValidLevel = level;
+ }
+ } else if (lastValidLevel !== null) {
+ // Level is 0 or less, fallback
+ level = lastValidLevel;
+ }
return {
timestamp: item.timestamp,
@@ -134,7 +156,7 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
day: '2-digit', month: '2-digit', year: 'numeric',
hour: '2-digit', minute: '2-digit'
}),
- level: item.level === null || isNaN(item.level) ? 0 : item.level,
+ level: level,
outflow: outflow,
inflow: item.inflow || 0,
volume: item.volume || 0,
@@ -393,13 +415,58 @@ const LakeDetail = ({ language, lakeId, windUnit = 'kmh' }: Props) => {
{/* Data Series */}
{limits && limits.map((limit, idx) => (
-
+
))}
- {!isRiver && staticConfig?.maxLevel && (
-
- )}
- {!isRiver && staticConfig?.storageLevel && (
-
+ {!isRiver && staticConfig?.maxLevel && staticConfig?.storageLevel && Math.abs(staticConfig.maxLevel - staticConfig.storageLevel) < 0.05 ? (
+
+ ) : (
+ <>
+ {!isRiver && staticConfig?.maxLevel && (
+
+ )}
+ {!isRiver && staticConfig?.storageLevel && (
+
+ )}
+ >
)}