はじめに
こんにちは、ほうき星です。
皆さんは、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 デバイス(モノ)の接続状態を取得することができるようになります。
実装方法
-
マネジメントコンソールにて AWS IoT > 設定より
インデックス作成の管理を押下します -
フリートのインデックス作成の管理にて
モノのインデックス作成にチェックを入れ、モノの接続の追加にチェックし、画面下部の更新を押下します -
モノの接続に関するフリートのインデックス作成ができればOKです
動作確認
-
IoT デバイス(モノ)を IoT Core に接続します
フリートのインデックス作成でモノの接続を有効にすると、AWS IoT ? 管理 > モノ > 該当のIoT デバイスに現在の接続状態が表示されるようになります -
IoT デバイス(モノ)を IoT Core から切断します
※電源断で切断しました
-
IoT デバイス(モノ)の切断後、AWS IoT ? 管理 > モノ > 該当のIoT デバイス状の表示も
接続されていませんの表示になればOKです -
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)する実装とします。
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 については以下ドキュメントも参考にしてください。
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の更新に失敗")
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)のサンプルコードは以下のリポジトリにもおいています。
合わせて確認いただけると幸いです。
動作確認
-
IoT デバイス(モノ)を IoT Core に接続します
Device Shadow 上に connected ステートが存在し、 true であることが確認できます -
IoT デバイス(モノ)を IoT Core から切断します
※電源断で切断しました -
IoT デバイス(モノ)の切断に伴って Device Shadow の connected ステートが false に更新されたことを確認できればOKです
さいごに
今回はIoT デバイス(モノ)の接続状態をオンデマンドで取得する方法を2つご紹介しました。
フリートインデックスを利用するパターンは手軽な反面、アプリケーションから IoT デバイスの状態(Device Shadow)とあわせて取得したい場合、取得元が分散し、実装が複雑になりがちです。
Device Shadow に接続状態のステートも持たせておき、接続断時に発生する Lifecycle Events をトリガーに Lambda 関数から接続状態を更新しておけば、アプリ側の実装は簡潔になりオススメです。
この記事が皆さんの IoT ライフの助けになれば幸いです!







