Ajout foctions dans l'app
This commit is contained in:
118
Technique.py
118
Technique.py
@@ -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.")
|
||||
|
||||
|
||||
@@ -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
|
||||
36
utils/db.py
36
utils/db.py
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user