Backup automatico script del 2026-07-05 07:00

This commit is contained in:
2026-07-05 07:00:03 +02:00
parent bd3b4b66cc
commit b5a2a814e2
3 changed files with 221 additions and 28 deletions
@@ -76,11 +76,19 @@ STORM_SCORE_THRESHOLD = 40.0 # Storm Severity Score minimo per allerta
# Una località viene notificata SOLO se ha almeno un evento "significativo":
# fulminazioni forti, bomba d'acqua/nubifragio forte, alluvione o downburst.
# Soglie volutamente alte per filtrare i temporali marginali estivi.
SIGNIFICANT_CAPE_LIGHTNING = 1500.0 # J/kg - fulminazioni rilevanti (oltre il marginale)
SIGNIFICANT_CAPE_LIGHTNING = 1200.0 # J/kg - fulminazioni rilevanti (instabilità moderata: scelta orientata alla sicurezza)
# La fulminazione "forte" deve corrispondere a una cella temporalesca prevista sul posto:
# oltre a CAPE+LPI richiede precipitazione convettiva consistente.
SIGNIFICANT_LIGHTNING_PRECIP_H = 2.0 # mm/h
SIGNIFICANT_LIGHTNING_PRECIP_3H = 5.0 # mm/3h
SIGNIFICANT_PRECIP_H = 30.0 # mm/h - bomba d'acqua (nubifragio forte)
SIGNIFICANT_PRECIP_3H = 50.0 # mm/3h - nubifragio forte su 3 ore
SIGNIFICANT_SCORE = 55.0 # Storm Severity Score minimo per considerare l'evento significativo
# Pioggia minima per considerare un evento REALMENTE convettivo (no pioggia = no temporale).
CONVECTIVE_MIN_PRECIP_H = 0.5 # mm/h
CONVECTIVE_MIN_PRECIP_3H = 2.0 # mm/3h
# ----------------- RATE LIMITING NOTIFICHE -----------------
# Notifiche "molto contingentate":
# - eventi imminenti (entro IMMINENT_HOURS): massimo 2 al giorno
@@ -282,7 +290,10 @@ def event_significance(event: Dict) -> List[str]:
precip_3h = float(event.get("precip_3h", 0.0) or 0.0)
score = float(event.get("score", 0.0) or 0.0)
if "Fulminazioni" in threats and cape >= SIGNIFICANT_CAPE_LIGHTNING and lpi > 0:
lightning_precip = (precip >= SIGNIFICANT_LIGHTNING_PRECIP_H or
precip_3h >= SIGNIFICANT_LIGHTNING_PRECIP_3H)
if ("Fulminazioni" in threats and cape >= SIGNIFICANT_CAPE_LIGHTNING
and lpi > 0 and lightning_precip):
reasons.append("Fulminazioni forti")
if precip >= SIGNIFICANT_PRECIP_H or precip_3h >= SIGNIFICANT_PRECIP_3H:
reasons.append("Bomba d'acqua")
@@ -535,11 +546,16 @@ def analyze_convective_risk(icon_data: Dict, arome_data: Dict, times_base: List[
dynamic_score = min(30.0, ((gusts_val - WIND_GUST_DOWNBURST_THRESHOLD) / 40.0) * 30.0)
score += dynamic_score
# Identifica minacce
if cape_val > CAPE_LIGHTNING_THRESHOLD and lpi_val > 0:
# Precipitazione convettiva reale: senza pioggia non c'è temporale.
has_convective_precip = (precip_val >= CONVECTIVE_MIN_PRECIP_H or
precip_3h_val >= CONVECTIVE_MIN_PRECIP_3H)
# Identifica minacce (fulminazioni e downburst richiedono precipitazione reale)
if cape_val > CAPE_LIGHTNING_THRESHOLD and lpi_val > 0 and has_convective_precip:
threats.append("Fulminazioni")
if cape_val > CAPE_SEVERE_THRESHOLD and gusts_val > WIND_GUST_DOWNBURST_THRESHOLD:
if (cape_val > CAPE_SEVERE_THRESHOLD and gusts_val > WIND_GUST_DOWNBURST_THRESHOLD
and has_convective_precip):
threats.append("Downburst/Temporale violento")
if precip_val > RAIN_INTENSE_THRESHOLD_H or precip_3h_val > RAIN_INTENSE_THRESHOLD_3H:
@@ -552,7 +568,9 @@ def analyze_convective_risk(icon_data: Dict, arome_data: Dict, times_base: List[
flood_bonus = min(10.0, (precip_24h_val - RAIN_FLOOD_THRESHOLD_24H) / 10.0)
score += flood_bonus
if score >= STORM_SCORE_THRESHOLD or threats:
# Registra solo eventi con una minaccia reale (tutte richiedono precipitazione).
# Il CAPE alto da solo (cielo asciutto) NON genera più un evento.
if threats:
results.append({
"timestamp": times_base[i],
"score": score,