Using DeviceManager is indeed simple: create a template with attributes and then create devices using that template. That’s it. This page will show how to do that.
All examples in this page consider that all dojot’s components are up
and running (check the
documentation for how to do that).
All request will include a ${JWT}
variable - this was retrieved from
auth component.
Right off the bat, let’s retrieve a token from auth
:
curl -X POST http://localhost:8000/auth \
-H 'Content-Type:application/json' \
-d '{"username": "admin", "passwd" : "admin"}'
{
"jwt": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIU..."
}
This token will be stored in bash ${JWT}
bash variable, referenced
in all requests.
Attention!
Every request made with this token will be valid only for the tenant (user “service”) associated with this token. For instance, listing created devices will return only those devices which were created using this tenant.
A template is, simply put, a model from which devices can be created. They can be merged to build a single device (or a set of devices). It is created by sending a HTTP request to DeviceManager:
curl -X POST http://localhost:8000/template \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
"label": "SuperTemplate",
"attrs": [
{
"label": "temperature",
"type": "dynamic",
"value_type": "float"
},
{
"label": "pressure",
"type": "dynamic",
"value_type": "float"
},
{
"label": "model",
"type": "static",
"value_type" : "string",
"static_value" : "SuperTemplate Rev01"
}
]
}'
Supported type
values are “dynamic”, “static” and “meta”. Supported
value_types
are “float”, “geo” (for georeferenced data), “string”,
“integer”.
The answer is:
{
"result": "ok",
"template": {
"created": "2018-01-05T15:41:54.803052+00:00",
"attrs": [
{
"template_id": "1",
"created": "2018-01-05T15:41:54.840116+00:00",
"label": "temperature",
"value_type": "float",
"type": "dynamic",
"id": 1
},
{
"template_id": "1",
"created": "2018-01-05T15:41:54.882169+00:00",
"label": "pressure",
"value_type": "float",
"type": "dynamic",
"id": 2
},
{
"static_value": "SuperTemplate Rev01",
"created": "2018-01-05T15:41:54.883507+00:00",
"label": "model",
"value_type": "string",
"type": "static",
"id": 3,
"template_id": "1"
}
],
"id": 1,
"label": "SuperTemplate"
}
}
Let’s create one more template, so that we can see what happens when two templates are merged.
curl -X POST http://localhost:8000/template \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
"label": "ExtraTemplate",
"attrs": [
{
"label": "gps",
"type": "dynamic",
"value_type": "geo"
}
]
}'
Which results in:
{
"result": "ok",
"template": {
"created": "2018-01-05T15:47:02.993965+00:00",
"attrs": [
{
"template_id": "2",
"created": "2018-01-05T15:47:02.995541+00:00",
"label": "gps",
"value_type": "geo",
"type": "dynamic",
"id": 4
}
],
"id": 2,
"label": "ExtraTemplate"
}
}
Let’s check all templates we’ve created so far.
curl -X GET http://localhost:8000/template -H "Authorization: Bearer ${JWT}"
{
"templates": [
{
"created": "2018-01-05T15:41:54.803052+00:00",
"attrs": [
{
"template_id": "1",
"created": "2018-01-05T15:41:54.840116+00:00",
"label": "temperature",
"value_type": "float",
"type": "dynamic",
"id": 1
},
{
"template_id": "1",
"created": "2018-01-05T15:41:54.882169+00:00",
"label": "pressure",
"value_type": "float",
"type": "dynamic",
"id": 2
},
{
"static_value": "SuperTemplate Rev01",
"created": "2018-01-05T15:41:54.883507+00:00",
"label": "model",
"value_type": "string",
"type": "static",
"id": 3,
"template_id": "1"
}
],
"id": 1,
"label": "SuperTemplate"
},
{
"created": "2018-01-05T15:47:02.993965+00:00",
"attrs": [
{
"template_id": "2",
"created": "2018-01-05T15:47:02.995541+00:00",
"label": "gps",
"value_type": "geo",
"type": "dynamic",
"id": 4
}
],
"id": 2,
"label": "ExtraTemplate"
}
],
"pagination": {
"has_next": false,
"next_page": null,
"total": 1,
"page": 1
}
}
Now devices can be created using these two templates. Such request would be:
curl -X POST http://localhost:8000/device \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
"templates": [
"1",
"2"
],
"label": "device"
}'
The result is:
{
"device": {
"templates": [
1,
2
],
"created": "2018-01-05T17:33:31.605748+00:00",
"attrs": {
"1": [
{
"template_id": "1",
"created": "2018-01-05T15:41:54.840116+00:00",
"label": "temperature",
"value_type": "float",
"type": "dynamic",
"id": 1
},
{
"template_id": "1",
"created": "2018-01-05T15:41:54.882169+00:00",
"label": "pressure",
"value_type": "float",
"type": "dynamic",
"id": 2
},
{
"static_value": "SuperTemplate Rev01",
"created": "2018-01-05T15:41:54.883507+00:00",
"label": "model",
"value_type": "string",
"type": "static",
"id": 3,
"template_id": "1"
}
],
"2": [
{
"template_id": "2",
"created": "2018-01-05T15:47:02.995541+00:00",
"label": "gps",
"value_type": "geo",
"type": "dynamic",
"id": 4
}
]
},
"id": "b7bd",
"label": "device"
},
"message": "device created"
}
Notice how the resulting device is structured: it has a list of related
templates (template
attribute) and each of its attributes are
separated by template ID: temperature
, pressure
and model
are inside attribute 1
(ID of the first created template) and
gps
is inside attribute 2
(ID of the second template). The new
device ID can be found in the id
attribute, which is b7bd
.
A few considerations must be made:
- If the templates used to compose this new device had attributes with the same name, an error would be generated and the device would not be created.
- If any of the related templates are removed, all its attributes will also be removed from the devices that were created using it. So be careful.
Let’s retrieve this new device:
curl -X GET http://localhost:8000/device -H "Authorization: Bearer ${JWT}"
This request will list all created devices for the tenant.
{
"pagination": {
"has_next": false,
"next_page": null,
"total": 1,
"page": 1
},
"devices": [
{
"templates": [
1,
2
],
"created": "2018-01-05T17:33:31.605748+00:00",
"attrs": {
"1": [
{
"template_id": "1",
"created": "2018-01-05T15:41:54.840116+00:00",
"label": "temperature",
"value_type": "float",
"type": "dynamic",
"id": 1
},
{
"template_id": "1",
"created": "2018-01-05T15:41:54.882169+00:00",
"label": "pressure",
"value_type": "float",
"type": "dynamic",
"id": 2
},
{
"static_value": "SuperTemplate Rev01",
"created": "2018-01-05T15:41:54.883507+00:00",
"label": "model",
"value_type": "string",
"type": "static",
"id": 3,
"template_id": "1"
}
],
"2": [
{
"template_id": "2",
"created": "2018-01-05T15:47:02.995541+00:00",
"label": "gps",
"value_type": "geo",
"type": "dynamic",
"id": 4
}
]
},
"id": "b7bd",
"label": "device"
}
]
}
Removing templates and devices is also very simple. Let’s remove the device created previously:
curl -X DELETE http://localhost:8000/device/b7bd -H "Authorization: Bearer ${JWT}"
{
"removed_device": {
"templates": [
1,
2
],
"created": "2018-01-05T17:33:31.605748+00:00",
"attrs": {
"1": [
{
"template_id": "1",
"created": "2018-01-05T15:41:54.840116+00:00",
"label": "temperature",
"value_type": "float",
"type": "dynamic",
"id": 1
},
{
"template_id": "1",
"created": "2018-01-05T15:41:54.882169+00:00",
"label": "pressure",
"value_type": "float",
"type": "dynamic",
"id": 2
},
{
"static_value": "SuperTemplate Rev01",
"created": "2018-01-05T15:41:54.883507+00:00",
"label": "model",
"value_type": "string",
"type": "static",
"id": 3,
"template_id": "1"
}
],
"2": [
{
"template_id": "2",
"created": "2018-01-05T15:47:02.995541+00:00",
"label": "gps",
"value_type": "geo",
"type": "dynamic",
"id": 4
}
]
},
"id": "b7bd",
"label": "device"
},
"result": "ok"
}
Removing templates is also simple:
curl -X DELETE http://localhost:8000/template/1 -H "Authorization: Bearer ${JWT}"
{
"removed": {
"created": "2018-01-05T15:41:54.803052+00:00",
"attrs": [
{
"template_id": "1",
"created": "2018-01-05T15:41:54.840116+00:00",
"label": "temperature",
"value_type": "float",
"type": "dynamic",
"id": 1
},
{
"template_id": "1",
"created": "2018-01-05T15:41:54.882169+00:00",
"label": "pressure",
"value_type": "float",
"type": "dynamic",
"id": 2
},
{
"static_value": "SuperTemplate Rev01",
"created": "2018-01-05T15:41:54.883507+00:00",
"label": "model",
"value_type": "string",
"type": "static",
"id": 3,
"template_id": "1"
}
],
"id": 1,
"label": "SuperTemplate"
},
"result": "ok"
}
These are the very basic operations performed by DeviceManager. All operations can be found in API documentation.
You can invoke any device actuation via DeviceManager. In order to do so, you have to create some "actuator" attributes in a template. They represent a function exposed by the physical device, such as setting the target temperature, making a step-motor move a bit, resetting the device, etc. Let's create a very similar template from Creating templates and devices section and call it a 'Thermostat':
curl -X POST http://localhost:8000/template \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
"label": "Thermostat",
"attrs": [
{
"label": "temperature",
"type": "dynamic",
"value_type": "float"
},
{
"label": "pressure",
"type": "dynamic",
"value_type": "float"
},
{
"label": "model",
"type": "static",
"value_type" : "string",
"static_value" : "Thermostat Rev01"
},
{
"label": "target_temperature",
"type": "actuator",
"value_type": "float"
}
]
}'
Note that we have one more attribute - target_temperature
- to which we
will send messages to set the target temperature. This attribute could also
have the same name as temperature
with no side-effects whatsoever. If an
actuation request is received by dojot, only actuator
-type attribute are
considered.
This request should give an answer like this:
{
"result": "ok",
"template": {
"created": "2018-01-30T12:16:51.423705+00:00",
"label": "Thermostat",
"attrs": [
{
"template_id": "1",
"created": "2018-01-30T12:16:51.427113+00:00",
"label": "temperature",
"value_type": "float",
"type": "dynamic",
"id": 1
},
{
"template_id": "1",
"created": "2018-01-30T12:16:51.429224+00:00",
"label": "pressure",
"value_type": "float",
"type": "dynamic",
"id": 2
},
{
"static_value": "Thermostat Rev01",
"created": "2018-01-30T12:16:51.430194+00:00",
"label": "model",
"value_type": "string",
"type": "static",
"id": 3,
"template_id": "1"
},
{
"template_id": "1",
"created": "2018-01-30T12:16:51.430870+00:00",
"label": "target_temperature",
"value_type": "float",
"type": "actuator",
"id": 4
}
],
"id": 1
}
}
Creating a device based on it is no different than before:
curl -X POST http://localhost:8000/device \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
"templates": [
"1"
],
"label": "device"
}'
This gives back the following data:
{
"message": "devices created",
"devices": [
{
"id": "356d",
"label": "device"
}
]
}
To send a configuration message to the device, you should send a request like this:
curl -X PUT http://localhost:8000/device/356d/actuate \
-H "Authorization: Bearer ${JWT}" \
-H 'Content-Type:application/json' \
-d ' {
"attrs": {
"target_temperature" : 10.6
}
}'
The request payload contains only the following attribute:
- attrs: All the attributes and their respective values that will be configured on the device. Each value can be as simple as a float or a string, or it could hold a more complex structure, such as an object.
Remember that the attribute must be an actuator for this request to succeed. If not, a message like the following one is returned:
{
"status": "some of the attributes are not configurable",
"attrs": [
"pressure"
]
}
The request will be published via Kafka. All elements that are interested in device notifications (such as IoT agents), will received it. What should be done with it is up to the component that processes this message. Check the documentation of each component (in particular, from IoT agents) to check what is done with it.