Hi,
I would like to create an application that connects to a MQTT server, fetch some data, and display it in a chart.
I’m able to subscribe to a MQTT topic from a button and refresh in real-time my chart but it goes wrong when i’m adding a button to stop the stream.
I’ve tried two approaches, one with loop_forever
:
import json
import streamlit as st
from paho.mqtt import client as mqtt
# Create a line chart
my_chart = st.line_chart([0.])
# Initialize MQTT client
mqtt_client = mqtt.Client()
# Connect to MQTT broker
mqtt_client.connect("broker.hivemq.com", 1883)
# Define a function to handle incoming MQTT messages
def on_message(client, userdata, msg):
my_chart.add_rows([float(json.loads(msg.payload)["temp"])])
# Set the function to handle incoming messages
mqtt_client.on_message = on_message
# Create a "Start subscription" button
if st.button("Start subscription"):
mqtt_client.subscribe("xxx")
mqtt_client.loop_forever()
# Create a "Stop subscription" button
if st.button("Stop subscription"):
mqtt_client.disconnect()
# Tried with loop_stop() as well, same issue
#mqtt_client.loop_stop()
if st.button("dummy"):
pass
But when I’m clicking the “Stop subscription” or even the “dummy” button, the whole webpage refreshes and i lose my data.
I’ve tried with loop_start
with another thread and a queue to update the chart, but this time I’m unable to stop the stream:
import json
import streamlit as st
from paho.mqtt import client as mqtt
import threading
import queue
# Initialize empty list to store data for the line chart
data = []
# Initialize MQTT client
mqtt_client = mqtt.Client()
# Connect to MQTT broker
mqtt_client.connect("broker.hivemq.com", 1883)
# create queue
q = queue.Queue()
# Define a function to handle incoming MQTT messages
def on_message(client, userdata, msg):
q.put(float(json.loads(msg.payload)["temp"]))
# Set the function to handle incoming messages
mqtt_client.on_message = on_message
# Define a function to run in a separate thread
def mqtt_thread():
mqtt_client.subscribe("xxx")
mqtt_client.loop_start()
# Create a line chart
chart = st.line_chart(data)
thread = None
running = True
# Create a "Start subscription" button
if st.button("Start subscription"):
thread = threading.Thread(target=mqtt_thread)
thread.start()
while running:
if not q.empty():
chart.add_rows([q.get()])
# Create a "Stop subscription" button
if st.button("Stop subscription"):
running = False
mqtt_client.loop_stop()
#thread.join()
mqtt_client.disconnect
Does someone see what’s wrong in my code ? Is it even possible to achieve such a thing on Streamlit?
Thanks in advance!