Hi there,
There is a great project dash-mqtt developed by @aegis1980 .
Let me dig up my old toy and try this.
This is a temperature and humidity meter, which consists of an Esp8266 microcontroller, a dht12 sensor, and a small oled screen. The classic 8266 has a built-in wifi module, which allows me to send sensor data over a wireless network.
I used MicroPython to implement the control logic, the drivers can be found here and here. I recommend Thonny this IDE.
Sending and receiving MQTT requires a broker server, and dash-mqtt uses the MQTT over WebSockets, so the server also needs to listen to WS.
Then I can observe the changes in the room temperature.
Here’s my code.
from dash import Dash, Input, Output, State, html, dcc, no_update
import dash_mqtt
import plotly.graph_objects as go
from collections import deque
import json
import pandas as pd
TEST_SERVER = 'my_sever'
TEST_SERVER_PORT = 8883
TEST_SERVER_PATH = None
MESSAGE_OUT_TOPIC = 'Notification'
MESSAGE_IN_TOPIC = 'home/dht12_state'
Q = deque(maxlen=60)
app = Dash(__name__)
app.layout = html.Div([
html.H1('MQTT Thermo-hygrometer'),
fig := dcc.Graph(),
ipt := dcc.Input(placeholder='message to send',
debounce=True), btn := html.Button('Send'),
dash_mqtt.DashMqtt(id='mqtt',
broker_url=TEST_SERVER,
broker_port=TEST_SERVER_PORT,
broker_path=TEST_SERVER_PATH,
topics=[MESSAGE_IN_TOPIC])
])
@app.callback(Output('mqtt', 'message'), Input(btn, 'n_clicks'),
State(ipt, 'value'))
def display_output(n_clicks, message_payload):
if n_clicks:
return {'topic': MESSAGE_OUT_TOPIC, 'payload': message_payload}
return no_update
@app.callback(Output(fig, 'figure'), Input('mqtt', 'incoming'))
def update_fig(incoming_message):
if (incoming_message):
msg = json.loads(incoming_message['payload'])
msg['time'] = pd.Timestamp(*msg['time'][:-2])
Q.append(msg)
df = pd.DataFrame(data=Q, columns=["humidity", "temperature", "time"])
fig = go.Figure()
fig.add_trace(
go.Scatter(x=df['time'],
y=df["humidity"],
mode='lines',
name='humidity'))
fig.add_trace(
go.Scatter(x=df['time'],
y=df["temperature"],
mode='lines+markers',
name='temperature'))
fig.update_layout(xaxis=dict(range=[
df['time'].max() - pd.Timedelta(5, unit='min'), df['time'].max()
]))
return fig
else:
return no_update
if __name__ == "__main__":
app.run_server(debug=True)
It might be a good idea to replace the Home Assistant’s built-in visualization module with Dash.
Hope you like this. XD
Keywords: MQTT, ESP8266, MicroPython, WebSockets
Other Daily Tips series:
Daily Tips - If I have a Bunch of Triggers
Daily Tips - Share the Function
Daily Tips - How many Ways to share Dash in a company?
Daily Tips - Give your Component a Name
Daily Tips - Share Dash to Social Media
Daily Tips - Double-click to open Dash
Daily Tips - What rows of data have I modified?
Daily Tips - Write the Simplest Client-side Callback
Daily Tips - Some simple Expressions