| 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) |