Skip to content

Don't miss the unveiling of HiveMQ Pulse with Walker Reynolds! Join the webinar

HiveMQ on Raspberry Pi: As an MQTT Broker and an MQTT Client

by Bill Sommers
17 min read

Raspberry Pi single board computers (SBCs) are very powerful yet inexpensive computers readily available for use in IoT and IIoT settings to connect a wide array of sensors to an MQTT-centric data system. With Raspberry Pi clients in the field and HiveMQ Platform installed throughout your IIoT networks, you can make intelligent, actionable use of your data. Add HiveMQ Pulse into this mix, and you’ve got an excellent basis for your AI strategy, powering maximum use of your data at scale.

In this article, we’ll install HiveMQ on a Raspberry Pi. We’ll show you how to connect to a HiveMQ Cloud Broker and use the Raspberry Pi as an MQTT Client. We’ll cover installing HiveMQ on a Raspberry Pi to act as a plant or satellite broker, installing a Python MQTT Client to connect to the HiveMQ Broker; and writing the Python MQTT client.

Tutorial Overview

  • Prepare the Raspberry PI(s) and install the necessary software

  • Start the HiveMQ MQTT Broker

  • Create the HiveMQ Raspberry Pi Client

  • Run the code

  • View and analyze the output

Prerequisites

Run through the following checklist, and gather what you need to prepare for this exercise. 

Hardware Checklist:

  • A Raspberry Pi (Model 3B+ or newer recommended for built-in Wi-Fi).

  • A microSD card (at least 16GB).

  • The official Raspberry Pi power supply.

  • Access to a computer for initial setup.

Software Checklist:

Knowledge Checklist:

  • No prior knowledge of MQTT is required.

  • Basic familiarity with the Raspberry Pi is helpful, but not essential.

Preparation

The first step in our setup will be preparing the Raspberry Pi computers to act as a HiveMQ plant or satellite Broker and an MQTT client, respectively. If you already have a HiveMQ Broker up and running, you can skip those Broker setup steps and focus on the client portions.

Prepare SD Card and Raspberry Pi(s)

Prepare the Raspberry Pi: Ensure it has a clean Raspberry Pi OS installation. Download Raspberry Pi Imager from: https://www.raspberrypi.com/software/

Preparing the Raspberry PiClick Write Image:

Preparing the Raspberry Pi Imager

When you are finished, eject and remove the SD card. Install the SD Card into the Raspberry Pi’s SD Card slot. Be sure to do this with the Raspberry Pi powered off!

Boot Raspberry Pi

  1. Connect to the Raspberry Pi

    a. Connect a monitor, keyboard, mouse (optional), ethernet (optional), and power.

    b. Or connect to the Raspberry Pi at the console, or SSH into the Raspberry Pi (if already set up).

  2. Log in to the Raspberry Pi using the username and password assigned when you wrote the OS image.  Or use the defaults of:

    Username: pi

    Password: raspberry

  3. Now you should be logged into the Raspberry Pi to either the GUI desktop environment or a shell prompt “$

  4. From here, you can follow the instructions below to install Java, Python, and the HiveMQ MQTT-CLI.

Installing Java

Download and install JDK 17 or higher on your client system. For example:

sudo apt install openjdk-17-jdk 

Installing Python3 (if needed)

Python 3 should be installed already on your Raspberry Pi. If not, install it with:

sudo apt upgrade

sudo apt install python3 python3-pip

Verify that Python is installed:

python3 --version

pip3 --version

Installing HiveMQ MQTT CLI

This example is for MacOS:

brew tap hivemq/mqtt-cli/mqtt-cli

brew install hivemq/mqtt-cli/mqtt-cli

mqtt --version

Go to the official HiveMQ MQTT-CLI site for more detailed instructions and documentation.

Starting Up

Installing and Starting Up HiveMQ Broker

This step is optional if you already have a HiveMQ Broker running. Otherwise, use a second Raspberry PI, Virtual Machine (VM), cloud host/instance, or a Linux, Mac, or Windows system with at least 4 GB of RAM and 4 CPUs to get started. Refer to the official HiveMQ installation instructions to install and set up HiveMQ. 

With HiveMQ running, connect to the Control Center Console with https://<< your DNS or IP>:8080/. You should see a screen similar to:

HiveMQ Enterprise MQTT Broker Control CenterWe’ll switch to the new Control Center V2 (CCv2):

HiveMQ Enterprise MQTT Broker Control CenterOnce you’ve logged in, you’ll see:

HiveMQ Enterprise MQTT Broker Control CenterNote the warning in the lower left. For production environments, you should set up proper security using the HiveMQ Enterprise Security Extension.    

HiveMQ MQTT Client 

Next, we’ll get into the heart of the matter—writing the HiveMQ MQTT client. Switch to your other Raspberry Pi that will act as the MQTT client. This HiveMQ client connects to the broker, publishes some sample data about motors of pizza dough mixers running in a specific plant and lines within that plant. The MQTT topic name addresses the data in a standard way:

site1/line2/mixer3/motor1/sensors/mainmotor

Be sure that the Python MQTT client is installed with:

pip3 install gmqtt

Clone the GitHub repository: https://github.com/williamsommers-hmq/raspberry-hivemq to access the code.  

Here, we’ll focus on the main functions of the code rather than a complete line-by-line review of the code’s functions. 

Import gmqtt client to make it available to the Python code module:

from gmqtt import Client as MQTTClient

Publishing is accomplished with two main function calls: connect and publish, as shown in the following snippet of code. Adjust the values of BROKER_HOST and BROKER_PORT as needed to connect to a local instance (localhost) or using the DNS or IP address of the HiveMQ Cloud broker instance. 

async def publish_data():
    client = MQTTClient("publisher-client")
    await client.connect(BROKER_HOST, BROKER_PORT)

    while True:
             # generate random values of data for testing
        data = {
            "datetime_stamp": datetime.now().isoformat(),
            "operation_time": random.uniform(100.0, 500.0),
            "voltage": random.uniform(220.0, 240.0),
            "current": random.uniform(5.0, 7.5),
            "last_maintenance": "2025-08-01"
        }
        payload = json.dumps(data)
        print(f"Publishing: {payload}")
        client.publish(TOPIC, payload, qos=1)
        await asyncio.sleep(5)

This key functionality in the code is here:

We create a client object:

client = MQTTClient("publisher-client")

We connect to the Broker specified by the value of the variable BROKER_HOST with the client.connect() method:

await client.connect(BROKER_HOST, BROKER_PORT)

Next, we create the payload:

data = {
            "datetime_stamp": datetime.now().isoformat(),
            "operation_time": random.uniform(100.0, 500.0),
            "voltage": random.uniform(220.0, 240.0),
            "current": random.uniform(5.0, 7.5),
            "last_maintenance": "2025-08-01"
        }

Then, as the last major step in creating a publisher client, we publish the message:

client.publish(TOPIC, payload, qos=1)

For the subscriber client, we follow a similar pattern, but change the method call on the client object from client.publish()  to client.subscribe() in the on_connect method():

def on_connect(client, flags, rc, properties):
    print(f'Connected to broker with result code: {rc}')
    client.subscribe(TOPIC, qos=1)

The asyncio.Event() loop in the subscriber code handles calling the on_message() method when the broker sends a message to the subscriber:

def on_message(client, topic, payload, qos, properties):
    print(f'Received message on topic "{topic}"')
    try:
        data = json.loads(payload)
        print(json.dumps(data, indent=2))
    except json.JSONDecodeError:
        print(f"Error decoding JSON: {payload.decode()}")

Of course, this simple code above merely formats the JSON and prints it, and can be changed to suit your needs.  For example, this data could be stored, written to a file, processed by extracting data elements of interest, or other handling as needed. 

Running the Code

Now that we have the code, it is time to run it and see the output. Using the provided code in the GitHub repository, open a terminal window and change your source repository directory. Make the Python code executable with:

chmod +x ./publisher.py ./subscriber.py

Run this code in separate terminal shells as shown in the image above. 

Publisher:

./publisher.py

Subscriber:

./subscriber.py 

Viewing and Analyzing the Output

You should see output from the publisher similar to the below image:

MQTT Message Publish SubscribeAnd output from the subscriber similar to the following. Adjust the example topic for the publisher and subscriber according to your needs. 

MQTT message topicThis is an example showing the hivemq.log on the left pane, the subscriber on the top left, and the publisher on the bottom right. 

example showing the hivemq.log on the left pane, the subscriber on the top left, and the publisher on the bottom right.Refer to the full code at https://github.com/williamsommers-hmq/raspberry-hivemq

Improved Publisher

The publisher code shown earlier is fine if the connection stays up and stable. However, in real-world scenarios, this is rarely the case. The following code improves the publisher by adding a reconnect loop to handle disconnects after initial connection:

def on_disconnect(client, packet, exc=None):
    print('Disconnected from broker. Reconnecting...')

def ask_exit(*args):
    STOP.set()

async def main():
    client = MQTTClient("robust-publisher-client")

    client.on_connect = on_connect
    client.on_disconnect = on_disconnect

    # Set reconnect_retries to a large number 
    client.reconnect_retries = 100
    client.reconnect_delay = 5  # seconds

    # create the asyncio event loop
    loop = asyncio.get_event_loop()
    for signame in ('SIGINT', 'SIGTERM'):
        loop.add_signal_handler(getattr(signal, signame), ask_exit)

    # wait for connection
    await client.connect(BROKER_HOST, BROKER_PORT)
    
    # loop, checking for connection and reconnecting if needed
    while not STOP.is_set():
        data = {
            "datetime_stamp": datetime.now().isoformat(),
            "operation_time": random.uniform(100.0, 500.0),
            "voltage": random.uniform(220.0, 240.0),
            "current": random.uniform(5.0, 7.5),
            "last_maintenance": "2025-08-01"
        }
        payload = json.dumps(data)

        try:
            if client.is_connected:
                print(f"Publishing: {payload}")
                client.publish(TOPIC, payload, qos=1)
            else:
                print("Client is not connected. Waiting for reconnection...")
        except Exception as e:
            print(f"An error occurred during publishing: {e}")

        await asyncio.sleep(5)

    await client.disconnect()
    print("Publisher stopped.")

The code above gives you the option to easily set the number of retries and the delay in between retrying connections:   

client.reconnect_retries = 100

client.reconnect_delay = 5  # seconds

Alternatively, you can set the client configuration directly: 

client.set_config({'reconnect_retries': 10, 'reconnect_delay': 60})

Enhancements

The code shown in this article is mainly to demonstrate the basics of connectivity, publishing, and subscribing to MQTT data flowing through HiveMQ Broker Platform. 

Remote Management

Remote management of clients is an important function you’ll want to utilize. This is particularly necessary if you use many clients, have many sites or plants, or if they are geographically distributed or are far apart in remote places such as farms, distant fields, atop buildings or towers. For certain applications, it may be appropriate to use a so-called “watchdog” to ensure that the Raspberry Pi does not crash or otherwise become unresponsive. A watchdog will restart the Raspberry Pi to ensure operations and connectivity even at the cost of a potential loss of data. Using a watchdog can be a good tradeoff: a small risk of a small window of data loss versus an expensive and time-consuming trip to a remote site to physically check on the devices. 

Logging

For production uses of HiveMQ, we recommend using robust logging to persistent storage for clients. Logging provides invaluable insights into operations, gives needed data for debugging, and can be used for performance management. 

Logging can be done locally to persistent storage like SSDs, attached USB storage, or to NVMe storage. Log aggregation—that is, collecting logs from multiple clients—can be done using a log server such as DataDog, New Relic, Logstash, Splunk, to name just a few. With log aggregation, clients typically both store their data locally for a period of time and forward a copy to a central, remote server either in real-time or periodically for long-term use.   

Summary

In this article, we’ve introduced the basics of setting up a Raspberry Pi as an MQTT client to connect to HiveMQ. The code shared here provides a solid foundation for a powerful approach to connecting your IoT and IIoT sensors to a Raspberry Pi and routing your vital sensor data through HiveMQ to drive business, gain insights, monitor processes, and deliver real-time data to the relevant individuals and systems. 

If you’re an active customer, reach out to your Customer Success TAM or CSM to learn more. If you’re new to HiveMQ, please contact us for more information and a technical discussion.

Resources

  1. gmqtt : Python async MQTT Client Implementation

  2. HiveMQ Cloud

  3. HiveMQ 4.43

  4. Source code for this article

Bill Sommers

Bill Sommers is a Technical Account Manager at HiveMQ, where he champions customer success by bridging technical expertise with IoT innovation. With a strong background in capacity planning, Kubernetes, cloud-native integration, and microservices, Bill brings extensive experience across diverse domains, including healthcare, financial services, academia, and the public sector. At HiveMQ, he guides customers in leveraging MQTT, HiveMQ, UNS, and Sparkplug to drive digital transformation and Industry 4.0 initiatives. A skilled advocate for customer needs, he ensures seamless technical support, fosters satisfaction, and contributes to the MQTT community through technical insights and code contributions.

  • Bill Sommers on LinkedIn
HiveMQ logo
Review HiveMQ on G2