diff --git a/services/telegram-bot/severe_weather.py b/services/telegram-bot/severe_weather.py index a1c317e..60f451e 100644 --- a/services/telegram-bot/severe_weather.py +++ b/services/telegram-bot/severe_weather.py @@ -6,19 +6,21 @@ import time from dateutil import parser from zoneinfo import ZoneInfo -# --- CONFIGURAZIONE --- -# 👇👇 INSERISCI QUI I TUOI DATI 👇👇 +# --- CONFIGURAZIONE UTENTE --- TELEGRAM_BOT_TOKEN = "8155587974:AAF9OekvBpixtk8ZH6KoIc0L8edbhdXt7A4" TELEGRAM_CHAT_IDS = ["64463169", "24827341", "132455422", "5405962012"] -# Coordinate (San Marino) +# Coordinate (San Marino / Casa) LAT = 43.9356 LON = 12.4296 -# SOGLIE DI ALLARME -WIND_LIMIT_WARN = 60.0 # km/h (Vento Forte) -WIND_LIMIT_CRIT = 90.0 # km/h (Burrasca) -RAIN_3H_LIMIT = 30.0 # mm in 3 ore (Rischio idrogeologico) +# --- SOGLIE UFFICIALI EMILIA-ROMAGNA (Vento) --- +WIND_YELLOW = 62.0 # km/h (Burrasca Moderata) +WIND_ORANGE = 75.0 # km/h (Burrasca Forte) +WIND_RED = 88.0 # km/h (Tempesta) + +# Soglia Pioggia (Invariata) +RAIN_3H_LIMIT = 25.0 # mm in 3 ore # File di stato STATE_FILE = "/home/daniely/docker/telegram-bot/weather_state.json" @@ -55,7 +57,7 @@ def load_state(): try: with open(STATE_FILE, 'r') as f: return json.load(f) except: pass - return {"alert_active": False, "last_wind": 0, "last_rain": 0, "time": 0} + return {"alert_active": False, "last_wind": 0, "last_rain": 0, "wind_level": 0} def save_state(state): try: @@ -63,6 +65,7 @@ def save_state(state): except: pass def analyze(): + print("--- Controllo Meteo Severo ---") data = get_forecast() if not data: return @@ -102,47 +105,61 @@ def analyze(): if current_sum > sum_rain_3h: sum_rain_3h = current_sum - # --- LOGICA DI DECISIONE --- + # --- CLASSIFICAZIONE VENTO --- + wind_level_curr = 0 + wind_msg_header = "" + wind_msg_desc = "" + + if max_wind > WIND_RED: + wind_level_curr = 3 + wind_msg_header = "🔴 **TEMPESTA (Burrasca Fortissima)**" + wind_msg_desc = f"Previste raffiche > {WIND_RED:.0f} km/h (Picco: **{max_wind:.0f}** km/h).\n_Possibili danni a tetti e alberi._" + elif max_wind > WIND_ORANGE: + wind_level_curr = 2 + wind_msg_header = "🟠 **VENTO MOLTO FORTE (Burrasca Forte)**" + wind_msg_desc = f"Previste raffiche > {WIND_ORANGE:.0f} km/h (Picco: **{max_wind:.0f}** km/h)." + elif max_wind > WIND_YELLOW: + wind_level_curr = 1 + wind_msg_header = "🟡 **VENTO FORTE (Burrasca Moderata)**" + wind_msg_desc = f"Previste raffiche > {WIND_YELLOW:.0f} km/h (Picco: **{max_wind:.0f}** km/h)." + + # --- LOGICA DI ALLARME --- - is_wind_alarm = max_wind > WIND_LIMIT_WARN is_rain_alarm = sum_rain_3h > RAIN_3H_LIMIT - IS_ALARM_NOW = is_wind_alarm or is_rain_alarm + IS_ALARM_NOW = (wind_level_curr > 0) or is_rain_alarm WAS_ALARM = state.get("alert_active", False) + LAST_WIND_LEVEL = state.get("wind_level", 0) alerts = [] - - # SCENARIO A: NUOVO ALLARME o PEGGIORAMENTO + should_notify = False + + # SCENARIO A: C'È UN ALLARME if IS_ALARM_NOW: - should_notify = False - - # Logica Vento - if is_wind_alarm: - # Notifica se è nuovo o se è peggiorato di 10km/h rispetto all'ultimo avviso - if not WAS_ALARM or max_wind > state.get("last_wind", 0) + 10: - icon = "💨" if max_wind < WIND_LIMIT_CRIT else "🌪️ ⛔️" - livello = "FORTE" if max_wind < WIND_LIMIT_CRIT else "BURRASCA" - alerts.append(f"{icon} **VENTO {livello}**\nRaffiche previste fino a **{max_wind:.0f} km/h** verso le {max_wind_time}.\n_Consiglio: Ritirare oggetti leggeri._") - state["last_wind"] = max_wind + # 1. Gestione Vento + if wind_level_curr > 0: + # Notifica se è un NUOVO allarme o se il livello è AUMENTATO (es. Giallo -> Arancione) + if not WAS_ALARM or wind_level_curr > LAST_WIND_LEVEL: + alerts.append(f"{wind_msg_header}\n{wind_msg_desc}\n🕒 Orario picco: {max_wind_time}") should_notify = True - - # Logica Pioggia + state["wind_level"] = wind_level_curr # Aggiorna livello salvato + state["last_wind"] = max_wind + + # 2. Gestione Pioggia if is_rain_alarm: - # Notifica se è nuovo o se è peggiorata di 10mm if not WAS_ALARM or sum_rain_3h > state.get("last_rain", 0) + 10: alerts.append(f"🌧️ **PIOGGIA INTENSA**\nPrevisti **{sum_rain_3h:.1f} mm** in 3 ore.\n_Rischio disagi idraulici._") state["last_rain"] = sum_rain_3h should_notify = True if should_notify: - full_msg = f"⚠️ **AVVISO METEO (Prossime 12h)**\n\n" + "\n\n".join(alerts) + full_msg = f"⚠️ **AVVISO METEO SEVERO**\n\n" + "\n\n".join(alerts) send_telegram_message(full_msg) state["alert_active"] = True - state["time"] = time.time() save_state(state) print("Allerta inviata.") else: - print("Condizioni critiche ma stabili (già notificato).") + print(f"Condizioni severe stabili (Livello {wind_level_curr}). Già notificato.") # SCENARIO B: ALLARME RIENTRATO elif WAS_ALARM and not IS_ALARM_NOW: @@ -153,13 +170,14 @@ def analyze(): ) send_telegram_message(msg) - # Reset stato - state = {"alert_active": False, "last_wind": 0, "last_rain": 0, "time": time.time()} + # Reset stato completo + state = {"alert_active": False, "last_wind": 0, "last_rain": 0, "wind_level": 0} save_state(state) print("Allarme rientrato inviato.") else: - print(f"Situazione tranquilla. Vento: {max_wind:.1f}, Pioggia: {sum_rain_3h:.1f}") + # Aggiorna lo stato per dire "tutto ok" ma non resetta se non necessario + print(f"Situazione tranquilla. Vento Max: {max_wind:.0f} km/h") if __name__ == "__main__": analyze()