4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS IoT Core でモノの接続状態をオンデマンドで取得する2つの方法

Posted at

はじめに

こんにちは、ほうき星です。

皆さんは、AWS IoT Core に接続した自作 IoT デバイス(Raspberry Pi / ESP32 など)が
「今オンラインなのか、それともオフラインなのか」を確認したいと思ったことはありませんか?

私は自作した IoT デバイス(Raspberry Pi / ESP32 など)を AWS IoT Core に接続して運用しており、S3 上にホストした Web アプリから操作できるようにしています。
しかし、Web アプリから操作しても反応がないことがあり、原因を調べてみると、IoT デバイスが AWS IoT Core から切断されたままになっているケースがありました。

このような場合、Web アプリ上でデバイスの状態を「オフライン」と表示できれば、ユーザーにとってより親切な UI になるはずです。

そこで本記事では、IoT デバイスの接続状態を オンデマンド で取得する方法として、

  • フリートインデックス(Fleet Indexing)を利用する方法
  • Device Shadow を利用する方法

の 2 つをご紹介します。

なお、デバイスの切断を即座に検知して通知するリアルタイム通知の方法については、別記事で解説する予定です。

方法① フリートインデックス(Fleet Indexing)を利用する方法

AWS IoT Core に IoT デバイス(モノ)を接続しただけでは、接続や切断といった「Lifecycle Events」は発生しますが、「今そのデバイスがオンラインなのか」をオンデマンドで問い合わせることはできません。

しかし、フリートインデックスを作成することで、IoT デバイス(モノ)の接続状態を取得することができるようになります。

実装方法

  1. マネジメントコンソールにて AWS IoT > 設定よりインデックス作成の管理を押下します

    image.png

  2. フリートのインデックス作成の管理にてモノのインデックス作成にチェックを入れ、モノの接続の追加にチェックし、画面下部の更新を押下します

    image.png
    image.png

  3. モノの接続に関するフリートのインデックス作成ができればOKです

    image.png

動作確認

  1. IoT デバイス(モノ)を IoT Core に接続します
    フリートのインデックス作成でモノの接続を有効にすると、AWS IoT ? 管理 > モノ > 該当のIoT デバイスに現在の接続状態が表示されるようになります

    image.png

  2. IoT デバイス(モノ)を IoT Core から切断します
    ※電源断で切断しました

  3. IoT デバイス(モノ)の切断後、AWS IoT ? 管理 > モノ > 該当のIoT デバイス状の表示も接続されていませんの表示になればOKです

    image.png

  4. AWS CLI等を使用して情報を取得することもできます

取得例
$ aws iot get-thing-connectivity-data --thing-name 該当のIoT デバイス
{
    "thingName": "該当のIoT デバイス",
    "connected": false,
    "timestamp": "2026-01-12T01:24:28.506000+00:00",
    "disconnectReason": "MQTT_KEEP_ALIVE_TIMEOUT"
}

方法② Device Shadow を利用する方法

方法①はフリートインデックス(Fleet Indexing)を有効にするだけで接続状態を取得することができ便利に思えます。

しかし、Web アプリ等の設計を考えるとIoT デバイス(モノ)の状態(接続状態や、照明器具なら「明るさ」など)を一括で取得できた方が望ましく、前述の方法ではフリートインデックスと Device Shadow からそれぞれ取得する必要があり、アプリケーション側の実装が煩雑になりがちです。

そこで、Device Shadow に 接続状態を保持するステート:connected を追加しDevice Shadow に状態を一元化、オンデマンドでの状態取得を簡潔にできるようにします。

実装方法 IoT デバイス(モノ)側:接続中は「connected: true」を常に報告

IoT デバイス(モノ)からは Device Shadow に接続状態を常に connected: true として報告します。

例えば Micro Python で実装した IoT な照明器具の場合、明るさ(brightness)に加え接続状態(connected)を報告(reported)する実装とします。

Micro Pythonでの例
shadow: dict = {
    "brightness": brightness,
    "connected": True
}
mqtt_client.publish(
    f"$aws/things/{THING_NAME}/shadow/update",
    json.dumps({
        "state": {
            "reported": shadow
        }
    }).encode()
)

Micro Python でのサンプルコード全文は以下のリポジトリにおいています。
合わせて確認いただけると幸いです。

実装方法 Lambda側:接続断を検知した Lambda が「connected: false」で更新

IoT デバイス(モノ)からは常に connected: true が報告されます。
そのためIoT デバイス(モノ)の接続が切れた際にはIoT デバイス(モノ)以外から connected: false を報告する必要があります。

IoT Core の Lifecycle Events を使用して IoT ルールでデバイスの接続断をトリガーに、Lambda 関数を用いて該当のIoT デバイス(モノ)の Device Shadowに connected: false を報告します。


Lifecycle Events については以下ドキュメントも参考にしてください。

IoT デバイス(モノ)が切断された時に「connected: false」を Device Shadow に報告する Lambda
import json

import boto3

def lambda_handler(event, context) -> None:
    client = boto3.client("iot-data")

    shadow: dict = {
        "state": {
            "reported": {
                "connected": False
            }
        }
    }

    response: dict = client.update_thing_shadow(
        thingName = event["thingName"],
        payload = json.dumps(shadow, ensure_ascii=False)
    )

    if response["ResponseMetadata"]["HTTPStatusCode"] != 200:
        raise Exception("DeviceShadowの更新に失敗")

IoT デバイス(モノ)が切断された時に「connected: false」を Device Shadow に報告する Lambda の SAM テンプレート
AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Description: "IoT Thing Connection Down Reporter"

Resources:
  IoTThingConnectionDownReporter:
    Type: "AWS::Serverless::Function"
    Properties:
      Description: "IoT Thing の接続が切れた際に、該当の Thing  Device Shadow を更新する Lambda 関数"
      Events:
        IoTThingConnectionDownEvent:
          Type: "IoTRule"
          Properties:
            Sql: "SELECT * FROM '$aws/events/presence/disconnected/+'"
      FunctionName: "iot-thing-connection-down-reporter"
      Handler: "lambda_function.lambda_handler"
      MemorySize: 128
      PackageType: "Zip"
      Policies:
        - AWSLambdaBasicExecutionRole
        - Statement:
            - Effect: "Allow"
              Action: "iot:UpdateThingShadow"
              Resource: !Sub "arn:aws:iot:${AWS::Region}:${AWS::AccountId}:thing/*"
      Timeout: 10
      Runtime: "python3.13"

Lambda(sam)のサンプルコードは以下のリポジトリにもおいています。
合わせて確認いただけると幸いです。

動作確認

  1. IoT デバイス(モノ)を IoT Core に接続します
    Device Shadow 上に connected ステートが存在し、 true であることが確認できます

    image.png

  2. IoT デバイス(モノ)を IoT Core から切断します
    ※電源断で切断しました

  3. IoT デバイス(モノ)の切断に伴って Device Shadow の connected ステートが false に更新されたことを確認できればOKです

    image.png

さいごに

今回はIoT デバイス(モノ)の接続状態をオンデマンドで取得する方法を2つご紹介しました。

フリートインデックスを利用するパターンは手軽な反面、アプリケーションから IoT デバイスの状態(Device Shadow)とあわせて取得したい場合、取得元が分散し、実装が複雑になりがちです。

Device Shadow に接続状態のステートも持たせておき、接続断時に発生する Lifecycle Events をトリガーに Lambda 関数から接続状態を更新しておけば、アプリ側の実装は簡潔になりオススメです。

この記事が皆さんの IoT ライフの助けになれば幸いです!

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?