Store HKO intraday observations in runtime state

This commit is contained in:
2569718930@qq.com
2026-03-23 21:28:04 +08:00
parent b1102400f6
commit fcaa9d5c7f
2 changed files with 115 additions and 44 deletions
+88
View File
@@ -132,6 +132,22 @@ class RuntimeStateDB:
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_open_meteo_cache_expires ON open_meteo_cache_store(source_kind, expires_at)"
)
conn.execute(
"""
CREATE TABLE IF NOT EXISTS official_intraday_observations_store (
source_code TEXT NOT NULL,
station_code TEXT NOT NULL,
target_date TEXT NOT NULL,
observation_time TEXT NOT NULL,
value REAL NOT NULL,
payload_json TEXT,
PRIMARY KEY (source_code, station_code, observation_time)
)
"""
)
conn.execute(
"CREATE INDEX IF NOT EXISTS idx_official_intraday_obs_station_date ON official_intraday_observations_store(source_code, station_code, target_date, observation_time)"
)
conn.commit()
@@ -466,6 +482,78 @@ class OpenMeteoCacheRepository:
return 0.0
class OfficialIntradayObservationRepository:
def __init__(self, db: Optional[RuntimeStateDB] = None):
self.db = db or RuntimeStateDB.instance()
def upsert_point(
self,
*,
source_code: str,
station_code: str,
target_date: str,
observation_time: str,
value: float,
payload: Optional[Dict[str, Any]] = None,
) -> None:
payload_json = json.dumps(payload, ensure_ascii=False) if payload is not None else None
with self.db.connect() as conn:
conn.execute(
"""
INSERT INTO official_intraday_observations_store (
source_code, station_code, target_date, observation_time, value, payload_json
) VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(source_code, station_code, observation_time) DO UPDATE SET
target_date = excluded.target_date,
value = excluded.value,
payload_json = excluded.payload_json
""",
(
source_code,
station_code,
target_date,
observation_time,
float(value),
payload_json,
),
)
conn.commit()
def load_points(
self,
*,
source_code: str,
station_code: str,
target_date: str,
) -> List[Dict[str, Any]]:
with self.db.connect() as conn:
rows = conn.execute(
"""
SELECT observation_time, value, payload_json
FROM official_intraday_observations_store
WHERE source_code = ? AND station_code = ? AND target_date = ?
ORDER BY observation_time
""",
(source_code, station_code, target_date),
).fetchall()
out: List[Dict[str, Any]] = []
for row in rows:
point = {
"time": str(row["observation_time"] or "").strip(),
"temp": float(row["value"]),
}
if row["payload_json"]:
try:
payload = json.loads(row["payload_json"])
except Exception:
payload = None
if isinstance(payload, dict):
point.update(payload)
if point["time"]:
out.append(point)
return out
def _top_bucket(snapshot: Optional[List[Dict[str, Any]]]) -> Optional[int]:
best_value = None
best_prob = -1.0