IoT API
9 min read
Apps and Devices
Devices (firmware) and Web, Mobile or Cloud/Server Apps can utilize IoT APIs using HTTP
, Websocket
, or MQTT
protocols.
Which Protocols to Use?
With Websocket
and MQTT
protocols Apps and Devices clients can both send data to the Rapidomize platform and/or receive commands/requests from the platform (termed as SSR - Server Sent Request
). HTTP
can be used only for sending data to the platform. Clients who ONLY send data to the platform without needing to respond to SSR, can use HTTP connection to trigger a Generic my-app
as trigger. Clients who need responding to SSR (via my-app
Action
s settings) e.g. for IoT devices or monitoring apps, need to connect to the platform using Websocket
or MQTT
protocols.
Base Endpoint URIs & MQTT Topics
-
HTTP/Websocket:
- Apps/Devices Management:
https://ics.rapidomize.com/api/v1/mo/{appId}
- Trigger
Based API: https://ics.rapidomize.com/api/v1/icapp/{icappId}
- Apps/Devices Management:
-
MQTT Endpoint:
ssl://ics.rapidomize.com:8883
Topics:- Apps/Devices Management:
/api/v1/mo/{appId}
- Trigger
Based API: /api/v1/icapp/{icappId}
- Apps/Devices Management:
Manage Apps/Devices
Using My Apps & Devices
in the Rapidomize UI, you can declare a digital (twin) model to represent your App/Device. Refer Apps or Devices guide on how to create a digital (twin) model for your Apps/Devices.
You create a common declaration for all the instances of a same type of app/device. In other words, If you have more than one instance of the same type of app/device, you just declare one digital (twin) model for all of them. This common declaration will be used by each instance and anything specific to the instance can to be defined at the time the instance is registered/connected with the platform. See below for registration API that can be used for registering per instance Attributes & Properties.
E.g. While attributes such as model #, make, manufacturer could be common for all instances of a device and per instance attribute could be devices serial #, location …etc.
Each instance of the App/Device must be distinguished from each other by using a separate Client ID
when registering/connecting that instance to the Rapidomize platform. Client ID
is optional if you have only a single instance and is identified by _
as default Client ID
. Each App/Device instance need to specify Client ID
by appending /cid/{clientId}
to the URI of HTTP
and Websocket
protocols and to the topics of MQTT
protocol.
- Attributes: are used for informational purpose to identify or distinguish App/Device instances from each other
- Properties: are parameters, state variables or functions that allowing to read, write or execute in an app/device. These represents sensors state, digital/analog I/O or actuators functionality in case of IoT devices.
Registering Instance’s Attributes & Properties
You can declare/define Apps/Devices attributes/properties by registering an instance that is already having a digital (twin) model declaration. Apps/Devices do not required to have any attributes/properties already declared, unless there are any common ones.
N.B. You must avoid registering attributes/properties each time an instance connect to the platform.
Definition of property values are optional and they reflects current state of the property. Event trigger API allows updating property values to reflect the App/Device state.
{
"att": {"n":"attribute-name", "v": attribute-value},
"prop":{"n":"property-name", "dt":"", "rwx":0x01, "v": optional-property-value},
"loc":{"lat": ..., "lng": ...}
}
where:
- att - Attributes name (n) & value (v)
- prop - Property name (n), data type (dt), permission read/write/execute hex value (rwx) and value (v)
- loc - App/Device Location (if any) coordinates as latitude (lat) & longitude (lng)
Each fields is independent of each other. i.e. you can specify only one of “att” or “prop” or “loc” in a request. e.g. request payload for registering a single property:
{
"prop":{"n":"property-name", "dt":"", "rwx":0x01, "v": optional-property-value},
}
Request payload for multiple attributes/properties registration can be done by sending them in a json object array.
{
"att": [{"n":"attribute-name", "v":...}, {"n":"attribute-name", "v":..., }, {...}],
"prop": [{"n":"property-name", "dt":"", "rwx":0x01, "v": optional-property-value},
{"n":"property-name", ..., ..., ... }, {...}],
}
Retrieving declared properties
App/Device instances can retrieve (read) properties declared/defined in the digital (twin) model via API.
Properties can be requested by providing a json object or array having property names as in following examples (using cURL)
All properties can be retrieved by specifying {}
empty json object as payload. All properties are returned in a json object array.
{}
Response is received as acknowledgement and would use the format:
[{"n":"property-name", "v":...}, {"n":"property-name", "v":..., }, {...}]
where v contain the value of the property.
If multiple property entries are requested, then the response is returned with only having those json objects in the array.
[{"n":"property-name", "v":...}, {"n":"property-name", "v":..., }, {...}]
Single property can be retrieved by specifying property name in the payload:
{"n":"property-name"}
Endpoints
Events
/api/v1/icapp/{icappId}/event
- App or Device Events reporting.
You can:
- Report state changes in your App/Device properties to maintain it’s state as a shadow/digital twin model.
- Use this endpoint for data ingestion / telemetry data capturing for
Analytics
Note that, all events must have a way to associate them with a unique instance/session id, and must have meaningful way to associate them with e.g. user id, resource id, asset id …etc. It is your responsibility to define such relationship in your data so that data can be meaningful for analytics.
For example you can capture energy usage by electrical equipments for Analytics
using
{
"_evt": "electricity", <-- "_evt" is a mandatory field if state of shadow/digital twin model need to be updated
"equipment": "heater",
"v": 100.0,
....
}
Acknowledge SSR
/api/v1/icapp/{icappId}/ack/{refId}
- Acknowledge from App/Device for read/write/execute requests.
Acknowledgement for remote invocations of Apps/Devices. Use with Apps/Devices that are connected
with the platform to response to Server Sent Request
(SSR).
{
...
}
Create a Long Running Session
For Websocket/MQTT transport’s ONLY, client connect and start processing messages.
Clients who need responding to Server Sent Request
(SSR) via my-app
settings e.g. for IoT devices or monitoring Apps, need to connect using websocket/mqtt (WSS=1 and MQTT=2).
Esp for MQTT, if you need to subscribe to server/cloud platform sent requests per
-
App/Device session: /api/v1/mo/{appId}
-
App/Device instance session: /api/v1/mo/{appId}/cid/{cid}
-
App/Device ACK: /api/v1/mo/{appId}/ack/{refId} - it will associate back to it’s original flow via a reference state
-
App/Device SSE: /api/v1/mo/{appId}/sse
MQTT
Properties
- Support only MQTT 3.1.1. Currently No support for ver 5.x (3.1 is also not supported)
- Only QoS levels 0 and 1 are supported
- When QoS level 2 is requested, we do not send a PUBACK or SUBACK.
- Will msg is not supported for the time being.
- automatic reconnect: true
- clean session: true
Authentication:
clientId: App/Device ID username - empty string password - app token - token could be App/Device or Bearer
Topic for publishing must match the API paths:
Use /# for wildcards for all App/Device without a specific instance: /api/v1/mo/{appId}/#
e.g. /api/v1/mo/cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/#
Topics
Publishing
Topic | Description |
---|---|
/api/v1/mo/{appId} | read, update(register) App/Device config. [IN: create, delete session]. |
/api/v1/mo/{appId}/cid/{clientId} | read, update(register) App/Device client config. [IN: create, delete session]. |
/api/v1/mo/{appId}/cid/{clientId}/event | Events capture for status update |
/api/v1/mo/{appId}/cid/{clientId}/ack/{refId} | Acknowledgement from client for reads requests |
/api/v1/icapp/{icappId} | Trigger an |
/api/v1/icapp/{icappId}/event | Events capture for status update and trigger an |
/api/v1/icapp/{icappId}/cid/{clientId}/event | Events capture from a client for status update and trigger an |
/api/v1/icapp/{icappId}/ack/{refId} | Acknowledgement for a |
/api/v1/agw/{icappId}/{path} | API Gateway API request |
Subscription
To read/write/execute commands
Topic | Description |
---|---|
$/api/v1/mo/{appId}/# | All clients of a App/Device - for write/execute only |
$/api/v1/mo/{appId}/cid/# | All clients of a App/Device - for write/execute only |
$/api/v1/mo/{appId}/cid/{clientId} | For a client with ID clientId - for read/write/execute only |
$/api/v1/icapp/{icappId}/cid/# | For a |
$/api/v1/icapp/{icappId}/cid/{clientId} | For a |
Payload
Request:
{
mid: 999,
op: "", Op code <-- on error this is the error status
msg: ... <-- when no errors this is the msg
err: ... <-- on error this is err msg
}
Response:
{
mid: 999,
op: "", Op code <-- on error this is the error status
msg: ... <-- when no errors this is the msg
err: ... <-- on error this is err msg
}
How to
$ mosquitto_sub -h ics.rapidomize.com -p 8883 -u "cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd" -P YOUR_TOKEN --cafile ./testca.pem -i cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt -t /api/v1/mo/cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt
$ mosquitto_sub -h localhost -p 8883 -u "cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd" -P YOUR_TOKEN --cafile ./testca.pem -i cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt -t /api/v1/mo/cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt
$ mosquitto_pub -h localhost -p 8883 -u "cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd" -P YOUR_TOKEN --cafile ./testca.pem -i cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt -t /api/v1/mo/cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt/ack/855608337603271d63b6-7-8169fdbf02521 -m "{\"op\":2,\"msg\":{\"n\":\"color\", \"v\":\"blue\"}}"
$ mosquitto_sub -h localhost -p 8883 -u "cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd" -P YOUR_TOKEN --cafile ./testca.pem -i cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt -t /api/v1/mo/cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt/event
$ mosquitto_pub -h localhost -p 8883 -u "cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd" -P YOUR_TOKEN --cafile ./testca.pem -i cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt -t /api/v1/mo/cd3c3674-8d92-4c2e-a6b0-e8412e6fbefd/cid/cls-mqtt/event -m "{\"op\":2,\"msg\":{\"_evt\":\"colorCh\", \"n\":\"color\", \"v\":\"blue\"}}"
Operation (op-code) & status code for Websocket and MQTT
In Websocket and MQTT, messages uses op-code & status code to indicate operations such as read, write or execute and response status. To be consistent with HTTP API, it has been defined some what matching the HTTP request & status codes. A simple hex code is partly adopted from CoAP spec reduce payload size.
3-bit class and a 5-bit detail are used to encode a op-code & status code:
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|class| detail |
+-+-+-+-+-+-+-+-+
e.g. request op-code
- 0x01 -> 000 00001 -> 0.01 => READ
- 0x02 -> 000 00002 -> 0.02 => WRITE
e.g. response status
- 0x41 -> 010 00001 -> 2.01 => CREATED
- 0x9d -> 100 11101 -> 4.29 => TOO_MANY_REQUESTS
- 0xA5 -> 101 00101 -> 5.20 => UNKNOWN
Request op-code
op-code (hex) | Operation (Method) | code | Equivalent HTTP method |
---|---|---|---|
0x00 | NOP | ||
0x01 | READ | 0.01 | GET |
0x02 | WRITE | 0.02 | POST |
0x03 | UPDATE | 0.03 | PUT |
0x04 | DELETE | 0.04 | DELETE |
0x05 | EXEC | 0.05 | POST |
0x06 | PATCH | 0.06 | PATCH |
0x07 | INFO | 0.07 | OPTIONS |
Response status code
op-code (hex) | Equivalent HTTP status | code |
---|---|---|
0x20 | CONTINUE | 1.00 |
0x21 | SWITCHING_PROTOCOLS | 1.01 |
0x22 | PROCESSING | 1.02 |
0x40 | OK | 2.00 |
0x41 | CREATED | 2.01 |
0x42 | ACCEPTED | 2.02 |
0x44 | CHANGED | 2.04 |
0x44 | NO_CONTENT | 2.04 |
0x45 | TUN_ACK | 2.05 |
0x62 | FOUND | 3.02 |
0x64 | NOT_CHANGED | 3.04 |
Client Error 4xx | ||
0x80 | BAD_REQUEST | 4.00 |
0x81 | UNAUTHORIZED | 4.01 |
0x83 | FORBIDDEN | 4.03 |
0x84 | NOT_FOUND | 4.04 |
0x86 | NOT_ACCEPTABLE | 4.06 |
0x88 | REQUEST_TIMEOUT | 4.08 |
0x89 | CONFLICT | 4.09 |
0x8A | GONE | 4.10 |
0x8B | INVALID_CONTENT_SIZE | 4.11 |
0x8C | PRECONDITION_FAILED | 4.12 |
0x8D | PAYLOAD_TOO_LARGE | 4.13 |
0x8F | UNSUPPORTED_MEDIA_TYPE | 4.15 |
0x9D | TOO_MANY_REQUESTS | 4.29 |
Server Error 5xx | ||
0xA0 | INTERNAL_SERVER_ERROR | 5.00 |
0xA2 | BAD_GATEWAY | 5.02 |
0xA3 | SERVICE_UNAVAILABLE | 5.03 |
0xA4 | GATEWAY_TIMEOUT | 5.04 |
0xA5 | INVALID_VERSION | 5.05 |
0xB4 | UNKNOWN | 5.20 |
Client SDK
Refer to Client SDK for a list of client SDKs that you can use in your favorite language to access the APIs.