Real time data update (using mqtt)

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?

Hi @AndreZ

Conceptually, you could have the app periodically check for any status change that would imply that the data has been updated. Once that occurs, you can tell the app to retrieve the updated data and process it as desired.

Please see this section from a blog on using Assembly AI with Streamlit for receiving transcription results (which takes time to compute and thus the apps periodically checks if the status has changed from processing to complete. Once complete, the results are retrieved. You can adapt this to your use case.

Hope this help!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.