Hi,
I am building a device that sends lap times for my son’s slot car track through mqtt and would like to display them in a Streamlit app. I would like real time updates and avoid using a refresh or something inside a loop.
This is my demo code:
Code snippet:
import paho.mqtt.client as mqtt
import streamlit as st
import os
from time import sleep
# MQTT settings
MQTT_BROKER = os.getenv("MQTT_HOST")
MQTT_PORT = int(os.getenv("MQTT_PORT"))
MQTT_TOPIC = "sensor_01_02_time_difference"
MQTT_USER = os.getenv("MQTT_USER")
MQTT_PW = os.getenv("MQTT_PW")
# Streamlit app
st.title("MQTT Metric Display")
# Initialize the metric value
metric_value = 0
st.session_state.time_diff = 0
container = st.container()
# Display the metric
st.metric("Metric Value", metric_value)
st.metric("Metric Value", st.session_state.time_diff)
# Callback function when a message is received
def on_message(client, userdata, message):
global metric_value
metric_value = int(message.payload.decode())
st.session_state.time_diff = metric_value
print(f"Received value: {metric_value}")
st.rerun()
# Create an MQTT client
client = mqtt.Client()
client.on_message = on_message
# Connect to the MQTT broker and subscribe to the topic
def connect_to_mqtt():
client.username_pw_set(username=MQTT_USER, password=MQTT_PW)
client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.subscribe(MQTT_TOPIC)
client.loop_start()
# Function to check if MQTT is connected
def is_mqtt_connected():
return client.is_connected()
# Check MQTT connection and reconnect if necessary
if not is_mqtt_connected():
print("Connecting to MQTT...")
connect_to_mqtt()
print("Connected to MQTT!")
# Display the metric
st.metric("Metric Value", metric_value)
st.metric("Metric Value", st.session_state.time_diff)
container.metric("Metric Value", metric_value)
container.metric("Metric Value", st.session_state.time_diff)
In this code, I now have six displays of the metric, as I was at some point just trying everything out. I wish when the on_message function gets called, one of them would update with the new value.
Actual behavior:
I get the print message in the on_message function (actually twice, no idea why) every time a message is sent to the mqtt topic.
Non of the displayed metrics updates to the new value.
I have seen this post here:
https://blog.streamlit.io/how-to-build-a-real-time-live-dashboard-with-streamlit/
But it did not help and also seems to simply run a loop and sleep.
Is it really not possible to somehow trigger an update as soon and only when a new mqtt message arrives?