Spaces:
Running on Zero
Running on Zero
| """Keyless current-weather lookup via Open-Meteo (no API key required). | |
| FR24's API does not expose airport weather, so we fetch real conditions from | |
| Open-Meteo for the airport's coordinates. Cached briefly to stay polite. | |
| """ | |
| from __future__ import annotations | |
| import time | |
| import requests | |
| _CACHE: dict[tuple, tuple[float, dict]] = {} | |
| _TTL = 600 # seconds | |
| _ARROWS = ["β", "β", "β", "β", "β", "β", "β", "β"] | |
| def wind_arrow(deg) -> str: | |
| if deg is None: | |
| return "Β·" | |
| # Arrow points in the direction the wind blows TOWARD (deg is "from"). | |
| idx = int(((float(deg) + 180) % 360) / 45 + 0.5) % 8 | |
| return _ARROWS[idx] | |
| def current(lat: float, lon: float) -> dict | None: | |
| """Return {temp_c, wind_kts, wind_dir, code} or None.""" | |
| if lat is None or lon is None: | |
| return None | |
| key = (round(lat, 2), round(lon, 2)) | |
| now = time.time() | |
| hit = _CACHE.get(key) | |
| if hit and now - hit[0] < _TTL: | |
| return hit[1] | |
| try: | |
| resp = requests.get( | |
| "https://api.open-meteo.com/v1/forecast", | |
| params={ | |
| "latitude": lat, | |
| "longitude": lon, | |
| "current": "temperature_2m,wind_speed_10m,wind_direction_10m,weather_code", | |
| "wind_speed_unit": "kn", | |
| }, | |
| timeout=10, | |
| ) | |
| if resp.status_code >= 400: | |
| return None | |
| cur = resp.json().get("current", {}) | |
| out = { | |
| "temp_c": cur.get("temperature_2m"), | |
| "wind_kts": cur.get("wind_speed_10m"), | |
| "wind_dir": cur.get("wind_direction_10m"), | |
| "code": cur.get("weather_code"), | |
| } | |
| _CACHE[key] = (now, out) | |
| return out | |
| except Exception: | |
| return None | |
| # WMO weather codes -> compact glyph for the hacker readout. | |
| def code_glyph(code) -> str: | |
| if code is None: | |
| return "Β·" | |
| code = int(code) | |
| if code == 0: | |
| return "β" | |
| if code in (1, 2): | |
| return "β " | |
| if code == 3: | |
| return "β" | |
| if code in (45, 48): | |
| return "β" | |
| if 51 <= code <= 67: | |
| return "β" | |
| if 71 <= code <= 77: | |
| return "β" | |
| if 80 <= code <= 82: | |
| return "β" | |
| if 95 <= code <= 99: | |
| return "β‘" | |
| return "Β·" | |