# Devices Management
One of the major use cases for running an Ability Edge gateway is to have an enabler for cloud communication for other legacy devices. In order to properly manage the devices information models, module is able to do the following operations:
- create new devices,
- update devices,
- delete devices.
These are the respective MQTT topics that must be used to accomplish the above:
{topics_messages_out}/type=deviceCreated&objectId={optional device's objectId}
{topics_messages_out}/type=deviceUpdated&objectId={device's objectId}
{topics_messages_out}/type=deviceDeleted&objectId={device's objectId}
The payload format of deviceUpdated
has already been shown in the article
about model updates.
# Creating Devices
Use it to create a model for a new device connected to the module (directly or indirectly). If the device is created with an objectId it must be included in the properties. The payload must include a type identifier, unique properties (if any) as well as an objectId of the parent that this device will be linked to. If a model already exists based on (optional) objectId, type and unique properties provided in the request, it will be updated if necessary.
Once a model is created/updated, it will be delivered via
{topics_model_in}/{model}/{objectId}
. The module can then correlate this
objectId with the device based on unique properties (if objectId was not known
on creation). Every module restart will also result in delivery of the children
objects.
The module will become an owner of the new object, which means that only the module will be able to update the abb.ability.device information model.
Example of the message:
Topic: type=deviceCreated&objectId=55555cb3-435d-4ef6-8779-9dd34f01a2b6
Payload:
{
"type": "abb.ability.device.sampleDevice@1",
"properties": {...},
"parent": {
"objectId": "{object which device model this device will be linked to, i.e. the module itself}",
"reference": "{reference name for the above link}",
"attributes": "{map of attributes for the above reference, if any}"
}
}
# Example
Let's say that our module has the following abb.ability.device type definition:
{
"model": "abb.ability.device",
"typeId": "abb.mj.simpleEdge.module.device",
"version": "1.0.0",
"unique": [
"name"
],
"properties": {
"name": {
"description": "Name of this module (in the context of the edge device)",
"dataType": "string",
"isMandatory": true
}
},
"variables": {
"docker": {
"image": {
"description": "Docker image of this module. Reported by the edge runtime",
"dataType": "string"
},
"state": {
"description": "Runtime state of this module. Reported by the edge runtime",
"dataType": "string",
"enum": [
"running",
"stopped"
]
}
}
},
"relatedModels": {
"abb.ability.configuration": {
"type": "abb.mj.simpleEdge.module.configuration@1",
"uniqueMapping": {
"name": "name"
}
}
},
"references": {
"devices": {
"isHierarchical": true,
"to": [
{
"type": "abb.mj.physicalSensor.device@1"
}
]
}
}
}
As you can see, there is a possibility to create references to the objects of type "abb.mj.physicalSensor.device@1". Here's the type definition:
{
"typeId": "abb.mj.physicalSensor.device",
"model": "abb.ability.device",
"version": "1.0.0",
"unique": [
"serialNumber"
],
"properties": {
"serialNumber": {
"dataType": "string",
"isMandatory": true
}
}
}
In this example, the module's goal is to manage some device that is not able to
communicate with the Ability Platform on its own. The module would somehow
connect with that device and inform the cloud of its existence by creating a
model for it in the cloud. That model would be linked as a child of the module
itself. The module would have to send the deviceCreated
message:
Topic: modules/simpledotnetmodule/messages/events/type=deviceCreated
Payload:
{
"type": "abb.mj.physicalSensor.device@1",
"properties": {
"serialNumber": {
"value": "abc"
}
},
"parent": {
"objectId": "4fd2de7c-0a11-4f50-8f66-b985a261df12",
"reference": "devices"
}
}
The parent
object contains the objectId of the module (since the module will
be a parent of the device), and the name of the reference that the device will
be using (devices
- look in the type definition of the module).
Since we did not set any objectId (in the topic name and in the payload), it will be generated by the cloud components. As soon as the model gets created, it will be delivered to the module as a message:
Topic:
modules/simpledotnetmodule/model/desired/abb.ability.device/7ebad07d-c3e3-428b-9b23-5d7d3f9ac194
Payload:
{"model":"abb.ability.device","type":"abb.mj.physicalSensor.device@1","ownerId":"540d523f-5c7a-4b9d-a77e-33b8fc1ea448","path":"simpledotnetmodule","version":1,"lastModified":"2021-02-10T14:58:14.514Z","properties":{"serialNumber":{"value":"abc"}},"objectId":"7ebad07d-c3e3-428b-9b23-5d7d3f9ac194","tenantId":"5f059166-65ea-49f5-8227-f8f547d75641"}
As you can see, we got the JSON containing the full representation of the device's information model. The device's objectId is present in the topic itself, and in the payload.
To verify from the cloud side that the child has been created, we can use the References endpoint of Instance API to query for all references of our new device:
curl -X GET "https://{instance api url}/v1/objects/7ebad07d-c3e3-428b-9b23-5d7d3f9ac194/models/abb.ability.device/references" /
--header "accept: application/json" /
--header "Authorization: Bearer eyJ0eXAi..."
Here's the response:
{
"data": [
{
"referenceId": "c61f5b8e-b517-4c8b-bba5-5cccf7571c55",
"name": "devices",
"from": {
"model": "abb.ability.device",
"objectId": "4fd2de7c-0a11-4f50-8f66-b985a261df12"
},
"to": {
"model": "abb.ability.device",
"objectId": "7ebad07d-c3e3-428b-9b23-5d7d3f9ac194"
}
}
]
}
You can see a reference from the module to the device (look at the objectIds).
# Deleting Devices
You might need to remove existing module's child devices. One of the reasons
could be that the device gets broken and needs to be replaced. The deviceDeleted
message will do the following:
- remove a reference from the module
- delete the device's object model
Properties must contain an objectId of the device. All incoming and outgoing
references to/from that device model will be removed, as well as target models
of outgoing references which are defined with isContainment=true
in the type
definition.
The payload of the message should be an empty JSON object ({}
).
# Example
Continuing the last example, let's try to remove the device that we have just created. First, the module should send the following message:
Topic: modules/simpledotnetmodule/messages/events/type=deviceDeleted&objectId=7ebad07d-c3e3-428b-9b23-5d7d3f9ac194
Payload:
{}
Since we did not ask for an acnowledgement, no answer is delivered back.
We can verify that the object was deleted by invoking the Instance API endpoint:
curl -X GET "https://{instance api URL}/v1/objects/7ebad07d-c3e3-428b-9b23-5d7d3f9ac194/models/abb.ability.device?isHolistic=false" /
--header "accept: application/json" /
--header "Authorization: Bearer eyJ0eXA..."
The response tells us that the object does not exist:
{
"errors": [
{
"code": "404",
"title": "NotFound",
"detail": "Object with objectId: 7ebad07d-c3e3-428b-9b23-5d7d3f9ac194 and model: abb.ability.device not found in database.",
"id": "0HM614SOC2D3G:000013B6",
"status": "NotFound"
}
]
}
← Telemetry Model Query →