Ajout foctions dans l'app

This commit is contained in:
2025-06-01 09:54:35 +02:00
parent 45c4c3756c
commit b3c70abb6a
3 changed files with 156 additions and 9 deletions

View File

@@ -1,8 +1,25 @@
import streamlit as st
import pandas as pd
from utils.db import get_latest_chaufferie, get_history_by_sonde, verifier_utilisateur_commun
import mysql.connector
from utils.db import (
get_latest_chaufferie,
get_history_by_sonde,
verifier_utilisateur_commun,
lire_alertes_sondes,
acquitter_alerte
)
import altair as alt
from dotenv import load_dotenv
import os
st.set_page_config(page_title="Tech Chaufferie", layout="wide")
load_dotenv() # charger .env à la racine du projet
# Accès aux variables d'environnement
MYSQL_HOST = os.getenv("DB_HOST")
MYSQL_USER = os.getenv("DB_USER")
MYSQL_PASSWORD = os.getenv("DB_PASSWORD")
MYSQL_DATABASE = os.getenv("DB_NAME")
def login_commun():
login = st.text_input("Identifiant", type="default")
@@ -58,17 +75,108 @@ for topic in df["Topic"].unique():
st.markdown("---")
st.header("📈 Historique par sonde (24h)")
# Ce bloc doit exister pour que sonde_selection soit défini
sonde_selection = st.selectbox("Choisir une sonde à afficher", df["Sonde"].unique())
if sonde_selection:
historique = get_history_by_sonde(sonde_selection)
if historique:
df_hist = pd.DataFrame(historique)
df_hist["Date"] = pd.to_datetime(df_hist["Date"])
df_hist["Temperature"] = pd.to_numeric(df_hist["Temperature"], errors="coerce")
st.line_chart(
df_hist.set_index("Date")["Temperature"],
use_container_width=True
# ✅ Message si -127°C détecté
if (df_hist["Temperature"] <= -126).any():
st.error("🚨 Sonde défaillante détectée (-127°C). Vérification urgente requise.")
# ✅ Ligne limite (modifiable ici)
limite = 80
ligne_limite = alt.Chart(pd.DataFrame({
"y": [limite]
})).mark_rule(color="red").encode(y="y")
# ✅ Points rouge si erreur (-127°C)
alerte_sonde = alt.Chart(df_hist[df_hist["Temperature"] <= -126]).mark_point(
shape="cross", color="red", size=100
).encode(
x="Date:T",
y="Temperature:Q",
tooltip=["Date:T", "Temperature:Q"]
)
# Insérer une alerte dans Mysql en cas de sonde défectueuse
def inserer_alerte_defaut_sonde(sonde, date_defaut):
conn = None
cursor = None
try:
conn = mysql.connector.connect(
host=MYSQL_HOST,
user=MYSQL_USER,
password=MYSQL_PASSWORD,
database=MYSQL_DATABASE
)
cursor = conn.cursor()
# Vérifie s'il existe déjà une alerte en cours
query_check = """
SELECT COUNT(*) FROM Alertes_Chaufferie
WHERE Sonde = %s AND Etat = 'En cours'
"""
cursor.execute(query_check, (sonde,))
count = cursor.fetchone()[0]
if count == 0:
# Date du premier -127°C détecté
date_defaut = df_hist[df_hist["Temperature"] <= -126]["Date"].min()
query_insert = """
INSERT INTO Alertes_Chaufferie (Sonde, Debut_defaut, Etat)
VALUES (%s, %s, 'En cours')
"""
cursor.execute(query_insert, (sonde, date_defaut))
conn.commit()
except Exception as e:
st.warning(f"⚠️ Erreur enregistrement alerte : {e}")
finally:
if cursor:
cursor.close()
if conn and conn.is_connected():
conn.close()
# 🔁 Appel de la fonction si -127 détecté
if (df_hist["Temperature"] <= -126).any():
inserer_alerte_defaut_sonde(sonde_selection, df_hist["Date"].min())
# ✅ Graphique principal
chart = alt.Chart(df_hist).mark_line().encode(
x=alt.X("Date:T", title="Date"),
y=alt.Y("Temperature:Q", title="Température (°C)", scale=alt.Scale(domain=[-130, 100])),
tooltip=["Date:T", "Temperature:Q"]
).properties(
width=900,
height=400,
title=f"Évolution sur 24h de {sonde_selection}"
)
st.altair_chart(chart + ligne_limite + alerte_sonde, use_container_width=True)
else:
st.info("Aucune donnée disponible pour cette sonde dans les dernières 24h.")
st.markdown("---")
st.header("🧯 Alertes sondes défaillantes")
alertes = lire_alertes_sondes()
if alertes:
for alerte in alertes:
col1, col2, col3, col4 = st.columns([3, 3, 2, 2])
col1.markdown(f"**Sonde :** {alerte['Sonde']}")
col2.markdown(f"**Défaut depuis :** {alerte['Debut_defaut'].strftime('%Y-%m-%d %H:%M')}")
col3.markdown(f"**État :** :orange[{alerte['Etat']}]")
if alerte['Etat'] != 'Acquitté':
if col4.button("✅ Acquitter", key=f"acquitter_{alerte['Id']}"):
acquitter_alerte(alerte['Id'])
st.rerun()
else:
st.success("Aucune alerte active.")

View File

@@ -8,7 +8,10 @@ paho-mqtt~=2.1.0
requests~=2.32.3
schedule~=1.2.2
paramiko~=3.5.1
dotenv
fpdf
ovh
bcrypt
dotenv~=0.9.9
fpdf~=1.7.2
ovh~=1.2.0
bcrypt~=4.3.0
altair
python-dotenv~=1.1.0
altair~=5.5.0

View File

@@ -4,6 +4,42 @@ from dotenv import load_dotenv
load_dotenv()
def lire_alertes_sondes():
conn = None
cursor = None
try:
conn = get_connection()
cursor = conn.cursor(dictionary=True)
cursor.execute("SELECT * FROM Alertes_Chaufferie ORDER BY Debut_defaut DESC")
return cursor.fetchall()
except Exception as e:
import streamlit as st
st.warning(f"Erreur lecture alertes : {e}")
return []
finally:
if cursor:
cursor.close()
if conn and conn.is_connected():
conn.close()
def acquitter_alerte(id_alerte):
conn = None
cursor = None
try:
conn = get_connection()
cursor = conn.cursor()
cursor.execute("UPDATE Alertes_Chaufferie SET Etat = 'Acquitté' WHERE Id = %s", (id_alerte,))
conn.commit()
except Exception as e:
import streamlit as st
st.warning(f"Erreur lors de l'acquittement : {e}")
finally:
if cursor:
cursor.close()
if conn and conn.is_connected():
conn.close()
def verifier_utilisateur_commun(login, password):
conn = get_connection()
cursor = conn.cursor(dictionary=True)