Skip to content

AndreFavotto/epicsMQTT

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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 MQTT QoS levels;
  • Checks and reject invalid messages (based mostly on type-checking);
  • Auto reconnection of broker;
  • Planned - short term:
    • Support for parsing fields from one-level JSON topic payloads
    • 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:

    The versions below are the ones in use for development, but it is very likely that EPICS Base >= 3.15 should work.

  2. 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 += mqtt
  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, either FLAT or JSON. For now, only FLAT is supported.
  • <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 an optional field name to be used when parsing JSON payloads (not yet implemented).

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")
}
  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 is a table with the supported interfaces for the FLAT topics, example of I/O link strings and current status of the implementation. The JSON payload support is planned to come next.

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

About

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

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published