Aggiorna script backup e bot meteo Telegram.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
3a7b867e83
commit
beb790ed7e
6 files changed
+350
-102
No files matched your search
@@ -41,6 +41,9 @@ ICON_DAILY_VARS = (
|
||||
|
||||
PRECIP_HOURLY_KEYS = ("precipitation", "rain", "showers", "snowfall")
|
||||
PRECIP_DAILY_KEYS = ("precipitation_sum", "rain_sum", "showers_sum", "snowfall_sum", "precipitation_hours")
|
||||
WMO_PRECIP_CODES = frozenset(
|
||||
list(range(51, 68)) + list(range(71, 78)) + list(range(80, 83)) + [85, 86, 95, 96, 99]
|
||||
)
|
||||
|
||||
|
||||
def is_casa(lat: float, lon: float, tol: float = 0.01) -> bool:
|
||||
@@ -84,6 +87,61 @@ def daily_precip_from_hourly(hourly: Dict) -> Dict[str, float]:
|
||||
return dict(out)
|
||||
|
||||
|
||||
def daily_component_from_hourly(hourly: Dict, key: str) -> Dict[str, float]:
|
||||
"""Somma un campo orario (rain, showers, snowfall) per data locale YYYY-MM-DD."""
|
||||
times = hourly.get("time") or []
|
||||
arr = hourly.get(key) or []
|
||||
out: Dict[str, float] = defaultdict(float)
|
||||
for i, t in enumerate(times):
|
||||
if not t or i >= len(arr) or arr[i] is None:
|
||||
continue
|
||||
try:
|
||||
out[str(t)[:10]] += float(arr[i])
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
return dict(out)
|
||||
|
||||
|
||||
def apply_hourly_daily_precip(daily: Dict, hourly: Dict) -> Dict:
|
||||
"""Allinea i totali daily alla somma delle ore (stessa metrica della tabella oraria)."""
|
||||
daily = dict(daily)
|
||||
times = daily.get("time") or []
|
||||
mapping = {
|
||||
"precipitation_sum": daily_precip_from_hourly(hourly),
|
||||
"rain_sum": daily_component_from_hourly(hourly, "rain"),
|
||||
"showers_sum": daily_component_from_hourly(hourly, "showers"),
|
||||
"snowfall_sum": daily_component_from_hourly(hourly, "snowfall"),
|
||||
}
|
||||
for key, totals in mapping.items():
|
||||
arr = list(daily.get(key) or [])
|
||||
while len(arr) < len(times):
|
||||
arr.append(None)
|
||||
for i, t in enumerate(times):
|
||||
d = str(t)[:10]
|
||||
if d in totals:
|
||||
arr[i] = round(totals[d], 2)
|
||||
daily[key] = arr
|
||||
return daily
|
||||
|
||||
|
||||
def hourly_table_should_show(hours_from_start: int, precip_mm: float, weathercode: int = 0) -> bool:
|
||||
"""
|
||||
Tabella 48h: prime 24 ore tutte; dalle 25 alle 48 ogni 2 ore,
|
||||
ma un'ora con precipitazione (mm o codice WMO) non viene mai omessa.
|
||||
"""
|
||||
if hours_from_start < 24:
|
||||
return True
|
||||
if hours_from_start % 2 == 0:
|
||||
return True
|
||||
if float(precip_mm or 0) >= 0.1:
|
||||
return True
|
||||
try:
|
||||
code = int(weathercode or 0)
|
||||
except (TypeError, ValueError):
|
||||
code = 0
|
||||
return code in WMO_PRECIP_CODES
|
||||
|
||||
|
||||
def daily_precip_sum(daily: Dict, date_str: str) -> Optional[float]:
|
||||
times = daily.get("time") or []
|
||||
arr = daily.get("precipitation_sum") or []
|
||||
@@ -125,8 +183,19 @@ def fetch_icon_italia(
|
||||
return None
|
||||
|
||||
|
||||
def _time_key(t) -> str:
|
||||
if not t:
|
||||
return ""
|
||||
return str(t).strip()[:16]
|
||||
|
||||
|
||||
def _index_by_time(section: Dict) -> Dict[str, int]:
|
||||
return {str(t): i for i, t in enumerate(section.get("time") or [])}
|
||||
out: Dict[str, int] = {}
|
||||
for i, t in enumerate(section.get("time") or []):
|
||||
k = _time_key(t)
|
||||
if k:
|
||||
out[k] = i
|
||||
return out
|
||||
|
||||
|
||||
def overlay_icon_precip_on_hourly(target: Dict, icon_hourly: Dict) -> Dict:
|
||||
|
||||
Reference in new issue
Block a user