ADA Documentation Help

Integrations

Introduction

The Ada Gateway allows for third party integrations into the Ada network. Even though the Ada network consists of multiple underlying networking technologies, interacting with devices is always handled in the same way as described below.

Integrations primarily function through the use of webhooks, which is configured through a web interface at gateway.adasensors.com.

Gateway Dashboard

Approved users can access this web interface and configure the webhook endpoints and authorization.

Webhooks

Integrating uplink messages into an application requires implementing a receiving HTTP endpoint. The messages are delivered as POST requests containing a single JSON document in the request body. The document contains some network and device metadata and a device payload object.

Uplink messages are processed immediately after the network server receives the message, and then forwarded to the Ada Gateway which relays the message to the specified integration endpoint. The server hosting the endpoint should respond in less than 5 seconds or the request will time out. Failed requests will be retried 3 times with an increasing backoff. It is therefore important to examine the received time in the request document.

The endpoint should be absolute, use HTTPS and use a valid certificate signed by a certificate authority.

Two headers are added to the HTTP request, "Ada-Integration" and "Ada-Key", which contains the assigned integration identifier and the secret key specified in the configuration interface.

Uplink payloads are unique to each device type.

Ada-Integration: ed629da1-e41d-4f90-ac57-82230a7a61f9 Ada-Key: My Super Secret Key

Below is an example uplink JSON document.

{ "network": "ADA", "deviceId": "339e9364-c405-4136-a210-90a35a289fdd", "reference": "0707c014-5a08-40ab-9083-1d24913258d7", "deviceType": "Click", "receivedTime": "2022-06-20T11:45:12.3009149Z", "processedTime": "2022-06-20T11:45:12.4330038Z", "signalQuality": "Good", "payload": { "button": 2 } }

Field name

Type

Conditional

Description

Notes

network

string

No

The network from which the message is received.

Possible values are: "ADA"

deviceId

string

No

A unique guid string representing a device.

reference

string

Yes

A reference field which can be set programatically through the API.

deviceType

string

No

The device type the message originated from.

See specific device documentation.

receivedTime

string

No

UTC timestamp indicating the time the message was received by the network.

This value may differ significantly from the "nsReceivedTime" since the gateways can buffer messages in certain circumstances, such as a back-haul failure.

processedTime

string

No

UTC timestamp indicating the time the message was processed by the Ada Gateway.

signalQuality

string

No

A string describing the signal quality.

Possible values are: "Poor", "Moderate", "Good" and "Excellent"

payload

object

Yes

Object containing decoded payload data.

Contents of the payload object depends on the device type.

Example Implementation

The following is an example implementation for a 'Click' device written in C# for .NET 6+ using the built-in JSON serializer (controllers, using and namespaces omitted for brevity).

First we define the Uplink request model.

[JsonConverter(typeof(JsonStringEnumConverter))] public enum SignalQuality { Poor, Moderate, Good, Excellent } public class UplinkModel { [JsonPropertyName("network")] public string Network { get; set; } = string.Empty; [JsonPropertyName("deviceId")] public Guid DeviceId { get; set; } = Guid.Empty; [JsonPropertyName("reference")] public Guid? Reference { get; set; } [JsonPropertyName("deviceType")] public string DeviceType { get; set; } = string.Empty; [JsonPropertyName("receivedTime")] public DateTime ReceivedTime { get; set; } [JsonPropertyName("processedTime")] public DateTime ProcessedTime { get; set; } [JsonPropertyName("signalQuality")] public SignalQuality SignalQuality { get; set; } [JsonPropertyName("payload")] public JsonObject? Payload { get; set; } }

In the controller we define a post endpoint which accepts an UplinkRequest object. The DeviceType field is used to determine how to deserialize the payload.

[HttpPost("Uplink")] public async Task<IActionResult> Uplink( [FromHeader(Name = "Ada-Integration")] Guid integration, [FromHeader(Name = "Ada-Key")] string key, [FromBody] UplinkModel uplink) { if (key != "My Super Secret Key") { return Unauthorized(); } if (uplink.Payload == null) { return Ok(); } switch (uplink.DeviceType) { case "Click": await HandleClickPayload(uplink.Payload.Deserialize<ClickPayload>()); break; } return Ok(); } private async Task HandleClickPayload(ClickPayload? payload) { _logger.LogInformation($"Button {payload?.Button} clicked"); // TODO Implement device payload handling. }

The Click payload model declares two properties, button and battery. Since not every request will contain both values the properties are declared as nullable.

public class ClickPayload { [JsonPropertyName("button")] public int? Button { get; set; } [JsonPropertyName("battery")] public int? Battery { get; set; } }

Provision

Applications can be notified when a device is provisioned and registered to the integration. This is done by setting the 'Provision event' webhook in the configuration webinterface.

Below is an example provision request

{ "network": "ADA", "deviceId": "339e9364-c405-4136-a210-90a35a289fdd", "deviceName": "MY-INTEGRATION-0001", "deviceType": "Click", "devicePin": "9d19f4a5a7" }

Field name

Type

Conditional

Description

Notes

network

string

No

The network on which the device has been provisioned.

deviceId

string

No

A unique guid representing a device.

deviceName

string

No

A generated friendly device name.

This is only used for convenience and can be ignored in all device communications.

deviceType

string

No

The type of the new device.

See device documentation.

devicePin

string

No

A unique device pin.

Not used during device communication, but can be used for implementing device claiming.

Example implementation

The following is an example implementation for a 'Click' device written in C# for .NET 6+ using the built-in JSON serializer (controllers, using and namespaces omitted for brevity).

First we define the provision request model.

public class ProvisionModel { [JsonPropertyName("network")] public string Network { get; set; } = string.Empty; [JsonPropertyName("deviceId")] public Guid DeviceId { get; set; } [JsonPropertyName("deviceName")] public string DeviceName { get; set; } = string.Empty; [JsonPropertyName("deviceType")] public string DeviceType { get; set; } = string.Empty; [JsonPropertyName("devicePin")] public string DevicePin { get; set; } = string.Empty; }

In the controller we define a post endpoint which accepts an ProvisionModel object.

[HttpPost("Provision")] public IActionResult Provision([FromHeader(Name = "Ada-Key")] string apiKey, [FromBody] ProvisionModel provision) { if (apiKey != "super-secret") { return Unauthorized(); } CreateDevice(provision.DeviceName, provision.DeviceId, provision.DeviceType); return Ok(); }

Join notifications

Applications can be notified when devices join the network. This is done by subscribing to the 'Join event' webhook in the configuration webinterface.

Documentation still in preparation...

Error notifications

Applications can be notified when a device communication error occurs. This is done by subscribing to the 'Error event' webhook in the configuration webinterface.

Documentation still in preparation...

Downlink messages can be sent using the gateway API. These types of messages are typically used to configure device parameters. Some networking technologies such as LoRaWAN have a more limited downlink capacity. This is due to legal restrictions on the publicly available frequency bands.

To queue a downlink a post request including authorization headers should be sent to the /Devices/{ID}/Downlink route, where is the GUID of the device receiving the downlink.

{ "confirmed": true, "port": 5, "payload": { "reportInterval": 600 } }

Field name

Type

Conditional

Description

confirmed

Boolean

No

Indicates whether the downlink should be confirmed.

port

Number

No

The network port on which the downlink should be sent. The significance of the port depends on the device.

payload

Object

No

An object containing the payload to be sent to the device. The payload specifications can be found in the device sections.

Documentation still in preparation...

MQTT

An MQTT adapter is available. It works by accepting ADA webhooks, converting them into topics and forwarding them to an MQTT broker.

The adapter is a standalone application written in C#. It can run on all major platforms where .NET is available, such as Windows and Linux.

Configuration

Hosting the adapter can be done on any publicly available host that fulfills the requirements outlined in the integrations topic

To configure the adapter a JSON document with the filename 'config.json' is placed in the '/usr/share/AdaMQTT' (Linux) directory.

The document should contain the following fields:

{ "Hostname": "mqtt.example.com", "Port": 8883, "Username": "SomeUser", "Password": "Super Secret!", "UplinkTopic": "/Ada/Uplink" }

Payload data can be transformed using a script written in JavaScript. The uplink request can be accessed through the 'uplink' variable.

log(`Device type is ${uplink.deviceType}`); switch (uplink.deviceType) { case "IoTController": log("Received IoTController payload"); uplink.payload.temp1 = uplink.payload.pt1001 + 100; uplink.payload.temp2 = uplink.payload.pt1002 + 200; break; case "SmartCurrent": log("Received SmartCurrent payload"); break; default: throw "Unknown device type"; }
19 juni 2025