feat: dashboard shows the live model version; DB stats count openmeteo_rain
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 24s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Integration Test with Services (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 15s
Documentation / Generate API Documentation (push) Successful in 9s
Documentation / Documentation Summary (push) Successful in 2s
Documentation / Validate Documentation (push) Failing after 7s
Documentation / Build Sphinx Documentation (push) Successful in 15s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 1s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 24s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Build Docker Image (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Integration Test with Services (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Staging (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Deploy to Production (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Performance Test (push) Skipped
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Successful in 15s
Documentation / Generate API Documentation (push) Successful in 9s
Documentation / Documentation Summary (push) Successful in 2s
Documentation / Validate Documentation (push) Failing after 7s
Documentation / Build Sphinx Documentation (push) Successful in 15s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 1s
The flood-outlook subtitle now reads '... · model hgb-v3+<sha> (trained <date>)' from the forecast rows, so the deployed model is always visible on the page. /api/stats adds openmeteo_rain_measurements (guarded — the table may not exist on older DBs) to the whole-DB total, and the Total-datapoints tile note gains a 'forecast rain' entry.
This commit is contained in:
@@ -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)}`;
|
||||
|
||||
+22
-2
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user