diff --git a/services/telegram-bot/check_ghiaccio.py b/services/telegram-bot/check_ghiaccio.py index f69c204..5758983 100644 --- a/services/telegram-bot/check_ghiaccio.py +++ b/services/telegram-bot/check_ghiaccio.py @@ -201,11 +201,11 @@ def get_weather_data(lat, lon, model_slug, include_past_days=1): # Modificati per ridurre falsi positivi mantenendo alta sensibilità # ============================================================================= H_COLD_THR = 69.0 # hPa (Profondità minima strato freddo) -T_COLD_THR = 0.09 # °C (Temp max al suolo considerata 'fredda') - mantenuta bassa per evitare falsi negativi +T_COLD_THR = -0.5 # °C (Temp max al suolo considerata 'fredda') - abbassata da 0.09 per meno falsi positivi (solo quando è più gelido) T_MELT_THR = 0.0 # °C (Temp min per considerare uno strato 'in fusione') - aumentata da -0.64°C a 0.0°C per ridurre falsi positivi mantenendo sensibilità RH_MELT_THR = 89.0 # % (Umidità relativa minima nello strato di fusione) PR_THR_6H = 0.39 # mm/6h -PR_THR_1H = 0.1 # mm/h - aumentata da 0.065 per richiedere precipitazione più significativa +PR_THR_1H = 0.25 # mm/h - alzata da 0.1 per richiedere precipitazione più significativa (meno allerte gelicidio) # Differenza minima temperatura tra strato di fusione e suolo (per ridurre falsi positivi) T_MELT_SURFACE_DIFF = 1.0 # °C - lo strato di fusione deve essere almeno 1°C più caldo del suolo (bilanciato tra riduzione falsi positivi e mantenimento sensibilità) diff --git a/services/telegram-bot/civil_protection.py b/services/telegram-bot/civil_protection.py index 272866d..92583d8 100644 --- a/services/telegram-bot/civil_protection.py +++ b/services/telegram-bot/civil_protection.py @@ -43,6 +43,7 @@ TOKEN_FILE_ETC = "/etc/telegram_dpc_bot_token" # Zone target (come compaiono tipicamente nel testo del bollettino) TARGET_ZONES = { "EMR-B2": "Costa romagnola", + "EMR-B1": "Pianura romagnola", "EMR-A2": "Alta collina romagnola", "EMR-D1": "Pianura bolognese", } diff --git a/services/telegram-bot/log_monitor.py b/services/telegram-bot/log_monitor.py index 74cf910..d2ebf73 100644 --- a/services/telegram-bot/log_monitor.py +++ b/services/telegram-bot/log_monitor.py @@ -14,6 +14,11 @@ import requests BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DEFAULT_PATTERNS = ["*.log", "*_log.txt"] +EXCLUDED_FILES = { + "circondario_log.txt", + "road_weather.log", + "snow_radar.log", +} TOKEN_FILE_HOME = os.path.expanduser("~/.telegram_dpc_bot_token") TOKEN_FILE_ETC = "/etc/telegram_dpc_bot_token" @@ -21,7 +26,8 @@ TS_RE = re.compile(r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})") CATEGORIES = { "open_meteo_timeout": re.compile( - r"timeout|timed out|Read timed out|Gateway Time-out|504", re.IGNORECASE + r"timeout|timed out|Read timed out|Gateway Time-out|HTTP\s*504|status\s*504|\b504\b", + re.IGNORECASE, ), "ssl_handshake": re.compile(r"handshake", re.IGNORECASE), "permission_error": re.compile(r"PermissionError|permesso negato|Errno 13", re.IGNORECASE), @@ -207,6 +213,9 @@ def main(): parser.add_argument("--log", action="append", help="Aggiungi un file log specifico") args = parser.parse_args() + run_ts = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(f"--- Log Monitor run {run_ts} ---") + if args.log: files = [p for p in args.log if os.path.exists(p)] else: @@ -215,6 +224,7 @@ def main(): for pat in DEFAULT_PATTERNS: files.extend(sorted([str(p) for p in Path(BASE_DIR).glob(pat)])) files = sorted(set(files)) + files = [p for p in files if os.path.basename(p) not in EXCLUDED_FILES] since = datetime.datetime.now() - datetime.timedelta(days=args.days) category_hits, per_file_counts, timeout_minutes, stale_logs = analyze_logs(files, since, args.max_lines) diff --git a/services/telegram-bot/net_quality.py b/services/telegram-bot/net_quality.py index ab7722c..8a0db58 100644 --- a/services/telegram-bot/net_quality.py +++ b/services/telegram-bot/net_quality.py @@ -11,7 +11,7 @@ from typing import List, Optional # --- CONFIGURAZIONE --- BOT_TOKEN="8155587974:AAF9OekvBpixtk8ZH6KoIc0L8edbhdXt7A4" -TELEGRAM_CHAT_IDS = ["64463169", "24827341", "132455422", "5405962012"] +TELEGRAM_CHAT_IDS = ["64463169"] # BERSAGLIO (Cloudflare è solitamente il più stabile per i ping) TARGET_HOST = "1.1.1.1" @@ -86,8 +86,20 @@ def measure_quality(chat_ids: Optional[List[str]] = None): # Parsing Packet Loss # Cerca pattern: "X% packet loss" - loss_match = re.search(r'(\d+)% packet loss', output) - loss = int(loss_match.group(1)) if loss_match else 100 + loss_match = re.search(r'([0-9]+(?:[\\.,][0-9]+)?)% packet loss', output) + if loss_match: + loss_raw = loss_match.group(1).replace(",", ".") + try: + loss = float(loss_raw) + except Exception: + loss = 100.0 + else: + loss = 100.0 + # Clamp to avoid parsing artifacts (e.g., "0.96078%" -> 0.96078, not 96078). + if loss < 0: + loss = 0.0 + if loss > 100: + loss = 100.0 # Parsing Jitter (mdev) # Output tipico: rtt min/avg/max/mdev = 10.1/12.5/40.2/5.1 ms @@ -101,7 +113,7 @@ def measure_quality(chat_ids: Optional[List[str]] = None): else: avg_ping = 0.0 - result_line = f"Risultati: Loss={loss}% | Jitter={jitter}ms | AvgPing={avg_ping}ms" + result_line = f"Risultati: Loss={loss:.2f}% | Jitter={jitter}ms | AvgPing={avg_ping}ms" print(result_line) log_line(f"INFO {result_line}") @@ -116,7 +128,7 @@ def measure_quality(chat_ids: Optional[List[str]] = None): # NUOVO ALLARME msg = f"📉 **DEGRADO QUALITÀ LINEA**\n\n" if loss >= LIMIT_LOSS: - msg += f"🔴 **Packet Loss:** `{loss}%` (Soglia {LIMIT_LOSS}%)\n" + msg += f"🔴 **Packet Loss:** `{loss:.2f}%` (Soglia {LIMIT_LOSS}%)\n" if jitter >= LIMIT_JITTER: msg += f"⚠️ **Jitter (Instabilità):** `{jitter}ms` (Soglia {LIMIT_JITTER}ms)\n" @@ -133,7 +145,7 @@ def measure_quality(chat_ids: Optional[List[str]] = None): # RECOVERY msg = f"✅ **QUALITÀ LINEA RIPRISTINATA**\n\n" msg += f"I parametri sono rientrati nella norma.\n" - msg += f"Ping: `{avg_ping}ms` | Jitter: `{jitter}ms` | Loss: `{loss}%`" + msg += f"Ping: `{avg_ping}ms` | Jitter: `{jitter}ms` | Loss: `{loss:.2f}%`" send_telegram(msg, chat_ids=chat_ids) save_state(False) print("Recovery inviata.")