Smart home programming starter: MQTT clients in Python, C# and PHP (tested examples, Oct 2026)

A Place to discuss programming languages, APIs and software development
Post Reply
User avatar
ZerOne
Site Admin
Posts: 216
Joined: Sun Dec 13, 2020 8:21 am

Overview

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.
Python: paho-mqtt 2.1.0
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()
C#: MQTTnet 5.x
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();
Attach your message handler before connecting, as the samples do, or early messages are lost.

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();
Broker and security

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?
Post Reply

Return to “Programming and API Forums”