Skip to content

Asset Management Service – Modeling Hierarchical Asset Structures

The following example illustrates how to model hierarchical structures of assets. In this example, a simple robotic arm inside a car factory is created, which is equipped with an IoT 2040 box. The final model will consist of 5 levels of hierarchy:

  1. The root asset representing the tenant
  2. A site asset representing the factory
  3. An area asset representing the assembly area
  4. A device asset representing a simple robotic arm
  5. An agent asset representing an IoT 2040 box

Creating the Site Asset

The factory asset is created using the following request:

POST /assets

The following JSON structure is given to define the site asset:

{
  "name": "MindCar",
  "externalId": "SN 123456-123-123456",
  "description": "Factory of MindCar",
  "location": {
    "country": "Austria",
    "region": "Tyrol",
    "locality": "Innsbruck",
    "streetAddress": "Industriestraße 21 A/II",
    "postalCode": "6020",
    "longitude": 53.5125546,
    "latitude": 9.9763411
  },
  "typeId": "core.basicsite",
  "parentId": "{assetId}",
  "timezone": "Europe/Berlin"
}

The response of the call contains the newly created asset instance, so you can validate the correct creation:

{
  "assetId": "{assetId}",
  "tenantId": "{tenantName}",
  "name": "MindCar",
  "etag": {etagValue},
  "externalId": "SN 123456-123-123456",
  "t2Tenant": null,
  "subTenant": null,
  "description": "Factory of MindCar",
  "timezone": "Europe/Berlin",
  "parentId": "{parentAssetId}",
  "typeId": "core.basicsite",
  "location": {
    "country": "Austria",
    "region": "Tyrol",
    "locality": "Innsbruck",
    "streetAddress": "Industriestraße 21 A/II",
    "postalCode": "6020",
    "longitude": 53.5125546,
    "latitude": 9.9763411
  },
  "fileAssignments": [],
  "variables": [],
  "aspects": [],
  "locks": [],
  "hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    }
  ],
  "deleted": null,
  "_links": {
    "self": {
      "href": "{link}"
    },
    "aspects": {
      "href": "{link}"
    },
    "variables": {
      "href": "{link}"
    },
    "location": {
      "href": "{link}"
    },
    "parent": {
      "href": "{link}"
    }
  }
}

Lines 26 to 31 contain the hierarchy path up to the root asset, including the parent asset's ID and its name:

"hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    }
  ]

Note

The returned hierarchy path may differ: Tenant users receive the full path to the tenant's root asset, whereas subtenant users only receive the path to the subtenant's root asset.

Creating the Area Asset

The area asset is created using the same request as before, but using the following JSON structure to define the area asset:

{
  "name": "AssemblyArea",
  "externalId": "SN 123456-123-123456",
  "description": "Assembly area of MindCar",
  "location": {
    "country": "Austria",
    "region": "Tyrol",
    "locality": "Innsbruck",
    "streetAddress": "Industriestraße 21 A/II",
    "postalCode": "6020",
    "longitude": 53.5125546,
    "latitude": 9.9763411
  },
  "typeId": "core.basicarea",
  "parentId": "{assetId}",
  "timezone": "Europe/Berlin"
}

The response of the call contains the newly created asset instance, so you can validate the correct creation:

{
  "assetId": "{assetId}",
  "tenantId": "{tenantName}",
  "name": "AssemblyArea",
  "etag": {etagValue},
  "externalId": "SN 123456-123-123456",
  "t2Tenant": null,
  "subTenant": null,
  "description": "Assembly area of MindCar",
  "timezone": "Europe/Berlin",
  "parentId": "{parentId}",
  "typeId": "core.basicarea",
  "location": {
    "country": "Austria",
    "region": "Tyrol",
    "locality": "Innsbruck",
    "streetAddress": "Industriestraße 21 A/II",
    "postalCode": "6020",
    "longitude": 53.5125546,
    "latitude": 9.9763411
  },
  "fileAssignments": [],
  "variables": [],
  "aspects": [],
  "locks": [],
  "hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    },
    {
      "assetId": "{siteAssetId}",
      "name": "MindCar"
    }
  ],
  "deleted": null,
  "_links": {
    "self": {
      "href": "{link}"
    },
    "aspects": {
      "href": "{link}"
    },
    "variables": {
      "href": "{link}"
    },
    "location": {
      "href": "{link}"
    },
    "parent": {
      "href": "{link}"
    }
  }
}

Lines 26 to 35 contain the hierarchy path up to the root asset, which consists of two levels in this case. The hierarchy path always starts at the root asset and ends with the direct parent asset:

"hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    },
    {
      "assetId": "{siteAssetId}",
      "name": "MindCar"
    }
  ]

Creating the Device Asset

When creating a new asset, the required aspect types and asset type must be defined first. In this example, the device is a simple robotic arm and the variable to be measured is its rotation.

Creating the Aspect Type

The aspect type for the rotation variable is created using the following request:

PUT /aspecttype/{id}

The following input is given for the id parameter:

{tenantName}.rotation

The following JSON structure is given to define the aspect type:

{
  "name": "rotation",
  "category": "dynamic",
  "scope": "private",
  "description": "Rotation of the robotic arm",
  "variables": [
    {
      "name": "rotation",
      "dataType": "DOUBLE",
      "unit": "degree",
      "searchable": true
    }
  ]
}

The response of the call contains the newly created aspect type, so you can validate the correct creation:

{
  "id": "{tenantName}.rotation",
  "tenantId": "{tenantName}",
  "name": "rotation",
  "category": "dynamic",
  "scope": "private",
  "description": "Rotation of the robotic arm",
  "variables": [
    {
      "name": "rotation",
      "unit": "degree",
      "searchable": true,
      "qualityCode": false,
      "dataType": "DOUBLE",
      "defaultValue": null,
      "length": null
    }
  ],
  "etag": {etagValue},
  "_links": {
    "self": {
      "href": "{link}"
    }
  }
}

Creating the Asset Type

After creating the required aspect type, the asset type for the robotic arm can be created using the following request:

PUT /assecttype/{id}

The following input is given for the id parameter:

{tenantName}.roboticarm

The following JSON structure is given to define the asset type:

{
  "name": "roboticArm",
  "description": "Robotic arm assembling cars",
  "parentTypeId": "core.basicdevice",
  "instantiable": true,
  "scope": "private",
    "aspects": [
    {
      "name": "rotation",
      "aspectTypeId": "{tenantName}.rotation"
    }
  ]
}

The response of the call contains the newly created asset type, so you can validate the correct creation:

{
  "parentTypeId": "core.basicdevice",
  "instantiable": true,
  "tenantId": "{tenantName}",
  "name": "roboticArm",
  "description": "Robotic arm assembling cars",
  "scope": "private",
  "variables": [],
  "aspects": [
    {
      "name": "rotation",
      "aspectType": {
        "id": "{tenantName}.rotation",
        "tenantId": "{tenantName}",
        "name": "rotation",
        "category": "dynamic",
        "scope": "private",
        "description": "Rotation of the robotic arm",
        "variables": [
          {
            "name": "rotation",
            "unit": "degree",
            "searchable": true,
            "qualityCode": false,
            "defaultValue": null,
            "dataType": "DOUBLE",
            "length": null
          }
        ],
        "etag": {etagValue},
        "_links": {
          "self": {
            "href": "{link}"
          }
        }
      }
    }
  ],
  "fileAssignments": [],
  "etag": {etagValue},
  "_links": {
    "self": {
      "href": "{link}"
    },
    "parent": {
      "href": "{link}"
    }
  },
  "id": "{tenantName}.roboticarm"
}

Creating the Asset

After creating the required asset type, the device asset for the robotic arm can be created using the following request:

POST /assets

The following JSON structure is given to define the device asset:

{
  "name": "roboticarm",
  "externalId": "SN 123456-123-123456",
  "description": "Robotic arm assembling cars",
  "typeId": "{tenantName}.roboticarm",
  "parentId": "{assetId}",
  "timezone": "Europe/Berlin"
}

The response of the call contains the newly created asset instance, so you can validate the correct creation:

{
  "assetId": "{assetId}",
  "tenantId": "{tenantName}",
  "name": "roboticarm",
  "etag": {etagValue},
  "externalId": "SN 123456-123-123456",
  "t2Tenant": null,
  "subTenant": null,
  "description": "Robotic arm assembling cars",
  "timezone": "Europe/Berlin",
  "parentId": "{parentId}",
  "typeId": "{tenantName}.roboticarm",
  "location": {
    "country": "Austria",
    "region": "Tyrol",
    "locality": "Innsbruck",
    "streetAddress": "Industriestraße 21 A/II",
    "postalCode": "6020",
    "longitude": 53.5125546,
    "latitude": 9.9763411
  },
  "fileAssignments": [],
  "variables": [],
  "aspects": [],
  "locks": [],
  "hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    },
    {
      "assetId": "{assetId}",
      "name": "MindCar"
    },
    {
      "assetId": "{assetId}",
      "name": "AssemblyArea"
    }
  ],
  "deleted": null,
  "_links": {
    "self": {
      "href": "{link}"
    },
    "aspects": {
      "href": "{link}"
    },
    "variables": {
      "href": "{link}"
    },
    "location": {
      "href": "{link}"
    },
    "parent": {
      "href": "{link}"
    }
  }
}

Lines 26 to 35 contain the hierarchy path up to the root asset. The hierarchy path shows all the parents up to the root asset with their assetId and name, starting from the root and finishing at the direct parent the area.

"hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    },
    {
      "assetId": "{assetId}",
      "name": "MindCar"
    },
    {
      "assetId": "{assetId}",
      "name": "AssemblyArea"
    }
  ]

Creating the IoT 2040 Agent Asset

Finally, an IoT 2040 agent asset is created using the following request:

POST /assets

The following JSON structure is given to define the agent asset:

{
  "name": "IoT2040",
  "externalId": "SN 123456-123-123456",
  "description": "IoT2040",
  "typeId": "core.mciot2040",
  "parentId": "{assetId}",
  "timezone": "Europe/Berlin"
}

The response of the call contains the newly created asset instance, so you can validate the correct creation:

{
  "assetId": "{assetId}",
  "tenantId": "{tenantValue}",
  "name": "IoT2040",
  "etag": {etagValue},
  "externalId": "SN 123456-123-123456",
  "t2Tenant": null,
  "subTenant": null,
  "description": "IoT2040",
  "timezone": "Europe/Berlin",
  "parentId": "{assetId}",
  "typeId": "core.mciot2040",
  "location": {
    "country": "Austria",
    "region": "Tyrol",
    "locality": "Innsbruck",
    "streetAddress": "Industriestraße 21 A/II",
    "postalCode": "6020",
    "longitude": 53.5125546,
    "latitude": 9.9763411
  },
  "fileAssignments": [],
  "variables": [],
  "aspects": [],
  "locks": [],
  "hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    },
    {
      "assetId": "{assetId}",
      "name": "MindCar"
    },
    {
      "assetId": "{assetId}",
      "name": "AssemblyArea"
    },
    {
      "assetId": "{assetId}",
      "name": "roboticarm"
    }
  ],
  "deleted": null,
  "_links": {
    "self": {
      "href": "{link}"
    },
    "aspects": {
      "href": "{link}"
    },
    "variables": {
      "href": "{link}"
    },
    "location": {
      "href": "{link}"
    },
    "parent": {
      "href": "{link}"
    }
  }
}

The hierarchy path shows all the parents up to the root asset with their assetId and name starting from the root and finishing at the direct parent the robotic arm.

  "hierarchyPath": [
    {
      "assetId": "{rootAssetId}",
      "name": "{tenantName}"
    },
    {
      "assetId": "{assetId}",
      "name": "MindCar"
    },
    {
      "assetId": "{assetId}",
      "name": "AssemblyArea"
    },
    {
      "assetId": "{assetId}",
      "name": "roboticarm"
    }
  ]