Backup automatico script del 2026-01-18 07:00

This commit is contained in:
2026-01-18 07:00:02 +01:00
parent 4555d6615e
commit 9dbe0cfa93
8 changed files with 339 additions and 57 deletions

View File

@@ -221,7 +221,9 @@ def get_forecast(lat, lon, model=None, is_home=False, timezone=None, retry_after
# Nota: minutely_15 non è usato in meteo.py (solo per script di allerta)
try:
r = requests.get(OPEN_METEO_URL, params=params, headers=HTTP_HEADERS, timeout=25)
t0 = time.time()
# Timeout ridotto a 20s per fallire più velocemente in caso di problemi
r = requests.get(OPEN_METEO_URL, params=params, headers=HTTP_HEADERS, timeout=20)
if r.status_code != 200:
# Dettagli errore più specifici
error_details = f"Status {r.status_code}"
@@ -238,22 +240,23 @@ def get_forecast(lat, lon, model=None, is_home=False, timezone=None, retry_after
logger.error(f"API Error {error_details}")
return None, error_details # Restituisce anche i dettagli dell'errore
response_data = r.json()
logger.info("get_forecast ok model=%s points=5 elapsed=%.2fs", model or "best_match", time.time() - t0)
# Open-Meteo per multiple locations (lat/lon separati da virgola) restituisce
# direttamente un dict con "hourly", "daily", etc. che contiene liste di valori
# per ogni location. Per semplicità, restituiamo il dict così com'è
# e lo gestiamo nel codice chiamante
return response_data, None
except requests.exceptions.Timeout as e:
error_details = f"Timeout dopo 25s: {str(e)}"
logger.error(f"Request timeout: {error_details}")
error_details = f"Timeout dopo 20s: {str(e)}"
logger.error("Request timeout: %s elapsed=%.2fs", error_details, time.time() - t0)
return None, error_details
except requests.exceptions.ConnectionError as e:
error_details = f"Errore connessione: {str(e)}"
logger.error(f"Connection error: {error_details}")
logger.error("Connection error: %s elapsed=%.2fs", error_details, time.time() - t0)
return None, error_details
except Exception as e:
error_details = f"Errore richiesta: {type(e).__name__}: {str(e)}"
logger.error(f"Request error: {error_details}")
logger.error("Request error: %s elapsed=%.2fs", error_details, time.time() - t0)
return None, error_details
def get_visibility_forecast(lat, lon):
@@ -271,16 +274,19 @@ def get_visibility_forecast(lat, lon):
"hourly": "visibility"
}
try:
r = requests.get(OPEN_METEO_URL, params=params_ecmwf, headers=HTTP_HEADERS, timeout=15)
t0 = time.time()
# Timeout ridotto a 12s per fallire più velocemente
r = requests.get(OPEN_METEO_URL, params=params_ecmwf, headers=HTTP_HEADERS, timeout=12)
if r.status_code == 200:
data = r.json()
hourly = data.get("hourly", {})
vis = hourly.get("visibility", [])
# Verifica se ci sono valori validi (non tutti None)
if vis and any(v is not None for v in vis):
logger.info("get_visibility_forecast ok model=ecmwf_ifs04 elapsed=%.2fs", time.time() - t0)
return vis
except Exception as e:
logger.debug(f"ECMWF IFS visibility request error: {e}")
logger.debug("ECMWF IFS visibility request error: %s elapsed=%.2fs", e, time.time() - t0)
# Fallback: usa best match (senza models) che seleziona automaticamente GFS o ICON-D2
params_best = {
@@ -291,16 +297,20 @@ def get_visibility_forecast(lat, lon):
"hourly": "visibility"
}
try:
r = requests.get(OPEN_METEO_URL, params=params_best, headers=HTTP_HEADERS, timeout=15)
t0 = time.time()
# Timeout ridotto a 12s per fallire più velocemente
r = requests.get(OPEN_METEO_URL, params=params_best, headers=HTTP_HEADERS, timeout=12)
if r.status_code == 200:
data = r.json()
hourly = data.get("hourly", {})
logger.info("get_visibility_forecast ok model=best_match elapsed=%.2fs", time.time() - t0)
return hourly.get("visibility", [])
except Exception as e:
logger.error(f"Visibility request error: {e}")
logger.error("Visibility request error: %s elapsed=%.2fs", e, time.time() - t0)
return None
def generate_weather_report(lat, lon, location_name, debug_mode=False, cc="IT", timezone=None) -> str:
t_total = time.time()
# Determina se è Casa
is_home = (abs(lat - HOME_LAT) < 0.01 and abs(lon - HOME_LON) < 0.01)
@@ -596,7 +606,9 @@ def generate_weather_report(lat, lon, location_name, debug_mode=False, cc="IT",
if not blocks:
return f"❌ Nessun dato da mostrare nelle prossime 48 ore (da {current_hour.strftime('%H:%M')})."
return f"🌤️ *METEO REPORT*\n📍 {location_name}\n🧠 Fonte: {model_name}\n\n" + "\n\n".join(blocks)
report = f"🌤️ *METEO REPORT*\n📍 {location_name}\n🧠 Fonte: {model_name}\n\n" + "\n\n".join(blocks)
logger.info("generate_weather_report ok elapsed=%.2fs", time.time() - t_total)
return report
if __name__ == "__main__":
args_parser = argparse.ArgumentParser()