Exchange ase.exchange.driver

Setup

User: device-driver-user

Permissions: the device driver user can create an exclusive queue that starts with "ase.queue.driver." (with a unique suffix) and bind it to the ase.exchange.driver (headers) exchange specifying which headers/arguments to bind with (x-match=all or x-match=any). This user can only subscribe and consume/get messages. This is a mechanism for core services to publish messages to the driver with specific targeting.

The headers to be used for binding and targeting as follows.

Exchange Headers
ase.exchange.driver thingID=<thingID>
ase.exchange.driver messageType=addThing

Incoming Messages

These messages come in on the unique queue bound to the exchange.

Exchange Queue Headers Body Response
ase.exchange.driver <unique> messageType=addThing <The Thing Description for thingID> "none"
ase.exchange.driver <unique>

messageType=updateThing

thingID={thingID}

<The Thing Description for thingID> "none"
ase.exchange.driver <unique>

messageType=deleteThing

thingID={thingID}

<empty> "none"
ase.exchange.driver <unique>

messageType=setProperty

thingID={thingID}

property={propertyKey}

{"<propertyKey>": <propertyValue>} "none"
ase.exchange.driver <unique>

messageType=requestAction

thingID={thingID}

action={actionKey}

actionID={actionID}

{"<actionKey>": {"input": <action input>}} "actionStatus"
ase.exchange.driver <unique>

messageType=cancelAction

thingID={thingID}

action={actionKey}

actionID={actionID}

{"<actionKey>": {"input": <action input>}} "actionStatus"
ase.exchange.driver <unique> messageType=ping <empty> "pong"
ase.exchange.driver <unique> messageType=setLogConfig {"level":<level>, "pretty": <true/false>, "color": <true/false>} "setLogConfig"
ase.exchange.driver <unique>

messageType=requestReport

reportType=<report type>

reportID=<report id>

<see applications > device drivers > opcua/bacnet > usage> "reportStatus"
ase.exchange.driver <unique>

messageType=updateReport

reportType=<report type>

reportID=<report id>

<see applications > device drivers > opcua/bacnet > usage> "reportStatus"
ase.exchange.driver <unique> messageType=requestAPIregistration <none> "registerAPI"

Response Messages

The following are response messages to the incoming messages. Note that the messages are published to different exchanges or queues. The queue is the "replyTo" property of the AMQP message.

The responses to the incoming messages related to discovery ("upload" and "reportStatus" responses) are described on the "Exchange Core" page.

The response to the requestAPIregistration message is done by publishing a message to the "Exchange API" as described on the "Register API" page.

Exchange Queue Headers Body Response To
ase.exchange.telemetry

messageType=actionStatus

publishTag=raw

thingID=<thingID>

{"messageType":<messageType>,"thingID":<thingID>,"timestamp":<timestamp>,"data":{"<actionKey>":{"href":<action href>"input":<action input>,"status":<action status>}}} "requestAction""cancelAction"
<replyTo>

messageType=pong

serviceKey=<service key>

serviceName=<service name>

timestamp=<timestamp>

version=<version>

gitSha=<git SHA>

buildDate=<build date>

<empty> "ping"
<replyTo>

messageType=setLogConfig

serviceKey=<service key>

{"status": "completed"} "setLogConfig"

Action Message Processing

Let's use an example of a device that has an Action called "activate" defined on its Thing description (schema) and an Event, with the same name, as follows:

    "uid": "453AEP18F901FRJK8J1MJ10ZYR",
    "actions": {
        "activate": {
            "title": "Activate",
            "description": "Activate the device",
            "input": {
                "properties": {
                    "address": {
                        "type": "string"
                    },
                    "secure_key": {
                        "type": "string"
                    }
                },
                "type": "object"
            }
        }
    },
    "events": {
        "activate": {
            "title": "Activate request is done",
            "description": "Response of activate request",
            "data": {
                "type": "object"
            }
        }
    }
Note: The unique IDs in this example are made up and will differ for a real use case.

When the user request this Action through an API call (using Studio or direct), the following AMQP message is published to all queues on the ase.exchange.driver exchange bound with header thingID=453AEP18F901FRJK8J1MJ10ZYR as follows:

AMQP headers:
messageType=requestAction
thingID=453AEP18F901FRJK8J1MJ10ZYR
action=activate
actionID=6CTAX0F1M01FRJKZ1DJXG5T3ZS
AMQP message body:
{
    "activate": {
        "input": {
            "address": "f1110197",
            "secure_key": "e4eb6ff6281bea9e568236802dcf4e0a"
        }
    }
}

When the third party service receives this Action request it should first publish an actionStatus message to the ase.exchange.telemetry exchange as follows:

AMQP headers:
messageType=actionStatus
publishTag=raw
thingID=453AEP18F901FRJK8J1MJ10ZYR
AMQP message body:
{
    "thingId": "453AEP18F901FRJK8J1MJ10ZYR",
    "timestamp": 1645421436,
    "data": {
        "activate" {
            "href": "/things/453AEP18F901FRJK8J1MJ10ZYR/actions/activate/6CTAX0F1M01FRJKZ1DJXG5T3ZS",
            "timeRequested": "2022-02-21T05:30:36Z",
            "status": "received"
        }
    }
}

The href item is required for further processing by the core services of the ECP and is constructed as follows: /things/<thingID>/actions/<action>/<actionID>.

The status item will update the state of the action request. When the third party service has received an action request this status should be updated to received.

The third party service can now do the necessary to run the requested action. If successful the result of the action should be published to the associated event by publishing an event message to the ase.exchange.telemetry exchange as follows:
AMQP headers:
messageType=event
publishTag=raw
thingID=453AEP18F901FRJK8J1MJ10ZYR
AMQP message body:
{
    "thingId": "453AEP18F901FRJK8J1MJ10ZYR",
    "data": {
        "activate" {
            "data": {
                "address": "f1110197",
                "access_key": "ea9e56823e4eb6ff6281b6802dcf4e0a"                
            }
        }
    }
}

With the action completed successfully, an actionStatus message needs to be published with status=completed to the ase.exchange.telemetry exchange as follows:

AMQP headers:
messageType=actionStatus
publishTag=raw
thingID=453AEP18F901FRJK8J1MJ10ZYR
AMQP message body:
{
    "thingId": "453AEP18F901FRJK8J1MJ10ZYR",
    "timestamp": 1645421439,
    "data": {
        "activate" {
            "href": "/things/453AEP18F901FRJK8J1MJ10ZYR/actions/activate/6CTAX0F1M01FRJKZ1DJXG5T3ZS",
            "timeRequested": "2022-02-21T05:30:36Z",
            "timeCompleted": "2022-02-21T05:30:39Z",
            "status": "completed"
        }
    }
}

However, if the action was not successful, the event should not be published and the final actionStatus message should be sent with status=failed instead.

Property Message Processing

Let's use an example of a device that has a writeable property (readOnly:false) called "pollSeconds" defined on its thing description (schema) as follows:
    "uid": "RJK8J1453AEP18F901FMJ10ZYR",
    "properties: {
        "pollSeconds": {
            "title": "Poll Seconds",
            "type": "integer",
            "readOnly": false
        }
    }
When the user sets this property through an API call (using Studio or direct), the following AMQP message is published to all queues on the ase.exchange.driver exchange bound with header thingID=RJK8J1453AEP18F901FMJ10ZYR as follows:
AMQP headers:
messageType=setProperty
thingID=RJK8J1453AEP18F901FMJ10ZYR
property=pollSeconds
AMQP message body:
{
    "pollSeconds": 20
}
The third party service can now do the necessary to set this new property value on the end device. Any resulting telemetry data change by the end device should be published to the associated event by publishing a propertyStatus message to the ase.exchange.telemetry exchange, just like any regular telemetry data publish, as follows:
AMQP headers:
messageType=propertyStatus
publishTag=raw
thingID=RJK8J1453AEP18F901FMJ10ZYR
AMQP message body:
{
    "thingId": "RJK8J1453AEP18F901FMJ10ZYR",
    "timestamp": 1645421449,
    "data": {
        "pollSeconds": 20
    }
}