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,13 +123,11 @@ 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:
now_str = datetime.datetime.now(ZoneInfo("Europe/Rome")).strftime('%H:%M')
icon_main = "❄️" if alarm_snow else "🌧️" icon_main = "❄️" if alarm_snow else "🌧️"
msg = f"{icon_main} **ALLERTA METEO BOLOGNA**\n" msg = f"{icon_main} **ALLERTA METEO BOLOGNA**\n"
@@ -116,19 +143,16 @@ def main():
if alarm_rain: if alarm_rain:
msg += f"• Pioggia 3h: **{bo_stats['rain_3h']:.1f}** mm (Intensa!)\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" msg += "\n🚗 **SITUAZIONE AI CASELLI (A14):**\n"
# 2. ANALISI PERCORSO (Loop sugli altri punti) # 2. ANALISI PERCORSO (Solo se c'è allerta)
route_issues = False route_issues = False
for p in POINTS[1:]: for p in POINTS[1:]:
stats = get_stats(get_forecast(p["lat"], p["lon"])) stats = get_stats(get_forecast(p["lat"], p["lon"]))
if not stats: continue if not stats: continue
# Format della riga percorso
# Mostriamo solo se c'è qualcosa di significativo (>0 neve o >5mm pioggia)
has_snow = stats["snow_24h"] > 0 has_snow = stats["snow_24h"] > 0
has_rain = stats["rain_3h"] > 5.0 has_rain = stats["rain_3h"] > 5.0
@@ -138,16 +162,30 @@ def main():
if has_snow: line += f"❄️ {stats['snow_12h']:.1f}cm (12h) " if has_snow: line += f"❄️ {stats['snow_12h']:.1f}cm (12h) "
if has_rain: line += f"🌧️ {stats['rain_3h']:.1f}mm " if has_rain: line += f"🌧️ {stats['rain_3h']:.1f}mm "
msg += f"{line}\n" 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: if not route_issues:
msg += "✅ Il percorso di ritorno sembra pulito." msg += "✅ I caselli autostradali sembrano puliti."
send_telegram_message(msg) send_telegram_message(msg)
save_current_state(True)
print("Allerta inviata.") print("Allerta inviata.")
# --- SCENARIO B: ALLARME RIENTRATO ---
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()