Changement d'adresse IP
This commit is contained in:
8
.env
8
.env
@@ -1,18 +1,18 @@
|
|||||||
# connexion mysql
|
# connexion mysql
|
||||||
DB_HOST=localhost
|
DB_HOST=192.168.1.100
|
||||||
DB_USER=sondes
|
DB_USER=sondes
|
||||||
DB_PASS=TX.)-U1!zq5Axdk4
|
DB_PASS=TX.)-U1!zq5Axdk4
|
||||||
DB_NAME=Sondes
|
DB_NAME=Sondes
|
||||||
|
|
||||||
DB_USER2=journal_connexions
|
DB_USER2=journal_connexions
|
||||||
DB_PASS2=uu%O6sHgqY%gl&iSMML
|
DB_PASS2=wQ%geAx*2%%HiE2a!9S
|
||||||
DB_NAME2=Acces
|
DB_NAME2=Acces
|
||||||
|
|
||||||
AUTH_USERS=[{"user":"Michel","pass":"210462"}]
|
AUTH_USERS=[{"user":"Michel","pass":"210462"}]
|
||||||
|
|
||||||
# MQTT
|
# MQTT
|
||||||
MQTT_HOST=162.19.78.131
|
MQTT_HOST=192.168.1.100
|
||||||
MQTT_USER=sondes
|
MQTT_USER=Sondes
|
||||||
MQTT_PASS=3J@bjYP0
|
MQTT_PASS=3J@bjYP0
|
||||||
MQTT_PORT=1883
|
MQTT_PORT=1883
|
||||||
|
|
||||||
|
|||||||
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
@@ -3,6 +3,7 @@
|
|||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/Gestion sondes.iml" filepath="$PROJECT_DIR$/.idea/Gestion sondes.iml" />
|
<module fileurl="file://$PROJECT_DIR$/.idea/Gestion sondes.iml" filepath="$PROJECT_DIR$/.idea/Gestion sondes.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/pandas.iml" filepath="$PROJECT_DIR$/.idea/pandas.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Mqtt_Meudon.py (version nettoyée)
|
Mqtt_Meudon.py
|
||||||
--------------------------------
|
--------------------------------
|
||||||
- S'abonne à Meudon/# sur le broker MQTT
|
- S'abonne à Meudon/# sur le broker MQTT
|
||||||
- Parse les messages (topic -> nom de sonde, payload -> température)
|
- Parse les messages (topic -> nom de sonde, payload -> température)
|
||||||
@@ -36,24 +36,30 @@ from mysql.connector.cursor import MySQLCursor
|
|||||||
# =========================
|
# =========================
|
||||||
# Configuration (ENV)
|
# Configuration (ENV)
|
||||||
# =========================
|
# =========================
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
MQTT_HOST = os.getenv("MQTT_HOST", "127.0.0.1")
|
load_dotenv()
|
||||||
MQTT_PORT = int(os.getenv("MQTT_PORT", "1883"))
|
|
||||||
MQTT_USER = os.getenv("MQTT_USER", "")
|
|
||||||
MQTT_PASS = os.getenv("MQTT_PASS", "")
|
|
||||||
|
|
||||||
DB_HOST = os.getenv("DB_HOST", "127.0.0.1")
|
DB_HOST = os.getenv("DB_HOST", "localhost")
|
||||||
DB_USER = os.getenv("DB_USER", "root")
|
DB_USER = os.getenv("DB_USER")
|
||||||
DB_PASS = os.getenv("DB_PASS", "")
|
DB_PASS = os.getenv("DB_PASS")
|
||||||
DB_NAME = os.getenv("DB_NAME", "Sondes")
|
DB_NAME = os.getenv("DB_NAME", "Sondes")
|
||||||
|
|
||||||
DB_TABLE = os.getenv("DB_TABLE", "Meudon")
|
DB_TABLE = os.getenv("DB_TABLE", "Meudon")
|
||||||
|
|
||||||
LOG_FILE = os.getenv("LOG_FILE", "Mqtt_meudon.log")
|
|
||||||
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
|
|
||||||
|
|
||||||
DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "5"))
|
DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "5"))
|
||||||
|
|
||||||
|
MQTT_HOST = os.getenv("MQTT_HOST", "192.168.1.100")
|
||||||
|
MQTT_USER = os.getenv("MQTT_USER", "Sondes")
|
||||||
|
MQTT_PASS = os.getenv("MQTT_PASS", "3J@bjYP0")
|
||||||
|
MQTT_PORT = int(os.getenv("MQTT_PORT", "1883"))
|
||||||
|
|
||||||
|
GYRO_TOPIC_MEUDON = os.getenv("GYRO_MQTT_TOPIC_MEUDON", "Meudon/gyrophare")
|
||||||
|
|
||||||
|
LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper()
|
||||||
|
LOG_FILE = os.getenv(
|
||||||
|
"LOG_FILE",
|
||||||
|
"/home/domo91/Gestion_sondes/Logs/cuisine_meudon_script.log"
|
||||||
|
)
|
||||||
# =========================
|
# =========================
|
||||||
# Logging
|
# Logging
|
||||||
# =========================
|
# =========================
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ DB_USER = os.getenv("DB_USER")
|
|||||||
DB_PASS = os.getenv("DB_PASS")
|
DB_PASS = os.getenv("DB_PASS")
|
||||||
DB_NAME = os.getenv("DB_NAME")
|
DB_NAME = os.getenv("DB_NAME")
|
||||||
|
|
||||||
MQTT_HOST = "162.19.78.131"
|
MQTT_HOST = "192.168.1.100"
|
||||||
MQTT_USER = "sondes"
|
MQTT_USER = "Sondes"
|
||||||
MQTT_PASS = "3J@bjYP0"
|
MQTT_PASS = "3J@bjYP0"
|
||||||
MQTT_PORT = int(os.getenv("MQTT_PORT", 1883))
|
MQTT_PORT = int(os.getenv("MQTT_PORT", 1883))
|
||||||
|
|
||||||
|
|||||||
@@ -949,7 +949,8 @@ if st.session_state.get("authenticated"):
|
|||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
styled_df = df_sonde.style.applymap(surlignage_temp, subset=["Temperature"])
|
|
||||||
|
styled_df = df_sonde.style.map(surlignage_temp, subset=["Temperature"])
|
||||||
st.dataframe(styled_df, use_container_width=True)
|
st.dataframe(styled_df, use_container_width=True)
|
||||||
|
|
||||||
st.subheader("📈 Évolution de la température")
|
st.subheader("📈 Évolution de la température")
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
@@ -51,8 +52,12 @@ load_dotenv(ENV_PATH, override=True)
|
|||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
TABLES = ["Saclay", "Meudon"]
|
# Table de configuration : seuls les sites avec Actif = 'ON' seront surveillés.
|
||||||
TABLES_SET = set(TABLES)
|
TABLE_SITES_SURVEILLANCE = "Sites_Surveillance"
|
||||||
|
|
||||||
|
# Sécurité / secours : utilisé uniquement si la table Sites_Surveillance est absente
|
||||||
|
# ou si elle ne retourne aucun site actif.
|
||||||
|
TABLES_FALLBACK = ["Saclay", "Meudon"]
|
||||||
|
|
||||||
DELAI_MINUTES = 15
|
DELAI_MINUTES = 15
|
||||||
RAPPEL_HEURES = 6
|
RAPPEL_HEURES = 6
|
||||||
@@ -269,8 +274,23 @@ def envoyer_notifications(site: str, sujet: str, message: str) -> None:
|
|||||||
# ACCES BASE
|
# ACCES BASE
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
|
def is_safe_identifier(name: str) -> bool:
|
||||||
|
"""
|
||||||
|
Autorise uniquement les noms simples de tables/sites :
|
||||||
|
lettres, chiffres et underscore.
|
||||||
|
Cela évite toute injection SQL via un nom de table dynamique.
|
||||||
|
"""
|
||||||
|
return bool(re.fullmatch(r"[A-Za-z0-9_]+", name or ""))
|
||||||
|
|
||||||
|
|
||||||
|
def quote_identifier(name: str) -> str:
|
||||||
|
if not is_safe_identifier(name):
|
||||||
|
raise ValueError(f"Nom de table/site invalide : {name!r}")
|
||||||
|
return f"`{name}`"
|
||||||
|
|
||||||
|
|
||||||
def get_last_update(cursor, table: str) -> datetime | None:
|
def get_last_update(cursor, table: str) -> datetime | None:
|
||||||
cursor.execute(f"SELECT MAX(Date) FROM `{table}`")
|
cursor.execute(f"SELECT MAX(Date) FROM {quote_identifier(table)}")
|
||||||
row = cursor.fetchone()
|
row = cursor.fetchone()
|
||||||
|
|
||||||
if not row or row[0] is None:
|
if not row or row[0] is None:
|
||||||
@@ -284,19 +304,77 @@ def get_last_update(cursor, table: str) -> datetime | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_tables_a_surveiller(cursor) -> list[str]:
|
||||||
|
"""
|
||||||
|
Lit la table Sites_Surveillance.
|
||||||
|
Seuls les sites Actif = 'ON' sont surveillés.
|
||||||
|
Les sites Actif = 'OFF' sont journalisés mais ignorés.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
cursor.execute(f"""
|
||||||
|
SELECT Lieu, Actif, Commentaire
|
||||||
|
FROM {quote_identifier(TABLE_SITES_SURVEILLANCE)}
|
||||||
|
ORDER BY Lieu
|
||||||
|
""")
|
||||||
|
rows = cursor.fetchall()
|
||||||
|
|
||||||
|
except mysql.connector.Error as e:
|
||||||
|
logging.error(
|
||||||
|
"Impossible de lire %s : %s. Utilisation du fallback : %s",
|
||||||
|
TABLE_SITES_SURVEILLANCE,
|
||||||
|
e,
|
||||||
|
", ".join(TABLES_FALLBACK),
|
||||||
|
)
|
||||||
|
return TABLES_FALLBACK.copy()
|
||||||
|
|
||||||
|
tables_actives: list[str] = []
|
||||||
|
|
||||||
|
for lieu, actif, commentaire in rows:
|
||||||
|
lieu = str(lieu).strip()
|
||||||
|
actif = str(actif).strip().upper()
|
||||||
|
|
||||||
|
if not is_safe_identifier(lieu):
|
||||||
|
logging.warning("Site ignoré dans %s : nom invalide %r", TABLE_SITES_SURVEILLANCE, lieu)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if actif == "ON":
|
||||||
|
tables_actives.append(lieu)
|
||||||
|
else:
|
||||||
|
if commentaire:
|
||||||
|
logging.info("⏸️ %s ignoré : surveillance OFF (%s)", lieu, commentaire)
|
||||||
|
else:
|
||||||
|
logging.info("⏸️ %s ignoré : surveillance OFF", lieu)
|
||||||
|
|
||||||
|
if not tables_actives:
|
||||||
|
logging.warning(
|
||||||
|
"Aucun site actif dans %s. Utilisation du fallback : %s",
|
||||||
|
TABLE_SITES_SURVEILLANCE,
|
||||||
|
", ".join(TABLES_FALLBACK),
|
||||||
|
)
|
||||||
|
return TABLES_FALLBACK.copy()
|
||||||
|
|
||||||
|
logging.info("Sites surveillés : %s", ", ".join(tables_actives))
|
||||||
|
return tables_actives
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# TRAITEMENT DES TABLES
|
# TRAITEMENT DES TABLES
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
def traiter_table(cursor, table: str, limite: datetime,
|
def traiter_table(cursor, table: str, limite: datetime,
|
||||||
|
tables_autorisees: set[str],
|
||||||
defauts_en_cours: list[str],
|
defauts_en_cours: list[str],
|
||||||
alertes_envoyees: list[str],
|
alertes_envoyees: list[str],
|
||||||
erreurs_sql: list[str]) -> None:
|
erreurs_sql: list[str]) -> None:
|
||||||
"""
|
"""
|
||||||
Gère la surveillance d'une table.
|
Gère la surveillance d'une table.
|
||||||
"""
|
"""
|
||||||
if table not in TABLES_SET:
|
if table not in tables_autorisees:
|
||||||
logging.warning(f"Table ignorée (non whitelistée) : {table}")
|
logging.warning(f"Table ignorée (non autorisée) : {table}")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not is_safe_identifier(table):
|
||||||
|
logging.warning(f"Table ignorée (nom invalide) : {table}")
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -386,11 +464,15 @@ def main() -> None:
|
|||||||
with closing(cnx):
|
with closing(cnx):
|
||||||
cursor = cast(MySQLCursor, cnx.cursor())
|
cursor = cast(MySQLCursor, cnx.cursor())
|
||||||
with closing(cursor):
|
with closing(cursor):
|
||||||
for table in TABLES:
|
tables_a_surveiller = get_tables_a_surveiller(cursor)
|
||||||
|
tables_autorisees = set(tables_a_surveiller)
|
||||||
|
|
||||||
|
for table in tables_a_surveiller:
|
||||||
traiter_table(
|
traiter_table(
|
||||||
cursor=cursor,
|
cursor=cursor,
|
||||||
table=table,
|
table=table,
|
||||||
limite=limite,
|
limite=limite,
|
||||||
|
tables_autorisees=tables_autorisees,
|
||||||
defauts_en_cours=defauts_en_cours,
|
defauts_en_cours=defauts_en_cours,
|
||||||
alertes_envoyees=alertes_envoyees,
|
alertes_envoyees=alertes_envoyees,
|
||||||
erreurs_sql=erreurs_sql,
|
erreurs_sql=erreurs_sql,
|
||||||
|
|||||||
Reference in New Issue
Block a user