

# Bulk operations with assets and models


To work with a large number of assets or asset models, use bulk operations to bulk import and export resources to a different location. For example, you can create a data file that defines assets or asset models in an Amazon S3 bucket, and use bulk import to create or update them in AWS IoT SiteWise. Alternatively, if you have a large number of assets or asset models in AWS IoT SiteWise, you can export them to Amazon S3. 

**Note**  
You perform bulk operations in AWS IoT SiteWise by calling operations in the AWS IoT TwinMaker API. You can do this without setting up AWS IoT TwinMaker or creating an AWS IoT TwinMaker workspace. All you need is an Amazon S3 bucket where you can place your AWS IoT SiteWise content.   


**Topics**
+ [

## Key concepts and terminology
](#bulk-operations-terminology)
+ [

## Supported functionality
](#bulk-operations-functionality)
+ [

# Bulk operation prerequisites
](bulk-operations-prereqs.md)
+ [

# Run a bulk import job
](running-bulk-operations-import.md)
+ [

# Run a bulk export job
](running-bulk-operations-export.md)
+ [

# Jobs progress tracking and error handling
](jobs-progress-error-handling.md)
+ [

# Import metadata examples
](bulk-operations-import-metadata-example.md)
+ [

# Export metadata examples
](bulk-operations-export-filter-examples.md)
+ [

# AWS IoT SiteWise metadata transfer job schema
](bulk-operations-schema.md)

## Key concepts and terminology


AWS IoT SiteWise bulk import and export features rely on the following concepts and terminology:
+ **Import**: The action of moving assets or asset models from a file in an Amazon S3 bucket to AWS IoT SiteWise.
+ **Export**: The action of moving assets or asset models from AWS IoT SiteWise to an Amazon S3 bucket.
+ **Source**: The starting location of where you want to move content from.

  For example, an Amazon S3 bucket is an import source, and AWS IoT SiteWise is an export source.
+ **Destination**: The desired location of where you want to move your content to.

  For example, an Amazon S3 bucket is an export destination, and AWS IoT SiteWise is an import destination.
+ **AWS IoT SiteWise Schema**: This schema is used to import and export metadata from AWS IoT SiteWise.
+ **Top-level resource:** An AWS IoT SiteWise resource that you can individually create or update, such as an asset or asset model.
+ **Sub-resource:** A nested AWS IoT SiteWise resource within a top-level resource. Examples include properties, hierarchies, and composite models.
+ **Metadata**: Key information required to import or export resources successfully. Examples of metadata are definitions of assets and asset models.
+ **metadataTransferJob**: The object created when you run `CreateMetadataTransferJob`.

## Supported functionality


This topic explains what you can do when you run a bulk operation. Bulk operations support the following functionality:
+ **Top-level resource creation:** When you import an asset or asset model that doesn't define an ID, or whose ID doesn't match that of an existing one, then it will be created as a new resource.
+ **Top-level resource replacement:** When you import an asset or asset model whose ID matches one that already exists, then it will replace the existing resource.
+ **Subresource creation, replacement, or deletion:** When your import replaces a top-level resource such as an asset or asset model, then the new definition replaces all sub-resources, such as properties, hierarchies, or composite models. 

  For example, if you update an asset model during a bulk import, and the updated version defines a property that wasn't present on the original, then a new property is created. If it defines a property that already exists, then the existing property will be updated. If the updated asset model omits a property that was present on the original, then the property is deleted.
+ **No top-level resource deletion:** Bulk operations don't delete an asset or asset model. Bulk operations only create or update them.

# Bulk operation prerequisites


This section explains bulk operation prerequisites, including AWS Identity and Access Management (IAM) permissions for exchanging resources between AWS services and your local machine. Before you start a bulk operation, complete the following prerequisite:
+ Create an Amazon S3 bucket to store resources. For more information about using Amazon S3, see [What is Amazon S3?](https://docs.aws.amazon.com//AmazonS3/latest/userguide/Welcome.html)

## IAM permissions


To perform bulk operations, you must create an AWS Identity and Access Management (IAM) policy with permissions that allow the exchange of AWS resources between Amazon S3, AWS IoT SiteWise, and your local machine. For more information about creating IAM policies, see [Creating IAM policies](https://docs.aws.amazon.com//IAM/latest/UserGuide/access_policies_create.html). 

To perform bulk operations, you need the following policies.

### AWS IoT SiteWise policy


This policy allows access to the required AWS IoT SiteWise API actions for bulk operations:

```
{
    "Sid": "SiteWiseApiAccess",
    "Effect": "Allow",
    "Action": [
        "iotsitewise:CreateAsset",
        "iotsitewise:CreateAssetModel",
        "iotsitewise:UpdateAsset",
        "iotsitewise:UpdateAssetModel",
        "iotsitewise:UpdateAssetProperty",
        "iotsitewise:ListAssets",
        "iotsitewise:ListAssetModels",
        "iotsitewise:ListAssetProperties",
        "iotsitewise:ListAssetModelProperties",
        "iotsitewise:ListAssociatedAssets",
        "iotsitewise:DescribeAsset",
        "iotsitewise:DescribeAssetModel",
        "iotsitewise:DescribeAssetProperty",
        "iotsitewise:AssociateAssets",
        "iotsitewise:DisassociateAssets",
        "iotsitewise:AssociateTimeSeriesToAssetProperty",
        "iotsitewise:DisassociateTimeSeriesFromAssetProperty",
        "iotsitewise:BatchPutAssetPropertyValue",
        "iotsitewise:BatchGetAssetPropertyValue",
        "iotsitewise:TagResource",
        "iotsitewise:UntagResource",
        "iotsitewise:ListTagsForResource",
        "iotsitewise:CreateAssetModelCompositeModel",
        "iotsitewise:UpdateAssetModelCompositeModel",
        "iotsitewise:DescribeAssetModelCompositeModel",
        "iotsitewise:DeleteAssetModelCompositeModel",
        "iotsitewise:ListAssetModelCompositeModels",
        "iotsitewise:ListCompositionRelationships",
        "iotsitewise:DescribeAssetCompositeModel"
    ],
    "Resource": "*"
}
```

### AWS IoT TwinMaker policy


This policy allows access to the AWS IoT TwinMaker API operations that you use to work with bulk operations:

```
{
    "Sid": "MetadataTransferJobApiAccess",
    "Effect": "Allow",
    "Action": [
        "iottwinmaker:CreateMetadataTransferJob",
        "iottwinmaker:CancelMetadataTransferJob",
        "iottwinmaker:GetMetadataTransferJob",
        "iottwinmaker:ListMetadataTransferJobs"
    ],
    "Resource": "*"
}
```

### Amazon S3 policy


This policy provides access to Amazon S3 buckets for transferring metadata for bulk operations.

------
#### [ For a specific Amazon S3 bucket ]

If you use one specific bucket for working with your bulk operations metadata, this policy provides access to that bucket:

```
{
    "Effect": "Allow",
    "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:GetBucketLocation",
        "s3:ListBucket",
        "s3:AbortMultipartUpload",
        "s3:ListBucketMultipartUploads",
        "s3:ListMultipartUploadParts"
    ],
    "Resource": [
        "arn:aws:s3:::bucket name",
        "arn:aws:s3:::bucket name/*"
    ]
}
```

------
#### [ To allow any Amazon S3 bucket ]

If you will use many different buckets to work with your bulk operations metadata, this policy provides access to any bucket:

```
{
    "Effect": "Allow",
    "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:GetBucketLocation",
        "s3:ListBucket",
        "s3:AbortMultipartUpload",
        "s3:ListBucketMultipartUploads",
        "s3:ListMultipartUploadParts"
    ],
    "Resource": "*"
}
```

------

For information about troubleshooting import and export operations, see [Troubleshoot bulk import and export](troubleshooting-bulk.md).

# Run a bulk import job


 Bulk import is the action of moving metadata into an AWS IoT SiteWise workspace. For example, bulk import can move metadata from a local file, or a file in an Amazon S3 bucket, to an AWS IoT SiteWise workspace. 

## Step 1: Prepare the file to import


Download the AWS IoT SiteWise native format file to import assets and the asset models. See [AWS IoT SiteWise metadata transfer job schema](bulk-operations-schema.md) for more details. 

## Step 2: Upload the prepared file to Amazon S3


 Upload the file to Amazon S3. See [Uploading a file to Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html#uploading-an-object-bucket) in the *Amazon Simple Storage Service User Guide* for details. 

## Import metadata (console)


You can use the AWS IoT SiteWise console to bulk import metadata. Follow [Step 1: Prepare the file to import](#preparing-import-file) and [Step 2: Upload the prepared file to Amazon S3](#uploading-import-file) to prepare a file that is ready to be imported.

**Import data from Amazon S3 to AWS IoT SiteWise console**

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. Choose **Bulk operations New** from the navigation pane.

1. Choose **New import** to start the import process.

1. On the **Import metadata** page:
   + Choose **Browse Amazon S3** to view the Amazon S3 bucket and files.
   + Navigate to the Amazon S3 bucket that contains the prepared import file.
   + Select the file to import.
   + Review the selected file, and choose **Import**.

1. The **Bulk operations on SiteWise metadata** page of the AWS IoT SiteWise console displays the newly created import job in the **Jobs progress** table.

## Import metadata (AWS CLI)


To perform an import action, use the following procedure:

**Import data from Amazon S3 to AWS CLI**

1. Create a metadata file that specifies the resources you want to import, following the [AWS IoT SiteWise metadata transfer job schema](bulk-operations-schema.md). Store this file in your Amazon S3 bucket.

   For examples of metadata files to import, see [Import metadata examples](bulk-operations-import-metadata-example.md). 

1. Now create a JSON file with the request body. The request body specifies the source and destination for the transfer job. This file is separate from the file from the previous step. Make sure to specify your Amazon S3 bucket as a source and `iotsitewise` as the destination. 

   The following example shows the request body:

   ```
   {
         "metadataTransferJobId": "your-transfer-job-Id",
         "sources": [{
             "type": "s3",
             "s3Configuration": {
                 "location": "arn:aws:s3:::amzn-s3-demo-bucket/your_import_metadata.json"
             }
         }],
         "destination": {
             "type": "iotsitewise"
         }
     }
   ```

1. Invoke the `CreateMetadataTransferJob` by running the following AWS CLI command. In this example, the request body file from the previous step is named `createMetadataTransferJobExport.json`.

   ```
   aws iottwinmaker create-metadata-transfer-job --region us-east-1 \
     --cli-input-json file://createMetadataTransferJobImport.json
   ```

   This will create a metadata transfer job, and begin the process of the transferring your selected resources.

# Run a bulk export job


 Bulk export is the action of moving metadata from an AWS IoT SiteWise workspace to an Amazon S3 bucket. 

When you perform a bulk export of your AWS IoT SiteWise content to Amazon S3, you can specify filters to limit which specific asset models and assets you'd like to export.

The filters must be specified in an `iotSiteWiseConfiguration` section within the sources section of your JSON request.

**Note**  
 You can include multiple filters in your request. The bulk operation will export asset models and assets that match any of the filters.   
 If you don't provide any filters, the bulk operation exports all of your asset models and assets. 

**Example request body with filters**  

```
{
      "metadataTransferJobId": "your-transfer-job-id",
      "sources": [
       {
        "type": "iotsitewise",
        "iotSiteWiseConfiguration": {
          "filters": [
           {
              "filterByAssetModel": {
                  "assetModelId": "asset model ID"
              }
            },
            {
              "filterByAssetModel": {
                  "assetModelId": "asset model ID",
                  "includeAssets": true
              }
            },
            {
              "filterByAssetModel": {
                  "assetModelId": "asset model ID",
                  "includeOffspring": true
               }
             }
           ]
          }
        }
       ],
       "destination": {
          "type": "s3",
          "s3Configuration": {
            "location": "arn:aws:s3:::amzn-s3-demo-bucket"
          }
      }
}
```

## Export metadata (console)


The following procedure explains the console export action:

**Create an export job in the AWS IoT SiteWise console**

1.  Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. Choose **Bulk operations New** from the navigation pane.

1. Choose **New export** to start the export process.

1. On the **Export metadata** page:
   +  Enter a name for the export job. This is the name used for the exported file in your Amazon S3 bucket. 
   + Choose your resources to export, which sets the filters for the job:
     + Export all assets and asset models. Use filters on assets and asset models.
     + Export assets. Filter on your assets.
       + Select the asset to use for the export filter.
       + (Optional) Add the offspring or the associated asset model.
     + Export asset models. Filter on your asset models.
       + Select the asset model to use for the export filter.
       + (Optional) Add the offspring, or the associated asset or both. 
     + Choose **Next**.
   + Navigate to the Amazon S3 bucket:
     + Choose **Browse Amazon S3** to view the Amazon S3 bucket and files.
     + Navigate to the Amazon S3 bucket where the file must be placed.
     + Choose **Next**.
   + Review the export job and choose **Export**.

1. The **Bulk operations on SiteWise metadata** page of the AWS IoT SiteWise console displays the newly created import job in the **Jobs progress** table.

For the different ways to use filters when exporting metadata, see [Export metadata examples](bulk-operations-export-filter-examples.md). 

## Export metadata (AWS CLI)


The following procedure explains the AWS CLI export action:

**Export data from AWS IoT SiteWise to Amazon S3**

1. Create a JSON file with your request body. The request body specifies the source and destination for the transfer job. The following example shows an example request body:

   ```
   {
       "metadataTransferJobId": "your-transfer-job-Id",
       "sources": [{
           "type": "iotsitewise"
       }],
       "destination": {
           "type": "s3",
           "s3Configuration": {
               "location": "arn:aws:s3:::amzn-s3-demo-bucket"
           }
       }
   }
   ```

   Make sure to specify your Amazon S3 bucket as the destination of the metadata transfer job.
**Note**  
This example will export all of your asset models and assets. To limit the export to specific asset models or assets, you can include filters in your request body. For more information about applying export filters, see [Export metadata examples](bulk-operations-export-filter-examples.md).

1. Save your request body file to use in the next step. In this example, the file is named `createMetadataTransferJobExport.json`.

1. Invoke the `CreateMetadataTransferJob` by running the following AWS CLI command:

   ```
   aws iottwinmaker create-metadata-transfer-job --region us-east-1 \ 
            --cli-input-json file://createMetadataTransferJobExport.json
   ```

   Replace the input JSON file `createMetadataTransferJobExport.json` with your own transfer file name.

# Jobs progress tracking and error handling


 A bulk process job takes time to process. Each job is processed in the order of AWS IoT SiteWise receiving the request. It is processed one-at-a-time for each account. When a job completes, the next in queue automatically starts processing. AWS IoT SiteWise resolves the jobs asynchronously and updates the status of each as it progresses. Each job has a status field that contains the state of the resource and an error message, if applicable.

The state can be one of the following values:
+ `VALIDATING` – Validating the job including the submitted file format, and its contents.
+ `PENDING` – The job is in a queue. You can cancel jobs in this state from the AWS IoT SiteWise console, but all other states will continue until the end.
+ `RUNNING` – Processing the job. It is creating and updating resources as defined by the import file, or exporting resources based on the chosen export job filters. If canceled, any resource imported by this job is not deleted. See [Review job progress and details (console)](review-job-progress.md#review-job-progress-console) for more information.
+ `CANCELLING` – The job is actively being cancelled.
+ `ERROR` – One or more resources failed to process. Check the detailed job report for more information. See [Inspect error details (console)](inspect-errors.md#inspect-errors-console) for more information.
+ `COMPLETED` – Job completed without errors.
+ `CANCELLED` – The job is cancelled and not queued. If you cancelled a `RUNNING` job, resources already imported by this job at the time of cancellation is not deleted from AWS IoT SiteWise.

**Topics**
+ [

# Jobs progress tracking
](review-job-progress.md)
+ [

# Inspect errors for AWS IoT SiteWise
](inspect-errors.md)

# Jobs progress tracking


## Review job progress and details (console)


See [Import metadata (console)](running-bulk-operations-import.md#import-metadata-console) or [Export metadata (console)](running-bulk-operations-export.md#export-metadata-console) to start a bulk job.

**Job progress overview in the AWS IoT SiteWise console:**

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. Choose **Bulk operations New** from the navigation pane.

1. The **Jobs progress** table in the AWS IoT SiteWise console, displays the list of bulk operation jobs.

1. The **Job type** column describes if it's an export or import job. The **Date imported** columns display the date that the job started.

1. The **Status** column displays the status of the job. You can select a job to see details about the job.

1. The selected job shows **Success** upon being successful, or a list of failure if the job failed. An error description is also displayed with each resource type.

**Job details overview in the AWS IoT SiteWise console:**

The **Jobs progress** table in the AWS IoT SiteWise console, displays the list of bulk operation jobs.

1. Choose a job to see more details.

1. For an **import** job, the `Data source ARN` represents the Amazon S3 location of the import file.

1. For an **export** job, the `Data destination ARN` represents the Amazon S3 location of the file after the export.

1. The `Status` and `Status reason`, provide additional details on the current job. See [Jobs progress tracking and error handling](jobs-progress-error-handling.md) for more details.

1. The `Queued position` represents the position of the job in the process queue. The jobs are processed one at a time. A queued position of 1, indicates that the job will be processed next.

1.  The jobs details page also displays the job progress counts.

   1. The job progress count types are:

     1. `Total resources` – Indicates the total count of assets in the transfer process.

     1. `Succeeded` – Indicates the count of assets successfully transferred during the process.

     1. `Failed` – Indicates the count assets that failed during the process.

     1. `Skipped` – Indicates the count of assets that were skipped during the process.

1. A job status of `PENDING` or `VALIDATING`, displays all the jobs progress counts as `–`. This indicates that the jobs progress counts are being evaluated.

1. A job status of `RUNNING` displays the `Total resources` count, the job submitted for processing. The detailed counts (`Succeeded`, `Failed`, and `Skipped`), apply to the processed resources. The sum of the detailed counts is lesser than the `Total resources` count, until the job's status is `COMPLETED` or `ERROR`.

1.  If a job's status is `COMPLETED` or `ERROR`, the `Total resources` count equals the sum of the detailed counts (`Succeeded`, `Failed`, and `Skipped`). 

1.  If a job's status is `ERROR`, check the **Job failures** table for details about the specific errors and failures. See [Inspect error details (console)](inspect-errors.md#inspect-errors-console) for more details. 

## Review job progress and details (AWS CLI)


After starting a bulk operation, you can check or update its status using the following API actions:
+ To retrieve information on a specific job, use the [ GetMetadataTransferJob](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_GetMetadataTransferJob.html) API action.

**Retrieve information with the `GetMetadataTransferJob` API:**

  1. Create and run a transfer job. Call the `GetMetadataTransferJob` API.  
**Example AWS CLI command:**  

     ```
     aws iottwinmaker get-metadata-transfer-job \ 
             --metadata-transfer-job-id your_metadata_transfer_job_id \
             --region your_region
     ```

  1.  The `GetMetadataTransferJob` API returns a `MetadataTransferJobProgress` object with the following parameters: 
     + **succeededCount** – Indicates the count of assets successfully transferred in the process.
     + **failedCount** – Indicates the count of assets that failed during the process.
     + **skippedCount** – Indicates the count of assets that were skipped during the process.
     + **totalCount** – Indicates the total count of assets in the transfer process.

     These parameters indicate the job progress status. If the status is `RUNNING`, they help track the number of resources still to be processed.

     If you encounter schema validation errors, or if **failedCount** is greater than or equal to 1, the job progress state turns to `ERROR`. A full error report for the job is placed in your Amazon S3 bucket. See [Inspect errors for AWS IoT SiteWise](inspect-errors.md) for more details.
+ To list current jobs, use the [ListMetadataTransferJobs](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_ListMetadataTransferJobs.html) API action.

  Use a JSON file to filter the returned jobs based on their current state. See the following procedure:

  1. To specify the filters you want to use, create an AWS CLI input JSON file. want to use:

     ```
     {
         "sourceType": "s3",
         "destinationType": "iottwinmaker",
         "filters": [{
             "state": "COMPLETED"
         }]
     }
     ```

     For a list of valid `state` values, see [ListMetadataTransferJobsFilter](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_ListMetadataTransferJobsFilter.html) in the *AWS IoT TwinMaker API Reference Guide*.

  1.  Use the JSON file as an argument in the following AWS CLI example command:

     ```
     aws iottwinmaker list-metadata-transfer-job --region your_region \
             --cli-input-json file://ListMetadataTransferJobsExample.json
     ```
+ To cancel a job, use the [CancelMetadataTransferJob](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_CancelMetadataTransferJob.html) API action. This API cancels the specific metadata transfer job, without affecting any resources already exported or imported:

  ```
  aws iottwinmaker cancel-metadata-transfer-job \ 
          --region your_region \ 
          --metadata-transfer-job-id job-to-cancel-id
  ```

# Inspect errors for AWS IoT SiteWise
Inspect errors

## Inspect error details (console)


**Error details in the AWS IoT SiteWise console:**

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. See the **Jobs progress** table in AWS IoT SiteWise console for a list of bulk operation jobs.

1. Select a job to view the job details.

1. If a job's status is `COMPLETED` or `ERROR`, the `Total resources` count equals the sum of the detailed counts (`Succeeded`, `Failed`, and `Skipped`).

1.  If a job's status is `ERROR`, check the **Job failures** table for details about the specific errors and failures.

1. The **Job failures** table displays the content from the job report. The `Resource type` field indicates the location of the error or failures, such as the following:
   + For example, a validation error in the `Bulk operations template` in the `Resource type` field indicates that the import template and metadata schema file format don't match. See [AWS IoT SiteWise metadata transfer job schema](bulk-operations-schema.md) for more information. 
   + A failed `Asset` in the `Resource type` field indicates that the asset is not created because of a conflict with another asset. See [Common errors](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/CommonErrors.html) for information on AWS IoT SiteWise resource errors and conflicts. 

## Inspect error details (AWS CLI)


To handle and diagnose errors produced during a transfer job, see the following procedure about using the `GetMetadataTransferJob` API action:

1. After creating and running a transfer job, call [GetMetadataTransferJob](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_GetMetadataTransferJob.html):

   ```
   aws iottwinmaker get-metadata-transfer-job \
           --metadata-transfer-job-id your_metadata_transfer_job_id \
           --region us-east-1
   ```

1. Once you see the state of the job turn to `COMPLETED`, you can start verifying the results of the job.

1. When you call `GetMetadataTransferJob`, it returns an object called [https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_MetadataTransferJobProgress.html](https://docs.aws.amazon.com//iot-twinmaker/latest/apireference/API_MetadataTransferJobProgress.html).

   The MetadataTransferJobProgress object contains the following parameters:
   + **failedCount:** Indicates the count of assets that failed during the transfer process.
   + **skippedCount:** Indicates the count of assets that were skipped during the transfer process.
   + **succeededCount:** Indicates the count of assets that succeeded during the transfer process.
   + **totalCount:** Indicates the total count of assets involved in the transfer process.

1. Additionally, the API call returns an element `reportUrl`, which contains a presigned URL. If your transfer job has any issues that you need to investigate further, visit this url. 

# Import metadata examples
Import metadata examples

This section shows how to create metadata files to import asset models and assets with a single bulk import operation.

## Example of a bulk import


You can import many asset models and assets with a single bulk import operation. The following example shows how to create a metadata file to do this.

 In this example scenario, you have various work sites that contain industrial robots in work cells. 

The example defines two asset models:
+ `RobotModel1`: This asset model represents a particular type of robot that you have in your work sites. The robot has a measurement property, `Temperature`. 
+ `WorkCell`: This asset model represents a collection of robots within one of your work sites. The asset model defines a hierarchy, `robotHierarchyOEM1`, to represent the relationship that a work cell contains robots. 

The example also defines some assets:
+ `WorkCell1`: a work cell within your Boston site
+ `RobotArm123456`: a robot within that work cell
+ `RobotArm987654`: another robot within that work cell

The following JSON metadata file defines these asset models and assets. Running a bulk import with this metadata creates the asset models and assets within AWS IoT SiteWise, including their hierarchical relationships.

### Metadata file for import


```
{
    "assetModels": [
        {
            "assetModelExternalId": "Robot.OEM1.3536",
            "assetModelName": "RobotModel1",
            "assetModelProperties": [
                {
                    "dataType": "DOUBLE",
                    "externalId": "Temperature",
                    "name": "Temperature",
                    "type": {
                        "measurement": {
                            "processingConfig": {
                                "forwardingConfig": {
                                    "state": "ENABLED"
                                }
                            }
                        }
                    },
                    "unit": "fahrenheit"
                }
            ]
        },
        {
            "assetModelExternalId": "ISA95.WorkCell",
            "assetModelName": "WorkCell",
            "assetModelProperties": [],
            "assetModelHierarchies": [
                {
                    "externalId": "workCellHierarchyWithOEM1Robot",
                    "name": "robotHierarchyOEM1",
                    "childAssetModelExternalId": "Robot.OEM1.3536"
                }
            ]
        }
    ],
    "assets": [
        {
            "assetExternalId": "Robot.OEM1.3536.123456",
            "assetName": "RobotArm123456",
            "assetModelExternalId": "Robot.OEM1.3536"
        },
        {
            "assetExternalId": "Robot.OEM1.3536.987654",
            "assetName": "RobotArm987654",
            "assetModelExternalId": "Robot.OEM1.3536"
        },
        {
            "assetExternalId": "BostonSite.Area1.Line1.WorkCell1",
            "assetName": "WorkCell1",
            "assetModelExternalId": "ISA95.WorkCell",
            "assetHierarchies": [
                {
                    "externalId": "workCellHierarchyWithOEM1Robot",
                    "childAssetExternalId": "Robot.OEM1.3536.123456"
                },
                {
                    "externalId": "workCellHierarchyWithOEM1Robot",
                    "childAssetExternalId": "Robot.OEM1.3536.987654"
                }
            ]
        }
    ]
}
```

## Example of initial on-boarding of models and assets


In this example scenario, you have various work sites that contain industrial robots in a company.

The example defines multiple asset models:
+ `Sample_Enterprise` – This asset model represents the company that the sites are part of. The asset model defines a hierarchy, `Enterprise to Site`, to represent the relationship of the sites to the enterprise.
+ `Sample_Site` – This asset model represents the manufacturing sites within the company. The asset model defines a hierarchy, `Site to Line`, to represent the relationship of the lines to the site.
+ `Sample_Welding Line` – This asset model represents an assembly line within work sites. The asset model defines a hierarchy, `Line to Robot`, to represent the relationship of the robots to the line.
+ `Sample_Welding Robot` – This asset model represents a particular type of robot in your work sites.

The example also defines assets based on the asset models.
+ `Sample_AnyCompany Motor` – This asset is created from `Sample_Enterprise` asset model.
+ `Sample_Chicago` – This asset is created from `Sample_Site` asset model.
+ `Sample_Welding Line 1` – This asset is created from `Sample_Welding Line` asset model.
+ `Sample_Welding Robot 1` – This asset is created from `Sample_Welding Robot` asset model.
+ `Sample_Welding Robot 2` – This asset is created from `Sample_Welding Robot` asset model.

The following JSON metadata file defines these asset models and assets. Running a bulk import with this metadata creates the asset models and assets within AWS IoT SiteWise, including their hierarchical relationships.

### JSON file to onboard assets and models for import


```
{
    "assetModels": [
        {
            "assetModelExternalId": "External_Id_Welding_Robot",
            "assetModelName": "Sample_Welding Robot",
            "assetModelProperties": [
                {
                    "dataType": "STRING",
                    "externalId": "External_Id_Welding_Robot_Serial_Number",
                    "name": "Serial Number",
                    "type": {
                        "attribute": {
                            "defaultValue": "-"
                        }
                    },
                    "unit": "-"
                },
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Robot_Cycle_Count",
                    "name": "CycleCount",
                    "type": {
                        "measurement": {}
                    },
                    "unit": "EA"
                },
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Robot_Joint_1_Current",
                    "name": "Joint 1 Current",
                    "type": {
                        "measurement": {}
                    },
                    "unit": "Amps"
                },
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Robot_Joint_1_Max_Current",
                    "name": "Max Joint 1 Current",
                    "type": {
                        "metric": {
                            "expression": "max(joint1current)",
                            "variables": [
                                {
                                    "name": "joint1current",
                                    "value": {
                                        "propertyExternalId": "External_Id_Welding_Robot_Joint_1_Current"
                                    }
                                }
                            ],
                            "window": {
                                "tumbling": {
                                    "interval": "5m"
                                }
                            }
                        }
                    },
                    "unit": "Amps"
                }
            ]
        },
        {
            "assetModelExternalId": "External_Id_Welding_Line",
            "assetModelName": "Sample_Welding Line",
            "assetModelProperties": [
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Line_Availability",
                    "name": "Availability",
                    "type": {
                        "measurement": {}
                    },
                    "unit": "%"
                }
            ],
            "assetModelHierarchies": [
                {
                    "externalId": "External_Id_Welding_Line_TO_Robot",
                    "name": "Line to Robot",
                    "childAssetModelExternalId": "External_Id_Welding_Robot"
                }
            ]
        },
        {
            "assetModelExternalId": "External_Id_Site",
            "assetModelName": "Sample_Site",
            "assetModelProperties": [
                {
                    "dataType": "STRING",
                    "externalId": "External_Id_Site_Street_Address",
                    "name": "Street Address",
                    "type": {
                        "attribute": {
                            "defaultValue": "-"
                        }
                    },
                    "unit": "-"
                }
            ],
            "assetModelHierarchies": [
                {
                    "externalId": "External_Id_Site_TO_Line",
                    "name": "Site to Line",
                    "childAssetModelExternalId": "External_Id_Welding_Line"
                }
            ]
        },
        {
            "assetModelExternalId": "External_Id_Enterprise",
            "assetModelName": "Sample_Enterprise",
            "assetModelProperties": [
                {
                    "dataType": "STRING",
                    "name": "Company Name",
                    "externalId": "External_Id_Enterprise_Company_Name",
                    "type": {
                        "attribute": {
                            "defaultValue": "-"
                        }
                    },
                    "unit": "-"
                }
            ],
            "assetModelHierarchies": [
                {
                    "externalId": "External_Id_Enterprise_TO_Site",
                    "name": "Enterprise to Site",
                    "childAssetModelExternalId": "External_Id_Site"
                }
            ]
        }
    ],
    "assets": [
        {
            "assetExternalId": "External_Id_Welding_Robot_1",
            "assetName": "Sample_Welding Robot 1",
            "assetModelExternalId": "External_Id_Welding_Robot",
            "assetProperties": [
                {
                    "externalId": "External_Id_Welding_Robot_Serial_Number",
                    "attributeValue": "S1000"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Cycle_Count",
                    "alias": "AnyCompany/Chicago/Welding Line/S1000/Count"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Joint_1_Current",
                    "alias": "AnyCompany/Chicago/Welding Line/S1000/1/Current"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Welding_Robot_2",
            "assetName": "Sample_Welding Robot 2",
            "assetModelExternalId": "External_Id_Welding_Robot",
            "assetProperties": [
                {
                    "externalId": "External_Id_Welding_Robot_Serial_Number",
                    "attributeValue": "S2000"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Cycle_Count",
                    "alias": "AnyCompany/Chicago/Welding Line/S2000/Count"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Joint_1_Current",
                    "alias": "AnyCompany/Chicago/Welding Line/S2000/1/Current"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Welding_Line_1",
            "assetName": "Sample_Welding Line 1",
            "assetModelExternalId": "External_Id_Welding_Line",
            "assetProperties": [
                {
                    "externalId": "External_Id_Welding_Line_Availability",
                    "alias": "AnyCompany/Chicago/Welding Line/Availability"
                }
            ],
            "assetHierarchies": [
                {
                    "externalId": "External_Id_Welding_Line_TO_Robot",
                    "childAssetExternalId": "External_Id_Welding_Robot_1"
                },
                {
                    "externalId": "External_Id_Welding_Line_TO_Robot",
                    "childAssetExternalId": "External_Id_Welding_Robot_2"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Site_Chicago",
            "assetName": "Sample_Chicago",
            "assetModelExternalId": "External_Id_Site",
            "assetHierarchies": [
                {
                    "externalId": "External_Id_Site_TO_Line",
                    "childAssetExternalId": "External_Id_Welding_Line_1"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Enterprise_AnyCompany",
            "assetName": "Sample_AnyEnterprise Motor",
            "assetModelExternalId": "External_Id_Enterprise",
            "assetHierarchies": [
                {
                    "externalId": "External_Id_Enterprise_TO_Site",
                    "childAssetExternalId": "External_Id_Site_Chicago"
                }
            ]
        }
    ]
}
```

The following screenshot is of models that display in the AWS IoT SiteWise console after you run the previous code example.

![\[AWS IoT SiteWise models with asset and asset models.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/import-example-asset.png)


The following screenshot is of models, assets, and hierarchies that display in the AWS IoT SiteWise console after you run the previous code example.

![\[AWS IoT SiteWise models with assets, asset models, and hierarchies.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/hierarchy-example-import.png)


## Example of onboarding additional assets


This example defines additional assets to import to an existing asset model in your account:
+ `Sample_Welding Line 2` – This asset is created from `Sample_Welding Line` asset model.
+ `Sample_Welding Robot 3`– This asset is created from `Sample_Welding Robot` asset model.
+ `Sample_Welding Robot 4`– This asset is created from `Sample_Welding Robot` asset model.

To create the initial assets for this example, see [Example of initial on-boarding of models and assets](#example-scenario1).

The following JSON metadata file defines these asset models and assets. Running a bulk import with this metadata creates the asset models and assets within AWS IoT SiteWise, including their hierarchical relationships.

### JSON file to onboard additional assets


```
{
    "assets": [
        {
            "assetExternalId": "External_Id_Welding_Robot_3",
            "assetName": "Sample_Welding Robot 3",
            "assetModelExternalId": "External_Id_Welding_Robot",
            "assetProperties": [
                {
                    "externalId": "External_Id_Welding_Robot_Serial_Number",
                    "attributeValue": "S3000"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Cycle_Count",
                    "alias": "AnyCompany/Chicago/Welding Line/S3000/Count"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Joint_1_Current",
                    "alias": "AnyCompany/Chicago/Welding Line/S3000/1/Current"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Welding_Robot_4",
            "assetName": "Sample_Welding Robot 4",
            "assetModelExternalId": "External_Id_Welding_Robot",
            "assetProperties": [
                {
                    "externalId": "External_Id_Welding_Robot_Serial_Number",
                    "attributeValue": "S4000"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Cycle_Count",
                    "alias": "AnyCompany/Chicago/Welding Line/S4000/Count"
                },
                {
                    "externalId": "External_Id_Welding_Robot_Joint_1_Current",
                    "alias": "AnyCompany/Chicago/Welding Line/S4000/1/Current"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Welding_Line_1",
            "assetName": "Sample_Welding Line 1",
            "assetModelExternalId": "External_Id_Welding_Line",
            "assetHierarchies": [
                {
                    "externalId": "External_Id_Welding_Line_TO_Robot",
                    "childAssetExternalId": "External_Id_Welding_Robot_1"
                },
                {
                    "externalId": "External_Id_Welding_Line_TO_Robot",
                    "childAssetExternalId": "External_Id_Welding_Robot_2"
                },
                {
                    "externalId": "External_Id_Welding_Line_TO_Robot",
                    "childAssetExternalId": "External_Id_Welding_Robot_3"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Welding_Line_2",
            "assetName": "Sample_Welding Line 2",
            "assetModelExternalId": "External_Id_Welding_Line",
            "assetHierarchies": [
                {
                    "externalId": "External_Id_Welding_Line_TO_Robot",
                    "childAssetExternalId": "External_Id_Welding_Robot_4"
                }
            ]
        },
        {
            "assetExternalId": "External_Id_Site_Chicago",
            "assetName": "Sample_Chicago",
            "assetModelExternalId": "External_Id_Site",
            "assetHierarchies": [
                {
                    "externalId": "External_Id_Site_TO_Line",
                    "childAssetExternalId": "External_Id_Welding_Line_1"
                },
                {
                    "externalId": "External_Id_Site_TO_Line",
                    "childAssetExternalId": "External_Id_Welding_Line_2"
                }
            ]
        }
    ]
}
```

The following screenshot is of models, assets, and hierarchies that display in the AWS IoT SiteWise console after you run the previous code example.

![\[AWS IoT SiteWise models with asset and asset models.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/additional-assets-import.png)


## Example of onboarding new properties


This example defines new properties on existing asset models. See [Example of onboarding additional assets](#example-scenario2) to onboard additional assets and models.
+ `Joint 1 Temperature` – This property is added to the `Sample_Welding Robot` asset model. This new property will also propagate to each asset created from the `Sample_Welding Robot` asset model. 

To add a new property to an existing asset model, see the following JSON metadata file example. As shown in the JSON, the entire existing `Sample_Welding Robot` asset model definition must be provided along with the new property. If the entire property list from the existing definition is not provided, AWS IoT SiteWise deletes the omitted properties. 

### JSON file to onboard new properties


This example adds a new property `Joint 1 Temperature` to the asset model.

```
{
    "assetModels": [
        {
            "assetModelExternalId": "External_Id_Welding_Robot",
            "assetModelName": "Sample_Welding Robot",
            "assetModelProperties": [
                {
                    "dataType": "STRING",
                    "externalId": "External_Id_Welding_Robot_Serial_Number",
                    "name": "Serial Number",
                    "type": {
                        "attribute": {
                            "defaultValue": "-"
                        }
                    },
                    "unit": "-"
                },
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Robot_Cycle_Count",
                    "name": "CycleCount",
                    "type": {
                        "measurement": {}
                    },
                    "unit": "EA"
                },
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Robot_Joint_1_Current",
                    "name": "Joint 1 Current",
                    "type": {
                        "measurement": {}
                    },
                    "unit": "Amps"
                },
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Robot_Joint_1_Max_Current",
                    "name": "Max Joint 1 Current",
                    "type": {
                        "metric": {
                            "expression": "max(joint1current)",
                            "variables": [
                                {
                                    "name": "joint1current",
                                    "value": {
                                        "propertyExternalId": "External_Id_Welding_Robot_Joint_1_Current"
                                    }
                                }
                            ],
                            "window": {
                                "tumbling": {
                                    "interval": "5m"
                                }
                            }
                        }
                    },
                    "unit": "Amps"
                },
                {
                    "dataType": "DOUBLE",
                    "externalId": "External_Id_Welding_Robot_Joint_1_Temperature",
                    "name": "Joint 1 Temperature",
                    "type": {
                        "measurement": {}
                    },
                    "unit": "degC"
                }
            ]
        }
    ]
}
```

## Example of managing data streams


 This example shows two ways of managing data streams associated with an asset property. When renaming an asset property alias, there are two options for the historical data currently stored in the asset property's data stream.
+  Option one – Keep the current data stream and rename the alias alone, allowing the historical data to be accessible with the new alias. 

   In the JSON metadata file example, the asset property with ID `External_Id_Welding_Robot_Cycle_Count` changes its alias to `AnyCompany/Chicago/Welding Line/S3000/Count-Updated`. The historical data for this asset property remains the same after this change. 
+  Option two – Assign a new data stream to the asset property which is accessible with the new alias. The old data stream along with its historical data is still accessible with the old alias, but not associated with any asset property. 

   In the JSON metadata file example, the asset property with ID `External_Id_Welding_Robot_Joint_1_Current` changes its alias to `AnyCompany/Chicago/Welding Line/S4999/1/Current`. This time the additional value `retainDataOnAliasChange` is present and set to `False`. With this setting, the original data stream is disassociated from the asset property, and a new data stream is created containing no historical data. 

 To access the old data stream with the original historical data, in the AWS Console Home, go to the *Data Streams* page and search for the old alias `AnyCompany/Chicago/Welding Line/S3000/1/Current`. 

### JSON file to update property aliases


```
{
    "assetExternalId": "External_Id_Welding_Robot_3",
    "assetName": "Sample_Welding Robot 3",
    "assetModelExternalId": "External_Id_Welding_Robot",
    "assetProperties": [
        {
            "externalId": "External_Id_Welding_Robot_Serial_Number",
            "attributeValue": "S3000"
        },
        {
            "externalId": "External_Id_Welding_Robot_Cycle_Count",
            "alias": "AnyCompany/Chicago/Welding Line/S3000/Count-Updated"
        },
        {
            "externalId": "External_Id_Welding_Robot_Joint_1_Current",
            "alias": "AnyCompany/Chicago/Welding Line/S4999/1/Current",
            "retainDataOnAliasChange": "FALSE"
        }
    ]
}
```

# Export metadata examples
Export metadata examples

When you perform a bulk export of your AWS IoT SiteWise content to Amazon S3, you can specify *filters* to limit which specific asset models and assets you'd like to export. 

You specify the filters in an `iotSiteWiseConfiguration` section within the `sources` section of your request body.

**Note**  
You can include multiple filters. The bulk operation will export any asset model or asset that matches any of the filters.  
If you don't provide any filters, then the operation will export all of your asset models and assets.

```
{
    "metadataTransferJobId": "your-transfer-job-id",
    "sources": [{
        "type": "iotsitewise",
        "iotSiteWiseConfiguration": {
            "filters": [{
                list of filters
            }]
        }
    }],
    "destination": {
        "type": "s3",
        "s3Configuration": {
            "location": "arn:aws:s3:::amzn-s3-demo-bucket"
        }
    }
}
```



## Filter by asset model


You can filter a specific asset model. You can also include all assets using that model, or all asset models within its hierarchy. You can't include both assets and hierarchy.

For more information about hierarchies, see [Define asset model hierarchies](define-asset-hierarchies.md).

------
#### [ Asset model ]

This filter includes the specified asset model:

```
"filterByAssetModel": {
    "assetModelId": "asset model ID"
}
```

------
#### [ Asset model and its assets ]

This filter includes the specified asset model, along with all assets using that asset model:

```
"filterByAssetModel": {
    "assetModelId": "asset model ID",
    "includeAssets": true
}
```

------
#### [ Asset model and its hierarchy ]

This filter includes the specified asset model, along with all associated asset models in its hierarchy:

```
"filterByAssetModel": {
    "assetModelId": "asset model ID",
    "includeOffspring": true
}
```

------

## Filter by asset


You can filter a specific asset. You can also include its asset model, or all associated assets within its hierarchy. You can't include both asset model and hierarchy.

For more information about hierarchies, see [Define asset model hierarchies](define-asset-hierarchies.md).

------
#### [ Asset ]

This filter includes the specified asset:

```
"filterByAsset": {
    "assetId": "asset ID"
}
```

------
#### [ Asset and its asset model ]

This filter includes the specified asset, along with the asset model it uses:

```
"filterByAsset": {
    "assetId": "asset ID",
    "includeAssetModel": true
}
```

------
#### [ Asset and its hierarchy ]

This filter includes the specified asset, along with all associated assets in its hierarchy:

```
"filterByAsset": {
    "assetId": "asset ID",
    "includeOffspring": true
}
```

------

# AWS IoT SiteWise metadata transfer job schema
Metadata transfer job schema

Use the AWS IoT SiteWise metadata transfer job schema for reference when performing your own bulk import and export operations:

```
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "IoTSiteWise",
  "description": "Metadata transfer job resource schema for IoTSiteWise",
  "definitions": {
    "Name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "[^\\u0000-\\u001F\\u007F]+"
    },
    "Description": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2048,
      "pattern": "[^\\u0000-\\u001F\\u007F]+"
    },
    "ID": {
      "type": "string",
      "minLength": 36,
      "maxLength": 36,
      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
    },
    "ExternalId": {
      "type": "string",
      "minLength": 2,
      "maxLength": 128,
      "pattern": "[a-zA-Z0-9_][a-zA-Z_\\-0-9.:]*[a-zA-Z0-9_]+"
    },
    "AttributeValue": {
      "description": "The value of the property attribute.",
      "type": "string",
      "pattern": "[^\\u0000-\\u001F\\u007F]+"
    },
    "PropertyUnit": {
      "description": "The unit of measure (such as Newtons or RPM) of the asset property.",
      "type": "string",
      "minLength": 1,
      "maxLength": 256,
      "pattern": "[^\\u0000-\\u001F\\u007F]+"
    },
    "PropertyAlias": {
      "description": "The property alias that identifies the property.",
      "type": "string",
      "minLength": 1,
      "maxLength": 1000,
      "pattern": "[^\\u0000-\\u001F\\u007F]+"
    },
    "AssetProperty": {
      "description": "The asset property's definition, alias, unit, and notification state.",
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "id"
          ]
        },
        {
          "required": [
            "externalId"
          ]
        }
      ],
      "properties": {
        "id": {
          "description": "The ID of the asset property.",
          "$ref": "#/definitions/ID"
        },
        "externalId": {
          "description": "The ExternalID of the asset property.",
          "$ref": "#/definitions/ExternalId"
        },
        "alias": {
          "$ref": "#/definitions/PropertyAlias"
        },
        "unit": {
          "$ref": "#/definitions/PropertyUnit"
        },
        "attributeValue": {
          "$ref": "#/definitions/AttributeValue"
        },
        "retainDataOnAliasChange": {
          "type": "string",
          "default": "TRUE",
          "enum": [
            "TRUE",
            "FALSE"
          ]
        },
        "propertyNotificationState": {
          "description": "The MQTT notification state (ENABLED or DISABLED) for this asset property.",
          "type": "string",
          "enum": [
            "ENABLED",
            "DISABLED"
          ]
        }
      }
    },
    "AssetHierarchy": {
      "description": "A hierarchy specifies allowed parent/child asset relationships.",
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "id",
            "childAssetId"
          ]
        },
        {
          "required": [
            "externalId",
            "childAssetId"
          ]
        },
        {
          "required": [
            "id",
            "childAssetExternalId"
          ]
        },
        {
          "required": [
            "externalId",
            "childAssetExternalId"
          ]
        }
      ],
      "properties": {
        "id": {
          "description": "The ID of a hierarchy in the parent asset's model.",
          "$ref": "#/definitions/ID"
        },
        "externalId": {
          "description": "The ExternalID of a hierarchy in the parent asset's model.",
          "$ref": "#/definitions/ExternalId"
        },
        "childAssetId": {
          "description": "The ID of the child asset to be associated.",
          "$ref": "#/definitions/ID"
        },
        "childAssetExternalId": {
          "description": "The ExternalID of the child asset to be associated.",
          "$ref": "#/definitions/ExternalId"
        }
      }
    },
    "Tag": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "key",
        "value"
      ],
      "properties": {
        "key": {
          "type": "string"
        },
        "value": {
          "type": "string"
        }
      }
    },
    "AssetModelType": {
      "type": "string",
      "default": null,
      "enum": [
        "ASSET_MODEL",
        "COMPONENT_MODEL"
      ]
    },
    "AssetModelCompositeModel": {
      "description": "Contains a composite model definition in an asset model. This composite model definition is applied to all assets created from the asset model.",
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "id"
          ]
        },
        {
          "required": [
            "externalId"
          ]
        }
      ],
      "required": [
        "name",
        "type"
      ],
      "properties": {
        "id": {
          "description": "The ID of the asset model composite model.",
          "$ref": "#/definitions/ID"
        },
        "externalId": {
          "description": "The ExternalID of the asset model composite model.",
          "$ref": "#/definitions/ExternalId"
        },
        "parentId": {
          "description": "The ID of the parent asset model composite model.",
          "$ref": "#/definitions/ID"
        },
        "parentExternalId": {
          "description": "The ExternalID of the parent asset model composite model.",
          "$ref": "#/definitions/ExternalId"
        },
        "composedAssetModelId": {
          "description": "The ID of the composed asset model.",
          "$ref": "#/definitions/ID"
        },
        "composedAssetModelExternalId": {
          "description": "The ExternalID of the composed asset model.",
          "$ref": "#/definitions/ExternalId"
        },
        "description": {
          "description": "A description for the asset composite model.",
          "$ref": "#/definitions/Description"
        },
        "name": {
          "description": "A unique, friendly name for the asset composite model.",
          "$ref": "#/definitions/Name"
        },
        "type": {
          "description": "The type of the composite model. For alarm composite models, this type is AWS/ALARM.",
          "$ref": "#/definitions/Name"
        },
        "properties": {
          "description": "The property definitions of the asset model.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/AssetModelProperty"
          }
        }
      }
    },
    "AssetModelProperty": {
      "description": "Contains information about an asset model property.",
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "id"
          ]
        },
        {
          "required": [
            "externalId"
          ]
        }
      ],
      "required": [
        "name",
        "dataType",
        "type"
      ],
      "properties": {
        "id": {
          "description": "The ID of the asset model property.",
          "$ref": "#/definitions/ID"
        },
        "externalId": {
          "description": "The ExternalID of the asset model property.",
          "$ref": "#/definitions/ExternalId"
        },
        "name": {
          "description": "The name of the asset model property.",
          "$ref": "#/definitions/Name"
        },
        "dataType": {
          "description": "The data type of the asset model property.",
          "$ref": "#/definitions/DataType"
        },
        "dataTypeSpec": {
          "description": "The data type of the structure for this property.",
          "$ref": "#/definitions/Name"
        },
        "unit": {
          "description": "The unit of the asset model property, such as Newtons or RPM.",
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "pattern": "[^\\u0000-\\u001F\\u007F]+"
        },
        "type": {
          "description": "The property type",
          "$ref": "#/definitions/PropertyType"
        }
      }
    },
    "DataType": {
      "type": "string",
      "enum": [
        "STRING",
        "INTEGER",
        "DOUBLE",
        "BOOLEAN",
        "STRUCT"
      ]
    },
    "PropertyType": {
      "description": "Contains a property type, which can be one of attribute, measurement, metric, or transform.",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "attribute": {
          "$ref": "#/definitions/Attribute"
        },
        "transform": {
          "$ref": "#/definitions/Transform"
        },
        "metric": {
          "$ref": "#/definitions/Metric"
        },
        "measurement": {
          "$ref": "#/definitions/Measurement"
        }
      }
    },
    "Attribute": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "defaultValue": {
          "type": "string",
          "pattern": "[^\\u0000-\\u001F\\u007F]+"
        }
      }
    },
    "Transform": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "expression",
        "variables"
      ],
      "properties": {
        "expression": {
          "description": "The mathematical expression that defines the transformation function.",
          "type": "string",
          "minLength": 1,
          "maxLength": 1024
        },
        "variables": {
          "description": "The list of variables used in the expression.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/ExpressionVariable"
          }
        },
        "processingConfig": {
          "$ref": "#/definitions/TransformProcessingConfig"
        }
      }
    },
    "TransformProcessingConfig": {
      "description": "The processing configuration for the given transform property.",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "computeLocation"
      ],
      "properties": {
        "computeLocation": {
          "description": "The compute location for the given transform property.",
          "$ref": "#/definitions/ComputeLocation"
        },
        "forwardingConfig": {
          "description": "The forwarding configuration for a given property.",
          "$ref": "#/definitions/ForwardingConfig"
        }
      }
    },
    "Metric": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "expression",
        "variables",
        "window"
      ],
      "properties": {
        "expression": {
          "description": "The mathematical expression that defines the metric aggregation function.",
          "type": "string",
          "minLength": 1,
          "maxLength": 1024
        },
        "variables": {
          "description": "The list of variables used in the expression.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/ExpressionVariable"
          }
        },
        "window": {
          "description": "The window (time interval) over which AWS IoT SiteWise computes the metric's aggregation expression",
          "$ref": "#/definitions/MetricWindow"
        },
        "processingConfig": {
          "$ref": "#/definitions/MetricProcessingConfig"
        }
      }
    },
    "MetricProcessingConfig": {
      "description": "The processing configuration for the metric.",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "computeLocation"
      ],
      "properties": {
        "computeLocation": {
          "description": "The compute location for the given metric property.",
          "$ref": "#/definitions/ComputeLocation"
        }
      }
    },
    "ComputeLocation": {
      "type": "string",
      "enum": [
        "EDGE",
        "CLOUD"
      ]
    },
    "ForwardingConfig": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "state"
      ],
      "properties": {
        "state": {
          "type": "string",
          "enum": [
            "ENABLED",
            "DISABLED"
          ]
        }
      }
    },
    "MetricWindow": {
      "description": "Contains a time interval window used for data aggregate computations (for example, average, sum, count, and so on).",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "tumbling": {
          "description": "The tumbling time interval window.",
          "type": "object",
          "additionalProperties": false,
          "required": [
            "interval"
          ],
          "properties": {
            "interval": {
              "description": "The time interval for the tumbling window.",
              "type": "string",
              "minLength": 2,
              "maxLength": 23
            },
            "offset": {
              "description": "The offset for the tumbling window.",
              "type": "string",
              "minLength": 2,
              "maxLength": 25
            }
          }
        }
      }
    },
    "ExpressionVariable": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "value"
      ],
      "properties": {
        "name": {
          "description": "The friendly name of the variable to be used in the expression.",
          "type": "string",
          "minLength": 1,
          "maxLength": 64,
          "pattern": "^[a-z][a-z0-9_]*$"
        },
        "value": {
          "description": "The variable that identifies an asset property from which to use values.",
          "$ref": "#/definitions/VariableValue"
        }
      }
    },
    "VariableValue": {
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "propertyId"
          ]
        },
        {
          "required": [
            "propertyExternalId"
          ]
        }
      ],
      "properties": {
        "propertyId": {
          "$ref": "#/definitions/ID"
        },
        "propertyExternalId": {
          "$ref": "#/definitions/ExternalId"
        },
        "hierarchyId": {
          "$ref": "#/definitions/ID"
        },
        "hierarchyExternalId": {
          "$ref": "#/definitions/ExternalId"
        }
      }
    },
    "Measurement": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "processingConfig": {
          "$ref": "#/definitions/MeasurementProcessingConfig"
        }
      }
    },
    "MeasurementProcessingConfig": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "forwardingConfig"
      ],
      "properties": {
        "forwardingConfig": {
          "description": "The forwarding configuration for the given measurement property.",
          "$ref": "#/definitions/ForwardingConfig"
        }
      }
    },
    "AssetModelHierarchy": {
      "description": "Contains information about an asset model hierarchy.",
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "id",
            "childAssetModelId"
          ]
        },
        {
          "required": [
            "id",
            "childAssetModelExternalId"
          ]
        },
        {
          "required": [
            "externalId",
            "childAssetModelId"
          ]
        },
        {
          "required": [
            "externalId",
            "childAssetModelExternalId"
          ]
        }
      ],
      "required": [
        "name"
      ],
      "properties": {
        "id": {
          "description": "The ID of the asset model hierarchy.",
          "$ref": "#/definitions/ID"
        },
        "externalId": {
          "description": "The ExternalID of the asset model hierarchy.",
          "$ref": "#/definitions/ExternalId"
        },
        "name": {
          "description": "The name of the asset model hierarchy.",
          "$ref": "#/definitions/Name"
        },
        "childAssetModelId": {
          "description": "The ID of the asset model. All assets in this hierarchy must be instances of the child AssetModelId asset model.",
          "$ref": "#/definitions/ID"
        },
        "childAssetModelExternalId": {
          "description": "The ExternalID of the asset model. All assets in this hierarchy must be instances of the child AssetModelId asset model.",
          "$ref": "#/definitions/ExternalId"
        }
      }
    },
    "AssetModel": {
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "assetModelId"
          ]
        },
        {
          "required": [
            "assetModelExternalId"
          ]
        }
      ],
      "required": [
        "assetModelName"
      ],
      "properties": {
        "assetModelId": {
          "description": "The ID of the asset model.",
          "$ref": "#/definitions/ID"
        },
        "assetModelExternalId": {
          "description": "The ID of the asset model.",
          "$ref": "#/definitions/ExternalId"
        },
        "assetModelName": {
          "description": "A unique, friendly name for the asset model.",
          "$ref": "#/definitions/Name"
        },
        "assetModelDescription": {
          "description": "A description for the asset model.",
          "$ref": "#/definitions/Description"
        },
        "assetModelType": {
          "description": "The type of the asset model.",
          "$ref": "#/definitions/AssetModelType"
        },
        "assetModelProperties": {
          "description": "The property definitions of the asset model.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/AssetModelProperty"
          }
        },
        "assetModelCompositeModels": {
          "description": "The composite asset models that are part of this asset model. Composite asset models are asset models that contain specific properties.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/AssetModelCompositeModel"
          }
        },
        "assetModelHierarchies": {
          "description": "The hierarchy definitions of the asset model. Each hierarchy specifies an asset model whose assets can be children of any other assets created from this asset model.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/AssetModelHierarchy"
          }
        },
        "tags": {
          "description": "A list of key-value pairs that contain metadata for the asset model.",
          "type": "array",
          "items": {
            "$ref": "#/definitions/Tag"
          }
        }
      }
    },
    "Asset": {
      "type": "object",
      "additionalProperties": false,
      "anyOf": [
        {
          "required": [
            "assetId",
            "assetModelId"
          ]
        },
        {
          "required": [
            "assetExternalId",
            "assetModelId"
          ]
        },
        {
          "required": [
            "assetId",
            "assetModelExternalId"
          ]
        },
        {
          "required": [
            "assetExternalId",
            "assetModelExternalId"
          ]
        }
      ],
      "required": [
        "assetName"
      ],
      "properties": {
        "assetId": {
          "description": "The ID of the asset",
          "$ref": "#/definitions/ID"
        },
        "assetExternalId": {
          "description": "The external ID of the asset",
          "$ref": "#/definitions/ExternalId"
        },
        "assetModelId": {
          "description": "The ID of the asset model from which to create the asset.",
          "$ref": "#/definitions/ID"
        },
        "assetModelExternalId": {
          "description": "The ExternalID of the asset model from which to create the asset.",
          "$ref": "#/definitions/ExternalId"
        },
        "assetName": {
          "description": "A unique, friendly name for the asset.",
          "$ref": "#/definitions/Name"
        },
        "assetDescription": {
          "description": "A description for the asset",
          "$ref": "#/definitions/Description"
        },
        "assetProperties": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/AssetProperty"
          }
        },
        "assetHierarchies": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/AssetHierarchy"
          }
        },
        "tags": {
          "description": "A list of key-value pairs that contain metadata for the asset.",
          "type": "array",
          "uniqueItems": false,
          "items": {
            "$ref": "#/definitions/Tag"
          }
        }
      }
    }
  },
  "additionalProperties": false,
  "properties": {
    "assetModels": {
      "type": "array",
      "uniqueItems": false,
      "items": {
        "$ref": "#/definitions/AssetModel"
      }
    },
    "assets": {
      "type": "array",
      "uniqueItems": false,
      "items": {
        "$ref": "#/definitions/Asset"
      }
    }
  }
}
```