

# Model industrial assets
Model industrial assets

## Assets overview


You can create virtual representations of your industrial operation with AWS IoT SiteWise assets. An **asset** represents a device, a piece of equipment, or a process that uploads one or more data streams to the AWS Cloud. For example, an asset device can be a wind turbine that sends air temperature, propeller rotation speed, and power output time-series measurements to asset properties in AWS IoT SiteWise.

![\[AWS IoT SiteWise assets representing the devices in an industrial operation.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-asset.png)


## Property aliases identify equipment data streams


Each data stream corresponds to unique property alias. For example, the alias `/company/windfarm/3/turbine/7/temperature` uniquely identifies the temperature data stream coming from turbine \$17 in wind farm \$13. You can configure AWS IoT SiteWise assets to transform incoming measurement data using mathematical expressions, such as to convert temperature data from Celsius to Fahrenheit.

## Asset hierarchies represent equipment relationships


An asset can also represent a logical grouping of devices, such as an entire wind farm. You can associate assets with other assets to create asset hierarchies that represent complex industrial operations. Assets can access the data within their associated child assets. By doing so, you can use AWS IoT SiteWise expressions to calculate aggregate metrics, such as the net power output of a wind farm.

![\[AWS IoT SiteWise asset hierarchies representing device relationships.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-asset-hierarchy.png)


## Asset models standardize equipment representation


You must create every asset from an **asset model**. Asset models are declarative structures that standardize the format of your assets. Asset models enforce consistent information across multiple assets of the same type so that you can process data in assets that represent groups of devices. For example, a manufacturing plant might have an asset model for CNC machines that defines properties such as temperature, downtime, and production rate. In the preceding diagram, you use the same asset model for all three turbines because they share a common set of properties.

## Modeling options for industrial equipment


When designing your industrial asset representation, consider these options:
+ **Asset models** represent specific types of equipment or processes. You must create each physical asset from an asset model. For example, a chemical processing plant might have separate asset models for reactors, mixers, and storage tanks.
+ **Component models** define reusable sub-assemblies that you can include in asset models or other component models. For example, you could include a temperature sensor component model in multiple equipment asset models across a factory.
+ **Asset model interfaces** apply standards across different asset models. For example, a "Rotating Equipment" interface could define standard properties for vibration, temperature, and RPM that apply to pumps, turbines, and motors, despite each having its own unique asset model.

## Creating and managing assets


After you define your asset models, you can create your industrial assets. To create an asset, select an `ACTIVE` asset model to create an asset from that model. Then, you can populate asset-specific information such as data stream aliases and attributes. In the preceding diagram, you create three turbine assets from one asset model and then associate data stream aliases like `/company/windfarm/3/turbine/7/temperature` for each turbine.

You can also update and delete existing assets, asset models, and component models. When you update an asset model, every asset based on that asset model reflects any changes that you make to the underlying model. When you update a component model, this applies to every asset based on every asset model that references the component model.

## Managing complex asset models


Your asset models may be very complex, for example when modeling a complicated piece of equipment that has many subcomponents. To help keep such asset models organized and maintainable, you can use custom composite models to group related properties or to re-use shared components. For more information, see [Custom composite models (components)](custom-composite-models.md).

**Topics**

# Asset and model states


When you create, update, or delete an asset, an asset model, or a component model, the changes take time to propagate. AWS IoT SiteWise resolves these operations asynchronously and updates the status of each resource. Each asset, asset model, and component model has a status field that contains the state of the resource and any error message, if applicable. The state can be one of the following values:
+ `ACTIVE` – The resource is active. This is the only state in which you can query and interact with assets, asset models, and component models.
+ `CREATING` – The resource is being created.
+ `UPDATING` – The resource is being updated.
+ `DELETING` – The resource is being deleted.
+ `PROPAGATING` – (Asset models and component models only) The changes are propagating to all dependent resources (from asset model to assets, or from component model to asset models).
+ `FAILED` – The resource failed to validate during a create or update operation, possibly due to a circular reference in an expression. You can delete resources that are in the `FAILED` state.

Some of the create, update, and delete operations in AWS IoT SiteWise place an asset, asset model, or component model in a state other than `ACTIVE` while the operation resolves. To query or interact with a resource after you perform one of these operations, you must wait until the state changes to `ACTIVE`. Otherwise, your requests fail.

**Topics**
+ [

# Check the status of an asset
](check-asset-status.md)
+ [

# Check the status of an asset or component model
](check-model-status.md)

# Check the status of an asset


You can use the AWS IoT SiteWise console or API to check the status of an asset.

**Topics**
+ [

## Check the status of an asset (console)
](#check-asset-status-console)
+ [

## Check the status of an asset (AWS CLI)
](#check-asset-status-cli)

## Check the status of an asset (console)


Use the following procedure to check the status of an asset in the AWS IoT SiteWise console.

**To check the status of an asset (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-assets"></a>In the navigation pane, choose **Assets**.

1. Choose the asset to check.
**Tip**  <a name="sitewise-expand-asset-hierarchy"></a>
You can choose the arrow icon to expand an asset hierarchy to find your asset.

1. Find **Status** in the **Asset details** panel.  
![\[AWS IoT SiteWise Asset details panel with Status as Active.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-view-asset-status-console.png)

## Check the status of an asset (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to check the status of an asset.

To check the status of an asset, use the [DescribeAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAsset.html) operation with the `assetId` parameter.

**To check the status of an asset (AWS CLI)**
+ Run the following command to describe the asset. Replace *asset-id* with the asset's ID or external ID. The external ID is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

  ```
  aws iotsitewise describe-asset --asset-id asset-id
  ```

  The operation returns a response that contains the asset's details. The response contains an `assetStatus` object that has the following structure:

  ```
  {
      ...
      "assetStatus": {
        "state": "String",
        "error": {
           "code": "String",
           "message": "String"
        }
      }
    }
  ```

  The asset's state is in `assetStatus.state` in the JSON object.

# Check the status of an asset or component model


You can use the AWS IoT SiteWise console or API to check the status of an asset model or component model.

**Topics**
+ [

## Check the status of an asset model or component model (console)
](#check-model-status-console)
+ [

## Check the status of an asset model or component model (AWS CLI)
](#check-model-status-cli)

## Check the status of an asset model or component model (console)


Use the following procedure to check the status of an asset model or component model in the AWS IoT SiteWise console.

**Tip**  
Asset models and component models are both listed under **Models** in the navigation pane. The **Details** panel of the selected asset model or component model indicates which type it is.

**To check the status of an asset model or component model (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the model to check.

1. Find **Status** in the **Details** panel.  
![\[AWS IoT SiteWise "Asset model" page screenshot with asset model status highlighted.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-view-model-status-console.png)

## Check the status of an asset model or component model (AWS CLI)


You can use the AWS CLI to check the status of an asset model or component model.

To check the status of an asset model or component model, use the [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation with the `assetModelId` parameter.

**Tip**  
The AWS CLI defines component models as a type of asset model. Therefore, you use the same [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation for both types of model. The `assetModelType` field in the response indicates whether it's an `ASSET_MODEL` or a `COMPONENT_MODEL`. 

**To check the status of an asset model or component model (AWS CLI)**
+ Run the following command to describe the model. Replace *asset-model-id* with the ID or the external ID of the asset model or component model. The external ID is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

  ```
  aws iotsitewise describe-asset-model --asset-model-id asset-model-id
  ```

  The operation returns a response that contains the model's details. The response contains an `assetModelStatus` object that has the following structure.

  ```
  {
      ...
      "assetModelStatus": {
        "state": "String",
        "error": {
           "code": "String",
           "message": "String"
        }
      }
    }
  ```

  The model's state is in `assetModelStatus.state` in the JSON object.

# Asset model versions


 AWS IoT SiteWise supports asynchronous processing of create and update operations on asset models and component models. It also updates the status of the model. 

 AWS IoT SiteWise propagates a valid model's changes in the create and update requests to its dependent resources (from asset model to assets, or from component model to asset models). It then places the model in `ACTIVE` state. 

 If the provided model definition is invalid, AWS IoT SiteWise places the model in a `FAILED` state. The changes are not propagated to the dependent resources. The dependent resources refer to the last model definition propagated when the model was in an `ACTIVE` state. 

 Based on the information above, model definitions have two types of model versions: 

1. **Latest version –** The latest definition accepted as part of a create or update request.

1. **Active version –** The latest definition successfully processed, and the model state is `ACTIVE`.

 By default, details of the model's latest version is returned when describe APIs are called on an asset model or component model. There are scenarios where the active version of the asset model or component model is needed. See example scenarios below: 
+  An update operation with an invalid definition places your asset model in a `FAILED` state. You must revert your changes by retrieving the active version of the asset model, and creating another update request referring to this valid definition. 
+  An application on AWS IoT SiteWise exists where customers can view assets and their corresponding asset models. When a user refers the asset model definition corresponding to a particular asset, and the asset model is in a transitory `UPDATING`, `PROPAGATING`, or `FAILED` state, the latest version returns the asset model definition that is not yet propagated to its assets. In this case, you must retrieve the active version of the asset model to customers. 

**Topics**
+ [

## Retrieve the active version of an asset model or component model (console)
](#active-console)
+ [

## Retrieve the active version of an asset model or component model (AWS CLI)
](#active-cli)

## Retrieve the active version of an asset model or component model (console)


Follow this procedure to retrieve the active version of an asset model or component model in the AWS IoT SiteWise console.

**Tip**  
Asset models and component models are both listed under **Models** in the navigation pane. The **Details** panel of the selected asset model or component model indicates which type it is.

**To retrieve the active version of an asset model or component model (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the model to retrieve its active version.

   1.  If the model is in an `ACTIVE` state, you are viewing its active version. 

   1.  If the model is in a transitory `UPDATING`, `PROPAGATING`, or `FAILED` state, find the **See active version** under **Status** in the **Details** panel. 

## Retrieve the active version of an asset model or component model (AWS CLI)


Use the AWS CLI to retrieve the active version of an asset model or component model.

To retrieve the active version of an asset model or component model, use the [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation with the `assetModelVersion` parameter.

**Tip**  
The AWS CLI defines component models as a type of asset model. Therefore, you use the same [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation for both types of model. The `assetModelType` field in the response indicates whether it's an `ASSET_MODEL` or a `COMPONENT_MODEL`. 

**To retrieve the active version of an asset model or component model (AWS CLI)**
+ Run the following command to describe the model. Replace *asset-model-id* with the ID or the external ID of the asset model or component model. The external ID is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

  ```
  aws iotsitewise describe-asset-model --asset-model-id asset-model-id --asset-model-version ACTIVE
  ```

  The operation returns a response with the model's details. The response contains an `assetModelStatus` object with the following structure.

  ```
  {
      ...
      "assetModelName": "string",
      "assetModelProperties": [ ... ],
      ...,
      "assetModelVersion": "string"
  }
  ```

# Custom composite models (components)
Custom composite models (components)

 When you're modeling an especially complex industrial asset, such as a complicated piece of machinery that has many parts, it can become a challenge to keep your asset models organized and maintainable.

In such cases, you can add custom composite models, or components if you're using the console, to your existing asset models and component models. These help you stay organized by grouping related properties and re-using subcomponent definitions.

There are two types of custom composite models:
+ **Inline** custom composite models define a set of grouped properties that apply to the asset model or component model to which the custom composite model belongs. You use them to group related properties. They consists of a name, a description, and a set of asset model properties. They are not reusable.
+ **Component-model-based** custom composite models reference a component model that you want to include in your asset model or component model. You use them to include standard subassemblies in your model. They consist of a name, a description, and the ID of the component model it references. They have no properties of their own; the referenced component model provides its associated properties to any created assets.

The following sections illustrate how to use custom composite models in your designs.

**Topics**
+ [

## Inline custom composite models
](#inline-composite-models)
+ [

## Component-model-based custom composite models
](#component-based-custom-composite-models)
+ [

## Use paths to reference custom composite model properties
](#property-paths)

## Inline custom composite models


Inline custom composite models provide a way to organize your asset model by grouping related properties.

For example, suppose you want to model a robot asset. The robot includes a servomotor, a power supply, and a battery. Each of those constituent parts has its own properties that you want to include in the model. You might define an asset model called `robot_model` that has properties such as the following.


****  

|  | 
| --- |
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/custom-composite-models.html)  | 

However, in some cases, there might be many subassemblies, or the subassemblies themselves might have many properties. In these cases, there might be so many properties that they become cumbersome to reference and maintain in a single flat list at the model root, like in the preceding example.

To deal with such situations, you can use an inline custom composite model to group properties. An inline custom composite model is a custom composite model that defines its own properties. For example, you could model your robot like the following.


****  

|  | 
| --- |
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/custom-composite-models.html)  | 

In the preceding example, `servo`, `powersupply`, and `battery` are the names of inline custom composite models defined within the `robot_model` asset model. Each of these composite models then defines properties of its own.

**Note**  
In this case, each custom composite model defines its own properties, so that all the properties are part of the asset model itself (`robot_model` in this case). These properties aren't shared with any other asset models or component models. For example, if you created some other asset model that also had an inline custom composite model called `servo`, then making a change to the `servo` within `robot_model` wouldn't affect the other asset model's `servo` definition.  
 If you want to implement such sharing (for example, to have only one definition for a servo, which all your asset models can share), you would create a component model for it instead, and then create **component-model-based** composite models that reference it. See the following section for details. 

For information about how to create inline custom composite models, see [Create custom composite models (components)](create-custom-composite-models.md).

## Component-model-based custom composite models


You can create a component model in AWS IoT SiteWise to define a standard, reusable sub-assembly. Once you have created a component model, you can add references to it in your other asset models and component models. You do this by adding a **component-model-based custom composite model** to any model where you want to reference the component. You can add references to your component from many models, or multiple times within the same model.

In this way, you can avoid duplicating the same definitions across models. It also simplifies maintaining your models, because any changes you make to a component model will be reflected across all asset models that use it.

For example, suppose that your industrial installation has many types of equipment that all use the same kind of servo motor. Some of them have many servo motors in a single piece of equipment. You create an asset model for each equipment type, but you don't want to duplicate the definition of `servo` every time. You want to model it just once and use it in your various asset models. If you later make a change to the definition of `servo`, it will be updated across all your models and assets.

To model the robot from the previous example in this way, you could define servo motors, power supplies, and batteries as component models, like this.


****  

|  | 
| --- |
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/custom-composite-models.html)  | 


****  

|  | 
| --- |
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/custom-composite-models.html)  | 


****  

|  | 
| --- |
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/custom-composite-models.html)  | 

You could then define asset models, such as `robot_model`, that reference these components. Multiple asset models can reference the same component model. You can also reference the same component model multiple times in one asset model, such as if your robot has multiple servomotors in it.


****  

|  | 
| --- |
|  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/custom-composite-models.html)  | 

For information about how to create component models, see [Create component models](create-component-models.md).

For information about how to reference your component models in other models, see [Create custom composite models (components)](create-custom-composite-models.md).

## Use paths to reference custom composite model properties


When you create a property on an asset model, component model, or custom composite model, you can reference it from other properties that use its value, such as [transforms](transforms.md) and [metrics](metrics.md).

AWS IoT SiteWise provides different ways for you to reference your property. The simplest way is often to use its property ID. However, if the property you want to reference is on a custom composite model, you may find it more useful to reference it by *path* instead.

A path is an ordered sequence of *path segments* that specifies a property in terms of its position among the nested composite models within an asset model and composite model.

### Obtain property paths


You can get a property's path from the `path` field of its [AssetModelProperty](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssetModelProperty.html).

For example, suppose you have an asset model `robot_model` that contains a custom composite model `servo`, which has a property `position`. If you call [DescribeAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModelCompositeModel.html) on `servo`, then the `position` property would list a `path` field that looks like this: 

```
"path": [
    {
       "id": "asset model ID",
       "name": "robot_model"
    },
    {
       "id": "composite model ID",
       "name": "servo"
    },
    {
       "id": "property ID",
       "name": "position"
    }
]
```

### Using property paths


You can use a property path when you define a property that references other properties, such as a transform or metric.

A property uses a *variable* to reference another property. For more information about working with variables, see [Use variables in formula expressions](expression-variables.md).

When you define a variable to reference a property, you can use either the property's ID or its path.

To define a variable that uses the path of the referenced property, specify the `propertyPath` field of its value.

For example, to define an asset model that has a metric that references a property by using a path, you could pass a payload like this to [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html):

```
{
    ...
    "assetModelProperties": [
        {
            ...
            "type": {
                "metric": {
                    ...
                    "variables": [
                        {
                            "name": "variable name",
                            "value": {
                                "propertyPath": [
                                    path segments
                                ]
                            }
                        }
                    ],
                    ...
                }
            },
            ...
        },
        ...
    ],
    ...
}
```

# Asset model interfaces
Asset model interfaces

AWS IoT SiteWise interfaces set standards across different asset models. They define a common structure that ensures consistency while allowing for variations in implementation.

Interfaces share the same structure as asset models (properties, composite models, and hierarchies) but you cannot create assets directly from them. Instead, interfaces are applied to existing asset models to ensure standardization. Component models are not supported for interfaces.

Using interfaces provides several benefits:
+ Standardized properties and metrics across different asset model variations
+ Simplified metric definitions at the interface level
+ More efficient management of complex asset hierarchies
+ Independent property lifecycle management for each asset model variation
+ Enhanced cross-team collaboration where operations teams focus on physical asset representation while data teams establish standards across equipment

We recommend creating your asset models first to model your real-world industrial equipment. Every equipment type, with their own set of properties, can be represented by their own asset models. 

## Asset model standardization use case


Interfaces help standardize properties across different asset models while preserving their unique characteristics.

For example, there are four stations in a powertrain shop: engine, transmission, differential, and assembly. Each station contains various equipment types. For example, the engine station includes CNC machines, but they differ in specifications: some are 3-axis, while others are 5-axis.

![\[Diagram showing the hierarchy of the powertrain shop's equipment using only asset models and assets. The powertrain shop is at the top, then each of the asset models for the engine, transmission, differential and assemble stations on the second level down. On the third level down, there's the individual CNC machines broken down by axis stemming from the engine station asset model. Conversely, there's asset models stemming from the assemble station model as well. On the fourth level, are each of the assets representing the individual CNC machines or robotic arms by name.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/models-interface-hierarchy.png)


However, interfaces let you create standards for commonalities seen in the CNC machines. You can use the repeatable properties in an interface rather than create asset models for each property.

For example, you can:

1. Create separate asset models for each category of machine types. In this example, that's the "CNC 3 Axis machines" and the "CNC 5 Axis machines."

1. Define a standard interface with common properties and metrics. In this example, `Temperature-in-C`, `Down-time`, and `Running-time` are all common properties that apply to both CNC machines.

1. Apply this interface to all CNC machine asset models, still allowing for device-specific properties on the individual asset models.

![\[Diagram showing how interfaces simplify the organization of asset models from previous diagram. It shows several repeatable parameters for the engine station CNC machines now governed by the interfaces carrying over to various properties to the 3-axis and 5-axis CNC machine asset models, while also allowing for device-specific properties on each.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/models-interface-to-asset-models.png)


You can also define availability metrics at the interface level. For example, `Avail = avg(Down-time, Running-time)` calculates the availability based on the down time and running time values.

Using interfaces simplifies your asset model management by ensuring consistent property definitions and metrics across applicable equipment while maintaining the unique characteristics of each machine type.

## Structure and components


Interfaces include the same property types as asset models: attributes, measurements, transforms, and metrics. When overlayed on an asset model, you map existing properties to their interface counterparts. Unmapped interface properties are automatically created in the asset model.

Interface hierarchies define rollup metrics, while asset model hierarchies enable asset associations. When you use an interface, the service will automatically map asset model hierarchies to interface hierarchies when computing rollup metrics. After applying an interface, rollup metrics are defined through the interface hierarchy rather than the asset model's own hierarchy.

## Considerations


When working with interfaces, keep these considerations in mind:
+ Asset model and interface properties can be automatically mapped by name or manually mapped. Hierarchies are automatically mapped by the service when computing rollup metrics.
+ You cannot define additional metrics in the linked asset model that use interface metrics as inputs.
+ An asset model can only be linked to one interface. However, you can have multiple asset models applied to the same interface.
+ Alarms are not supported in interfaces.
+ Component models are not supported for interfaces.

**Topics**
+ [

## Asset model standardization use case
](#interface-powertrain-shop-example)
+ [

## Structure and components
](#interface-structure)
+ [

## Considerations
](#interface-considerations)
+ [

# Understand the interface-asset model relationship
](interface-asset-model-relationship.md)
+ [

# Create an interface
](interface-create.md)
+ [

# Apply an interface to an asset model
](interfaces-link-asset-model.md)
+ [

# Manage interfaces, linked asset models, and properties
](interfaces-manage.md)
+ [

# Additional interface examples
](interface-additional-examples.md)

# Understand the interface-asset model relationship


Interfaces and asset models work together in a complementary relationship:


**Interfaces vs. Asset Models**  

| Aspect | Interfaces | Asset Models | 
| --- | --- | --- | 
| Purpose | Define standards and applies consistency | Represent physical or logical assets | 
| Asset Creation | Cannot create assets directly | Used to create assets | 
| Properties | Define standard properties that must be implemented in models | Can have interface-applied and unique properties | 
| Metrics | Define standard calculations | Implement interface metrics and can have additional metrics | 
| Hierarchies | Define data computation hierarchical relationships for rollup metrics | Define physical hierarchical relationships for asset associations | 

When you apply an interface to an asset model:
+ The asset model must map all properties defined in the interface.
+ Property mappings define how interface properties correspond to asset model properties.
+ Mapped asset model properties must remain synchronized with their corresponding interface properties and cannot be modified in a way that would cause inconsistency between the two.
+ Unmapped interface properties are automatically created in the asset model.
+ The asset model can have additional properties beyond those defined in the interface.
+ The asset model implements interface metrics. Changes to interface metrics propagate to all asset models using the interface.
+ Interface hierarchies are used for computing rollup metrics. Asset model hierarchies can be defined independently, and the service will automatically map them when computing rollup metrics.

This relationship ensures standardization while allowing for the flexibility needed to represent diverse equipment types.

## Standardize existing asset models


While interfaces are valuable when designing new asset models from scratch, they're equally powerful for standardizing existing asset models that may have evolved independently over time.

When working with existing asset models, you can apply interfaces to standardize metrics and properties:

1. Identify common metrics and properties across your existing asset models

1. Create an interface that defines these standard properties and metrics

1. Apply the interface to your existing asset models using property mapping

1. Use rollup metrics to aggregate data across your asset hierarchy

For example, if you have existing CNC machine asset models with different property names but similar data, like `temp_celsius`, `temperature_c`, `machine_temp`), you can:

1. Create a `CNC-INTERFACE` with a standardized `Temperature-in-C` property

1. Apply this interface to each CNC asset model, mapping the existing temperature properties to the interface's `Temperature-in-C` property

1. Define rollup metrics in the interface that calculate statistics across all machines (e.g., average temperature)

This approach allows you to maintain your existing asset models while gaining the benefits of standardization and simplified metrics calculation.

## Hierarchy relationships


Interface hierarchy  
Defines relationships for calculating and aggregating data across different interfaces. For example, in a factory setting, an interface hierarchy could connect temperature-monitoring interfaces at different levels to calculate average temperatures. For example: machine, production line, and facility. When you define a rollup metric like `AverageTemperature`, the interface hierarchy determines how that metric aggregates data from lower levels to higher levels.

Asset model hierarchy  
Represents the actual physical or logical structure of your assets. For instance, a CNC machine asset model might be part of a production line asset model, which in turn belongs to a factory asset model. This hierarchy reflects real-world relationships and helps organize assets in a way that matches their physical arrangement or business structure. When combined with interface hierarchies, asset model hierarchies help the system understand which assets should be included in rollup calculations.

These two hierarchy types work together: interface hierarchies define how to compute aggregated metrics, while asset model hierarchies define which specific assets should be included in those calculations.

## Interface metrics and rollup calculations


Interfaces excel at defining standardized metrics that can be applied across different asset models. This is particularly valuable for rollup metrics that aggregate data from multiple assets.

When you define metrics in an interface, they're automatically applied to all asset models that implement the interface. The metrics can reference properties defined in the interface, use aggregation functions to calculate statistics across assets, and ensure consistent calculations across all implementing asset models For example, you can define an availability metric in an interface that calculates the ratio of running time to total time:

```
{
  "name": "Availability",
  "dataType": "DOUBLE",
  "type": {
    "metric": {
      "expression": "Running-time / (Running-time + Down-time) * 100",
      "variables": [
        {
          "name": "Running-time",
          "value": {
            "propertyId": "${Running-time}"
          }
        },
        {
          "name": "Down-time",
          "value": {
            "propertyId": "${Down-time}"
          }
        }
      ],
      "window": {
        "tumbling": {
          "interval": "1h"
        }
      }
    }
  },
  "unit": "Percent"
}
```

When this interface is applied to multiple asset models, the availability metric is calculated consistently for all of them, even if the underlying property names differ (thanks to property mapping).

For more information about defining metrics and using aggregation functions, see [Aggregate data from properties and other assets (metrics)](metrics.md).

### Rollup metrics with interfaces


Interfaces can also define rollup metrics that aggregate data across assets in a hierarchy. When you define a hierarchy in an interface and apply it to an asset model, you can create metrics that aggregate data from child assets.

For example, you can define a metric that calculates the average temperature across all CNC machines in a factory:

```
{
  "name": "AverageTemperature",
  "dataType": "DOUBLE",
  "type": {
    "metric": {
      "expression": "avg(Temperature-in-C)",
      "variables": [
        {
          "name": "Temperature-in-C",
          "value": {
            "propertyId": "${Temperature-in-C}",
            "hierarchyId": "${CNC-machines}"
          }
        }
      ],
      "window": {
        "tumbling": {
          "interval": "1h"
        }
      }
    }
  },
  "unit": "Celsius"
}
```

This metric uses the `avg()` aggregation function to calculate the average temperature across all CNC machines in the hierarchy. The `hierarchyId` parameter specifies which hierarchy to use for the aggregation.

When this interface is applied to an asset model, the rollup metric automatically aggregates data from all child assets that match the hierarchy mapping.

# Create an interface


You can create interfaces using either the AWS IoT SiteWise console or the AWS CLI.

------
#### [ Console ]

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/) and choose **Models** from the navigation pane.

1. Choose **Create interface**.

1. Enter a unique **Name** and optional **Description** for your interface. You can also optionally add an **External ID** of you choosing.

1. Add properties to your interface. You can add attributes, measurements, transforms, and metrics just like with asset models. For more information, see [Create an asset model (console)](create-asset-models.md#create-asset-model-console).

1. Choose **Create interface** to create the interface.

1. If you have hierarchies to define parent-child relationships between interfaces, choose **Add hierarchy** and enter relevant details.

------
#### [ AWS CLI ]

To create an interface, use the `CreateAssetModel` operation with the `assetModelType` parameter set to `INTERFACE`:

```
aws iotsitewise create-asset-model \
  --asset-model-name "CNC-INTERFACE" \
  --asset-model-description "Standard interface for CNC machines" \
  --asset-model-type "INTERFACE" \
  --asset-model-properties '[
    {
      "name": "Temperature-in-C",
      "dataType": "DOUBLE",
      "type": {
        "measurement": {}
      },
      "unit": "Celsius"
    },
    {
      "name": "Down-time",
      "dataType": "DOUBLE",
      "type": {
        "measurement": {}
      },
      "unit": "Minutes"
    },
    {
      "name": "Running-time",
      "dataType": "DOUBLE",
      "type": {
        "measurement": {}
      },
      "unit": "Minutes"
    },
    {
      "name": "Availability",
      "dataType": "DOUBLE",
      "type": {
        "metric": {
          "expression": "Running-time / (Running-time + Down-time) * 100",
          "variables": [
            {
              "name": "Running-time",
              "value": {
                "propertyId": "${Running-time}"
              }
            },
            {
              "name": "Down-time",
              "value": {
                "propertyId": "${Down-time}"
              }
            }
          ],
          "window": {
            "tumbling": {
              "interval": "1h"
            }
          }
        }
      },
      "unit": "Percent"
    }
  ]'
```

------

# Apply an interface to an asset model


When applying an interface to an asset model, you map asset model properties and hierarchies to their interface counterparts. For unmapped interface properties, corresponding properties are automatically created in the asset model. After linking, the service prevents changes to the asset model that would violate interface standards.

You can add one asset model to an interface at a time. However, multiple asset models can be linked to a single interface.

------
#### [ Console ]

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/) and choose **Models** from the navigation pane.

1. Select the asset model to which you want to apply an interface.

1. Choose **Link asset model** in the **Link asset models** section. This brings up the **Link interface** page.

1. In the **Asset models and interfaces** section, select an asset model from the **Select a model to link** dropdown menu.

1. In the **Property mappings** section, map each interface property to an existing asset model property or create a new property. AWS IoT SiteWise automatically links properties with matching names in the asset model and interface.

1. Review the property mappings and choose **Link interface**.

------
#### [ AWS CLI ]

To apply an interface to an asset model, use the `PutAssetModelInterfaceRelationship` operation:

```
aws iotsitewise put-asset-model-interface-relationship \
  --asset-model-id "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \ 
  --interface-asset-model-id "a1b2c3d4-5678-90ab-cdef-22222EXAMPLE" \
  --property-mapping-configuration '{
    "createMissingProperty": true,
    "matchByPropertyName": true,   
    "overrides": [
      {
        "assetModelPropertyId": "a1b2c3d4-5678-90ab-cdef-44444EXAMPLE",
        "interfaceAssetModelPropertyId": "a1b2c3d4-5678-90ab-cdef-33333EXAMPLE"      
      }
    ]
  }'
```

To retrieve information about an interface relationship, use the `DescribeAssetModelInterfaceRelationship` operation:

```
aws iotsitewise describe-asset-model-interface-relationship \
  --asset-model-id "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
  --interface-asset-model-id "a1b2c3d4-5678-90ab-cdef-22222EXAMPLE"
```

To list all asset models that have a specific interface applied to them, use the `ListInterfaceRelationships` operation:

```
aws iotsitewise list-interface-relationships \
  --interface-asset-model-id "a1b2c3d4-5678-90ab-cdef-22222EXAMPLE" \
  --max-results 10
```

To delete an interface relationship, use the `DeleteAssetModelInterfaceRelationship` operation:

```
aws iotsitewise delete-asset-model-interface-relationship \
  --asset-model-id "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
  --interface-asset-model-id "a1b2c3d4-5678-90ab-cdef-22222EXAMPLE"
```

------

# Manage interfaces, linked asset models, and properties
Manage interfaces

After creating interfaces and linking them to asset models, you can manage relationships, edit, and delete interfaces through the console or AWS CLI.

## Modify an interface and asset model relationship


To change an interface's relationship to an asset model, do the following in either the AWS IoT SiteWise console or through AWS CLI:

------
#### [ Console ]

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/) and choose **Models** from the navigation pane.

1. Select the interface you want modify.

1. Choose the asset model to modify and edit it.

   You can follow the [Apply an interface to an asset model](interfaces-link-asset-model.md) instructions to link a different asset model.

1. Choose **Apply interface** to save your changes.

------
#### [ AWS CLI ]

To edit an interface and asset model relationship, use the `PutAssetModelInterfaceRelationship` action. Replace *your-asset-model-id* and *your-interface-asset-model-id* with your own values. For more information, see [PutAssetModelInterfaceRelationship](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_PutAssetModelInterfaceRelationship.html) in the *AWS IoT SiteWise API Reference*.

```
aws iotsitewise put-asset-model-interface-relationship \
    --asset-model-id your-asset-model-id \
    --interface-asset-model-id your-interface-asset-model-id
```

------

## Modify an interface property mapping


To change an interface's property, do the following in either the AWS IoT SiteWise console or through AWS CLI:

------
#### [ Console ]

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/) and choose **Models** from the navigation pane.

1. Select the interface for which you want modify property mappings. The **Edit property mappings** page appears.

1. In the **Property mappings** section, filter the list to find the appropriate property mappings.

1. Change the properties using the **Model property** column.

------
#### [ AWS CLI ]

To edit an interface and asset model relationship, use the `PutAssetModelInterfaceRelationship` action. Replace *your-asset-model-id* and *your-interface-asset-model-id* with your own values. For more information, see [PutAssetModelInterfaceRelationship](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_PutAssetModelInterfaceRelationship.html) in the *AWS IoT SiteWise API Reference*.

```
aws iotsitewise put-asset-model-interface-relationship \
    --asset-model-id your-asset-model-id \
    --interface-asset-model-id your-interface-asset-model-id \
```

------

## List interfaces linked to an asset model


To get a list of interfaces applied to an asset model, do the following in either the AWS IoT SiteWise console or through AWS CLI:

------
#### [ Console ]

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/) and choose **Models** from the navigation pane.

1. In the **Models** section, choose the appropriate asset model or interface. You can view a list of either applied interfaces or linked asset models on the model's corresponding details page. 
   + When viewing a particular interface, see the **Linked asset models** section.
   + When viewing a particular asset model, see the **Applied interfaces** section.

------
#### [ AWS CLI ]

To list interfaces, you can use the `ListInterfaceRelationships` operation. Replace *your-interface-asset-model-id* with your own value. For more information, see [ListInterfaceRelationships](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ListInterfaceRelationships.html) in the *AWS IoT SiteWise API Reference*.

```
aws iotsitewise list-interface-relationships \
    --interface-asset-model-id your-interface-asset-model-id \
    [--next-token your-next-token] \
    [--max-results 20]
```

------

## View the details of an interface and asset model relationship


To see the details of an interface applied to an asset model, do the following in either the AWS IoT SiteWise console or through AWS CLI:

------
#### [ Console ]

View the details of applied interfaces and linked asset models.

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/) and choose **Models** from the navigation pane.

1. In the **Models** section, search for the appropriate asset model or interface. Select the model or interface's **Name** to open up a page containing more details.

------
#### [ AWS CLI ]

To view interface details for an interface and asset model relationship, use the `DescribeAssetModelInterfaceRelationship` action. Replace *your-asset-model-id* and *your-interface-asset-model-id* with your own values. For more information, see [DescribeAssetModelInterfaceRelationship](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModelInterfaceRelationship.html) in the *AWS IoT SiteWise API Reference*.

```
aws iotsitewise describe-asset-model-interface-relationship \
    --asset-model-id your-asset-model-id \
    --interface-asset-model-id your-interface-asset-model-id
```

------

## Remove an interface applied to an asset model


To remove an interface applied to an asset model, do the following in either the AWS IoT SiteWise console or through AWS CLI:

------
#### [ Console ]

We recommend removing an interface through the asset model. You can also delete an interface or unlink an interface through a particular interface's page.

1. Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/) and choose **Models** from the navigation pane.

1. Select the appropriate asset model from which to remove the interface relationship.

1. Choose **Unlink asset model**.

------
#### [ AWS CLI ]

To remove an interface relationship from an asset model, you can use the `DeleteAssetModelInterfaceRelationship` action. Replace *your-interface-asset-model-id* with your own value. For more information, see [DeleteAssetModelInterfaceRelationship](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DeleteAssetModelInterfaceRelationship.html) in the *AWS IoT SiteWise API Reference*.

```
aws iotsitewise delete-asset-model-interface-relationship \
    --asset-model-id your-asset-model-id \
    --interface-asset-model-id your-interface-asset-model-id
```

------

# Additional interface examples


Here are additional examples of how interfaces can be used in different industrial scenarios:

## Energy generation equipment


A power generation company can use interfaces to standardize metrics across different types of generation equipment:

```
{
  "assetModelName": "GENERATOR-INTERFACE",
  "assetModelDescription": "Standard interface for power generators",
  "assetModelType": "INTERFACE",
  "assetModelProperties": [
    {
      "name": "ActivePower",
      "dataType": "DOUBLE",
      "type": { "measurement": {} },
      "unit": "MW"
    },
    {
      "name": "ReactivePower",
      "dataType": "DOUBLE",
      "type": { "measurement": {} },
      "unit": "MVAR"
    },
    {
      "name": "Frequency",
      "dataType": "DOUBLE",
      "type": { "measurement": {} },
      "unit": "Hz"
    },
    {
      "name": "PowerFactor",
      "dataType": "DOUBLE",
      "type": {
        "metric": {
          "expression": "cos(atan(ReactivePower / ActivePower))",
          "variables": [
            {
              "name": "ActivePower",
              "value": { "propertyId": "${ActivePower}" }
            },
            {
              "name": "ReactivePower",
              "value": { "propertyId": "${ReactivePower}" }
            }
          ],
          "window": { "tumbling": { "interval": "5m" } }
        }
      },
      "unit": "None"
    }
  ]
}
```

This interface can be applied to various generator asset models (gas turbines, steam turbines, wind turbines) to ensure consistent power metrics across the fleet.

## Water treatment facilities


A water utility can use interfaces to standardize monitoring across treatment plants:

```
{
  "assetModelName": "WATER-QUALITY-INTERFACE",
  "assetModelDescription": "Standard interface for water quality monitoring",
  "assetModelType": "INTERFACE",
  "assetModelProperties": [
    {
      "name": "pH",
      "dataType": "DOUBLE",
      "type": { "measurement": {} },
      "unit": "pH"
    },
    {
      "name": "Turbidity",
      "dataType": "DOUBLE",
      "type": { "measurement": {} },
      "unit": "NTU"
    },
    {
      "name": "DissolvedOxygen",
      "dataType": "DOUBLE",
      "type": { "measurement": {} },
      "unit": "mg/L"
    },
    {
      "name": "QualityIndex",
      "dataType": "DOUBLE",
      "type": {
        "metric": {
          "expression": "(pH >= 6.5 && pH <= 8.5 ? 100 : 50) * (Turbidity < 1 ? 1 : 0.8) * (DissolvedOxygen > 5 ? 1 : 0.7)",
          "variables": [
            {
              "name": "pH",
              "value": { "propertyId": "${pH}" }
            },
            {
              "name": "Turbidity",
              "value": { "propertyId": "${Turbidity}" }
            },
            {
              "name": "DissolvedOxygen",
              "value": { "propertyId": "${DissolvedOxygen}" }
            }
          ],
          "window": { "tumbling": { "interval": "1h" } }
        }
      },
      "unit": "Score"
    }
  ]
}
```

This interface ensures that water quality is measured consistently across all treatment facilities, regardless of their specific equipment configurations.

## Hierarchical interfaces


Interfaces can be organized hierarchically to support aggregate metrics at different levels of your operation:

1. **Equipment-level interface** (for example, `PUMP-INTERFACE`)
   + Properties: Flow rate, pressure, power consumption, vibration
   + Metrics: Efficiency, health score

1. **Process-level interface** (for example, `PUMPING-STATION-INTERFACE`)
   + Properties: Total flow, average pressure, total power
   + Metrics: Station efficiency, operational cost per volume
   + Hierarchy: Contains `PUMP-INTERFACE` equipment

1. **Facility-level interface** (for example, `WATER-FACILITY-INTERFACE`)
   + Properties: Facility throughput, energy usage, chemical usage
   + Metrics: Facility efficiency, cost per unit volume, carbon footprint
   + Hierarchy: Contains `PUMPING-STATION-INTERFACE` processes

This hierarchical approach allows metrics to be calculated at each level while maintaining consistency across your entire operation.

# Set up AWS IoT SiteWise object IDs
Set up object IDs

 AWS IoT SiteWise defines various types of persistent objects, such as assets, asset models, properties, and hierarchies. All such objects have unique identifiers that you can use to retrieve, update, and delete them. 

 AWS IoT SiteWise has different options for customers for ID creation. AWS IoT SiteWise generates one for you by default at object creation time. Users can also provide their own IDs to your objects. 

**Topics**
+ [

## Work with object UUIDs
](#object-uuids)
+ [

## Use external IDs
](#external-ids)

## Work with object UUIDs


 Every persistent object in AWS IoT SiteWise has a [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) to identify it. For example, asset models have an asset model ID, assets have an asset ID, and so on. This ID is assigned at the time that you create the object, and remains unchanged for the object's lifetime. 

 When you create a new object, AWS IoT SiteWise generates a unique ID for you by default. You can also provide your own ID at creation time in UUID format. 

**Note**  
UUIDs **must** be globally unique within the AWS Region where it's created, and for the same object type. When AWS IoT SiteWise auto-generates an ID for you, it's always unique. If you choose your own ID, make sure that it's unique.

For example, if you create a new asset model by calling [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html), you can provide your own UUID in the optional `assetModelId` field of the request.

By contrast, if you omit `assetModelId` from the request, AWS IoT SiteWise generates a UUID for the new asset model.

## Use external IDs


To define your own ID in some format other than UUID, you can assign an *external ID*. For example, you can do this if you reuse an ID that you're using in a system that's not AWS, or to be more human-readable. External IDs have a more flexible format. You can use them to reference your objects in AWS IoT SiteWise API operations where you would otherwise use the UUID. 

 Like the UUIDs, each external ID must be unique within its context. For example, you can't have two asset models with the same external ID. Also, like the UUIDs, an object can only have one external ID in its lifetime, which can't change. 

### Differences between external IDs and UUIDs


External IDs differ from UUIDs in the following ways:
+ Every object has a UUID, but external IDs are optional.
+ AWS IoT SiteWise never generates external IDs. You provide these yourself.
+ If the object does not already have one, you can assign an external ID at any time.

### Format of external IDs


A valid external ID has the following properties:
+ Is between 2 and 128 characters long.
+ The first and last characters must be alphanumeric (A-Z, a-z, 0-9).
+ Characters other than first and last must either be alphanumeric, or else one of the following: `_-.:`

For example, an external ID must conform to the following regular expression:

`[a-zA-Z0-9][a-zA-Z0-9_\-.:]*[a-zA-Z0-9]+`

### Reference objects with external IDs


In many places that you could reference an object using its UUID, you can use its external ID instead, if it has one. To do so, append the external ID to the string `externalId:`.

For example, suppose you have an asset model whose UUID (asset model ID) is `a1b2c3d4-5678-90ab-cdef-11111EXAMPLE`, which also has the external ID `myExternalId`. Call [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) to get details about it. You could use either of the following as the value of `assetModelId`:
+ With the asset model ID (UUID) itself: `a1b2c3d4-5678-90ab-cdef-11111EXAMPLE`
+ With the external ID: `externalId:myExternalId`

```
aws iotsitewise describe-asset-model --asset-model-id a1b2c3d4-5678-90ab-cdef-11111EXAMPLE
aws iotsitewise describe-asset-model --asset-model-id externalId:myExternalId
```

**Note**  
The `externalId:` prefix is not, itself, part of the external ID. You only need to provide the prefix when you supply an external ID to an API operation that accepts either UUIDs or external IDs. For example, supply the prefix when you query or update an existing object.  
When you define an external ID for an object, such as when you create an asset model, don't include the prefix.

You can use external IDs in place of UUIDs in this fashion for many API operations in AWS IoT SiteWise, but not all. For example, the [GetAssetPropertyValue](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_GetAssetPropertyValue.html), **must** use UUIDs; it doesn't support external ID usage.

To determine whether a particular API operation supports this usage, consult the [API Reference](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_Operations.html).

# Create asset models, component models, and interfaces for AWS IoT SiteWise
Create models

AWS IoT SiteWise asset models, component models, and interfaces drive standardization of your industrial data. Asset models define the overall asset, such as a wind turbine or a manufacturing line. Component models represent the individual components that make up the asset, such as blades, generators, or sensors. Interfaces enforce standards across different asset models. By creating these models, you can organize and structure your asset data in a way that reflects the real-world relationships and hierarchies of your industrial equipment, making it easier to monitor, analyze, and maintain.

An asset model or component model contains a name, description, asset properties, and (optionally) custom composite models that group properties together, or that reference component models for subassemblies. 

In AWS IoT SiteWise, you can create asset models, component models, and interfaces to represent the structure and properties of your industrial assets and their components. 
+ You use an **asset model** to create assets. In addition to the features listed above, an asset model can also contain hierarchy definitions that define relationships among assets.
+ A **component model** represents a subassembly within an asset model or another component model. When you create a component model, you can add references to it in asset models and in other component models. However, you can't create assets directly from component models.
+ An **interface** enforces standards across different asset models. Interfaces define common properties, metrics, and hierarchies that must be implemented by asset models. You can't create assets directly from interfaces, but they help ensure consistency across similar asset types.

After you create an asset model or component model, you can create custom composite models for it to group properties together or to reference existing component models. You can also link interfaces to asset models to enforce standardization.

For details about how to create asset models, component models, and interfaces, see the following sections.

**Topics**
+ [

# Create asset models in AWS IoT SiteWise
](create-asset-models.md)
+ [

# Create component models
](create-component-models.md)
+ [

# Define data properties
](asset-properties.md)
+ [

# Create custom composite models (components)
](create-custom-composite-models.md)

# Create asset models in AWS IoT SiteWise


AWS IoT SiteWise asset models drive standardization of your industrial data. An asset model contains a name, description, asset properties, and asset hierarchy definitions. For example, you can define a wind turbine model with temperature, rotations per minute (RPM), and power properties. Then, you can define a wind farm model with a net power output property and a wind turbine hierarchy definition.

**Note**  
We recommend that you model your operation starting with the lowest-level nodes. For example, create your wind turbine model before you create your wind farm model. Asset hierarchy definitions contain references to existing asset models. With this approach, you can define asset hierarchies as you create your models.
Asset models can't contain other asset models. If you must define a model that you can reference as a subassembly within another model, you should create a component--> model instead. For more information, see [Create component models](create-component-models.md).

The following sections describe how to use the AWS IoT SiteWise console or API to create asset models. The following sections also describe the different types of asset properties and asset hierarchies that you can use to create models.

**Topics**
+ [

## Create an asset model (console)
](#create-asset-model-console)
+ [

## Create an asset model (AWS CLI)
](#create-asset-model-cli)
+ [

## Example asset models
](#asset-model-examples)
+ [

# Define asset model hierarchies
](define-asset-hierarchies.md)

## Create an asset model (console)


You can use the AWS IoT SiteWise console to create an asset model. The AWS IoT SiteWise console provides various features, such as formula auto completion, that can help you define valid asset models.

**To create an asset model (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose **Create asset model**.

1. On the **Create model** page, do the following:

   1. Enter a **Name** for the asset model, such as **Wind Turbine** or **Wind Turbine Model**. This name must be unique across all models in your account in this Region.

   1. (Optional) Add an **External ID** for the model. This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

   1. (Optional) Add **Measurement definitions** for the model. Measurements represent data streams from your equipment. For more information, see [Define data streams from equipment (measurements)](measurements.md).

   1. (Optional) Add **Transform definitions** for the model. Transforms are formulas that map data from one form to another. For more information, see [Transform data (transforms)](transforms.md).

   1. (Optional) Add **Metric definitions** for the model. Metrics are formulas that aggregate data over time intervals. Metrics can input data from associated assets, so that you can calculate values that represent your operation or a subset of your operation. For more information, see [Aggregate data from properties and other assets (metrics)](metrics.md). 

   1. (Optional) Add **Hierarchy definitions** for the model. Hierarchies are relationships between assets. For more information, see [Define asset model hierarchies](define-asset-hierarchies.md).

   1. (Optional) Add tags for the asset model. For more information, see [Tag your AWS IoT SiteWise resources](tag-resources.md).

   1. Choose **Create model**.

   When you create an asset model, the AWS IoT SiteWise console navigates to the new model's page. On this page, you can see the model's **Status**, which is initially **CREATING**. This page automatically updates, so you can wait for the model's status to update.
**Note**  
The asset model creation process can take up to a few minutes for complex models. After the asset model status is **ACTIVE**, you can use the asset model to create assets. For more information, see [Asset and model states](asset-and-model-states.md).

1. (Optional) After you create your asset model, you can configure your asset model for the edge. For more information about SiteWise Edge, see [Configure edge capabilities on AWS IoT SiteWise Edge](edge-data-collection-and-processing.md). 

   1. On the model page, choose **Configure for Edge**.
**Note**  
The data processing pack (DPP) feature is no longer availabke to new customers. Existing customers can continue to use the service as normal. For more information, see [Data processing pack availability change](https://docs.aws.amazon.com/iot-sitewise/latest/appguide/iotsitewise-dpp-availability-change.html).

   1. On the model configuration page, choose the edge configuration for your model. This controls where AWS IoT SiteWise can compute and store properties associated with this asset model. For more information about configuring your model for the edge, see [Set up an OPC UA source in SiteWise Edge](configure-opcua-source.md).

   1. For **Custom edge configuration**, choose the location that you want AWS IoT SiteWise to compute and store each of your asset model properties.
**Note**  
Transforms and metrics that are associated must be configured for the same location. For more information about configuring your model for the edge, see [Set up an OPC UA source in SiteWise Edge](configure-opcua-source.md).

   1. Choose **Save**. On the model page, your **Edge configuration** should now be **Configured**.

## Create an asset model (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to create an asset model.

Use the [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html) operation to create an asset model with properties and hierarchies. This operation expects a payload with the following structure.

```
{
  "assetModelType": "ASSET_MODEL",
  "assetModelName": "String",
  "assetModelDescription": "String",
  "assetModelProperties": Array of AssetModelProperty,
  "assetModelHierarchies": Array of AssetModelHierarchyDefinition
}
```

**To create an asset model (AWS CLI)**

1. Create a file called `asset-model-payload.json` and then copy the following JSON object into the file.

   ```
   {
     "assetModelType": "ASSET_MODEL",
     "assetModelName": "",
     "assetModelDescription": "",
     "assetModelProperties": [
   
     ],
     "assetModelHierarchies": [
   
     ],
     "assetModelCompositeModels": [
   
     ]
   }
   ```

1. Use your preferred JSON text editor to edit the `asset-model-payload.json` file for the following:

   1. Enter a name (`assetModelName`) for the asset model, such as **Wind Turbine** or **Wind Turbine Model**. This name must be unique across all asset models and component models in your account in this AWS Region.

   1. (Optional) Enter an external ID (`assetModelExternalId`) for the asset model. This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

   1. (Optional) Enter a description (`assetModelDescription`) for the asset model, or remove the `assetModelDescription` key-value pair.

   1. (Optional) Define asset properties (`assetModelProperties`) for the model. For more information, see [Define data properties](asset-properties.md).

   1. (Optional) Define asset hierarchies (`assetModelHierarchies`) for the model. For more information, see [Define asset model hierarchies](define-asset-hierarchies.md).

   1. (Optional) Define alarms for the model. Alarms monitor other properties so that you can identify when equipment or processes require attention. Each alarm definition is a composite model (`assetModelCompositeModels`) that standardizes the set of properties that the alarm uses. For more information, see [Monitor data with alarms in AWS IoT SiteWise](industrial-alarms.md) and [Define alarms on asset models in AWS IoT SiteWise](define-alarms.md).

   1. (Optional) Add tags (`tags`) for the asset model. For more information, see [Tag your AWS IoT SiteWise resources](tag-resources.md).

1. Run the following command to create an asset model from the definition in the JSON file.

   ```
   aws iotsitewise create-asset-model --cli-input-json file://asset-model-payload.json
   ```

   The operation returns a response that contains the `assetModelId` that you refer to when creating an asset. The response also contains the state of the model (`assetModelStatus.state`), which is initially `CREATING`. The asset model's status is `CREATING` until the changes propagate.
**Note**  
The asset model creation process can take up to a few minutes for complex models. To check the current status of your asset model, use the [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation by specifying the `assetModelId`. After the asset model status is `ACTIVE`, you can use the asset model to create assets. For more information, see [Asset and model states](asset-and-model-states.md).

1. (Optional) Create custom composite models for your asset model. With custom composite models, you can group properties within the model, or include a subassembly by referencing a component model. For more information, see [Create custom composite models (components)](create-custom-composite-models.md).

## Example asset models


This section contains example asset models definitions that you can use to create asset models with the AWS CLI and AWS IoT SiteWise SDKs. These asset models represent a wind turbine and a wind farm. Wind turbine assets ingest raw sensor data and calculate values such as power and average wind speed. Wind farm assets calculate values such as total power for all wind turbines in the wind farm.

**Topics**
+ [

### Wind turbine asset model
](#example-wind-turbine)
+ [

### Wind farm asset model
](#example-wind-farm)

### Wind turbine asset model


The following asset model represents a turbine in a wind farm. The wind turbine ingests sensor data to calculate values such as power and average wind speed.

**Note**  
This example model resembles the wind turbine model from the AWS IoT SiteWise demo. For more information, see [Use the AWS IoT SiteWise demo](getting-started-demo.md).

```
{
  "assetModelType": "ASSET_MODEL",
  "assetModelName": "Wind Turbine Asset Model",
  "assetModelDescription": "Represents a turbine in a wind farm.",
  "assetModelProperties": [
    {
      "name": "Location",
      "dataType": "STRING",
      "type": {
        "attribute": {
          "defaultValue": "Renton"
        }
      }
    },
    {
      "name": "Make",
      "dataType": "STRING",
      "type": {
        "attribute": {
          "defaultValue": "Amazon"
        }
      }
    },
    {
      "name": "Model",
      "dataType": "INTEGER",
      "type": {
        "attribute": {
          "defaultValue": "500"
        }
      }
    },
    {
      "name": "Torque (KiloNewton Meter)",
      "dataType": "DOUBLE",
      "unit": "kNm",
      "type": {
        "measurement": {}
      }
    },
    {
      "name": "Wind Direction",
      "dataType": "DOUBLE",
      "unit": "Degrees",
      "type": {
        "measurement": {}
      }
    },
    {
      "name": "RotationsPerMinute",
      "dataType": "DOUBLE",
      "unit": "RPM",
      "type": {
        "measurement": {}
      }
    },
    {
      "name": "Wind Speed",
      "dataType": "DOUBLE",
      "unit": "m/s",
      "type": {
        "measurement": {}
      }
    },
    {
      "name": "RotationsPerSecond",
      "dataType": "DOUBLE",
      "unit": "RPS",
      "type": {
        "transform": {
          "expression": "rpm / 60",
          "variables": [
            {
              "name": "rpm",
              "value": {
                "propertyId": "RotationsPerMinute"
              }
            }
          ]
        }
      }
    },
    {
      "name": "Overdrive State",
      "dataType": "DOUBLE",
      "type": {
        "transform": {
          "expression": "gte(torque, 3)",
          "variables": [
            {
              "name": "torque",
              "value": {
                "propertyId": "Torque (KiloNewton Meter)"
              }
            }
          ]
        }
      }
    },
    {
      "name": "Average Power",
      "dataType": "DOUBLE",
      "unit": "Watts",
      "type": {
        "metric": {
          "expression": "avg(torque) * avg(rps) * 2 * 3.14",
          "variables": [
            {
              "name": "torque",
              "value": {
                "propertyId": "Torque (Newton Meter)"
              }
            },
            {
              "name": "rps",
              "value": {
                "propertyId": "RotationsPerSecond"
              }
            }
          ],
          "window": {
            "tumbling": {
              "interval": "5m"
            }
          }
        }
      }
    },
    {
      "name": "Average Wind Speed",
      "dataType": "DOUBLE",
      "unit": "m/s",
      "type": {
        "metric": {
          "expression": "avg(windspeed)",
          "variables": [
            {
              "name": "windspeed",
              "value": {
                "propertyId": "Wind Speed"
              }
            }
          ],
          "window": {
            "tumbling": {
              "interval": "5m"
            }
          }
        }
      }
    },
    {
      "name": "Torque (Newton Meter)",
      "dataType": "DOUBLE",
      "unit": "Nm",
      "type": {
        "transform": {
          "expression": "knm * 1000",
          "variables": [
            {
              "name": "knm",
              "value": {
                "propertyId": "Torque (KiloNewton Meter)"
              }
            }
          ]
        }
      }
    },
    {
      "name": "Overdrive State Time",
      "dataType": "DOUBLE",
      "unit": "Seconds",
      "type": {
        "metric": {
          "expression": "statetime(overdrive_state)",
          "variables": [
            {
              "name": "overdrive_state",
              "value": {
                "propertyId": "Overdrive State"
              }
            }
          ],
          "window": {
            "tumbling": {
              "interval": "5m"
            }
          }
        }
      }
    }
  ],
  "assetModelHierarchies": []
}
```

### Wind farm asset model


The following asset model represents a wind farm that comprises multiple wind turbines. This asset model defines a [hierarchy](define-asset-hierarchies.md) to the wind turbine model. This lets the wind farm calculate values (such as average power) from data for all wind turbines in the wind farm.

**Note**  
This example model resembles the wind farm model from the AWS IoT SiteWise demo. For more information, see [Use the AWS IoT SiteWise demo](getting-started-demo.md).

This asset model depends on the [Wind turbine asset model](#example-wind-turbine). Replace the `propertyId` and `childAssetModelId` values with those from an existing wind turbine asset model.

```
{
  "assetModelName": "Wind Farm Asset Model",
  "assetModelDescription": "Represents a wind farm.",
  "assetModelProperties": [
    {
      "name": "Code",
      "dataType": "INTEGER",
      "type": {
        "attribute": {
          "defaultValue": "300"
        }
      }
    },
    {
      "name": "Location",
      "dataType": "STRING",
      "type": {
        "attribute": {
          "defaultValue": "Renton"
        }
      }
    },
    {
      "name": "Reliability Manager",
      "dataType": "STRING",
      "type": {
        "attribute": {
          "defaultValue": "Mary Major"
        }
      }
    },
    {
      "name": "Total Overdrive State Time",
      "dataType": "DOUBLE",
      "unit": "seconds",
      "type": {
        "metric": {
          "expression": "sum(overdrive_state_time)",
          "variables": [
            {
              "name": "overdrive_state_time",
              "value": {
                "propertyId": "ID of Overdrive State Time property in Wind Turbine Asset Model",
                "hierarchyId": "Turbine Asset Model"
              }
            }
          ],
          "window": {
            "tumbling": {
              "interval": "5m"
            }
          }
        }
      }
    },
    {
      "name": "Total Average Power",
      "dataType": "DOUBLE",
      "unit": "Watts",
      "type": {
        "metric": {
          "expression": "sum(turbine_avg_power)",
          "variables": [
            {
              "name": "turbine_avg_power",
              "value": {
                "propertyId": "ID of Average Power property in Wind Turbine Asset Model",
                "hierarchyId": "Turbine Asset Model"
              }
            }
          ],
          "window": {
            "tumbling": {
              "interval": "5m"
            }
          }
        }
      }
    }
  ],
  "assetModelHierarchies": [
    {
      "name": "Turbine Asset Model",
      "childAssetModelId": "ID of Wind Turbine Asset Model"
    }
  ]
}
```

# Define asset model hierarchies


You can define asset model hierarchies to create logical associations between the asset models in your industrial operation. For example, you can define a wind farm composed of onshore and offshore wind farms. An onshore wind farm contains a turbine and onshore location. An offshore wind farm contains a turbine and offshore location.

![\[AWS IoT SiteWise wind farm hierarchies between asset models.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/asset-model-hierarchies.png)


When you associate a child asset model to a parent asset model through a hierarchy, the parent asset model's metrics can input data from the child asset model's metrics. You can use asset model hierarchies and metrics to calculate statistics that provide insight to your operation or a subset of your operation. For more information, see [Aggregate data from properties and other assets (metrics)](metrics.md).

Each hierarchy defines a relationship between a parent asset model and a child asset model. In a parent asset model, you can define multiple hierarchies to the same child asset model. For example, if you have two different types of wind turbines in your wind farms, where all wind turbines are represented by the same asset model, you can define a hierarchy for each type. Then, you can define metrics in the wind farm model to calculate independent and combined statistics for each type of wind turbine.

A parent asset model can be associated with multiple child asset models. For example, if you have an onshore wind farm and an offshore wind farm that are represented by two different asset models, you can associate these asset models with the same parent wind farm asset model. 

A child asset model can also be associated with multiple parent asset models. For example, if you have two different types of wind farms, where all wind turbines are represented by the same asset model, you can associate the wind turbine asset model with different wind farm asset models. 

**Note**  
When you define an asset model hierarchy, the child asset model must be `ACTIVE` or have a previous `ACTIVE` version. For more information, see [Asset and model states](asset-and-model-states.md).

After you define hierarchical asset models and create assets, you can associate the assets to complete the parent-child relationship. For more information, see [Create assets for asset models in AWS IoT SiteWise](create-assets.md) and [Associate and disassociate assets](add-associated-assets.md).

**Topics**
+ [

## Define asset model hierarchies (console)
](#define-asset-hierarchies-console)
+ [

## Define asset hierarchies (AWS CLI)
](#define-asset-hierarchies-cli)

## Define asset model hierarchies (console)


When you define a hierarchy for an asset model in the AWS IoT SiteWise console, you specify the following parameters:
+ **Hierarchy name** – The hierarchy's name, such as **Wind Turbines**.
+ **Hierarchy model** – The child asset model.
+ **Hierarchy External ID** (Optional) – This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

For more information, see [Create an asset model (console)](create-asset-models.md#create-asset-model-console).

## Define asset hierarchies (AWS CLI)


When you define a hierarchy for an asset model with the AWS IoT SiteWise API, you specify the following parameters:
+ `name` – The hierarchy's name, such as **Wind Turbines**.
+ `childAssetModelId` – The ID or the external ID of the child asset model for the hierarchy. You can use the [ListAssetModels](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ListAssetModels.html) operation to find the ID of an existing asset model.

**Example hierarchy definition**  
The following example demonstrates an asset model hierarchy that represents a wind farm's relationship to wind turbines. This object is an example of an [AssetModelHierarchy](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssetModelHierarchy.html). For more information, see [Create an asset model (AWS CLI)](create-asset-models.md#create-asset-model-cli).  

```
{
  ...
  "assetModelHierarchies": [
    {
      "name": "Wind Turbines",
      "childAssetModelId": "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE"
    },
  ]
}
```

# Create component models
Create component models

Use AWS IoT SiteWise component models to define subassemblies that you can reference from asset models or other component models. In this way, you can re-use the definition of the component across multiple other models, or multiple times within the same model.

The process of defining a component model is very similar to defining an asset model. Like an asset model, a component model has a name, description, and asset properties. However, component models can't include asset hierarchy definitions, since component models themselves can't be used to create assets directly. Component models also can't define alarms.

For example, you can define a component for a servo motor with motor temperature, encoder temperature, and insulation resistance properties. Then, you can define an asset model for equipment that contains servo motors, such as a CNC machine.

**Note**  
We recommend that you model your operation starting with the lowest-level nodes. For example, create your servo motor component before you create your CNC machine's asset model. Asset models contain references to existing component models.
You can't create an asset directly from a component model. To create an asset that uses your component, you must create an asset model for your asset. Then, you create a custom composite model for it that references your component. For more information about creating asset models, see [Create asset models in AWS IoT SiteWise](create-asset-models.md) For more information about creating custom composite models, see [Create custom composite models (components)](create-custom-composite-models.md).

The following sections describe how to use the AWS IoT SiteWise API to create component models.

**Topics**
+ [

## Create a component model (AWS CLI)
](#create-component-model-cli)
+ [

## Example component model
](#component-model-example)

## Create a component model (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to create a component model.

Use the [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html) operation to create a component model with properties. This operation expects a payload with the following structure:

```
{
  "assetModelType": "COMPONENT_MODEL",
  "assetModelName": "String",
  "assetModelDescription": "String",
  "assetModelProperties": Array of AssetModelProperty,
}
```

**To create a component model (AWS CLI)**

1. Create a file called `component-model-payload.json` and then copy the following JSON object into the file:

   ```
   {
     "assetModelType": "COMPONENT_MODEL",
     "assetModelName": "",
     "assetModelDescription": "",
     "assetModelProperties": [
   
     ]
   }
   ```

1. Use your preferred JSON text editor to edit the `component-model-payload.json` file for the following:

   1. Enter a name (`assetModelName`) for the component model, such as **Servo Motor** or **Servo Motor Model**. This name must be unique across all asset models and component models in your account in this AWS Region.

   1. (Optional) Enter an external ID (`assetModelExternalId`) for the component model. This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

   1. (Optional) Enter a description (`assetModelDescription`) for the asset model, or remove the `assetModelDescription` key-value pair.

   1. (Optional) Define asset properties (`assetModelProperties`) for the component model. For more information, see [Define data properties](asset-properties.md).

   1. (Optional) Add tags (`tags`) for the asset model. For more information, see [Tag your AWS IoT SiteWise resources](tag-resources.md).

1. Run the following command to create a component model from the definition in the JSON file.

   ```
   aws iotsitewise create-asset-model --cli-input-json file://component-model-payload.json
   ```

   The operation returns a response that contains the `assetModelId` that you refer to when adding a reference to your component model in an asset model or another component model. The response also contains the state of the model (`assetModelStatus.state`), which is initially `CREATING`. The component model's status is `CREATING` until the changes propagate.
**Note**  
The component model creation process can take up to a few minutes for complex models. To check the current status of your component model, use the [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation by specifying the `assetModelId`. After the component model status is `ACTIVE`, you can add references to your component model in asset models or other component models. For more information, see [Asset and model states](asset-and-model-states.md).

1. (Optional) Create custom composite models for your component model. With custom composite models, you can group properties within the model, or to include a subassembly by referencing another component model. For more information, see [Create custom composite models (components)](create-custom-composite-models.md). 

## Example component model


This section contains an example component model definition that you can use to create a component model with the AWS CLI and AWS IoT SiteWise SDKs. This component model represents a servo motor that can be used within another piece of equipment, such as a CNC machine.

**Topics**
+ [

### Servo motor component model
](#example-servo-motor)

### Servo motor component model


The following component model represents a servo motor that can be used within equipment such as CNC machines. The servo motor provides various measurements, such as temperatures and electrical resistance. These measurements are available as properties on assets created from asset models that reference the servo motor component model.

```
{
    "assetModelName": "ServoMotor",
    "assetModelType": "COMPONENT_MODEL",
    "assetModelProperties": [
        {
            "dataType": "DOUBLE",
            "name": "Servo Motor Temperature",
            "type": {
            "measurement": {}
            },
            "unit": "Celsius"
        },
        {
            "dataType": "DOUBLE",
            "name": "Spindle speed",
            "type": {
            "measurement": {}
            },
            "unit": "rpm"
        }
    ]
}
```

# Define data properties


*Asset properties* are the structures within each asset that contain asset data. Asset properties can be any of the following types:
+ **Attributes** – An asset's generally static properties, such as device manufacturer or geographic region. For more information, see [Define static data (attributes)](attributes.md).
+ **Measurements** – An asset's raw device's sensor data streams, such as timestamped rotation speed values or timestamped temperature values in Celsius. A measurement is defined by a data stream alias. For more information, see [Define data streams from equipment (measurements)](measurements.md).
+ **Transforms** – An asset's transformed time-series values, such as timestamped temperature values in Fahrenheit. A transform is defined by an expression and the variables to consume with that expression. For more information, see [Transform data (transforms)](transforms.md).
+ **Metrics** – An asset's data aggregated over a specified time interval, such as the hourly average temperature. A metric is defined by a time interval, an expression, and the variables to consume with that expression. Metric expressions can input associated assets' metric properties, so that you can calculate metrics that represent your operation or a subset of your operation. For more information, see [Aggregate data from properties and other assets (metrics)](metrics.md).

For more information, see [Create asset models in AWS IoT SiteWise](create-asset-models.md).

For an example of how to use measurements, transforms, and metrics to calculate Overall Equipment Effectiveness (OEE), see [Calculate OEE in AWS IoT SiteWise](calculate-oee.md).

**Topics**
+ [

# Define static data (attributes)
](attributes.md)
+ [

# Define data streams from equipment (measurements)
](measurements.md)
+ [

# Transform data (transforms)
](transforms.md)
+ [

# Aggregate data from properties and other assets (metrics)
](metrics.md)
+ [

# Use formula expressions
](formula-expressions.md)

# Define static data (attributes)
Define static data

*Asset attributes* represent information that is generally static, such as device manufacturer or geographic location. Each asset that you create from an asset model contains the attributes of that model.

**Topics**
+ [

## Define attributes (console)
](#define-attributes-console)
+ [

## Define attributes (AWS CLI)
](#define-attributes-cli)

## Define attributes (console)


When you define an attribute for an asset model in the AWS IoT SiteWise console, you specify the following parameters:
+ <a name="asset-property-name-console"></a>**Name** – The property's name.
+ **Default value** – (Optional) The default value for this attribute. Assets created from the model have this value for the attribute. For more information about how to override the default value in an asset created from a model, see [Update attribute values](update-attribute-values.md).
+ <a name="asset-property-data-type-console"></a>**Data type** – The property's data type, which is one of the following:
  + **String** – A string with up to 1024 bytes.
  + **Integer** – A signed 32-bit integer with range [-2,147,483,648, 2,147,483,647].
  + **Double** – A floating point number with range [-10^100, 10^100] and IEEE 754 double precision.
  + **Boolean** – `true` or `false`.
+ **External ID** – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

For more information, see [Create an asset model (console)](create-asset-models.md#create-asset-model-console).

## Define attributes (AWS CLI)


When you define an attribute for an asset model with the AWS IoT SiteWise API, you specify the following parameters:
+ <a name="asset-property-name-cli"></a>`name` – The property's name.
+ `defaultValue` – (Optional) The default value for this attribute. Assets created from the model have this value for the attribute. For more information about how to override the default value in an asset created from a model, see [Update attribute values](update-attribute-values.md).
+ <a name="asset-property-data-type-cli"></a>`dataType` – The property's data type, which is one of the following:
  + `STRING` – A string with up to 1024 bytes.
  + `INTEGER` – A signed 32-bit integer with range [-2,147,483,648, 2,147,483,647].
  + `DOUBLE` – A floating point number with range [-10^100, 10^100] and IEEE 754 double precision.
  + `BOOLEAN` – `true` or `false`.
+ `externalId` – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

**Example attribute definition**  
The following example demonstrates an attribute that represents an asset's model number with a default value. This object is an example of an [AssetModelProperty](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssetModelProperty.html) that contains an [Attribute](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_Attribute.html). You can specify this object as a part of the [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html) request payload to create an attribute property. For more information, see [Create an asset model (AWS CLI)](create-asset-models.md#create-asset-model-cli).  

```
{
...
"assetModelProperties": [
{
  "name": "Model number",
  "dataType": "STRING",
  "type": {
    "attribute": {
      "defaultValue": "BLT123"
    }
  }
}
],
...
}
```

# Define data streams from equipment (measurements)
Define data streams from equipment (measurement)

A *measurement* represents a device's raw sensor data stream, such as timestamped temperature values or timestamped rotations per minute (RPM) values.

**Topics**
+ [

## Define measurements (console)
](#define-measurements-console)
+ [

## Define measurements (AWS CLI)
](#define-measurements-cli)

## Define measurements (console)


When you define a measurement for an asset model in the AWS IoT SiteWise console, you specify following parameters:
+ <a name="asset-property-name-console"></a>**Name** – The property's name.
+ <a name="asset-property-unit-console"></a>**Unit** – (Optional) The scientific unit for the property, such as mm or Celsius.
+ <a name="asset-property-data-type-console"></a>**Data type** – The property's data type, which is one of the following:
  + **String** – A string with up to 1024 bytes.
  + **Integer** – A signed 32-bit integer with range [-2,147,483,648, 2,147,483,647].
  + **Double** – A floating point number with range [-10^100, 10^100] and IEEE 754 double precision.
  + **Boolean** – `true` or `false`.
+ **External ID** – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

For more information, see [Create an asset model (console)](create-asset-models.md#create-asset-model-console).

## Define measurements (AWS CLI)


When you define a measurement for an asset model with the AWS IoT SiteWise API, you specify the following parameters:
+ <a name="asset-property-name-cli"></a>`name` – The property's name.
+ <a name="asset-property-data-type-cli"></a>`dataType` – The property's data type, which is one of the following:
  + `STRING` – A string with up to 1024 bytes.
  + `INTEGER` – A signed 32-bit integer with range [-2,147,483,648, 2,147,483,647].
  + `DOUBLE` – A floating point number with range [-10^100, 10^100] and IEEE 754 double precision.
  + `BOOLEAN` – `true` or `false`.
+ <a name="asset-property-unit-cli"></a>`unit` – (Optional) The scientific unit for the property, such as mm or Celsius.
+ `externalId` – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

**Example measurement definition**  
The following example demonstrates a measurement that represents an asset's temperature sensor readings. This object is an example of an [AssetModelProperty](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssetModelProperty.html) that contains a [Measurement](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_Measurement.html). You can specify this object as a part of the [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html) request payload to create a measurement property. For more information, see [Create an asset model (AWS CLI)](create-asset-models.md#create-asset-model-cli).  
The [Measurement](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_Measurement.html) structure is an empty structure when you define an asset model because you later configure each asset to use unique device data streams. For more information about how to connect an asset's measurement property to a device's sensor data stream, see [Manage data streams for AWS IoT SiteWise](manage-data-streams.md).  

```
{
      ...
      "assetModelProperties": [
      {
          "name": "Temperature C",
          "dataType": "DOUBLE",
          "type": {
              "measurement": {}
          },
          "unit": "Celsius"
      }
  ],
      ...
}
```

# Transform data (transforms)
Transform data (transforms)

*Transforms* are mathematical expressions that map asset properties' data points from one form to another. A transform expression consists of asset property variables, literals, operators, and functions. The transformed data points hold a one-to-one relationship with the input data points. AWS IoT SiteWise calculates a new transformed data point each time any of the input properties receives a new data point.

**Note**  
For property updates with the same timestamp, output values may be overwritten by updates from other incoming properties.

For example, if your asset has a temperature measurement stream named `Temperature_C` with units in Celsius, you can convert each data point to Fahrenheit with the formula `Temperature_F = 9/5 * Temperature_C + 32`. Each time AWS IoT SiteWise receives a data point in the `Temperature_C` measurement stream, the corresponding `Temperature_F` value is calculated within a few seconds and available as the `Temperature_F` property.

If your transform contains more than one variable, the data point that arrives earlier initiates the computation immediately. Consider an example where a parts manufacturer uses a transform to monitor product quality. Using a different standard based on the part type, the manufacturer uses the following measurements to represent the process:
+ `Part_Number` - A string that identifies the part type.
+ `Good_Count` - An integer that increases by one if the part meets the standard.
+ `Bad_Count` - An integer that increases by one if the part doesn't meet the standard.

The manufacturer also creates a transform, `Quality_Monitor`, that equals ` if(eq(Part_Number, "BLT123") and (Bad_Count / (Good_Count + Bad_Count) > 0.1), "Caution", "Normal")`.

This transform monitors the percentage of bad parts produced for a specific part type. If the part number is BLT123 and the percentage of bad parts exceeds 10 percent (0.1), the transform returns `"Caution"`. Otherwise, the transform returns `"Normal"`.

**Note**  
If `Part_Number` receives a new data point before other measurements, the `Quality_Monitor` transform uses the new `Part_Number` value and the latest `Good_Count` and `Bad_Count` values. To avoid errors, reset `Good_Count` and `Bad_Count` before the next manufacturing run.
Use [metrics](metrics.md) if you want to evaluate expressions only after all variables receive new data points.

**Topics**
+ [

## Define transforms (console)
](#define-transforms-console)
+ [

## Define transforms (AWS CLI)
](#define-transform-cli)

## Define transforms (console)


When you define a transform for an asset model in the AWS IoT SiteWise console, you specify following parameters:
+ <a name="asset-property-name-console"></a>**Name** – The property's name.
+ <a name="asset-property-unit-console"></a>**Unit** – (Optional) The scientific unit for the property, such as mm or Celsius.
+ **Data type** – The data type of the transform, which can be **Double** or **String**.
+ **External ID** – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.
+ **Formula** – The transform expression. Transform expressions can't use aggregation functions or temporal functions. To open the auto complete feature, start typing or press the down arrow key. For more information, see [Use formula expressions](formula-expressions.md).
**Important**  <a name="transform-input-rules"></a>
Transforms can input properties that are integer, double, Boolean, or string type. Booleans convert to `0` (false) and `1` (true).  
Transforms must input one or more properties that aren't attributes and any number of attribute properties. AWS IoT SiteWise calculates a new transformed data point each time the input property that isn't an attribute receives a new data point. New attribute values don't launch transform updates. The same request rate for asset property data API operations applies for transform computation results.  
<a name="formula-output-rules"></a>Formula expressions can only output double or string values. Nested expressions can output other data types, such as strings, but the formula as a whole must evaluate to a number or string. You can use the [jp function](expression-string-functions.md#jp-definition) to convert a string to a number. The Boolean value must be 1 (true) or 0 (false). For more information, see [Undefined, infinite, and overflow values](expression-tutorials.md#undefined-values).

For more information, see [Create an asset model (console)](create-asset-models.md#create-asset-model-console).

## Define transforms (AWS CLI)


When you define a transform for an asset model with the AWS IoT SiteWise API, you specify the following parameters:
+ <a name="asset-property-name-cli"></a>`name` – The property's name.
+ <a name="asset-property-unit-cli"></a>`unit` – (Optional) The scientific unit for the property, such as mm or Celsius.
+ `dataType` – The data type of the transform, which must be `DOUBLE` or `STRING`.
+ `externalId` – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.
+ `expression` – The transform expression. Transform expressions can't use aggregation functions or temporal functions. For more information, see [Use formula expressions](formula-expressions.md).
+ `variables` – The list of variables that defines the other properties of your asset to use in the expression. Each variable structure contains a simple name to use in the expression and a `value` structure that identifies which property to link to that variable. The `value` structure contains the following information:
  + `propertyId` – The ID of the property from which to input values. You can use the property's name instead of its ID.
**Important**  <a name="transform-input-rules"></a>
Transforms can input properties that are integer, double, Boolean, or string type. Booleans convert to `0` (false) and `1` (true).  
Transforms must input one or more properties that aren't attributes and any number of attribute properties. AWS IoT SiteWise calculates a new transformed data point each time the input property that isn't an attribute receives a new data point. New attribute values don't launch transform updates. The same request rate for asset property data API operations applies for transform computation results.  
<a name="formula-output-rules"></a>Formula expressions can only output double or string values. Nested expressions can output other data types, such as strings, but the formula as a whole must evaluate to a number or string. You can use the [jp function](expression-string-functions.md#jp-definition) to convert a string to a number. The Boolean value must be 1 (true) or 0 (false). For more information, see [Undefined, infinite, and overflow values](expression-tutorials.md#undefined-values).

**Example transform definition**  
The following example demonstrates a transform property that converts an asset's temperature measurement data from Celsius to Fahrenheit. This object is an example of an [AssetModelProperty](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssetModelProperty.html) that contains a [Transform](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_Transform.html). You can specify this object as a part of the [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html) request payload to create a transform property. For more information, see [Create an asset model (AWS CLI)](create-asset-models.md#create-asset-model-cli).  

```
{
...
"assetModelProperties": [
...
{
  "name": "Temperature F",
  "dataType": "DOUBLE",
  "type": {
    "transform": {
      "expression": "9/5 * temp_c + 32",
      "variables": [
        {
          "name": "temp_c",
          "value": {
            "propertyId": "Temperature C"
          }
        }
      ]
    }
  },
  "unit": "Fahrenheit"
}
],
...
}
```

**Example transform definition that contains three variables**  
The following example demonstrates a transform property that returns a warning message (`"Caution"`) if more than 10 percent of the BLT123 parts don't meet the standard. Otherwise, it returns an information message (`"Normal"`).  

```
{
...
"assetModelProperties": [
...
{
"name": "Quality_Monitor",
"dataType": "STRING",
"type": {
    "transform": {
        "expression": "if(eq(Part_Number,"BLT123") and (Bad_Count / (Good_Count + Bad_Count) > 0.1), "Caution", "Normal")",
        "variables": [
            {
                "name": "Part_Number",
                "value": {
                    "propertyId": "Part Number"
                }
            },
            {
                "name": "Good_Count",
                "value": {
                    "propertyId": "Good Count"
                }
            },
            {
                "name": "Bad_Count",
                "value": {
                    "propertyId": "Bad Count"
                }
            }
        ]
    }
}
}
...
}
```

# Aggregate data from properties and other assets (metrics)
Aggregate data (metrics)

Metrics are mathematical expressions that use aggregation functions to process all input data points and output a single data point per specified time interval. For example, a metric can calculate the average hourly temperature from a temperature data stream.

Metrics can input data from associated assets' metrics, so you can calculate statistics that provide insight to your operation or a subset of your operation. For example, a metric can calculate the average hourly temperature across all wind turbines in a wind farm. For more information about how to define associations between assets, see [Define asset model hierarchies](define-asset-hierarchies.md).

Metrics can also input data from other properties without aggregating data over each time interval. If you specify an [attribute](attributes.md) in a formula, AWS IoT SiteWise uses the [latest](expression-temporal-functions.md#latest-definition) value for that attribute when it computes the formula. If you specify a metric in a formula, AWS IoT SiteWise uses the [last](expression-temporal-functions.md#last-definition) value for the time interval over which it computes the formula. This means you can define metrics like `OEE = Availability * Quality * Performance`, where `Availability`, `Quality`, and `Performance` are all other metrics on the same asset model.

AWS IoT SiteWise also automatically computes a set of basic aggregation metrics for all asset properties. To reduce computation costs, you can use these aggregates instead of defining custom metrics for basic computations. For more information, see [Query asset property aggregates in AWS IoT SiteWise](aggregates.md).

**Topics**
+ [

## Define metrics (console)
](#define-metrics-console)
+ [

## Define metrics (AWS CLI)
](#define-metrics-cli)

## Define metrics (console)


When you define a metric for an asset model in the AWS IoT SiteWise console, you specify the following parameters:
+ <a name="asset-property-name-console"></a>**Name** – The property's name.
+ **Data type** – The data type of the transform, which can be **Double** or **String**.
+ **External ID** – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.
+ **Formula** – The metric expression. Metric expressions can use [aggregation functions](expression-aggregation-functions.md) to input data from a property for all associated assets in a hierarchy. Start typing or press the down arrow key to open the auto complete feature. For more information, see [Use formula expressions](formula-expressions.md).
**Important**  <a name="metric-input-rules"></a>
Metrics can only be properties that are integer, double, Boolean, or string type. Booleans convert to `0` (false) and `1` (true).  
If you define any metric input variables in a metric's expression, those inputs must have the same time interval as the output metric.  
<a name="formula-output-rules"></a>Formula expressions can only output double or string values. Nested expressions can output other data types, such as strings, but the formula as a whole must evaluate to a number or string. You can use the [jp function](expression-string-functions.md#jp-definition) to convert a string to a number. The Boolean value must be 1 (true) or 0 (false). For more information, see [Undefined, infinite, and overflow values](expression-tutorials.md#undefined-values).
+ **Time interval** – The metric time interval. <a name="metric-window-info"></a>AWS IoT SiteWise supports the following tumbling window time intervals, where each interval starts when the previous one ends:
  + **1 minute** – <a name="metric-window-1m"></a>1 minute, computed at the end of each minute (12:00:00 AM, 12:01:00 AM, 12:02:00 AM, and so on).
  + **5 minutes** – <a name="metric-window-5m"></a>5 minutes, computed at the end of every five minutes starting on the hour (12:00:00 AM, 12:05:00 AM, 12:10:00 AM, and so on).
  + **15 minutes** – <a name="metric-window-15m"></a>15 minutes, computed at the end of every fifteen minutes starting on the hour (12:00:00 AM, 12:15:00 AM, 12:30:00 AM, and so on).
  + **1 hour** – <a name="metric-window-1h"></a>1 hour (60 minutes), computed at the end of every hour in UTC (12:00:00 AM, 01:00:00 AM, 02:00:00 AM, and so on).
  + **1 day** – <a name="metric-window-1d"></a>1 day (24 hours), computed at the end of every day in UTC (12:00:00 AM Monday, 12:00:00 AM Tuesday, and so on).
  + **1 week** – <a name="metric-window-1w"></a>1 week (7 days), computed at the end of every Sunday in UTC (every 12:00:00 AM Monday).
  + **Custom interval** – You can enter any time interval between a minute and a week.
+ **Offset date** – (Optional) The reference date from which to aggregate data.
+ **Offset time** – (Optional) The reference time from which to aggregate data. The offset time must be between 00:00:00 and 23:59:59.
+ **Offset time zone** – (Optional) The time zone for the offset. If it isn't specified, the default offset time zone is the Universal Coordinated Time (UTC). See the following supported time zones.

### Supported time zones

+ (UTC\$100:00) Universal Coordinated Time
+ (UTC\$101:00) European Central Time
+ (UTC\$102:00) Eastern European
+ (UTC03\$1:00) Eastern African Time
+ (UTC\$104:00) Near East Time
+ (UTC\$105:00) Pakistan Lahore Time
+ (UTC\$105:30) India Standard Time
+ (UTC\$106:00) Bangladesh Standard Time
+ (UTC\$107:00) Vietnam Standard Time
+ (UTC\$108:00) China Taiwan Time
+ (UTC\$109:00) Japan Standard Time
+ (UTC\$109:30) Australia Central Time
+ (UTC\$110:00) Australia Eastern Time
+ (UTC\$111:00) Solomon Standard Time
+ (UTC\$112:00) New Zealand Standard Time
+ (UTC-11:00) Midway Islands Time
+ (UTC-10:00) Hawaii Standard Time
+ (UTC-09:00) Alaska Standard Time
+ (UTC-08:00) Pacific Standard Time
+ (UTC-07:00) Phoenix Standard Time
+ (UTC-06:00) Central Standard Time
+ (UTC-05:00) Eastern Standard Time
+ (UTC-04:00) Puerto Rico and US Virgin Islands Time
+ (UTC-03:00) Argentina Standard Time
+ (UTC-02:00) South Georgia Time
+ (UTC-01:00) Central African Time

**Example custom time interval with an offset (console)**  
The following example shows you how to define a 12-hour time interval with an offset on February 20, 2021, at 6:30:30 PM (PST).  

**To define a custom interval with an offset**

1. For **Time interval**, choose **Custom interval**.

1. For **Time interval**, do one of the following:
   + Enter **12**, and then choose **hours**.
   + Enter **720**, and then choose **minutes**.
   + Enter **43200**, and then choose **seconds**.
**Important**  
The **Time interval** must be an integer regardless of the unit.

1. For **Offset date**, choose **2021/02/20**.

1. For **Offset time**, enter **18:30:30**.

1. For **Offset timezone**, choose **(UTC-08:00) Pacific Standard Time**.
If you create the metric on July 1, 2021, before or at 06:30:30 PM (PST), you get the first aggregation result on July 1, 2021, at 06:30:30 PM (PST). The second aggregation result is on July 2, 2021, at 06:30:30 AM (PST), and so on.

## Define metrics (AWS CLI)


When you define a metric for an asset model with the AWS IoT SiteWise API, you specify the following parameters:
+ <a name="asset-property-name-cli"></a>`name` – The property's name.
+ `dataType` – The data type of the metric, which can be `DOUBLE` or `STRING`.
+ `externalId` – (Optional) This is a user-defined ID. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.
+ `expression` – The metric expression. Metric expressions can use [aggregation functions](expression-aggregation-functions.md) to input data from a property for all associated assets in a hierarchy. For more information, see [Use formula expressions](formula-expressions.md).
+ `window` – The time interval and offset for the metric's tumbling window, where each interval starts when the previous one ends:
  + `interval` – The time interval for the tumbling window. The time interval must be between a minute and a week.
  + `offsets` – The offset for the tumbling window. 

  For more information, see [TumblingWindow](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_TumblingWindow.html) in the *AWS IoT SiteWise API Reference*.  
**Example custom time interval with an offset (AWS CLI)**  

  The following example shows you how to define a 12-hour time interval with an offset on February 20, 2021, at 06:30:30 PM (PST).

  ```
  {
      "window": {
          "tumbling": {
              "interval": "12h",
              "offset": " 2021-07-23T18:30:30-08"
          }
      }
  }
  ```

  If you create the metric on July 1, 2021, before or at 06:30:30 PM (PST), you get the first aggregation result on July 1, 2021, at 06:30:30 PM (PST). The second aggregation result is on July 2, 2021, at 06:30:30 AM (PST), and so on.
+ `variables` – The list of variables that defines the other properties of your asset or child assets to use in the expression. Each variable structure contains a simple name for use in the expression and a `value` structure that identifies which property to link to that variable. The `value` structure contains the following information:
  + `propertyId` – The ID of the property from which to pull values. You can use the property's name instead of its ID if the property is defined in the current model (rather than defined in a model from a hierarchy).
  + `hierarchyId` – (Optional) The ID of the hierarchy from which to query child assets for the property. You can use the hierarchy definition's name instead of its ID. If you omit this value, AWS IoT SiteWise finds the property in the current model.
**Important**  <a name="metric-input-rules"></a>
Metrics can only be properties that are integer, double, Boolean, or string type. Booleans convert to `0` (false) and `1` (true).  
If you define any metric input variables in a metric's expression, those inputs must have the same time interval as the output metric.  
<a name="formula-output-rules"></a>Formula expressions can only output double or string values. Nested expressions can output other data types, such as strings, but the formula as a whole must evaluate to a number or string. You can use the [jp function](expression-string-functions.md#jp-definition) to convert a string to a number. The Boolean value must be 1 (true) or 0 (false). For more information, see [Undefined, infinite, and overflow values](expression-tutorials.md#undefined-values).
+ <a name="asset-property-unit-cli"></a>`unit` – (Optional) The scientific unit for the property, such as mm or Celsius.

**Example metric definition**  
The following example demonstrates a metric property that aggregates an asset's temperature measurement data to calculate maximum hourly temperature in Fahrenheit. This object is an example of an [AssetModelProperty](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssetModelProperty.html) that contains a [Metric](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_Metric.html). You can specify this object as a part of the [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html) request payload to create a metric property. For more information, see [Create an asset model (AWS CLI)](create-asset-models.md#create-asset-model-cli).  

```
{
      ...
      "assetModelProperties": [
      ...
      {
        "name": "Max temperature",
        "dataType": "DOUBLE",
        "type": {
          "metric": {
            "expression": "max(temp_f)",
            "variables": [
              {
                "name": "temp_f",
                "value": {
                  "propertyId": "Temperature F"
                }
              }
            ],
            "window": {
              "tumbling": {
                "interval": "1h"
              }
            }
          }
        },
        "unit": "Fahrenheit"
      }
    ],
    ...
}
```

**Example metric definition that inputs data from associated assets**  
The following example demonstrates a metric property that aggregates multiple wind turbines' average power data to calculate total average power for a wind farm. This object is an example of an [AssetModelProperty](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssetModelProperty.html) that contains a [Metric](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_Metric.html). You can specify this object as a part of the [CreateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModel.html) request payload to create a metric property.   

```
{
      ...
      "assetModelProperties": [
      ...
      {
          "name": "Total Average Power",
          "dataType": "DOUBLE",
          "type": {
            "metric": {
              "expression": "avg(power)",
              "variables": [
                {
                  "name": "power",
                  "value": {
                    "propertyId": "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE",
                    "hierarchyId": "Turbine Asset Model"
                  }
                }
              ],
              "window": {
                "tumbling": {
                  "interval": "5m"
                }
              }
            }
        },
        "unit": "kWh"
      }
    ],
    ...
}
```

# Use formula expressions


With formula expressions, you can define the mathematical functions to transform and aggregate your raw industrial data to gain insights about your operation. Formula expressions combine literals, operators, functions, and variables to process data. For more information about how to define asset properties that use formula expressions, see [Transform data (transforms)](transforms.md) and [Aggregate data from properties and other assets (metrics)](metrics.md). Transforms and metrics are formula properties.

**Topics**
+ [

# Use variables in formula expressions
](expression-variables.md)
+ [

# Use literals in formula expressions
](expression-literals.md)
+ [

# Use operators in formula expressions
](expression-operators.md)
+ [

# Use constants in formula expressions
](expression-constants.md)
+ [

# Use functions in formula expressions
](expression-functions.md)
+ [

# Formula expression tutorials
](expression-tutorials.md)

# Use variables in formula expressions
Use variables

Variables represent AWS IoT SiteWise asset properties in formula expressions. Use variables to input values from other asset properties in your expressions, so that you can process data from constant properties ([attributes](attributes.md)), raw data streams ([measurements](measurements.md)), and other formula properties.

Variables can represent asset properties from the same asset model or from associated child asset models. Only metric formulas can input variables from child asset models.

You identify variables by different names in the console and the API.
+ **AWS IoT SiteWise console** – Use asset property names as variables in your expressions.
+ **AWS IoT SiteWise API (AWS CLI, AWS SDKs)** – Define variables with the [ExpressionVariable](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ExpressionVariable.html) structure, which requires a variable name and a reference to an asset property. The variable name can contain lowercase letters, numbers, and underscores. Then, use variable names to reference asset properties in your expressions.

Variable names are case sensitive.

For more information, see [Defining transforms](transforms.md) and [Defining metrics](metrics.md).

## Use variables to reference properties


A variable's *value* defines the property that it references. AWS IoT SiteWise provides different ways to do this.
+ **By property ID:** You can specify the property's unique ID (UUID) to identify it.
+ **By name:** If the property is on the same asset model, you can specify its name in the property ID field.
+ **By path:** A variable value can refer to a property by its *path.* For more information, see [Use paths to reference custom composite model properties](custom-composite-models.md#property-paths).

**Note**  
 Variables are not supported by AWS IoT SiteWise console. They are used by AWS IoT SiteWise API, including the AWS Command Line Interface AWS CLI) and AWS SDKs. 

 A variable that you receive in a response from AWS IoT SiteWise includes full information about the value, including both the ID and the path.

 However, when you pass a variable into AWS IoT SiteWise (for example, in a "create" or "update" call), you only need to specify one of these. For example, if you specify the path, you don't need to provide the ID. 

# Use literals in formula expressions
Use literals

AWS IoT SiteWise supports the use of literals in expressions and formulas. Literals are fixed values that represent a specific data type. In AWS IoT SiteWise, you can define number and string literals in formula expressions. Literals can be used in various contexts, including data transformations, alarm conditions, and visualization calculations.


+ <a name="number-literal-definition"></a>**Numbers**

  Use numbers and scientific notation to define integers and doubles. You can use [E notation](https://en.wikipedia.org/wiki/Scientific_notation#E_notation) to express numbers with scientific notation.

  Examples: `1`, `2.0`, `.9`, `-23.1`, `7.89e3`, `3.4E-5`
+ <a name="string-literal-definition"></a>**Strings**

  Use the `'` (quote) and `"` (double quote) characters to define strings. The quote type for the start and end must match. To escape a quote that matches the one that you use to declare a string, include that quote character twice. This is the only escape character in AWS IoT SiteWise strings.

  Examples: `'active'`, `"inactive"`, `'{"temp": 52}'`, `"{""temp"": ""high""}"`

# Use operators in formula expressions
Use operators

You can use the following common operators in formula expressions.


| Operator | Description | 
| --- | --- | 
|  `+`  |  If both operands are numbers, this operator adds the left and right operands. If either operand is a string, this operator concatenates the left and right operands as strings. For example, the expression `1 + 2 + " is three"` evaluates to `"3 is three"`. The concatenated string can have up to 1024 characters. If the string exceeds 1024 characters, then AWS IoT SiteWise doesn't output a data point for that computation.  | 
|  `-`  |  Subtracts the right operand from the left operand. <a name="operator-numbers-only"></a>You can only use this operator with numeric operands.  | 
|  `/`  |  Divides the left operand by the right operand. <a name="operator-numbers-only"></a>You can only use this operator with numeric operands.  | 
|  `*`  |  Multiplies the left and right operands. <a name="operator-numbers-only"></a>You can only use this operator with numeric operands.  | 
|  `^`  |  Raises the left operand to the power of the right operand (exponentiation). <a name="operator-numbers-only"></a>You can only use this operator with numeric operands.  | 
|  `%`  |  Returns the remainder from dividing the left operand by the right operand. The result has the same sign as the left operand. This behavior differs from the modulo operation. <a name="operator-numbers-only"></a>You can only use this operator with numeric operands.  | 
|  `x < y`  |  Returns `1` if `x` is less than `y`, otherwise `0`.  | 
|  `x > y`  |  Returns `1` if `x` is greater than `y`, otherwise `0`.  | 
|  `x <= y`  |  Returns `1` if `x` is less than or equal to `y`, otherwise `0`.  | 
|  `x >= y`  |  Returns `1` if `x` is greater than or equal to `y`, otherwise `0`.  | 
|  `x == y`  |  Returns `1` if `x` is equal to `y`, otherwise `0`.  | 
|  `x != y`  |  Returns `1` if `x` is not equal to `y`, otherwise `0`.  | 
|  `!x`  |  Returns `1` if `x` is evaluated to `0` (false), otherwise `0`. `x` is evaluated to false if:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-operators.html)  | 
|  `x and y`  |  Returns `0` if `x` is evaluated to `0` (false). Otherwise, returns the evaluated result of `y`. `x` or `y` is evaluated to false if:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-operators.html)  | 
|  `x or y`  |  Returns `1` if `x` is evaluated to `1` (true). Otherwise, returns the evaluated result of `y`. `x` or `y` is evaluated to false if:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-operators.html)  | 
|  `not x`  |  Returns `1` if `x` is evaluated to `0` (false), otherwise `0`. `x` is evaluated to false if:  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-operators.html)  | 
|   `[]` `s[index]`  |  Returns the character at an index `index` of the string `s`. This is equivalent to the index syntax in Python. 

**Examples**  
+ `"Hello!"[1]` returns `e`.
+ `"Hello!"[-2]` returns `o`.  | 
|   `[]` `s[start:end:step]`  |  Returns a slice of the string `s`. This is equivalent to the slice syntax in Python. This operator has the following arguments: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-operators.html) You can omit the `step` argument to use its default value. For example, `s[1:4:1]` is equivalent to `s[1:4]`. The arguments must be integers or the [none](expression-constants.md#none-definition) constant. If you specify `none`, AWS IoT SiteWise uses the default value for that argument. 

**Examples**  
+ `"Hello!"[1:4]` returns `"ell"`.
+ `"Hello!"[:2]` returns `"He"`.
+ `"Hello!"[3:]` returns `"lo!"`.
+ `"Hello!"[:-4]` returns `"He"`.
+ `"Hello!"[::2]` returns `"Hlo"`.
+ `"Hello!"[::-1]` returns `"!olleH"`.  | 

# Use constants in formula expressions
Use constants

In AWS IoT SiteWise, you can use constants in your expressions and formulas to represent fixed values or predefined parameters. Constants can be used in various contexts, such as data transformations, alarm conditions, or visualization calculations. By using constants, you can simplify your expressions and make them more readable and maintainable.

You can use the following common mathematical constants in your expressions. All constants are case insensitive.

**Note**  
If you define a variable with the same name as a constant, the variable overrides the constant.


| Constant | Description | 
| --- | --- | 
|  `pi`  |  The number pi (`π`): `3.141592653589793`  | 
|  `e`  |  The number e: `2.718281828459045`  | 
|  `true`  |  Equivalent to the number 1. In AWS IoT SiteWise, Booleans convert to their number equivalents.  | 
|  `false`  |  Equivalent to the number 0. In AWS IoT SiteWise, Booleans convert to their number equivalents.  | 
|   `none`  |  Equivalent to no value. You can use this constant to output nothing as the result of a [conditional expression](expression-conditional-functions.md).  | 

# Use functions in formula expressions
Use functions

You can use the following functions to operate on data in your formula expressions.

Transforms and metrics support different functions. The following table indicates which types of functions are compatible with each type of formula property.

**Note**  
You can include a maximum of 10 functions in a formula expression.


| Function type | Transforms | Metrics | 
| --- | --- | --- | 
|  [Use common functions in formula expressions](expression-common-functions.md)  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  | 
|  [Use comparison functions in formula expressions](expression-comparison-functions.md)  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  | 
|  [Use conditional functions in formula expressions](expression-conditional-functions.md)  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  | 
|  [Use string functions in formula expressions](expression-string-functions.md)  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  | 
|  [Use aggregation functions in formula expressions](expression-aggregation-functions.md)  |  <a name="polaris-no-para"></a>![\[A red circle with the letter x for no.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-no.png) No  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  | 
|  [Use temporal functions in formula expressions](expression-temporal-functions.md)  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  | 
|  [Use date and time functions in formula expressions](expression-date-and-time-functions.md)  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  |  <a name="polaris-yes-para"></a>![\[A green circle with a checkmark for yes.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/icon-yes.png) Yes  | 

## Function syntax


You can use the following syntax to create functions:

Regular syntax  
With the regular syntax, the function name is followed by parentheses with zero or more arguments.  
`function_name(argument1, argument2, argument3, ...)`. For example, functions with the regular syntax might look like `log(x)` and `contains(s, substring)`.

Uniform function call syntax (UFCS)  
UFCS enables you to call functions using the syntax for method calls in object-oriented programming. With UFCS, the first argument is followed by dot (`.`), then the function name and the remaining arguments (if any) inside parentheses.  
`argument1.function_name(argument2, argument3, ...)`. For example, functions with UFCS might look like `x.log()` and `s.contains(substring)`.  
You can also use UFCS to chain subsequent functions. AWS IoT SiteWise uses the evaluation result of the current function as the first argument for the next function.  
For example, you can use `message.jp('$.status').lower().contains('fail')` instead of `contains(lower(jp(message, '$.status')),'fail')`.  
For more information, visit the [D Programming Language](https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs) website.

**Note**  
You can use UFCS for all AWS IoT SiteWise functions.  
AWS IoT SiteWise functions are not case sensitive. For example, you can use `lower(s)` and `Lower(s)` interchangeably.

# Use common functions in formula expressions
Use common functions

In [transforms](transforms.md) and [metrics](metrics.md), you can use the following functions to calculate common mathematical functions in transforms and metrics.


| Function | Description | 
| --- | --- | 
|  `abs(x)`  |  Returns the absolute value of `x`.  | 
|  `acos(x)`  |  Returns the arccosine of `x`.  | 
|  `asin(x)`  |  Returns the arcsine of `x`.  | 
|  `atan(x)`  |  Returns the arctangent of `x`.  | 
|  `cbrt(x)`  |  Returns the cubic root of `x`.  | 
|  `ceil(x)`  |  Returns the nearest integer greater than `x`.  | 
|  `cos(x)`  |  Returns the cosine of `x`.  | 
|  `cosh(x)`  |  Returns the hyperbolic cosine of `x`.  | 
|  `cot(x)`  |  Returns the cotangent of `x`.  | 
|  `exp(x)`  |  Returns `e` to the power of `x`.  | 
|  `expm1(x)`  |  Returns `exp(x) - 1`. Use this function to more accurately calculate `exp(x) - 1` for small values of `x`.  | 
|  `floor(x)`  |  Returns the nearest integer less than `x`.  | 
|  `log(x)`  |  Returns the `loge` (base `e`) of `x`.  | 
|  `log10(x)`  |  Returns the `log10` (base `10`) of `x`.  | 
|  `log1p(x)`  |  Returns `log(1 + x)`. Use this function to more accurately calculate `log(1 + x)` for small values of `x`.  | 
|  `log2(x)`  |  Returns the `log2` (base `2`) of `x`.  | 
|  `pow(x, y)`  |  Returns `x` to the power of `y`. This is equivalent to `x ^ y`.  | 
|  `signum(x)`  |  Returns the sign of `x` (`-1` for negative inputs, `0` for zero inputs, `+1` for positive inputs).  | 
|  `sin(x)`  |  Returns the sine of `x`.  | 
|  `sinh(x)`  |  Returns the hyperbolic sine of `x`.  | 
|  `sqrt(x)`  |  Returns the square root of `x`.  | 
|  `tan(x)`  |  Returns the tangent of `x`.  | 
|  `tanh(x)`  |  Returns the hyperbolic tangent of `x`.  | 

# Use comparison functions in formula expressions
Use comparison functions

In [transforms](transforms.md) and [metrics](metrics.md), you can use the following comparison functions to compare two values and output `1` (true) or `0` (false). AWS IoT SiteWise compares strings by [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order).


| Function | Description | 
| --- | --- | 
|  `gt(x, y)`  |  Returns `1` if `x` is greater than `y`, otherwise `0` (`x > y`). <a name="comparison-function-incompatible-types"></a>This function doesn't return a value if `x` and `y` are incompatible types, such as a number and a string.  | 
|  `gte(x, y)`  |  Returns `1` if `x` is greater than or equal to `y`, otherwise `0` (`x ≥ y`). <a name="comparison-function-relative-tolerance"></a>AWS IoT SiteWise considers the arguments equal if they are within a relative tolerance of `1E-9`. This behaves similar to the [isclose](https://docs.python.org/3/library/math.html#math.isclose) function in Python. <a name="comparison-function-incompatible-types"></a>This function doesn't return a value if `x` and `y` are incompatible types, such as a number and a string.  | 
|  `eq(x, y)`  |  Returns `1` if `x` is equal to `y`, otherwise `0` (`x == y`). <a name="comparison-function-relative-tolerance"></a>AWS IoT SiteWise considers the arguments equal if they are within a relative tolerance of `1E-9`. This behaves similar to the [isclose](https://docs.python.org/3/library/math.html#math.isclose) function in Python. <a name="comparison-function-incompatible-types"></a>This function doesn't return a value if `x` and `y` are incompatible types, such as a number and a string.  | 
|  `lt(x, y)`  |  Returns `1` if `x` is less than `y`, otherwise `0` (`x < y`). <a name="comparison-function-incompatible-types"></a>This function doesn't return a value if `x` and `y` are incompatible types, such as a number and a string.  | 
|  `lte(x, y)`  |  Returns `1` if `x` is less than or equal to `y`, otherwise `0` (`x ≤ y`). <a name="comparison-function-relative-tolerance"></a>AWS IoT SiteWise considers the arguments equal if they are within a relative tolerance of `1E-9`. This behaves similar to the [isclose](https://docs.python.org/3/library/math.html#math.isclose) function in Python. <a name="comparison-function-incompatible-types"></a>This function doesn't return a value if `x` and `y` are incompatible types, such as a number and a string.  | 
|  `isnan(x)`  |  Returns `1` if `x` is equal to `NaN`, otherwise `0`. This function doesn't return a value if `x` is a string.  | 

# Use conditional functions in formula expressions
Use conditional functions

In [transforms](transforms.md) and [metrics](metrics.md), you can use the following function to check a condition and return different results, whether the condition evaluates to true or false.


| Function | Description | 
| --- | --- | 
|   `if(condition, result_if_true, result_if_false)`  |  Evaluates the `condition` and returns `result_if_true` if the condition evaluates to true or `result_if_false` if the condition evaluates to `false`. `condition` must be a number. This function considers `0` and an empty string as `false` and everything else (including `NaN`) as `true`. Booleans convert to `0` (false) and `1` (true). You can return the [none constant](expression-constants.md#none-definition) from this function to discard the output for a particular condition. This means you can filter out data points that don't meet a condition. For more information, see [Filter data points](expression-tutorials.md#filter-data). 

**Examples**  
+ `if(0, x, y)` returns the variable `y`.
+ `if(5, x, y)` returns the variable `x`.
+ `if(gt(temp, 300), x, y)` returns the variable `x` if the variable `temp` is greater than `300`.
+ `if(gt(temp, 300), temp, none)` returns the variable `temp` if it's greater than or equal to `300`, or `none` (no value) if `temp` is less than `300`. We recommend that you use UFCS for nested conditional functions where one or more arguments are conditional functions. You can use `if(condition, result_if_true)` to evaluate a condition and `elif(condition, result_if_true, result_if_false)` to evaluate additional conditions. For example, you can use `if(condition1, result1_if_true).elif(condition2, result2_if_true, result2_if_false)` instead of `if(condition1, result1_if_true, if(condition2, result2_if_true, result2_if_false))`. You can also chain additional intermediate conditional functions. For example, you can use `if(condition1, result1_if_true).elif(condition2, result2_if_true).elif(condition3, result3_if_true, result3_if_false)` instead of nesting multiple `if` statements, such as `if(condition1, result1_if_true, if(condition2, result2_if_true, if(condition3, result3_if_true result3_if_false)))`.  You must use `elif(condition, result_if_true, result_if_false)` with UFCS.   | 

# Use string functions in formula expressions
Use string functions

In [transforms](transforms.md) and [metrics](metrics.md), you can use the following functions to operate on strings. For more information, see [Use strings in formulas](expression-tutorials.md#use-strings-in-formulas).

**Important**  
<a name="formula-output-rules"></a>Formula expressions can only output double or string values. Nested expressions can output other data types, such as strings, but the formula as a whole must evaluate to a number or string. You can use the [jp function](#jp-definition) to convert a string to a number. The Boolean value must be 1 (true) or 0 (false). For more information, see [Undefined, infinite, and overflow values](expression-tutorials.md#undefined-values).


| Function | Description | 
| --- | --- | 
|  `len(s)`  |  Returns the length of the string `s`.  | 
|  `find(s, substring)`  |  Returns the index of the string `substring` in the string `s`.  | 
|  `contains(s, substring)`  |  Returns `1` if the string `s` contains the string `substring`, otherwise `0`.  | 
|  `upper(s)`  |  Returns the string `s` in uppercase form.  | 
|  `lower(s)`  |  Returns the string `s` in lowercase form.  | 
|   `jp(s, json_path)`  |  Evaluates the string `s` with the [JsonPath](https://github.com/json-path/JsonPath) expression `json_path` and returns the result. Use this function to do the following: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-string-functions.html) To extract a string value from a JSON structure and return it as a number, you must use multiple nested `jp` functions. The outer `jp` function extracts the string from the JSON structure, and the inner `jp` function converts the string to a number. The string `json_path` must contain a string literal. This means that `json_path` can't be an expression that evaluates to a string. 

**Examples**  
+ `jp('{"status":"active","value":15}', '$.value')` returns `15`.
+ `jp('{"measurement":{"reading":25,"confidence":0.95}}', '$.measurement.reading')` returns `25`.
+ `jp('[2,8,23]', '$[2]')` returns `23`.
+ `jp('{"values":[3,6,7]}', '$.values[1]')` returns `6`.
+ `jp('111', '$')` returns `111`.
+ `jp(jp('{"measurement":{"reading":25,"confidence":"0.95"}}', '$.measurement.confidence'), '$')` returns `0.95`.  | 
|  `join(s0, s1, s2, s3, ...)`  |  Returns a concatenated string with a delimiter. This function uses the first input string as a delimiter and joins the remaining input strings together. This behaves similar to the [join(CharSequence delimiter, CharSequence... elements)](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#join-java.lang.CharSequence-java.lang.CharSequence...-) function in Java. 

**Examples**  
+ `join("-", "aa", "bb", "cc")` returns `aa-bb-cc`  | 
|  `format(expression: "format")` or `format("format", expression)`  |  Returns a string in the specified format. This function evaluates `expression` to a value, and then returns the value in the specified format. This behaves similar to the [format(String format, Object... args)](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#format-java.lang.String-java.lang.Object...-) function in Java. For more information about supported formats, see Conversions under [Class Formatter](https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html) in the *Java Platform, Standard Edition 7 API Specification*. 

**Examples**  
+ `format(100+1: "d")` returns a string, `101`.
+ `format("The result is %d", 100+1)` returns a string, `The result is 101`.  | 
|  `f'expression'`  |  Returns a concatenated string. With this formatted function, you can use a simple expression to concatenate and format strings. These functions may contain nested expressions. You can use `{}` (curly braces) to interpolate expressions. This behaves similar to the [formatted string literals](https://docs.python.org/3/reference/lexical_analysis.html#f-strings) in Python. 

**Examples**  
+ `f'abc{1+2: "f"}d'` returns `abc3.000000d`. To evaluate this example expression, do the following:

  1. `format(1+2: "f")` returns a floating point number, `3.000000`.

  1. `join('', "abc", 1+2, 'd')` returns a string, `abc3.000000d`.

  You can also write the expression in the following way: `join('', "abc", format(1+2: "f"), 'd')`.  | 

# Use aggregation functions in formula expressions
Use aggregation functions

In [metrics](metrics.md) only, you can use the following functions that aggregate input values over each time interval and calculate a single output value. Aggregation functions can aggregate data from associated assets.

Aggregation function arguments can be [variables](expression-variables.md), [number literals](expression-literals.md#number-literal-definition), [temporal functions](expression-temporal-functions.md), nested expressions, or aggregation functions. The formula `max(latest(x), latest(y), latest(z))` uses an aggregation function as an argument and returns the largest current value of the `x`, `y`, and `z` properties.

You can use nested expressions in aggregation functions. When you use nested expressions, the following rules apply: 
+ Each argument can have only one variable.  
**Example**  

  For example, `avg(x*(x-1))` and `sum(x/2 )/avg(y^2 )` are supported.

  For example, `min(x/y)` isn't supported.
+ Each argument can have multilevel nested expressions.  
**Example**  

  For example, `sum(avg(x^2 )/2)` is supported.
+ Different arguments can have different variables.  
**Example**  

  For example, `sum(x/2, y*2)` is supported.

**Note**  
If your expressions contain measurements, AWS IoT SiteWise uses the last values over the current time interval for the measurements to compute aggregates.
If your expressions contain attributes, AWS IoT SiteWise uses the latest values for the attributes to compute aggregates.


| Function | Description | 
| --- | --- | 
|  `avg(x0, ..., xn)`  |  Returns the mean of the given variables' values over the current time interval. <a name="aggregation-function-no-output"></a>This function outputs a data point only if the given variables have at least one data point over the current time interval.  | 
|   `sum(x0, ..., xn)`  |  Returns the sum of the given variables' values over the current time interval. <a name="aggregation-function-no-output"></a>This function outputs a data point only if the given variables have at least one data point over the current time interval.  | 
|  `min(x0, ..., xn)`  |  Returns the minimum of the given variables' values over the current time interval. <a name="aggregation-function-no-output"></a>This function outputs a data point only if the given variables have at least one data point over the current time interval.  | 
|  `max(x0, ..., xn)`  |  Returns the maximum of the given variables' values over the current time interval. <a name="aggregation-function-no-output"></a>This function outputs a data point only if the given variables have at least one data point over the current time interval.  | 
|  `count(x0, ..., xn)`  |  Returns the total number of data points for the given variables over the current time interval. For more information about how to count the number of data points that meet a condition, see [Count data points that match a condition](expression-tutorials.md#count-filtered-data). <a name="aggregation-function-always-output"></a>This function computes a data point for every time interval.  | 
| `stdev(x0, ..., xn)` | Returns the standard deviation of the given variables' values over the current time interval. This function outputs a data point only if the given variables have at least one data point over the current time interval.  | 

# Use temporal functions in formula expressions
Use temporal functions

Use temporal functions to return values based on timestamps of data points.

## Use temporal functions in metrics


In [metrics](metrics.md) only, you can use the following functions that return values based on timestamps of data points.

Temporal function arguments must be properties from the local asset model or nested expressions. This means that you can't use properties from child asset models in temporal functions.

You can use nested expressions in temporal functions. When you use nested expressions, the following rules apply: 
+ Each argument can have only one variable.

  For example, `latest( t*9/5 + 32 )` is supported.
+ Arguments can't be aggregation functions.

  For example, `first( sum(x) )` isn't supported.


| Function | Description | 
| --- | --- | 
|  `first(x)`  |  Returns the given variable's value with the earliest timestamp over the current time interval.  | 
|   `last(x)` |  Returns the given variable's value with the latest timestamp over the current time interval.  | 
|  `earliest(x)`  |  Returns the given variable's last value before the start of the current time interval. This function computes a data point for every time interval, if the input property has at least one data point in its history. See [time-range-defintion](#time-range-def) for details.   | 
|   `latest(x)` |  Returns the given variable's last value with the latest timestamp before the end of the current time interval. This function computes a data point for every time interval, if the input property has at least one data point in its history. See [time-range-defintion](#time-range-def) for details.  | 
|   `statetime(x)`  |  Returns the amount of time in seconds that the given variables are positive over the current time interval. You can use the [comparison functions](expression-comparison-functions.md) to create a transform property for the `statetime` function to consume.  For example, if you have an `Idle` property that is `0` or `1`, you can calculate idle time per time interval with this expression: `IdleTime = statetime(Idle)`. For more information, see the [example statetime scenario](#statetime-example). This function doesn't support metric properties as input variables. This function computes a data point for every time interval, if the input property has at least one data point in its history.  | 
|   `TimeWeightedAvg(x, [interpolation])`  | Returns the average of input data weighted with time intervals between points.See [Time weighted functions parameters](#timeweighted-parameter) for computation and intervals details.The optional argument `interpolaton` must be a string constant:[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-temporal-functions.html) | 
|   `TimeWeightedStDev(x, [algo])`  |  Returns the standard deviation of input data weighted with time intervals between points.  See [Time weighted functions parameters](#timeweighted-parameter) for computation and intervals details.  The calculation uses the Last Observed Carry Forward computation algorithm for intervals between data points. In this approach, the data point is computed as the last observed value until the next input data point time stamp. Weight is computed as time interval in seconds between data points or window boundaries.  The optional argument `algo` must be a string constant: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-temporal-functions.html) The following formulas are used for computation where: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-temporal-functions.html) Equation for population standard deviation: ![\[Equation for population standard deviation.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/timeweightedstdev1.png) Equation for frequency standard deviation: ![\[Equation for frequency standard deviation.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/timeweighted-frequency-stdev.png)  | 

The following diagram shows how AWS IoT SiteWise computes the temporal functions `first`, `last`, `earliest`, and `latest`, relative to the current time interval.

![\[AWS IoT SiteWise temporal functions return data points based on their timestamp.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-temporal-functions.png)
<a name="time-range-def"></a>

**Note**  
The time range for `first(x)`, `last(x)` is (current window start, current window end].
The time range for `latest(x)` is (beginning of time, current window end].
The time range for `earliest(x)` is (beginning of time, previous window end].

**Time-weighted functions parameters**

Time-weighted functions computed for the aggregate window take into account the following:
+ Data points inside the window
+ Time intervals between data points
+ Last data point before the window
+ First data point after the window (for some algorithms)

**Terms:**
+ **Bad data point** – Any data point with non-good quality or non-number value. This is not considered in a window result computation.
+ **Bad interval** – The interval after a bad data point. The interval before the first known data point is also considered a bad interval.
+ **Good data point** – Any data point with good quality and numeric value.

**Note**  
AWS IoT SiteWise only consumes `GOOD` quality data when it computes transforms and metrics. It ignores `UNCERTAIN` and `BAD` data points.
The interval before the first known data point is considered a **bad interval**. See [Formula expression tutorials](expression-tutorials.md) for more information.

The interval after the last known data point continues indefinitely, affecting all following windows. When a new data point arrives, the function recomputes the interval.

Following the rules above, the aggregate window result is computed and limited to window boundaries. By default, the function only sends the window result if the whole window is a **good interval**.

If the window **good interval** is smaller than the window length, the function does not send the window. 

When the data points affecting the window result change, the function recalculates the window, even if the data points are outside of the window. 

If the input property has at least one data point in its history and a computation has been initiated, the function calculates the time-weighted aggregate functions for every time interval.

**Example statetime scenario**  
Consider an example where you have an asset with the following properties:  
+ `Idle` – A measurement that is `0` or `1`. When the value is `1`, the machine is idle.
+ `Idle Time` – A metric that uses the formula `statetime(Idle)` to calculate the amount of time in seconds where the machine is idle, per 1 minute interval.
The `Idle` property has the following data points.  


|  |  |  |  |  |  | 
| --- |--- |--- |--- |--- |--- |
| Timestamp | 2:00:00 PM | 2:00:30 PM | 2:01:15 PM | 2:02:45 PM | 2:04:00 PM | 
| Idle | 0 | 1 | 1 | 0 | 0 | 
AWS IoT SiteWise calculates the `Idle Time` property every minute from the values of `Idle`. After this calculation completes, the `Idle Time` property has the following data points.  


|  |  |  |  |  |  | 
| --- |--- |--- |--- |--- |--- |
| Timestamp | 2:00:00 PM | 2:01:00 PM | 2:02:00 PM | 2:03:00 PM | 2:04:00 PM | 
| Idle Time | N/A | 30 | 60 | 45 | 0 | 
AWS IoT SiteWise performs the following calculations for `Idle Time` at the end of each minute.  
+ At 2:00 PM (for 1:59 PM to 2:00 PM)
  + There is no data for `Idle` before 2:00 PM, so no data point is calculated.
+ At 2:01 PM (for 2:00 PM to 2:01 PM)
  + At 2:00:00 PM, the machine is active (`Idle` is `0`).
  + At 2:00:30 PM, the machine is idle (`Idle` is `1`).
  + `Idle` doesn't change again before the end of the interval at 2:01:00 PM, so `Idle Time` is 30 seconds.
+ At 2:02 PM (for 2:01 PM to 2:02 PM)
  + At 2:01:00 PM, the machine is idle (per the last data point at 2:00:30 PM).
  + At 2:01:15 PM, the machine is still idle.
  + `Idle` doesn't change again before the end of the interval at 2:02:00 PM, so `Idle Time` is 60 seconds.
+ At 2:03 PM (for 2:02 PM to 2:03 PM)
  + At 2:02:00 PM, the machine is idle (per the last data point at 2:01:15 PM).
  + At 2:02:45 PM, the machine is active.
  + `Idle` doesn't change again before the end of the interval at 2:03:00 PM, so `Idle Time` is 45 seconds.
+ At 2:04 PM (for 2:03 PM to 2:04 PM)
  + At 2:03:00 PM, the machine is active (per the last data point at 2:02:45 PM).
  + `Idle` doesn't change again before the end of the interval at 2:04:00 PM, so `Idle Time` is 0 seconds.

**Example TimeWeightedAvg and TimeWeightedStDev scenario**  
The following tables provide sample inputs and outputs for these one-minute window metrics: `Avg(x), TimeWeightedAvg(x), TimeWeightedAvg(x, "linear"), stDev(x), timeWeightedStDev(x), timeWeightedStDev(x, 'p')`.  
Sample input for one-minute aggregate window:  
These data points all have `GOOD` quality.


|  |  | 
| --- |--- |
| 03:00:00 | 4.0 | 
| 03:01:00 | 2.0 | 
| 03:01:10 | 8.0 | 
| 03:01:50 | 20.0 | 
| 03:02:00 | 14.0 | 
| 03:02:05 | 10.0 | 
| 03:02:10 | 3.0 | 
| 03:02:30 | 20.0 | 
| 03:03:30 | 0.0 | 
Aggregate results output:  
None – Result not produced for this window.


| Time | `Avg(x)` | `TimeWeightedAvg(x)` | `TimeWeightedAvg(X, "linear")` | `stDev(X)` | `timeWeightedStDev(x)` | `timeWeightedStDev(x, 'p')` | 
| --- | --- | --- | --- | --- | --- | --- | 
| 3:00:00 | 4 | None | None | 0 | None | None | 
| 3:01:00 | 2 | 4 | 3 | 0 | 0 | 0 | 
| 3:02:00 | 14 | 9 | 13 | 6 | 5.430610041581775 | 5.385164807134504 | 
| 3:03:00 | 11 | 13 | 12.875 | 8.54400374531753 | 7.724054437220943 | 7.659416862050705 | 
| 3:04:00 | 0 | 10 | 2.5 | 0 | 10.084389681792215 | 10 | 
| 3:05:00 | None | 0 | 0 | None | 0 | 0 | 

## Use temporal functions in transforms


In [transforms](transforms.md) only, you can use the `pretrigger()` function to retrieve the `GOOD` quality value for a variable prior to the property update that initiated the current transform calculation.

Consider an example where a manufacturer uses AWS IoT SiteWise to monitor the status of a machine. The manufacturer uses the following measurements and transforms to represent the process:
+ A measurement, `current_state`, that can be 0 or 1.
  + If the machine is in the cleaning state, `current_state` equals 1.
  + If the machine is in the manufacturing state, `current_state` equals 0.
+ A transform, `cleaning_state_duration`, that equals `if(pretrigger(current_state) == 1, timestamp(current_state) - timestamp(pretrigger(current_state)), none)`. This transform returns how long the machine has been in the cleaning state in seconds, in the Unix epoch format. For more information, see [Use conditional functions in formula expressions](expression-conditional-functions.md) and the [timestamp()](expression-date-and-time-functions.md) function.

If the machine stays in the cleaning state longer than expected, the manufacturer might investigate the machine.

You can also use the `pretrigger()` function in multivariate transforms. For example, you have two measurements named `x` and `y`, and a transform, `z`, that equals `x + y + pretrigger(y)`. The following table shows the values for `x`, `y`, and `z` from 9:00 AM to 9:15 AM.

**Note**  
This example assumes that the values for the measurements arrive chronologically. For example, the value of `x` for 09:00 AM arrives before the value of `x` for 09:05 AM.
If the data points for 9:05 AM arrive before the data points for 9:00 AM, `z` isn't calculated at 9:05 AM.
If the value of `x` for 9:05 AM arrives before the value of `x` for 09:00 AM and the values of `y` arrive chronologically, `z` equals `22 = 20 + 1 + 1` at 9:05 AM.


|  | 09:00 AM | 09:05 AM | 09:10 AM | 09:15 AM | 
| --- | --- | --- | --- | --- | 
|  `x`  |  10  |  20  |    |  30  | 
|  `y`  |  1  |  2  |  3  |    | 
|  `z = x + y + pretrigger(y)`  |  `y` doesn't receive any data point before 09:00 AM. Therefore, `z` isn't calculated at 09:00 AM.  |  23 = 20 \$1 2 \$1 1 `pretrigger(y)` equals 1.  |  25 = 20 \$1 3 \$1 2 `x` doesn't receive a new data point. `pretrigger(y)` equals 2.  |  36 = 30 \$1 3 \$1 3 `y` doesn't receive a new data point. Therefore, `pretrigger(y)` equals 3 at 09:15 AM.  | 

# Use date and time functions in formula expressions
Use date and time functions

In [transforms](transforms.md) and [metrics](metrics.md), you can use the date and time functions in the following ways:
+ Retrieve the current timestamp of a data point in UTC or in the local time zone.
+ Construct timestamps with arguments, such as `year`, `month`, and `day_of_month`.
+ Extract a time period such as a year or month with the `unix_time` argument.


| Function | Description | 
| --- | --- | 
|  `now()`  |  Returns the current date and time, in seconds, in the Unix epoch format.  | 
|  `timestamp()`  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-date-and-time-functions.html)  | 
|  `mktime(time_zone, year, month, day_of_month, hour, minute, second)`  |  Returns the input time in seconds, in the Unix epoch format. The following requirements apply for using this function: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-date-and-time-functions.html) The following limits apply for using this function: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-date-and-time-functions.html) Examples: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-date-and-time-functions.html)  | 
|  `localtime(unix_time, time_zone)`  |  Returns the year, the day of the month, the day of the week, the day of the year, the hour, the minute, or the second in the specified time zone from the Unix time. The following requirements apply for using this function: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-date-and-time-functions.html) Example response: `2007-12-03T10:15:30+01:00[Europe/Paris]` `localtime(unix_time, time_zone)` isn't a standalone function. The `year()`, `mon()`, `mday`, `wday()`, `yday()`, `hour()`, `minute()`, and `sec()` functions take `localtime(unix_time, time_zone)` as an argument. Examples: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/expression-date-and-time-functions.html)  | 
|  `year(localtime(unix_time, time_zone)`  |  Returns the year from `localtime(unix_time, time_zone)`.  | 
|  `mon(localtime(unix_time, time_zone))`  |  Returns the month from `localtime(unix_time, time_zone)`.  | 
|  `mday(localtime(unix_time, time_zone))`  |  Returns the day of the month from `localtime(unix_time, time_zone)`.  | 
|  `wday(localtime(unix_time, time_zone))`  |  Returns the day of the week from `localtime(unix_time, time_zone)`.  | 
|  `yday(localtime(unix_time, time_zone))`  |  Returns the day of the year from `localtime(unix_time, time_zone)`.  | 
|  `hour(localtime(unix_time, time_zone))`  |  Returns the hour from `localtime(unix_time, time_zone)`.  | 
|  `minute(localtime(unix_time, time_zone))`  |  Returns the minute from `localtime(unix_time, time_zone)`.  | 
|  `sec(localtime(unix_time, time_zone))`  |  Returns the second from `localtime(unix_time, time_zone)`.  | 

## Supported time zone formats


You can specify the time zone argument in the following ways:
+ Time zone offset - Specify `'Z'` for UTC or an offset (`'+2'` or `'-5'`).
+ Offset IDs - Combine a time zone abbreviation and an offset. For example, `'GMT+2'` and `'UTC-01:00'`. The time zone abbreviation must contain only three letters.
+ Region based IDs - For example, `'Etc/GMT+12'` and `'Pacific/Pago_Pago'`.

### Supported time zone abbreviations


The date and time functions support the following three-letter time zone abbreviations: 
+ EST - -05:00
+ HST - -10:00
+ MST - -07:00
+ ACT - Australia/Darwin
+ AET - Australia/Sydney
+ AGT - America/Argentina/Buenos\$1Aires
+ ART - Africa/Cairo
+ AST - America/Anchorage
+ BET - America/Sao\$1Paulo
+ BST - Asia/Dhaka
+ CAT - Africa/Harare
+ CET - Europe/Paris
+ CNT - America/St\$1Johns
+ CST - America/Chicago
+ CTT - Asia/Shanghai 
+ EAT - Africa/Addis\$1Ababa
+ IET - America/Indiana/Indianapolis
+ IST - Asia/Kolkata
+ JST - Asia/Tokyo
+ MIT - Pacific/Apia
+ NET - Asia/Yerevan
+ NST - Pacific/Auckland
+ PLT - Asia/Karachi
+ PRT - America/Puerto\$1Rico
+ PST - America/Los\$1Angeles
+ SST - Pacific/Guadalcanal
+ VST - Asia/Ho\$1Chi\$1Minh

### Supported Region-based IDs


The date and time functions support the following Region-based IDs, organized by their relation to UTC\$100:00:
+ Etc/GMT\$112 (UTC-12:00)
+ Pacific/Pago\$1Pago (UTC-11:00)
+ Pacific/Samoa (UTC-11:00)
+ Pacific/Niue (UTC-11:00)
+ US/Samoa (UTC-11:00)
+ Etc/GMT\$111 (UTC-11:00)
+ Pacific/Midway (UTC-11:00)
+ Pacific/Honolulu (UTC-10:00)
+ Pacific/Rarotonga (UTC-10:00)
+ Pacific/Tahiti (UTC-10:00)
+ Pacific/Johnston (UTC-10:00)
+ US/Hawaii (UTC-10:00)
+ SystemV/HST10 (UTC-10:00)
+ Etc/GMT\$110 (UTC-10:00)
+ Pacific/Marquesas (UTC-09:30)
+ Etc/GMT\$19 (UTC-09:00)
+ Pacific/Gambier (UTC-09:00)
+ America/Atka (UTC-09:00)
+ SystemV/YST9 (UTC-09:00)
+ America/Adak (UTC-09:00)
+ US/Aleutian (UTC-09:00)
+ Etc/GMT\$18 (UTC-08:00)
+ US/Alaska (UTC-08:00)
+ America/Juneau (UTC-08:00)
+ America/Metlakatla (UTC-08:00)
+ America/Yakutat (UTC-08:00)
+ Pacific/Pitcairn (UTC-08:00)
+ America/Sitka (UTC-08:00)
+ America/Anchorage (UTC-08:00)
+ SystemV/PST8 (UTC-08:00)
+ America/Nome (UTC-08:00)
+ SystemV/YST9YDT (UTC-08:00)
+ Canada/Yukon (UTC-07:00)
+ US/Pacific-New (UTC-07:00)
+ Etc/GMT\$17 (UTC-07:00)
+ US/Arizona (UTC-07:00)
+ America/Dawson\$1Creek (UTC-07:00)
+ Canada/Pacific (UTC-07:00)
+ PST8PDT (UTC-07:00)
+ SystemV/MST7 (UTC-07:00)
+ America/Dawson (UTC-07:00)
+ Mexico/BajaNorte (UTC-07:00)
+ America/Tijuana (UTC-07:00)
+ America/Creston (UTC-07:00)
+ America/Hermosillo (UTC-07:00)
+ America/Santa\$1Isabel (UTC-07:00)
+ America/Vancouver (UTC-07:00)
+ America/Ensenada (UTC-07:00)
+ America/Phoenix (UTC-07:00)
+ America/Whitehorse (UTC-07:00)
+ America/Fort\$1Nelson (UTC-07:00)
+ SystemV/PST8PDT (UTC-07:00)
+ America/Los\$1Angeles (UTC-07:00)
+ US/Pacific (UTC-07:00)
+ America/El\$1Salvador (UTC-06:00)
+ America/Guatemala (UTC-06:00)
+ America/Belize (UTC-06:00)
+ America/Managua (UTC-06:00)
+ America/Tegucigalpa (UTC-06:00)
+ Etc/GMT\$16 (UTC-06:00)
+ Pacific/Easter (UTC-06:00)
+ Mexico/BajaSur (UTC-06:00)
+ America/Regina (UTC-06:00)
+ America/Denver (UTC-06:00)
+ Pacific/Galapagos (UTC-06:00)
+ America/Yellowknife (UTC-06:00)
+ America/Swift\$1Current (UTC-06:00)
+ America/Inuvik (UTC-06:00)
+ America/Mazatlan (UTC-06:00)
+ America/Boise (UTC-06:00)
+ America/Costa\$1Rica (UTC-06:00)
+ MST7MDT (UTC-06:00)
+ SystemV/CST6 (UTC-06:00)
+ America/Chihuahua (UTC-06:00)
+ America/Ojinaga (UTC-06:00)
+ Chile/EasterIsland (UTC-06:00)
+ US/Mountain (UTC-06:00)
+ America/Edmonton (UTC-06:00)
+ Canada/Mountain (UTC-06:00)
+ America/Cambridge\$1Bay (UTC-06:00)
+ Navajo (UTC-06:00)
+ SystemV/MST7MDT (UTC-06:00)
+ Canada/Saskatchewan (UTC-06:00)
+ America/Shiprock (UTC-06:00)
+ America/Panama (UTC-05:00)
+ America/Chicago (UTC-05:00)
+ America/Eirunepe (UTC-05:00)
+ Etc/GMT\$15 (UTC-05:00)
+ Mexico/General (UTC-05:00)
+ America/Porto\$1Acre (UTC-05:00)
+ America/Guayaquil (UTC-05:00)
+ America/Rankin\$1Inlet (UTC-05:00)
+ US/Central (UTC-05:00)
+ America/Rainy\$1River (UTC-05:00)
+ America/Indiana/Knox (UTC-05:00)
+ America/North\$1Dakota/Beulah (UTC-05:00)
+ America/Monterrey (UTC-05:00)
+ America/Jamaica (UTC-05:00)
+ America/Atikokan (UTC-05:00)
+ America/Coral\$1Harbour (UTC-05:00)
+ America/North\$1Dakota/Center (UTC-05:00)
+ America/Cayman (UTC-05:00)
+ America/Indiana/Tell\$1City (UTC-05:00)
+ America/Mexico\$1City (UTC-05:00)
+ America/Matamoros (UTC-05:00)
+ CST6CDT (UTC-05:00)
+ America/Knox\$1IN (UTC-05:00)
+ America/Bogota (UTC-05:00)
+ America/Menominee (UTC-05:00)
+ America/Resolute (UTC-05:00)
+ SystemV/EST5 (UTC-05:00)
+ Canada/Central (UTC-05:00)
+ Brazil/Acre (UTC-05:00)
+ America/Cancun (UTC-05:00)
+ America/Lima (UTC-05:00)
+ America/Bahia\$1Banderas (UTC-05:00)
+ US/Indiana-Starke (UTC-05:00)
+ America/Rio\$1Branco (UTC-05:00)
+ SystemV/CST6CDT (UTC-05:00)
+ Jamaica (UTC-05:00)
+ America/Merida (UTC-05:00)
+ America/North\$1Dakota/New\$1Salem (UTC-05:00)
+ America/Winnipeg (UTC-05:00)
+ America/Cuiaba (UTC-04:00)
+ America/Marigot (UTC-04:00)
+ America/Indiana/Petersburg (UTC-04:00)
+ Chile/Continental (UTC-04:00)
+ America/Grand\$1Turk (UTC-04:00)
+ Cuba (UTC-04:00)
+ Etc/GMT\$14 (UTC-04:00)
+ America/Manaus (UTC-04:00)
+ America/Fort\$1Wayne (UTC-04:00)
+ America/St\$1Thomas (UTC-04:00)
+ America/Anguilla (UTC-04:00)
+ America/Havana (UTC-04:00)
+ US/Michigan (UTC-04:00)
+ America/Barbados (UTC-04:00)
+ America/Louisville (UTC-04:00)
+ America/Curacao (UTC-04:00)
+ America/Guyana (UTC-04:00)
+ America/Martinique (UTC-04:00)
+ America/Puerto\$1Rico (UTC-04:00)
+ America/Port\$1of\$1Spain (UTC-04:00)
+ SystemV/AST4 (UTC-04:00)
+ America/Indiana/Vevay (UTC-04:00)
+ America/Indiana/Vincennes (UTC-04:00)
+ America/Kralendijk (UTC-04:00)
+ America/Antigua (UTC-04:00)
+ America/Indianapolis (UTC-04:00)
+ America/Iqaluit (UTC-04:00)
+ America/St\$1Vincent (UTC-04:00)
+ America/Kentucky/Louisville (UTC-04:00)
+ America/Dominica (UTC-04:00)
+ America/Asuncion (UTC-04:00)
+ EST5EDT (UTC-04:00)
+ America/Nassau (UTC-04:00)
+ America/Kentucky/Monticello (UTC-04:00)
+ Brazil/West (UTC-04:00)
+ America/Aruba (UTC-04:00)
+ America/Indiana/Indianapolis (UTC-04:00)
+ America/Santiago (UTC-04:00)
+ America/La\$1Paz (UTC-04:00)
+ America/Thunder\$1Bay (UTC-04:00)
+ America/Indiana/Marengo (UTC-04:00)
+ America/Blanc-Sablon (UTC-04:00)
+ America/Santo\$1Domingo (UTC-04:00)
+ US/Eastern (UTC-04:00)
+ Canada/Eastern (UTC-04:00)
+ America/Port-au-Prince (UTC-04:00)
+ America/St\$1Barthelemy (UTC-04:00)
+ America/Nipigon (UTC-04:00)
+ US/East-Indiana (UTC-04:00)
+ America/St\$1Lucia (UTC-04:00)
+ America/Montserrat (UTC-04:00)
+ America/Lower\$1Princes (UTC-04:00)
+ America/Detroit (UTC-04:00)
+ America/Tortola (UTC-04:00)
+ America/Porto\$1Velho (UTC-04:00)
+ America/Campo\$1Grande (UTC-04:00)
+ America/Virgin (UTC-04:00)
+ America/Pangnirtung (UTC-04:00)
+ America/Montreal (UTC-04:00)
+ America/Indiana/Winamac (UTC-04:00)
+ America/Boa\$1Vista (UTC-04:00)
+ America/Grenada (UTC-04:00)
+ America/New\$1York (UTC-04:00)
+ America/St\$1Kitts (UTC-04:00)
+ America/Caracas (UTC-04:00)
+ America/Guadeloupe (UTC-04:00)
+ America/Toronto (UTC-04:00)
+ SystemV/EST5EDT (UTC-04:00)
+ America/Argentina/Catamarca (UTC-03:00)
+ Canada/Atlantic (UTC-03:00)
+ America/Argentina/Cordoba (UTC-03:00)
+ America/Araguaina (UTC-03:00)
+ America/Argentina/Salta (UTC-03:00)
+ Etc/GMT\$13 (UTC-03:00)
+ America/Montevideo (UTC-03:00)
+ Brazil/East (UTC-03:00)
+ America/Argentina/Mendoza (UTC-03:00)
+ America/Argentina/Rio\$1Gallegos (UTC-03:00)
+ America/Catamarca (UTC-03:00)
+ America/Cordoba (UTC-03:00)
+ America/Sao\$1Paulo (UTC-03:00)
+ America/Argentina/Jujuy (UTC-03:00)
+ America/Cayenne (UTC-03:00)
+ America/Recife (UTC-03:00)
+ America/Buenos\$1Aires (UTC-03:00)
+ America/Paramaribo (UTC-03:00)
+ America/Moncton (UTC-03:00)
+ America/Mendoza (UTC-03:00)
+ America/Santarem (UTC-03:00)
+ Atlantic/Bermuda (UTC-03:00)
+ America/Maceio (UTC-03:00)
+ Atlantic/Stanley (UTC-03:00)
+ America/Halifax (UTC-03:00)
+ Antarctica/Rothera (UTC-03:00)
+ America/Argentina/San\$1Luis (UTC-03:00)
+ America/Argentina/Ushuaia (UTC-03:00)
+ Antarctica/Palmer (UTC-03:00)
+ America/Punta\$1Arenas (UTC-03:00)
+ America/Glace\$1Bay (UTC-03:00)
+ America/Fortaleza (UTC-03:00)
+ America/Thule (UTC-03:00)
+ America/Argentina/La\$1Rioja (UTC-03:00)
+ America/Belem (UTC-03:00)
+ America/Jujuy (UTC-03:00)
+ America/Bahia (UTC-03:00)
+ America/Goose\$1Bay (UTC-03:00)
+ America/Argentina/San\$1Juan (UTC-03:00)
+ America/Argentina/ComodRivadavia (UTC-03:00)
+ America/Argentina/Tucuman (UTC-03:00)
+ America/Rosario (UTC-03:00)
+ SystemV/AST4ADT (UTC-03:00)
+ America/Argentina/Buenos\$1Aires (UTC-03:00)
+ America/St\$1Johns (UTC-02:30)
+ Canada/Newfoundland (UTC-02:30)
+ America/Miquelon (UTC-02:00)
+ Etc/GMT\$12 (UTC-02:00)
+ America/Godthab (UTC-02:00)
+ America/Noronha (UTC-02:00)
+ Brazil/DeNoronha (UTC-02:00)
+ Atlantic/South\$1Georgia (UTC-02:00)
+ Etc/GMT\$11 (UTC-01:00)
+ Atlantic/Cape\$1Verde (UTC-01:00)
+ Pacific/Kiritimati (UTC\$114:00)
+ Etc/GMT-14 (UTC\$114:00)
+ Pacific/Fakaofo (UTC\$113:00)
+ Pacific/Enderbury (UTC\$113:00)
+ Pacific/Apia (UTC\$113:00)
+ Pacific/Tongatapu (UTC\$113:00)
+ Etc/GMT-13 (UTC\$113:00)
+ NZ-CHAT (UTC\$112:45)
+ Pacific/Chatham (UTC\$112:45)
+ Pacific/Kwajalein (UTC\$112:00)
+ Antarctica/McMurdo (UTC\$112:00)
+ Pacific/Wallis (UTC\$112:00)
+ Pacific/Fiji (UTC\$112:00)
+ Pacific/Funafuti (UTC\$112:00)
+ Pacific/Nauru (UTC\$112:00)
+ Kwajalein (UTC\$112:00)
+ NZ (UTC\$112:00)
+ Pacific/Wake (UTC\$112:00)
+ Antarctica/South\$1Pole (UTC\$112:00)
+ Pacific/Tarawa (UTC\$112:00)
+ Pacific/Auckland (UTC\$112:00)
+ Asia/Kamchatka (UTC\$112:00)
+ Etc/GMT-12 (UTC\$112:00)
+ Asia/Anadyr (UTC\$112:00)
+ Pacific/Majuro (UTC\$112:00)
+ Pacific/Ponape (UTC\$111:00)
+ Pacific/Bougainville (UTC\$111:00)
+ Antarctica/Macquarie (UTC\$111:00)
+ Pacific/Pohnpei (UTC\$111:00)
+ Pacific/Efate (UTC\$111:00)
+ Pacific/Norfolk (UTC\$111:00)
+ Asia/Magadan (UTC\$111:00)
+ Pacific/Kosrae (UTC\$111:00)
+ Asia/Sakhalin (UTC\$111:00)
+ Pacific/Noumea (UTC\$111:00)
+ Etc/GMT-11 (UTC\$111:00)
+ Asia/Srednekolymsk (UTC\$111:00)
+ Pacific/Guadalcanal (UTC\$111:00)
+ Australia/Lord\$1Howe (UTC\$110:30)
+ Australia/LHI (UTC\$110:30)
+ Australia/Hobart (UTC\$110:00)
+ Pacific/Yap (UTC\$110:00)
+ Australia/Tasmania (UTC\$110:00)
+ Pacific/Port\$1Moresby (UTC\$110:00)
+ Australia/ACT (UTC\$110:00)
+ Australia/Victoria (UTC\$110:00)
+ Pacific/Chuuk (UTC\$110:00)
+ Australia/Queensland (UTC\$110:00)
+ Australia/Canberra (UTC\$110:00)
+ Australia/Currie (UTC\$110:00)
+ Pacific/Guam (UTC\$110:00)
+ Pacific/Truk (UTC\$110:00)
+ Australia/NSW (UTC\$110:00)
+ Asia/Vladivostok (UTC\$110:00)
+ Pacific/Saipan (UTC\$110:00)
+ Antarctica/DumontDUrville (UTC\$110:00)
+ Australia/Sydney (UTC\$110:00)
+ Australia/Brisbane (UTC\$110:00)
+ Etc/GMT-10 (UTC\$110:00)
+ Asia/Ust-Nera (UTC\$110:00)
+ Australia/Melbourne (UTC\$110:00)
+ Australia/Lindeman (UTC\$110:00)
+ Australia/North (UTC\$109:30)
+ Australia/Yancowinna (UTC\$109:30)
+ Australia/Adelaide (UTC\$109:30)
+ Australia/Broken\$1Hill (UTC\$109:30)
+ Australia/South (UTC\$109:30)
+ Australia/Darwin (UTC\$109:30)
+ Etc/GMT-9 (UTC\$109:00)
+ Pacific/Palau (UTC\$109:00)
+ Asia/Chita (UTC\$109:00)
+ Asia/Dili (UTC\$109:00)
+ Asia/Jayapura (UTC\$109:00)
+ Asia/Yakutsk (UTC\$109:00)
+ Asia/Pyongyang (UTC\$109:00)
+ ROK (UTC\$109:00)
+ Asia/Seoul (UTC\$109:00)
+ Asia/Khandyga (UTC\$109:00)
+ Japan (UTC\$109:00)
+ Asia/Tokyo (UTC\$109:00)
+ Australia/Eucla (UTC\$108:45)
+ Asia/Kuching (UTC\$108:00)
+ Asia/Chungking (UTC\$108:00)
+ Etc/GMT-8 (UTC\$108:00)
+ Australia/Perth (UTC\$108:00)
+ Asia/Macao (UTC\$108:00)
+ Asia/Macau (UTC\$108:00)
+ Asia/Choibalsan (UTC\$108:00)
+ Asia/Shanghai (UTC\$108:00)
+ Antarctica/Casey (UTC\$108:00)
+ Asia/Ulan\$1Bator (UTC\$108:00)
+ Asia/Chongqing (UTC\$108:00)
+ Asia/Ulaanbaatar (UTC\$108:00)
+ Asia/Taipei (UTC\$108:00)
+ Asia/Manila (UTC\$108:00)
+ PRC (UTC\$108:00)
+ Asia/Ujung\$1Pandang (UTC\$108:00)
+ Asia/Harbin (UTC\$108:00)
+ Singapore (UTC\$108:00)
+ Asia/Brunei (UTC\$108:00)
+ Australia/West (UTC\$108:00)
+ Asia/Hong\$1Kong (UTC\$108:00)
+ Asia/Makassar (UTC\$108:00)
+ Hongkong (UTC\$108:00)
+ Asia/Kuala\$1Lumpur (UTC\$108:00)
+ Asia/Irkutsk (UTC\$108:00)
+ Asia/Singapore (UTC\$108:00)
+ Asia/Pontianak (UTC\$107:00)
+ Etc/GMT-7 (UTC\$107:00)
+ Asia/Phnom\$1Penh (UTC\$107:00)
+ Asia/Novosibirsk (UTC\$107:00)
+ Antarctica/Davis (UTC\$107:00)
+ Asia/Tomsk (UTC\$107:00)
+ Asia/Jakarta (UTC\$107:00)
+ Asia/Barnaul (UTC\$107:00)
+ Indian/Christmas (UTC\$107:00)
+ Asia/Ho\$1Chi\$1Minh (UTC\$107:00)
+ Asia/Hovd (UTC\$107:00)
+ Asia/Bangkok (UTC\$107:00)
+ Asia/Vientiane (UTC\$107:00)
+ Asia/Novokuznetsk (UTC\$107:00)
+ Asia/Krasnoyarsk (UTC\$107:00)
+ Asia/Saigon (UTC\$107:00)
+ Asia/Yangon (UTC\$106:30)
+ Asia/Rangoon (UTC\$106:30)
+ Indian/Cocos (UTC\$106:30)
+ Asia/Kashgar (UTC\$106:00)
+ Etc/GMT-6 (UTC\$106:00)
+ Asia/Almaty (UTC\$106:00)
+ Asia/Dacca (UTC\$106:00)
+ Asia/Omsk (UTC\$106:00)
+ Asia/Dhaka (UTC\$106:00)
+ Indian/Chagos (UTC\$106:00)
+ Asia/Qyzylorda (UTC\$106:00)
+ Asia/Bishkek (UTC\$106:00)
+ Antarctica/Vostok (UTC\$106:00)
+ Asia/Urumqi (UTC\$106:00)
+ Asia/Thimbu (UTC\$106:00)
+ Asia/Thimphu (UTC\$106:00)
+ Asia/Kathmandu (UTC\$105:45)
+ Asia/Katmandu (UTC\$105:45)
+ Asia/Kolkata (UTC\$105:30)
+ Asia/Colombo (UTC\$105:30)
+ Asia/Calcutta (UTC\$105:30)
+ Asia/Aqtau (UTC\$105:00)
+ Etc/GMT-5 (UTC\$105:00)
+ Asia/Samarkand (UTC\$105:00)
+ Asia/Karachi (UTC\$105:00)
+ Asia/Yekaterinburg (UTC\$105:00)
+ Asia/Dushanbe (UTC\$105:00)
+ Indian/Maldives (UTC\$105:00)
+ Asia/Oral (UTC\$105:00)
+ Asia/Tashkent (UTC\$105:00)
+ Antarctica/Mawson (UTC\$105:00)
+ Asia/Aqtobe (UTC\$105:00)
+ Asia/Ashkhabad (UTC\$105:00)
+ Asia/Ashgabat (UTC\$105:00)
+ Asia/Atyrau (UTC\$105:00)
+ Indian/Kerguelen (UTC\$105:00)
+ Iran (UTC\$104:30)
+ Asia/Tehran (UTC\$104:30)
+ Asia/Kabul (UTC\$104:30)
+ Asia/Yerevan (UTC\$104:00)
+ Etc/GMT-4 (UTC\$104:00)
+ Etc/GMT-4 (UTC\$104:00)
+ Asia/Dubai (UTC\$104:00)
+ Indian/Reunion (UTC\$104:00)
+ Europe/Saratov (UTC\$104:00)
+ Europe/Samara (UTC\$104:00)
+ Indian/Mahe (UTC\$104:00)
+ Asia/Baku (UTC\$104:00)
+ Asia/Muscat (UTC\$104:00)
+ Europe/Volgograd (UTC\$104:00)
+ Europe/Astrakhan (UTC\$104:00)
+ Asia/Tbilisi (UTC\$104:00)
+ Europe/Ulyanovsk (UTC\$104:00)
+ Asia/Aden (UTC\$103:00)
+ Africa/Nairobi (UTC\$103:00)
+ Europe/Istanbul (UTC\$103:00)
+ Etc/GMT-3 (UTC\$103:00)
+ Europe/Zaporozhye (UTC\$103:00)
+ Israel (UTC\$103:00)
+ Indian/Comoro (UTC\$103:00)
+ Antarctica/Syowa (UTC\$103:00)
+ Africa/Mogadishu (UTC\$103:00)
+ Europe/Bucharest (UTC\$103:00)
+ Africa/Asmera (UTC\$103:00)
+ Europe/Mariehamn (UTC\$103:00)
+ Asia/Istanbul (UTC\$103:00)
+ Europe/Tiraspol (UTC\$103:00)
+ Europe/Moscow (UTC\$103:00)
+ Europe/Chisinau (UTC\$103:00)
+ Europe/Helsinki (UTC\$103:00)
+ Asia/Beirut (UTC\$103:00)
+ Asia/Tel\$1Aviv (UTC\$103:00)
+ Africa/Djibouti (UTC\$103:00)
+ Europe/Simferopol (UTC\$103:00)
+ Europe/Sofia (UTC\$103:00)
+ Asia/Gaza (UTC\$103:00)
+ Africa/Asmara (UTC\$103:00)
+ Europe/Riga (UTC\$103:00)
+ Asia/Baghdad (UTC\$103:00)
+ Asia/Damascus (UTC\$103:00)
+ Africa/Dar\$1es\$1Salaam (UTC\$103:00)
+ Africa/Addis\$1Ababa (UTC\$103:00)
+ Europe/Uzhgorod (UTC\$103:00)
+ Asia/Jerusalem (UTC\$103:00)
+ Asia/Riyadh (UTC\$103:00)
+ Asia/Kuwait (UTC\$103:00)
+ Europe/Kirov (UTC\$103:00)
+ Africa/Kampala (UTC\$103:00)
+ Europe/Minsk (UTC\$103:00)
+ Asia/Qatar (UTC\$103:00)
+ Europe/Kiev (UTC\$103:00)
+ Asia/Bahrain (UTC\$103:00)
+ Europe/Vilnius (UTC\$103:00)
+ Indian/Antananarivo (UTC\$103:00)
+ Indian/Mayotte (UTC\$103:00)
+ Europe/Tallinn (UTC\$103:00)
+ Turkey (UTC\$103:00)
+ Africa/Juba (UTC\$103:00)
+ Asia/Nicosia (UTC\$103:00)
+ Asia/Famagusta (UTC\$103:00)
+ W-SU (UTC\$103:00)
+ EET (UTC\$103:00)
+ Asia/Hebron (UTC\$103:00)
+ Asia/Amman (UTC\$103:00)
+ Europe/Nicosia (UTC\$103:00)
+ Europe/Athens (UTC\$103:00)
+ Africa/Cairo (UTC\$102:00)
+ Africa/Mbabane (UTC\$102:00)
+ Europe/Brussels (UTC\$102:00)
+ Europe/Warsaw (UTC\$102:00)
+ CET (UTC\$102:00)
+ Europe/Luxembourg (UTC\$102:00)
+ Etc/GMT-2 (UTC\$102:00)
+ Libya (UTC\$102:00)
+ Africa/Kigali (UTC\$102:00)
+ Africa/Tripoli (UTC\$102:00)
+ Europe/Kaliningrad (UTC\$102:00)
+ Africa/Windhoek (UTC\$102:00)
+ Europe/Malta (UTC\$102:00)
+ Europe/Busingen (UTC\$102:00)
+ 
+ Europe/Skopje (UTC\$102:00)
+ Europe/Sarajevo (UTC\$102:00)
+ Europe/Rome (UTC\$102:00)
+ Europe/Zurich (UTC\$102:00)
+ Europe/Gibraltar (UTC\$102:00)
+ Africa/Lubumbashi (UTC\$102:00)
+ Europe/Vaduz (UTC\$102:00)
+ Europe/Ljubljana (UTC\$102:00)
+ Europe/Berlin (UTC\$102:00)
+ Europe/Stockholm (UTC\$102:00)
+ Europe/Budapest (UTC\$102:00)
+ Europe/Zagreb (UTC\$102:00)
+ Europe/Paris (UTC\$102:00)
+ Africa/Ceuta (UTC\$102:00)
+ Europe/Prague (UTC\$102:00)
+ Antarctica/Troll (UTC\$102:00)
+ Africa/Gaborone (UTC\$102:00)
+ Europe/Copenhagen (UTC\$102:00)
+ Europe/Vienna (UTC\$102:00)
+ Europe/Tirane (UTC\$102:00)
+ MET (UTC\$102:00)
+ Europe/Amsterdam (UTC\$102:00)
+ Africa/Maputo (UTC\$102:00)
+ Europe/San\$1Marino (UTC\$102:00)
+ Poland (UTC\$102:00)
+ Europe/Andorra (UTC\$102:00)
+ Europe/Oslo (UTC\$102:00)
+ Europe/Podgorica (UTC\$102:00)
+ Africa/Bujumbura (UTC\$102:00)
+ Atlantic/Jan\$1Mayen (UTC\$102:00)
+ Africa/Maseru (UTC\$102:00)
+ Europe/Madrid (UTC\$102:00)
+ Africa/Blantyre (UTC\$102:00)
+ Africa/Lusaka (UTC\$102:00)
+ Africa/Harare (UTC\$102:00)
+ Africa/Khartoum (UTC\$102:00)
+ Africa/Johannesburg (UTC\$102:00)
+ Europe/Belgrade (UTC\$102:00)
+ Europe/Bratislava (UTC\$102:00)
+ Arctic/Longyearbyen (UTC\$102:00)
+ Egypt (UTC\$102:00)
+ Europe/Vatican (UTC\$102:00)
+ Europe/Monaco (UTC\$102:00)
+ Europe/London (UTC\$101:00)
+ Etc/GMT-1 (UTC\$101:00)
+ Europe/Jersey (UTC\$101:00)
+ Europe/Guernsey (UTC\$101:00)
+ Europe/Isle\$1of\$1Man (UTC\$101:00)
+ Africa/Tunis (UTC\$101:00)
+ Africa/Malabo (UTC\$101:00)
+ GB-Eire (UTC\$101:00)
+ Africa/Lagos (UTC\$101:00)
+ Africa/Algiers (UTC\$101:00)
+ GB (UTC\$101:00)
+ Portugal (UTC\$101:00)
+ Africa/Sao\$1Tome (UTC\$101:00)
+ Africa/Ndjamena (UTC\$101:00)
+ Atlantic/Faeroe (UTC\$101:00)
+ Eire (UTC\$101:00)
+ Atlantic/Faroe (UTC\$101:00)
+ Europe/Dublin (UTC\$101:00)
+ Africa/Libreville (UTC\$101:00)
+ Africa/El\$1Aaiun (UTC\$101:00)
+ Africa/El\$1Aaiun (UTC\$101:00)
+ Africa/Douala (UTC\$101:00)
+ Africa/Brazzaville (UTC\$101:00)
+ Africa/Porto-Novo (UTC\$101:00)
+ Atlantic/Madeira (UTC\$101:00)
+ Europe/Lisbon (UTC\$101:00)
+ Atlantic/Canary (UTC\$101:00)
+ Africa/Casablanca (UTC\$101:00)
+ Europe/Belfast (UTC\$101:00)
+ Africa/Luanda (UTC\$101:00)
+ Africa/Kinshasa (UTC\$101:00)
+ Africa/Bangui (UTC\$101:00)
+ WET (UTC\$101:00)
+ Africa/Niamey (UTC\$101:00)
+ GMT (UTC\$100:00)
+ Etc/GMT-0 (UTC\$100:00)
+ Atlantic/St\$1Helena (UTC\$100:00)
+ Etc/GMT\$10 (UTC\$100:00)
+ Africa/Banjul (UTC\$100:00)
+ Etc/GMT (UTC\$100:00)
+ Africa/Freetown (UTC\$100:00)
+ Africa/Bamako (UTC\$100:00)
+ Africa/Conakry (UTC\$100:00)
+ Universal (UTC\$100:00)
+ Africa/Nouakchott (UTC\$100:00)
+ UTC (UTC\$100:00)
+ Etc/Universal (UTC\$100:00)
+ Atlantic/Azores (UTC\$100:00)
+ Africa/Abidjan (UTC\$100:00)
+ Africa/Accra (UTC\$100:00)
+ Etc/UCT (UTC\$100:00)
+ GMT0 (UTC\$100:00)
+ Zulu (UTC\$100:00)Zulu (UTC\$100:00)
+ Africa/Ouagadougou (UTC\$100:00)
+ Atlantic/Reykjavik (UTC\$100:00)
+ Etc/Zulu (UTC\$100:00)
+ Iceland (UTC\$100:00)
+ Africa/Lome (UTC\$100:00)
+ Greenwich (UTC\$100:00)
+ Etc/GMT0 (UTC\$100:00)
+ America/Danmarkshavn (UTC\$100:00)
+ Africa/Dakar (UTC\$100:00)
+ Africa/Bissau (UTC\$100:00)
+ Etc/Greenwich (UTC\$100:00)
+ Africa/Timbuktu (UTC\$100:00)
+ UCT (UTC\$100:00)
+ Africa/Monrovia (UTC\$100:00)
+ Etc/UTC (UTC\$100:00)

# Formula expression tutorials


You can follow these tutorials to use formula expressions in AWS IoT SiteWise.

**Topics**
+ [

## Use strings in formulas
](#use-strings-in-formulas)
+ [

## Filter data points
](#filter-data)
+ [

## Count data points that match a condition
](#count-filtered-data)
+ [

## Late data in formulas
](#late-data)
+ [

## Data quality in formulas
](#data-quality)
+ [

## Undefined, infinite, and overflow values
](#undefined-values)

## Use strings in formulas


You can operate on strings in your formula expressions. You also can input strings from variables that reference attribute and measurement properties.

**Important**  
<a name="formula-output-rules"></a>Formula expressions can only output double or string values. Nested expressions can output other data types, such as strings, but the formula as a whole must evaluate to a number or string. You can use the [jp function](expression-string-functions.md#jp-definition) to convert a string to a number. The Boolean value must be 1 (true) or 0 (false). For more information, see [Undefined, infinite, and overflow values](#undefined-values).

AWS IoT SiteWise provides the following formula expression features that you can use to operate on strings:
+ [String literals](expression-literals.md#string-literal-definition)
+ The [index operator](expression-operators.md#index-operator-definition) (`s[index]`)
+ The [slice operator](expression-operators.md#slice-operator-definition) (`s[start:end:step]`)
+ [Comparison functions](expression-comparison-functions.md), which you can use compare strings by [lexicographic order](https://en.wikipedia.org/wiki/Lexicographic_order)
+ [String functions](expression-string-functions.md), which include the `jp` function that can parse serialized JSON objects and convert strings to numbers

## Filter data points


You can use the [if function](expression-conditional-functions.md#if-definition) to filter out data points that don't meet a condition. The `if` function evaluates a condition and returns different values for `true` and `false` results. You can use the [none constant](expression-constants.md#none-definition) as an output for one case of an `if` function to discard the data point for that case.

**To filter out data points that match a condition**
+ Create a transform that uses the `if` function to define a condition that checks if a condition is met, and returns `none` as either the `result_if_true` or `result_if_false` value.

**Example: Filter out data points where water isn't boiling**  
Consider a scenario where you have a measurement, `temp_c`, that provides the temperature (in Celsius) of water in a machine. You can define the following transform to filter out data points where the water isn't boiling:  
+ Transform: `boiling_temps = if(gte(temp_c, 100), temp_c, none)` – Returns the temperature if it's greater than or equal to 100 degrees Celsius, otherwise returns no data point.

## Count data points that match a condition


You can use [comparison functions](expression-comparison-functions.md) and [sum()](expression-aggregation-functions.md#sum-definition) to count the number of data points for which a condition is true.

**To count data points that match a condition**

1. Create a transform that uses a comparison function to define a filter condition on another property.

1. Create a metric that sums the data points where that condition is met.

**Example: Count the number of data points where water is boiling**  
Consider a scenario where you have a measurement, `temp_c`, that provides the temperature (in Celsius) of water in a machine. You can define the following transform and metric properties to count the number of data points where the water is boiling:  
+ Transform: `is_boiling = gte(temp_c, 100)` – Returns `1` if the temperature is greater than or equal to 100 degrees Celsius, otherwise returns `0`.
+ Metric: `boiling_count = sum(is_boiling)` – Returns the number of data points where water is boiling.

## Late data in formulas


AWS IoT SiteWise supports late data ingestion of data that is up to 7 days old. When AWS IoT SiteWise receives late data, it recalculates existing values for any metric that inputs the late data in a past window. These recalculations result in data processing charges.

**Note**  
When AWS IoT SiteWise computes properties that input late data, it uses each property's current formula expression.

After AWS IoT SiteWise recalculates a past window for a metric, it replaces the previous value for that window. If you enabled notifications for that metric, AWS IoT SiteWise also emits a property value notification. This means that you can receive a new property value update notification for the same property and timestamp for which you previously received a notification. If your applications or data lakes consume property value notifications, you must update the previous value with the new value so that their data is accurate.

## Data quality in formulas


In AWS IoT SiteWise, each data point has a quality code, which can be one of the following:
+ `GOOD` – The data isn't affected by any issues.
+ `BAD` – The data is affected by an issue such as sensor failure.
+ `UNCERTAIN` – The data is affected by an issue such as sensor inaccuracy.

AWS IoT SiteWise consumes only `GOOD` quality data when it computes transforms and metrics. AWS IoT SiteWise outputs only `GOOD` quality data for successful computations. If a computation is unsuccessful, then AWS IoT SiteWise doesn't output a data point for that computation. This can occur if a computation results in an undefined, infinite, or overflow value.

For more information about how to query data and filter by data quality, see [Query data from AWS IoT SiteWise](query-industrial-data.md).

## Undefined, infinite, and overflow values


Some formula expressions (such as `x / 0`, `sqrt(-1)`, or `log(0)`) calculate values that are undefined in a real number system, infinite, or outside the range supported by AWS IoT SiteWise. When an asset property's expression computes an undefined, infinite, or overflow value, AWS IoT SiteWise doesn't output a data point for that computation.

AWS IoT SiteWise also doesn't output a data point if it computes a non-numeric value as the result of a formula expression. This means that if you define a formula that computes a string, array, or the [none constant](expression-constants.md#none-definition), then AWS IoT SiteWise doesn't output a data point for that computation.

**Examples**  
Each of the following formula expressions result in a value that AWS IoT SiteWise can't represent as a number. AWS IoT SiteWise doesn't output a data point when it computes these formula expressions.  
+ `x / 0` is undefined.
+ `log(0)` is undefined.
+ `sqrt(-1)` is undefined in a real number system.
+ `"hello" + " world"` is a string.
+ `jp('{"values":[3,6,7]}', '$.values')` is an array.
+ `if(gte(temp, 300), temp, none)` is `none` when `temp` is less than `300`.

# Create custom composite models (components)
Create custom composite models (components)

Custom composite models, or components if you're using the console, provide another level of organization for your asset models and component models. You can use them to structure your models by grouping properties or referencing other models. For more information about working with custom composite models, see [Custom composite models (components)](custom-composite-models.md).

You create a custom composite model within an existing asset model or component model. There are two types of custom composite models. To group related properties within a model, you can create an **inline** custom composite model. To reference a component model within your asset model or component model, you can create a **component-model-based** custom composite model.

The following sections describe how to use the AWS IoT SiteWise API to create custom composite models.

**Topics**
+ [

## Create an inline component (console)
](#create-inline-component-console)
+ [

## Create an inline custom composite model (AWS CLI)
](#create-inline-composite-models-cli)
+ [

## Create a component-model-based component (console)
](#create-component-console)
+ [

## Create a component-model-based custom composite model (AWS CLI)
](#create-component-based-composite-model-cli)

## Create an inline component (console)


You can use the AWS IoT SiteWise console to create an inline component that defines its own properties.

**Note**  
Because this is an *inline* component, these properties only apply to the current asset model and aren't shared anywhere else.  
If you need to produce a reusable model (for example, to share among multiple asset models, or to include multiple instances within one asset model), you should create a component based on a component model instead. See the following section for details.

**To create a component (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the asset model to which you want to add a component.

1. On the **Properties** tab, choose **Components**.

1. Choose **Create component**.

1. On the **Create component** page, do the following:

   1. Enter a **Name** for the component, such as **ServoMotor** or **ServoMotor Model**. This name must be unique across all components in your account in this Region.

   1. (Optional) Add **Attribute definitions** for the model. Attributes represent information that rarely changes. For more information, see [Define static data (attributes)](attributes.md).

   1. (Optional) Add **Measurement definitions** for the model. Measurements represent data streams from your equipment. For more information, see [Define data streams from equipment (measurements)](measurements.md).

   1. (Optional) Add **Transform definitions** for the model. Transforms are formulas that map data from one form to another. For more information, see [Transform data (transforms)](transforms.md).

   1. (Optional) Add **Metric definitions** for the model. Metrics are formulas that aggregate data over time intervals. Metrics can input data from associated assets, so that you can calculate values that represent your operation or a subset of your operation. For more information, see [Aggregate data from properties and other assets (metrics)](metrics.md).

   1. Choose **Create component**.

## Create an inline custom composite model (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to create an inline custom composite model that defines its own properties.

Use the [CreateAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModelCompositeModel.html) operation to create an inline model with properties. This operation expects a payload with the following structure.

**Note**  
Because this is an *inline* composite model, these properties only apply to the current asset model and aren't shared anywhere else. What makes it "inline" is that it doesn't provide a value for the `composedAssetModelId` field.  
If you need to produce a reusable model (for example, to share among multiple asset models, or to include multiple instances within one asset model), you should create a *component-model-based* composite model instead. See the following section for details.

```
{
    "assetModelCompositeModelName": "CNCLathe_ServoMotorA",
    "assetModelCompositeModelType": "CUSTOM",
    "assetModelCompositeModelProperties": [
        {
            "dataType": "DOUBLE",
            "name": "Servo Motor Temperature",
            "type": {
            "measurement": {}
            },
            "unit": "Celsius"
        },
        {
            "dataType": "DOUBLE",
            "name": "Spindle speed",
            "type": {
            "measurement": {}
            },
            "unit": "rpm"
        }
    ]
}
```

## Create a component-model-based component (console)


You can use the AWS IoT SiteWise console to create a component based on a component model.

**To create a component-model-based component (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the asset model to which you want to add a component.

1. On the **Properties** tab, choose **Components**.

1. Choose **Create component**.

1. On the **Create component** page, do the following:

   1. Select the component model you want to based the component on.

   1. Enter a **Name** for the component, such as **ServoMotor** or **ServoMotor Model**. This name must be unique across all components in your account in this Region.

   1. Choose **Create component**.

## Create a component-model-based custom composite model (AWS CLI)


You can use the AWS CLI to create a component-model-based custom composite model within your asset model. A component-model-based custom composite model is a reference to a component model that you've already defined elsewhere.

Use the [CreateAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModelCompositeModel.html) operation to create a component-model-based custom composite model. This operation expects a payload with the following structure.

**Note**  
In this example, the value of `composedAssetModelId` is the asset model ID or external ID of an existing component model. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*. For an example of how to create a component model, see [Create a component model (AWS CLI)](create-component-models.md#create-component-model-cli).

```
{
    "assetModelCompositeModelName": "CNCLathe_ServoMotorA",
    "assetModelCompositeModelType": "CUSTOM",
    "composedAssetModelId": component model ID
]
```

Since it's just a reference, a component-model-based custom composite model has no properties of its own, other than a name.

If you want to add multiple instances of the same component to your asset model (for example, a CNC machine that has multiple servo motors), you can add multiple component-model-based custom composite models that each have their own name but which all reference the same `composedAssetModelId`.

You can nest components within other components. To do so, you can add a component-model-based composite model, as shown in this example, to one of your component models.

# Create assets for asset models in AWS IoT SiteWise
Create assets

You can create an asset from an asset model. You must have an asset model before you can create an asset. If you haven't created an asset model, see [Create asset models in AWS IoT SiteWise](create-asset-models.md). 

**Note**  
You can only create assets from `ACTIVE` models. If your model's state isn't `ACTIVE`, you may need to wait for up to a few minutes before you can create assets from that model. For more information, see [Asset and model states](asset-and-model-states.md).

**Topics**
+ [

## Create an asset (console)
](#create-asset-console)
+ [

## Create an asset (AWS CLI)
](#create-asset-cli)
+ [

# Configure a new asset
](create-asset-next-steps.md)

## Create an asset (console)


You can use the AWS IoT SiteWise console to create an asset.

**To create an asset (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-assets"></a>In the navigation pane, choose **Assets**.

1. Choose **Create asset**.

1. On the **Create asset** page, do the following:

   1. For **Model**, choose the asset model from which to create an asset.
**Note**  
If your model isn't **ACTIVE**, you must wait until it's active, or resolve issues if it's **FAILED**.

   1. Enter a **Name** for your asset.

   1. (Optional) Add tags for your asset. For more information, see [Tag your AWS IoT SiteWise resources](tag-resources.md).

   1. Choose **Create asset**.

   When you create an asset, the AWS IoT SiteWise console navigates to the new asset's page. On this page, you can see the asset's **Status**, which is initially **CREATING**. This page automatically updates, so you can wait for the asset's status to update.
**Note**  
The asset creation process can take up to a minute. After the **Status** is **ACTIVE**, you can perform update operations on your asset. For more information, see [Asset and model states](asset-and-model-states.md).

After you create an asset, see [Configure a new asset](create-asset-next-steps.md).

## Create an asset (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to create an asset from an asset model.

You must have an `assetModelId` to create an asset. If you created an asset model, but don't know its `assetModelId`, use the [ListAssetModels](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ListAssetModels.html) API to view all of your asset models.

To create an asset from an asset model, use the [CreateAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAsset.html) API with the following parameters:
+ `assetName` – The new asset's name. Give your asset a name to help you identify it.
+ `assetModelId` – The ID of the asset. This is the actual ID in UUID format, or the `externalId:myExternalId` if it has one. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

**To create an asset (AWS CLI)**
+ Run the following command to create an asset. Replace *asset-name* with a name for the asset and *asset-model-id* with the ID or the external ID of the asset model. 

  ```
  aws iotsitewise create-asset \
    --asset-name asset-name \
    --asset-model-id asset-model-id
  ```

  The operation returns a response that contains your new asset's details and status in the following format.

  ```
  {
    "assetId": "String",
    "assetArn": "String",
    "assetStatus": {
      "state": "String",
      "error": {
        "code": "String",
        "message": "String"
      }
    }
  }
  ```

  The asset's `state` is `CREATING` until the asset creates.
**Note**  
The asset creation process can take up to a minute. To check your asset's status, use the [DescribeAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAsset.html) operation with your asset's ID as the `assetId` parameter. After the asset's `state` is `ACTIVE`, you can perform update operations on your asset. For more information, see [Asset and model states](asset-and-model-states.md).

After you create an asset, see [Configure a new asset](create-asset-next-steps.md).

# Configure a new asset


After creating an asset in AWS IoT SiteWise, there are several next steps you can take to fully utilize the asset and its data. These steps might include configuring data streams to ingest data from the asset, setting up alarms and notifications to monitor the asset's performance, creating visualizations and dashboards to display the asset's data, and integrating the asset with other AWS services or third-party applications for further analysis or automation.

Finish configuring your asset with the following optional actions:
+ [Manage data streams for AWS IoT SiteWise](manage-data-streams.md) if your asset has measurement properties.
+ [Update attribute values](update-attribute-values.md) if your asset has unique attribute values.
+ [Associate and disassociate assets](add-associated-assets.md) if your asset is a parent asset.

# Search assets on AWS IoT SiteWise console
Search assets

Use the AWS IoT SiteWise console search functionality to find assets based on metadata and real-time property value filters.

## Prerequisites
Prerequisites

 AWS IoT SiteWise requires permissions to integrate with AWS IoT TwinMaker to better organize, and model industrial data. If you have granted permissions to AWS IoT SiteWise, use the [ExecuteQuery](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ExecuteQuery.html) API. If you have not granted permissions to AWS IoT SiteWise, and need assistance getting started, see [Integrate AWS IoT SiteWise and AWS IoT TwinMaker](integrate-tm.md).

## Advanced search on AWS IoT SiteWise console
Advanced search on AWS IoT SiteWise console

### Metadata search
Metadata search

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

1. In the navigation pane, choose **Advanced search** under **Assets**.

1. Under **Advanced search** choose the **Metadata search** option.

1. Fill in the parameters. Fill in as many fields as possible for an efficient search.

   1. **Asset name** — Enter a full asset name, or a partial name for a wide search.

   1. **Property name** — Enter a full property name, or a partial name for a wide search.

   1. **Operator** — Choose an operator from:
      + **=**
      + **<**
      + **>**
      + **<=**
      + **>=**

   1. **Property value** — This value is compared with the property's latest value.

   1. **Property value type** — The data type of the property. Choose from the following:
      + **Double**
      + **Integer**
      + **String**
      + **Boolean**

1. Choose **Search**.

1. From the **Search results** table, choose the asset from the **Name** column. This takes you to the detailed asset page for that asset.

![\[metadata search results.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/search_results_all_fields.png)


#### Partial search
Partial search

All parameters do not need to be provided for an asset search. Here are some examples of partial searches using the Metadata search option:
+ Find assets by their name:
  + Enter a value in the **Asset name** field alone.
  + The **Property name** and **Property value** fields are empty.
+ Find assets containing properties with a specific name:
  + Enter a value in the **Property name** field alone.
  + The **Asset name** and **Property value** fields are empty.
+ Find assets based on the latest values of their properties:
  + Enter values in the **Property name** and **Property value** fields.
  + Select an **Operator** and **Property value type**.

### Query builder search
Query builder search

1. Navigate to the AWS IoT SiteWise console.

1. In the navigation pane, choose **Advanced search** under **Assets**.

1. Under **Advanced search** choose the **Query builder** option.

1. In the **Query builder** pane, write your SQL query to retrieve an `asset_name`, `asset_id` and `asset_description`.

1. Choose **Search**.

1. From the **Search results** table, choose the asset from the **Name** column. This takes you to the detailed asset page for that asset.

![\[query builder search results.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/search_results_sql_query.png)


**Note**  
 The `SELECT` clause in the SQL query must include the `asset_name` and `asset_id` fields to ensure a valid asset in the **Search results** table. 
 The **Query builder** only displays the **Name**, **Asset id**, and **Description** in the results table. Adding more fields to the `SELECT` clause does not add more columns to the results table 

# Update attribute values


Assets inherit the attributes of their asset model, including the default value of the attribute. In some cases, you will want to keep the asset model's default attribute, such as for an asset manufacturer property. In other cases, you will want to update the inherited attribute, such as for an asset's latitude and longitude. 

------
#### [ Updating an attribute value (console) ]

You can use the AWS IoT SiteWise console to update the value of an attribute asset property.

**To update an attribute's value (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-assets"></a>In the navigation pane, choose **Assets**.

1. Choose the asset for which you want to update an attribute.
**Tip**  <a name="sitewise-expand-asset-hierarchy"></a>
You can choose the arrow icon to expand an asset hierarchy to find your asset.

1. Choose **Edit**.

1. Find the attribute to update, and then enter its new value.  
![\[AWS IoT SiteWise "Edit asset" page screenshot with an attribute value highlighted.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-update-asset-attribute-console.png)

1. Choose **Save**.

------
#### [ Updating an attribute value (AWS CLI) ]

You can use the AWS Command Line Interface (AWS CLI) to update an attribute value.

You must know your asset's `assetId` and property's `propertyId` to complete this procedure. You can also use the external ID. If you created an asset and don't know its `assetId`, use the [ListAssets](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ListAssets.html) API to list all the assets for a specific model. Use the [DescribeAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAsset.html) operation to view your asset's properties including property IDs.

Use the [BatchPutAssetPropertyValue](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_BatchPutAssetPropertyValue.html) operation to assign attribute values to your asset. You can use this operation to set multiple attributes at once. This operation's payload contains a list of entries, and each entry contains the asset ID, property ID, and attribute value.<a name="attribute-id-update-cli"></a>

**To update an attribute's value (AWS CLI)**

1. Create a file called `batch-put-payload.json` and copy the following JSON object into the file. This example payload demonstrates how to set a wind turbine's latitude and longitude. Update the IDs, values, and timestamps to modify the payload for your use case.

   ```
   {
     "entries": [
       {
         "entryId": "windfarm3-turbine7-latitude",
         "assetId": "a1b2c3d4-5678-90ab-cdef-22222EXAMPLE",
         "propertyId": "a1b2c3d4-5678-90ab-cdef-33333EXAMPLE",
         "propertyValues": [
           {
             "value": {
               "doubleValue": 47.6204
             },
             "timestamp": {
               "timeInSeconds": 1575691200
             }
           }
         ]
       },
       {
         "entryId": "windfarm3-turbine7-longitude",
         "assetId": "a1b2c3d4-5678-90ab-cdef-22222EXAMPLE",
         "propertyId": "a1b2c3d4-5678-90ab-cdef-55555EXAMPLE",
         "propertyValues": [
           {
             "value": {
               "doubleValue": 122.3491
             },
             "timestamp": {
               "timeInSeconds": 1575691200
             }
           }
         ]
       }
     ]
   }
   ```
   + Each entry in the payload contains an `entryId` that you can define as any unique string. If any request entries fail, each error will contain the `entryId` of the corresponding request so that you know which requests to retry.
   + To set an attribute value, you can include one timestamp-quality-value (TQV) structure in the list of `propertyValues` for each attribute property. This structure must contain the new `value` and the current `timestamp`.
     + `value` – A structure that contains one of the following fields, depending on the type of the property being set:
       + `booleanValue`
       + `doubleValue`
       + `integerValue`
       + `stringValue`
       + `nullValue`
     + `timestamp` – A structure that contains the current Unix epoch time in seconds, `timeInSeconds`. AWS IoT SiteWise rejects any data points with timestamps that existed longer than 7 days in the past or newer than 5 minutes in the future.

   For more information about how to prepare a payload for [BatchPutAssetPropertyValue](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_BatchPutAssetPropertyValue.html), see [Ingest data with AWS IoT SiteWise APIs](ingest-api.md).

1. Run the following command to send the attribute values to AWS IoT SiteWise:

   ```
   aws iotsitewise batch-put-asset-property-value -\-cli-input-json file://batch-put-payload.json
   ```

------

# Associate and disassociate assets
Associate and disassociate assets

If your asset's model defines any child asset model hierarchies, you can associate child assets to your asset. Parent assets can access and aggregate data from associated assets. For more information about hierarchical asset models, see [Define asset model hierarchies](define-asset-hierarchies.md). If you're using interfaces, hierarchies defined in the interface are enforced on the asset models that implement the interface. For more information about interfaces, see [Asset model interfaces](model-interfaces.md).

**Topics**
+ [

## Associate and disassociate assets (console)
](#associate-asset-console)
+ [

## Associate and disassociate assets (AWS CLI)
](#associate-asset-cli)

## Associate and disassociate assets (console)


You can use the AWS IoT SiteWise console to associate and disassociate assets.

**To associate an asset (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-assets"></a>In the navigation pane, choose **Assets**.

1. Choose the parent asset for which you want to associate a child asset.
**Tip**  <a name="sitewise-expand-asset-hierarchy"></a>
You can choose the arrow icon to expand an asset hierarchy to find your asset.

1. Choose **Edit**.

1. In **Assets associated to this asset**, choose **Add associated asset**.  
![\[The AWS IoT SiteWise Edit asset page with this field text: Add associated asset.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-associate-asset-console.png)

1. For **Hierarchy**, choose the hierarchy that defines the relationship between the parent asset and the child asset.

1. For **Asset**, choose the child asset to associate.

1. Choose **Save**.

**To disassociate an asset (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-assets"></a>In the navigation pane, choose **Assets**.

1. Choose the parent asset for which you want to disassociate a child asset.
**Tip**  <a name="sitewise-expand-asset-hierarchy"></a>
You can choose the arrow icon to expand an asset hierarchy to find your asset.

1. Choose **Edit**.

1. In **Assets associated to this asset**, choose **Disassociate** for the asset.  
![\[AWS IoT SiteWise "Edit asset" page screenshot with "Disassociate" highlighted.\]](http://docs.aws.amazon.com/iot-sitewise/latest/userguide/images/sitewise-disassociate-asset-console.png)

1. Choose **Save**.

## Associate and disassociate assets (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to associate and disassociate assets.

For this procedure, you must know the ID of the hierarchy (`hierarchyId`) in the parent asset model that defines the relationship to the child asset model. Use the [DescribeAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAsset.html) operation to find the hierarchy ID in the response.

**To find a hierarchy ID**
+ Run the following command to describe the parent asset. Replace *parent-asset-id* with the parent asset's ID or external ID.

  ```
  aws iotsitewise describe-asset --asset-id parent-asset-id
  ```

  The operation returns a response that contains the asset's details. The response contains an `assetHierarchies` list that has the following structure:

  ```
  {
    ...
    "assetHierarchies": [
      {
        "id": "String",
        "name": "String"
      }
    ],
    ...
  }
  ```

  The hierarchy ID is the `id` value for a hierarchy in the list of asset hierarchies.

After you have the hierarchy ID, you can associate or disassociate an asset with that hierarchy.

To associate a child asset to a parent asset, use the [AssociateAssets](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_AssociateAssets.html) operation. To disassociate a child asset from a parent asset, use the [DisassociateAssets](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DisassociateAssets.html) operation. Specify the following parameters, which are the same for both operations:
+ `assetId` – The parent asset's ID or external ID.
+ `hierarchyId` – The hierarchy ID or external ID in the parent asset.
+ `childAssetId` – The child asset's ID or external ID.

**To associate an asset (AWS CLI)**
+ Run the following command to associate a child asset to a parent asset. Replace *parent-asset-id*, *hierarchy-id*, and *child-asset-id* with the respective IDs:

  ```
  aws iotsitewise associate-assets \
    --asset-id parent-asset-id \
    --hierarchy-id hierarchy-id \
    --child-asset-id child-asset-id
  ```

**To disassociate an asset (AWS CLI)**
+ Run the following command to disassociate a child asset from a parent asset. Replace *parent-asset-id*, *hierarchy-id*, and *child-asset-id* with the respective IDs:

  ```
  aws iotsitewise disassociate-assets \
    --asset-id parent-asset-id \
    --hierarchy-id hierarchy-id \
    --child-asset-id child-asset-id
  ```

# Update assets and models


You can update your assets, asset models, component models, and interfaces in AWS IoT SiteWise to modify their names and definitions. These update operations are asynchronous and take time to propagate through AWS IoT SiteWise. Check the status of the asset or model before you make additional changes. You must wait until the changes propagate before you can continue to use the updated asset or model.

**Topics**
+ [

# Update assets in AWS IoT SiteWise
](update-assets.md)
+ [

# Update asset models, component models, and interfaces
](update-asset-models.md)
+ [

# Update custom composite models (components)
](update-custom-composite-models.md)
+ [

# Optimistic locking for asset model writes
](opt-locking-for-model.md)

# Update assets in AWS IoT SiteWise


You can use the AWS IoT SiteWise console or API to update an asset's name.

When you update an asset, the asset's status is `UPDATING` until the changes propagate. For more information, see [Asset and model states](asset-and-model-states.md).

**Topics**
+ [

## Update an asset (console)
](#update-asset-console)
+ [

## Update an asset (AWS CLI)
](#update-asset-cli)

## Update an asset (console)


You can use the AWS IoT SiteWise console to update asset details.

**To update an asset (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-assets"></a>In the navigation pane, choose **Assets**.

1. Choose the asset to update.
**Tip**  <a name="sitewise-expand-asset-hierarchy"></a>
You can choose the arrow icon to expand an asset hierarchy to find your asset.

1. Choose **Edit**.

1. Update the asset's **Name**.

1. (Optional) On this page, update other information for the asset. For more information, see the following:
   + [Manage data streams for AWS IoT SiteWise](manage-data-streams.md)
   + [Update attribute values](update-attribute-values.md)
   + [Interact with other AWS services](interact-with-other-services.md)

1. Choose **Save**.

## Update an asset (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to update an asset's name.

Use the [UpdateAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAsset.html) operation to update an asset. Specify the following parameters:
+ `assetId` – The ID of the asset. This is the actual ID in UUID format, or the `externalId:myExternalId` if it has one. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.
+ `assetName` – The asset's new name.

**To update an asset's name (AWS CLI)**
+ Run the following command to update an asset's name. Replace *asset-id* with the ID or external ID of the asset. Update the *asset-name* with the new name for the asset.

  ```
  aws iotsitewise update-asset \
    --asset-id asset-id \
    --asset-name asset-name
  ```

# Update asset models, component models, and interfaces


Use the AWS IoT SiteWise console or API to update an asset model, component model, or interface.

You can't change the type or data type of an existing property, or the window of an existing metric. You also can't change the type of the model from asset model to component model or interface, or the other way around.

**Important**  
If you remove a property from an asset model or component model, AWS IoT SiteWise deletes all previous data for that property. For component models, this affects **all asset models using that component model**, so be especially careful to understand how widely your change may apply.
If you remove a hierarchy definition from an asset model, AWS IoT SiteWise disassociates all assets in that hierarchy.

When you update an asset model, every asset based on that model reflects any changes that you make to the underlying model. Until the changes propagate, each asset has the `UPDATING` state. You must wait until those assets return to the `ACTIVE` state before you interact with them. During this time, the updated asset model's status will be `PROPAGATING`.

When you update a component model, every asset model that incorporates that component model reflects the changes. Until the component model changes propagate, each affected asset model has the `UPDATING` state, followed by `PROPAGATING` as it updates its associated assets, as described in the preceding paragraph. You must wait until those asset models return to the `ACTIVE` state before you interact with them. During this time, the updated component model's status will be `PROPAGATING`.

For more information, see [Asset and model states](asset-and-model-states.md).

**Topics**
+ [

## Updating an asset model, component model, or interface (console)
](#update-asset-model-console)
+ [

## Update an asset model, component model, or interface (AWS CLI)
](#update-asset-model-cli)

## Updating an asset model, component model, or interface (console)


You can use the AWS IoT SiteWise console to update an asset model, component model, or interface.

**To update an asset model, component model, or interface (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the asset model, component model, or interface to update.

1. Choose **Edit**.

1. On the **Edit model** page, do any of the following:
   + In **Model details**, change the **Name** of the model.
   + Change any of the **Attribute definitions**. You can't change the **Data type** of existing attributes. For more information, see [Define static data (attributes)](attributes.md).
   + Change any of the **Measurement definitions**. You can't change the **Data type** of existing measurements. For more information, see [Define data streams from equipment (measurements)](measurements.md).
   + Change any of the **Transform definitions**. For more information, see [Transform data (transforms)](transforms.md).
   + Change any of the **Metric definitions**. You can't change the **Time interval** of existing metrics. For more information, see [Aggregate data from properties and other assets (metrics)](metrics.md).
   + (Asset models only) Change any of the **Hierarchy definitions**. You can't change the **Hierarchy model** of existing hierarchies. For more information, see [Define asset model hierarchies](define-asset-hierarchies.md).

1. Choose **Save**.

**Note**  
 Update requests made in the console are rejected, if another user successfully updates the asset model since you last opened the **Edit model** page. The console prompts the user to **Refresh** the **Edit model** page, to fetch the updated model. You must make your updates again, and retry your save. See [Optimistic locking for asset model writes](opt-locking-for-model.md) for more details. 

## Update an asset model, component model, or interface (AWS CLI)


Use the AWS Command Line Interface (AWS CLI) to update an asset model, component model, or interface.

Use the [UpdateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModel.html) API to update the name, description, and properties of an asset model, component model, or interface. For asset models only, you can update hierarchies. For interfaces, you can update properties and hierarchies. Specify the following parameters:
+ `assetModelId` – The ID of the asset. This is the actual ID in UUID format, or the `externalId:myExternalId` if it has one. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

Specify the updated model in the payload. To learn about the expected format of an asset model or component model, see [Create asset models in AWS IoT SiteWise](create-asset-models.md). 

**Warning**  
The [UpdateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModel.html) API overwrites the existing model with the model that you provide in the payload. To avoid deleting your model's properties or hierarchies, you must include their IDs and definitions in the updated model payload. To learn how to query your model's existing structure, see the [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation.

**Note**  
The following procedure can only update composite models of type `AWS/ALARM`. If you want to update `CUSTOM` composite models, use [UpdateAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModelCompositeModel.html) instead. For more information, see [Update custom composite models (components)](update-custom-composite-models.md).

**To update an asset model or component model (AWS CLI)**

1. Run the following command to retrieve the existing model definition. Replace *asset-model-id* with the ID or the external ID of the asset model or component model to update.

   ```
   aws iotsitewise describe-asset-model --asset-model-id asset-model-id
   ```

   The above command returns the model definition corresponding to model’s latest version.

    For an use case where an asset model is in a `FAILED` state, retrieve the valid model definition corresponding to its active version to build your update request. See [Asset model versions](model-active-version.md) for details. Run the following command to retrieve the active model definition:

   ```
   aws iotsitewise describe-asset-model --asset-model-id asset-model-id --asset-model-version ACTIVE 
   ```

   The operation returns a response that contains the model's details. The response has the following structure.

   ```
   {
       "assetModelId": "String",
       "assetModelArn": "String",
       "assetModelName": "String",
       "assetModelDescription": "String",
       "assetModelProperties": Array of AssetModelProperty,
       "assetModelHierarchies": Array of AssetModelHierarchyDefinition,
       "assetModelCompositeModels": Array of AssetModelCompositeModel,
       "assetModelCompositeModelSummaries": Array of AssetModelCompositeModelSummary,
       "assetModelCreationDate": "String",
       "assetModelLastUpdateDate": "String",
       "assetModelStatus": {
         "state": "String",
         "error": {
           "code": "String",
           "message": "String"
         },
       "assetModelType": "String"
       },
       "assetModelVersion": "String",
       "eTag": "String"
   }
   ```

   For more information, see the [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) operation.

1. Create a file called `update-asset-model.json` and copy the previous command's response into the file.

1. Remove the following key-value pairs from the JSON object in `update-asset-model.json`:
   + `assetModelId`
   + `assetModelArn`
   + `assetModelCompositeModelSummaries`
   + `assetModelCreationDate`
   + `assetModelLastUpdateDate`
   + `assetModelStatus`
   + `assetModelType`
   + `assetModelVersion`
   + `eTag`

   The [UpdateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModel.html) operation expects a payload with the following structure:

   ```
   {
     "assetModelName": "String",
     "assetModelDescription": "String",
     "assetModelProperties": Array of AssetModelProperty,
     "assetModelHierarchies": Array of AssetModelHierarchyDefinition,
     "assetModelCompositeModels": Array of AssetModelCompositeModel
   }
   ```

1. In `update-asset-model.json`, do any of the following:
   + Change the asset model's name (`assetModelName`).
   + Change, add, or remove the asset model's description (`assetModelDescription`).
   + Change, add, or remove any of the asset model's properties (`assetModelProperties`). You can't change the `dataType` of existing properties or the `window` of existing metrics. For more information, see [Define data properties](asset-properties.md).
   + Change, add, or remove any of the asset model's hierarchies (`assetModelHierarchies`). You can't change the `childAssetModelId` of existing hierarchies. For more information, see [Define asset model hierarchies](define-asset-hierarchies.md).
   + Change, add, or remove any of the asset model's composite models of type `AWS/ALARM` (`assetModelCompositeModels`). Alarms monitor other properties so that you can identify when equipment or processes require attention. Each alarm definition is a composite model that standardizes the set of properties that the alarm uses. For more information, see [Monitor data with alarms in AWS IoT SiteWise](industrial-alarms.md) and [Define alarms on asset models in AWS IoT SiteWise](define-alarms.md).

1. Run the following command to update the asset model with the definition stored in `update-asset-model.json`. Replace *asset-model-id* with the ID of the asset model:

   ```
   aws iotsitewise update-asset-model \
     --asset-model-id asset-model-id \
     --cli-input-json file://model-payload.json
   ```

**Important**  
 When multiple users update an asset model at the same time, an user's changes may be inadvertently overwritten by another user. To prevent this, you must define a conditional update request. See [Optimistic locking for asset model writes](opt-locking-for-model.md). 

# Update custom composite models (components)


You can use the AWS IoT SiteWise API to update a custom composite model, or the AWS IoT SiteWise console to update components.

**Topics**
+ [

## Update a component (console)
](#update-custom-composite-model-console)
+ [

## Update a custom composite model (AWS CLI)
](#update-custom-composite-model-cli)

## Update a component (console)


You can use the AWS IoT SiteWise console to update a component.

**To update a component (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the asset model where the component is.

1. On the **Properties** tab, choose **Components**.

1. Choose the component that you want to update.

1. Choose **Edit**.

1. On the **Edit component** page, do any of the following:
   + In **Model details**, change the **Name** of the model.
   + Change any of the **Attribute definitions**. You can't change the **Data type** of existing attributes. For more information, see [Define static data (attributes)](attributes.md).
   + Change any of the **Measurement definitions**. You can't change the **Data type** of existing measurements. For more information, see [Define data streams from equipment (measurements)](measurements.md).
   + Change any of the **Transform definitions**. For more information, see [Transform data (transforms)](transforms.md).
   + Change any of the **Metric definitions**. You can't change the **Time interval** of existing metrics. For more information, see [Aggregate data from properties and other assets (metrics)](metrics.md).

1. Choose **Save**.

## Update a custom composite model (AWS CLI)


Use the AWS Command Line Interface (AWS CLI) to update a custom composite model.

To update the name or description, use the [UpdateAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModelCompositeModel.html) operation. For inline custom composite models only, you can also update the properties. You can't update the properties of a component-model-based custom composite model, because its referenced component model provides its associated properties.

**Important**  
If you remove a property from a custom composite model, AWS IoT SiteWise deletes all previous data for that property. You can’t change the type or data type of an existing property.  
To replace an existing composite model property with a new one with the same `name`, do the following:  
Submit an `UpdateAssetModelCompositeModel` request with the entire existing property removed.
Submit a second `UpdateAssetModelCompositeModel` request that includes the new property. The new asset property will have the same `name` as the previous one and AWS IoT SiteWise will generate a new unique `id`.

**To update a custom composite model (AWS CLI)**

1. To retrieve the existing composite model definition, run the following command. Replace *composite-model-id* with the ID or the external ID of the custom composite model to update, and *asset-model-id* with the asset model that the custom composite model is associated with. For more information, see the *AWS IoT SiteWise User Guide*.

   1. Run the command below:

      ```
      aws iotsitewise describe-asset-model-composite-model \
      --asset-model-composite-model-id composite-model-id \
      --asset-model-id asset-model-id
      ```

   1.  The above command returns the composite model definition corresponding to associated model’s latest version. For an use case where an asset model is in a `FAILED` state, retrieve the valid model definition corresponding to its active version to build your update request. See [Asset model versions](model-active-version.md) for details. 

   1. Run the following command to retrieve the active model definition:

      ```
      aws iotsitewise describe-asset-model-composite-model \
      --asset-model-composite-model-id composite-model-id \
      --asset-model-id asset-model-id \
      --asset-model-version ACTIVE
      ```

   1. For more information, see the [DescribeAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModelCompositeModel.html) operation.

1. Create a file called `update-custom-composite-model.json`, and then copy the previous command's response into the file.

1. Remove every key-value pair from the JSON object in `update-custom-composite-model.json` except for the following fields:
   + `assetModelCompositeModelName`
   + `assetModelCompositeModelDescription` (if present)
   + `assetModelCompositeModelProperties` (if present)

1. In `update-custom-composite-model.json`, do any of the following:
   + Change the value of `assetModelCompositeModelName`.
   + Add or remove `assetModelCompositeModelDescription`, or change its value.
   + For inline custom composite models only: Change, add, or remove any of the asset model's properties in `assetModelCompositeModelProperties`.

   For more information about the required format for this file, see the request syntax for [UpdateAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModelCompositeModel.html).

1. Run the following command to update the custom composite model with the definition stored in `update-custom-composite-model.json`. Replace *composite-model-id* with the ID of the composite model, and *asset-model-id* with the ID of the asset model it's in.

   ```
   aws iotsitewise update-asset-model-composite-model \
   --asset-model-composite-model-id composite-model-id \
   --asset-model-id asset-model-id \
   --cli-input-json file://update-custom-composite-model.json
   ```

**Important**  
 When multiple users update an asset model at the same time, an user's changes may be inadvertently overwritten by another user. To prevent this, you must define a conditional update request. See [Optimistic locking for asset model writes](opt-locking-for-model.md). 

# Optimistic locking for asset model writes


 When updating an asset model, an user does the following: 

1. Read the current asset model definition.

1. Edit the asset model definition with required changes.

1. Update asset model with the new definition.

 In a scenario with two users updating a model, the following is possible: 
+ User A reads the asset model X definition.
+ User B reads the asset model X definition and commits changes, modifying the definition of X.
+ User A commits and overwrites the change made by user B for asset model X, without verifying or incorporating User B's changes.

 Optimistic locking is a mechanism used by AWS IoT SiteWise to prevent accidental overwrites like the scenario above. Optimistic locking is a strategy to ensure the current version of asset model being updated or deleted, is the same as its current version in AWS IoT SiteWise. This protects asset model writes from being overwritten by accidental updates. 

Follow these steps to perform asset model writes with optimistic locking:

**Topics**
+ [

## Performing asset model writes with optimistic lock (console)
](#opt-locking-for-model-console)
+ [

## Performing asset model writes with optimistic lock (AWS CLI)
](#opt-locking-for-model-cli)

## Performing asset model writes with optimistic lock (console)


The procedure below describes how to perform asset model writes with an optimistic lock on the asset model's active version in the console.

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the asset model or component model to update.

1. Choose **Edit**.

1. Make changes on the **Edit model** page.

1. Choose **Save**.
**Note**  
Sometimes, one or more successful model updates have happened between when the user starts editing the model, and saves the made edits to the model.  
To ensure the user does not accidentally overwrite over new successful updates, the user's write is rejected. The console disables the **Save** button, and prompts the user to refresh the **Edit model** page. The user must update the new active version of the model again. The user must perform the following additional steps: 

1. Choose **Refresh**.

1. Follow steps 5 and 6 again.

## Performing asset model writes with optimistic lock (AWS CLI)


The procedure below describes how to perform asset model writes with optimistic locking in the AWS CLI.

1. **Fetch the ETag associated with current model definition**

    `ETag` is a unique token generated for each new representation of an asset model. Call [DescribeAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAssetModel.html) API to fetch the current asset model definition, and associated `ETag` from the response. 

    During concurrent updates, users perform either successful updates (model in `ACTIVE` state), or unsuccessful updates (model in `FAILED` state). To ensure that an user does not accidentally overwrite a successful update, you must retrieve the active version of the asset model from [Asset model versions](model-active-version.md), and get the `ETag` value. 

   Run the following command:

   ```
   aws iotsitewise describe-asset-model --asset-model-id asset-model-id \
   --asset-model-version ACTIVE
   ```

    The response returns the following structure: 

   ```
   {
     "assetModelId": "String",
     "assetModelArn": "String",
     "assetModelName": "String",
     ...
     "eTag": "String"
   }
   ```
**Note**  
 You must retrieve the latest version of the asset model and its `ETag` in order to not overwrite any updates. 

1. **Perform UPDATE and DELETE operations with write conditions**

   The following asset model APIs support optimistic locking:
   + [UpdateAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModel.html)
   + [DeleteAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DeleteAssetModel.html)
   + [CreateAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_CreateAssetModelCompositeModel.html)
   + [UpdateAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_UpdateAssetModelCompositeModel.html)
   + [DeleteAssetModelCompositeModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DeleteAssetModelCompositeModel.html)
**Note**  
 The below scenarios use `UpdateAssetModel` API as a reference. The conditions apply to all the operations listed above. 

   The below scenarios describe the different write conditions depending on concurrency control requirements:
   +  Run the following command in order not to overwrite any successful updates. A new active version must not exist, since the last read active version. Replace `e-tag` with the `ETag` returned in the API operation used in the read of the active version. 

     ```
     aws iotsitewise update-asset-model \
       --asset-model-id asset-model-id \
       --if-match e-tag \
       --match-for-version-type ACTIVE \
       --cli-input-json file://model-payload.json
     ```
   +  When a model creation fails, an active version does not exist for it yet, because it's in a `FAILED` state. It is still possible to overwrite a new active version that is present, before your changes are committed. Run the following command to not overwrite a new active version, when an active version does not exist during your last read.

     ```
     aws iotsitewise update-asset-model \
       --asset-model-id asset-model-id \
       --if-none-match "*" \
       --match-for-version-type ACTIVE \
       --cli-input-json file://model-payload.json
     ```
   +  Run the following command to avoid overwriting any successful or unsuccessful updates. This command defines a write condition which ensures that a latest version is not created since your last read latest version. Replace `e-tag` with the `ETag` returned in the API operation used in the read of the active version.

     ```
     aws iotsitewise update-asset-model \
       --asset-model-id asset-model-id \
       --if-match eTag \
       --match-for-version-type LATEST \
       --cli-input-json file://model-payload.json
     ```

     If the write condition evaluates to `FALSE`, the write request fails with the `PreconditionFailedException`.

# Delete assets and models in AWS IoT SiteWise


You can delete your assets, asset models, component models, and interfaces from AWS IoT SiteWise when you're done with them. The delete operations are asynchronous and take time to propagate through AWS IoT SiteWise.

**Topics**
+ [

# Delete assets in AWS IoT SiteWise
](delete-assets.md)
+ [

# Delete asset models, component models, and interfaces in AWS IoT SiteWise
](delete-asset-models.md)

# Delete assets in AWS IoT SiteWise
Delete assets

You can use the AWS IoT SiteWise console or API to delete an asset no longer needed in your environment. Deleting an asset model also deletes all associated assets and component models. However, it's important to note that deleting an asset or model is a permanent action, and any data associated with the deleted resources is also be removed. Before deleting assets or models, it's recommended to review any dependencies or integrations that might be impacted and ensure that you have a backup of any important data.

Before you can delete an asset, you must first disassociate its child assets and disassociate it from its parent asset. For more information, see [Associate and disassociate assets](add-associated-assets.md). If you use the AWS Command Line Interface (AWS CLI), you can use the [ListAssociatedAssets](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ListAssociatedAssets.html) operation to list an asset's children.

When you delete an asset, its status is `DELETING` until the changes propagate. For more information, see [Asset and model states](asset-and-model-states.md). After the asset is deleted, you can't query that asset. If you do, the API returns an HTTP 404 response.

**Important**  
AWS IoT SiteWise deletes all property data for deleted assets.

**Topics**
+ [

## Delete an asset (console)
](#delete-asset-console)
+ [

## Delete an asset (AWS CLI)
](#delete-asset-cli)

## Delete an asset (console)


You can use the AWS IoT SiteWise console to delete an asset.

**To delete an asset (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-assets"></a>In the navigation pane, choose **Assets**.

1. Choose the asset to delete.
**Tip**  <a name="sitewise-expand-asset-hierarchy"></a>
You can choose the arrow icon to expand an asset hierarchy to find your asset.

1. If the asset has any **Associated assets**, delete each asset. You can choose an asset's name to navigate to its page, where you can delete it.

1. On the asset's page, choose **Delete**.

1. In the **Delete asset** dialog box, do the following:

   1. Enter **Delete** to confirm deletion.

   1. Choose **Delete**.

## Delete an asset (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to delete an asset.

Use the [DeleteAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DeleteAsset.html) operation to delete an asset. Specify the following parameter:
+ `assetId` – The ID of the asset. This is the actual ID in UUID format, or the `externalId:myExternalId` if it has one. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

**To delete an asset (AWS CLI)**

1. Run the following command to list the asset's hierarchies. Replace *asset-id* with the ID or the external ID of the asset:

   ```
   aws iotsitewise describe-asset --asset-id asset-id
   ```

   The operation returns a response that contains the asset's details. The response contains an `assetHierarchies` list that has the following structure:

   ```
   {
     ...
     "assetHierarchies": [
       {
         "id": "String",
         "name": "String"
       }
     ],
     ...
   }
   ```

   For more information, see the [DescribeAsset](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DescribeAsset.html) operation.

1. For each hierarchy, run the following command to list the asset's children that are associated with that hierarchy. Replace *asset-id* with the ID or external ID of the asset and *hierarchy-id* with the ID or external ID of the hierarchy.

   ```
   aws iotsitewise list-associated-assets \
     --asset-id asset-id \
     --hierarchy-id hierarchy-id
   ```

   For more information, see the [ListAssociatedAssets](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ListAssociatedAssets.html) operation.

1. Run the following command to delete each associated asset and then to delete the asset. Replace *asset-id* with the ID or external ID of the asset.

   ```
   aws iotsitewise delete-asset --asset-id asset-id
   ```

# Delete asset models, component models, and interfaces in AWS IoT SiteWise
Delete models and interfaces

You can use the AWS IoT SiteWise console or API to delete an asset model, component model, or interface.

Before you can delete an asset model, you must first delete all assets that were created from the asset model. Before you can delete an interface, you must first unlink it from all asset models that implement it.

When you delete an asset model or interface, its status is `DELETING` until the changes propagate. For more information, see [Asset and model states](asset-and-model-states.md). After the asset model or interface is deleted, you can't query that asset model or interface. If you do, the API returns an HTTP 404 response.

**Topics**
+ [

## Delete an asset model, component model, or interface (console)
](#delete-asset-model-console)
+ [

## Delete an asset model, component model, or interface (AWS CLI)
](#delete-asset-model-cli)

## Delete an asset model, component model, or interface (console)


You can use the AWS IoT SiteWise console to delete an asset model, component model, or interface.

**Topics**

**To delete an asset model, component model, or interface (console)**

1. <a name="sitewise-open-console"></a>Navigate to the [AWS IoT SiteWise console](https://console.aws.amazon.com/iotsitewise/).

1. <a name="sitewise-choose-models"></a>In the navigation pane, choose **Models**.

1. Choose the asset model, component model, or interface to delete.

1. If deleting an asset model and it has any **Assets**, delete each asset. Choose an asset's name to navigate to its page, where you can delete it. For more information, see [Delete an asset (console)](delete-assets.md#delete-asset-console).

1. On the model's page, choose **Delete**.

1. In the **Delete model** dialog box, do the following:

   1. Enter **Delete** to confirm deletion.

   1. Choose **Delete**.

## Delete an asset model, component model, or interface (AWS CLI)


You can use the AWS Command Line Interface (AWS CLI) to delete an asset model, component model, or interface.

Use the [DeleteAssetModel](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_DeleteAssetModel.html) operation to delete an asset model, component model, or interface. Specify the following parameter:
+ `assetModelId` – The ID of the asset. This is the actual ID in UUID format, or the `externalId:myExternalId` if it has one. For more information, see [Reference objects with external IDs](object-ids.md#external-id-references) in the *AWS IoT SiteWise User Guide*.

**To delete an asset model (AWS CLI)**

1. Run the following command to list all assets created from the model. Replace *asset-model-id* with the ID or the external ID of the asset model.

   ```
   aws iotsitewise list-assets --asset-model-id asset-model-id
   ```

   For more information, see the [ListAssets](https://docs.aws.amazon.com/iot-sitewise/latest/APIReference/API_ListAssets.html) operation.

1. If the previous command returns any assets from the model, delete each asset. For more information, see [Delete an asset (AWS CLI)](delete-assets.md#delete-asset-cli).

1. Run the following command to delete the asset model. Replace *asset-model-id* with the ID or external ID of the asset model.

   ```
   aws iotsitewise delete-asset-model --asset-model-id asset-model-id
   ```

**Important**  
 To avoid deleting an asset model that was concurrently updated since the last read operation, you must define a conditional delete request. See [Optimistic locking for asset model writes](opt-locking-for-model.md). 

# 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"
      }
    }
  }
}
```