|
|
import streamlit as st |
|
|
import paho.mqtt.client as mqtt |
|
|
import json |
|
|
from queue import Queue |
|
|
from threading import Thread |
|
|
import pandas as pd |
|
|
import time |
|
|
|
|
|
st.title("Real-Time Sensor Data Dashboard") |
|
|
|
|
|
|
|
|
with st.form("mqtt_form"): |
|
|
MQTT_HOST = st.text_input("Enter your MQTT host:", "b6bdb89571144b3d8e5ca4bbe666ddb5.s1.eu.hivemq.cloud") |
|
|
MQTT_PORT = st.number_input("Enter the port number:", min_value=1, max_value=65535, value=8883) |
|
|
MQTT_USERNAME = st.text_input("Enter your MQTT username:", "LuthiraMQ") |
|
|
MQTT_PASSWORD = st.text_input("Enter your MQTT password:", "jLVx8y9v83gmgERTr0AP", type="password") |
|
|
MQTT_TOPIC = st.text_input("Enter your MQTT topic:", "sensors/bme680/data") |
|
|
submit_button = st.form_submit_button(label="Submit") |
|
|
|
|
|
if submit_button: |
|
|
st.success("MQTT Configuration Submitted") |
|
|
|
|
|
message_queue = Queue() |
|
|
|
|
|
def on_connect(client, userdata, flags, rc): |
|
|
if rc == 0: |
|
|
print("Connected to MQTT broker") |
|
|
client.subscribe(MQTT_TOPIC) |
|
|
else: |
|
|
print(f"Failed to connect, return code {rc}") |
|
|
|
|
|
def on_message(client, userdata, msg): |
|
|
try: |
|
|
message = msg.payload.decode() |
|
|
message_queue.put(message) |
|
|
except Exception as e: |
|
|
print(f"Error decoding message: {e}") |
|
|
|
|
|
def start_mqtt_client(): |
|
|
client = mqtt.Client() |
|
|
client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD) |
|
|
client.on_connect = on_connect |
|
|
client.on_message = on_message |
|
|
client.tls_set() |
|
|
|
|
|
try: |
|
|
client.connect(MQTT_HOST, MQTT_PORT, keepalive=60) |
|
|
client.loop_start() |
|
|
except Exception as e: |
|
|
print(f"Failed to connect to MQTT broker: {e}") |
|
|
|
|
|
Thread(target=start_mqtt_client, daemon=True).start() |
|
|
|
|
|
st.subheader("Live Sensor Data") |
|
|
col1, col2 = st.columns(2) |
|
|
with col1: |
|
|
st.markdown("### Temperature Over Time") |
|
|
temperature_chart = st.line_chart([]) |
|
|
with col2: |
|
|
st.markdown("### Humidity Over Time") |
|
|
humidity_chart = st.line_chart([]) |
|
|
|
|
|
pressure_gauge = st.empty() |
|
|
gas_gauge = st.empty() |
|
|
|
|
|
sensor_data = pd.DataFrame(columns=["timestamp", "temperature", "humidity", "pressure", "gas"]) |
|
|
|
|
|
while True: |
|
|
if not message_queue.empty(): |
|
|
message = message_queue.get() |
|
|
try: |
|
|
parsed_message = json.loads(message) |
|
|
|
|
|
|
|
|
temperature = parsed_message.get("temperature") |
|
|
humidity = parsed_message.get("humidity") |
|
|
pressure = parsed_message.get("pressure") |
|
|
gas = parsed_message.get("gas") |
|
|
timestamp = time.time() |
|
|
|
|
|
|
|
|
new_row = pd.DataFrame([{ |
|
|
"timestamp": timestamp, |
|
|
"temperature": temperature, |
|
|
"humidity": humidity, |
|
|
"pressure": pressure, |
|
|
"gas": gas, |
|
|
}]) |
|
|
sensor_data = pd.concat([sensor_data, new_row], ignore_index=True) |
|
|
temperature_chart.line_chart(sensor_data[["temperature"]]) |
|
|
humidity_chart.line_chart(sensor_data[["humidity"]]) |
|
|
pressure_gauge.metric( |
|
|
label="Pressure (hPa)", |
|
|
value=f"{pressure:.2f}" if pressure else "N/A", |
|
|
) |
|
|
gas_gauge.metric( |
|
|
label="Gas (ohms)", |
|
|
value=f"{gas:.2f}" if gas else "N/A", |
|
|
) |
|
|
except json.JSONDecodeError: |
|
|
st.error("Failed to parse JSON payload") |
|
|
|
|
|
time.sleep(0.1) |