Skip to content

Creating Data Model from MQTT Agent

Overview

Asset Modeler service defines topics and message structures to create their assets, types and mappings.

Models are templates describing asset/aspect types, asset instances, asset hierarchy and mappings from data point ids to variables in aspects. Instantiations are the realization of the model. An instantiation job takes a model and creates the items described in the model by creating types, instances and mappings. A model can be instantiated many times.

Models and instantiations are loosely coupled. A change to model instantiation does not affect the model. Also, a change in the model does not affect any completed instantiations as well. For example, if a model is deleted, existing instantiations are not affected. Also, moving an asset created by an instantiation does not affect the model.

Limitations

  • The number of asset model definitions per tenant is limited.

  • There are frequency limits per tenant and per client for published and received messages.

  • The maximum size of the body is 128KBs.

Prerequisites

  • To generate certificates, ensure to have the OpenSSL toolkit or an equivalent setup to create certificates.

  • MQTTX is installed on your computer or an equivalent setup.

Preparation

Update the following fields with appropriate values before using the samples given in this section:

  • <requestId>
  • <tenantId>
  • <clientId>

MQTTX Create and Instantiate Model

EU1

  1. Agent Connection

    Agent connection should be established before publishing model creation and instantiation messages. Refer to Onboarding MindConnect MQTT Agent.

    Image1

  2. Publish Your Model

    PUB tc/<tenantId>/<clientId>/o/amo_v3/m

    Payload: Structure containing models for asset/aspect types, asset instances and mappings from provided keys to variables in the specified model.

    Model Message Example:

    {
      "id":"<requestId>",
      "data":{
        "externalId":"SpaceShip",
        "typeModel":{
          "aspectTypes":[
            {
              "id":"<tenantId>.wing",
              "name":"${aspectTypeName}",
              "category":"static",
              "scope":"private",
              "variables":[
                {
                  "name":"temperature",
                  "dataType":"STRING",
                  "unit":"C/F",
                  "searchable":true,
                  "length":5,
                  "qualityCode":true
                }
              ],
              "description":"wing aspect type description",
              "referenceId":"287adc1a086840e0a6721dfd1170e97c"
            }
          ],
          "assetTypes":[
            {
              "id":"<tenantId>.spaceship",
              "name":"wingAssetTypeName",
              "parentTypeId":"core.basicasset",
              "aspects":[
                {
                  "name":"wingAspect",
                  "aspectTypeId":"<tenantId>.wing"
                }
              ],
              "description":"Hyperspace jump capable space ship",
              "instantiable":true,
              "scope":"private",
              "referenceId":"82a4cc2a69cc42af80c1c6cf5dbefde5"
            }
          ]
        },
        "instanceModel":{
          "assets":[
            {
              "referenceId":"wingAssetReference",
              "parentReferenceId":"root",
              "typeId":"<tenantId>.spaceship",
              "name":"wingAsset",
              "description":"The ship of Han Solo and Chewbacca"
            }
          ]
        },
        "mappingModel":{
          "mappings":[
            {
              "dataPointId":"dp01",
              "assetReferenceId":"wingAssetReference",
              "aspectName":"wingAspect",
              "variableName":"temperature",
              "referenceId":"19e9048e78f540e7a9ba25e1249fea9b"
            }
          ]
        }
      }
    }
    

    image2

  3. Get Model Status

    Receive model creation results for a previous model request.

    SUB tc/<tenantId>/<clientId>/i/amo_v3/ms or SUB tc/<tenantId>/<clientId>/i/amo_v3/#

    Response Message Example:

    {
      "id":"01FQC37FCCASSFT7M0D6W5EB8P",
      "correlationId":"01FQC37FCBG1DWMTEC4DYCZ327",
      "requestId":"72609761sdv245248e126814c2dd83a27f",
      "data":{
        "id":"01FQC37HX2KGP4DR0HNVR3K5B2",
        "externalId":"SpaceShip",
        "status":"Success"
      }
    }
    

    image3

  4. Instantiate your Model

    Create a new model with given asset model in body.

    PUB tc/<tenantId>/<clientId>/o/amo_v3/i

    Payload: Message containing model instantiation request parameters. Model Id can be found in response of Model Status, Id in data object represents modelId.

    Instantiate Message Example:

    {
      "id":"<requestId>",
      "data":{
        "modelExternalId":"SpaceShip",
        "parameterization":{
          "values":[
            {
              "name":"aspectTypeName",
              "value":"wingAspectTypeName"
            }
          ]
        }
      }
    }
    

    image4

  5. Get Instantiate Model Status

    Receive instantiation job results for a previous instantiation request.

    SUB tc/<tenantId>/<clientId>/i/amo_v3/ip or SUB tc/<tenantId>/<clientId>/i/amo_v3/#

    Response Message Examples:

    Message 1:

    {
        "id": "01FQC37RDJ54CAM75RWNAQV781",
        "correlationId": "01FQC37NKDHM4774NB1R1H7PST",
        "data": {
            "id": "01FQC37NVVFZWET43NSHYZJV4B",
            "modelId": "01FQC37HX2KGP4DR0HNVR3K5B2",
            "modelExternalId": "SpaceShip",
            "message": "25% completed.",
            "status": "InProgress"
        },
        "requestId": "bb9b9d8d6193ddsss45a5w2s7e848fe28c"
    }
    

    Message 2:

    {
        "id": "01FQC37RDJ54CAM75RWNAQV781",
        "correlationId": "01FQC37NKDHM4774NB1R1H7PST",
        "data": {
            "id": "01FQC37NVVFZWET43NSHYZJV4B",
            "modelId": "01FQC37HX2KGP4DR0HNVR3K5B2",
            "modelExternalId": "SpaceShip",
            "message": "50% completed.",
            "status": "InProgress"
        },
        "requestId": "bb9b9d8d6193ddsss45a5w2s7e848fe28c"
    }
    

    Message 3:

    {
        "id": "01FQC37RDJ54CAM75RWNAQV781",
        "correlationId": "01FQC37NKDHM4774NB1R1H7PST",
        "data": {
            "id": "01FQC37NVVFZWET43NSHYZJV4B",
            "modelId": "01FQC37HX2KGP4DR0HNVR3K5B2",
            "modelExternalId": "SpaceShip",
            "message": "75% completed.",
            "status": "InProgress"
        },
        "requestId": "bb9b9d8d6193ddsss45a5w2s7e848fe28c"
    }
    

    Message 4:

    {
        "id": "01FQC37RDJ54CAM75RWNAQV781",
        "correlationId": "01FQC37NKDHM4774NB1R1H7PST",
        "data": {
            "id": "01FQC37NVVFZWET43NSHYZJV4B",
            "modelId": "01FQC37HX2KGP4DR0HNVR3K5B2",
            "modelExternalId": "SpaceShip",
            "message": "100% completed.",
            "status": "Success"
        },
        "requestId": "bb9b9d8d6193ddsss45a5w2s7e848fe28c"
    }
    

    image5

    After instantiation completed successfully, Created resources can be verified from Asset Manager.

    image6

Creating Parameterized DataModel Examples

Tenant Independent Data Model

The model is designed to be agent-independent. Parameterization feature can be used for making data model tenant agnostic. As a result, this model can be shared between agents and tenants.

In the following data model, actual tenant id information is abstracted from the data model. Variable "tenantId" has to be provided in the instantiation model. Agents which have the same configuration in different tenants can use the parameterized data model feature to re-use it. Each agent should publish the following data model after that each agent should instantiate this model with the actual tenant id.

{
  "id":"<requestId>",
  "data":{
    "externalId":"ParameterizedElectricMechanicalDeviceModel",
    "typeModel":{
      "aspectTypes":[
        {
          "id":"${tenantId}.mechanicalAspectType",
          "name":"mechanicalAspectType",
          "category":"dynamic",
          "scope":"private",
          "variables":[
            {
              "name":"readTime",
              "dataType":"TIMESTAMP",
              "unit":"second",
              "searchable":false,
              "qualityCode":true
            },
            {
              "name":"displacement",
              "dataType":"INT",
              "unit":"cm",
              "searchable":true,
              "qualityCode":true
            },
            {
              "name":"rpm",
              "dataType":"LONG",
              "searchable":true,
              "qualityCode":true
            }
          ],
          "description":"Mechanical properties of an device"
        },
        {
          "id":"${tenantId}.electricalAspectType",
          "name":"electricalAspectType",
          "category":"dynamic",
          "scope":"private",
          "variables":[
            {
              "name":"overloaded",
              "dataType":"BOOLEAN",
              "searchable":true,
              "qualityCode":true
            },
            {
              "name":"current",
              "dataType":"DOUBLE",
              "unit":"A",
              "searchable":true,
              "qualityCode":true
            },
            {
              "name":"errorMessage",
              "dataType":"STRING",
              "length":255,
              "searchable":true,
              "qualityCode":true
            }
          ],
          "description":"Electrical properties of an device"
        }
      ],
      "assetTypes":[
        {
          "id":"${tenantId}.electricalAndMechanicalAssetType",
          "name":"electricalAndMechanicalAssetType",
          "parentTypeId":"core.basicasset",
          "aspects":[
            {
              "name":"electricalAspect",
              "aspectTypeId":"${tenantId}.electricalAspectType"
            },
            {
              "name":"mechanicalAspect",
              "aspectTypeId":"${tenantId}.mechanicalAspectType"
            }
          ],
          "description":"Asset Type with electrical and mechanical properties",
          "instantiable":true,
          "scope":"private"
        }
      ]
    },
    "instanceModel":{
      "assets":[
        {
          "referenceId":"electricalAndMechanicalAssetReference",
          "parentReferenceId":"root",
          "typeId":"${tenantId}.electricalAndMechanicalAssetType",
          "name":"electricalAndMechanicalAsset",
          "description":"Asset with electrical and mechanical properties"
        }
      ]
    },
    "mappingModel":{
      "mappings":[
        {
          "dataPointId":"dataPoint1",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"electricalAspect",
          "variableName":"current"
        },
        {
          "dataPointId":"dataPoint2",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"mechanicalAspect",
          "variableName":"displacement"
        },
        {
          "dataPointId":"dataPoint3",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"mechanicalAspect",
          "variableName":"rpm"
        },
        {
          "dataPointId":"dataPoint4",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"electricalAspect",
          "variableName":"errorMessage"
        },
        {
          "dataPointId":"dataPoint5",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"electricalAspect",
          "variableName":"overloaded"
        },
        {
          "dataPointId":"dataPoint6",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"mechanicalAspect",
          "variableName":"readTime"
        }
      ]
    }
  }
}

Here is the instantiation model and this model contains actual values for parameterized values.

{
  "id":"<requestId>",
  "data":{
    "modelExternalId":"ParameterizedElectricMechanicalDeviceModel",
    "parameterization":{
      "values":[
        {
          "name":"tenantId",
          "value":"<ActualTenantId>"
        }
      ]
    }
  }
}

Name Parameterized Data Model

In the following data model, the actual tenant id and all asset-related naming information are abstracted from the data model. Variables tenantId, mechanicalAspectType, electricalAspectType , mechanicalAspect, electricalAspect electricalAndMechanicalAssetType, electricalAndMechanicalAssetType have to be provided in instantiation model.

{
  "id":"<requestId>",
  "data":{
    "externalId":"ParameterizedElectricMechanicalDeviceModel",
    "typeModel":{
      "aspectTypes":[
        {
          "id":"${tenantId}.${mechanicalAspectType}",
          "name":"${mechanicalAspectType}",
          "category":"dynamic",
          "scope":"private",
          "variables":[
            {
              "name":"readTime",
              "dataType":"TIMESTAMP",
              "unit":"second",
              "searchable":false,
              "qualityCode":true
            },
            {
              "name":"displacement",
              "dataType":"INT",
              "unit":"cm",
              "searchable":true,
              "qualityCode":true
            },
            {
              "name":"rpm",
              "dataType":"LONG",
              "searchable":true,
              "qualityCode":true
            }
          ],
          "description":"Mechanical properties of an device"
        },
        {
          "id":"${tenantId}.${electricalAspectType}",
          "name":"${electricalAspectType}",
          "category":"dynamic",
          "scope":"private",
          "variables":[
            {
              "name":"overloaded",
              "dataType":"BOOLEAN",
              "searchable":true,
              "qualityCode":true
            },
            {
              "name":"current",
              "dataType":"DOUBLE",
              "unit":"A",
              "searchable":true,
              "qualityCode":true
            },
            {
              "name":"errorMessage",
              "dataType":"STRING",
              "length":255,
              "searchable":true,
              "qualityCode":true
            }
          ],
          "description":"Electrical properties of an device"
        }
      ],
      "assetTypes":[
        {
          "id":"${tenantId}.${electricalAndMechanicalAssetType}",
          "name":"${electricalAndMechanicalAssetType}",
          "parentTypeId":"core.basicasset",
          "aspects":[
            {
              "name":"${electricalAspect}",
              "aspectTypeId":"${tenantId}.${electricalAspectType}"
            },
            {
              "name":"${mechanicalAspect}",
              "aspectTypeId":"${tenantId}.${mechanicalAspectType}"
            }
          ],
          "description":"Asset Type with electrical and mechanical properties",
          "instantiable":true,
          "scope":"private"
        }
      ]
    },
    "instanceModel":{
      "assets":[
        {
          "referenceId":"electricalAndMechanicalAssetReference",
          "parentReferenceId":"root",
          "typeId":"${tenantId}.${electricalAndMechanicalAssetType}",
          "name":"${electricalAndMechanicalAsset}",
          "description":"Asset with electrical and mechanical properties"
        }
      ]
    },
    "mappingModel":{
      "mappings":[
        {
          "dataPointId":"dataPoint1",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"${electricalAspect}",
          "variableName":"current"
        },
        {
          "dataPointId":"dataPoint2",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"${mechanicalAspect}",
          "variableName":"displacement"
        },
        {
          "dataPointId":"dataPoint3",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"${mechanicalAspect}",
          "variableName":"rpm"
        },
        {
          "dataPointId":"dataPoint4",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"${electricalAspect}",
          "variableName":"errorMessage"
        },
        {
          "dataPointId":"dataPoint5",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"${electricalAspect}",
          "variableName":"overloaded"
        },
        {
          "dataPointId":"dataPoint6",
          "assetReferenceId":"electricalAndMechanicalAssetReference",
          "aspectName":"${mechanicalAspect}",
          "variableName":"readTime"
        }
      ]
    }
  }
}

Here is the instantiation model and this model contains actual values for parameterized values.

{
  "id":"<requestId>",
  "data":{
    "modelExternalId":"ParameterizedElectricMechanicalDeviceModel",
    "parameterization":{
      "values":[
        {
          "name":"tenantId",
          "value":"<ActualTenantId>"
        },
        {
          "name":"mechanicalAspectType",
          "value":"<ActualMechanicalAspectTypeName>"
        },
        {
          "name":"electricalAspectType",
          "value":"<ActualElectricalAspectTypeName>"
        },
        {
          "name":"electricalAspect",
          "value":"<electricalAspectName>"
        },
        {
          "name":"mechanicalAspect",
          "value":"<mechanicalAspectName>"
        },
        {
          "name":"electricalAndMechanicalAssetType",
          "value":"<ActualElectricalAndMechanicalAssetTypeName>"
        },
        {
          "name":"electricalAndMechanicalAsset",
          "value":"<ActualElectricalAndMechanicalAssetName>"
        }
      ]
    }
  }
}

Adding New Variable to Created Aspect Type and Mapping Created Asset

Create new model which will add new variable to existing aspect type and add new mapping to existing data asset with new externalId.

  1. Check created mappings from MindConnect MQTT plugin.

    image8

  2. Get Asset id from Asset Manager.

    image8

  3. Send New Model with new Added Variable On mapping model put existing data assetId to the model. Rather than using assetReferenceId use assetId like: assetId: 26a7ede133674bcd91fcfe053238eca1

    {
      "id":"<requestId>",
      "data":{
        "externalId":"SpaceShipWithNewVariable",
        "typeModel":{
          "aspectTypes":[
            {
              "id":"<tenantId>.wing",
              "name":"${aspectTypeName}",
              "category":"static",
              "scope":"private",
              "variables":[
                {
                  "name":"temperature",
                  "dataType":"STRING",
                  "unit":"C/F",
                  "searchable":true,
                  "length":5,
                  "qualityCode":true
                },
                {
                  "name":"speed",
                  "dataType":"LONG",
                  "unit":"km/h",
                  "searchable":true,
                  "qualityCode":true
                }
              ],
    
              "description":"wing aspect type description",
              "referenceId":"287adc1a086840e0a6721dfd1170e97c"
            }
          ],
          "assetTypes":[
          ]
        },
        "instanceModel":{
          "assets":[
          ]
        },
        "mappingModel":{
          "mappings":[
            {
              "dataPointId":"dp02",
              "assetId":"26a7ede133674bcd91fcfe053238eca1",
              "aspectName":"wingAspect",
              "variableName":"speed"
            }
          ]
        }
      }
    }
    
  4. Instantiate New Model

        {
            "id": "<requestId>",
            "data": {
                "modelExternalId": "SpaceShipWithNewVariable",
                "parameterization": {
                    "values": [{
                        "name": "aspectTypeName",
                        "value": "wingAspectTypeName"
                    }]
                }
            }
        }
    
  5. Check Newly Added Mapping from MindConnect MQTT plugin.

    image8

  6. Check Newly Added Variable from MindConnect MQTT plugin.

    image8


Last update: March 5, 2024

Except where otherwise noted, content on this site is licensed under the Development License Agreement.