MQTT is the glue for a lot of home automation (Zigbee2MQTT, Tasmota, ESPHome, Home Assistant and more). Here are minimal clients in three languages that I ran against a local Mosquitto 2.0.21 broker, with the library versions that were current when I checked. This is separate from my GTK# threads. The same ideas apply whichever language you use.
MQTT in five lines
- Topics are slash-separated paths like home/lounge/temperature. In subscriptions, + matches one level and # matches the rest.
- QoS 0 is at most once, QoS 1 is at least once (expect duplicates), and QoS 2 is exactly once.
- Retained messages are stored by the broker and given to new subscribers, which suits state topics.
- Last Will: the broker publishes a message for you if you drop off without a clean disconnect, so you can mark a device offline.
- Subscribe inside your on-connect handler so subscriptions are restored after a reconnect.
Install with pip install paho-mqtt. Version 2.x needs the callback API version passed to the client. See the PyPI page and the project.
Code: Select all
import json, time
import paho.mqtt.client as mqtt
def on_connect(client, userdata, flags, reason_code, properties):
if not reason_code.is_failure:
client.subscribe("home/+/temperature", qos=1)
def on_message(client, userdata, msg):
print(msg.topic, msg.payload.decode("utf-8", errors="replace"))
c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="py-demo")
c.on_connect, c.on_message = on_connect, on_message
c.will_set("home/py-demo/status", "offline", qos=1, retain=True)
c.connect("127.0.0.1", 1883, keepalive=60)
c.loop_start()
time.sleep(0.5)
c.publish("home/lounge/temperature", json.dumps({"c": 22.4}), qos=1)
time.sleep(1)
c.loop_stop(); c.disconnect()Install with dotnet add package MQTTnet (I used 5.2.0.1603 on .NET 10). Older tutorials show the v3 API, which no longer matches. Current samples are in the MQTTnet repo, and the package is on NuGet.
Code: Select all
using MQTTnet;
using MQTTnet.Protocol;
var factory = new MqttClientFactory();
using var client = factory.CreateMqttClient();
client.ApplicationMessageReceivedAsync += e =>
{
Console.WriteLine($"{e.ApplicationMessage.Topic} -> {e.ApplicationMessage.ConvertPayloadToString()}");
return Task.CompletedTask;
};
var options = new MqttClientOptionsBuilder()
.WithTcpServer("127.0.0.1", 1883)
.WithClientId("cs-demo")
.WithWillTopic("home/cs-demo/status").WithWillPayload("offline").WithWillRetain(true)
.Build();
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(5));
await client.ConnectAsync(options, timeout.Token);
await client.SubscribeAsync(factory.CreateSubscribeOptionsBuilder()
.WithTopicFilter(f => f.WithTopic("home/+/temperature").WithAtLeastOnceQoS()).Build());
await client.PublishAsync(new MqttApplicationMessageBuilder()
.WithTopic("home/study/temperature").WithPayload("{\"c\":21.3}")
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce).Build());
await Task.Delay(1000);
await client.DisconnectAsync();PHP: php-mqtt/client 2.3.2
Install with composer require php-mqtt/client. It is a blocking client, so it suits CLI scripts and workers rather than web requests. See the project and Packagist.
Code: Select all
<?php
require __DIR__ . '/vendor/autoload.php';
use PhpMqtt\Client\{ConnectionSettings, MqttClient};
$mqtt = new MqttClient('127.0.0.1', 1883, 'php-demo');
$settings = (new ConnectionSettings())
->setKeepAliveInterval(60)
->setLastWillTopic('home/php-demo/status')
->setLastWillMessage('offline')
->setRetainLastWill(true);
$mqtt->connect($settings, true);
$mqtt->subscribe('home/+/temperature', function ($topic, $message) use ($mqtt) {
echo "$topic -> $message\n";
$mqtt->interrupt();
}, 1);
$mqtt->publish('home/hall/temperature', json_encode(['c' => 20.1]), 1);
$mqtt->loop(true);
$mqtt->disconnect();Use Mosquitto for local testing. Never test with real credentials on a public broker. On a LAN broker, turn off anonymous access, use per-client usernames and passwords (or client certificates), and use TLS if clients cross untrusted networks (see the mosquitto.conf docs). Load passwords from environment variables or a secrets file, never from source code you share.
Discussion: Which MQTT library do you use, and how do you handle reconnects and offline detection in long-running services?