【问题标题】:AWS IoT DynamoDB rule not able to read value SELECTed from topic() functionAWS IoT DynamoDB 规则无法读取从 topic() 函数中选择的值
【发布时间】:2020-05-15 20:07:25
【问题描述】:

我正在尝试使用规则将来自 AWS IoT MQTT 主题的数据导入 DynamoDB。 一个示例主题是cooler/cooler42/sensors 和示例消息

{ "waterTemp": 10, "timestamp": 1580370731383 }

我已经这样定义查询,从主题中提取deviceName(例如cooler42)并将其插入JSON:

SELECT *, topic(2) AS deviceName FROM 'cooler/+/sensors'

这似乎确实有效,好像我将消息重新发布到另一个主题我现在看到添加了 deviceName 的相同 JSON:

{ "waterTemp": 10, "timestamp": 1580370731383, "deviceName": "cooler42" }

我的理解是,所有 3 个字段现在都应该可以在我的 DynamoDB 规则中使用,如下所示:

但是,我可以从 CloudWatch 看到该规则因错误而失败 One or more parameter values were invalid: An AttributeValue may not contain an empty string (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException 和分区键(又名哈希键)是空的:

{ "ItemRangeKeyValue":"1580370731383", "IsPayloadJSON":"true", "ItemHashKeyField":"deviceName", "Operation":"Insert", "ItemRangeKeyField":"timestamp", "Table":"SensorDataTest2", "ItemHashKeyValue":"" <--- Empty }

我不能使用我刚刚从规则中的主题名称中选择的deviceName 吗?如果没有,还有其他方法可以提取吗?

注意,如果我手动将消息发布到已经包含 deviceName 的主题上,那么它确实可以正常工作,但我在受限环境中工作并且不希望额外的有效负载大小。

【问题讨论】:

    标签: amazon-web-services amazon-dynamodb aws-iot


    【解决方案1】:

    键值使用不能引用 deviceName 别名 (*) 的 substitution template

    AWS 文档强调了这一点:

    因为替换模板中的表达式是与“SELECT ...”语句分开计算的,所以您不能引用使用 AS 子句创建的别名。除了支持的函数和运算符之外,您只能引用原始有效负载中存在的信息。

    您只能参考原始有效载荷中的信息。

    由于原始负载中不存在别名,您可以使用${topic(2)} 作为分区键值。该函数可以访问主题,尽管这意味着键值与主题名称耦合。

    另一种选择是让规则重新发布到负载中带有deviceName 的另一个主题。处理此主题的规则/操作可以写入 DynamoDB。然后,此操作将有权访问 deviceName 属性,因为它在重新发布的有效负载中可用。


    * 文档暗示键值语法是替换模板。

    上面的链接说:

    替换模板出现在规则内的操作参数中

    但是,我还通过使用encode 函数将操作中可用的整个有效负载写入表来验证函数可用的有效负载不包含别名。

    例如使用包含一些别名的规则:

    将操作配置为使用${encode(*, 'base64')}Sort key value,它将整个有效负载编码为base 64 字符串。

    当您发布消息时:

    此消息写入 DynamoDB 为:

    {
      "DateTime": "ewogICJtZXNzYWdlIjogIkhlbGxvIGZyb20gQVdTIElvVCBjb25zb2xlIgp9",
      "Payload": {
        "arrivalTime": 1581082253585,
        "myField": "Hello from AWS IoT console",
        "payload": {
          "message": "Hello from AWS IoT console"
        }
      },
      "Topic": "blt/test"
    }
    

    包括别名在内的整个有效负载位于Payload 字段中。 但是解码 DateTime 字段中的 base 64 字符串将显示别名不存在于 encode 函数中。

    【讨论】:

    • 谢谢!我已经确认可以在规则屏幕中直接引用 {topic(2)} 并且它工作正常。我还可以看到有效载荷信息的编码对于调试也非常有用。
    • 没问题。如果它解决了您的问题,请随时将其标记为答案。
    【解决方案2】:

    我有一个完整的教程:

    CPU Temperature - IoT Project

    您可以使用 AWS 的 MQTT 库:Notebook

    将遥测数据发送到 AWS IoT 并保存在 DynamoDB 中:

    然后运行查询:

    SELECT message.reported.* FROM '#'
    

    然后使用 Quick Sight 或 Kibana 创建实时仪表板。整个思路如下:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-26
      • 2019-05-03
      • 1970-01-01
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      相关资源
      最近更新 更多