FGPT / app.py
bhagwandas's picture
Update app.py
ff73cbe verified
raw
history blame
5 kB
# app.py - FactoryRAG+: Smart Chatbot with Role-Based Assistant, Dashboard, PDF, and Digital Twin
import streamlit as st
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sentence_transformers import SentenceTransformer
from transformers import pipeline
from sklearn.ensemble import IsolationForest
import base64
from io import BytesIO
from fpdf import FPDF
st.set_page_config(page_title="FactoryRAG+ - Smart Sensor Twin", layout="wide")
st.title("🏭 FactoryRAG+: Smart Dashboard with AI Monitoring, PDF Reporting & Digital Twin")
# Load models
EMBED_MODEL = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')
GEN_MODEL = pipeline('text2text-generation', model='google/flan-t5-base')
# Upload data
uploaded_file = st.sidebar.file_uploader("πŸ“‚ Upload your condition monitoring CSV", type=["csv"])
if uploaded_file:
df = pd.read_csv(uploaded_file)
numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
st.success("βœ… Data loaded successfully!")
st.subheader("πŸ“Š Sensor Snapshot")
st.dataframe(df.head())
# --- Multi-signal Dashboard ---
st.subheader("πŸ“ˆ Sensor Dashboard")
selected_cols = st.multiselect("Select signals to visualize", numeric_cols, default=numeric_cols[:3])
fig, ax = plt.subplots(len(selected_cols), 1, figsize=(8, 2 * len(selected_cols)))
if len(selected_cols) == 1:
ax = [ax]
for i, col in enumerate(selected_cols):
ax[i].plot(df[col], label=col)
ax[i].set_ylabel(col)
ax[i].legend()
st.pyplot(fig)
# --- Convert Logs to Chunks ---
def convert_to_chunks(df):
chunks = []
for idx, row in df.iterrows():
sentence = f"[Log {idx}] " + ", ".join([f"{col}: {row[col]:.2f}" for col in numeric_cols])
chunks.append(sentence)
return chunks
# Ensure initialization
if 'chunks' not in st.session_state or 'embeddings' not in st.session_state:
chunks = convert_to_chunks(df)
embeddings = EMBED_MODEL.encode(chunks)
st.session_state.chunks = chunks
st.session_state.embeddings = embeddings
# --- Anomaly Detection ---
st.subheader("🚨 Anomaly Detection (Isolation Forest)")
iso = IsolationForest(contamination=0.02)
anomaly_labels = iso.fit_predict(df[numeric_cols])
df['anomaly'] = ['❌' if x == -1 else '' for x in anomaly_labels]
st.dataframe(df[df['anomaly'] == '❌'].head(5))
# --- Digital Twin Summary ---
st.subheader("πŸ§ͺ Digital Twin Summary")
twin_report = ""
for col in selected_cols:
max_v = df[col].max()
min_v = df[col].min()
mean_v = df[col].mean()
twin_report += f"{col}\n→ Max: {max_v:.2f}, Min: {min_v:.2f}, Avg: {mean_v:.2f}\n\n"
st.code(twin_report)
# --- PDF Export ---
st.subheader("πŸ“€ Export Digital Twin Report as PDF")
pdf = FPDF()
pdf.add_page()
pdf.set_font("Arial", size=12)
pdf.multi_cell(0, 10, f"FactoryRAG+ Digital Twin Report\n\nSelected Signals: {', '.join(selected_cols)}\n\n" + twin_report)
pdf_bytes = pdf.output(dest='S').encode('latin1')
b64 = base64.b64encode(pdf_bytes).decode()
href = f'<a href="data:application/octet-stream;base64,{b64}" download="digital_twin_report.pdf">πŸ“„ Download PDF Report</a>'
st.markdown(href, unsafe_allow_html=True)
# --- Role-based Factory Assistant ---
st.subheader("πŸ’¬ Factory Assistant Chat")
roles = {
"Operator": "You are a machine operator. Provide practical insights and safety warnings.",
"Maintenance": "You are a maintenance technician. Suggest inspections and likely causes of sensor anomalies.",
"Engineer": "You are a control systems engineer. Offer analytical interpretations and system-level advice."
}
role = st.selectbox("πŸ‘€ Choose your role: Operator, Maintenance, or Engineer", list(roles.keys()))
if 'chat_history' not in st.session_state:
st.session_state.chat_history = []
user_input = st.text_input("Ask FactoryGPT anything (based on uploaded sensor logs):", key="chat_input")
if user_input:
query_vec = EMBED_MODEL.encode([user_input])[0]
sims = np.dot(st.session_state.embeddings, query_vec)
top_idxs = np.argsort(sims)[-3:][::-1]
context = "\n".join([st.session_state.chunks[i] for i in top_idxs])
system_prompt = roles[role]
full_prompt = f"{system_prompt}\n\nSensor Context:\n{context}\n\nUser Question: {user_input}"
reply = GEN_MODEL(full_prompt, max_length=256)[0]['generated_text']
st.session_state.chat_history.append(("You", user_input))
st.session_state.chat_history.append((f"{role} - FactoryGPT", reply))
for speaker, msg in st.session_state.chat_history[-10:]:
st.markdown(f"**{speaker}:** {msg}")
else:
st.info("πŸ‘ˆ Upload a sensor log CSV file to explore digital twin analysis, chatbot Q&A, waveform charts, anomaly detection, and PDF export.")