diff --git a/src/static/dashboard.html b/src/static/dashboard.html
index bef0101..45551c3 100644
--- a/src/static/dashboard.html
+++ b/src/static/dashboard.html
@@ -1283,8 +1283,13 @@
grid.appendChild(cardEl);
});
const asOf = rows[0].as_of ? new Date(rows[0].as_of).toLocaleString([], { dateStyle: 'medium', timeStyle: 'short' }) : null;
+ const modelRow = rows.find((r) => r.source === 'model');
+ const trainedAt = modelRow?.trained_at ? new Date(modelRow.trained_at).toLocaleDateString([], { day: 'numeric', month: 'short' }) : null;
+ const modelInfo = modelRow?.model_version
+ ? ` · model ${modelRow.model_version}${trainedAt ? ` (trained ${trainedAt})` : ''}`
+ : '';
$('forecast-status').textContent = `Probability of exceeding warning / danger level within 6, 12 and 24 h` +
- (asOf ? ` · based on readings up to ${asOf}` : '');
+ (asOf ? ` · based on readings up to ${asOf}` : '') + modelInfo;
// Only the P.1 city outlook is shown by default; the per-station
// grid stays collapsed behind the expander.
const expand = $('forecast-expand');
@@ -1311,7 +1316,10 @@
$('db-total').textContent = Number(stats.total_measurements).toLocaleString();
if (stats.rid_measurements != null) {
const fmtNum = (value) => Number(value || 0).toLocaleString();
- $('db-total-note').textContent = `${fmtNum(stats.rid_measurements)} RID · ${fmtNum(stats.hii_waterlevel_measurements)} HII level · ${fmtNum(stats.hii_rainfall_measurements)} rain`;
+ const openmeteo = stats.openmeteo_rain_measurements
+ ? ` · ${fmtNum(stats.openmeteo_rain_measurements)} forecast rain`
+ : '';
+ $('db-total-note').textContent = `${fmtNum(stats.rid_measurements)} RID · ${fmtNum(stats.hii_waterlevel_measurements)} HII level · ${fmtNum(stats.hii_rainfall_measurements)} rain${openmeteo}`;
$('db-stations-note').textContent = `${stats.rid_station_count} RID · ${stats.hii_station_count} ThaiWater/HII`;
}
$('db-range').textContent = `${fmtDate(stats.first_timestamp)} – ${fmtDate(stats.last_timestamp)}`;
diff --git a/src/web_api.py b/src/web_api.py
index eae5dae..2060fe3 100644
--- a/src/web_api.py
+++ b/src/web_api.py
@@ -1222,6 +1222,22 @@ async def get_database_stats():
except Exception as e:
logger.warning(f"HII stats unavailable: {e}")
+ openmeteo_n = 0
+ try: # table appears with the 2026-08 rain work; older DBs lack it
+ engine = _hii_engine()
+ if engine is not None:
+ from sqlalchemy import text as _text
+
+ with engine.connect() as conn:
+ openmeteo_n = int(
+ conn.execute(
+ _text("SELECT COUNT(*) FROM openmeteo_rain")
+ ).scalar()
+ or 0
+ )
+ except Exception:
+ pass
+
def as_dt(value):
if isinstance(value, str):
return datetime.fromisoformat(value)
@@ -1241,11 +1257,15 @@ async def get_database_stats():
last_ts = hi
return {
- # Whole-DB totals (RID + HII feeds); breakdown fields alongside
- "total_measurements": stats["total_measurements"] + rain_n + wl_n,
+ # Whole-DB totals (RID + HII + Open-Meteo); breakdown alongside
+ "total_measurements": stats["total_measurements"]
+ + rain_n
+ + wl_n
+ + openmeteo_n,
"rid_measurements": stats["total_measurements"],
"hii_rainfall_measurements": rain_n,
"hii_waterlevel_measurements": wl_n,
+ "openmeteo_rain_measurements": openmeteo_n,
"station_count": stats["station_count"] + hii_stations,
"rid_station_count": stats["station_count"],
"hii_station_count": hii_stations,