Skip to main content

OpenGate MQTT connector

·1038 words·5 mins
Carlos Prados
Author
Carlos Prados
Telecommunications Engineer, Entrepreneur, CTO & CIO, Team Leader & Manager, IoT-M2M-Big Data Consultant, Pre-sales Engineer, Product-Service Manager & Strategist.

This post shows how to use the OpenGate MQTT connector.

The MQTT protocol provides a lightweight method of carrying out messaging using a publish/subscribe model. These features make it suitable for Internet of Things messaging, such as with low-power sensors or mobile devices such as phones, embedded computers, or microcontrollers.

In MQTT, there are a few basic concepts that you need to understand:

  • Publish/Subscribe - In a publish and subscribe system, a device can publish a message on a topic or be subscribed to a particular topic to receive messages.
  • Messages - Messages are the information you want to exchange between your devices. These messages can either be a command or data.
  • Topics - Topics are the way you register interest in incoming messages or how you specify where you want to publish the message.
  • Broker - The broker is primarily responsible for receiving all messages, filtering them, deciding who is interested in them, and then publishing the message to all subscribed clients.

In MQTT, a publisher (device/client) publishes messages on a topic, and a subscriber must subscribe to that topic to view the message.

OpenGate MQTT connector
#

These are the connection data:

  • Host: api.opengate.es
  • Port: 1883
  • User: device_id
  • Password: your_api_key

How to obtain your API key
#

In addition, you’ll need your API key. Once you login onto the OpenGate web interface, you can find your API key by clicking on the cogs at the top-right of the OpenGate home page, then on the User option, and finally on the “Click to show” link.

OpenGate Topics
#

  • To publish collected data: odm/iot/{device_id}
  • To subscribe to incoming operations from OpenGate: odm/request/{device_id}
  • To publish operation responses: odm/response/{device_id}
  • To ask OpenGate for pending operations: odm/operationOnDemand/{device_id}

You have to replace {device_id} with the OpenGate unique identifier of your device.

Payload
#

The payload definition in the official OpenGate documentation to publish data is entirely valid. You only have to add a "device": "device_id" field, filled with your OpenGate device unique identifier, at the top level of the JSON document with the collected values. See the following example:

{
  "version": "1.0.0",
  "device": "device_id",
  "datastreams": [
    {
      "id": "temperature",
      "datapoints": [
        {
          "at": 1431602523123,
          "value": 24.1
        }
      ]
    }
  ]
}

Using mosquitto client
#

Eclipse Mosquitto is an open source (EPL/EDL licensed) message broker that implements the MQTT protocol versions 5.0, 3.1.1, and 3.1. Mosquitto is lightweight and suitable for all devices, from low-power single board computers to full servers.

Subscribing to OpenGate MQTT operations topic with mosquito client
#

Your device must subscribe to odm/request/{device_id} topic to receive operation requests from the north API. Replace {device_id} with the provisioned device id:

// extract from provision JSON
...
"provision.device.identifier": {
        "_value": {
            "_current": {
                "value": "sensehat01"
            }
        }
    }
...

Example using mosquitto_sub:

# Debian/Ubuntu install: sudo apt-get install mosquitto-clients
mosquitto_sub \
  -h api.opengate.es \
  -u "your-device-id" \
  -P "your-api-key" \
  -t "odm/request/your-device-id"

Launch operations using the North API
#

The North API end-point for jobs and operations is https://api.opengate.es:443/north/v80/operation/jobs.

Every http request to the North or South API must include this header: X-ApiKey: your-api-key.

Example using curl:

curl -X POST \
    -H "Content-Type: application/json" \
    -H "X-ApiKey: your-api-key" \
    -d @SET_DEVICE_PARAMETERS.json \
    https://api.opengate.es:443/north/v80/operation/jobs

SET_DEVICE_PARAMETERS.json file used in the previous example:

{
  "job": {
    "request": {
      "operationParameters": {
        "timeout": 90000,
        "retries": 0,
        "retriesDelay": 0
      },
      "name": "SET_DEVICE_PARAMETERS",
      "schedule": {
        "stop": {
          "delayed": 120000
        }
      },
      "parameters": {
        "variableList": [{ "name": "f", "value": "180" }]
      },
      "target": {
        "append": {
          "entities": ["sensehat01"]
        }
      },
      "active": true
    }
  }
}

HTTP response:

{
  "id": "0898f8e6-6773-43d4-ac34-fab214581463",
  "request": {
    "name": "SET_DEVICE_PARAMETERS",
    "parameters": {
      "variableList": [
        {
          "name": "r",
          "value": "180"
        }
      ]
    },
    "active": true,
    "notify": false,
    "user": "[email protected]",
    "schedule": {
      "stop": {
        "delayed": "120000"
      },
      "scattering": {
        "strategy": {}
      },
      "window": {
        "weekly": [
          {
            "daily": {}
          }
        ]
      }
    },
    "operationParameters": {
      "timeout": 90000,
      "retries": 0,
      "retriesDelay": 0
    }
  },
  "report": {
    "execution": {},
    "target": {}
  }
}

If you didn’t provision the parameter to be set in a data stream, you’ll receive the following response from the North API:

{
  "errors": [
    {
      "code": "0x020003",
      "message": "At least one valid reference to an entity (list of entities or tags) is required."
    }
  ]
}

Processing operations on the device side
#

OpenGate operation routing
#

OpenGate routes operations to specific connectors depending on:

  • specific manufacturer and model pair
  • or specific operations.

For the sake of this example, let’s assume routing by manufacturer and model; thus, the provisioning must be (OpenGate/OpenGateMqtt):

...
"provision.device.model": {
        "_value": {
            "_current": {
                "value": {
                    "name": "OpenGateMqtt",
                    "manufacturer": "OpenGate"
                }
            }
        }
    }
...

Example operation: SET_DEVICE_PARAMETERS
#

Parameters to be set must be configured in a data model as data streams and must be WRITABLE (and only WRITABLE).

Publishing operation responses to OpenGate MQTT connector with mosquito client
#

OpenGate only supports one MQTT session at the same time. Don’t connect two mosquitto_pub or mosquitto_sub clients simultaneously.

The following example publishes a JSON payload stored on SET_DEVICE_PARAMETERS_RESPONSE.json file with an example of the response required by OpenGate Operations Engine:

# Debian/Ubuntu install: sudo apt-get install mosquitto-clients
mosquitto_pub \
  -h api.opengate.es \
  -u "your-device-id" \
  -P "your-api-key" \
  -t "odm/response/your-device-id" \
  -f SET_DEVICE_PARAMETERS_RESPONSE.json

The following code is an example of a response SET_DEVICE_PARAMETERS_RESPONSE.json file:

{
  "version": "7.0",
  "operation": {
    "response": {
      "deviceId": "sensehat01",
      "timestamp": 1599810726318,
      "name": "SET_DEVICE_PARAMETERS",
      "id": "f5d56834-63b8-45d8-93cb-5fdfcc30de9b",
      "resultCode": "SUCCESSFUL",
      "resultDescription": "Success",
      "steps": [
        {
          "name": "SET_DEVICE_PARAMETERS",
          "timestamp": 1599810726318,
          "result": "SUCCESSFUL",
          "description": "Parameters set ok",
          "response": []
        }
      ]
    }
  }
}

Publishing IoT data
#

# Debian/Ubuntu install: sudo apt-get install mosquitto-clients
mosquitto_pub \
  -h api.opengate.es \
  -u "your-device-id" \
  -P "your-api-key" \
  -t "odm/iot/your-device-id" \
  -f iot_data.json

MQTT connector supports the payloads defined in the OpenGate’s public documentation, with the following extra considerations:

Additionally, the JSON message must include the field "device": "your-device-id". This field is required when you’re using the OpenGate MQTT connector.

{
  "version": "1.0.0",
  "device": "your-device-id",
  "datastreams": [
    {
      "id": "temperature.from.pressure",
      "datapoints": [
        {
          "at": 1529398727,
          "value": 28
        }
      ]
    },
    {
      "id": "temperature.from.humidity",
      "datapoints": [
        {
          "at": 1529398727,
          "value": 30
        }
      ]
    },
    {
      "id": "pressure",
      "datapoints": [
        {
          "at": 1529398727,
          "value": 957
        }
      ]
    },
    {
      "id": "humidity",
      "datapoints": [
        {
          "at": 1529398727,
          "value": 40
        }
      ]
    }
  ]
}