Riorganizzazione struttura repository: separazione servizi e script
This commit is contained in:
125
scripts/pi2-backup/daily_report.py
Normal file
125
scripts/pi2-backup/daily_report.py
Normal file
@@ -0,0 +1,125 @@
|
||||
import sqlite3
|
||||
import os
|
||||
import datetime
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import json
|
||||
|
||||
# --- CONFIGURAZIONE ---
|
||||
BOT_TOKEN = os.environ.get('BOT_TOKEN')
|
||||
CHAT_ID = os.environ.get('ALLOWED_USER_ID')
|
||||
DB_PATH = "/data/speedtest.sqlite"
|
||||
|
||||
# SOGLIE DI ALLARME (Mbps)
|
||||
WARN_DOWN = 400
|
||||
WARN_UP = 100
|
||||
|
||||
def send_telegram_message(message):
|
||||
if not message: return
|
||||
|
||||
url = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage"
|
||||
payload = {
|
||||
"chat_id": CHAT_ID,
|
||||
"text": message,
|
||||
"parse_mode": "Markdown"
|
||||
}
|
||||
|
||||
try:
|
||||
data = urllib.parse.urlencode(payload).encode('utf-8')
|
||||
req = urllib.request.Request(url, data=data)
|
||||
with urllib.request.urlopen(req) as response:
|
||||
if response.status == 200:
|
||||
print("✅ Report inviato.")
|
||||
except Exception as e:
|
||||
print(f"❌ Errore invio Telegram: {e}")
|
||||
|
||||
def generate_report():
|
||||
if not os.path.exists(DB_PATH):
|
||||
print(f"❌ Database non trovato: {DB_PATH}")
|
||||
return None
|
||||
|
||||
try:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
# Calcola l'orario UTC di 24h fa (perché il DB è in UTC)
|
||||
yesterday = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(hours=24)
|
||||
|
||||
query = "SELECT download, upload, ping, created_at FROM results WHERE created_at > ? AND status = 'completed' ORDER BY created_at ASC"
|
||||
cursor.execute(query, (yesterday,))
|
||||
rows = cursor.fetchall()
|
||||
except Exception as e:
|
||||
print(f"❌ Errore DB: {str(e)}")
|
||||
return None
|
||||
finally:
|
||||
if 'conn' in locals(): conn.close()
|
||||
|
||||
if not rows:
|
||||
print("ℹ️ Nessun test trovato.")
|
||||
return None
|
||||
|
||||
# Variabili per statistiche
|
||||
total_down = 0
|
||||
total_up = 0
|
||||
count = 0
|
||||
issues = 0
|
||||
|
||||
# Intestazione Messaggio
|
||||
# Usiamo l'ora locale del sistema per l'intestazione
|
||||
now_local = datetime.datetime.now()
|
||||
msg = f"📊 **REPORT VELOCITÀ 24H**\n📅 {now_local.strftime('%d/%m/%Y')}\n\n"
|
||||
|
||||
msg += "```text\n"
|
||||
msg += "ORA | DOWN | UP \n"
|
||||
msg += "------+------+-----\n"
|
||||
|
||||
for row in rows:
|
||||
# Conversione Bit -> Mbps
|
||||
d_val = (int(row[0]) * 8) / 1000000
|
||||
u_val = (int(row[1]) * 8) / 1000000
|
||||
|
||||
total_down += d_val
|
||||
total_up += u_val
|
||||
count += 1
|
||||
|
||||
marker = ""
|
||||
if d_val < WARN_DOWN or u_val < WARN_UP:
|
||||
issues += 1
|
||||
marker = "!"
|
||||
|
||||
# Parsing Data e CONVERSIONE TIMEZONE
|
||||
try:
|
||||
d_str = row[3].split(".")[0].replace("T", " ")
|
||||
# 1. Creiamo l'oggetto datetime e gli diciamo "Tu sei UTC"
|
||||
dt_utc = datetime.datetime.strptime(d_str, '%Y-%m-%d %H:%M:%S').replace(tzinfo=datetime.timezone.utc)
|
||||
|
||||
# 2. Convertiamo nell'orario locale del sistema (definito da TZ nel docker-compose)
|
||||
dt_local = dt_utc.astimezone()
|
||||
|
||||
time_str = dt_local.strftime('%H:%M')
|
||||
except:
|
||||
time_str = "--:--"
|
||||
|
||||
# Formattazione tabella
|
||||
row_str = f"{time_str} | {d_val:>4.0f} | {u_val:>3.0f} {marker}"
|
||||
msg += f"{row_str}\n"
|
||||
|
||||
msg += "```\n"
|
||||
|
||||
if count > 0:
|
||||
avg_d = total_down / count
|
||||
avg_u = total_up / count
|
||||
|
||||
icon_d = "✅" if avg_d >= WARN_DOWN else "⚠️"
|
||||
icon_u = "✅" if avg_u >= WARN_UP else "⚠️"
|
||||
|
||||
msg += f"📈 **MEDIA:**\n⬇️ {icon_d} `{avg_d:.0f}` Mbps\n⬆️ {icon_u} `{avg_u:.0f}` Mbps"
|
||||
|
||||
if issues > 0:
|
||||
msg += f"\n\n⚠️ **{issues}** test sotto soglia (!)"
|
||||
|
||||
return msg
|
||||
|
||||
if __name__ == "__main__":
|
||||
report = generate_report()
|
||||
if report:
|
||||
send_telegram_message(report)
|
||||
56
scripts/pi2-backup/dhcp-watchdog.sh
Executable file
56
scripts/pi2-backup/dhcp-watchdog.sh
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
# --- CONFIGURAZIONE ---
|
||||
MASTER_IP="192.168.128.80"
|
||||
CONFIG_FILE="/etc/pihole/pihole.toml"
|
||||
LOG_FILE="/var/log/dhcp-watchdog.log"
|
||||
|
||||
# Funzione per il logging
|
||||
log_message() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
# Funzione ROBUSTA v2 per leggere lo stato
|
||||
# Usa i campi ($1, $2) per ignorare gli spazi di indentazione
|
||||
is_dhcp_active() {
|
||||
val=$(awk '/^\[dhcp\]/{flag=1} flag && $1=="active" && $2=="=" {print $3; exit}' "$CONFIG_FILE")
|
||||
echo "$val"
|
||||
}
|
||||
|
||||
# Funzione per ATTIVARE (sed robusto)
|
||||
enable_dhcp() {
|
||||
# Cerca nel blocco [dhcp] e sostituisce mantenendo l'indentazione (\1)
|
||||
sudo sed -i '/^\[dhcp\]/,/^\[/ s/^\(\s*\)active\s*=\s*false/\1active = true/' "$CONFIG_FILE"
|
||||
sudo systemctl restart pihole-FTL
|
||||
}
|
||||
|
||||
# Funzione per DISATTIVARE (sed robusto)
|
||||
disable_dhcp() {
|
||||
sudo sed -i '/^\[dhcp\]/,/^\[/ s/^\(\s*\)active\s*=\s*true/\1active = false/' "$CONFIG_FILE"
|
||||
sudo systemctl restart pihole-FTL
|
||||
}
|
||||
|
||||
# --- LOGICA DI CONTROLLO ---
|
||||
|
||||
if ping -c 3 -W 5 "$MASTER_IP" &> /dev/null; then
|
||||
# MASTER VIVO
|
||||
CURRENT_STATUS=$(is_dhcp_active)
|
||||
if [ "$CURRENT_STATUS" == "true" ]; then
|
||||
log_message "RECOVERY: Master tornato online. Disattivo DHCP Backup."
|
||||
disable_dhcp
|
||||
log_message "STATO: DHCP disattivato."
|
||||
fi
|
||||
else
|
||||
# MASTER FORSE MORTO
|
||||
sleep 30
|
||||
if ! ping -c 3 -W 5 "$MASTER_IP" &> /dev/null; then
|
||||
# CONFERMATO MORTO
|
||||
CURRENT_STATUS=$(is_dhcp_active)
|
||||
if [ "$CURRENT_STATUS" == "false" ]; then
|
||||
log_message "EMERGENZA: Master irraggiungibile. Attivo DHCP Backup."
|
||||
enable_dhcp
|
||||
log_message "STATO: DHCP ATTIVO."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user