Remise en état des relevés temp

This commit is contained in:
2025-11-14 21:31:40 +01:00
parent 367c6a10b8
commit dca69728e0
10 changed files with 643 additions and 608 deletions

188
app/Mqtt_meudon.py Normal file
View File

@@ -0,0 +1,188 @@
#!/usr/bin/env python3
"""
Mqtt_meudon.py
Récupère les mesures MQTT du site Meudon et les insère dans la table Sondes.Meudon.
"""
import os
import logging
from logging.handlers import RotatingFileHandler
import mysql.connector
from mysql.connector import Error
import paho.mqtt.client as mqtt
from paho.mqtt.client import CallbackAPIVersion
from dotenv import load_dotenv
# =========================
# Chargement du .env
# =========================
load_dotenv()
# --- MySQL (commun) ---
DB_HOST = os.getenv("DB_HOST")
DB_USER = os.getenv("DB_USER")
DB_PASS = os.getenv("DB_PASS")
DB_NAME = os.getenv("DB_NAME")
# --- MQTT Meudon ---
MQTT_HOST = os.getenv("MQTT_HOST_MEUDON", os.getenv("MQTT_HOST"))
MQTT_USER = os.getenv("MQTT_USER_MEUDON", os.getenv("MQTT_USER"))
MQTT_PASS = os.getenv("MQTT_PASS_MEUDON", os.getenv("MQTT_PASS"))
MQTT_PORT = int(os.getenv("MQTT_PORT_MEUDON", os.getenv("MQTT_PORT", 1883)))
GYRO_TOPIC_MEUDON = os.getenv("GYRO_MQTT_TOPIC_MEUDON", "Meudon/gyrophare")
# Nom de la table de destination
TABLE_NAME = "Meudon"
# =========================
# Logging
# =========================
def setup_logging():
logger = logging.getLogger()
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
"%(asctime)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
# Console
console = logging.StreamHandler()
console.setFormatter(formatter)
logger.addHandler(console)
# Logs fichier (même logique que Saclay)
log_dir = os.getenv("LOG_DIR", "./Logs")
try:
os.makedirs(log_dir, exist_ok=True)
file_handler = RotatingFileHandler(
os.path.join(log_dir, "Mqtt_meudon.log"),
maxBytes=1_000_000,
backupCount=5,
encoding="utf-8",
)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
except Exception as e:
logging.warning("Impossible de créer le fichier de log : %s", e)
# =========================
# Accès MySQL
# =========================
def insert_temperature(sonde: str, temperature: float) -> None:
"""
Insère une mesure dans la table Sondes.Meudon.
La colonne Date utilise CURRENT_TIMESTAMP par défaut dans MySQL.
"""
try:
conn = mysql.connector.connect(
host=DB_HOST,
user=DB_USER,
password=DB_PASS,
database=DB_NAME,
)
cursor = conn.cursor()
sql = f"INSERT INTO {TABLE_NAME} (Sonde, Temperature) VALUES (%s, %s)"
cursor.execute(sql, (sonde, temperature))
conn.commit()
logging.info("Insertion OK (Meudon) -> %s = %.2f", sonde, temperature)
except Error as e:
logging.exception("Erreur MySQL (Meudon) pour la sonde %s : %s", sonde, e)
finally:
try:
if cursor:
cursor.close()
if conn and conn.is_connected():
conn.close()
except Exception:
pass
# =========================
# Callbacks MQTT (API v2)
# =========================
def on_connect(client, userdata, flags, reason_code, properties=None):
if reason_code == 0:
logging.info("Connecté au broker MQTT Meudon (%s)", MQTT_HOST)
client.subscribe("Meudon/mod02/#")
logging.info("Abonné au topic : Meudon/#")
else:
logging.error("Échec de connexion MQTT (Meudon), code retour = %s", reason_code)
def on_message(client, userdata, msg: mqtt.MQTTMessage):
topic = msg.topic
payload_raw = msg.payload.decode("utf-8", errors="ignore").strip()
logging.debug("Msg reçu (Meudon) : topic=%s payload=%s", topic, payload_raw)
# On ignore le gyrophare
if topic == GYRO_TOPIC_MEUDON:
logging.debug("Topic gyrophare Meudon ignoré : %s", topic)
return
# Nom de la sonde = dernier segment du topic
sonde = topic.split("/")[-1] if "/" in topic else topic
# Conversion du payload en float
try:
value = float(payload_raw.replace(",", "."))
except ValueError:
logging.warning(
"Payload non numérique (Meudon), mesure ignorée (topic=%s, payload=%s)",
topic,
payload_raw,
)
return
insert_temperature(sonde, value)
# =========================
# Programme principal
# =========================
def main():
setup_logging()
logging.info("Démarrage du script Mqtt_meudon")
# Vérif minimale des variables d'env
for var in ["DB_HOST", "DB_USER", "DB_PASS", "DB_NAME"]:
if os.getenv(var) in (None, ""):
logging.error("Variable d'environnement %s manquante !", var)
client = mqtt.Client(
client_id="Mqtt_meudon_client",
callback_api_version=CallbackAPIVersion.VERSION2
)
client.username_pw_set(MQTT_USER, MQTT_PASS)
client.on_connect = on_connect
client.on_message = on_message
try:
client.connect(MQTT_HOST, MQTT_PORT, keepalive=60)
except Exception as e:
logging.exception("Impossible de se connecter au broker MQTT Meudon : %s", e)
return
logging.info("Boucle MQTT Meudon en cours (Ctrl+C pour arrêter)...")
try:
client.loop_forever()
except KeyboardInterrupt:
logging.info("Arrêt demandé par l'utilisateur (Meudon).")
finally:
client.disconnect()
logging.info("Client MQTT Meudon déconnecté.")
if __name__ == "__main__":
main()