IoT Core ルールのSQLで名前にハイフン「-」があるJSONを参照するときは、get()関数を使いましょうという話

IoT Coreのルール(SQL)で名前にハイフン「-」があるJSONを扱うとき、そのまま参照するとルールの実行に失敗します。 これを回避するためには get() を利用して参照します。
2020.03.24

IoT Coreのルール(SQL)で名前にハイフン-を含むJSONの参照に失敗しました。 地味にハマる部分でもあり、気づくまで時間がかかる事もあるため、初めからget()を使うと良さそうです。

扱うJSONデータの例

下記のJSONデータとします。

{
    "id": "123",
    "bbb": "this is sample.",
    "hoge": {
        "xxx-yyy": true
    }
}

IoT ルール実行が失敗するとき

JSONデータのxxx-yyytrueのときだけ、アクションが実行されるように設定しますが、このSQLを使ってもルールアクションは実行されません。

SELECT
  *
FROM
  '/topic/sample'
WHERE
  hoge.xxx-yyy = true

get()を使って参照する

IoT ルールを設定する

ルールクエリ(SQL)

get()を用いてJSONデータのxxx-yyytrueのときだけ、アクションが実行されるようにします。

SELECT
  *
FROM
  '/topic/sample'
WHERE
  get(hoge, 'xxx-yyy') = true

ちなみに、最上位階層にある場合は、get(*, 'xxx-yyy')で参照できます。

アクション

DynamoDBv2を用いて、DynamoDBテーブルにデータを格納します。

IoT Coreのルールの様子

DynamoDBテーブルは、ハッシュキーがid(str)になっています。

利用するDynamoDBの定義

トピックにデータをPublishする

IoT Coreのテスト画面でPublishします。

  • トピック: /topic/sample
  • JSONデータ:下記
{
    "id": "123",
    "bbb": "this is sample.",
    "hoge": {
        "xxx-yyy": true
    }
}

IoT Coreのテスト画面でデータをPublishする

動作結果

無事にIoTルールが実行され、DynamoDBテーブルにデータが格納されました。

DynamoDBにデータが格納された様子

さいごに

多くのプログラミング言語では変数名にハイフン-が使えません。おそらく演算子のマイナス-と区別できないからだと思います。 今にして思えば「確かに……」という感想ですが、地味にハマります。 初めからget()を使うと良さそうですね。

ASCII 範囲 (U+0001..U+007F) 内では、識別子として有効な文字は Python 2.x におけるものと同じです。 大文字と小文字の A から Z、アンダースコア _、先頭の文字を除く数字 0 から 9 です。

https://docs.python.org/ja/3/reference/lexical_analysis.html#identifiers

参考