Skip to content

epics-modules/mqtt

Repository files navigation

EPICS Support for the MQTT protocol

This module provides an EPICS driver for the MQTT protocol, allowing EPICS clients to communicate with MQTT brokers and devices directly from EPICS.

Contributions are welcome - feel free to open issues and pull requests!


Table of Contents


Features

  • Auto-update of EPICS PVS via I/O Intr records;
  • Support for read/write flat MQTT topics (i.e, topics where the payload is a single value or array);
  • Support for reading arbitrarily nested fields from JSON topic payloads;
  • Support for MQTT QoS levels;
  • Checks and reject invalid messages (based mostly on type-checking);
  • Auto reconnection of broker;
  • Planned - short term:
    • Support for MQTT retained messages.
    • Support for MQTT last will messages.
    • Support for MQTT authentication and TLS.

Note: Virtually all features from the Paho C++ MQTT client are available to be implemented in this driver, so feel free to open an issue if you need a specific feature.

This module is built on top of Cosylab autoparamDriver, which uses the standard asyn interfaces for device support. For now, the supported interfaces are the following:

  • asynInt32
  • asynFloat64
  • asynUInt32Digital
  • asynOctet
  • asynInt32Array
  • asynFloat64Array

    See Implementation status to check the status of development of the interface you need.

Building the module

  1. Install the dependencies:

    Tested with the following versions.

Note: AutoparamDriver explicitly requires EPICS >= 7.0, see reference. For this reason, this module requires EPICS 7.0 or later to be built and used.

  1. Clone this repository:
  git clone https://github.com/AndreFavotto/epicsMQTT.git
  1. Edit the configure/RELEASE file to include your paths to the dependencies:

    EPICS_BASE = /path/to/epics/base
    ASYN = /path/to/asyn
    AUTOPARAM = /path/to/autoparamDriver
    PAHO_CPP_INC = /path/to/paho/cpp/include #by default, should be /usr/local/include
    PAHO_CPP_LIB = /path/to/paho/cpp/lib     #by default, should be /usr/local/lib

    For now we have two macros for setting paho path because we build the module with separate linking flags -I and -L, but this might change soon.

  2. Run make. The library should now be ready for usage.

Usage

  1. Include the module in your IOC build instructions:

    • Add asyn and mqtt to your configure/RELEASE file:

      ## Other definitions ...
      ASYN = /path/to/asyn
      MQTT = /path/to/epicsMqtt
      ## Other definitions ...
    • Add the mqtt database definition and include the necessary libraries to your yourApp/src/Makefile:

      #### Other commands ...
      yourIOC_DBD += mqtt.dbd
      #### Other commands ...
      yourIOC_LIBS += asyn
      yourIOC_LIBS += mqttSupport
  2. In your database file, link the EPICS records and the MQTT topics through the INP and OUT fields. The syntax is as follows:

  field(INP|OUT, "@asyn(<PORT>) <FORMAT>:<TYPE> <TOPIC> [<FIELD>]")

Where:

  • <PORT> is the name of the asyn port defined in the asynPortDriver configuration.
  • <FORMAT> is the format of the payload: FLAT or JSON.
  • <TYPE> is the general type of the expected value [INT|FLOAT|DIGITAL|STRING|INTARRAY|FLOATARRAY].
  • <TOPIC> is the MQTT topic to which the record will be subscribed/published.
  • <FIELD> is the dot-separated path to the field to extract from a JSON payload (e.g. sensor.temperature). Arbitrary nesting is supported. Required when FORMAT is JSON.

Note on JSON write support: Writing to JSON-formatted topics is currently not supported. At the moment the driver has no way of knowing the JSON structure expected by the broker ahead of time for write records. For this reason, only FLAT format can be used for output records.

Important: Due to the pub/sub nature of MQTT, ALL input records are expected to be I/O Intr.

Example:

record(ai, "$(P)$(R)AnalogIn"){
  field(DESC, "Analog Input Record")
  field(DTYP, "asynInt32")
  field(SCAN, "I/O Intr")
  field(INP, "@asyn($(PORT)) FLAT:INT test/analogtopic")
}

record(ai, "$(P)$(R)AnalogOut"){
  field(DESC, "Analog Output Record")
  field(DTYP, "asynInt32")
  field(OUT, "@asyn($(PORT)) FLAT:INT test/analogtopic")
}

Note: Several examples can be found in mqttExampleApp/Db for other record types.

  1. Load the module in your startup script using the following syntax:
 mqttDriverConfigure(const char *portName, const char *brokerUrl, const char *mqttClientID, const int qos)

Example:

  # (... other startup commands ...)
  epicsEnvSet("PORT", "test")
  epicsEnvSet("BROKER_URL", "mqtt://localhost:1883")
  epicsEnvSet("CLIENT_ID", "mqttEpics")
  epicsEnvSet("QOS", "1")
  mqttDriverConfigure($(PORT), $(BROKER_URL), $(CLIENT_ID), $(QOS))
  # (... other startup commands ...)
  dbLoadRecords("your_database.db", "PORT=$(PORT)")
  iocInit()

Implementation status

Below are the supported interfaces and their implementation status.

Message type Asyn Parameter Type FORMAT:TYPE string to use Direction Status
Integer asynInt32 FLAT:INT Read / Write Supported
Float asynFloat64 FLAT:FLOAT Read / Write Supported
Bit masked integers asynUInt32Digital FLAT:DIGITAL Read / Write Supported
Strings asynOctetRead/asynOctetWrite FLAT:STRING Read / Write Supported
Integer Array asynInt32ArrayIn/asynInt32ArrayOut FLAT:INTARRAY Read / Write Supported
Float Array asynFloat64ArrayIn/asynFloat64ArrayOut FLAT:FLOATARRAY Read / Write Supported
Integer asynInt32 JSON:INT Read only Supported
Float asynFloat64 JSON:FLOAT Read only Supported
Bit masked asynUInt32Digital JSON:DIGITAL Read only Supported
String asynOctetRead JSON:STRING Read only Supported

Licensing Terms

Copyright (C) 2026 André Favoto

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

About

EPICS native support for MQTT - Based on asyn, autoparamDriver and Paho

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages