feat: add multiple weather data source scrapers and integrate dashboard temperature chart logic components

This commit is contained in:
2569718930@qq.com
2026-05-27 09:31:24 +08:00
parent 05010d20e2
commit e6a673e27d
12 changed files with 327 additions and 49 deletions
@@ -601,6 +601,38 @@ export function runTests() {
"AMOS runway_obs patch should use the runway temperature, not ignore the SR/SL point",
);
const busanSnapshotWithLocalAndUtc = __buildTemperatureChartDataForTest(
{
city: "busan",
local_date: "2026-05-27",
local_time: "09:58",
tz_offset_seconds: 9 * 60 * 60,
temp_symbol: "°C",
} as any,
{
localTime: "09:58",
times: ["00:00", "12:00", "18:00", "23:00"],
temps: [19.6, 21.1, 20.0, 19.0],
amos: {
source: "amos",
observation_time: "2026-05-27T00:58:00Z",
observation_time_local: "2026-05-27 09:58:00",
runway_obs: {
runway_pairs: [["S R", "S L"]],
temperatures: [[21.5, 12.4]],
},
},
} as any,
"1D",
);
const busanSnapshotLabels = busanSnapshotWithLocalAndUtc.data
.filter((point: any) => point[runwayKey("SR/SL")] === 21.5)
.map((point: any) => point.label);
assert(
busanSnapshotLabels.includes("09:58:00"),
"AMOS snapshot fallback should prefer UTC observation_time over naive observation_time_local for chart positioning",
);
const busanCurrentOnly = __buildTemperatureChartDataForTest(
{
city: "busan",
@@ -0,0 +1,51 @@
import { __buildTemperatureTooltipRowsForTest } from "@/components/dashboard/scan-terminal/TemperatureTooltipContent";
function assert(condition: unknown, message: string) {
if (!condition) throw new Error(message);
}
export function runTests() {
const data = [
{
ts: Date.UTC(2026, 4, 27, 9, 10),
label: "09:10:00",
runway_35R_17L: 26,
gfs: 24.2,
deb: null,
},
{
ts: Date.UTC(2026, 4, 27, 14, 0),
label: "14:00:00",
runway_35R_17L: null,
gfs: null,
deb: 26.7,
},
{
ts: Date.UTC(2026, 4, 27, 19, 0),
label: "19:00:00",
runway_35R_17L: null,
gfs: 24.8,
deb: 23.5,
},
];
const series = [
{ key: "runway_35R_17L", label: "35R/17L 结算跑道", color: "#009688" },
{ key: "gfs", label: "GFS", color: "#10b981" },
{ key: "deb", label: "DEB Forecast", color: "#f97316" },
];
const rows = __buildTemperatureTooltipRowsForTest(data[1], data, series);
assert(
!rows.some((row) => row.key === "runway_35R_17L"),
"runway tooltip rows should not use nearest-value fallback when the active x slot has no runway value",
);
assert(
rows.some((row) => row.key === "deb" && row.value === 26.7),
"tooltip should still show direct values at the active x slot",
);
assert(
rows.some((row) => row.key === "gfs" && row.value === 24.2),
"non-runway sparse series should keep nearest-value fallback",
);
}