Skip to content

AWS IOT Rule to update DynamoDB

0

Hi, I have setup an AWS IOT rule ("SELECT param1, param2, param3 from topic/test") that updates a dynamodb. The Rule and associated actions get triggered. However, I see that this does an INSERT/OVERWRITE action of the entire row of the table and hence the values in other columns (other than param1, param2 and param3) get deleted... Is they anyway to retain the other columns and just update these 3 parameters when the rule action happens on dynamodb? Kindly let know. Thanks a ton.

asked 2 years ago297 views
2 Answers
1

The behavior you're experiencing is the default for AWS IoT rules when updating DynamoDB. However, there are ways to update only specific attributes without overwriting the entire item. Here's how you can modify your setup to achieve this:

  1. Use UpdateItem instead of PutItem: By default, the IoT rule action uses PutItem, which overwrites the entire item. To update only specific attributes, you need to use UpdateItem.

  2. Modify your IoT rule action: In the AWS IoT console or using the AWS CLI, modify your rule action to use UpdateItem. Here's an example of how to set this up:

    {
      "sql": "SELECT param1, param2, param3 FROM 'topic/test'",
      "ruleDisabled": false,
      "awsIotSqlVersion": "2016-03-23",
      "actions": [{
        "dynamoDB": {
          "tableName": "YourTableName",
          "roleArn": "arn:aws:iam::your-account-id:role/your-role",
          "operation": "UPDATE",
          "hashKeyField": "your-hash-key",
          "hashKeyValue": "${topic()}",
          "hashKeyType": "STRING",
          "rangeKeyField": "your-range-key",
          "rangeKeyValue": "${timestamp()}",
          "rangeKeyType": "NUMBER",
          "payloadField": "payload"
        }
      }]
    }
  3. Use an UpdateExpression: In your DynamoDB action, include an UpdateExpression to specify which attributes to update:

    "dynamoDBv2": {
      "roleName": "your-role",
      "putItem": {
        "tableName": "YourTableName",
        "conditionExpression": "attribute_exists(#pk)",
        "expressionAttributeNames": {"#pk": "your-primary-key"},
        "updateExpression": "SET param1 = :p1, param2 = :p2, param3 = :p3"
      }
    }
  4. Use substitution templates: Use ${param1}, ${param2}, and ${param3} in your UpdateExpression to dynamically set the values from your IoT message.

  5. Handle new items: If you want to insert a new item when it doesn't exist, you can use a conditional write:

    "conditionExpression": "attribute_not_exists(#pk)",
    "expressionAttributeNames": {"#pk": "your-primary-key"}
  6. Consider using a Lambda function: For more complex updates or conditional logic, you can use a Lambda function as the rule action. This gives you full control over how the DynamoDB item is updated.

By implementing these changes, your IoT rule will update only the specified attributes (param1, param2, param3) in your DynamoDB table, preserving the values in other columns.

Remember to test your setup thoroughly to ensure it behaves as expected with different types of messages and scenarios.

AWS
answered 2 years ago
AWS
EXPERT
reviewed a year ago
1

Your JSON structure is close, but it needs some adjustments to work with AWS IoT SiteWise's batch data ingestion format. Here's a simple example that should work for buffered ingestion into SiteWise:

{
  "entries": [
    {
      "entryId": "1",
      "assetId": "12345678-90ab-cdef-1234-567890abcdef",
      "propertyValues": [
        {
          "propertyId": "34567890-1bcd-ef12-3456-7890abcdef12",
          "propertyAlias": "/wind_turbine_1/temperature",
          "propertyValues": [
            {
              "value": {
                "doubleValue": 74.2
              },
              "timestamp": {
                "timeInSeconds": 1695981000,
                "offsetInNanos": 0
              },
              "quality": "GOOD"
            }
          ]
        },
        {
          "propertyId": "45678901-2cde-f123-4567-890abcdef123",
          "propertyAlias": "/wind_turbine_1/rotation_speed",
          "propertyValues": [
            {
              "value": {
                "integerValue": 1540
              },
              "timestamp": {
                "timeInSeconds": 1695981000,
                "offsetInNanos": 0
              },
              "quality": "GOOD"
            }
          ]
        }
      ]
    }
  ]
}

Key points about this structure:

  1. The top-level key is entries, not assets.

  2. Each entry has an entryId, which is a unique identifier for the entry in the batch.

  3. assetId is used instead of assetModelId and assetName.

  4. Property values are nested under propertyValues.

  5. Each property can have multiple values, hence the array under propertyValues.

  6. The value field specifies the data type (doubleValue for decimals, integerValue for whole numbers).

  7. Timestamps are in Unix epoch format (seconds since 1970-01-01) with an optional nanosecond offset.

  8. A quality field is included for each value.

  9. You can use either propertyId or propertyAlias to identify properties, but not both in the same entry.

This JSON structure should work for buffered ingestion into AWS IoT SiteWise when stored in S3. Remember to configure your SiteWise ingestion job to point to the S3 bucket and file containing this data.

Also, ensure that the asset and property IDs in your JSON match those in your SiteWise asset model. The timestamp in the example (1695981000) corresponds to 2023-09-29T10:10:00Z, matching your original timestamp.

AWS
answered 2 years ago
AWS
EXPERT
reviewed a year ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.