Backup automatico script del 2025-12-02 21:49

This commit is contained in:
2025-12-02 21:49:25 +01:00
parent 658b7c13cb
commit 19df6ca479

View File

@@ -1,31 +1,58 @@
import requests import requests
import datetime import datetime
import time import time
import json
import os
from dateutil import parser from dateutil import parser
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
# --- CONFIGURAZIONE UTENTE --- # --- CONFIGURAZIONE UTENTE ---
# 👇👇 INSERISCI QUI I TUOI DATI 👇👇
TELEGRAM_BOT_TOKEN = "8155587974:AAF9OekvBpixtk8ZH6KoIc0L8edbhdXt7A4" TELEGRAM_BOT_TOKEN = "8155587974:AAF9OekvBpixtk8ZH6KoIc0L8edbhdXt7A4"
TELEGRAM_CHAT_IDS = ["64463169", "132455422"] TELEGRAM_CHAT_IDS = ["64463169", "24827341", "132455422", "5405962012"]
# --- SOGLIE DI ALLARME (Bologna) --- # --- SOGLIE DI ALLARME (Bologna) ---
SOGLIA_NEVE = 0.0 # cm (Basta che nevichi per attivare) SOGLIA_NEVE = 0.0 # cm (Basta neve per attivare)
SOGLIA_PIOGGIA_3H = 15.0 # mm in 3 ore (Pioggia molto forte/Bomba d'acqua) SOGLIA_PIOGGIA_3H = 15.0 # mm in 3 ore (Pioggia molto forte)
# --- PUNTI DEL PERCORSO --- # File di stato per la memoria
# Il primo punto deve essere BOLOGNA (Trigger) STATE_FILE = "/home/daniely/docker/telegram-bot/student_state.json"
# --- PUNTI DEL PERCORSO (Caselli A14) ---
POINTS = [ POINTS = [
{"name": "🎓 Bologna (V. Regnoli)", "lat": 44.4930, "lon": 11.3690, "type": "trigger"}, {"name": "🎓 Bologna (V. Regnoli)", "lat": 44.4930, "lon": 11.3690, "type": "trigger"},
{"name": "🏎️ Imola", "lat": 44.3590, "lon": 11.7130, "type": "route"}, {"name": "🛣️ Casello Imola", "lat": 44.3798, "lon": 11.7397, "type": "route"},
{"name": "ceramica Faenza", "lat": 44.2900, "lon": 11.8800, "type": "route"}, {"name": "🛣️ Casello Faenza", "lat": 44.3223, "lon": 11.9040, "type": "route"},
{"name": "✈️ Forlì", "lat": 44.2220, "lon": 12.0410, "type": "route"}, {"name": "🛣️ Casello Forlì", "lat": 44.2502, "lon": 12.0910, "type": "route"},
{"name": "🛣️ Cesena", "lat": 44.1390, "lon": 12.2430, "type": "route"}, {"name": "🛣️ Casello Cesena", "lat": 44.1675, "lon": 12.2835, "type": "route"},
{"name": "🏖️ Rimini", "lat": 44.0600, "lon": 12.5600, "type": "route"}, {"name": "🛣️ Casello Rimini", "lat": 44.0362, "lon": 12.5659, "type": "route"},
{"name": "🏠 San Marino", "lat": 43.9356, "lon": 12.4296, "type": "end"} {"name": "🏠 San Marino", "lat": 43.9356, "lon": 12.4296, "type": "end"}
] ]
# --- FUNZIONI DI UTILITÀ ---
def load_last_state():
"""Legge se c'era un allerta attiva"""
if not os.path.exists(STATE_FILE): return False
try:
with open(STATE_FILE, 'r') as f:
data = json.load(f)
return data.get("alert_active", False)
except: return False
def save_current_state(is_active):
"""Salva lo stato corrente"""
try:
with open(STATE_FILE, 'w') as f:
json.dump({"alert_active": is_active, "updated": str(datetime.datetime.now())}, f)
except Exception as e:
print(f"Errore salvataggio stato: {e}")
def send_telegram_message(message): def send_telegram_message(message):
if "INSERISCI" in TELEGRAM_BOT_TOKEN: return if not TELEGRAM_BOT_TOKEN or "INSERISCI" in TELEGRAM_BOT_TOKEN:
print(f"[TEST OUT] {message}")
return
url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage" url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
for chat_id in TELEGRAM_CHAT_IDS: for chat_id in TELEGRAM_CHAT_IDS:
try: try:
@@ -57,7 +84,6 @@ def get_stats(data):
now = datetime.datetime.now(ZoneInfo("Europe/Rome")) now = datetime.datetime.now(ZoneInfo("Europe/Rome"))
# Indice ora corrente
start_idx = -1 start_idx = -1
for i, t in enumerate(times): for i, t in enumerate(times):
if parser.isoparse(t).replace(tzinfo=ZoneInfo("Europe/Rome")) >= now.replace(minute=0,second=0,microsecond=0): if parser.isoparse(t).replace(tzinfo=ZoneInfo("Europe/Rome")) >= now.replace(minute=0,second=0,microsecond=0):
@@ -65,9 +91,8 @@ def get_stats(data):
break break
if start_idx == -1: return None if start_idx == -1: return None
limit = min(start_idx + 24, len(times)) # Analisi max 24h limit = min(start_idx + 24, len(times))
# Calcolo finestre temporali
def sum_slice(arr, hours): def sum_slice(arr, hours):
return sum(x for x in arr[start_idx:min(start_idx+hours, limit)] if x) return sum(x for x in arr[start_idx:min(start_idx+hours, limit)] if x)
@@ -76,13 +101,17 @@ def get_stats(data):
"snow_6h": sum_slice(snow, 6), "snow_6h": sum_slice(snow, 6),
"snow_12h": sum_slice(snow, 12), "snow_12h": sum_slice(snow, 12),
"snow_24h": sum_slice(snow, 24), "snow_24h": sum_slice(snow, 24),
"rain_3h": sum_slice(rain, 3), # Per bomba d'acqua "rain_3h": sum_slice(rain, 3),
"rain_max": max(rain[start_idx:limit]) if rain else 0 # Picco mm/h "rain_max": max(rain[start_idx:limit]) if rain else 0
} }
# --- LOGICA PRINCIPALE ---
def main(): def main():
print("--- Analisi Studente Bologna ---") print("--- Analisi Studente Bologna ---")
now_str = datetime.datetime.now(ZoneInfo("Europe/Rome")).strftime('%H:%M')
# 1. ANALISI BOLOGNA (Il Trigger) # 1. ANALISI BOLOGNA (Il Trigger)
bo_point = POINTS[0] bo_point = POINTS[0]
bo_data = get_forecast(bo_point["lat"], bo_point["lon"]) bo_data = get_forecast(bo_point["lat"], bo_point["lon"])
@@ -94,60 +123,69 @@ def main():
alarm_snow = bo_stats["snow_24h"] > SOGLIA_NEVE alarm_snow = bo_stats["snow_24h"] > SOGLIA_NEVE
alarm_rain = bo_stats["rain_3h"] > SOGLIA_PIOGGIA_3H alarm_rain = bo_stats["rain_3h"] > SOGLIA_PIOGGIA_3H
if not (alarm_snow or alarm_rain): # Carica stato precedente
print("Bologna tranquilla. Nessun report.") WAS_ACTIVE = load_last_state()
return
# --- C'È ALLERTA: GENERIAMO IL REPORT --- # --- SCENARIO A: C'È ALLERTA ---
if alarm_snow or alarm_rain:
icon_main = "❄️" if alarm_snow else "🌧️"
now_str = datetime.datetime.now(ZoneInfo("Europe/Rome")).strftime('%H:%M') msg = f"{icon_main} **ALLERTA METEO BOLOGNA**\n"
icon_main = "❄️" if alarm_snow else "🌧️" msg += f"📅 _Aggiornamento ore {now_str}_\n\n"
msg = f"{icon_main} **ALLERTA METEO BOLOGNA**\n" # Dettaglio Bologna
msg += f"📅 _Aggiornamento ore {now_str}_\n\n" msg += f"🎓 **A BOLOGNA:**\n"
if alarm_snow:
msg += f"• Neve 3h: **{bo_stats['snow_3h']:.1f}** cm\n"
msg += f"• Neve 6h: **{bo_stats['snow_6h']:.1f}** cm\n"
msg += f"• Neve 12h: **{bo_stats['snow_12h']:.1f}** cm\n"
msg += f"• Neve 24h: **{bo_stats['snow_24h']:.1f}** cm\n"
# Dettaglio Bologna if alarm_rain:
msg += f"🎓 **A BOLOGNA:**\n" msg += f"• Pioggia 3h: **{bo_stats['rain_3h']:.1f}** mm (Intensa!)\n"
if alarm_snow:
msg += f"• Neve 3h: **{bo_stats['snow_3h']:.1f}** cm\n"
msg += f"• Neve 6h: **{bo_stats['snow_6h']:.1f}** cm\n"
msg += f"• Neve 12h: **{bo_stats['snow_12h']:.1f}** cm\n"
msg += f"• Neve 24h: **{bo_stats['snow_24h']:.1f}** cm\n"
if alarm_rain: msg += "\n🚗 **SITUAZIONE AI CASELLI (A14):**\n"
msg += f"• Pioggia 3h: **{bo_stats['rain_3h']:.1f}** mm (Intensa!)\n"
msg += f"• Picco orario: {bo_stats['rain_max']:.1f} mm/h\n"
msg += "\n🚗 **SITUAZIONE RIENTRO (A14):**\n" # 2. ANALISI PERCORSO (Solo se c'è allerta)
route_issues = False
# 2. ANALISI PERCORSO (Loop sugli altri punti) for p in POINTS[1:]:
route_issues = False stats = get_stats(get_forecast(p["lat"], p["lon"]))
if not stats: continue
for p in POINTS[1:]: has_snow = stats["snow_24h"] > 0
stats = get_stats(get_forecast(p["lat"], p["lon"])) has_rain = stats["rain_3h"] > 5.0
if not stats: continue
# Format della riga percorso if has_snow or has_rain:
# Mostriamo solo se c'è qualcosa di significativo (>0 neve o >5mm pioggia) route_issues = True
has_snow = stats["snow_24h"] > 0 line = f"**{p['name']}**: "
has_rain = stats["rain_3h"] > 5.0 if has_snow: line += f"❄️ {stats['snow_12h']:.1f}cm (12h) "
if has_rain: line += f"🌧️ {stats['rain_3h']:.1f}mm "
msg += f"{line}\n"
if has_snow or has_rain: if not route_issues:
route_issues = True msg += "✅ I caselli autostradali sembrano puliti."
line = f"**{p['name']}**: "
if has_snow: line += f"❄️ {stats['snow_12h']:.1f}cm (12h) "
if has_rain: line += f"🌧️ {stats['rain_3h']:.1f}mm "
msg += f"{line}\n"
else:
# Se è pulito, mettiamo un check leggero per far capire che è OK
# msg += f"{p['name']}: ✅ OK\n"
pass
if not route_issues: send_telegram_message(msg)
msg += "✅ Il percorso di ritorno sembra pulito." save_current_state(True)
print("Allerta inviata.")
send_telegram_message(msg) # --- SCENARIO B: ALLARME RIENTRATO ---
print("Allerta inviata.") elif not (alarm_snow or alarm_rain) and WAS_ACTIVE:
msg = (
f"🟢 **ALLARME RIENTRATO (Bologna)**\n"
f"📅 _Aggiornamento ore {now_str}_\n\n"
f"Le previsioni non indicano più neve o piogge critiche per le prossime 24 ore.\n"
f"Situazione tornata alla normalità."
)
send_telegram_message(msg)
save_current_state(False)
print("Allarme rientrato. Notifica inviata.")
# --- SCENARIO C: TRANQUILLO ---
else:
save_current_state(False)
print("Nessuna allerta.")
if __name__ == "__main__": if __name__ == "__main__":
main() main()