Réorganisation fichiers .env
This commit is contained in:
12
.env
12
.env
@@ -1,9 +1,15 @@
|
|||||||
#connexion mysql
|
#connexion mysql
|
||||||
DB_HOST=162.19.78.131
|
DB_HOST=162.19.78.131
|
||||||
DB_USER=excel_auth
|
DB_USER=sondes
|
||||||
DB_PASSWORD=%n#%3Lay1MPa$%kR^5@
|
DB_PASSWORD=TX.)-U1!zq5Axdk4
|
||||||
DB_NAME=Sondes
|
DB_NAME=Sondes
|
||||||
AUTH_USERS=[{"user":"Michel","pass":"921#%!LC3^71509PiyK"}]
|
|
||||||
|
# MQTT
|
||||||
|
MQTT_HOST=162.19.78.131
|
||||||
|
MQTT_PORT=1883
|
||||||
|
MQTT_USER=sondes
|
||||||
|
MQTT_PASS=3J@bjYP0
|
||||||
|
|
||||||
|
|
||||||
# paramètres mail
|
# paramètres mail
|
||||||
SMTP_HOST=smtp.mail.ovh.net
|
SMTP_HOST=smtp.mail.ovh.net
|
||||||
|
|||||||
@@ -1,43 +1,49 @@
|
|||||||
Date;Lieu;Sonde;Température;Seuil;État
|
Date;Lieu;Sonde;Température;Seuil;État
|
||||||
2025-08-23 13:08:36;Saclay;Congelateur;-16.75;-15.0;Normal
|
2025-09-02 09:29:07;Saclay;Congelateur;-18.50;-15.0;Normal
|
||||||
2025-08-23 13:03:33;Saclay;Congelateur;-17.50;-15.0;Normal
|
2025-09-02 09:24:04;Saclay;Congelateur;-19.00;-15.0;Normal
|
||||||
2025-08-23 12:58:31;Saclay;Congelateur;-16.25;-15.0;Normal
|
2025-09-02 09:19:01;Saclay;Congelateur;-18.50;-15.0;Normal
|
||||||
2025-08-23 12:53:28;Saclay;Congelateur;-17.00;-15.0;Normal
|
2025-09-02 09:13:59;Saclay;Congelateur;-17.75;-15.0;Normal
|
||||||
2025-08-23 12:48:26;Saclay;Congelateur;-17.75;-15.0;Normal
|
2025-09-02 09:08:56;Saclay;Congelateur;-18.25;-15.0;Normal
|
||||||
2025-08-23 12:43:23;Saclay;Congelateur;-16.25;-15.0;Normal
|
2025-09-02 09:03:54;Saclay;Congelateur;-18.75;-15.0;Normal
|
||||||
2025-08-23 13:08:36;Saclay;BOF;2.00;8.0;Normal
|
2025-09-02 09:29:07;Saclay;BOF;2.50;8.0;Normal
|
||||||
2025-08-23 13:03:34;Saclay;BOF;1.25;8.0;Normal
|
2025-09-02 09:24:05;Saclay;BOF;0.75;8.0;Normal
|
||||||
2025-08-23 12:58:31;Saclay;BOF;1.00;8.0;Normal
|
2025-09-02 09:19:02;Saclay;BOF;2.00;8.0;Normal
|
||||||
2025-08-23 12:53:29;Saclay;BOF;2.00;8.0;Normal
|
2025-09-02 09:13:59;Saclay;BOF;2.00;8.0;Normal
|
||||||
2025-08-23 12:48:26;Saclay;BOF;0.50;8.0;Normal
|
2025-09-02 09:08:57;Saclay;BOF;0.75;8.0;Normal
|
||||||
2025-08-23 12:43:23;Saclay;BOF;2.50;8.0;Normal
|
2025-09-02 09:03:54;Saclay;BOF;1.75;8.0;Normal
|
||||||
2025-08-23 13:08:37;Saclay;Legumes;5.25;10.0;Normal
|
2025-09-02 09:29:08;Saclay;Viandes;2.75;6.0;Normal
|
||||||
2025-08-23 13:03:35;Saclay;Legumes;4.75;10.0;Normal
|
2025-09-02 09:24:05;Saclay;Viandes;2.00;6.0;Normal
|
||||||
2025-08-23 12:58:32;Saclay;Legumes;3.75;10.0;Normal
|
2025-09-02 09:19:02;Saclay;Viandes;4.75;6.0;Normal
|
||||||
2025-08-23 12:53:30;Saclay;Legumes;5.50;10.0;Normal
|
2025-09-02 09:14:00;Saclay;Viandes;4.25;6.0;Normal
|
||||||
2025-08-23 12:48:27;Saclay;Legumes;3.00;10.0;Normal
|
2025-09-02 09:08:57;Saclay;Viandes;3.75;6.0;Normal
|
||||||
2025-08-23 12:43:24;Saclay;Legumes;6.25;10.0;Normal
|
2025-09-02 09:03:55;Saclay;Viandes;2.50;6.0;Normal
|
||||||
2025-08-23 13:08:38;Saclay;MeP;4.75;8.0;Normal
|
2025-09-02 09:29:08;Saclay;Legumes;5.00;10.0;Normal
|
||||||
2025-08-23 13:03:35;Saclay;MeP;3.50;8.0;Normal
|
2025-09-02 09:24:06;Saclay;Legumes;4.50;10.0;Normal
|
||||||
2025-08-23 12:58:33;Saclay;MeP;3.75;8.0;Normal
|
2025-09-02 09:19:03;Saclay;Legumes;5.00;10.0;Normal
|
||||||
2025-08-23 12:53:30;Saclay;MeP;4.50;8.0;Normal
|
2025-09-02 09:14:00;Saclay;Legumes;5.50;10.0;Normal
|
||||||
2025-08-23 12:48:28;Saclay;MeP;3.00;8.0;Normal
|
2025-09-02 09:08:58;Saclay;Legumes;4.25;10.0;Normal
|
||||||
2025-08-23 12:43:25;Saclay;MeP;5.50;8.0;Normal
|
2025-09-02 09:03:55;Saclay;Legumes;5.75;10.0;Normal
|
||||||
2025-08-23 13:04:25;Meudon;Viandes;4.31;6.0;Normal
|
2025-09-02 09:29:09;Saclay;MeP;6.50;8.0;Normal
|
||||||
2025-08-23 12:59:24;Meudon;Viandes;4.13;6.0;Normal
|
2025-09-02 09:24:06;Saclay;MeP;3.00;8.0;Normal
|
||||||
2025-08-23 12:54:24;Meudon;Viandes;3.94;6.0;Normal
|
2025-09-02 09:19:03;Saclay;MeP;5.75;8.0;Normal
|
||||||
2025-08-23 12:49:23;Meudon;Viandes;3.75;6.0;Normal
|
2025-09-02 09:14:01;Saclay;MeP;7.25;8.0;Normal
|
||||||
2025-08-23 12:44:22;Meudon;Viandes;3.94;6.0;Normal
|
2025-09-02 09:08:58;Saclay;MeP;4.00;8.0;Normal
|
||||||
2025-08-23 12:39:21;Meudon;Viandes;4.13;6.0;Normal
|
2025-09-02 09:03:56;Saclay;MeP;4.25;8.0;Normal
|
||||||
2025-08-23 13:04:25;Meudon;Poissons;4.56;6.0;Normal
|
2025-09-02 09:30:38;Meudon;Viandes;4.69;6.0;Normal
|
||||||
2025-08-23 12:59:24;Meudon;Poissons;3.94;6.0;Normal
|
2025-09-02 09:25:37;Meudon;Viandes;5.38;6.0;Normal
|
||||||
2025-08-23 12:54:24;Meudon;Poissons;3.94;6.0;Normal
|
2025-09-02 09:20:36;Meudon;Viandes;5.25;6.0;Normal
|
||||||
2025-08-23 12:49:23;Meudon;Poissons;3.88;6.0;Normal
|
2025-09-02 09:15:36;Meudon;Viandes;4.88;6.0;Normal
|
||||||
2025-08-23 12:44:22;Meudon;Poissons;3.75;6.0;Normal
|
2025-09-02 09:10:35;Meudon;Viandes;4.69;6.0;Normal
|
||||||
2025-08-23 12:39:21;Meudon;Poissons;3.75;6.0;Normal
|
2025-09-02 09:05:34;Meudon;Viandes;4.44;6.0;Normal
|
||||||
2025-08-23 13:04:25;Meudon;BOF;2.00;8.0;Normal
|
2025-09-02 09:30:38;Meudon;Poissons;4.06;6.0;Normal
|
||||||
2025-08-23 12:59:24;Meudon;BOF;2.00;8.0;Normal
|
2025-09-02 09:25:37;Meudon;Poissons;4.13;6.0;Normal
|
||||||
2025-08-23 12:54:24;Meudon;BOF;2.25;8.0;Normal
|
2025-09-02 09:20:36;Meudon;Poissons;4.13;6.0;Normal
|
||||||
2025-08-23 12:49:23;Meudon;BOF;2.50;8.0;Normal
|
2025-09-02 09:15:36;Meudon;Poissons;3.94;6.0;Normal
|
||||||
2025-08-23 12:44:22;Meudon;BOF;2.50;8.0;Normal
|
2025-09-02 09:10:35;Meudon;Poissons;3.94;6.0;Normal
|
||||||
2025-08-23 12:39:21;Meudon;BOF;2.75;8.0;Normal
|
2025-09-02 09:05:34;Meudon;Poissons;4.25;6.0;Normal
|
||||||
|
2025-09-02 09:30:38;Meudon;BOF;3.25;8.0;Normal
|
||||||
|
2025-09-02 09:25:37;Meudon;BOF;2.50;8.0;Normal
|
||||||
|
2025-09-02 09:20:37;Meudon;BOF;2.50;8.0;Normal
|
||||||
|
2025-09-02 09:15:36;Meudon;BOF;2.50;8.0;Normal
|
||||||
|
2025-09-02 09:10:35;Meudon;BOF;2.25;8.0;Normal
|
||||||
|
2025-09-02 09:05:34;Meudon;BOF;2.50;8.0;Normal
|
||||||
|
|||||||
|
@@ -6,7 +6,13 @@ from utils_db import connect_to_mysql
|
|||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from utils_sms import envoyer_sms
|
from utils_sms import envoyer_sms
|
||||||
|
|
||||||
|
# === AJOUT GYRO (MQTT) ===
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
from contextlib import closing
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
# Logs
|
||||||
|
# -----------------------------------------------------------
|
||||||
if os.name != 'nt':
|
if os.name != 'nt':
|
||||||
log_dir = Path('/home/debian/Gestion_sondes/Logs')
|
log_dir = Path('/home/debian/Gestion_sondes/Logs')
|
||||||
else:
|
else:
|
||||||
@@ -14,15 +20,47 @@ else:
|
|||||||
|
|
||||||
log_dir.mkdir(parents=True, exist_ok=True)
|
log_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
# Env
|
||||||
|
# -----------------------------------------------------------
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
ENVOI_SMS = os.getenv("ENVOI_SMS") == "1"
|
ENVOI_SMS = os.getenv("ENVOI_SMS") == "1"
|
||||||
|
|
||||||
|
# === AJOUT GYRO (MQTT) ===
|
||||||
|
MQTT_HOST = os.getenv("MQTT_HOST", "127.0.0.1")
|
||||||
|
MQTT_PORT = int(os.getenv("MQTT_PORT", "1883"))
|
||||||
|
MQTT_USER = os.getenv("MQTT_USER", "")
|
||||||
|
MQTT_PASS = os.getenv("MQTT_PASS", "")
|
||||||
|
MQTT_QOS = 1
|
||||||
|
GYRO_PUBLISH_GLOBAL = os.getenv("GYRO_PUBLISH_GLOBAL", "0") == "1"
|
||||||
|
|
||||||
print("▶️ Lancement Monitor.py")
|
print("▶️ Lancement Monitor.py")
|
||||||
|
|
||||||
# --- Suivi des alertes actives pour rappels ---
|
# --- Suivi des alertes actives pour rappels ---
|
||||||
alertes_actives = {}
|
alertes_actives = {}
|
||||||
|
|
||||||
|
# === AJOUT GYRO (MQTT) ===
|
||||||
|
def publish_gyro_states(states_by_site: dict):
|
||||||
|
"""Publie Alarmes/<Site>/Gyro = ON|OFF (retained). Optionnel : Alarmes/Global/Gyro."""
|
||||||
|
client = mqtt.Client(client_id="MonitorGyroPublisher", clean_session=True)
|
||||||
|
if MQTT_USER or MQTT_PASS:
|
||||||
|
client.username_pw_set(MQTT_USER, MQTT_PASS)
|
||||||
|
client.connect(MQTT_HOST, MQTT_PORT, keepalive=30)
|
||||||
|
client.loop_start()
|
||||||
|
try:
|
||||||
|
for site, state in states_by_site.items():
|
||||||
|
topic = f"Alarmes/{site}/Gyro"
|
||||||
|
client.publish(topic, state, qos=MQTT_QOS, retain=True)
|
||||||
|
print(f"📣 MQTT publish {topic} = {state} (retain)", flush=True)
|
||||||
|
|
||||||
|
if GYRO_PUBLISH_GLOBAL:
|
||||||
|
global_state = "ON" if any(v == "ON" for v in states_by_site.values()) else "OFF"
|
||||||
|
client.publish("Alarmes/Global/Gyro", global_state, qos=MQTT_QOS, retain=True)
|
||||||
|
print(f"📣 MQTT publish Alarmes/Global/Gyro = {global_state} (retain)", flush=True)
|
||||||
|
finally:
|
||||||
|
client.loop_stop()
|
||||||
|
client.disconnect()
|
||||||
|
|
||||||
# --- Fonction de surveillance ---
|
# --- Fonction de surveillance ---
|
||||||
def surveiller():
|
def surveiller():
|
||||||
global alertes_actives
|
global alertes_actives
|
||||||
@@ -31,6 +69,7 @@ def surveiller():
|
|||||||
conn = connect_to_mysql()
|
conn = connect_to_mysql()
|
||||||
cursor = conn.cursor(dictionary=True)
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
# Liste des lieux
|
||||||
cursor.execute("SELECT DISTINCT Lieu FROM `Chambres_froides`")
|
cursor.execute("SELECT DISTINCT Lieu FROM `Chambres_froides`")
|
||||||
lieux = [row['Lieu'] for row in cursor.fetchall()]
|
lieux = [row['Lieu'] for row in cursor.fetchall()]
|
||||||
|
|
||||||
@@ -38,6 +77,7 @@ def surveiller():
|
|||||||
table_temp = lieu
|
table_temp = lieu
|
||||||
table_alertes = f"Alertes_{lieu}"
|
table_alertes = f"Alertes_{lieu}"
|
||||||
|
|
||||||
|
# Sondes actives et non en entretien
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
SELECT Sonde, Temp_Max
|
SELECT Sonde, Temp_Max
|
||||||
FROM Sondes.Chambres_froides
|
FROM Sondes.Chambres_froides
|
||||||
@@ -51,6 +91,7 @@ def surveiller():
|
|||||||
nom_sonde = sonde['Sonde']
|
nom_sonde = sonde['Sonde']
|
||||||
seuil = sonde['Temp_Max']
|
seuil = sonde['Temp_Max']
|
||||||
|
|
||||||
|
# Derniers relevés (30 min = 6 pas de 5 min)
|
||||||
cursor.execute(f"""
|
cursor.execute(f"""
|
||||||
SELECT Date, Temperature FROM {table_temp}
|
SELECT Date, Temperature FROM {table_temp}
|
||||||
WHERE Sonde = %s
|
WHERE Sonde = %s
|
||||||
@@ -58,6 +99,7 @@ def surveiller():
|
|||||||
""", (nom_sonde,))
|
""", (nom_sonde,))
|
||||||
releves = cursor.fetchall()
|
releves = cursor.fetchall()
|
||||||
|
|
||||||
|
# Logging détaillé
|
||||||
for r in releves:
|
for r in releves:
|
||||||
log_entries.append({
|
log_entries.append({
|
||||||
"Date": r['Date'],
|
"Date": r['Date'],
|
||||||
@@ -68,6 +110,7 @@ def surveiller():
|
|||||||
"État": "Dépassement" if r['Temperature'] > seuil else "Normal"
|
"État": "Dépassement" if r['Temperature'] > seuil else "Normal"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Détection dépassement > 30 min
|
||||||
if len(releves) == 6:
|
if len(releves) == 6:
|
||||||
toutes_hors_seuil = all(r['Temperature'] > seuil for r in releves)
|
toutes_hors_seuil = all(r['Temperature'] > seuil for r in releves)
|
||||||
plus_ancien = releves[-1]['Date']
|
plus_ancien = releves[-1]['Date']
|
||||||
@@ -96,6 +139,7 @@ def surveiller():
|
|||||||
alertes_actives[nom_sonde] = maintenant
|
alertes_actives[nom_sonde] = maintenant
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
# Rappel SMS toutes les 1h si toujours en défaut
|
||||||
dernier_envoi = alertes_actives.get(nom_sonde)
|
dernier_envoi = alertes_actives.get(nom_sonde)
|
||||||
if dernier_envoi and (maintenant - dernier_envoi >= timedelta(hours=1)):
|
if dernier_envoi and (maintenant - dernier_envoi >= timedelta(hours=1)):
|
||||||
message = (
|
message = (
|
||||||
@@ -106,7 +150,7 @@ def surveiller():
|
|||||||
envoyer_sms(lieu, message)
|
envoyer_sms(lieu, message)
|
||||||
alertes_actives[nom_sonde] = maintenant
|
alertes_actives[nom_sonde] = maintenant
|
||||||
|
|
||||||
# Vérifier retour à la normale (Acquittement)
|
# Vérifier retour à la normale (Acquittement)
|
||||||
cursor.execute(f"""
|
cursor.execute(f"""
|
||||||
SELECT Temperature FROM {table_temp}
|
SELECT Temperature FROM {table_temp}
|
||||||
WHERE Sonde = %s
|
WHERE Sonde = %s
|
||||||
@@ -123,14 +167,30 @@ def surveiller():
|
|||||||
if nom_sonde in alertes_actives:
|
if nom_sonde in alertes_actives:
|
||||||
del alertes_actives[nom_sonde]
|
del alertes_actives[nom_sonde]
|
||||||
|
|
||||||
|
# --- À ce stade : tables d'alertes mises à jour.
|
||||||
|
# On calcule l'état GYRO par site et on publie MQTT.
|
||||||
|
# === AJOUT GYRO (calcul + publication) ===
|
||||||
|
states = {}
|
||||||
|
for lieu in lieux:
|
||||||
|
table_alertes = f"Alertes_{lieu}"
|
||||||
|
# Etat actif si Status <> 'Acquitté'
|
||||||
|
cursor.execute(f"SELECT EXISTS(SELECT 1 FROM {table_alertes} WHERE Status <> 'Acquitté' LIMIT 1) AS actif")
|
||||||
|
actif = cursor.fetchone()
|
||||||
|
states[lieu] = "ON" if actif and list(actif.values())[0] == 1 else "OFF"
|
||||||
|
|
||||||
|
# Commit avant publication MQTT (les états reflètent la DB)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
|
# Publie ON/OFF par site (retain)
|
||||||
|
publish_gyro_states(states)
|
||||||
|
|
||||||
cursor.close()
|
cursor.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
# Ecriture log CSV
|
||||||
if log_entries:
|
if log_entries:
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
df_logs = pd.DataFrame(log_entries)
|
df_logs = pd.DataFrame(log_entries)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
df_logs.to_csv(log_dir / "monitor.csv", sep=";", index=False)
|
df_logs.to_csv(log_dir / "monitor.csv", sep=";", index=False)
|
||||||
print(f"✅ Log écrit dans {log_dir}/monitor.csv", flush=True)
|
print(f"✅ Log écrit dans {log_dir}/monitor.csv", flush=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user