feat: Add multi-source weather data collection and a web application for display.

This commit is contained in:
2569718930@qq.com
2026-03-04 17:11:20 +08:00
parent 6823559bf4
commit 0917f8d010
3 changed files with 56 additions and 35 deletions
+4
View File
@@ -445,6 +445,10 @@ def _analyze(city: str) -> Dict[str, Any]:
"status": peak_status,
},
"hourly": today_hourly,
"metar_today_obs": [
{"time": t, "temp": v}
for t, v in (metar.get("today_obs", []) if metar else [])
],
"ai_analysis": ai_text,
"updated_at": datetime.now(timezone.utc).isoformat(),
}
+17 -7
View File
@@ -476,15 +476,25 @@ function renderChart(data) {
curIdx < 0 || i >= curIdx ? t : null,
);
// METAR observation scatter points
// METAR observation scatter points — use full today's obs if available
const metarPoints = new Array(times.length).fill(null);
const metarRecent = data.trend?.recent || [];
if (metarRecent.length > 0) {
metarRecent.forEach((r) => {
// Match METAR time (e.g. "15:00") to chart time labels
const idx = times.indexOf(r.time);
const metarSrc = data.metar_today_obs?.length
? data.metar_today_obs
: data.trend?.recent || [];
if (metarSrc.length > 0) {
metarSrc.forEach((r) => {
// METAR time may be "14:20" but chart labels are whole hours "14:00"
const parts = r.time.split(":");
let h = parseInt(parts[0], 10);
const m = parseInt(parts[1] || "0", 10);
if (m >= 30) h = (h + 1) % 24; // round to nearest hour
const hourKey = h.toString().padStart(2, "0") + ":00";
const idx = times.indexOf(hourKey);
if (idx >= 0) {
metarPoints[idx] = r.temp;
// If multiple METARs map to the same hour, keep the latest (first in array)
if (metarPoints[idx] === null) {
metarPoints[idx] = r.temp;
}
}
});
}