Save up to 17% with yearly billing

See pricing

Auf der Strecke

Lauffähige Beispiele für Wetter auf der Strecke (En-Route) innerhalb eines geografischen Begrenzungsrahmens (Bounding Box): Höhenwinde, PIREPs und AIRMET/SIGMET. Für Abläufe mit METAR/TAF am Flughafen siehe Am Flughafen.

#FrageVerwendete Daten
7Reiseflugwind auf FL180 nahe dem Abflug in KJFK (regionale US-Bbox)?Höhenwinde
8Gibt es dringende Pilotenmeldungen (UUA) entlang der Route in den letzten 3 Stunden?PIREPs
9Aktive AIRMET-Polygone, die die Bbox der Route schneiden?AIRMET/SIGMET

Voraussetzungen

Auth
x-api-key bei jeder Anfrage (Direktabonnement). Mehr erfahren →

Installation

Die folgenden Skripte verwenden requests für API-Aufrufe und rich für die Terminalausgabe. Einmalig installieren:

pip install requests rich

7. Reiseflugwind auf FL180 (Höhenwinde)

Frage: Welche Höhenwind-Stufe liegt nahe dem Abflug in KJFK am nächsten an FL180?

Höhenwinde sind nur für die USA verfügbar. Fragen Sie bei langen Routen regionale Bboxes entlang des US-Abschnitts ab (eine Box von Küste zu Küste ist langsam und führt oft zu 503). Im Folgenden: eine enge Box rund um New York.

import os

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"

# Regional box around KJFK - reliable for FB Winds (US only)
NYC_BBOX = "38,-76,42,-71"
TARGET_ALT_FT = 18_000


def fetch_winds_aloft(bbox: str, forecast: int = 12) -> dict | None:
    r = requests.get(
        f"{BASE}/weather/winds-aloft",
        headers=HEADERS,
        params={"bbox": bbox, "forecast": forecast, "level": "low"},
        timeout=(10, 20),
    )
    if r.status_code in (404, 503):
        return None
    r.raise_for_status()
    return r.json()


def print_cruise_wind(bbox: str, label: str, target_ft: int = TARGET_ALT_FT) -> None:
    data = fetch_winds_aloft(bbox)
    if not data:
        console.print("[yellow]Winds aloft unavailable or no stations - retry or widen bbox.[/]")
        return
    if not data.get("stations"):
        console.print("[yellow]No FB winds stations in this bbox.[/]")
        return

    station = data["stations"][0]
    levels = station.get("winds") or []
    if not levels:
        console.print(f"[yellow]Station {station['station']} returned no wind levels.[/]")
        return

    best = min(levels, key=lambda w: abs(w["altitude_ft"] - target_ft))
    table = Table(title=f"Cruise wind near FL{target_ft // 100} - {label}")
    table.add_column("Field", style="cyan")
    table.add_column("Value", justify="right")
    table.add_row("Bbox", bbox)
    table.add_row("Station", station["station"])
    table.add_row("Level used", f"{best['altitude_ft']} ft MSL")
    table.add_row("Direction", f"{best.get('wind_direction') or '-'}° true")
    table.add_row("Speed", f"{best.get('wind_speed_kt') or '-'} kt")
    temp = best.get("temperature_c")
    table.add_row("Temperature", f"{temp} °C" if temp is not None else "not reported")
    table.add_row("Valid time", data.get("valid_time") or "-")
    console.print(table)


if __name__ == "__main__":
    print_cruise_wind(NYC_BBOX, "KJFK departure area")

Ausgabe: Tabelle mit der Windstufe, die Ihrer Zielhöhe am nächsten liegt, von der ersten Station in der Bbox.


8. Dringende PIREPs entlang der Route

Frage: Wurden in den letzten 3 Stunden in der Bbox der Route UUA-Pilotenmeldungen (dringend) abgegeben?

PIREPs sind selten — eine leere Liste ist üblich. Wenn Meldungen vorhanden sind, zeigen Sie UUA vor routinemäßigen UA-Meldungen an.

import os

import requests
from rich.console import Console
from rich.panel import Panel

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"

KJFK = (40.6413, -73.7781)
KLAX = (33.9425, -118.4081)


def route_bbox(dep, arr, pad_deg: float = 2.0) -> str:
    dep_lat, dep_lon = dep
    arr_lat, arr_lon = arr
    return (
        f"{min(dep_lat, arr_lat) - pad_deg},{min(dep_lon, arr_lon) - pad_deg},"
        f"{max(dep_lat, arr_lat) + pad_deg},{max(dep_lon, arr_lon) + pad_deg}"
    )


def fetch_pireps(bbox: str, hours: int = 3) -> dict:
    r = requests.get(
        f"{BASE}/weather/pireps",
        headers=HEADERS,
        params={"bbox": bbox, "hours": hours},
        timeout=(10, 20),
    )
    r.raise_for_status()
    return r.json()


def print_urgent_pireps(dep, arr) -> None:
    bbox = route_bbox(dep, arr)
    data = fetch_pireps(bbox, hours=3)
    reports = data.get("reports") or []
    urgent = [r for r in reports if r.get("report_type") == "UUA"]
    routine = [r for r in reports if r.get("report_type") != "UUA"]

    if not reports:
        console.print(Panel(
            f"No PIREPs in bbox {bbox} (last 3 h).\n"
            "This is normal on quiet routes - not an error.",
            title="PIREPs - none filed",
            style="blue",
        ))
        return

    lines = []
    for r in urgent + routine[:5]:
        tag = "[red]UUA[/]" if r.get("report_type") == "UUA" else "UA"
        turb = r.get("turbulence") or "-"
        icing = r.get("icing") or "-"
        lines.append(f"{tag} {r.get('location') or '?'} @ {r.get('altitude') or '?'} - turb: {turb}, ice: {icing}")

    console.print(Panel(
        "\n".join(lines),
        title=f"PIREPs in route bbox ({data['total']} total, {len(urgent)} urgent)",
    ))


if __name__ == "__main__":
    print_urgent_pireps(KJFK, KLAX)

Ausgabe: Panel, das zuerst dringende PIREPs und danach bis zu fünf Routinemeldungen auflistet — oder eine eindeutige Meldung „keine abgegeben“.


9. Aktive AIRMETs auf der Route

Frage: Schneiden derzeit AIRMET-Warnungen die Bbox der Route?

Verwenden Sie type=airmet für Bulletins zu IFR, Turbulenz und Vereisung, wie sie in der Flugdienstberatung (Dispatch) genutzt werden. Zeichnen Sie observation.coords auf einer Karte ein, sofern vorhanden.

import os

import requests
from rich.console import Console
from rich.table import Table

console = Console()

HEADERS = {
    "X-RapidAPI-Key": os.getenv("RAPIDAPI_KEY", "YOUR_RAPIDAPI_KEY"),
    "X-RapidAPI-Host": "skylink-api.p.rapidapi.com",
}
BASE = "https://skylink-api.p.rapidapi.com"

KJFK = (40.6413, -73.7781)
KLAX = (33.9425, -118.4081)


def route_bbox(dep, arr, pad_deg: float = 2.0) -> str:
    dep_lat, dep_lon = dep
    arr_lat, arr_lon = arr
    return (
        f"{min(dep_lat, arr_lat) - pad_deg},{min(dep_lon, arr_lon) - pad_deg},"
        f"{max(dep_lat, arr_lat) + pad_deg},{max(dep_lon, arr_lon) + pad_deg}"
    )


def fetch_airsigmets(bbox: str, advisory_type: str = "airmet") -> dict:
    r = requests.get(
        f"{BASE}/weather/airsigmet",
        headers=HEADERS,
        params={"bbox": bbox, "type": advisory_type},
        timeout=(10, 25),
    )
    r.raise_for_status()
    return r.json()


def print_route_airsigmets(dep, arr) -> None:
    bbox = route_bbox(dep, arr)
    data = fetch_airsigmets(bbox)
    reports = data.get("reports") or []

    if not reports:
        console.print(f"[green]No active AIRMETs intersect bbox {bbox} - fair weather or outside advisory area.[/]")
        return

    table = Table(title=f"Active AIRMETs - {len(reports)} in bbox")
    table.add_column("Type")
    table.add_column("Valid")
    table.add_column("Hazard")
    table.add_column("Polygon points")

    for r in reports:
        obs = r.get("observation") or {}
        hazard = obs.get("type") or r.get("report_type") or "-"
        floor = obs.get("floor") or "-"
        ceiling = obs.get("ceiling") or "-"
        coords = obs.get("coords") or []
        valid = f"{r.get('start_time') or '?'} → {r.get('end_time') or '?'}"
        table.add_row(
            r.get("report_type") or "AIRMET",
            valid,
            f"{hazard} ({floor}–{ceiling})",
            str(len(coords)),
        )

    console.print(table)
    console.print("[dim]Render observation.coords as map polygons; hide expired advisories past end_time.[/dim]")


if __name__ == "__main__":
    print_route_airsigmets(KJFK, KLAX)

Ausgabe: Tabelle der aktiven AIRMETs mit Gültigkeitszeitraum, Gefahrentyp und Anzahl der Polygoneckpunkte.


Siehe auch: METAR · TAF · Höhenwinde · PIREPs · AIRMET/SIGMET · Fehlerbehandlung · Caching & Monitoring