Remise en état des relevés temp
This commit is contained in:
188
app/Mqtt_meudon.py
Normal file
188
app/Mqtt_meudon.py
Normal 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()
|
||||
Reference in New Issue
Block a user