Skip to content

MQTT

MQTT is a messaging protocol for (IoT). It is designed as a lightweight publish/subscribe messaging transport that is ideal for connecting remote devices with a small code footprint and minimal network bandwidth.

The Ioto MQTT support is an efficient MQTT client that is ideal for connecting to the cloud.

MQTT Features

  • MQTT 3.1.1 support
  • Connect, publish, subscribe, ping and disconnect messages.
  • TLS encryption with ALPN over port 443 to get through firewalls.
  • Message quality of service for reliable delivery.
  • Retained messages.
  • High message throughput with exceptionally low overhead.
  • Wait for delivery or acknowledgement options.
  • Resilient reconnect on network interruptions.
  • Automatic configuration after cloud provisioning.
  • Parallelism via fiber coroutines. No ugly callbacks or complex threads.
  • Tiny footprint of 8K code.

MQTT Configuration

The Ioto MQTT connection is opened automatically based on the config/config/ioto.json5 configuration settings:

1
2
3
4
5
6
7
8
mqtt: {
    cert: 'certs/mqtt.crt',
    key: 'certs/mqtt.key',
    ca: 'certs/root.crt',
    client: 'my-device-client-id',
    endpoint: 'https://',
    port: 1883
}

These properties describe the MQTT endpoint, port, certificates and keys to use to establish communications with an MQTT broker.

If using AWS Iot as your broker, Ioto can automatically configure the MQTT connected based on the properties below:

1
2
3
4
5
6
7
8
9
mqtt: {
    cert: 'auto',
    key: 'auto',
    client: 'auto',
    endpoint: 'auto',
    port: 443,
    alpn: 'x-amzn-mqtt-ca',
    ca: 'certs/aws.crt',
}

Publishing Messages

Publishing messages is done via the mqttPublish API:

Ioto creates a MQTT connection to the device cloud on startup. This connection is referenced via ioto->mqtt.

mqttPublish(ioto->mqtt, "Initialized", 0, MQTT_QOS_1, MQTT_WAIT_NONE, "myDevice/init");

This will publish an "initialized" message with quality of service (1) which means "send at least once". The message will be published on the "myDevice/init" topic and this API call will not block for sending or acknowledgement of the message. The sending will happen in the background with any required re-transmissions.

Subscribing for Messages

You can subscribe to receive incoming messages on a topic via the mqttSubscribe API:

mqttSubscribe(ioto->mqtt, incoming, MQTT_QOS_1, MQTT_WAIT_NONE, "myDevice/change");

When messages are received on the "myDevice/change" topic, the function incoming will be invoked with the message.

The incoming callback will be passed the message response packet.

1
2
3
4
static void incoming(MqttResp *rp)
{
    printf(stdout, "Received from topic %s: %s", rp->topic, rp->data);
}

The message topic will be a null terminated string in rp->topic.

The message data will be passed in rp->data and the size of the data will be defined in rp->dataSize. The data will always be null terminated which is useful when passing message strings.

Ioto Key/Value Store

Many devices maintain simple device settings that can be sent to the cloud and stored in a key/value store.

An Ioto device cloud provides such a key/value store in the device database called the Store. Values can easily be written and read to/from the Store using the ioSet APIs.

iotSet("model", "Acme Rocket");
iotSetNum("cpu", 55);

These values can be displayed in the Device Manager UI and can be retrieved in the device via the ioGet APIs.

char *model = iotSet("model");
double cpu = iotSetNum("cpu");

These APIs are simple wrappers over the mqttPublish and mqttRequest APIs.

Creating Metrics

When you publish data to the Store, you can create a metric for the published data. This metric can then be displayed using graphical widgets in the Device Manager.

To enable metrics for your data, define your metrics under the Store processing definition in the Device schema and upload that schema to your manager.

Note: this is not available when using the Eval cloud.

For example:

{
    Store: {
        enable: 'both',
        sync: 'up',
        notify: 'default',
        metrics: [
            {
                namespace: 'Embedthis/Device',
                fields: [{CPU: 'value'}],
                where: 'key == "cpu"',
                dimensions: [{Device: 'deviceId'}],
                buffer: {count: 5, elapsed: 10},
            },
        ],
    },
}

See Database Metrics for details.

See the MQTT API for more details.

References

MQTT Configuration Properties MQTT 3.1.1 spec