Consume an aspect

In the previous section Read digital twins and their aspects, you have seen how the Digital Twin Registry can be queried for a digital twin.

The query response for a twin contains, among other things, the information about which aspects are registered with the digital twin.

Example of an array of aspects

"aspects": [
  {
    "id": "...",
    "owningTenantId": "...",
    "modelReference": {
      "urn": "urn:samm:io.openmanufacturing.examples.movement:1.0.0#Movement",
      "aspectName": "Movement",
      "aspectVersion": "1.0.0"
    },
    "httpEndpoints": [
      {
        "url": "https://demo.bosch-semantic-stack.com/api/movement/42",
        "id": "...",
        "owningTenantId": "...",
        "method": "GET",
        "type": "READ"
      }
    ]
  }
]

For each entry in the aspects array, there are two important bits of information:

  1. The URN of an Aspect Model : this is the full identifier of the model that provides the semantic description of the aspect, including the namespace, version, and name. In this case, the URN references the Movement.ttl Aspect Model.

  2. One or more aspect endpoints that can be queried for the actual data of the aspect.

You will learn more about the Aspect Model in the next section, Understand Aspect Models to reveal semantics of data.

Read the aspect data

Even without knowing or understanding the movement Aspect Model, you can retrieve raw data from the aspect, as you now know the HTTP endpoint.

Multiple types of queries are possible, details of which are explained in Aspect endpoint types.

The easiest, most straightforward request is an HTTP GET request to the given URL of the aspect to read the current state of the data in the aspect. This is indicated by the response shown above by:

  • "method": "GET"

  • "type": "READ"

Note that the URL for the aspect will most likely contain a reference to the digital twin the aspect is registered with. In the example response above, the 42 part in the URL refers to the digital twin with this ID.

This GET request will return the aspect’s data as HTTP response in JSON format:

{
  "isMoving" : true,
  "position" : {
    "altitude" : 153.0,
    "latitude" : 9.1781,
    "longitude" : 48.80835
  },
  "speed" : 23.5,
  "speedLimitWarning" : "green"
}

Operate your assets through the aspect API

Besides just reading data from your assets, you can also trigger actions on your assets, for example, actions that a machine should perform. Such operations are requests issued in JSON-RPC format. A JSON-RPC request calls a method on the aspect, hands over input parameters for the method and optionally returns a value.

You will learn more about operations in Aspect Models and JSON-RPC in the next section, Understand Aspect Models to reveal semantics of data.

Try it out

You can try these requests yourself by importing C1-consume-aspect.json into Postman and executing it.

The collection shows how to retrieve the twin ID and add it on the path of the aspect implementation, which is currently a demo. It also shows how an operation on an aspect is called.

Expected results:

  • The temperature of Machine1 should be a number.

    {
      "temperature": 13
    }
  • The movement of AGV2 should be more complex JSON object, holding a boolean, the position coordinates, etc. in fact all elements described in the Aspect Model it is based on.

    {
      "isMoving": false,
      "position": {
        "latitude": 48.80835,
        "longitude": 9.1781,
        "altitude": 153.0
      },
      "speed": 0,
      "speedLimitWarning": "green"
    }
  • Calling the operation called temperatureInTimeRange on the Temperature aspect is done by sending an HTTP POST request with the JSON-RPC request body:

    {
      "jsonrpc": "2.0",
      "method": "temperatureInTimeRange",
      "params": {
        "start": "2023-01-01T04:20:00.00000+2:00",
        "end": "2023-01-01T08:00:00.00000+2:00"
      },
      "id": 1
    }

    The result should be a JSON-RPC response with a corresponding value:

    {
      "jsonrpc": "2.0",
      "result": 13,
      "id": 1
    }
  • In the same way, the operation setSpeedLevel on the OperatingSpeed aspect is called:

    {
      "jsonrpc": "2.0",
      "method": "setSpeedLevel",
      "params": {
        "speedLevel": "HIGH"
      },
      "id": 1
    }

    The result is the corresponding JSON-RPC response:

    {
      "jsonrpc": "2.0",
      "result": "OK",
      "id": 1
    }