feat: rainfall + HII water-level layers on the dashboard
Documentation / Build Sphinx Documentation (push) Successful in 1m3s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 1m4s
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
Documentation / Generate API Documentation (push) Successful in 23s
Documentation / Validate Documentation (push) Failing after 18s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 1s
Documentation / Documentation Summary (push) Successful in 3s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Failing after 11m16s
Documentation / Build Sphinx Documentation (push) Successful in 1m3s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Test Suite (3.11) (push) Failing after 1m4s
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
Documentation / Generate API Documentation (push) Successful in 23s
Documentation / Validate Documentation (push) Failing after 18s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Cleanup (push) Successful in 1s
Documentation / Documentation Summary (push) Successful in 3s
CI/CD Pipeline - Northern Thailand Ping River Monitor / Code Quality (push) Failing after 11m16s
New endpoints GET /api/hii/rainfall/latest and /api/hii/waterlevel/latest serve the latest per-station rows from the hii_* tables. The map gains a TWA-style rain layer: circle markers binned by TMD 24-h classes (blues for light/moderate/heavy, site amber/red for very-heavy/extreme), with a legend block and show/hide toggle. The ThaiWater sensor panel now prefers the DB-backed HII feed (no API key required, 97+ stations, ThaiWater storage-percent situation colors, gauge-datum conversion via offset_msl) and falls back to the live /sensors/thaiwater passthrough.
This commit is contained in:
@@ -275,6 +275,58 @@ class TestParseGraphRows:
|
||||
assert parse_graph_rows({}) == []
|
||||
|
||||
|
||||
class TestHiiApiEndpoints:
|
||||
"""Call the endpoint coroutines directly (the venv's httpx/starlette
|
||||
combination is incompatible with TestClient)."""
|
||||
|
||||
@pytest.fixture
|
||||
def web_api(self, tmp_path, monkeypatch):
|
||||
from src import web_api
|
||||
from src.hii_collector import HiiCollector
|
||||
|
||||
collector = HiiCollector(
|
||||
{"type": "sqlite", "connection_string": f"sqlite:///{tmp_path}/api.db"}
|
||||
)
|
||||
now = datetime.datetime.now().replace(microsecond=0)
|
||||
rain = parse_rain_records(_rain_payload())
|
||||
wl = parse_waterlevel_records(_waterlevel_payload())
|
||||
for record in rain + wl:
|
||||
record["timestamp"] = now
|
||||
assert collector.store.save_rain(rain) == 1
|
||||
assert collector.store.save_waterlevel(wl) == 2
|
||||
monkeypatch.setitem(web_api.app_state, "hii_collector", collector)
|
||||
return web_api
|
||||
|
||||
def test_rainfall_latest(self, web_api):
|
||||
import asyncio
|
||||
|
||||
rows = asyncio.run(web_api.get_hii_rainfall_latest(hours=26))
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["oldcode"] == "CHM005"
|
||||
assert rows[0]["rain_24h"] == 49.6
|
||||
assert rows[0]["latitude"] == pytest.approx(19.12207)
|
||||
|
||||
def test_waterlevel_latest(self, web_api):
|
||||
import asyncio
|
||||
|
||||
rows = asyncio.run(web_api.get_hii_waterlevel_latest(hours=26))
|
||||
assert len(rows) == 2
|
||||
p1 = next(r for r in rows if r["oldcode"] == "P.1")
|
||||
assert p1["rid_code"] == "P.1"
|
||||
assert p1["wl_msl"] == 303.27
|
||||
assert p1["offset_msl"] == 300.5
|
||||
assert p1["situation_level"] == 4
|
||||
|
||||
def test_empty_when_collector_disabled(self, monkeypatch):
|
||||
import asyncio
|
||||
|
||||
from src import web_api
|
||||
|
||||
monkeypatch.setitem(web_api.app_state, "hii_collector", None)
|
||||
assert asyncio.run(web_api.get_hii_rainfall_latest(hours=26)) == []
|
||||
assert asyncio.run(web_api.get_hii_waterlevel_latest(hours=26)) == []
|
||||
|
||||
|
||||
class TestBackfillHelpers:
|
||||
def test_chunk_date_range(self):
|
||||
chunks = chunk_date_range(
|
||||
|
||||
Reference in New Issue
Block a user