

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# AWS IoT Device SDKs を使用したソリューションの構築
<a name="iot-tutorials-sdk-intro"></a>

このセクションのチュートリアルでは、 を使用して本番環境にデプロイできる IoT ソリューションを開発する手順について説明します AWS IoT。

これらのチュートリアルは、 AWS IoT Device SDKs を使用し、安全で信頼性の高いソリューションを作成するために適用されている概念をより詳細に説明[AWS IoT Device Client を使用したデモの構築](iot-tutorials-dc-intro.md)するため、 のセクションよりも完了までに時間がかかる場合があります。

## AWS IoT Device SDKsを使用してソリューションの構築を開始する
<a name="iot-sdk-tutorial-overview"></a>

これらのチュートリアルでは、さまざまな AWS IoT シナリオについて説明します。必要に応じて、チュートリアルでは AWS IoT Device SDKsを使用します。

**Topics**
+ [AWS IoT Device SDKsを使用してソリューションの構築を開始する](#iot-sdk-tutorial-overview)
+ [チュートリアル: Device SDK AWS IoT Core を使用して AWS IoT デバイスを に接続する](sdk-tutorials.md)
+ [デバイスデータを他の サービスにルーティングする AWS IoT ルールの作成](iot-rules-tutorial.md)
+ [デバイスがオフラインになっている間にデバイスの状態をデバイスシャドウで保持する](iot-shadows-tutorial.md)
+ [チュートリアル: のカスタムオーソライザーの作成 AWS IoT Core](custom-auth-tutorial.md)
+ [チュートリアル: AWS IoT と Raspberry Pi を使用した土壌湿度のモニタリング](iot-moisture-tutorial.md)

# チュートリアル: Device SDK AWS IoT Core を使用して AWS IoT デバイスを に接続する
<a name="sdk-tutorials"></a>

このチュートリアルでは、デバイスを に接続 AWS IoT Core して、データを送受信する方法を示します AWS IoT。このチュートリアルを完了する AWS IoT Core と、デバイスが に接続するように設定され、デバイスが と通信する方法を理解できます AWS IoT。

**Topics**
+ [前提条件](#sdk-tutorials-prereq)
+ [のデバイスを準備します。 AWS IoT](#sdk-tutorials-prepare)
+ [MQTT プロトコルを確認する](#sdk-tutorials-mqtt-review)
+ [pubsub.py Device SDK サンプルアプリケーションを確認する](#sdk-tutorials-explore-sample)
+ [デバイスを接続して と通信する AWS IoT Core](#sdk-tutorials-experiment)
+ [結果を確認する](#sdk-tutorials-conclusion)
+ [チュートリアル: AWS IoT Device SDK for Embedded C の使用](iot-embedded-c-sdk.md)

## 前提条件
<a name="sdk-tutorials-prereq"></a>

このチュートリアルを開始する前に、以下の要件を満たしていることを確認してください。
+ 

**[AWS IoT Core チュートリアルの開始方法](iot-gs.md) を完了していること**  
[デバイスを設定する](configure-device.md) する必要があるチュートリアルのセクションで、デバイスの [Raspberry Pi または他のデバイスを接続する](connecting-to-existing-device.md) オプションを選択し、Python 言語オプションを使用してデバイスを設定します。
**注記**  
このチュートリアルでも使用するため、そのチュートリアルで使用するターミナルウィンドウは開いたままにします。
+ 

**Device SDK v2 for Python を実行できる AWS IoT デバイス。**  
このチュートリアルでは、比較的強力なデバイスを必要とする Python コード例 AWS IoT Core を使用して、デバイスを に接続する方法を示します。リソースに制約のあるデバイスを使用している場合は、これらのコード例が機能しない可能性があります。その場合は、「[チュートリアル: AWS IoT Device SDK for Embedded C の使用](iot-embedded-c-sdk.md)」チュートリアルの方が、接続に成功する可能性がより高くなります。
+ 

**デバイスに接続するために必要な情報を取得済みであること**  
デバイスを に接続するには AWS IoT、モノの名前、ホスト名、ポート番号に関する情報が必要です。
**注記**  
カスタム認証を使用してデバイスを AWS IoT Coreに接続することもできます。オーソライザーの Lambda 関数に渡す接続データは、使用するプロトコルによって異なります。
  + **モノの名前**: 接続する AWS IoT モノの名前。デバイスとして を AWS IoT モノとして登録している必要があります。詳細については、「[を使用したデバイスの管理 AWS IoT](iot-thing-management.md)」を参照してください。
  + **ホスト名**: アカウント固有の IoT エンドポイントのホスト名。
  + **ポート番号**: 接続先のポート番号。

  Python SDK の AWS IoT `configureEndpoint`メソッドを使用して、ホスト名とポート番号を設定できます。

  ```
  myAWSIoTMQTTClient.configureEndpoint("random.iot.region.amazonaws.com", 8883)
  ```

## のデバイスを準備します。 AWS IoT
<a name="sdk-tutorials-prepare"></a>

[AWS IoT Core チュートリアルの開始方法](iot-gs.md) では、デバイスと AWS アカウントが通信できるように準備しました。このセクションでは、 とのデバイス接続に適用される準備の側面を確認します AWS IoT Core。

デバイスの AWS IoT Core接続に際して

1. **AWS アカウント** が必要です。

   の手順[セットアップ AWS アカウント](setting-up.md)では、 をまだ作成 AWS アカウント していない場合に を作成する方法について説明します。

1. そのアカウントでは、 AWS アカウント および リージョンのデバイスに次の**AWS IoT リソース**を定義する必要があります。

   [AWS IoT リソースの作成](create-iot-resources.md) の手順では、 AWS アカウント とリージョンのデバイス用にこれらのリソースを作成する方法が示されています。
   +  AWS IoT に登録され、デバイスを認証するために有効化された**デバイス証明書**。

     多くの場合、証明書は **AWS IoT モノのオブジェクト**を使用して作成され、そのオブジェクトにアタッチされます。モノのオブジェクトはデバイスが に接続するためには必要ありませんが AWS IoT、追加の AWS IoT 機能がデバイスで利用可能になります。
   + デバイス証明書にアタッチされた**ポリシー**で、接続 AWS IoT Core して必要なすべてのアクションを実行することを許可します。

1.  AWS アカウントのデバイスエンドポイントにアクセスできる**インターネット接続**。

   デバイスエンドポイントは で説明[AWS IoT デバイスデータとサービスエンドポイント](iot-connect-devices.md#iot-connect-device-endpoints)されており、[AWS IoT コンソールの設定ページ](https://console.aws.amazon.com/iot/home#/settings)に表示されます。

1. **通信ソフトウェア** ( AWS IoT Device SDK が提供するものなど)。このチュートリアルでは、[AWS IoT Device SDK v2 for Python](https://github.com/aws/aws-iot-device-sdk-python-v2#aws-iot-device-sdk-v2-for-python) を使用します。

## MQTT プロトコルを確認する
<a name="sdk-tutorials-mqtt-review"></a>

サンプルアプリケーションについて説明する前に、MQTT プロトコルを理解しておくと役立ちます。MQTT プロトコルには、HTTP などの他のネットワーク通信プロトコルに比べていくつかの利点があり、IoT デバイスで一般的な選択肢となっています。このセクションでは、このチュートリアルに適用される MQTT の主要な側面を確認します。MQTT と HTTP を比較する方法の詳細については、「[デバイス通信用のアプリケーションプロトコルの選択](protocols.md#protocol-selection)」を参照してください。

**MQTT は、発行/サブスクライブ通信モデルを使用します**  
MQTT プロトコルは、ホストとの発行/サブスクライブ通信モデルを使用します。このモデルは、HTTP が使用するリクエスト/応答モデルとは異なります。MQTT では、デバイスは一意のクライアント ID によって識別されるホストとのセッションを確立します。データを送信するために、デバイスはトピックによって識別されたメッセージをホストのメッセージブローカーに発行します。メッセージブローカーからメッセージを受信するために、デバイスは、サブスクリプションリクエストでトピックフィルターをメッセージブローカーに送信することにより、トピックをサブスクライブします。

**MQTT サポート永続セッション**  
メッセージブローカーは、デバイスからメッセージを受信し、サブスクライブしているデバイスにメッセージを発行します。[永続セッション](mqtt.md#mqtt-persistent-sessions) (開始デバイスが切断されている場合でもアクティブなセッション) では、デバイスは、切断中に発行されたメッセージを取得できます。デバイス側では、MQTT は、デバイスによって送信されたメッセージをホストが確実に受信できるようにするサービス品質レベル ([QoS](mqtt.md#mqtt-qos)) をサポートします。

## pubsub.py Device SDK サンプルアプリケーションを確認する
<a name="sdk-tutorials-explore-sample"></a>

このセクションでは、このチュートリアルで使用されている **AWS IoT Device SDK v2 for Python** の `pubsub.py` サンプルアプリケーションを確認します。ここでは、 に接続 AWS IoT Core して MQTT メッセージを発行およびサブスクライブする方法を確認します。次のセクションでは、デバイスが接続および通信する方法を調べるのに役立ついくつかの演習を示します AWS IoT Core。

**`pubsub.py` サンプルアプリケーションは、 との MQTT 接続のこれらの側面を示しています AWS IoT Core。**
+ [通信プロトコル](#sdk-tutorials-explore-protocols)
+ [永続セッション](#sdk-tutorials-explore-persistent)
+ [サービスの品質](#sdk-tutorials-explore-qos)
+ [メッセージの発行](#sdk-tutorials-explore-publish)
+ [メッセージのサブスクリプション](#sdk-tutorials-explore-subscribe)
+ [デバイスの切断と再接続](#sdk-tutorials-explore-connect)

### 通信プロトコル
<a name="sdk-tutorials-explore-protocols"></a>

`pubsub.py` サンプルは、MQTT および MQTT over WSS プロトコルを使用した MQTT 接続を示しています。[AWS 共通ランタイム (AWS CRT)](https://github.com/awslabs/aws-crt-python#aws-crt-python) ライブラリは、低レベルの通信プロトコルサポートを提供し、 AWS IoT Device SDK v2 for Python に含まれています。

#### MQTT
<a name="sdk-tutorials-explore-mqtt"></a>

この`pubsub.py`サンプルでは`mtls_from_path`、MQTT プロトコル AWS IoT Core を使用して との接続を確立[https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py)するために、 で (ここに示す) を呼び出します。 `mtls_from_path`は X.509 証明書と TLS v1.2 を使用してデバイスを認証します。CRT AWS ライブラリは、その接続の下位レベルの詳細を処理します。

```
mqtt_connection = mqtt_connection_builder.mtls_from_path(
    endpoint=args.endpoint,
    cert_filepath=args.cert,
    pri_key_filepath=args.key,
    ca_filepath=args.ca_file,
    client_bootstrap=client_bootstrap,
    on_connection_interrupted=on_connection_interrupted,
    on_connection_resumed=on_connection_resumed,
    client_id=args.client_id,
    clean_session=False,
    keep_alive_secs=6
)
```

`endpoint`  
 AWS アカウントの IoT デバイスエンドポイント  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`cert_filepath`  
デバイスの証明書ファイルへのパス  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`pri_key_filepath`  
証明書ファイルで作成されたデバイスのプライベートキーファイルへのパス  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`ca_filepath`  
Root CA ファイルへのパス。MQTT サーバーがまだトラストストアにない証明書を使用する場合にのみ必要です。  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`client_bootstrap`  
ソケット通信アクティビティを処理する共通ランタイムオブジェクト  
サンプルアプリケーションでは、このオブジェクトは `mqtt_connection_builder.mtls_from_path` の呼び出しの前にインスタンス化されます。

`on_connection_interrupted``on_connection_resumed`  
デバイスの接続が中断され、再開されたときに呼び出すコールバック関数

`client_id`  
 AWS リージョンでこのデバイスを一意に識別する ID  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`clean_session`  
新しい永続セッションを開始するか、既存のセッションに再接続するか (存在する場合)

`keep_alive_secs`  
`CONNECT` リクエストで送信するキープアライブ値 (秒単位)。この間隔で ping が自動的に送信されます。サーバーは、この値の 1.5 倍の時間が経過しても ping を受信しなかった場合、接続が失われたとみなします。

#### MQTT over WSS
<a name="sdk-tutorials-explore-mqtt-wss"></a>

`pubsub.py` サンプルでは、[https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py) の `websockets_with_default_aws_signing` (以下に示されています) を呼び出して、WSS 経由で MQTT プロトコルを使用して AWS IoT Core との接続を確立します。`websockets_with_default_aws_signing` は、[署名 V4](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) を使用して WSS 経由で MQTT 接続を作成し、デバイスを認証します。

```
mqtt_connection = mqtt_connection_builder.websockets_with_default_aws_signing(
    endpoint=args.endpoint,
    client_bootstrap=client_bootstrap,
    region=args.signing_region,
    credentials_provider=credentials_provider,
    websocket_proxy_options=proxy_options,
    ca_filepath=args.ca_file,
    on_connection_interrupted=on_connection_interrupted,
    on_connection_resumed=on_connection_resumed,
    client_id=args.client_id,
    clean_session=False,
    keep_alive_secs=6
)
```

`endpoint`  
 AWS アカウントの IoT デバイスエンドポイント  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`client_bootstrap`  
ソケット通信アクティビティを処理する共通ランタイムオブジェクト  
サンプルアプリケーションでは、このオブジェクトは `mqtt_connection_builder.websockets_with_default_aws_signing` の呼び出しの前にインスタンス化されます。

`region`  
 AWS 署名 V4 認証で使用される署名リージョン。`pubsub.py` では、コマンドラインに入力されたパラメータを渡します。  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`credentials_provider`  
認証に使用するために提供される AWS 認証情報  
サンプルアプリケーションでは、このオブジェクトは `mqtt_connection_builder.websockets_with_default_aws_signing` の呼び出しの前にインスタンス化されます。

`websocket_proxy_options`  
HTTP プロキシオプション (プロキシホストを使用している場合)  
サンプルアプリケーションでは、この値は `mqtt_connection_builder.websockets_with_default_aws_signing` の呼び出しの前に初期化されます。

`ca_filepath`  
Root CA ファイルへのパス。MQTT サーバーがまだトラストストアにない証明書を使用する場合にのみ必要です。  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`on_connection_interrupted``on_connection_resumed`  
デバイスの接続が中断され、再開されたときに呼び出すコールバック関数

`client_id`  
 AWS リージョンでこのデバイスを一意に識別する ID。  
サンプルアプリケーションでは、この値はコマンドラインから渡されます。

`clean_session`  
新しい永続セッションを開始するか、既存のセッションに再接続するか (存在する場合)

`keep_alive_secs`  
`CONNECT` リクエストで送信するキープアライブ値 (秒単位)。この間隔で ping が自動的に送信されます。サーバーは、この値の 1.5 倍の時間が経過しても ping を受信しなかった場合、接続が失われたとみなします。

#### HTTPS
<a name="sdk-tutorials-explore-https"></a>

HTTPS とは? では、HTTPS リクエストを発行するデバイス AWS IoT Core をサポートしています。プログラミングの観点からは、デバイスは他のアプリケーションと同様に HTTPS リクエストを AWS IoT Core に送信します。デバイスから HTTP メッセージを送信する Python プログラムの例については、Python の `requests` ライブラリを使用した [HTTPS コード例](http.md#codeexample)を参照してください。この例では、 が AWS IoT Core MQTT メッセージとして解釈するように、HTTPS AWS IoT Core を使用して にメッセージを送信します。

はデバイスからの HTTPS リクエスト AWS IoT Core をサポートしますが、デバイスの通信に使用するプロトコルについて情報に基づいた決定[デバイス通信用のアプリケーションプロトコルの選択](protocols.md#protocol-selection)ができるように、 に関する情報を必ず確認してください。

### 永続セッション
<a name="sdk-tutorials-explore-persistent"></a>

サンプルアプリケーションでは、`clean_session` パラメータを `False` に設定して、接続を永続化する必要があることを示します。実際には、これは、この呼び出しによって開かれた接続が、既存の永続セッション (存在する場合) に再接続することを意味します。そうでなければ、新しい永続セッションを作成して接続します。

永続セッションでは、デバイスに送信されたメッセージは、デバイスが接続されていない間、メッセージブローカーによって保存されます。デバイスが永続セッションに再接続すると、メッセージブローカーは、サブスクライブしている保存済みメッセージをデバイスに送信します。

永続セッションがない場合、デバイスは、デバイスが接続されていないときに送信されたメッセージを受信しません。どのオプションを使用するかは、アプリケーションと、デバイスが接続されていないときに発生するメッセージを通信する必要があるかどうかによって異なります。詳細については、「」を参照してください[MQTT 永続的セッション](mqtt.md#mqtt-persistent-sessions)

### サービスの品質
<a name="sdk-tutorials-explore-qos"></a>

デバイスがメッセージを発行およびサブスクライブするときに、優先するサービス品質 (QoS) を設定できます。 は、発行およびサブスクライブオペレーションの QoS レベル 0 と 1 AWS IoT をサポートします。の QoS レベルの詳細については AWS IoT、「」を参照してください[MQTT Quality of Service (QoS) オプション](mqtt.md#mqtt-qos)。

Python の AWS CRT ランタイムは、サポートされる QoS レベルにこれらの定数を定義します。


**Python サービス品質レベル**  

| MQTT QoS レベル | SDK で使用される Python シンボリック値 | 説明 | 
| --- | --- | --- | 
| QoS レベル 0 | mqtt.QoS.AT\$1MOST\$1ONCE | メッセージの送信は、受信されたかどうかにかかわらず、1 回だけ行われます。例えば、デバイスが接続されていない場合やネットワークエラーがある場合など、メッセージがまったく送信されない場合があります。 | 
| QoS レベル 1 | mqtt.QoS.AT\$1LEAST\$1ONCE | メッセージは、PUBACK 確認応答を受信するまで繰り返し送信されます。 | 

サンプルアプリケーションでは、発行およびサブスクライブのリクエストは QoS レベル 1 (`mqtt.QoS.AT_LEAST_ONCE`) で行われます。
+ 

**発行での QoS**  
デバイスが QoS レベル 1 のメッセージを発行すると、メッセージブローカーからの `PUBACK` 応答を受信するまでメッセージが繰り返し送信されます。デバイスが接続されていない場合、メッセージは再接続後に送信されるようにキューに入れられます。
+ 

**サブスクライブでの QoS**  
デバイスが QoS レベル 1 のメッセージをサブスクライブすると、メッセージブローカーは、デバイスに送信できるようになるまで、デバイスがサブスクライブしているメッセージを保存します。メッセージブローカーは、デバイスから `PUBACK` 応答を受信するまでメッセージを再送信します。

### メッセージの発行
<a name="sdk-tutorials-explore-publish"></a>

への接続が正常に確立されると AWS IoT Core、デバイスはメッセージを発行できます。`pubsub.py` サンプルでは、`mqtt_connection` オブジェクトの `publish` オペレーションを呼び出してこれを行います。

```
mqtt_connection.publish(
    topic=args.topic,
    payload=message,
    qos=mqtt.QoS.AT_LEAST_ONCE
)
```

`topic`  
メッセージを識別するメッセージのトピック名  
サンプルアプリケーションでは、これはコマンドラインから渡されます。

`payload`  
文字列としてフォーマットされたメッセージペイロード (例: JSON ドキュメント)  
サンプルアプリケーションでは、これはコマンドラインから渡されます。  
JSON ドキュメントは一般的なペイロード形式であり、他の AWS IoT のサービスによって認識されます。ただし、メッセージペイロードのデータ形式は、パブリッシャーとサブスクライバーが同意する任意の形式にすることができます。ただし、他の AWS IoT サービスでは、いくつかのケースにおいて、ほとんどのオペレーションで JSON と CBOR のみが認識されます。

`qos`  
このメッセージの QoS レベル

### メッセージのサブスクリプション
<a name="sdk-tutorials-explore-subscribe"></a>

 AWS IoT およびその他の のサービスやデバイスからメッセージを受信するには、デバイスはそれらのメッセージをトピック名でサブスクライブします。デバイスは、[トピック名](topics.md#topicnames)を指定して個々のメッセージをサブスクライブし、ワイルドカード文字を含めることができる[トピックフィルター](topics.md#topicfilters)を指定してメッセージのグループをサブスクライブできます。この `pubsub.py` サンプルでは、ここに示すコードを使用してメッセージをサブスクライブし、受信後にメッセージを処理するためのコールバック関数を登録します。

```
subscribe_future, packet_id = mqtt_connection.subscribe(
    topic=args.topic,
    qos=mqtt.QoS.AT_LEAST_ONCE,
    callback=on_message_received
)
subscribe_result = subscribe_future.result()
```

`topic`  
サブスクライブするトピック。これは、トピック名またはトピックフィルターにすることができます。  
サンプルアプリケーションでは、これはコマンドラインから渡されます。

`qos`  
デバイスが切断されている間、メッセージブローカーがこれらのメッセージを保存する必要があるかどうか。  
`mqtt.QoS.AT_LEAST_ONCE` (QoS レベル 1) の値では、接続の作成時に永続セッションを指定する必要があります (`clean_session=False`)。

`callback`  
サブスクライブされたメッセージを処理するために呼び出す関数。

`mqtt_connection.subscribe` 関数は、future とパケット ID を返します。サブスクリプションリクエストが正常に開始された場合、返されるパケット ID は 0 より大きくなります。サブスクリプションがメッセージブローカーによって受信され、登録されたことを確認するには、コード例に示すように、非同期オペレーションの結果が返されるまで待機する必要があります。

**コールバック関数**  
`pubsub.py` サンプルのコールバックは、デバイスがサブスクライブされたメッセージを受信したときに処理します。

```
def on_message_received(topic, payload, **kwargs):
    print("Received message from topic '{}': {}".format(topic, payload))
    global received_count
    received_count += 1
    if received_count == args.count:
        received_all_event.set()
```

`topic`  
メッセージのトピック  
これは、トピックフィルターにサブスクライブしている場合でも、受信したメッセージの特定のトピック名です。

`payload`  
メッセージペイロード  
このフォーマットはアプリケーション固有です。

`kwargs`  
[https://awslabs.github.io/aws-crt-python/api/mqtt.html#awscrt.mqtt.Connection.subscribe](https://awslabs.github.io/aws-crt-python/api/mqtt.html#awscrt.mqtt.Connection.subscribe) で説明されている可能な追加の引数。

`pubsub.py` サンプルでは、`on_message_received` はトピックとそのペイロードのみを表示します。また、制限に達した後、プログラムを終了するために受信したメッセージもカウントします。

アプリケーションはトピックとペイロードを評価して、実行するアクションを決定します。

### デバイスの切断と再接続
<a name="sdk-tutorials-explore-connect"></a>

`pubsub.py` サンプルには、デバイスが切断されたときと接続が再確立されたときに呼び出されるコールバック関数が含まれています。これらのイベントに対してデバイスが実行するアクションは、アプリケーション固有です。

デバイスが初めて接続するとき、受信するトピックをサブスクライブする必要があります。再接続時にデバイスのセッションが存在する場合、そのサブスクリプションが復元され、それらのサブスクリプションから保存されたメッセージは再接続後にデバイスに送信されます。

再接続時にデバイスのセッションが存在しない場合は、サブスクリプションを再サブスクライブする必要があります。永続セッションには有効期限があり、デバイスが切断されている時間が長すぎると期限切れになる可能性があります。

## デバイスを接続して と通信する AWS IoT Core
<a name="sdk-tutorials-experiment"></a>

このセクションでは、デバイスの AWS IoT Coreへの接続のさまざまな側面を詳しく知るのに役立ついくつかの演習を紹介します。これらの演習では、 AWS IoT コンソールで [MQTT テストクライアント](https://console.aws.amazon.com/iot/home#/test)を使用して、デバイスが発行する内容を確認し、デバイスにメッセージを発行します。これらの演習では、「[AWS IoT Device SDK v2 for Python](https://github.com/aws/aws-iot-device-sdk-python-v2/tree/master/samples#sample-apps-for-the-aws-iot-device-sdk-v2-for-python)」の [https://github.com/aws/aws-iot-device-sdk-python-v2/blob/master/samples/pubsub.py](https://github.com/aws/aws-iot-device-sdk-python-v2/blob/master/samples/pubsub.py) サンプルを使用し、「[AWS IoT Core チュートリアルの開始方法](iot-gs.md)」のチュートリアルで得た経験を基に構築します。

**Topics**
+ [ワイルドカードトピックフィルターをサブスクライブする](#sdk-tutorials-experiment-wild)
+ [トピックフィルターのサブスクリプションを処理する](#sdk-tutorials-experiment-process)
+ [デバイスからメッセージを発行する](#sdk-tutorials-experiment-publish)

これらの演習では、`pubsub.py` サンプルプログラムから始めます。

**注記**  
これらの演習では、[AWS IoT Core チュートリアルの開始方法](iot-gs.md) のチュートリアルを完了しており、そのチュートリアルのデバイスのターミナルウィンドウを使用していることを前提としています。

### ワイルドカードトピックフィルターをサブスクライブする
<a name="sdk-tutorials-experiment-wild"></a>

この演習では、`pubsub.py` を呼び出してワイルドカードトピックフィルターをサブスクライブするために使用するコマンドラインを変更し、メッセージのトピックに基づいて受信したメッセージを処理します。

#### 演習手順
<a name="sdk-tutorials-experiment-wild-steps"></a>

この演習では、デバイスに温度制御と照明制御が含まれていると想像してください。これらのトピック名を使用して、トピックに関するメッセージを識別します。

1. 演習を開始する前に、[AWS IoT Core チュートリアルの開始方法](iot-gs.md) のチュートリアルのこのコマンドをデバイスで実行して、演習の準備がすべて整っていることを確認してください。

   ```
   cd ~/aws-iot-device-sdk-python-v2/samples
   python3 pubsub.py --topic topic_1 --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint
   ```

   [開始方法のチュートリアル](connecting-to-existing-device.md#gs-device-node-app-run)で見たのと同じ出力が表示されるはずです。

1. この演習では、これらのコマンドラインパラメータを変更します。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/sdk-tutorials.html)

   これらの変更を最初のコマンドラインに加えると、このコマンドラインになります。デバイスのターミナルウィンドウにこのコマンドを入力します。

   ```
   python3 pubsub.py --message "" --count 2 --topic device/+/details --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint
   ```

   プログラムは次のように表示されます。

   ```
   Connecting to a3qexamplesffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-24d7cdcc-cc01-458c-8488-2d05849691e1'...
   Connected!
   Subscribing to topic 'device/+/details'...
   Subscribed with QoS.AT_LEAST_ONCE
   Waiting for all messages to be received...
   ```

   ターミナルにこのように表示された場合、デバイスは準備ができており、トピック名が `device`で始まり `/detail`で終わるメッセージをリッスンしています。それでは、それをテストしてみましょう。

1. デバイスが受信する可能性のあるメッセージをいくつか示します。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/sdk-tutorials.html)

1.  AWS IoT コンソールで MQTT テストクライアントを使用して、前のステップで説明したメッセージをデバイスに送信します。

   1.  AWS IoT コンソールで [MQTT テストクライアント](https://console.aws.amazon.com/iot/home#/test)を開きます。

   1. [**Subscribe to topic**] (トピックへのサブスクライブ) の [**Subscription topic**] (トピックのサブスクリプション) フィールドで、トピックフィルター **device/\$1/details** を入力して、[**Subscribe to topic**] (トピックへのサブスクライブ) を選択します。

   1. MQTT テストクライアントの [**Subscriptions**] (サブスクリプション) 列で、[**device/\$1/details**] を選択します。

   1. 上記の表の各トピックについて、MQTT テストクライアントで次の操作を行います。

      1. [**Publish**] (発行) で、テーブルの [**Topic name**] (トピック名) 列の値を入力します。

      1. トピック名の下のメッセージペイロードフィールドに、表の [**Message payload**] (メッセージペイロード) 列の値を入力します。

      1. `pubsub.py` が実行されているターミナルウィンドウを確認し、MQTT テストクライアントで [**Publish to topic**] (トピックに発行) を選択します。

      ターミナルウィンドウで `pubsub.py` によってメッセージが受信されたことがわかります。

#### 演習結果
<a name="sdk-tutorials-experiment-wild-result"></a>

これにより、`pubsub.py` は、ワイルドカードトピックフィルターを使用してメッセージをサブスクライブし、それらを受信し、ターミナルウィンドウに表示しました。単一のトピックフィルターをサブスクライブし、2 つの異なるトピックを持つメッセージを処理するためにコールバック関数が呼び出されたことに注意してください。

### トピックフィルターのサブスクリプションを処理する
<a name="sdk-tutorials-experiment-process"></a>

前の演習に基づいて、`pubsub.py` サンプルアプリケーションを変更してメッセージトピックを評価し、トピックに基づいてサブスクライブされたメッセージを処理します。

#### 演習手順
<a name="sdk-tutorials-experiment-process-steps"></a>

**メッセージトピックを評価するには**

1. `pubsub.py` を `pubsub2.py` にコピーします。

1. お好きなテキストエディタまたは IDE で `pubsub2.py` を開きます。

1. `pubsub2.py` で、`on_message_received` 関数を見つけます。

1. `on_message_received` で、次のコードを `print("Received message` で始まる行の後、および `global received_count` で始まる行の前に挿入します。

   ```
       topic_parsed = False
       if "/" in topic:
           parsed_topic = topic.split("/")
           if len(parsed_topic) == 3:
               # this topic has the correct format
               if (parsed_topic[0] == 'device') and (parsed_topic[2] == 'details'):
                   # this is a topic we care about, so check the 2nd element
                   if (parsed_topic[1] == 'temp'):
                       print("Received temperature request: {}".format(payload))
                       topic_parsed = True
                   if (parsed_topic[1] == 'light'):
                       print("Received light request: {}".format(payload))
                       topic_parsed = True
       if not topic_parsed:
           print("Unrecognized message topic.")
   ```

1. このコマンドラインを使用して、変更を保存し、変更したプログラムを実行します。

   ```
   python3 pubsub2.py --message "" --count 2 --topic device/+/details --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint
   ```

1.  AWS IoT コンソールで、[MQTT テストクライアント](https://console.aws.amazon.com/iot/home#/test)を開きます。

1. [**Subscribe to topic**] (トピックへのサブスクライブ) の [**Subscription topic**] (トピックのサブスクリプション) フィールドで、トピックフィルター **device/\$1/details** を入力して、[**Subscribe to topic**] (トピックへのサブスクライブ) を選択します。

1. MQTT テストクライアントの [**Subscriptions**] (サブスクリプション) 列で、[**device/\$1/details**] を選択します。

1. この表の各トピックについて、MQTT テストクライアントで次の操作を行います。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/sdk-tutorials.html)

   1. [**Publish**] (発行) で、テーブルの [**Topic name**] (トピック名) 列の値を入力します。

   1. トピック名の下のメッセージペイロードフィールドに、表の [**Message payload**] (メッセージペイロード) 列の値を入力します。

   1. `pubsub.py` が実行されているターミナルウィンドウを確認し、MQTT テストクライアントで [**Publish to topic**] (トピックに発行) を選択します。

   ターミナルウィンドウで `pubsub.py` によってメッセージが受信されたことがわかります。

ターミナルウィンドウに、このような内容が表示されます。

```
Connecting to a3qexamplesffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-af794be0-7542-45a0-b0af-0b0ea7474517'...
Connected!
Subscribing to topic 'device/+/details'...
Subscribed with QoS.AT_LEAST_ONCE
Waiting for all messages to be received...
Received message from topic 'device/light/details': b'{ "desiredLight": 100, "currentLight": 50 }'
Received light request: b'{ "desiredLight": 100, "currentLight": 50 }'
Received message from topic 'device/temp/details': b'{ "desiredTemp": 20, "currentTemp": 15 }'
Received temperature request: b'{ "desiredTemp": 20, "currentTemp": 15 }'
2 message(s) received.
Disconnecting...
Disconnected!
```

#### 演習結果
<a name="sdk-tutorials-experiment-process-result"></a>

この演習では、サンプルアプリケーションがコールバック関数で複数のメッセージを認識して処理するようにコードを追加しました。これにより、デバイスはメッセージを受信し、それに基づいてアクションを実行できます。

デバイスが複数のメッセージを受信して処理する別の方法は、異なるメッセージを個別にサブスクライブし、各サブスクリプションを独自のコールバック関数に割り当てることです。

### デバイスからメッセージを発行する
<a name="sdk-tutorials-experiment-publish"></a>

pubsub.py サンプルアプリケーションを使用して、デバイスからメッセージを発行できます。メッセージをそのまま発行しますが、メッセージを JSON ドキュメントとして読み取ることはできません。この演習では、読み取り可能なメッセージペイロードに JSON ドキュメントを発行できるようにサンプルアプリを変更します AWS IoT Core。

#### 演習手順
<a name="sdk-tutorials-experiment-publish-steps"></a>

この演習では、次のメッセージが `device/data`トピックとともに送信されます。

```
{
    "timestamp": 1601048303,
    "sensorId": 28,
    "sensorData": [
        {
        "sensorName": "Wind speed",
        "sensorValue": 34.2211224
        }
    ]
}
```

**この演習のメッセージを監視するように MQTT テストクライアントを準備するには**

1. [**Subscribe to topic**] (トピックへのサブスクライブ)の[**Subscription topic field**] (トピックのサブスクリプションフィールド)で、topic filter(トピックフィルター) **device/data** を入力して、[**Subscribe to topic**] (トピックへのサブスクライブ) を選択します。

1. MQTT テストクライアントの [**Subscriptions**] (サブスクリプション) 列で、[**device/data**] (デバイス/データ) を選択します。

1. MQTT テストクライアントウィンドウを開いたままにして、デバイスからのメッセージを待ちます。

**pubsub.py サンプルアプリケーションで JSON ドキュメントを送信するには**

1. デバイスで、`pubsub.py` を `pubsub3.py` にコピーします。

1. `pubsub3.py` を編集して、発行するメッセージのフォーマット方法を変更します。

   1. テキストエディタで `pubsub3.py` を開きます。

   1. 次のコード行を見つけます。

      `message = "{} [{}]".format(message_string, publish_count)`

   1. 次のように変更します。

      `message = "{}".format(message_string)`

   1. 次のコード行を見つけます。

      `message_json = json.dumps(message)`

   1. 次のように変更します。

      `message = "{}".json.dumps(json.loads(message))`

   1. 変更を保存します。

1. デバイス上でこのコマンドを実行して、メッセージを 2 回送信します。

   ```
   python3 pubsub3.py  --ca_file ~/certs/Amazon-root-CA-1.pem  --cert ~/certs/device.pem.crt  --key ~/certs/private.pem.key  --topic device/data  --count 2 --message '{"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}'  --endpoint your-iot-endpoint
   ```

1. MQTT テストクライアントで、次のようにメッセージペイロード内の JSON ドキュメントを解釈してフォーマットしたことを確認します。  
![\[AWS IoT コンソールの MQTT クライアントに JSON メッセージペイロードがどのように表示されるかを示す画像。\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/images/mqtt-test-client-output.png)

デフォルトでは、`pubsub3.py` は送信するメッセージもサブスクライブします。アプリの出力でメッセージを受信したことがわかります。ターミナルウィンドウは次のようになります。

```
Connecting to a3qEXAMPLEsffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-5cff18ae-1e92-4c38-a9d4-7b9771afc52f'...
Connected!
Subscribing to topic 'device/data'...
Subscribed with QoS.AT_LEAST_ONCE
Sending 2 message(s)
Publishing message to topic 'device/data': {"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}
Received message from topic 'device/data': b'{"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}'
Publishing message to topic 'device/data': {"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}
Received message from topic 'device/data': b'{"timestamp":1601048303,"sensorId":28,"sensorData":[{"sensorName":"Wind speed","sensorValue":34.2211224}]}'
2 message(s) received.
Disconnecting...
Disconnected!
```

#### 演習結果
<a name="sdk-tutorials-experiment-publish-result"></a>

これにより、デバイスは に送信するメッセージを生成 AWS IoT Core して基本的な接続をテストし、 が処理 AWS IoT Core するデバイスメッセージを提供できます。たとえば、このアプリを使用して、デバイスからテスト AWS IoT ルールアクションにテストデータを送信できます。

## 結果を確認する
<a name="sdk-tutorials-conclusion"></a>

このチュートリアルの例では、デバイスが と通信する方法の基本 AWS IoT Core、つまり AWS IoT ソリューションの基本的な部分について実践的な経験をしました。デバイスが と通信できる場合 AWS IoT Core、対応できるサービスやその他のデバイスにメッセージを AWS 渡すことができます。同様に、 AWS サービスやその他のデバイスは、デバイスに返送されるメッセージにつながる情報を処理できます。

さらに詳しく調べる準備ができたら AWS IoT Core 、以下のチュートリアルを試してください。
+ [チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md)
+ [チュートリアル: デバイスデータの DynamoDB テーブルへの保存](iot-ddb-rule.md)
+ [チュートリアル: AWS Lambda 関数を使用して通知をフォーマットする](iot-lambda-rule.md)

# チュートリアル: AWS IoT Device SDK for Embedded C の使用
<a name="iot-embedded-c-sdk"></a>

このセクションでは、AWS IoT Device SDK for Embedded C を実行する方法について説明します。

**Topics**
+ [ステップ 1: AWS IoT Device SDK for Embedded C をインストールする](#install-embedded-c-sdk)
+ [ステップ 2: サンプルアプリケーションを設定する](#iot-c-sdk-app-config)
+ [ステップ 3: サンプルアプリケーションをビルドして実行する](#iot-c-sdk-app-run)

## ステップ 1: AWS IoT Device SDK for Embedded C をインストールする
<a name="install-embedded-c-sdk"></a>

AWS IoT Device SDK for Embedded C は通常、最適化された C 言語ランタイムを必要とするリソース制約のあるデバイスを対象としています。この SDK は、任意のオペレーティングシステムで使用でき、任意のプロセッサタイプ (MCU や MPU など) でホストできます。使用可能なメモリと処理リソースが多い場合は、上位の AWS IoT Device および Mobile SDK (C\$1\$1、Java、JavaScript、Python など) のいずれかを使用することをお勧めします。

一般的に、AWS IoT Device SDK for Embedded C は、組み込みオペレーティングシステムを実行する MCU またはローエンド MPU を使用するシステムを対象としています。このセクションのプログラミング例では、ご利用のデバイスが Linux を使用していると仮定しています。

**Example**  

1. [GitHub](https://github.com/aws/aws-iot-device-sdk-embedded-C) から AWS IoT Device SDK for Embedded C をデバイスにダウンロードします。

   ```
   git clone https://github.com/aws/aws-iot-device-sdk-embedded-c.git --recurse-submodules
   ```

   これにより、現在のディレクトリに `aws-iot-device-sdk-embedded-c` という名前のディレクトリが作成されます。

1. そのディレクトリに移動し、最新のリリースを確認します。最新のリリースタグについては、[github.com/aws/aws-iot-device-sdk-embedded-C/tags](https://github.com/aws/aws-iot-device-sdk-embedded-C/tags) を参照してください。

   ```
   cd aws-iot-device-sdk-embedded-c
   git checkout latest-release-tag
   ```

1. OpenSSL バージョン 1.1.0 以降をインストールします。OpenSSL 開発ライブラリは、通常、パッケージマネージャーを介してインストールされた場合、「libssl-dev」または「openssl-devel」と呼ばれます。

   ```
   sudo apt-get install libssl-dev
   ```

## ステップ 2: サンプルアプリケーションを設定する
<a name="iot-c-sdk-app-config"></a>

AWS IoT Device SDK for Embedded C には、サンプルアプリケーションが含まれています。分かりやすいように、このチュートリアルでは `mqtt_demo_mutual_auth` アプリケーションを使用して、AWS IoT Core メッセージブローカーに接続し MQTT トピックにサブスクライブして発行する方法を示します。

1. [AWS IoT Core チュートリアルの開始方法](iot-gs.md) で作成した証明書およびプライベートキーを `build/bin/certificates` ディレクトリにコピーします。
**注記**  
デバイスおよびルート CA 証明書の有効期限切れや失効の対象となります。これらの証明書の有効期限が切れたり、失効した場合は、新しい CA 証明書またはプライベートキーおよびデバイス証明書をデバイスにコピーする必要があります。

1. サンプルは、パーソナル AWS IoT Core エンドポイント、プライベートキー、証明書、およびルート CA 証明書で設定する必要があります。`aws-iot-device-sdk-embedded-c/demos/mqtt/mqtt_demo_mutual_auth` ディレクトリに移動します。

   AWS CLIがインストールされている場合は、コマンドを使用してアカウントのエンドポイント URL を見つける事ができます。

   ```
   aws iot describe-endpoint --endpoint-type iot:Data-ATS
   ```

   AWS CLI がインストールされていない場合は、[[AWS IoTconsole](https://console.aws.amazon.com/iot/home)](コンソール)を開きます。ナビゲーションペインで、[**Manage (管理)**]、[**Things (モノ)**] の順に選択します。デバイスの IoT のモノを選択し、[**Interact**] (操作) を選択します。モノ の詳細ページの [**HTTPS**] セクションにエンドポイントが表示されます。

1. `demo_config.h` ファイルを開いて、以下の値を更新します。  
AWS\$1IOT\$1ENDPOINT  
パーソナルエンドポイント。  
CLIENT\$1CERT\$1PATH  
証明書ファイルのパス (例　`certificates/device.pem.crt"`)。  
CLIENT\$1PRIVATE\$1KEY\$1PATH  
プライベートキーのファイル名 (例　`certificates/private.pem.key` )。

   以下に例を示します。

   ```
   // Get from demo_config.h
   // =================================================
   #define AWS_IOT_ENDPOINT               "my-endpoint-ats.iot.us-east-1.amazonaws.com"
   #define AWS_MQTT_PORT                  8883
   #define CLIENT_IDENTIFIER              "testclient"
   #define ROOT_CA_CERT_PATH              "certificates/AmazonRootCA1.crt"
   #define CLIENT_CERT_PATH               "certificates/my-device-cert.pem.crt"
   #define CLIENT_PRIVATE_KEY_PATH        "certificates/my-device-private-key.pem.key"
   // =================================================
   ```

1. 次のコマンドを使用して、デバイスに CMake がインストールされているかどうかを確認します。

   ```
   cmake --version
   ```

   コンパイラのバージョン情報が表示された場合は、次のセクションに進みます。

   エラーが発生する、または情報が表示されない場合は、次のコマンドを使用して cmake パッケージをインストールする必要があります。

   ```
   sudo apt-get install cmake
   ```

   **cmake --version** コマンドを再度実行し、CMake がインストールされ、続行する準備ができていることを確認します。

1. 次のコマンドを使用して、デバイスに開発ツールがインストールされているかどうかを確認します。

   ```
   gcc --version
   ```

   コンパイラのバージョン情報が表示された場合は、次のセクションに進みます。

   エラーが発生したり、コンパイラ情報が表示されない場合は、次のコマンドを使用して `build-essential` パッケージをインストールする必要があります。

   ```
   sudo apt-get install build-essential
   ```

   **gcc --version** コマンドを再度実行し、ビルドツールがインストールされ、続行する準備ができていることを確認します。

## ステップ 3: サンプルアプリケーションをビルドして実行する
<a name="iot-c-sdk-app-run"></a>

この手順では、デバイスで `mqtt_demo_mutual_auth` アプリケーションを生成し、AWS IoT Device SDK for Embedded C を使用して [AWS IoT コンソール](https://console.aws.amazon.com/iot/home)に接続する方法について説明します。

**AWS IoT Device SDK for Embedded C サンプルアプリケーションを実行するには**

1. `aws-iot-device-sdk-embedded-c` に移動し、ディレクトリを作成します。

   ```
   mkdir build && cd build
   ```

1. 次の CMake コマンドを入力して、ビルドに必要な Makefiles を生成します。

   ```
   cmake ..  
   ```

1. 次のコマンドを入力して、実行可能アプリケーションファイルをビルドします。

   ```
   make
   ```

1. 次のコマンドで `mqtt_demo_mutual_auth` アプリを実行します。

   ```
   cd bin
   ./mqtt_demo_mutual_auth
   ```

   次のような出力が表示されます:   
![\[AWS IoT Device SDK for Embedded C サンプルアプリケーションを実行するためのコマンドライン出力。\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/images/successful-run2.png)

これで、デバイスは AWS IoT Device SDK for Embedded C を使用して AWS IoT に接続されました。

AWS IoT コンソールを使用して、サンプルアプリケーションが発行している MQTT メッセージを表示することもできます。[AWS IoT コンソール](https://console.aws.amazon.com/iot/home)で MQTT クライアントを使用する方法については、「[MQTT クライアントで AWS IoT MQTT メッセージを表示する](view-mqtt-messages.md)」を参照してください。

# デバイスデータを他の サービスにルーティングする AWS IoT ルールの作成
<a name="iot-rules-tutorial"></a>

これらのチュートリアルでは、より一般的な AWS IoT ルールアクションを使用してルールを作成およびテストする方法を示します。

AWS IoT ルールは、デバイスから他の AWS サービスにデータを送信します。特定の MQTT メッセージをリッスンし、メッセージペイロード内のデータをフォーマットし、結果を他の AWS のサービスに送信します。

Lambda 関数やそれ以上に複雑なものを使用するルールを作成することが目標であっても、ここに示されている順序でこれらを試すことをお勧めします。チュートリアルは、基本的なものから複雑なものへと順に表示されます。新しい概念を段階的に提示することで、特定のチュートリアルを持たないルールアクションの作成に使用できる概念を学習するのに役立ちます。

**注記**  
AWS IoT ルールは、IoT デバイスから他の AWS サービスにデータを送信するのに役立ちます。ただし、これを正常に実行するには、データを送信する他のサービスに関する実用的な知識が必要です。これらのチュートリアルでは、タスクを完了するために必要な情報が提供されていますが、ソリューションで使用する前に、データの送信先のサービスについて詳しく知っておくと便利です。他のサービスの詳細な説明 AWS は、これらのチュートリアルの範囲外です。

**チュートリアルのシナリオの概要**  
これらのチュートリアルのシナリオは、定期的にデータを発行する気象センサーデバイスのシナリオです。この架空のシステムには、このようなセンサー装置がたくさんあります。ただし、このセクションのチュートリアルでは、1 つのデバイスに焦点を当てつつ、複数のセンサーに対応する方法を示します。

このセクションのチュートリアルでは、 AWS IoT ルールを使用して、気象センサーデバイスのこの架空のシステムで次のタスクを実行する方法を示します。
+ 

**[チュートリアル: MQTT メッセージの再発行](iot-repub-rule.md)**  
このチュートリアルでは、気象センサーから受信した MQTT メッセージを、センサー ID と温度値のみを含むメッセージとして再発行する方法を示します。 AWS IoT Core サービスのみを使用し、シンプルな SQL クエリと MQTT クライアントを使用してルールをテストする方法をデモンストレーションします。
+ 

**[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md)**  
このチュートリアルでは、気象センサーデバイスの値が特定の値を超えた場合に SNS メッセージを送信する方法を示します。前のチュートリアルで説明した概念に基づいており、別の AWS サービスである [Amazon Simple Notification Service](https://docs.aws.amazon.com//sns/latest/dg/welcome.html) (Amazon SNS) を操作する方法を追加しています。

  Amazon SNS を初めて使用する場合は、このチュートリアルを開始する前に、[開始方法](https://docs.aws.amazon.com//sns/latest/dg/sns-getting-started.html)の演習を行います。
+ 

**[チュートリアル: デバイスデータの DynamoDB テーブルへの保存](iot-ddb-rule.md)**  
このチュートリアルでは、気象センサーデバイスのデータをデータベーステーブルに保存する方法を示します。ルールクエリステートメントと置換テンプレートを使用して、送信先のサービスである [Amazon DynamoDB](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/Introduction.html) のメッセージデータをフォーマットします。

  DynamoDB を初めて使用する場合は、このチュートリアルを開始する前に、[開始方法](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html)の演習を行います。
+ 

**[チュートリアル: AWS Lambda 関数を使用して通知をフォーマットする](iot-lambda-rule.md)**  
このチュートリアルでは、Lambda 関数を呼び出してデバイスデータを再フォーマットし、それをテキストメッセージとして送信する方法を示します。[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) 関数に Python スクリプトと AWS SDK 関数を追加して、気象センサーデバイスからのメッセージペイロードデータでフォーマットし、テキストメッセージを送信します。

  Lambda を初めて使用する場合は、このチュートリアルを開始する前に、[開始方法](https://docs.aws.amazon.com//lambda/latest/dg/getting-started.html)の演習を行います。

**AWS IoT ルールの概要**  
これらのチュートリアルはすべて AWS IoT ルールを作成します。

デバイスから別の AWS サービスにデータを送信する AWS IoT ルールには、以下を使用します。


+ ルールクエリステートメントは、次のもので構成されます。
  + メッセージペイロードからデータを選択してフォーマットする SQL SELECT 句
  + 使用するメッセージを識別するトピックフィルター (ルールクエリステートメントの FROM オブジェクト)
  + アクションを実行する特定の条件を指定するオプションの条件ステートメント (SQL WHERE 句)
+ 少なくとも 1 つのルールアクション

デバイスは、MQTT トピックにメッセージを発行します。SQL SELECT ステートメントのトピックフィルターは、ルールを適用する MQTT トピックを識別します。SQL SELECT ステートメントで指定されたフィールドは、ルールのアクションで使用するために、着信 MQTT メッセージペイロードからのデータをフォーマットします。ルールのすべてのアクションのリストについては、「[AWS IoT ルールのアクション](iot-rule-actions.md)」を参照してください。

**Topics**
+ [チュートリアル: MQTT メッセージの再発行](iot-repub-rule.md)
+ [チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md)
+ [チュートリアル: デバイスデータの DynamoDB テーブルへの保存](iot-ddb-rule.md)
+ [チュートリアル: AWS Lambda 関数を使用して通知をフォーマットする](iot-lambda-rule.md)

# チュートリアル: MQTT メッセージの再発行
<a name="iot-repub-rule"></a>

このチュートリアルでは、指定された MQTT メッセージが受信されたときに MQTT メッセージを発行する AWS IoT ルールを作成する方法を示します。受信メッセージペイロードは、発行前にルールによって変更できます。これにより、デバイスやそのファームウェアを変更することなく、特定のアプリケーションに合わせたメッセージを作成できます。また、ルールのフィルタリング機能を使用して、特定の条件が満たされた場合にのみメッセージを発行することもできます。

ルールによって再発行されるメッセージは、他の AWS IoT デバイスまたはクライアントによって送信されるメッセージのように動作します。デバイスは、他の MQTT メッセージトピックにサブスクライブできるのと同様に、再発行されたメッセージにサブスクライブできます。

**このチュートリアルでは、次の内容を学習します。**
+ ルールクエリステートメントでシンプルな SQL クエリと関数を使用する方法
+ MQTT クライアントを使用して AWS IoT ルールをテストする方法

このチュートリアルの完了には 30 分ほどかかります。

**Topics**
+ [MQTT トピックと AWS IoT ルールを確認する](#iot-repub-rule-mqtt)
+ [ステップ 1: MQTT メッセージを再発行する AWS IoT ルールを作成する](#iot-repub-rule-define)
+ [ステップ 2: 新しいルールをテストする](#iot-repub-rule-test)
+ [ステップ 3: 結果と次のステップを確認する](#iot-repub-rule-review)

**このチュートリアルを開始する前に、以下の要件を満たしていることを確認してください。**
+ 

**[セットアップ AWS アカウント](setting-up.md)**  
このチュートリアルを完了するには、 AWS アカウント と AWS IoT コンソールが必要です。
+ 

**[MQTT クライアントで AWS IoT MQTT メッセージを表示する](view-mqtt-messages.md) を確認したこと**  
トピックにサブスクライブおよび発行するために MQTT クライアントを使用できることを確認してください。この手順では、MQTT クライアントを使用して新しいルールをテストします。

## MQTT トピックと AWS IoT ルールを確認する
<a name="iot-repub-rule-mqtt"></a>

 AWS IoT ルールについて話す前に、MQTT プロトコルを理解するのに役立ちます。IoT ソリューションでは、MQTT プロトコルは HTTP などの他のネットワーク通信プロトコルよりも優れた機能を提供しているため、IoT デバイスでの使用のための選択肢として好まれています。このセクションでは、このチュートリアルに適用される MQTT の主な側面を見ていきます。MQTT と HTTP を比較する方法の詳細については、「[デバイス通信用のアプリケーションプロトコルの選択](protocols.md#protocol-selection)」を参照してください。

**MQTT プロトコル**  
MQTT プロトコルは、ホストとの発行/サブスクライブ通信モデルを使用します。データを送信するために、デバイスはトピックによって識別される AWS IoT メッセージをメッセージブローカーに発行します。メッセージブローカーからメッセージを受信するために、デバイスは、サブスクリプションリクエストでトピックフィルターをメッセージブローカーに送信することにより、受信するトピックにサブスクライブします。 AWS IoT ルールエンジンは、メッセージブローカーから MQTT メッセージを受信します。

**AWS IoT ルール**  
AWS IoT ルールは、ルールクエリステートメントと 1 つ以上のルールアクションで構成されます。 AWS IoT ルールエンジンが MQTT メッセージを受信すると、これらの要素は次のようにメッセージに対するアクションを実行します。
+ 

**ルールクエリステートメント**  
ルールのクエリステートメントは、使用する MQTT トピックを記述し、メッセージペイロードからのデータを解釈し、一般的な SQL データベースで使用されるステートメントに似た SQL ステートメントによって記述されるようにデータをフォーマットします。クエリステートメントの結果は、ルールのアクションに送信されるデータです。
+ 

**ルールアクション**  
ルールの各ルールアクションは、ルールのクエリステートメントから生じるデータに作用します。 は[多くのルールアクション](iot-rule-actions.md) AWS IoT をサポートします。ただし、このチュートリアルでは、[再発行](republish-rule-action.md) ルールアクションに焦点を当てます。このアクションは、クエリステートメントの結果を特定のトピックを持つ MQTT メッセージとして発行します。

## ステップ 1: MQTT メッセージを再発行する AWS IoT ルールを作成する
<a name="iot-repub-rule-define"></a>

このチュートリアルで作成する AWS IoT ルールは、*device\$1id* がメッセージを送信したデバイスの ID である `device/device_id/data` MQTT トピックにサブスクライブします。これらのトピックは、`device/+/data` として [トピックフィルター](topics.md#topicfilters)によって記述されます。ここで、`+` は、2 つのスラッシュ文字の間の任意の文字列に一致するワイルドカードです。

一致するトピックからルールがメッセージを受信すると、`device_id` および `temperature` の値を `device/data/temp` トピックを含む新しい MQTT メッセージとして再発行します。

例えば、`device/22/data`トピックを含む MQTT メッセージのペイロードは、以下のようになります。

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

このルールは、メッセージペイロードから `temperature` 値を、トピックから `device_id` を取得し、`device/data/temp` トピックを含む MQTT メッセージおよびメッセージペイロードとして次のように再発行します。

```
{
  "device_id": "22",
  "temperature": 28
}
```

このルールでは、デバイスの ID と温度データのみを必要とするデバイスは、`device/data/temp` トピックにサブスクライブして、その情報のみを受信します。

**MQTT メッセージを再発行するルールを作成するには**

1. [AWS IoT コンソールの**ルール**ハブを開きます](https://console.aws.amazon.com//iot/home#/rulehub)。

1. [**Rules**] (ルール) で、[**Create**] (作成) を選択して、新しいルールの作成を開始します。

1. [**Create a rule**] (ルールを作成) の上部で、次のように操作します。

   1. **[Name]** (名前) で、ルールの名前を入力します。このチュートリアルでは、**republish\$1temp** という名前を付けます。

      ルール名は、アカウントとリージョン内で一意である必要があります。また、スペースを含めることはできません。この名前にアンダースコア文字を使用して、ルールの名前の 2 つの単語を区切りました。

   1.  [**Description**] (説明) で、ルールの説明を入力します。

      わかりやすい説明を使用すると、このルールの動作と作成した理由を思い出すのに役立ちます。説明は必要なだけ長くすることができるので、できるだけ詳述してください。

1. [**Create a rule**] (ルールを作成) の [**Rule query statement**] (ルールクエリステートメント) で、以下を実行します。

   1.  [**Using SQL version**] (SQL バージョンの使用) で、**2016-03-23** を選択します。

   1. [**Rule query statement**] (ルールクエリステートメント) 編集ボックスで、ステートメントを入力します。

      ```
      SELECT topic(2) as device_id, temperature FROM 'device/+/data'
      ```

      このステートメント:
      + `device/+/data` トピックフィルターに一致するトピックを持つ MQTT メッセージをリッスンします。
      + トピック文字列から 2 番目の要素を選択し、`device_id` フィールドに割り当てます。
      + メッセージペイロードから値 `temperature` フィールドを選択し、`temperature` フィールドに割り当てます。

1. [**Set one or more actions**] (1 つ以上のアクションを設定) で、以下を実行します。

   1. このルールのルールアクションのリストを開くには、[**Add action**] (アクションの追加) を選択します。

   1. **「アクションの選択**」で、**「 AWS IoT トピックへのメッセージの再発行**」を選択します。

   1. アクションリストの一番下で、[**Configure action**] (アクションを設定) を選択すると、選択したアクションの設定ページが開きます。

1. [**Configure action**] (アクションの設定) で、次のとおり実行します。

   1.  [**Topic**] (トピック) で、**device/data/temp** と入力します。これは、このルールが発行するメッセージの MQTT トピックです。

   1.  [**Quality of Service**] (サービスの品質) で、[**0 - The message is delivered zero or more times**] (0 - メッセージは 0 回以上配信されます。) を選択します。

   1.  **「ロールを選択または作成して、このアクションを実行するための AWS IoT アクセス権を付与**する」を参照してください。

      1.  [**ロールの作成**] を選択します。**[Create a new role]** (新しいロールを作成) ダイアログボックスが開きます。

      1. 新しいロールを説明する名前を入力します。このチュートリアルでは、**republish\$1role** を使用します。

         新しいロールを作成すると、ルールアクションを実行するための正しいポリシーが作成され、新しいロールにアタッチされます。このルールアクションのトピックを変更するか、別のルールアクションでこのロールを使用する場合は、そのロールのポリシーを更新して、新しいトピックまたはアクションを承認する必要があります。既存のロールを更新するには、このセクションで **[Update role]** (ロールの更新) を選択します。

      1. **[Create Role]** (ロールの作成) を選択してロールを作成し、ダイアログボックスを閉じます。

   1. [**Add action**] (アクションの追加) を選択してアクションをルールに追加し、[**Create a rule**] (ルールの作成) ページに戻ります。

1. ** AWS IoT トピックアクションへのメッセージの再発行**が**「1 つ以上のアクションを設定する**」にリストされるようになりました。

   新しいアクションのタイルの **[Republish a message to an AWS IoT topic]** (IoT トピックにメッセージを再発行する) をクリックすると、再発行アクションが発行されるトピックが表示されます。

   このルールに追加するルールアクションはこれだけです。

1. **[Create a rule]** (ルールの作成) で、一番下までスクロールし、**[Create rule]** (ルールの作成) を選択してルールを作成し、この手順を完了します。

## ステップ 2: 新しいルールをテストする
<a name="iot-repub-rule-test"></a>

新しいルールをテストするには、MQTT クライアントを使用して、このルールで使用される MQTT メッセージを発行して、これにサブスクライブします。

新しいウィンドウの [AWS IoT コンソールで MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)を開きます。これにより、MQTT クライアントの設定を失うことなくルールを編集できます。MQTT クライアントは、サブスクリプションやメッセージログをコンソール内の別のページに移動するために残しておいても、それらを保持しません。

**MQTT クライアントを使用してルールをテストするには**

1. [AWS IoT コンソールの MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)で、入力トピック (この場合は `device/+/data`) をサブスクライブします。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Subscribe to topic**] (トピックへのサブスクライブ) を選択します。

   1. [**Subscription topic**] (サブスクリプショントピック) で、入力トピックフィルター **device/\$1/data** のトピックを入力します。

   1. 残りのフィールドはデフォルト設定のままにします。

   1. [**Subscribe to topic**] を選択します。

      [**Subscriptions**] (サブスクリプション) 列の [**Publish to a topic**] (トピックへの発行) の下に **device/\$1/data** が表示されます。

1. ルールが発行するトピックをサブスクライブします: `device/data/temp`。

   1. [**Subscriptions**] (サブスクリプション) で、[**Subscribe to a topic**] (トピックへサブスクライブする) を再度選択し、[**Subscription topic**] (サブスクリプショントピック) で、再発行されたメッセージのトピック **device/data/temp** を入力します。

   1. 残りのフィールドはデフォルト設定のままにします。

   1. [**Subscribe to topic**] を選択します。

      [**Subscriptions**] (サブスクリプション) 列の [**device/\$1/data**] の下に **device/data/temp** が表示されます。

1. 特定のデバイス ID **device/22/data** を使用して入力トピックにメッセージを発行します。ワイルドカード文字を含む MQTT トピックには発行できません。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Publish to topic**] (トピックに発行) を選択します。

   1. [**Publish**] (発行) フィールドに、入力トピック名 **device/22/data** を入力します。

   1. ここに表示されているサンプルデータをコピーし、トピック名の下にある編集ボックスにサンプルデータを貼り付けます。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT メッセージを送信するには、[**Publish to topic**] (トピックに発行) を選択します。

1. 送信されたメッセージを確認します。

   1. MQTT クライアントの **[Subscriptions]** (サブスクリプション) で、以前にサブスクライブした 2 つのトピックの横に緑色のドットが表示されます。

      緑のドットは、最後に表示した後に 1 つ以上の新しいメッセージを受信したことを示します。

   1. [**Subscriptions**] (サブスクリプション) で [**device/\$1/data**] を選択して、メッセージペイロードが今発行したものと一致し、次のようになっていることを確認します。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. **[Subscriptions]** (サブスクリプション) で、**[device/data/temp]** を選択して、再発行されたメッセージペイロードが次のようになっていることを確認します。

      ```
      {
        "device_id": "22",  
        "temperature": 28
      }
      ```

      `device_id` 値は引用符で囲まれた文字列で、`temperature` 値は数値であることに注意してください。これは、[https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic) 関数が入力メッセージのトピック名から文字列を抽出している一方で、`temperature` 値は入力メッセージのペイロードの数値を使用することによるものです。

      `device_id` 値を数値にしたい場合は、ルールクエリステートメントで `topic(2)` を次のように置き換えます。

      ```
      cast(topic(2) AS DECIMAL)
      ```

      `topic(2)` 値を数値にキャストすることは、トピックのその部分に数字のみが含まれている場合にのみ機能することに注意してください。

1. 正しいメッセージが **device/data/temp** トピックに発行されたことが確認できれば、ルールは機能しています。再発行ルールアクションの詳細については、次のセクションを参照してください。

   **device/\$1/data** または **device/data/temp** トピックのいずれかに正しいメッセージが発行されたことが確認できない場合は、トラブルシューティングのヒントを確認してください。

### 再発行メッセージルールのトラブルシューティング
<a name="iot-repub-rule-trouble"></a>

想定する結果が表示されない場合に備えて、確認すべき事項をいくつかご紹介します。
+ 

**エラーバナーが表示された**  
入力メッセージの発行時にエラーが発生した場合は、まずそのエラーを修正してください。次の手順は、このエラーを修正するのに役立つ場合があります。
+ 

**MQTT クライアントで入力メッセージが表示されない**  
入力メッセージを `device/22/data` トピックにサブスクライブすると、そのメッセージは MQTT クライアントに表示されます。`device/+/data`トピックフィルターを選択します。

**確認すべき事項**
  + 

**サブスクライブしたトピックフィルターを確認する**  
手順の説明に従って入力メッセージのトピックをサブスクライブした場合は、発行するたびに入力メッセージのコピーが表示されます。

    メッセージが表示されない場合は、サブスクライブしたトピック名を確認し、発行したトピックと比較します。トピック名は大文字と小文字が区別されます。サブスクライブしたトピックは、メッセージペイロードを発行したトピックと同一である必要があります。
  + 

**メッセージ発行機能を確認する**  
MQTT クライアントの [**Subscriptions**] (サブスクリプション) で、[**device/\$1/data**] を選択し、パブリッシュ メッセージのトピックを確認してから、[**Publish to topic**] (トピックに発行) を選択します。トピックの下にある編集ボックスからメッセージペイロードがメッセージリストに表示されるのを確認できるはずです。
+ 

**MQTT クライアントに再発行されたメッセージが表示されない**  
ルールが機能するには、メッセージを受信および再発行することを許可する正しいポリシーを有しており、メッセージを受信する必要があります。

**確認すべき事項**
  + 

**AWS リージョン MQTT クライアントの と作成したルールを確認する**  
MQTT クライアントを実行しているコンソールは、作成したルールと同じ AWS リージョンにある必要があります。
  + 

**ルールクエリステートメントの入力メッセージのトピックを確認する**  
ルールが機能するためには、ルールクエリステートメントの FROM 句のトピックフィルターに一致するトピック名を持つメッセージを受信する必要があります。

    ルールクエリステートメントのトピックフィルターの綴りを、MQTT クライアントのトピックフィルターの綴りと照らし合わせて確認します。トピック名では大文字と小文字が区別され、メッセージのトピックはルールクエリステートメントのトピックフィルターと一致する必要があります。
  + 

**入力メッセージペイロードの内容を確認する**  
ルールが機能するためには、SELECT ステートメントで宣言されているメッセージペイロード内のデータフィールドを見つける必要があります。

    ルールクエリステートメントの `temperature` フィールドの綴りを、MQTT クライアントのメッセージペイロードの綴りと照らし合わせて確認します。フィールド名では大文字と小文字が区別され、ルールクエリステートメントの `temperature` フィールドはメッセージペイロードの `temperature` フィールドと同じである必要があります。

    メッセージペイロード内の JSON ドキュメントが正しくフォーマットされていることを確認します。JSON にコンマがないなどのエラーがある場合、ルールはそれを読み取ることができません。
  + 

**ルールアクションで再発行されたメッセージトピックを確認する**  
再発行ルールアクションが新しいメッセージを発行するトピックは、MQTT クライアントでサブスクライブしたトピックと一致する必要があります。

    コンソールで作成したルールを開き、ルールアクションがメッセージを再発行するトピックを確認します。
  + 

**ルールによって使用されているロールを確認する**  
ルールのアクションには、元のトピックを受け取り、新しいトピックを発行するためのアクセス許可が必要です。

    ルールがメッセージデータを受信して再発行することを許可するポリシーは、使用されるトピックに固有です。メッセージデータの再発行に使用するトピックを変更する場合は、ルールアクションのロールを更新して、現在のトピックに一致するようにポリシーを更新する必要があります。

    これが問題であると思われる場合は、再発行ルールアクションを編集して、新しいロールを作成します。ルールアクションによって作成された新しいロールは、これらのアクションを実行するために必要な権限を受け取ります。

## ステップ 3: 結果と次のステップを確認する
<a name="iot-repub-rule-review"></a>

**このチュートリアルでは、次の作業を行いました。**
+ 新しい MQTT メッセージを生成するために、ルールクエリステートメントでシンプルな SQL クエリといくつかの関数を使用しました。
+ 新しいメッセージを再発行するルールを作成しました。
+ MQTT クライアントを使用して AWS IoT ルールをテストしました。

**次の手順**  
このルールでいくつかのメッセージを再発行した後、チュートリアルのいくつかの側面を変更すると、再発行メッセージにどのように影響するかを試してみてください。手始めにいくつかアイデアをご紹介します。
+ 入力メッセージのトピックで *device\$1id* を変更し、再発行されたメッセージ ペイロードの影響を観察します。
+ ルールクエリステートメントで選択したフィールドを変更し、再発行されたメッセージペイロードに生じる影響を確認します。
+ このシリーズの次のチュートリアルを試して、[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md) の方法を学びましょう。

このチュートリアルで使用する [Republish] (再発行) ルールアクションも、ルールクエリステートメントのデバッグに役立ちます。例えば、このアクションをルールに追加して、ルールクエリステートメントがルールアクションで使用されるデータをどのようにフォーマットしているかを確認できます。

# チュートリアル: Amazon SNS 通知の送信
<a name="iot-sns-rule"></a>

このチュートリアルでは、MQTT メッセージデータを Amazon SNS トピックに送信して SMS テキストメッセージとして送信できるようにする AWS IoT ルールを作成する方法を示します。

このチュートリアルでは、温度がルールで設定された値を超えるたびに、気象センサーから Amazon SNS トピックのすべてのサブスクライバーにメッセージデータを送信するルールを作成します。ルールは、報告された温度がルールで設定された値を超えたことを検出し、そのとき、デバイス ID、報告された温度、および超過した温度制限のみを含む新しいメッセージペイロードを作成します。ルールは、新しいメッセージペイロードを JSON ドキュメントとして SNS トピックに送信し、このトピックが SNS トピックのすべてのサブスクライバーに通知します。

**このチュートリアルでは、次の内容を学習します。**
+ Amazon SNS 通知を作成してテストする方法
+  AWS IoT ルールから Amazon SNS 通知を呼び出す方法
+ ルールクエリステートメントでシンプルな SQL クエリと関数を使用する方法
+ MQTT クライアントを使用して AWS IoT ルールをテストする方法

このチュートリアルの完了には 30 分ほどかかります。

**Topics**
+ [ステップ 1: SMS テキストメッセージを送信する Amazon SNS トピックを作成する](#iot-sns-rule-create-sns-topic)
+ [ステップ 2: テキストメッセージを送信する AWS IoT ルールを作成する](#iot-sns-rule-create-rule)
+ [ステップ 3: AWS IoT ルールと Amazon SNS 通知をテストする](#iot-sns-rule-test-rule)
+ [ステップ 4: 結果と次のステップを確認する](#iot-sns-rule-review-results)

**このチュートリアルを開始する前に、以下の要件を満たしていることを確認してください。**
+ 

**[セットアップ AWS アカウント](setting-up.md)**  
このチュートリアルを完了するには、 AWS アカウント と AWS IoT コンソールが必要です。
+ 

**[MQTT クライアントで AWS IoT MQTT メッセージを表示する](view-mqtt-messages.md) を確認したこと**  
トピックにサブスクライブおよび発行するために MQTT クライアントを使用できることを確認してください。この手順では、MQTT クライアントを使用して新しいルールをテストします。
+ 

**[Amazon Simple Notification Service](https://docs.aws.amazon.com//sns/latest/dg/welcome.html) を確認しました**  
これまでに Amazon SNS を使用したことがない場合は、[Amazon SNS へのアクセスの設定](https://docs.aws.amazon.com//sns/latest/dg/sns-setting-up.html)を確認してください。他の AWS IoT チュートリアルをすでに完了している場合は、 AWS アカウント が正しく設定されている必要があります。

## ステップ 1: SMS テキストメッセージを送信する Amazon SNS トピックを作成する
<a name="iot-sns-rule-create-sns-topic"></a>

この手順では、気象センサーがメッセージデータを送信できる Amazon SNS トピックを作成する方法について説明します。その後、Amazon SNS トピックは、すべてのサブスクライバーに、温度制限を超えたことを SMS テキストメッセージで通知します。

**SMS テキストメッセージを送信する Amazon SNS トピックを作成するには**

1. **Amazon SNS トピックを作成します。**

   1. [Amazon SNS コンソール](https://console.aws.amazon.com//sns/home)にサインインします。

   1. 左のナビゲーションペインで、[**トピック**] を選択します。

   1. [**トピック**] ページで、[**トピックの作成**] を選択します。

   1. **[Details]** (詳細) で、**[Standard]** (標準) タイプを選択します。デフォルトでは、コンソールは FIFO トピックを作成します。

   1. **[Name]** (名前) で、SNS トピック名を入力します。このチュートリアルでは、**high\$1temp\$1notice** と入力します。

   1. ページの最下部にスクロールし、**[Create topic]** (トピックの作成) を選択します。

      コンソールに新しいトピックの [**詳細**] ページが表示されます。

1. **Amazon SNS サブスクリプションを作成します。**
**注記**  
このサブスクリプションで使用する電話番号では、このチュートリアルで送信するメッセージのテキストメッセージ料金が発生する可能性があります。

   1. **high\$1temp\$1notice** トピックの詳細ページで、**[Create subscription]** (サブスクリプションの作成) を選択します。

   1. **[Create subscription]** (サブスクリプションの作成) の **[Details]** (詳細) セクションの **[Protocol]** (プロトコル) リストで、**[SMS]** を選択します。

   1. **[Endpoint]** (エンドポイント) で、テキストメッセージを受信できる電話の番号を入力します。`+` で始まり、国コードと市外局番が含まれ、他の句読文字が含まれないように入力してください。

   1. [**Create subscription**] を選択します。

1. **Amazon SNS 通知をテストします。**

   1. [Amazon SNS コンソール](https://console.aws.amazon.com//sns/home)の左のナビゲーションペインで、**[Topics]** (トピック) を選択します。

   1. トピックの詳細ページを開くには、**[Topics]** (トピック) のトピックのリストで、**[high\$1temp\$1notice]** を選択します。

   1. **[Publish message to topic]** (トピックへのメッセージの発行) ページを開くには、**[high\$1temp\$1notice]** の詳細ページで **[Publish message]** (メッセージの発行) を選択します。

   1. **[Publish message to topic]** (トピックへのメッセージの発行) の **[Message body]** (メッセージ本文) セクションの **[Message body to send to the endpoint]** (エンドポイントに送信するメッセージ本文) で、短いメッセージを入力します。

   1. ページの下部まで下方向にスクロールし、**[Publish message]** (メッセージの発行) を選択します。

   1. サブスクリプションを作成するときに以前に使用した番号の電話で、メッセージが受信されたことを確認します。

   テストメッセージが受信されない場合は、電話番号と電話の設定を再度確認してください。

   チュートリアルを続行する前に、[Amazon SNS コンソール](https://console.aws.amazon.com//sns/home)からテストメッセージを発行できることを確認してください。

## ステップ 2: テキストメッセージを送信する AWS IoT ルールを作成する
<a name="iot-sns-rule-create-rule"></a>

このチュートリアルで作成する AWS IoT ルールは、 `device_id`がメッセージを送信したデバイスの ID である `device/device_id/data` MQTT トピックにサブスクライブします。これらのトピックは、`device/+/data` としてトピックフィルターで記述されます。ここで、`+` は、2 つのスラッシュ文字の間の任意の文字列に一致するワイルドカードです。このルールは、メッセージペイロードの `temperature` フィールドの値もテストします。

ルールは、一致するトピックからメッセージを受信すると、トピック名から `device_id` を、メッセージペイロードから `temperature` 値を取得し、テストする制限に定数値を追加し、これらの値を JSON ドキュメントとして Amazon SNS 通知トピックに送信します。

 例えば、気象センサーデバイス番号 32 からの MQTT メッセージは `device/32/data` トピックを使用し、次のようなメッセージペイロードを持っています。

```
{
  "temperature": 38,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

ルールのルールクエリステートメントは、メッセージペイロードから `temperature` 値を、トピック名から `device_id` 値を取得し、定数 `max_temperature` 値を追加して、次のようなメッセージペイロードを Amazon SNS トピックに送信します。

```
{
  "device_id": "32",
  "reported_temperature": 38,
  "max_temperature": 30
}
```

**制限を超えた温度値を検出する AWS IoT ルールを作成し、Amazon SNS トピックに送信するデータを作成するには**

1. [AWS IoT コンソールの**ルール**ハブを開きます](https://console.aws.amazon.com//iot/home#/rulehub)。

1. これが最初のルールである場合は、[**Create**] (作成) または [**Create a rule**] (ルールの作成) を選択します。

1. **[Create a rule]** (ルールの作成) で以下のとおり操作します。

   1. [**名前**] に「**temp\$1limit\$1notify**」と入力します。

      ルール名は AWS アカウント および リージョン内で一意である必要があり、スペースを含めることはできません。この名前にアンダースコア文字を使用して、ルールの名前の単語を区切りました。

   1. [**Description**] (説明) で、ルールの説明を入力します。

      わかりやすい説明を使用すると、このルールの動作と作成した理由を簡単に思い出すことができます。説明は必要なだけ長くすることができるので、できるだけ詳述してください。

1. [**Create a rule**] (ルールを作成) の [**Rule query statement**] (ルールクエリステートメント) で、以下を実行します。

   1.  **[Using SQL version]** (SQL バージョンの使用) で、**2016-03-23** を選択します。

   1. [**Rule query statement**] (ルールクエリステートメント) 編集ボックスで、ステートメントを入力します。

      ```
      SELECT topic(2) as device_id, 
          temperature as reported_temperature, 
          30 as max_temperature 
        FROM 'device/+/data' 
        WHERE temperature > 30
      ```

      このステートメント:
      + `device/+/data` トピックフィルターに一致し、`temperature` 値が 30 より大きいトピックを含む MQTT メッセージをリッスンします。
      + トピック文字列から 2 番目の要素を選択し、`device_id` フィールドに割り当てます。
      + メッセージペイロードから値 `temperature` フィールドを選択し、`reported_temperature` フィールドに割り当てます。
      + 制限値を表す定数値 `30` を作成し、それを `max_temperature` フィールドに割り当てます。

1. このルールのルールアクションのリストを開くには、**[Set one or more actions]** (1 つ以上のアクションを設定する) で **[Add action]** (アクションの追加) を選択します。

1. **[Select an action]** (アクションを選択してください) で、**[Send a message as an SNS push notification]** (SNS プッシュ通知としてメッセージを送信する) を選択します。

1. 選択したアクションの設定ページを開くには、アクションリストの下部にある [**Configure action**] (アクションの設定) を選択します。

1. [**Configure action**] (アクションの設定) で、次のとおり実行します。

   1. **SNS ターゲット**で、**[Select]** (選択) を選択し、**high\$1temp\$1notice** という名前の SNS トピックを見つけて、**[Select]** (選択) を選択します。

   1. [**Message format**] (メッセージ形式) で、[**RAW**] を選択します。

   1. **「ロールを選択または作成して、このアクションを実行するための AWS IoT アクセス権を付与する」で**、**「ロールの作成**」を選択します。

   1. [**Create a new role**] (新しいロールの作成) の [**Name**] (名前) で、新しいロールの一意の名前を入力します。このチュートリアルでは、**sns\$1rule\$1role** を使用します。

   1. [**ロールの作成**] を選択します。

   このチュートリアルを繰り返す場合、または既存のロールを再利用する場合は、続行する前に **[Update role]** (ロールの更新) を選択してください。これにより、ロールのポリシードキュメントが更新され、SNS ターゲットで動作します。

1. **[Add action]** (アクションの追加) を選択して、**[Create a rule]** (ルールの作成) ページに戻ります。

   新しいアクションのタイルの **[Send a message as an SNS push notification]** (SNS プッシュ通知としてメッセージを送信する) の下に、ルールが呼び出す SNS トピックが表示されます。

   このルールに追加するルールアクションはこれだけです。

1. ルールを作成してこの手順を完了するには、[**Create a rule**] (ルールの作成) で一番下までスクロールし、[**Create rule**] (ルールの作成) を選択します。

## ステップ 3: AWS IoT ルールと Amazon SNS 通知をテストする
<a name="iot-sns-rule-test-rule"></a>

新しいルールをテストするには、MQTT クライアントを使用して、このルールで使用される MQTT メッセージを発行して、これにサブスクライブします。

新しいウィンドウの [AWS IoT コンソールで MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)を開きます。これにより、MQTT クライアントの設定を失うことなくルールを編集できます。コンソールの別のページに移動するために MQTT クライアントを残しても、サブスクリプションやメッセージログは保持されません。

**MQTT クライアントを使用してルールをテストするには**

1. [AWS IoT コンソールの MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)で、入力トピック (この場合は `device/+/data`) をサブスクライブします。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Subscribe to topic**] (トピックへのサブスクライブ) を選択します。

   1. [**Subscription topic**] (サブスクリプショントピック) で、入力トピックフィルター **device/\$1/data** のトピックを入力します。

   1. 残りのフィールドはデフォルト設定のままにします。

   1. [**Subscribe to topic**] を選択します。

      [**Subscriptions**] (サブスクリプション) 列の [**Publish to a topic**] (トピックへの発行) の下に **device/\$1/data** が表示されます。

1. 特定のデバイス ID **device/32/data** を使用して入力トピックにメッセージを発行します。ワイルドカード文字を含む MQTT トピックには発行できません。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Publish to topic**] (トピックに発行) を選択します。

   1. [**Publish**] (発行) フィールドに、入力トピック名 **device/32/data** を入力します。

   1. ここに表示されているサンプルデータをコピーし、トピック名の下にある編集ボックスにサンプルデータを貼り付けます。

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. **[Publish to topic]** (トピックに発行) を選択して、MQTT メッセージを発行します。

1. テキストメッセージが送信されたことを確認します。

   1. MQTT クライアントの [**Subscriptions**] (サブスクリプション) の下に、以前にサブスクライブしたトピックの隣に緑色のドットが表示されます。

      緑色のドットは、最後にメッセージを表示してから 1 つ以上の新しいメッセージが受信されたことを示します。

   1. [**Subscriptions**] (サブスクリプション) で [**device/\$1/data**] を選択して、メッセージペイロードが今発行したものと一致し、次のようになっていることを確認します。

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. SNS トピックのサブスクライブに使用した電話を確認し、メッセージペイロードの内容が次のようになっていることを確認します。

      ```
      {"device_id":"32","reported_temperature":38,"max_temperature":30}
      ```

      `device_id` 値は引用符で囲まれた文字列で、`temperature` 値は数値であることに注意してください。これは、[https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic](https://docs.aws.amazon.com//iot/latest/developerguide/iot-sql-functions.html#iot-function-topic) 関数が入力メッセージのトピック名から文字列を抽出している一方で、`temperature` 値は入力メッセージのペイロードの数値を使用することによるものです。

      `device_id` 値を数値にしたい場合は、ルールクエリステートメントで `topic(2)` を次のように置き換えます。

      ```
      cast(topic(2) AS DECIMAL)
      ```

      `topic(2)` 値を数値にキャストすると、トピックのその部分に数字のみが含まれている場合にのみ `DECIMAL` 値が機能することに注意してください。

1. 温度が制限を超えていない MQTT メッセージの送信を試みます。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Publish to topic**] (トピックに発行) を選択します。

   1. [**Publish**] (発行) フィールドに、入力トピック名 **device/33/data** を入力します。

   1. ここに表示されているサンプルデータをコピーし、トピック名の下にある編集ボックスにサンプルデータを貼り付けます。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT メッセージを送信するには、[**Publish to topic**] (トピックに発行) を選択します。

   **device/\$1/data** サブスクリプションで送信したメッセージが表示されます。ただし、温度値がルールクエリステートメントの最大温度を下回っているため、テキストメッセージは受信されません。

   正しい動作が確認できない場合は、トラブルシューティングのヒントを確認してください。

### SNS メッセージルールのトラブルシューティング
<a name="iot-sns-rule-trouble"></a>

想定する結果が得られない場合に備えて、確認すべき事項をいくつか示します。
+ 

**エラーバナーが表示された**  
入力メッセージの発行時にエラーが発生した場合は、まずそのエラーを修正してください。次の手順は、このエラーを修正するのに役立つ場合があります。
+ 

**MQTT クライアントで入力メッセージが表示されない**  
手順で説明されているように `device/+/data` トピックフィルターをサブスクライブした場合、入力メッセージを `device/22/data` トピックに発行するたびに、そのメッセージが MQTT クライアントに表示されます。

**確認すべき事項**
  + 

**サブスクライブしたトピックフィルターを確認する**  
手順の説明に従って入力メッセージのトピックをサブスクライブした場合は、発行するたびに入力メッセージのコピーが表示されます。

    メッセージが表示されない場合は、サブスクライブしたトピック名を確認し、発行したトピックと比較します。トピック名は大文字と小文字が区別されます。サブスクライブしたトピックは、メッセージペイロードを発行したトピックと同一である必要があります。
  + 

**メッセージ発行機能を確認する**  
MQTT クライアントの [**Subscriptions**] (サブスクリプション) で、[**device/\$1/data**] を選択し、パブリッシュ メッセージのトピックを確認してから、[**Publish to topic**] (トピックに発行) を選択します。トピックの下にある編集ボックスからメッセージペイロードがメッセージリストに表示されるのを確認できるはずです。
+ 

**SMS メッセージが届かない**  
ルールが機能するには、メッセージの受信と SNS 通知の送信を許可する正しいポリシーを有しており、メッセージを受信する必要があります。

**確認すべき事項**
  + 

**AWS リージョン MQTT クライアントの と作成したルールを確認する**  
MQTT クライアントを実行しているコンソールは、作成したルールと同じ AWS リージョンにある必要があります。
  + 

**メッセージペイロードの温度値がテストしきい値を超えていることを確認します。**  
ルールクエリステートメントで定義されている温度値が 30 以下の場合、ルールはそのアクションを実行しません。
  + 

**ルールクエリステートメントの入力メッセージのトピックを確認する**  
ルールが機能するためには、ルールクエリステートメントの FROM 句のトピックフィルターに一致するトピック名を持つメッセージを受信する必要があります。

    ルールクエリステートメントのトピックフィルターの綴りを、MQTT クライアントのトピックフィルターの綴りと照らし合わせて確認します。トピック名では大文字と小文字が区別され、メッセージのトピックはルールクエリステートメントのトピックフィルターと一致する必要があります。
  + 

**入力メッセージペイロードの内容を確認する**  
ルールが機能するためには、SELECT ステートメントで宣言されているメッセージペイロード内のデータフィールドを見つける必要があります。

    ルールクエリステートメントの `temperature` フィールドの綴りを、MQTT クライアントのメッセージペイロードの綴りと照らし合わせて確認します。フィールド名では大文字と小文字が区別され、ルールクエリステートメントの `temperature` フィールドはメッセージペイロードの `temperature` フィールドと同じである必要があります。

    メッセージペイロード内の JSON ドキュメントが正しくフォーマットされていることを確認します。JSON にコンマがないなどのエラーがある場合、ルールはそれを読み取ることができません。
  + 

**ルールアクションで再発行されたメッセージトピックを確認する**  
再発行ルールアクションが新しいメッセージを発行するトピックは、MQTT クライアントでサブスクライブしたトピックと一致する必要があります。

    コンソールで作成したルールを開き、ルールアクションがメッセージを再発行するトピックを確認します。
  + 

**ルールによって使用されているロールを確認する**  
ルールのアクションには、元のトピックを受け取り、新しいトピックを発行するためのアクセス許可が必要です。

    ルールがメッセージデータを受信して再発行することを許可するポリシーは、使用されるトピックに固有です。メッセージデータの再発行に使用するトピックを変更する場合は、ルールアクションのロールを更新して、現在のトピックに一致するようにポリシーを更新する必要があります。

    これが問題であると思われる場合は、再発行ルールアクションを編集して、新しいロールを作成します。ルールアクションによって作成された新しいロールは、これらのアクションを実行するために必要な権限を受け取ります。

## ステップ 4: 結果と次のステップを確認する
<a name="iot-sns-rule-review-results"></a>

**このチュートリアルでは、次の作業を行いました。**
+ Amazon SNS 通知トピックとサブスクリプションを作成し、テストしました。
+ ルールクエリステートメントでシンプルな SQL クエリと関数を使用して、通知用の新しいメッセージを作成しました。
+ カスタマイズされたメッセージペイロードを使用した Amazon SNS 通知を送信する AWS IoT ルールを作成しました。
+ MQTT クライアントを使用して AWS IoT ルールをテストしました。

**次の手順**  
このルールを使用していくつかのテキストメッセージを送信した後、チュートリアルの一部を変更すると、メッセージと送信される場合にどのような影響があるかを試してみてください。手始めにいくつかアイデアをご紹介します。
+ 入力メッセージのトピックの *device\$1id* を変更し、テキストメッセージの内容に生じる影響を確認します。
+ ルールクエリステートメントで選択したフィールドを変更し、テキストメッセージの内容に生じる影響を確認します。
+ ルールクエリステートメントのテストを変更して、最高温度ではなく最低温度をテストします。`max_temperature` の名前を変更することを忘れないでください\$1
+ SNS 通知の送信時に MQTT メッセージを送信する再発行ルールアクションを追加します。
+ このシリーズの次のチュートリアルを試して、[チュートリアル: デバイスデータの DynamoDB テーブルへの保存](iot-ddb-rule.md) の方法を学びましょう。

# チュートリアル: デバイスデータの DynamoDB テーブルへの保存
<a name="iot-ddb-rule"></a>

このチュートリアルでは、DynamoDB テーブルにメッセージデータを送信する AWS IoT ルールを作成する方法を示します。

このチュートリアルでは、架空の気象センサーデバイスから DynamoDB テーブルにメッセージデータを送信するルールを作成します。このルールは、多くの気象センサーからのデータをフォーマットして、単一のデータベーステーブルに追加できるようにします。

**このチュートリアルで学習する内容**
+ DynamoDB テーブルの作成方法
+  AWS IoT ルールから DynamoDB テーブルにメッセージデータを送信する方法
+  AWS IoT ルールで置換テンプレートを使用する方法
+ ルールクエリステートメントでシンプルな SQL クエリと関数を使用する方法
+ MQTT クライアントを使用して AWS IoT ルールをテストする方法

このチュートリアルの完了には 30 分ほどかかります。

**Topics**
+ [ステップ 1: このチュートリアルの DynamoDB テーブルを作成する](#iot-ddb-rule-ddb-table)
+ [ステップ 2: DynamoDB テーブルにデータを送信する AWS IoT ルールを作成する](#iot-ddb-rule-topic-rule)
+ [ステップ 3: AWS IoT ルールと DynamoDB テーブルをテストする](#iot-ddb-rule-test)
+ [ステップ 4: 結果と次のステップを確認する](#iot-ddb-rule-review)

**このチュートリアルを開始する前に、以下の要件を満たしていることを確認してください。**
+ 

**[セットアップ AWS アカウント](setting-up.md)**  
このチュートリアルを完了するには、 AWS アカウント と AWS IoT コンソールが必要です。
+ 

**[MQTT クライアントで AWS IoT MQTT メッセージを表示する](view-mqtt-messages.md) を確認したこと**  
トピックにサブスクライブおよび発行するために MQTT クライアントを使用できることを確認してください。この手順では、MQTT クライアントを使用して新しいルールをテストします。
+ 

**[Amazon DynamoDB](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/Introduction.html) の概要を確認しました**  
これまで DynamoDB を使用したことがない場合は、[DynamoDB の開始方法](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html)を確認して、DynamoDB の基本的な概念と操作に慣れてください。

## ステップ 1: このチュートリアルの DynamoDB テーブルを作成する
<a name="iot-ddb-rule-ddb-table"></a>

このチュートリアルでは、これらの属性を持つ DynamoDB テーブルを作成し、架空の気象センサーデバイスのデータを記録します。
+ `sample_time` はプライマリキーで、サンプルが記録された時間を記述します。
+ `device_id` はソートキーで、サンプルを提供したデバイスを記述します 
+ `device_data` は、デバイスから受信され、ルールクエリステートメントによってフォーマットされたデータです

**このチュートリアルの DynamoDB テーブルを作成するには**

1. [DynamoDB コンソール](https://console.aws.amazon.com//dynamodb/home)を開き、**[Create table]** (テーブルの作成) を選択します。

1. **Create table** (テーブルの作成) の

   1.  **[Table name]** (テーブル名) で、テーブル名 **wx\$1data** を入力します。

   1. **[Partition key]** (パーティションキー) で **sample\$1time** と入力し、フィールドの横にあるオプションリストで **Number** を選択します。

   1. **[Sort key]** (ソートキー) で **device\$1id** と入力します。フィールドの横にあるオプションリストで **Number** を選択します。

   1. ページの下部で、**[Create]** (作成) を選択します。

後で DynamoDB ルールアクションを設定するときに `device_data` を定義します。

## ステップ 2: DynamoDB テーブルにデータを送信する AWS IoT ルールを作成する
<a name="iot-ddb-rule-topic-rule"></a>

このステップでは、ルールクエリステートメントを使用して、架空の気象センサーデバイスからのデータをフォーマットし、データベーステーブルに書き込みます。

気象センサーデバイスから受信したサンプルメッセージペイロードは、次のようになります。

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

データベースエントリでは、ルールクエリステートメントを使用して、メッセージペイロードの構造を次のようにフラット化します。

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind_velocity": 22,
  "wind_bearing": 255
}
```

このルールでは、いくつかの [置換テンプレート](iot-substitution-templates.md) も使用します。置換テンプレートは、関数およびメッセージデータから動的値を挿入することを可能にする式です。

**DynamoDB テーブルにデータを送信する AWS IoT ルールを作成するには**

1.  AWS IoT コンソールの [[Rules]](https://console.aws.amazon.com//iot/home#/rulehub) (ルール) ハブを開きます。または、 AWS マネジメントコンソール 内で AWS IoT ホームページを開き、**メッセージルーティング＞ルール**に移動できます。

1. **[Rules]** (ルール) で新しいルールの作成を開始するには、**[Create rule]** (ルールの作成) を選択します。

1. **[Rule properties]** (ルールのプロパティ) の

   1. **[Rule name]** (ルール名) で **wx\$1data\$1ddb** と入力します。

      ルール名は AWS アカウント および リージョン内で一意である必要があり、スペースを含めることはできません。この名前にアンダースコア文字を使用して、ルールの名前の 2 つの単語を区切りました。

   1. **[Rule description]** (ルールの説明) で、ルールを説明します。

      わかりやすい説明を使用すると、このルールの動作と作成した理由を簡単に思い出すことができます。説明は必要なだけ長くすることができるので、できるだけ詳述してください。

1. **[次へ]** を選択して続行します。

1. **[SQL statement]** (SQL ステートメント) の

   1. [**SQL version**] (SQL バージョン) で、**2016-03-23** を選択します。

   1. [**SQL statement**] (SQL ステートメント) 編集ボックスで、ステートメントを入力します。

      ```
      SELECT temperature, humidity, barometer,
        wind.velocity as wind_velocity,
        wind.bearing as wind_bearing,
      FROM 'device/+/data'
      ```

      このステートメント:
      + `device/+/data` トピックフィルターに一致するトピックを持つ MQTT メッセージをリッスンします。
      + `wind` 属性の要素を個々の属性としてフォーマットします。
      + `temperature`、`humidity`、および `barometer` 属性を変更せずに渡します。

1. **[次へ]** を選択して続行します。

1. **[Rule actions]** (ルールのアクション) で

   1. このルールのルールアクションのリストを開くには、**[Action 1]** (アクション 1) で **DynamoDB** を選択します。
**注記**  
ルールアクションとして DynamoDBv2 ではなく DynamoDB を選択してください。

   1. **[Table name]** (テーブル名) で、前の手順で作成した DynamoDB テーブルの名前 **wx\$1data** を選択します。

      **[Partition key type]** (パーティションキータイプ) および **[Sort key type]** (ソートキータイプ) のフィールドには、DynamoDB テーブルの値が入力されます。

   1. [**パーティションキー**] に「**sample\$1time**」と入力します。

   1. [**パーティションキーの値**] に「**\$1\$1timestamp()\$1**」と入力します。

      これは、このルールで使用する [置換テンプレート](iot-substitution-templates.md) の最初のものです。メッセージペイロードの値を使用する代わりに、timestamp 関数から返された値を使用します。詳細については、*AWS IoT Core デベロッパーガイド*の 「[タイムスタンプ](iot-sql-functions.md#iot-function-timestamp)」を参照してください。

   1. **[Sort key]** (ソートキー) に「**device\$1id**」と入力します。

   1. [**ソートキー値**] に「**\$1\$1cast(topic(2) AS DECIMAL)\$1**」と入力します。

      これは、このルールで使用する [置換テンプレート](iot-substitution-templates.md) の 2 番目のものです。キーの数値形式と一致するように DECIMAL 値にキャストした後、デバイスの ID である [topic] (トピック) 名の 2 番目の要素の値を挿入します。トピックの詳細については、*AWS IoT Core デベロッパーガイド*の「[トピック](iot-sql-functions.md#iot-function-topic)」を参照してください。または、キャスティングの詳細については、*AWS IoT Core デベロッパーガイド*の「[キャスト](iot-sql-functions.md#iot-sql-function-cast)」を参照してください。

   1. [**この列にメッセージデータを書き込む**] に **device\$1data** と入力します。

      これにより、DynamoDB テーブルに `device_data` 列が作成されます。

   1. [**オペレーション**] は空白のままにします。

   1. **[IAM role]** (IAM ロール) で、**[Create new role]** (新しいロールの作成) を選択します。

   1. **[Create role]** (ロールの作成) ダイアログボックスの **[Role name]** (ロール名) に **[wx\$1ddb\$1role]** と入力します。この新しいロールには、作成した **wx\$1data** DynamoDB テーブルにデータを送信する **wx\$1data\$1ddb** ルールを許可する「aws-iot-rule」というプレフィックスが付いたポリシーが自動的に含まれます。

   1. **IAM role** (IAM ロール) で **wx\$1ddb\$1role** を選択します。

   1. ページの最下部にある **[Next]** (次へ) を選択します。

1. **[Review and create]** (確認と作成) ページの最下部で、**[Create]** (作成) を選択して、ルールを作成します。

## ステップ 3: AWS IoT ルールと DynamoDB テーブルをテストする
<a name="iot-ddb-rule-test"></a>

新しいルールをテストするには、MQTT クライアントを使用して、このテストで使用した MQTT メッセージを発行し、これにサブスクライブします。

新しいウィンドウの [AWS IoT コンソールで MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)を開きます。これにより、MQTT クライアントの設定を失うことなくルールを編集できます。MQTT クライアントは、サブスクリプションやメッセージログをコンソール内の別のページに移動するために残しておいても、それらを保持しません。また、別のコンソールウィンドウを[AWS IoT コンソールの DynamoDB Tables ハブ](https://console.aws.amazon.com//dynamodb/home#tables:)に開いて、ルールが送信する新しいエントリを表示することもできます。

**MQTT クライアントを使用してルールをテストするには**

1. [AWS IoT コンソールの MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)で、入力トピック `device/+/data` をサブスクライブします。

   1. MQTT クライアントで、[**Subscribe to topic**] (トピックへのサブスクライブ) を選択します。

   1. [**Topic filter**] (トピックフィルター) に、入力トピックフィルター **device/\$1/data** のトピックを入力します。

   1. [**Subscribe**] (サブスクライブ) を選択します。

1. 特定のデバイス ID **device/22/data** を使用して入力トピックにメッセージを発行します。ワイルドカード文字を含む MQTT トピックには発行できません。

   1. MQTT クライアントで、[**Publish to a topic**] (トピックへの発行) を選択します。

   1. [**Topic name**] (トピック名) に、入力トピックの名前 **device/22/data** を入力します。

   1. [**Message payload**] (メッセージペイロード) に、次のサンプルデータを入力します。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT メッセージを発行するには、[**Publish**] (発行) を選択します。

   1. MQTT クライアントで、[**Subscribe to a topic**] (トピックへのサブスクライブ) を選択します。[**Subscribe**] (サブスクライブ) 列で、**device/\$1/data** サブスクリプションを選択します。前のステップのサンプルデータがそこに表示されていることを確認します。

1. ルールが作成した DynamoDB テーブルの行を確認します。

   1. [AWS IoT コンソールの DynamoDB Tables ハブで](https://console.aws.amazon.com//dynamodb/home#tables:)、**wx\$1data** を選択し、**Items** タブを選択します。

      [**Items**] (アイテム) タブを既に開いている場合は、テーブルのヘッダーの右上にある更新アイコンを選択して、表示を更新する必要がある場合があります。

   1. テーブルの **sample\$1time** 値はリンクであり、オープンであることに注意してください。最初のメッセージを送ったばかりの場合は、そのメッセージだけがリストに表示されます。

      このリンクには、テーブルのその行のすべてのデータが表示されます。

   1. **device\$1data** エントリを展開して、ルールクエリステートメントの結果のデータを表示します。

   1. この表示で使用できるデータのさまざまな表現を詳しく確認します。このディスプレイでデータを編集することもできます。

   1. このデータ行の確認が終了したら、加えた変更を保存するには [**Save**] (保存) を選択し、変更を保存せずに終了するには [**Cancel**] (キャンセル) を選択します。

正しい動作が確認できない場合は、トラブルシューティングのヒントを確認してください。

### DynamoDB ルールのトラブルシューティング
<a name="iot-ddb-rule-trouble"></a>

想定する結果が表示されない場合に備えて、確認すべき事項をいくつかご紹介します。
+ 

**エラーバナーが表示された**  
入力メッセージの発行時にエラーが発生した場合は、まずそのエラーを修正してください。次の手順は、このエラーを修正するのに役立つ場合があります。
+ 

**MQTT クライアントで入力メッセージが表示されない**  
入力メッセージを `device/22/data` トピックにサブスクライブすると、そのメッセージは MQTT クライアントに表示されます。`device/+/data`トピックフィルターを選択します。

**確認すべき事項**
  + 

**サブスクライブしたトピックフィルターを確認する**  
手順の説明に従って入力メッセージのトピックをサブスクライブした場合は、発行するたびに入力メッセージのコピーが表示されます。

    メッセージが表示されない場合は、サブスクライブしたトピック名を確認し、発行したトピックと比較します。トピック名は大文字と小文字が区別されます。サブスクライブしたトピックは、メッセージペイロードを発行したトピックと同一である必要があります。
  + 

**メッセージ発行機能を確認する**  
MQTT クライアントの [**Subscriptions**] (サブスクリプション) で、[**device/\$1/data**] を選択し、パブリッシュ メッセージのトピックを確認してから、[**Publish to topic**] (トピックに発行) を選択します。トピックの下にある編集ボックスからメッセージペイロードがメッセージリストに表示されるのを確認できるはずです。
+ 

**DynamoDB テーブルにデータが表示されない**  
まず、テーブルのヘッダーの右上にある更新アイコンを選択して、表示を更新します。探しているデータが表示されない場合は、以下を確認してください。

**確認すべき事項**
  + 

**AWS リージョン MQTT クライアントの と作成したルールを確認する**  
MQTT クライアントを実行しているコンソールは、作成したルールと同じ AWS リージョンにある必要があります。
  + 

**ルールクエリステートメントの入力メッセージのトピックを確認する**  
ルールが機能するためには、ルールクエリステートメントの FROM 句のトピックフィルターに一致するトピック名を持つメッセージを受信する必要があります。

    ルールクエリステートメントのトピックフィルターの綴りを、MQTT クライアントのトピックフィルターの綴りと照らし合わせて確認します。トピック名では大文字と小文字が区別され、メッセージのトピックはルールクエリステートメントのトピックフィルターと一致する必要があります。
  + 

**入力メッセージペイロードの内容を確認する**  
ルールが機能するためには、SELECT ステートメントで宣言されているメッセージペイロード内のデータフィールドを見つける必要があります。

    ルールクエリステートメントの `temperature` フィールドの綴りを、MQTT クライアントのメッセージペイロードの綴りと照らし合わせて確認します。フィールド名では大文字と小文字が区別され、ルールクエリステートメントの `temperature` フィールドはメッセージペイロードの `temperature` フィールドと同じである必要があります。

    メッセージペイロード内の JSON ドキュメントが正しくフォーマットされていることを確認します。JSON にコンマがないなどのエラーがある場合、ルールはそれを読み取ることができません。
  + 

**ルールアクションで使用されるキー名とフィールド名を確認する**  
トピックルールで使用されるフィールド名は、発行メッセージの JSON メッセージペイロードにあるフィールド名と一致する必要があります。

    コンソールで作成したルールを開き、そのルールを持つ MQTT クライアントで使用されているルールアクション設定のフィールド名を確認します。
  + 

**ルールによって使用されているロールを確認する**  
ルールのアクションには、元のトピックを受け取り、新しいトピックを発行するためのアクセス許可が必要です。

    ルールにメッセージデータの受信と DynamoDB テーブルの更新を許可するポリシーは、使用されるトピックに固有のものです。ルールで使用されるトピックまたは DynamoDB テーブル名を変更した場合は、ルールアクションのロールを更新して、ポリシーが一致するように更新する必要があります。

    これが問題であると疑われる場合は、ルールのアクションを編集し、新しいロールを作成します。ルールアクションによって作成された新しいロールは、これらのアクションを実行するために必要な権限を受け取ります。

## ステップ 4: 結果と次のステップを確認する
<a name="iot-ddb-rule-review"></a>

このルールを使用して DynamoDB テーブルにいくつかのメッセージを送信した後、チュートリアルからいくつかの側面を変更すると、テーブルに書き込まれるデータにどのように影響するかを試してみてください。手始めにいくつかアイデアをご紹介します。
+ 入力メッセージのトピックの *device\$1id* を変更し、データへの影響を観察します。これを使用して、複数の気象センサーからのデータ受信をシミュレートできます。
+ ルールクエリステートメントで選択したフィールドを変更し、データへの影響を確認します。これを使用すると、テーブルに保存されたデータをフィルタリングできます。
+ 再発行ルールアクションを追加して、テーブルに追加された各行について MQTT メッセージを送信します。これをデバッグに使用することができます。

このチュートリアルを完了したら、[チュートリアル: AWS Lambda 関数を使用して通知をフォーマットする](iot-lambda-rule.md) を確認してください。

# チュートリアル: AWS Lambda 関数を使用して通知をフォーマットする
<a name="iot-lambda-rule"></a>

このチュートリアルでは、MQTT メッセージデータを AWS Lambda アクションに送信してフォーマットし、別の AWS サービスに送信する方法を示します。このチュートリアルでは、 AWS Lambda アクションは AWS SDK を使用して、 の使用方法に関するチュートリアルで作成した Amazon SNS トピックにフォーマットされたメッセージを送信します[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md)。

[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md) の方法に関するチュートリアルでは、ルールのクエリステートメントから生成された JSON ドキュメントがテキストメッセージの本文として送信されました。その結果、次の例のようなテキストメッセージが表示されました。

```
{"device_id":"32","reported_temperature":38,"max_temperature":30}
```

このチュートリアルでは、 AWS Lambda ルールアクションを使用して、ルールクエリステートメントのデータを次の例のようにわかりやすい形式にフォーマットする AWS Lambda 関数を呼び出します。

```
Device 32 reports a temperature of 38, which exceeds the limit of 30.
```

このチュートリアルで作成する AWS Lambda 関数は、ルールクエリステートメントのデータを使用してメッセージ文字列をフォーマットし、 AWS SDK の [SNS 発行](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sns.html#SNS.Client.publish)関数を呼び出して通知を作成します。

**このチュートリアルで学習する内容**
+  AWS Lambda 関数を作成してテストする方法
+  AWS Lambda 関数で AWS SDK を使用して Amazon SNS 通知を発行する方法
+ ルールクエリステートメントでシンプルな SQL クエリと関数を使用する方法
+ MQTT クライアントを使用して AWS IoT ルールをテストする方法

このチュートリアルの完了には 45 分ほどかかります。

**Topics**
+ [ステップ 1: テキストメッセージを送信する AWS Lambda 関数を作成する](#iot-lambda-rule-create-lambda)
+ [ステップ 2: AWS IoT ルールアクションを使用して AWS Lambda ルールを作成する](#iot-lambda-rule-create-rule)
+ [ステップ 3: AWS IoT ルールと AWS Lambda ルールアクションをテストする](#iot-lambda-rule-test-rule)
+ [ステップ 4: 結果と次のステップを確認する](#iot-lambda-rule-next-steps)

**このチュートリアルを開始する前に、以下の要件を満たしていることを確認してください。**
+ 

**[セットアップ AWS アカウント](setting-up.md)**  
このチュートリアルを完了するには、 AWS アカウント と AWS IoT コンソールが必要です。
+ 

**[MQTT クライアントで AWS IoT MQTT メッセージを表示する](view-mqtt-messages.md) を確認したこと**  
トピックにサブスクライブおよび発行するために MQTT クライアントを使用できることを確認してください。この手順では、MQTT クライアントを使用して新しいルールをテストします。
+ 

**このセクションのその他のルールチュートリアルを完了しました**  
このチュートリアルでは、[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md) の方法に関するチュートリアルで作成した SNS 通知トピックが必要です。また、このセクションの他のルール関連のチュートリアルを完了していることも前提としています。
+ 

**[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) の概要を確認する**  
 AWS Lambda を使用したことがない場合は、[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html)「」と[「Lambda の開始方法](https://docs.aws.amazon.com//lambda/latest/dg/getting-started.html)」を確認して、その用語と概念を確認してください。

## ステップ 1: テキストメッセージを送信する AWS Lambda 関数を作成する
<a name="iot-lambda-rule-create-lambda"></a>

このチュートリアルの AWS Lambda 関数は、ルールクエリステートメントの結果を受け取り、要素をテキスト文字列に挿入し、その結果の文字列を通知のメッセージとして Amazon SNS に送信します。

通知の送信にルールアクション[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md)を使用した AWS IoT のチュートリアルとは異なり、このチュートリアルは AWS SDK の 関数を使用して Lambda 関数から通知を送信します。ただし、このチュートリアルで使用されている実際の Amazon SNS 通知トピックは、[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md) の方法に関するチュートリアルで使用したものと同じです。

**テキストメッセージを送信する AWS Lambda 関数を作成するには**

1. 新しい AWS Lambda 関数を作成します。

   1. [AWS Lambda コンソール](https://console.aws.amazon.com//lambda/home)で、[**関数の作成**] を選択します。

   1. [**Create function**] (関数の作成) で、[**Use a blueprint**] (ブループリントを使用) を選択します。

      **hello-world-python** ブループリントを検索して選択し、[**Configure**] (設定) を選択します。

   1. [**Basic information**] (基本的な情報) で、次の操作を実行します。

      1. [**Function name**] (関数名) で、関数の名前 **format-high-temp-notification** を入力します。

      1. **実行ロール**で、** AWS ポリシーテンプレートから新しいロールを作成する**を選択します。

      1. [Role name] (ロール名) で、新しいロールの名前 **format-high-temp-notification-role** を入力します。

      1. [**Policy templates - *optional***] (ポリシーテンプレート - オプション) で、[**Amazon SNS publish policy**] (Amazon SNS 発行ポリシー) を検索して選択します。

      1. [**Create function**] を選択します。

1. ブループリントコードを変更して、Amazon SNS 通知をフォーマットして送信します。

   1. 関数を作成すると、**format-high-temp-notification** の詳細ページが表示されます。表示されない場合は、[[Lambda **Functions**](https://console.aws.amazon.com//lambda/home#/functions)] (Lambda 関数) ページから開きます。

   1. **format-high-temp-notification** の詳細ページで、[**Configuration**] (設定) タブを選択し、[**Function code**] (関数コード) パネルまでスクロールします。

   1. [**Function code**] (関数コード) ウィンドウの [**Environment**] (環境) ペインで、Python ファイル `lambda_function.py` を選択します。

   1. [**Function code**] (関数コード) ウィンドウで、ブループリントから元のプログラムコードをすべて削除し、このコードに置き換えます。

      ```
      import boto3
      #
      #   expects event parameter to contain:
      #   {
      #       "device_id": "32",
      #       "reported_temperature": 38,
      #       "max_temperature": 30,
      #       "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
      #   }
      # 
      #   sends a plain text string to be used in a text message
      #
      #      "Device {0} reports a temperature of {1}, which exceeds the limit of {2}."
      #   
      #   where:
      #       {0} is the device_id value
      #       {1} is the reported_temperature value
      #       {2} is the max_temperature value
      #
      def lambda_handler(event, context):
      
          # Create an SNS client to send notification
          sns = boto3.client('sns')
      
          # Format text message from data
          message_text = "Device {0} reports a temperature of {1}, which exceeds the limit of {2}.".format(
                  str(event['device_id']),
                  str(event['reported_temperature']),
                  str(event['max_temperature'])
              )
      
          # Publish the formatted message
          response = sns.publish(
                  TopicArn = event['notify_topic_arn'],
                  Message = message_text
              )
      
          return response
      ```

   1. [**デプロイ**] を選択します。

1. 新しいウィンドウで、[チュートリアル: Amazon SNS 通知の送信](iot-sns-rule.md) の方法に関するチュートリアルから、Amazon SNS トピックの Amazon リソースネーム (ARN) を検索します。

   1. 新しいウィンドウで、[Amazon SNS コンソールの [Topics] (トピック) ページ](https://console.aws.amazon.com//sns/v3/home#/topics)を開きます。

   1. [**Topics**] (トピック) ページで、Amazon SNS トピックのリストから **high\$1temp\$1notice** 通知トピックを見つけます。

   1. 次のステップで使用する **high\$1temp\$1notice** 通知トピックの **ARN** を見つけます。

1. Lambda 関数のテストケースを作成します。

   1. コンソールの [[Lambda **Functions**](https://console.aws.amazon.com//lambda/home#/functions)] (Lambda 関数) ページの **format-high-temp-notification** ページで、ページの右上にある (無効に見える) [**Select a test event**] (テストイベントの選択) を選択し、[**Configure test events**] (テストイベントの設定) を選択します。

   1. [**Configure test event**] (テストイベントの設定) で、[**Create new test event**] (新しいテストイベントの作成) を選択します。

   1. [**Event name**] (イベント名) で、**SampleRuleOutput** と入力します。

   1. [**Event name**] (イベント名) の下の JSON エディタで、このサンプル JSON ドキュメントを貼り付けます。これは、 AWS IoT ルールが Lambda 関数に送信する内容の例です。

      ```
      {
        "device_id": "32",
        "reported_temperature": 38,
        "max_temperature": 30,
        "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
      }
      ```

   1. **high\$1temp\$1notice** 通知トピックの **ARN** があるウィンドウを参照し、ARN 値をコピーします。

   1. JSON エディターの `notify_topic_arn` 値を通知トピックの ARN に置き換えます。

       AWS IoT ルールを作成するときにこの ARN 値を再度使用できるように、このウィンドウを開いたままにします。

   1. [**Create**] を選択します。

1. サンプルデータを使用して関数をテストします。

   1. **format-high-temp-notification** の詳細ページの右上で、**SampleRuleOutput** が [**Test**] (テスト) ボタンの横に表示されていることを確認します。表示されない場合は、利用可能なテストイベントのリストから選択します。

   1. サンプルルール出力メッセージを関数に送信するには、[**Test**] (テスト) を選択します。

関数と通知の両方が機能した場合は、通知にサブスクライブした電話でテキストメッセージが受信されます。

電話でテキストメッセージが受信されない場合は、操作の結果を確認してください。[**Function code**] (関数コード) パネルの [**Execution result**] (実行結果) タブで、応答を確認して、発生したエラーを見つけます。関数が電話に通知を送信できるようになるまで、次のステップに進まないでください。

## ステップ 2: AWS IoT ルールアクションを使用して AWS Lambda ルールを作成する
<a name="iot-lambda-rule-create-rule"></a>

このステップでは、ルールクエリステートメントを使用して、架空の気象センサーデバイスからのデータをフォーマットして Lambda 関数に送信します。この関数は、テキストメッセージをフォーマットして送信します。

気象装置から受信したサンプルメッセージペイロードは、次のようになります。

```
{
  "temperature": 28,
  "humidity": 80,
  "barometer": 1013,
  "wind": {
    "velocity": 22,
    "bearing": 255
  }
}
```

このルールでは、ルールクエリステートメントを使用して、次のような Lambda 関数のメッセージペイロードを作成します。

```
{
  "device_id": "32",
  "reported_temperature": 38,
  "max_temperature": 30,
  "notify_topic_arn": "arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice"
}
```

これには、Lambda 関数が正しいテキストメッセージをフォーマットして送信するために必要なすべての情報が含まれます。

**Lambda 関数を呼び出す AWS IoT ルールを作成するには**

1. [AWS IoT コンソールの**ルール**ハブを開きます](https://console.aws.amazon.com//iot/home#/rulehub)。

1. [**Rules**] (ルール) で新しいルールの作成を開始するには、[**Create**] (作成) を選択します。

1. [**Create a rule**] (ルールを作成) の上部で、次のように操作します。

   1. [**Name**] (名前) で、ルールの名前 **wx\$1friendly\$1text** を入力します。

      ルール名は AWS アカウント および リージョン内で一意である必要があり、スペースを含めることはできません。この名前にアンダースコア文字を使用して、ルールの名前の 2 つの単語を区切りました。

   1.  [**Description**] (説明) で、ルールの説明を入力します。

      わかりやすい説明を使用すると、このルールの動作と作成した理由を簡単に思い出すことができます。説明は必要なだけ長くすることができるので、できるだけ詳述してください。

1. [**Create a rule**] (ルールを作成) の [**Rule query statement**] (ルールクエリステートメント) で、以下を実行します。

   1.  [**Using SQL version**] (SQL バージョンの使用) で、**2016-03-23** を選択します。

   1. [**Rule query statement**] (ルールクエリステートメント) 編集ボックスで、ステートメントを入力します。

      ```
      SELECT 
        cast(topic(2) AS DECIMAL) as device_id, 
        temperature as reported_temperature,
        30 as max_temperature,
        'arn:aws:sns:us-east-1:57EXAMPLE833:high_temp_notice' as notify_topic_arn
      FROM 'device/+/data' WHERE temperature > 30
      ```

      このステートメント:
      + `device/+/data` トピックフィルターに一致し、`temperature` 値が 30 より大きいトピックを含む MQTT メッセージをリッスンします。
      + トピック文字列から 2 番目の要素を選択し、それを 10 進数に変換してから、`device_id` フィールドに割り当てます。
      + メッセージペイロードから `temperature` フィールドの値を選択し、それを `reported_temperature` フィールドに割り当てます。
      + 制限値を表す定数値 `30` を作成し、それを `max_temperature` フィールドに割り当てます。
      + `notify_topic_arn` フィールドの定数値を作成します。

   1. **high\$1temp\$1notice** 通知トピックの **ARN** があるウィンドウを参照し、ARN 値をコピーします。

   1. ルールクエリステートメントエディタの ARN 値 (*arn:aws:sns:us-east-1:57EXAMPLE833:high\$1temp\$1notice*) を通知トピックの ARN に置き換えます。

1. [**Set one or more actions**] (1 つ以上のアクションを設定) で、以下を実行します。

   1. このルールのルールアクションのリストを開くには、[**Add action**] (アクションの追加) を選択します。

   1. [**Select an action**] (アクションを選択してください) で、[**Send a message to a Lambda function**] (Lambda 関数にメッセージを送信する) を選択します。

   1. 選択したアクションの設定ページを開くには、アクションリストの下部にある [**Configure action**] (アクションの設定) を選択します。

1. [**Configure action**] (アクションの設定) で、次のとおり実行します。

   1. [**Function name**] (関数名) で、[**Select**] (選択) を選択します。

   1. **format-high-temp-notification** を選択します。

   1. [**Configure action**] (アクションの設定) の下部で、[**Add action**] (アクションの追加) を選択します。

   1. ルールを作成するには、[**Create a rule**] (ルールの作成) の下部にある [**Create rule**] (ルールの作成) を選択します。

## ステップ 3: AWS IoT ルールと AWS Lambda ルールアクションをテストする
<a name="iot-lambda-rule-test-rule"></a>

新しいルールをテストするには、MQTT クライアントを使用して、このルールで使用される MQTT メッセージを発行して、これにサブスクライブします。

新しいウィンドウの [AWS IoT コンソールで MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)を開きます。これで、MQTT クライアントの設定を失うことなくルールを編集できるようになりました。コンソールの別のページに移動するために MQTT クライアントを残すと、サブスクリプションやメッセージログは失われます。

**MQTT クライアントを使用してルールをテストするには**

1. [AWS IoT コンソールの MQTT クライアント](https://console.aws.amazon.com//iot/home#/test)で、入力トピック (この場合は `device/+/data`) をサブスクライブします。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Subscribe to topic**] (トピックへのサブスクライブ) を選択します。

   1. [**Subscription topic**] (サブスクリプショントピック) で、入力トピックフィルター **device/\$1/data** のトピックを入力します。

   1. 残りのフィールドはデフォルト設定のままにします。

   1. [**Subscribe to topic**] を選択します。

      [**Subscriptions**] (サブスクリプション) 列の [**Publish to a topic**] (トピックへの発行) の下に **device/\$1/data** が表示されます。

1. 特定のデバイス ID **device/32/data** を使用して入力トピックにメッセージを発行します。ワイルドカード文字を含む MQTT トピックには発行できません。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Publish to topic**] (トピックに発行) を選択します。

   1. [**Publish**] (発行) フィールドに、入力トピック名 **device/32/data** を入力します。

   1. ここに表示されているサンプルデータをコピーし、トピック名の下にある編集ボックスにサンプルデータを貼り付けます。

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT メッセージを発行するには、[**Publish to topic**] (トピックに発行) を選択します。

1. テキストメッセージが送信されたことを確認します。

   1. MQTT クライアントの [**Subscriptions**] (サブスクリプション) の下に、以前にサブスクライブしたトピックの隣に緑色のドットが表示されます。

      緑色のドットは、最後にメッセージを表示してから 1 つ以上の新しいメッセージが受信されたことを示します。

   1. [**Subscriptions**] (サブスクリプション) で [**device/\$1/data**] を選択して、メッセージペイロードが今発行したものと一致し、次のようになっていることを確認します。

      ```
      {
        "temperature": 38,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. SNS トピックのサブスクライブに使用した電話を確認し、メッセージペイロードの内容が次のようになっていることを確認します。

      ```
      Device 32 reports a temperature of 38, which exceeds the limit of 30.
      ```

      メッセージトピックのトピック ID 要素を変更する場合、`topic(2)` 値を数値にキャストすることは、メッセージトピックのその要素に数字のみが含まれている場合にのみ機能することに注意してください。

1. 温度が制限を超えていない MQTT メッセージの送信を試みます。

   1. MQTT クライアントの [**Subscription**] (サブスクリプション) で、[**Publish to topic**] (トピックに発行) を選択します。

   1. [**Publish**] (発行) フィールドに、入力トピック名 **device/33/data** を入力します。

   1. ここに表示されているサンプルデータをコピーし、トピック名の下にある編集ボックスにサンプルデータを貼り付けます。

      ```
      {
        "temperature": 28,
        "humidity": 80,
        "barometer": 1013,
        "wind": {
          "velocity": 22,
          "bearing": 255
        }
      }
      ```

   1. MQTT メッセージを送信するには、[**Publish to topic**] (トピックに発行) を選択します。

   **device/\$1/data** サブスクリプションで送信したメッセージが表示されますが、温度値がルールクエリステートメントの最大温度を下回っているため、テキストメッセージは受信されません。

   正しい動作が確認できない場合は、トラブルシューティングのヒントを確認してください。

### AWS Lambda ルールと通知のトラブルシューティング
<a name="iot-lambda-rule-troubleshoot"></a>

想定する結果が得られない場合に備えて、確認すべき事項をいくつか示します。
+ 

**エラーバナーが表示された**  
入力メッセージの発行時にエラーが発生した場合は、まずそのエラーを修正してください。次の手順は、このエラーを修正するのに役立つ場合があります。
+ 

**MQTT クライアントで入力メッセージが表示されない**  
手順で説明されているように `device/+/data` トピックフィルターをサブスクライブした場合、入力メッセージを `device/32/data` トピックに発行するたびに、そのメッセージが MQTT クライアントに表示されます。

**確認すべき事項**
  + 

**サブスクライブしたトピックフィルターを確認する**  
手順の説明に従って入力メッセージのトピックをサブスクライブした場合は、発行するたびに入力メッセージのコピーが表示されます。

    メッセージが表示されない場合は、サブスクライブしたトピック名を確認し、発行したトピックと比較します。トピック名は大文字と小文字が区別されます。サブスクライブしたトピックは、メッセージペイロードを発行したトピックと同一である必要があります。
  + 

**メッセージ発行機能を確認する**  
MQTT クライアントの [**Subscriptions**] (サブスクリプション) で、[**device/\$1/data**] を選択し、パブリッシュ メッセージのトピックを確認してから、[**Publish to topic**] (トピックに発行) を選択します。トピックの下にある編集ボックスからメッセージペイロードがメッセージリストに表示されるのを確認できるはずです。
+ 

**SMS メッセージが届かない**  
ルールが機能するには、メッセージの受信と SNS 通知の送信を許可する正しいポリシーを有しており、メッセージを受信する必要があります。

**確認すべき事項**
  + 

**AWS リージョン MQTT クライアントの と作成したルールを確認する**  
MQTT クライアントを実行しているコンソールは、作成したルールと同じ AWS リージョンにある必要があります。
  + 

**メッセージペイロードの温度値がテストしきい値を超えていることを確認します。**  
ルールクエリステートメントで定義されている温度値が 30 以下の場合、ルールはそのアクションを実行しません。
  + 

**ルールクエリステートメントの入力メッセージのトピックを確認する**  
ルールが機能するためには、ルールクエリステートメントの FROM 句のトピックフィルターに一致するトピック名を持つメッセージを受信する必要があります。

    ルールクエリステートメントのトピックフィルターの綴りを、MQTT クライアントのトピックフィルターの綴りと照らし合わせて確認します。トピック名では大文字と小文字が区別され、メッセージのトピックはルールクエリステートメントのトピックフィルターと一致する必要があります。
  + 

**入力メッセージペイロードの内容を確認する**  
ルールが機能するためには、SELECT ステートメントで宣言されているメッセージペイロード内のデータフィールドを見つける必要があります。

    ルールクエリステートメントの `temperature` フィールドの綴りを、MQTT クライアントのメッセージペイロードの綴りと照らし合わせて確認します。フィールド名では大文字と小文字が区別され、ルールクエリステートメントの `temperature` フィールドはメッセージペイロードの `temperature` フィールドと同じである必要があります。

    メッセージペイロード内の JSON ドキュメントが正しくフォーマットされていることを確認します。JSON にコンマがないなどのエラーがある場合、ルールはそれを読み取ることができません。
  + 

**Amazon SNS 通知を確認する**  
[ステップ 1: SMS テキストメッセージを送信する Amazon SNS トピックを作成する](iot-sns-rule.md#iot-sns-rule-create-sns-topic) では、Amazon SNS 通知をテストする方法を説明するステップ 3 を参照し、通知をテストして通知が機能することを確認します。
  + 

**Lambda 関数を確認する**  
[ステップ 1: テキストメッセージを送信する AWS Lambda 関数を作成する](#iot-lambda-rule-create-lambda) では、テストデータを使用して Lambda 関数をテストする方法を説明するステップ 5 を参照し、Lambda 関数をテストします。
  + 

**ルールによって使用されているロールを確認する**  
ルールのアクションには、元のトピックを受け取り、新しいトピックを発行するためのアクセス許可が必要です。

    ルールがメッセージデータを受信して再発行することを許可するポリシーは、使用されるトピックに固有です。メッセージデータの再発行に使用するトピックを変更する場合は、ルールアクションのロールを更新して、現在のトピックに一致するようにポリシーを更新する必要があります。

    これが問題であると思われる場合は、再発行ルールアクションを編集して、新しいロールを作成します。ルールアクションによって作成された新しいロールは、これらのアクションを実行するために必要な権限を受け取ります。

## ステップ 4: 結果と次のステップを確認する
<a name="iot-lambda-rule-next-steps"></a>

**このチュートリアルでは、次の作業を行いました。**
+ カスタマイズされたメッセージペイロードを使用した Amazon SNS 通知を送信する Lambda 関数を呼び出す AWS IoT ルールを作成しました。
+ ルールクエリステートメントでシンプルな SQL クエリと関数を使用して、Lambda 関数の新しいメッセージペイロードを作成しました。
+ MQTT クライアントを使用して AWS IoT ルールをテストしました。

**次の手順**  
このルールを使用していくつかのテキストメッセージを送信した後、チュートリアルの一部を変更すると、メッセージと送信される場合にどのような影響があるかを試してみてください。手始めにいくつかアイデアをご紹介します。
+ 入力メッセージのトピックの *device\$1id* を変更し、テキストメッセージの内容に生じる影響を確認します。
+ ルールクエリステートメントで選択したフィールドを変更し、Lambda 関数を更新して新しいメッセージで使用し、テキストメッセージの内容に生じる影響を確認します。
+ ルールクエリステートメントのテストを変更して、最高温度ではなく最低温度をテストします。Lambda 関数を更新して新しいメッセージをフォーマットし、`max_temperature` の名前を変更することを忘れないでください。
+  AWS IoT ルールの開発中および使用中に発生する可能性のあるエラーを見つける方法の詳細については、「」を参照してください[モニタリング AWS IoT](monitoring_overview.md)。

# デバイスがオフラインになっている間にデバイスの状態をデバイスシャドウで保持する
<a name="iot-shadows-tutorial"></a>

これらのチュートリアルでは、 AWS IoT Device Shadow サービスを使用してデバイスの状態情報を保存および更新する方法を示します。JSON ドキュメントである Shadow ドキュメントは、デバイス、ローカルアプリケーション、またはサービスによって発行されたメッセージに基づいて、デバイスの状態の変化を示します。このチュートリアルでは、Shadow ドキュメントが電球の色の変化を示します。これらのチュートリアルでは、デバイスがインターネットから切断されている場合でもシャドウがこの情報を保存し、オンラインに戻ってこの情報をリクエストしたときに最新の状態情報をデバイスに返す方法も示しています。

ここに示されている順序でこれらのチュートリアルを試すことをお勧めします。この順序は、作成が必要な AWS IoT リソースと必要なハードウェアのセットアップから始まります。これは、概念を段階的に学ぶのにも役立ちます。これらのチュートリアルでは、 で使用する Raspberry Pi デバイスを設定して接続する方法を示します AWS IoT。必要なハードウェアがない場合は、選択したデバイスに適応させるか、[Amazon EC2 で仮想デバイスを作成](creating-a-virtual-thing.md)して、これらのチュートリアルに従うことができます。

**チュートリアルのシナリオの概要**  
これらのチュートリアルのシナリオは、電球の色を変更し、そのデータを予約済みのシャドウトピックに発行するローカルアプリケーションまたはサービスです。これらのチュートリアルは、[インタラクティブな開始方法のチュートリアル](interactive-demo.md)で説明されている Device Shadow 機能に似ており、Raspberry Pi デバイスに実装されています。このセクションのチュートリアルでは、名前付きのシャドウまたは複数のデバイスに対応する方法を示しつつ、単一のクラシックシャドウに焦点を当てます。

以下のチュートリアルは、 AWS IoT Device Shadow サービスの使用方法を学ぶのに役立ちます。
+ 

**[チュートリアル: シャドウアプリケーションを実行するための Raspberry Pi の準備](create-resources-shadow.md)**  
このチュートリアルでは、 に接続するための Raspberry Pi デバイスを設定する方法を示します AWS IoT。また、 AWS IoT ポリシードキュメントとモノのリソースを作成し、証明書をダウンロードして、そのモノのリソースにポリシーをアタッチします。このチュートリアルの完了には 30 分ほどかかります。
+ 

**[チュートリアル: Device SDK のインストールと Device Shadows のサンプルアプリケーションの実行](lightbulb-shadow-application.md)**  
このチュートリアルでは、必要なツール、ソフトウェア、 AWS IoT Device SDK for Python をインストールし、サンプルシャドウアプリケーションを実行する方法を示します。このチュートリアルは、[Raspberry Pi または他のデバイスを接続する](connecting-to-existing-device.md) に示されている概念に基づいており、完了までに 20 分かかります。
+ 

**[チュートリアル: サンプルアプリケーションと MQTT テストクライアントを使用した Device Shadow とのやり取り](interact-lights-device-shadows.md)**  
このチュートリアルでは、`shadow.py`サンプルアプリケーションと**AWS IoT コンソール**を使用して、 AWS IoT Device Shadows と電球の状態の変化との相互作用を観察する方法を示します。このチュートリアルでは、MQTT メッセージを Device Shadow の予約済みトピックに送信する方法も示しています。このチュートリアルの完了には 45 分間を要する場合があります。

**AWS IoT Device Shadow の概要**  
Device Shadow は、 AWS IoT レジストリで作成した[モノのリソース](iot-thing-management.md)によって管理されるデバイスの永続的な仮想表現です。Shadow ドキュメントは、デバイスの現在の状態の情報を保存および取得するために使用される JSON または JavaScript 表記のドキュメントです。シャドウを使用すれば、デバイスがインターネットに接続されているかどうかにかかわらず、MQTT トピックまたは HTTP REST API を介してデバイスの状態を取得および設定できます。

シャドウのドキュメントには、デバイスの状態の次の側面を説明する `state` プロパティが含まれています。
+ `desired`: アプリケーションは、`desired` オブジェクトを更新することによって、デバイスプロパティの必要な状態を指定します。
+ `reported`: デバイスは、`reported` オブジェクト内の現在の状態を報告します。
+ `delta`: `delta` オブジェクト内の目的の状態と報告された状態 AWS IoT の違いを報告します。

これは、Shadow 状態ドキュメントの例です。

```
{
  "state": {
    "desired": {
      "color": "green"
      },
    "reported": {
      "color": "blue"
      },
    "delta": {
      "color": "green"
      }
   }
}
```

デバイスの Shadow ドキュメントを更新するには、[予約済みの MQTT トピック](reserved-topics.md#reserved-topics-shadow)、HTTP で `GET`、`UPDATE`、および `DELETE` オペレーションをサポートする [Device Shadow REST API](device-shadow-rest-api.md)、ならびに [AWS IoT CLI](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot-data/index.html) を使用できます。

前の例で、`desired` 色を `yellow` に変更したいとします。これを行うには、[UpdateThingShadow](device-shadow-rest-api.md#API_UpdateThingShadow) API にリクエストを送信するか、[Update](device-shadow-mqtt.md#update-pub-sub-topic) トピック `$aws/things/THING_NAME/shadow/update` にメッセージを発行します。

```
{
  "state": {
    "desired": {
      "color": yellow
    }
  }
}
```

更新は、リクエストで指定したフィールドにのみ反映されます。Device Shadow が正常に更新されると、 は`delta`トピック に新しい`desired`状態 AWS IoT を発行します`$aws/things/THING_NAME/shadow/delta`。この場合の Shadow ドキュメントは次のようになります。

```
{
  "state": {
    "desired": {
      "color": yellow
    },
    "reported": {
      "color": green
    },
    "delta": {
      "color": yellow
      }
  }
}
```

次に、次の JSON メッセージ`$aws/things/THING_NAME/shadow/update`を含む `Update`トピックを使用して、新しい状態が AWS IoT Device Shadow に報告されます。

```
{
  "state": {
    "reported": {
      "color": yellow
    }
  }
}
```

現在の状態情報を取得する場合は、[GetThingShadow](device-shadow-rest-api.md#API_GetThingShadow) API にリクエストを送信するか、MQTT メッセージを [Get](device-shadow-mqtt.md#get-pub-sub-topic) トピック `$aws/things/THING_NAME/shadow/get` に発行します。

Device Shadow サービスの使用の詳細については、「[AWS IoT Device Shadow サービス](iot-device-shadows.md)」を参照してください。

デバイス、アプリケーション、およびサービスでの Device Shadow の使用の詳細については、[デバイスでのシャドウの使用](device-shadow-comms-device.md) および [アプリとサービスでのシャドウの使用](device-shadow-comms-app.md) を参照してください。

 AWS IoT シャドウの操作については、「」を参照してください[シャドウとの相互作用](device-shadow-data-flow.md)。

MQTT の予約済みトピックおよび HTTP REST API については、[Device Shadow MQTT トピック](device-shadow-mqtt.md) および [Device Shadow の REST API](device-shadow-rest-api.md) を参照してください。

# チュートリアル: シャドウアプリケーションを実行するための Raspberry Pi の準備
<a name="create-resources-shadow"></a>

このチュートリアルでは、Raspberry Pi デバイスをセットアップして設定し、デバイスが MQTT メッセージを接続および交換するために必要な AWS IoT リソースを作成する方法を示します。

**注記**  
[Amazon EC2 を使用して仮想デバイスを作成する](creating-a-virtual-thing.md) する予定がある場合は、このページをスキップして [デバイスを設定する](configure-device.md) に進むことができます。仮想のモノを作成するときに、これらのリソースを作成します。Raspberry Pi の代わりに別のデバイスを使用したい場合は、選択したデバイスに合わせてこれらのチュートリアルに従ってみてください。

**このチュートリアルの学習内容は次のとおりです。**
+ Raspberry Pi デバイスを設定し、 で使用するように設定します AWS IoT。
+ デバイスが サービスとやり取り AWS IoT することを許可する AWS IoT ポリシードキュメントを作成します。
+ X.509 デバイス証明書にモノ AWS IoT のリソースを作成し、ポリシードキュメントをアタッチします。

  モノは、 AWS IoT レジストリ内のデバイスの仮想表現です。証明書はデバイスを AWS IoT Core に認証し、ポリシードキュメントはデバイスを操作することを許可します AWS IoT。

**このチュートリアルを実行する方法**  
Device Shadows の `shadow.py` サンプルアプリケーションを実行するには、 AWS IoTに接続する Raspberry Pi デバイスが必要です。ここに示されている順序でこのチュートリアルに従うことをお勧めします。この順序では、最初に Raspberry Pi とその付属内容を設定してから、ポリシーを作成し、作成したモノのリソースにポリシーをアタッチします。その後、Raspberry Pi でサポートされているグラフィカルユーザーインターフェイス (GUI) を使用してデバイスのウェブブラウザで AWS IoT コンソールを開くことで、このチュートリアルに従うことができます。これにより、接続のために証明書を Raspberry Pi に直接ダウンロードしやすくなります AWS IoT。

**このチュートリアルを開始する前に、以下の要件を満たしていることを確認してください。**
+  AWS アカウント。アカウントをお持ちではない場合、続行する前に、[セットアップ AWS アカウント](setting-up.md) に記載されている手順を完了してください。このチュートリアルを完了するには、 AWS アカウント と AWS IoT コンソールが必要です。
+ Raspberry Pi とその必要な付属内容。次が必要になります。
  + [Raspberry Pi 3 モデル B](https://www.raspberrypi.com/products/) 以降の最新のモデル。このチュートリアルは、Raspberry Pi の以前のバージョンでも機能する可能性がありますが、テストはしていません。
  + [Raspberry Pi OS (32 ビット)](https://www.raspberrypi.com/software/operating-systems/)または、それ以降。Raspberry Pi OS の最新バージョンを使用することをお勧めします。以前のバージョンの OS でも動作する可能性がありますが、テストはしていません。
  + イーサネットまたは Wi-Fi 接続。
  + キーボード、マウス、モニタ、ケーブル、および電源。

このチュートリアルの完了には 30 分ほどかかります。

## ステップ 1: Raspberry Pi デバイスをセットアップおよび設定する
<a name="setup-device-shadow"></a>

このセクションでは、 で使用する Raspberry Pi デバイスを設定します AWS IoT。

**重要**  
これらの指示を他のデバイスやオペレーティングシステムに合わせて適用するのが難しい場合があります。これらの指示を解釈してご利用のデバイスに適用するには、そのデバイスを十分に理解する必要があります。問題が発生した場合は、[Amazon EC2 を使用して仮想デバイスを作成する](creating-a-virtual-thing.md) または [Windows または Linux の PC または Mac を AWS IoT デバイスとして使用する](using-laptop-as-device.md) など、他のデバイスオプションのいずれかを代替策として試してください。

Raspberry Pi を設定して、オペレーティングシステム (OS) を起動し、インターネットに接続し、コマンドラインインターフェイスで Raspberry Pi とインタラクションできるようにする必要があります。Raspberry Pi でサポートされているグラフィカルユーザーインターフェイス (GUI) を使用して AWS IoT コンソールを開き、このチュートリアルの残りの部分を実行することもできます。

**Raspberry Pi をセットアップするには**

1. SD カードを Raspberry Pi の MicroSD カードスロットに挿入します。一部の SD カードには、ボードの起動後に OS をインストールするためのメニューを表示するインストールマネージャーがプリロードされています。Raspberry Pi イメージャーを使用して、カードに OS をインストールすることもできます。

1. Raspberry Pi の HDMI ポートに接続する HDMI ケーブルに、HDMI TV またはモニターを接続します。

1. キーボードとマウスを Raspberry Pi の USB ポートに接続し、電源アダプタをつないでボードを起動します。

Raspberry Pi の起動後、SD カードにインストールマネージャーがプリロードされている場合は、オペレーティングシステムをインストールするためのメニューが表示されます。OS のインストールに問題がある場合は、次の手順を試すことができます。Raspberry Pi のセットアップの詳細については、「[Raspberry Pi のセットアップ](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/)」を参照してください。

**Raspberry Pi のセットアップで問題が発生している場合は、以下の操作を実行します。**
+ ボードを起動する前に、SD カードを挿入したかどうかを確認してください。ボードを起動した後に SD カードを差し込むと、インストールメニューが表示されない場合があります。
+ テレビまたはモニタの電源が入っていて、正しい入力が選択されていることを確認してください。
+ Raspberry Pi と互換性のあるソフトウェアを使用していることを確認します。

Raspberry Pi OS をインストールして設定したら、Raspberry Pi のウェブブラウザを開き、 AWS IoT Core コンソールに移動して、このチュートリアルの残りのステップを続行します。

 AWS IoT Core コンソールを開くことができる場合は、Raspberry Pi の準備が整い、 に進むことができます[チュートリアル: でのデバイスのプロビジョニング AWS IoT](shadow-provision-cloud.md)。

問題がある場合や、さらにサポートが必要な場合は、「[Getting help for your Raspberry Pi](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/5)」を参照してください。

# チュートリアル: でのデバイスのプロビジョニング AWS IoT
<a name="shadow-provision-cloud"></a>

このセクションでは、チュートリアルで使用する AWS IoT Core リソースを作成します。

**Topics**
+ [ステップ 1: Device Shadow の AWS IoT ポリシーを作成する](#create-policy-shadow)
+ [ステップ 2: モノのリソースを作成し、ポリシーをモノにアタッチする](#create-thing-shadow)
+ [ステップ 3: 結果と次のステップを確認する](#resources-shadow-review)

## ステップ 1: Device Shadow の AWS IoT ポリシーを作成する
<a name="create-policy-shadow"></a>

X.509 証明書 AWS IoT Core AWS IoT は、デバイスが Device Shadow サービスで使用される MQTT 予約トピックへのサブスクライブや発行などの AWS IoT オペレーションを実行できるようにする証明書にアタッチされます。デバイスは、接続してメッセージを送信するときに証明書を提示します AWS IoT Core。

この手順では、サンプルプログラムの実行に必要な AWS IoT オペレーションをデバイスが実行できるようにするポリシーを作成します。タスクの実行に必要なアクセス許可のみを付与するポリシーを作成することをお勧めします。最初に AWS IoT ポリシーを作成し、後で作成するデバイス証明書にアタッチします。

**AWS IoT ポリシーを作成するには**

1. 左のメニューで、[**Secure**] (安全性)、[**Policies**] (ポリシー) の順に選択します。アカウントに既存のポリシーがある場合は、**[作成]** を選択します。それ以外の場合は、**[ポリシーがまだありません]** ページで **[ポリシーの作成]** を選択します。

1. [**ポリシーの作成**] ページで、以下の手順を実行します。

   1. **[名前]** フィールドに、ポリシーの名前 (**My\$1Device\$1Shadow\$1policy** など) を入力します。ポリシー名で個人を特定できる情報を使用しないでください。

   1. ポリシードキュメントでは、MQTT 予約トピックを発行およびサブスクライブするアクセス許可をデバイスに付与する接続、サブスクライブ、受信、および発行アクションについて説明します。

      以下のサンプルポリシーをコピーして、ポリシードキュメントに貼り付けます。`thingname` を、作成するモノの名前 ( など`My_light_bulb`)、 をサービスを使用している`region` AWS IoT リージョン、 をお客様の AWS アカウント 番号`account`に置き換えます。 AWS IoT ポリシーの詳細については、「」を参照してください[AWS IoT Core ポリシー](iot-policies.md)。  
****  

      ```
      {
          "Version":"2012-10-17",		 	 	 
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Publish"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Receive"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/get/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingname/shadow/update/delta"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": [
                      "iot:Subscribe"
                  ],
                  "Resource": [
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/get/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/get/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/accepted",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/rejected",
                      "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingname/shadow/update/delta"
                  ]
              },
              {
                  "Effect": "Allow",
                  "Action": "iot:Connect",
                  "Resource": "arn:aws:iot:us-east-1:123456789012:client/test-*"
              }
          ]
      }
      ```

## ステップ 2: モノのリソースを作成し、ポリシーをモノにアタッチする
<a name="create-thing-shadow"></a>

に接続されたデバイスは、 AWS IoT レジストリ内の*モノのリソース*で表す AWS IoT ことができます。*モノのリソース*は、このチュートリアルの電球など、特定のデバイスまたは論理エンティティを表します。

でモノを作成する方法については AWS IoT、「」で説明されている手順に従ってください[モノのオブジェクトを作成する](create-iot-resources.md#create-aws-thing)。そのチュートリアルの手順に従うときに注意すべき重要な点がいくつかあります。

1. **[単一のモノを作成する]** を選択し、**[名前]** フィールドに、以前にポリシーを作成したときに指定した `thingname` と同じモノの名前 (例: `My_light_bulb`) を入力します。

   モノを作成した後に名前を変更することはできません。`thingname` 以外の名前を付けた場合は、`thingname` という名前の新しいモノを作成し、古いモノを削除します。
**注記**  
モノの名前で個人を特定できる情報を使用しないでください。モノの名前は、暗号化されていない通信やレポートに表示されることがあります。

1. **[証明書が作成されました\$1]** ページの各証明書ファイルを見つけやすい場所にダウンロードすることをお勧めします。サンプルアプリケーションを実行するには、これらのファイルをインストールする必要があります。

   Raspberry Pi の `home` ディレクトリ内の `certs` サブディレクトリにファイルをダウンロードし、次の表に示されているように、各ファイルに簡素な名前を付けることをお勧めします。  
**証明書ファイル名**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/shadow-provision-cloud.html)

1. 証明書を有効にして接続を有効にしたら AWS IoT、**ポリシーをア**タッチを選択し、以前に作成したポリシー ( など**My\$1Device\$1Shadow\$1policy**) をモノにアタッチしていることを確認します。

   モノを作成したら、モノのリソースが AWS IoT コンソールのモノのリストに表示されます。

## ステップ 3: 結果と次のステップを確認する
<a name="resources-shadow-review"></a>

**このチュートリアルで学習した内容は次のとおりです。**
+ Raspberry Pi デバイスをセットアップおよび設定します。
+ デバイスが サービスとやり取り AWS IoT することを許可する AWS IoT ポリシードキュメントを作成します。
+ モノのリソースと関連する X.509 デバイス証明書を作成し、それにポリシードキュメントをアタッチします。

**次の手順**  
 AWS IoT デバイス SDK for Python をインストールし、`shadow.py`サンプルアプリケーションを実行し、Device Shadows を使用して状態を制御できるようになりました。このチュートリアルの実行方法の詳細については、[チュートリアル: Device SDK のインストールと Device Shadows のサンプルアプリケーションの実行](lightbulb-shadow-application.md) を参照してください。

# チュートリアル: Device SDK のインストールと Device Shadows のサンプルアプリケーションの実行
<a name="lightbulb-shadow-application"></a>

このセクションでは、必要なソフトウェアと AWS IoT Device SDK for Python をインストールし、`shadow.py`サンプルアプリケーションを実行して Shadow ドキュメントを編集し、シャドウの状態を制御する方法について説明します。

**このチュートリアルの学習内容は次のとおりです。**
+ インストールされているソフトウェアと AWS IoT Device SDK for Python を使用して、サンプルアプリケーションを実行します。
+ サンプルアプリケーションを使用して値を入力すると、どのように AWS IoT コンソールで目的の値が発行されるかについて説明します。
+ `shadow.py` サンプルアプリケーションと、MQTT プロトコルを使用してシャドウの状態を更新する方法を確認してください。

**このチュートリアルを実行する前に:**  
をセットアップし AWS アカウント、Raspberry Pi デバイスを設定し、Device Shadow サービスの MQTT 予約済みトピックを発行およびサブスクライブするアクセス許可をデバイスに付与する AWS IoT モノとポリシーを作成しておく必要があります。詳細については、「[チュートリアル: シャドウアプリケーションを実行するための Raspberry Pi の準備](create-resources-shadow.md)」を参照してください。

Git、Python、および AWS IoT Device SDK for Python もインストールされている必要があります。このチュートリアルは、チュートリアル [Raspberry Pi または他のデバイスを接続する](connecting-to-existing-device.md) で提示された概念に基づいています。そのチュートリアルをまだ試していない場合は、そのチュートリアルで説明されている手順に従って証明書ファイルと Device SDK をインストールしてから、このチュートリアルに戻って `shadow.py` サンプルアプリケーションを実行することをお勧めします。

**Topics**
+ [ステップ 1: shadow.py サンプルアプリケーションを実行する](#run-sample-application-shadows)
+ [ステップ 2: shadow.py Device SDK サンプルアプリケーションを確認する](#review-shadow-sample-code)
+ [ステップ 3: `shadow.py` サンプルアプリケーションの問題をトラブルシューティングする](#shadow-sample-app-troubleshoot)
+ [ステップ 4: 結果と次のステップを確認する](#sample-app-shadow-review)

このチュートリアルの完了には 20 分ほどかかります。

## ステップ 1: shadow.py サンプルアプリケーションを実行する
<a name="run-sample-application-shadows"></a>

`shadow.py` サンプルアプリケーションを実行する前に、インストールした証明書ファイルの名前と場所に加えて、次の情報が必要です。


**アプリケーションパラメータ値**  

|  Parameter  |  値がある場所  | 
| --- | --- | 
| your-iot-thing-name |  で前に作成した AWS IoT モノの名前[ステップ 2: モノのリソースを作成し、ポリシーをモノにアタッチする](shadow-provision-cloud.md#create-thing-shadow)。 この値を見つけるには、[AWS IoT コンソール](https://console.aws.amazon.com/iot/home)で [**Manage**] (管理) を選択し、[**Things**] (モノ) を選択します。  | 
| your-iot-endpoint |   *your-iot-endpoint* 値の形式は `endpoint_id-ats.iot.region.amazonaws.com` です (例: `a3qj468EXAMPLE-ats.iot.us-west-2.amazonaws.com`)。この値を検索するには: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/lightbulb-shadow-application.html)  | 

**サンプルアプリケーションをインストールして実行する**

1. サンプルアプリディレクトリに移動します。

   ```
   cd ~/aws-iot-device-sdk-python-v2/samples/service-clients
   ```

1. コマンドラインウィンドウで、示されているように *your-iot-endpoint* と *your-iot-thing-name* を置き換えて、このコマンドを実行します。

   ```
   python3 shadow.py --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint --thing_name your-iot-thing-name
   ```

1. サンプルアプリケーションが次のようになっていることを観察します。

   1. アカウントの AWS IoT サービスに接続します。

   1. `Delta` イベントと `Update` および `Get` 応答をサブスクライブします。

   1. ターミナルに必要な値を入力するように求められます。

   1. 次のような出力を表示します。

   ```
   Connecting to a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-0c8ae2ff-cc87-49d2-a82a-ae7ba1d0ca5a'...
   Connected!
   Subscribing to Delta events...
   Subscribing to Update responses...
   Subscribing to Get responses...
   Requesting current shadow state...
   Launching thread to read user input...
   Finished getting initial shadow state.
   Shadow contains reported value 'off'.
   Enter desired value:
   ```

**注記**  
`shadow.py` サンプルアプリケーションの実行に問題がある場合は、[ステップ 3: `shadow.py` サンプルアプリケーションの問題をトラブルシューティングする](#shadow-sample-app-troubleshoot) を確認してください。問題の修正に役立つ可能性のある追加情報を取得するには、コマンドラインに `--verbosity debug` パラメータを追加して、サンプルアプリケーションが実行内容に関する詳細メッセージを表示するようにします。

**値を入力し、Shadow ドキュメントの更新を観察する**  
ターミナルに `desired` 値を入力して値を指定すると、`reported` 値も更新されます。ターミナルで色 `yellow` を入力するとします。`reported` 値も色 `yellow` に更新されます。ターミナルに表示されるメッセージを次に示します。

```
Enter desired value:
yellow
Changed local shadow value to 'yellow'.
Updating reported shadow value to 'yellow'...
Update request published.
Finished updating reported shadow value to 'yellow'.
```

この更新リクエストを発行すると、 はモノのリソースのデフォルトのクラシックシャドウ AWS IoT を作成します。 AWS IoT コンソールで `reported`および `desired`値に発行した更新リクエストを確認するには、作成したモノのリソースの Shadow ドキュメントを確認します (例: `My_light_bulb`)。Shadow ドキュメントで更新を表示するには、次の操作を行います。

1.  AWS IoT コンソールで、**管理**を選択し、**モノ**を選択します。

1. 表示されるモノのリストで、作成したモノを選択し、[**Shadows**] (シャドウ) を選択してから、[**Classic Shadow**] (クラシックシャドウ) を選択します。

Shadow ドキュメントは次のようになり、色 `yellow` に設定された `reported` と `desired` の値が表示されます。これらの値は、ドキュメントの **[Shadow の状態]** のセクションに表示されます。

```
{
"desired": {
  "welcome": "aws-iot",
  "color": "yellow"
},
"reported": {
  "welcome": "aws-iot",
  "color": "yellow"
}
}
```

リクエストのタイムスタンプ情報とバージョン番号を含む **[メタデータ]** セクションも表示されます。

状態ドキュメントのバージョンを使用して、デバイスのシャドウのドキュメントの最新バージョンを更新していることを確認できます。別の更新リクエストを送信すると、バージョン番号が 1 ずつ増えます。更新リクエストでバージョンを渡したとき、そのバージョンと状態ドキュメントの現在のバージョンとが一致しない場合、サービスは HTTP 409 conflict レスポンスコードでリクエストを拒否します。

```
{
"metadata": {
  "desired": {
    "welcome": {
      "timestamp": 1620156892
    },
    "color": {
      "timestamp": 1620156893
    }
  },
  "reported": {
    "welcome": {
      "timestamp": 1620156892
    },
    "color": {
      "timestamp": 1620156893
    }
  }
},
"version": 10
}
```

Shadow ドキュメントについてさらに学び、状態情報の変化を観察するには、このチュートリアルの [ステップ 4: 結果と次のステップを確認する](#sample-app-shadow-review) セクションで説明されている次のチュートリアル [チュートリアル: サンプルアプリケーションと MQTT テストクライアントを使用した Device Shadow とのやり取り](interact-lights-device-shadows.md) に進んでください。必要に応じて、次のセクションで `shadow.py` サンプルコードとそれが MQTT プロトコルを使用する方法について学ぶこともできます。

## ステップ 2: shadow.py Device SDK サンプルアプリケーションを確認する
<a name="review-shadow-sample-code"></a>

このセクションでは、このチュートリアルで使用されている **AWS IoT Device SDK v2 for Python** の `shadow.py` サンプルアプリケーションを確認します。ここでは、MQTT および MQTT over WSS プロトコル AWS IoT Core を使用して に接続する方法を確認します。[AWS 共通ランタイム (AWS-CRT)](https://github.com/awslabs/aws-crt-python#aws-crt-python) ライブラリは、低レベルの通信プロトコルサポートを提供し、 AWS IoT Device SDK v2 for Python に含まれています。

このチュートリアルでは MQTT と MQTT over WSS を使用していますが、 は HTTPS リクエストを発行するデバイス AWS IoT をサポートしています。デバイスから HTTP メッセージを送信する Python プログラムの例については、Python の `requests` ライブラリを使用した [HTTPS コード例](http.md#codeexample)を参照してください。

デバイス通信に使用するプロトコルについて十分な情報に基づいた決定を行う方法については、[デバイス通信用のアプリケーションプロトコルの選択](protocols.md#protocol-selection) を確認してください。

**MQTT**  
`shadow.py` サンプルでは、[https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py) の `mtls_from_path` (以下に示されています) を呼び出して、MQTT プロトコルを使用して AWS IoT Core との接続を確立します。`mtls_from_path` では、X.509 証明書と TLS v1.2 を使用してデバイスを認証します。 AWS CRT ライブラリは、その接続の下位の詳細を処理します。

```
mqtt_connection = mqtt_connection_builder.mtls_from_path(
  endpoint=args.endpoint,
  cert_filepath=args.cert,
  pri_key_filepath=args.key,
  ca_filepath=args.ca_file,
  client_bootstrap=client_bootstrap,
  on_connection_interrupted=on_connection_interrupted,
  on_connection_resumed=on_connection_resumed,
  client_id=args.client_id,
  clean_session=False,
  keep_alive_secs=6
)
```
+ `endpoint` は、コマンドラインから渡した AWS IoT エンドポイントであり、 でこのデバイスを一意に識別する ID `client_id`です AWS リージョン。
+ `cert_filepath`、`pri_key_filepath`、および `ca_filepath` は、デバイスの証明書とプライベートキーファイル、およびルート CA ファイルへのパスです。
+ `client_bootstrap` は、ソケット通信アクティビティを処理する共通のランタイムオブジェクトであり、`mqtt_connection_builder.mtls_from_path` の呼び出しの前にインスタンス化されます。
+ `on_connection_interrupted` および `on_connection_resumed` は、デバイスの接続が中断されて再開されるときに呼び出すコールバック関数です。
+ `clean_session` は、新しい永続セッションを開始するか、既存のセッションに再接続するか (存在する場合) です。`keep_alive_secs` は `CONNECT` リクエストで送信するキープアライブ値 (秒単位) です。この間隔で ping が自動的に送信されます。サーバーは、この値の 1.5 倍の時間が経過しても ping を受信しなかった場合、接続が失われたとみなします。

この `shadow.py` サンプルでは、WSS 経由で MQTT プロトコルを使用して AWS IoT Core との接続を確立するために [https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py](https://github.com/awslabs/aws-crt-python/blob/89207bcf1387177034e02fe29e8e469ca45e39b7/awscrt/awsiot_mqtt_connection_builder.py) の `websockets_with_default_aws_signing` も呼び出します。MQTT over WSS も MQTT と同じパラメータを使用し、次の追加パラメータを受け取ります。
+ `region` は、 AWS 署名 V4 認証で使用される署名リージョンであり、認証に使用するために提供される AWS 認証情報`credentials_provider`です。リージョンはコマンドラインから渡され、`credentials_provider` オブジェクトは `mqtt_connection_builder.websockets_with_default_aws_signing` の呼び出しの直前にインスタンス化されます。
+ `websocket_proxy_options` は、プロキシホストを使用する場合の HTTP プロキシオプションです。`shadow.py` サンプルアプリケーションでは、この値は `mqtt_connection_builder.websockets_with_default_aws_signing` の呼び出しの直前にインスタンス化されます。

**Shadow トピックとイベントをサブスクライブする**  
`shadow.py` サンプルは接続の確立を試み、完全に接続されるまで待機します。接続されていない場合、コマンドはキューに入れられます。接続されると、サンプルはデルタイベントをサブスクライブし、メッセージを更新および取得し、サービスの品質 (QoS) レベル 1 (`mqtt.QoS.AT_LEAST_ONCE`) でメッセージを発行します。

デバイスが QoS レベル 1 のメッセージをサブスクライブすると、メッセージブローカーは、デバイスに送信できるようになるまで、デバイスがサブスクライブしているメッセージを保存します。メッセージブローカーは、デバイスから `PUBACK` 応答を受信するまでメッセージを再送信します。

MQTT プロトコルの詳細については、[MQTT プロトコルを確認する](sdk-tutorials.md#sdk-tutorials-mqtt-review) および [MQTT](mqtt.md) を参照してください。

このチュートリアルで使用される MQTT、MQTT over WSS、永続セッション、および QoS レベルの詳細については、「[pubsub.py Device SDK サンプルアプリケーションを確認する](sdk-tutorials.md#sdk-tutorials-explore-sample)」を参照してください。

## ステップ 3: `shadow.py` サンプルアプリケーションの問題をトラブルシューティングする
<a name="shadow-sample-app-troubleshoot"></a>

`shadow.py` サンプルアプリケーションを実行すると、ターミナルにいくつかのメッセージが表示され、`desired` 値を入力するように求められます。プログラムがエラーをスローした場合、エラーをデバッグするには、まずシステムに対して正しいコマンドを実行したかどうかを確認します。

場合によっては、エラーメッセージは接続の問題を示し、`Host name was invalid for dns resolution` または `Connection was closed unexpectedly` のようになることがあります。このような場合、次のことを確認してみてください。
+ 

**コマンド内のエンドポイントアドレスを確認する**  
サンプルアプリケーションを実行するために入力したコマンドの `endpoint` 引数 (例: `a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com`) を確認し、**AWS IoT コンソール**でこの値を確認します。

  正しい値を使用したかどうかを確認するには、次の手順に従います。

  1. **AWS IoT コンソール**で、[**Manage**] (管理)、[**Things**] (モノ) の順に選択します。

  1. サンプルアプリケーション用に作成したモノ (例: **My\$1light\$1bulb**) を選択してから、[**Interact**] (操作) を選択します。

  モノの詳細ページで エンドポイントは、[**HTTPS**] セクションに表示されます。また、以下を記載したメッセージも表示されます: `This thing already appears to be connected.`。
+ 

**証明書の有効化を確認する**  
証明書は、 を使用してデバイスを認証します AWS IoT Core。

  証明書がアクティブかどうかを確認するには、次の手順に従います。

  1. **AWS IoT コンソール**で、[**Manage**] (管理)、[**Things**] (モノ) の順に選択します。

  1. サンプルアプリケーション用に作成したモノ (例: **My\$1light\$1bulb**) を選択してから、[**Security**] (セキュリティ) を選択します。

  1. 証明書を選択し、証明書の詳細ページで [証明書の選択] を選択してから、証明書の詳細ページで **[アクション]** を選択します。

  ドロップダウンリストで **[有効化]** が使用できず、**[無効化]** しか選択できない場合、証明書は有効です。そうでない場合は、**[有効化]** を選択し、サンプルプログラムを再実行します。

  それでもプログラムが実行されない場合は、`certs` フォルダ内の証明書ファイル名を確認してください。
+ 

**モノのリソースにアタッチされているポリシーを確認する**  
証明書がデバイスを認証している間、 AWS IoT ポリシーにより、デバイスは MQTT 予約済みトピックへのサブスクライブや発行などの AWS IoT オペレーションを実行できます。

  正しいポリシーがアタッチされているかどうかを確認するには、次の手順に従います。

  1. 前述したとおりに証明書を検索し、**[ポリシー]** を選択します。

  1. 表示されたポリシーを選択し、デバイスに MQTT 予約トピックへ発行およびサブスクライブするためのアクセス許可を付与する `connect`、`subscribe`、`receive`、および `publish` アクションが説明されているかどうかを確認します。

     サンプルポリシーについては、[ステップ 1: Device Shadow の AWS IoT ポリシーを作成する](shadow-provision-cloud.md#create-policy-shadow) を参照してください。

  への接続に問題があることを示すエラーメッセージが表示された場合は AWS IoT、ポリシーに使用しているアクセス許可が原因である可能性があります。その場合は、 AWS IoT リソースへのフルアクセスを提供するポリシーから開始し、サンプルプログラムを再実行することをお勧めします。現在のポリシーを編集するか、現在のポリシーを選択して [**Detach**] (デタッチ) を選択し、フルアクセスを提供する別のポリシーを作成してモノのリソースにアタッチすることができます。後で、プログラムの実行に必要なアクションとポリシーのみにポリシーを制限できます。  
****  

  ```
  {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:*"
            ],
            "Resource": "*"
        }
    ]
  }
  ```
+ 

**Device SDK のインストールを確認する**  
それでもプログラムが実行されない場合は、Device SDK を再インストールして、SDK のインストールが完了していて正しいことを確認できます。

## ステップ 4: 結果と次のステップを確認する
<a name="sample-app-shadow-review"></a>

**このチュートリアルで学習した内容は次のとおりです。**
+ 必要なソフトウェア、ツール、および AWS IoT Device SDK for Python をインストールします。
+ サンプルアプリケーション `shadow.py` が、シャドウの現在の状態を取得および更新するために MQTT プロトコルを使用する方法を理解します。
+ Device Shadows のサンプルアプリケーションを実行し、 AWS IoT コンソールで Shadow ドキュメントの更新を確認します。また、プログラムの実行時に問題をトラブルシューティングし、エラーを修正する方法も学びました。

**次の手順**  
これで、`shadow.py` サンプルアプリケーションを実行し、Device Shadow を使用して状態を制御できます。 AWS IoT コンソールで Shadow ドキュメントの更新を観察し、サンプルアプリケーションが応答するデルタイベントを観察できます。MQTT テストクライアントを使用して、予約済みのシャドウトピックにサブスクライブし、サンプルプログラムの実行時にトピックが受信するメッセージを観察できます。このチュートリアルの実行方法の詳細については、[チュートリアル: サンプルアプリケーションと MQTT テストクライアントを使用した Device Shadow とのやり取り](interact-lights-device-shadows.md) を参照してください。

# チュートリアル: サンプルアプリケーションと MQTT テストクライアントを使用した Device Shadow とのやり取り
<a name="interact-lights-device-shadows"></a>

`shadow.py` サンプルアプリケーションを操作するには、`desired` の値のためにターミナルに値を入力します。たとえば、トラフィックライトに似た色を指定してリクエストに AWS IoT 応答し、報告された値を更新できます。

**このチュートリアルの学習内容は次のとおりです。**
+ `shadow.py` サンプルアプリケーションを使用して、必要な状態を指定し、シャドウの現在の状態を更新します。
+ Shadow ドキュメントを編集して、デルタイベントと、`shadow.py` サンプルアプリケーションがそれにどのように応答するかを観察します。
+ MQTT テストクライアントを使用して、シャドウトピックをサブスクライブし、サンプルプログラムを実行するときに更新を確認します。

**このチュートリアルを実行する前に、以下の条件を満たす必要があります。**  
をセットアップし AWS アカウント、Raspberry Pi デバイスを設定し、モノとポリシーを作成 AWS IoT しました。また、必要なソフトウェア、Device SDK、証明書ファイルをインストールし、ターミナルでサンプルプログラムを実行する必要があります。詳細については、前のチュートリアルの [チュートリアル: シャドウアプリケーションを実行するための Raspberry Pi の準備](create-resources-shadow.md) および [ステップ 1: shadow.py サンプルアプリケーションを実行する](lightbulb-shadow-application.md#run-sample-application-shadows) を参照してください。これらのチュートリアルをまだ完了していない場合は、完了する必要があります。

**Topics**
+ [ステップ 1: `shadow.py` サンプルアプリケーションを使用して、必要な値と報告された値を更新する](#update-desired-shadow-sample)
+ [ステップ 2: MQTT テストクライアントで `shadow.py` サンプルアプリケーションからのメッセージを表示する](#shadow-sample-view-msg)
+ [ステップ 3: Device Shadow インタラクションに関するエラーをトラブルシューティングする](#shadow-observe-messages-troubleshoot)
+ [ステップ 4: 結果と次のステップを確認する](#sample-shadow-review)

このチュートリアルの完了には 45 分ほどかかります。

## ステップ 1: `shadow.py` サンプルアプリケーションを使用して、必要な値と報告された値を更新する
<a name="update-desired-shadow-sample"></a>

前のチュートリアル では[ステップ 1: shadow.py サンプルアプリケーションを実行する](lightbulb-shadow-application.md#run-sample-application-shadows)、セクション で説明されているように目的の値を入力するときに、 AWS IoT コンソールで Shadow ドキュメントに発行されたメッセージを確認する方法を学習しました[チュートリアル: Device SDK のインストールと Device Shadows のサンプルアプリケーションの実行](lightbulb-shadow-application.md)。

前の例では、目的の色を `yellow` に設定しました。各値を入力すると、ターミナルは別の `desired` 値を入力するように求めます。同じ値 (`yellow`) をもう一度入力すると、アプリケーションはこれを認識し、新しい `desired` 値を入力するように求めます。

```
Enter desired value:
yellow
Local value is already 'yellow'.
Enter desired value:
```

ここで、 という色を入力したとします`green`。 AWS IoT はリクエストに対応し、`reported`値を に更新します`green`。これは、`desired` 状態が `reported` 状態と異なる場合に更新が行われる方法であり、デルタが発生します。

**`shadow.py` サンプルアプリケーションが Device Shadow インタラクションをシミュレートする方法:**

1. ターミナルに `desired` 値 (例: `yellow`) を入力して、目的の状態を発行します。

1. `desired` 状態が `reported` 状態 (色 `green` など) と異なるため、デルタが発生し、デルタにサブスクライブしているアプリケーションがこのメッセージを受信します。

1. アプリケーションはメッセージに応答し、その状態を `desired` 値 `yellow` に更新します。

1. その後、アプリケーションはデバイスの状態 `yellow` の新しい報告値を含む更新メッセージを発行します。

以下は、更新リクエストがどのように発行されるかを示す、ターミナルに表示されるメッセージを示しています。

```
Enter desired value:
green
Changed local shadow value to 'green'.
Updating reported shadow value to 'green'...
Update request published.
Finished updating reported shadow value to 'green'.
```

 AWS IoT コンソールでは、Shadow ドキュメントは `reported`フィールドと `desired`フィールド`green`の両方で に更新された値を反映し、バージョン番号は 1 ずつ増加します。例えば、以前のバージョン番号が 10 と表示されていた場合、現在のバージョン番号は 11 と表示されます。

**注記**  
シャドウを削除しても、バージョン番号は 0 にリセットされません。更新リクエストを発行するか、同じ名前で別のシャドウを作成すると、シャドウバージョンが 1 ずつ増加することがわかります。

**Shadow ドキュメントを編集してデルタイベントを観察する**  
`shadow.py` サンプルアプリケーションも `delta` イベントにサブスクライブしており、`desired` 値が変更されると応答します。例えば、`desired` 値を色 `red` に変更できます。これを行うには、 AWS IoT コンソールで、**編集**をクリックして Shadow ドキュメントを編集し、`desired`値を に設定しながら JSON `red`で`reported`値を に設定します`green`。変更を保存する際には Raspberry Pi のターミナルを開いたままにしておきます。変更が発生するとターミナルにメッセージが表示されます。

```
{
"desired": {
  "welcome": "aws-iot",
  "color": "red"
},
"reported": {
  "welcome": "aws-iot",
  "color": "green"
}
}
```

新しい値を保存すると、`shadow.py` サンプルアプリケーションはこの変更に応答し、デルタを示すメッセージをターミナルに表示します。`desired` 値を入力するためのプロンプトの下に、次のメッセージが表示されます。

```
Enter desired value:
Received shadow delta event.
Delta reports that desired value is 'red'. Changing local value...
Changed local shadow value to 'red'.
Updating reported shadow value to 'red'...
Finished updating reported shadow value to 'red'.
Enter desired value:
Update request published.
Finished updating reported shadow value to 'red'.
```

## ステップ 2: MQTT テストクライアントで `shadow.py` サンプルアプリケーションからのメッセージを表示する
<a name="shadow-sample-view-msg"></a>

**AWS IoT コンソール**で** MQTT テストクライアント**を使用して、 AWS アカウントで渡される MQTT メッセージをモニタリングできます。Device Shadow サービスで使用される予約済みの MQTT トピックにサブスクライブすることで、サンプルアプリケーションの実行時にトピックが受信するメッセージを観察できます。

MQTT テストクライアントをまだ使用していない場合は、[MQTT クライアントで AWS IoT MQTT メッセージを表示する](view-mqtt-messages.md) を確認できます。これは、**AWS IoT コンソール**で **MQTT テストクライアント**を使用して、メッセージブローカーを通過する MQTT メッセージを表示する方法を学ぶのに役立ちます。

1. 

**MQTT テストクライアントを開く**

   [AWS IoT コンソールの新しいウィンドウで MQTT テストクライアント](https://console.aws.amazon.com//iot/home#/test)を開きます。これにより、MQTT テストクライアントの設定を失うことなく、MQTT トピックによって受信されたメッセージを観察できます。MQTT テストクライアントからコンソールの別のページに移動すると、サブスクリプションまたはメッセージログは保持されません。チュートリアルのこのセクションでは、 AWS IoT モノの Shadow ドキュメントと MQTT テストクライアントを別々のウィンドウで開いて、Device Shadows とのやり取りをより簡単に観察できます。

1. 

**MQTT 予約済み Shadow トピックをサブスクライブする**

   MQTT テストクライアントを使用して、Device Shadow の MQTT 予約済みトピックの名前を入力し、サブスクライブして、`shadow.py` サンプルアプリケーションの実行時に更新を受け取ることができます。トピックにサブスクライブするには:

   1. **AWS IoT コンソール**の **MQTT テストクライアント**で、[**Subscribe to a topic**] (トピックへサブスクライブする) を選択します。

   1.  [**Topic filter**] (トピックフィルター) のセクションで、**\$1aws/things/*thingname*/shadow/update/\$1** と入力します。ここで、`thingname` は以前に作成したモノのリソースの名前です (例: `My_light_bulb`)。

   1. 追加の構成設定はデフォルト値のままにして、**[サブスクライブ]** を選択します。

   トピックサブスクリプションで **\$1** ワイルドカードを使用すると、複数の MQTT トピックを同時にサブスクライブし、デバイスとその Shadow の間で交換されるすべてのメッセージを単一のウィンドウで観察できます。ワイルドカード文字とその使用の詳細については、「[MQTT トピック](topics.md)」を参照してください。

1. 

**`shadow.py` サンプルプログラムを実行してメッセージを観察する**

   Raspberry Pi のコマンドラインウィンドウで、プログラムを切断した場合は、サンプルアプリケーションを再度実行し、**AWS IoT コンソール**の **MQTT テストクライアント**のメッセージを確認します。

   1. 次のコマンドを実行して、サンプルプログラムを再起動します。*your-iot-thing-name* と *your-iot-endpoint* を、以前に作成した AWS IoT モノの名前 ( など`My_light_bulb`) と、デバイスを操作するエンドポイントに置き換えます。

      ```
      cd ~/aws-iot-device-sdk-python-v2/samples/service-clients
      python3 shadow.py --ca_file ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint your-iot-endpoint --thing_name your-iot-thing-name
      ```

      その後、`shadow.py` サンプルアプリケーションが実行され、現在のシャドウ状態が取得されます。シャドウを削除したか、現在の状態をクリアした場合、プログラムは現在の値を `off` に設定し、`desired` 値を入力するように求めます。

      ```
      Connecting to a3qEXAMPLEffp-ats.iot.us-west-2.amazonaws.com with client ID 'test-0c8ae2ff-cc87-49d2-a82a-ae7ba1d0ca5a'...
      Connected!
      Subscribing to Delta events...
      Subscribing to Update responses...
      Subscribing to Get responses...
      Requesting current shadow state...
      Launching thread to read user input...
      Finished getting initial shadow state.
      Shadow document lacks 'color' property. Setting defaults...
      Changed local shadow value to 'off'.
      Updating reported shadow value to 'off'...
      Update request published.
      Finished updating reported shadow value to 'off'...
      Enter desired value:
      ```

      一方、プログラムが実行されていて、それを再起動した場合、ターミナルで最新の色の値が報告されるのを確認できます。MQTT テストクライアントでは、トピック **\$1aws/things/*thingname*/shadow/get** および **\$1aws/things/*thingname*/shadow/get/accepted** の更新が表示されます。

      報告された最新の色が `green` であるとします。以下は、**\$1aws/things/*thingname*/shadow/get/accepted** JSON ファイルの内容を示しています。

      ```
      {
      "state": {
        "desired": {
          "welcome": "aws-iot",
          "color": "green"
        },
        "reported": {
          "welcome": "aws-iot",
          "color": "green"
        }
      },
      "metadata": {
        "desired": {
          "welcome": {
            "timestamp": 1620156892
          },
          "color": {
            "timestamp": 1620161643
          }
        },
        "reported": {
          "welcome": {
            "timestamp": 1620156892
          },
          "color": {
            "timestamp": 1620161643
          }
        }
      },
      "version": 10,
      "timestamp": 1620173908
      }
      ```

   1. `yellow` など、ターミナルに `desired` 値を入力します。`shadow.py` サンプルアプリケーションは応答し、`reported` 値の `yellow` への変更を示す次のメッセージをターミナルに表示します。

      ```
      Enter desired value:
      yellow
      Changed local shadow value to 'yellow'.
      Updating reported shadow value to 'yellow'...
      Update request published.
      Finished updating reported shadow value to 'yellow'.
      ```

      **AWS IoT コンソール**の **[MQTT テストクライアント]** の **[サブスクリプション]** で、次のトピックがメッセージを受信したことがわかります。
      + **\$1aws/things/*thingname*/shadow/update**: `desired` と `updated` 値の両方が色 `yellow` に変化することを示しています。
      + **\$1aws/things/*thingname*/shadow/update/accepted**: `desired` および `reported` 状態の現在の値、およびそれらのメタデータとバージョン情報を表示します。
      + **\$1aws/things/*thingname*/shadow/update/documents**: `desired` および `reported` 状態の以前の値と現在の値、およびそれらのメタデータとバージョン情報を表示します。

      ドキュメント **\$1aws/things/*thingname*/shadow/update/documents** にも他の 2 つのトピックに含まれる情報が含まれているため、これで状態情報を確認できます。以前の状態は、`green` に設定された報告された値、そのメタデータとバージョン情報、および `yellow` に更新された、報告された値を示す現在の状態を示しています。

      ```
      {
      "previous": {
        "state": {
          "desired": {
            "welcome": "aws-iot",
            "color": "green"
          },
          "reported": {
            "welcome": "aws-iot",
            "color": "green"
          }
        },
        "metadata": {
          "desired": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297898
            }
          },
          "reported": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297898
            }
          }
        },
        "version": 10
      },
      "current": {
        "state": {
          "desired": {
            "welcome": "aws-iot",
            "color": "yellow"
          },
          "reported": {
            "welcome": "aws-iot",
            "color": "yellow"
          }
        },
        "metadata": {
          "desired": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297904
            }
          },
          "reported": {
            "welcome": {
              "timestamp": 1617297888
            },
            "color": {
              "timestamp": 1617297904
            }
          }
        },
        "version": 11
      },
      "timestamp": 1617297904
      }
      ```

   1. ここで、別の `desired` 値を入力すると、`reported` 値のさらなる変更と、これらのトピックで受信したメッセージの更新が表示されます。バージョン番号も 1 ずつ増分します。例えば、値 `green` を入力すると、以前の状態が値 `yellow` を報告し、現在の状態が値 `green` を報告します。

1. 

**Shadow ドキュメントを編集してデルタイベントを観察する**

   デルタトピックへの変更を観察するには、 AWS IoT コンソールで Shadow ドキュメントを編集します。例えば、`desired` 値を色 `red` に変更できます。これを行うには、 AWS IoT コンソールで**編集**を選択し、`desired`値を に設定したまま JSON で`reported`値を赤に設定します`green`。変更を保存する際はターミナルを開いたままにしておいてください。ターミナルに報告されたデルタメッセージが表示されます。

   ```
   {
   "desired": {
     "welcome": "aws-iot",
     "color": "red"
   },
   "reported": {
     "welcome": "aws-iot",
     "color": "green"
   }
   }
   ```

   `shadow.py` サンプルアプリケーションはこの変更に応答し、デルタを示すメッセージをターミナルに表示します。MQTT テストクライアントでは、`update` トピックは、`desired` および `reported` 値の変更を示すメッセージを受け取ります。

   また、トピック **\$1aws/things/*thingname*/shadow/update/delta** がメッセージを受信したこともわかります。メッセージを表示するには、**[サブスクリプション]** の下にリストされているこのトピックを選択します。

   ```
   {
   "version": 13,
   "timestamp": 1617318480,
   "state": {
     "color": "red"
   },
   "metadata": {
     "color": {
       "timestamp": 1617318480
     }
   }
   }
   ```

## ステップ 3: Device Shadow インタラクションに関するエラーをトラブルシューティングする
<a name="shadow-observe-messages-troubleshoot"></a>

Shadow サンプルアプリケーションを実行すると、Device Shadow サービスとのインタラクションの観察に関する問題が発生する場合があります。

プログラムが正常に実行され、`desired` 値を入力するように求められた場合は、前述のように Shadow ドキュメントと MQTT テストクライアントを使用して、Device Shadow のインタラクションを観察できるはずです。ただし、インタラクションが表示されない場合は、次のことを確認できます。
+ 

**AWS IoT コンソールでモノの名前とそのシャドウを確認する**  
Shadow ドキュメントにメッセージが表示されない場合は、コマンドを確認して、**AWS IoT コンソール**のモノの名前と一致していることを確認してください。モノのリソースを選択してから [**Shadows**] (シャドウ) を選択することで、クラシックシャドウがあるかどうかを確認することもできます。このチュートリアルは、主にクラシックシャドウとのインタラクションに焦点を当てています。

   使用したデバイスがインターネットに接続されていることも確認できます。**AWS IoT コンソール**で、以前に作成したモノを選択してから、[**Interact**] (操作) を選択します。モノの詳細ページに、次を記載したメッセージが表示されます: `This thing already appears to be connected.`。
+ 

**サブスクライブした MQTT 予約済みトピックを確認する**  
メッセージが MQTT テストクライアントに表示されない場合は、サブスクライブしたトピックの形式が正しいかどうかを確認してください。MQTT デバイスシャドウトピックの形式は **\$1aws/things/*thingname*/shadow/** であり、シャドウで実行するアクションに応じて、`update`、`get`、または `delete` がそれに続く場合があります。このチュートリアルでは、トピック **\$1aws/things/*thingname*/shadow/\$1** を使用しているため、テストクライアントの [**Topic filter**] (トピックフィルター) セクションでトピックをサブスクライブするときに、正しく入力したことを確認してください。

  トピック名を入力するときは、*モノの名前*が前に作成した AWS IoT モノの名前と同じであることを確認します。追加の MQTT トピックにサブスクライブして、更新が正常に実行されたかどうかを確認することもできます。例えば、接続の問題をデバッグできるように、トピック **\$1aws/things/*thingname*/shadow/update/rejected** にサブスクライブして、更新リクエストが失敗したときにメッセージを受信します。予約されているトピックの詳細については、[シャドウトピック](reserved-topics.md#reserved-topics-shadow) および [Device Shadow MQTT トピック](device-shadow-mqtt.md) を参照してください。

## ステップ 4: 結果と次のステップを確認する
<a name="sample-shadow-review"></a>

**このチュートリアルで学習した内容は次のとおりです。**
+ `shadow.py` サンプルアプリケーションを使用して、必要な状態を指定し、シャドウの現在の状態を更新します。
+ Shadow ドキュメントを編集して、デルタイベントと、`shadow.py` サンプルアプリケーションがそれにどのように応答するかを観察します。
+ MQTT テストクライアントを使用して、シャドウトピックをサブスクライブし、サンプルプログラムを実行するときに更新を確認します。

**次のステップ**  
追加の MQTT 予約トピックにサブスクライブして、シャドウアプリケーションの更新を監視できます。例えば、トピック **\$1aws/things/*thingname*/shadow/update/accepted** のみをサブスクライブする場合、更新が正常に実行されると、現在の状態情報のみが表示されます。

追加のシャドウトピックにサブスクライブして、問題をデバッグしたり、Device Shadow のインタラクションの詳細を確認したり、Device Shadow のインタラクションに関する問題をデバッグしたりすることもできます。詳細については、「[シャドウトピック](reserved-topics.md#reserved-topics-shadow)」および「[Device Shadow MQTT トピック](device-shadow-mqtt.md)」を参照してください。

名前付きシャドウを使用するか、LED 用に Raspberry Pi に接続された追加のハードウェアを使用してアプリケーションを拡張し、ターミナルから送信されたメッセージを使用して状態の変化を観察することもできます。

Device Shadow サービス、デバイスでのサービスの使用、アプリケーションの使用、およびサービスの使用の詳細については、[AWS IoT Device Shadow サービス](iot-device-shadows.md)、[デバイスでのシャドウの使用](device-shadow-comms-device.md)、および [アプリとサービスでのシャドウの使用](device-shadow-comms-app.md) を参照してください。

# チュートリアル: のカスタムオーソライザーの作成 AWS IoT Core
<a name="custom-auth-tutorial"></a>

このチュートリアルでは、 AWS CLIを使用してカスタム認証を作成、検証、使用する手順を示します。オプションで、このチュートリアルを使用して、HTTP Publish API を使用して AWS IoT Core にデータを送信するために Postman を使用できます。

このチュートリアルでは、トークン署名が有効な **create-authorizer** 呼び出しを使用して、認可および認証ロジックとカスタムオーソライザーを実装するサンプル Lambda 関数を作成する方法を示します。その後、オーソライザーは を使用して検証され**test-invoke-authorizer**、最後に HTTP Publish API AWS IoT Core を使用してテスト MQTT トピックにデータを送信できます。サンプルリクエストでは、`x-amz-customauthorizer-name` ヘッダーを使用して呼び出すオーソライザーを指定し、トークンキー名と `x-amz-customauthorizer-signature` をリクエストヘッダーで渡します。

**このチュートリアルでは、次の内容を学習します。**
+ カスタムオーソライザーハンドラーとなる Lambda 関数を作成する方法
+ トークン署名を有効に AWS CLI して を使用してカスタムオーソライザーを作成する方法
+ **test-invoke-authorizer** コマンドを使用してカスタムオーソライザーをテストする方法
+ [Postman](https://www.postman.com/) を使用して MQTT トピックを発行し、カスタムオーソライザーでリクエストを検証する方法

このチュートリアルの完了には 60 分ほどかかります。

**Topics**
+ [ステップ 1: カスタムオーソライザー用の Lambda 関数を作成する](#custom-auth-tutorial-define)
+ [ステップ 2: カスタムオーソライザーのパブリックキーとプライベートキーのペアを作成する](#custom-auth-tutorial-keys)
+ [ステップ 3: カスタムオーソライザーリソースとその承認を作成する](#custom-auth-tutorial-authorizer)
+ [ステップ 4: test-invoke-authorizer を呼び出してオーソライザーをテストする](#custom-auth-tutorial-test)
+ [ステップ 5: Postman を使用して MQTT メッセージの発行をテストする](#custom-auth-tutorial-postman)
+ [ステップ 6: MQTT テストクライアントでメッセージを表示する](#custom-auth-tutorial-testclient)
+ [ステップ 7: 結果と次のステップを確認する](#custom-auth-tutorial-review)
+ [ステップ 8: クリーンアップする](#custom-auth-tutorial-cleanup)

**このチュートリアルを開始する前に、以下の要件を満たしていることを確認してください。**
+ 

**[セットアップ AWS アカウント](setting-up.md)**  
このチュートリアルを完了するには、 AWS アカウント と AWS IoT コンソールが必要です。

  このチュートリアルで使用するアカウントは、少なくとも次の AWS マネージドポリシーが含まれている場合に最適に機能します。
  + [https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/IAMFullAccess$jsonEditor](https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/IAMFullAccess$jsonEditor)
  + [https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTFullAccess$jsonEditor](https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSIoTFullAccess$jsonEditor)
  + [https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSLambda_FullAccess$jsonEditor](https://console.aws.amazon.com//iam/home#/policies/arn:aws:iam::aws:policy/AWSLambda_FullAccess$jsonEditor)
**重要**  
このチュートリアルで使用される IAM ポリシーは、本稼働環境で従うべきものよりも許容度が高いです。本稼働環境で、アカウントポリシーとリソースポリシーが必要なアクセス許可のみを付与していることを確認します。  
本稼働用の IAM ポリシーを作成する場合は、ユーザーとロールに必要なアクセスを判断し、次にそれらのタスクのみの実行を許可するポリシーを設計します。  
詳細については、[IAM のセキュリティのベストプラクティス](https://docs.aws.amazon.com//IAM/latest/UserGuide/best-practices.html)を参照してください。
+ 

**をインストールしました AWS CLI**  
をインストールする方法については AWS CLI、「 [AWS CLI のインストール](https://docs.aws.amazon.com//cli/latest/userguide/cli-chap-install.html)」を参照してください。このチュートリアルには AWS CLI バージョン `aws-cli/2.1.3 Python/3.7.4 Darwin/18.7.0 exe/x86_64` 以降が必要です。
+ 

**OpenSSL ツール**  
このチュートリアルの例では、[LibreSSL 2.6.5](https://www.libressl.org/) を使用しています。このチュートリアルでは、[OpenSSL v1.1.1i](https://www.openssl.org/) ツールを使用することもできます。
+ 

**「[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html) の概要」を確認します。**  
 AWS Lambda を初めて使用する場合は、[AWS Lambda](https://docs.aws.amazon.com//lambda/latest/dg/welcome.html)「」と[「Lambda の開始方法](https://docs.aws.amazon.com//lambda/latest/dg/getting-started.html)」を確認して、その用語と概念を確認してください。
+ 

**Postman でリクエストを作成する方法を見直しました**  
詳細については、「[リクエストのビルド](https://learning.postman.com/docs/sending-requests/requests/)」を参照してください。
+ 

**以前のチュートリアルからカスタムオーソライザーを削除しました**  
では、一度に設定 AWS アカウント できるカスタムオーソライザーの数は限られています。カスタムオーソライザーの削除方法の詳細については、[ステップ 8: クリーンアップする](#custom-auth-tutorial-cleanup) を参照してください。

## ステップ 1: カスタムオーソライザー用の Lambda 関数を作成する
<a name="custom-auth-tutorial-define"></a>

のカスタム認証 AWS IoT Core では、作成した[オーソライザーリソース](https://docs.aws.amazon.com//iot/latest/apireference/API_AuthorizerDescription.html)を使用してクライアントを認証および認可します。このセクションで作成する 関数は、クライアントが AWS IoT リソースに接続してアクセスするときに、クライアントを認証 AWS IoT Core および認可します。

Lambda 関数は以下を実行します。
+ リクエストが **test-invoke-authorizer** からのものである場合、`Deny` アクションを含む IAM ポリシーを返します。
+ リクエストが HTTP を使用して Postman から送信され、`actionToken` パラメータの値が `allow` の場合、`Allow` アクションを使用して IAM ポリシーを返します。それ以外の場合は、`Deny` アクションを含む IAM ポリシーを返します。

**カスタムオーソライザー用の Lambda 関数を作成するには**

1. [Lambda](https://console.aws.amazon.com//lambda/home#) コンソールで、[[関数]](https://console.aws.amazon.com//lambda/home#/functions) を開きます。

1. [**Create function**] を選択します。

1. **[一から作成]** が選択されていることを確認します。

1. [**Basic information**]:

   1. [**関数名**] に **custom-auth-function** と入力します。

   1. **[ランタイム]** で、**[Node.js 18.x]** を確認します 

1. [**Create function**] を選択します。

   Lambda により、Node.js の関数と[実行ロール](https://docs.aws.amazon.com//lambda/latest/dg/lambda-intro-execution-role.html)が作成され、ログをアップロードするためのアクセス許可が関数に付与されます。Lambda 関数は、関数を呼び出すときに実行ロールを引き受け、実行ロールを使用して AWS SDK の認証情報を作成し、イベントソースからデータを読み込みます。

1. [AWS Cloud9](https://docs.aws.amazon.com/cloud9/latest/user-guide/welcome.html) エディタで関数のコードと設定を表示するには、デザイナーウィンドウで **[custom-auth-function]** を選択し、エディタのナビゲーションペインで **[index.js]** を選択します。

   Node.js などのスクリプト言語では、Lambda には成功のレスポンスを返す基本関数が含まれています。ソースコードが 3 MB を超えない限り、[AWS Cloud9](https://docs.aws.amazon.com/cloud9/latest/user-guide/welcome.html) エディタを使用して関数を編集できます。

1. エディタの **index.js** コードを次のコードに置き換えます。

   ```
   // A simple Lambda function for an authorizer. It demonstrates
   // How to parse a CLI and Http password to generate a response.
   
   export const handler = async (event, context, callback) => {
   
       //Http parameter to initiate allow/deny request
       const HTTP_PARAM_NAME='actionToken';
       const ALLOW_ACTION = 'Allow';
       const DENY_ACTION = 'Deny';
   
       //Event data passed to Lambda function
       var event_str = JSON.stringify(event);
       console.log('Complete event :'+ event_str);
   
       //Read protocolData from the event json passed to Lambda function
       var protocolData = event.protocolData;
       console.log('protocolData value---> ' + protocolData);
   
       //Get the dynamic account ID from function's ARN to be used
       // as full resource for IAM policy
       var ACCOUNT_ID = context.invokedFunctionArn.split(":")[4];
       console.log("ACCOUNT_ID---"+ACCOUNT_ID);
   
       //Get the dynamic region from function's ARN to be used
       // as full resource for IAM policy
       var REGION = context.invokedFunctionArn.split(":")[3];
       console.log("REGION---"+REGION);
   
       //protocolData data will be undefined if testing is done via CLI.
       // This will help to test the set up.
       if (protocolData === undefined) {
   
           //If CLI testing, pass deny action as this is for testing purpose only.
           console.log('Using the test-invoke-authorizer cli for testing only');
           callback(null, generateAuthResponse(DENY_ACTION,ACCOUNT_ID,REGION));
   
       } else{
   
           //Http Testing from Postman
           //Get the query string from the request
           var queryString = event.protocolData.http.queryString;
           console.log('queryString values -- ' + queryString);
           /*         global URLSearchParams       */
           const params = new URLSearchParams(queryString);
           var action = params.get(HTTP_PARAM_NAME);
   
           if(action!=null && action.toLowerCase() === 'allow'){
   
               callback(null, generateAuthResponse(ALLOW_ACTION,ACCOUNT_ID,REGION));
   
           }else{
   
               callback(null, generateAuthResponse(DENY_ACTION,ACCOUNT_ID,REGION));
   
           }
   
       }
   
   };
   
   // Helper function to generate the authorization IAM response.
   var generateAuthResponse = function(effect,ACCOUNT_ID,REGION) {
   
       var full_resource = "arn:aws:iot:"+ REGION + ":" + ACCOUNT_ID + ":*";
       console.log("full_resource---"+full_resource);
   
       var authResponse = {};
       authResponse.isAuthenticated = true;
       authResponse.principalId = 'principalId';
   
       var policyDocument = {};
       policyDocument.Version = '2012-10-17';		 	 	 
       policyDocument.Statement = [];
       var statement = {};
       statement.Action = 'iot:*';
       statement.Effect = effect;
       statement.Resource = full_resource;
       policyDocument.Statement[0] = statement;
       authResponse.policyDocuments = [policyDocument];
       authResponse.disconnectAfterInSeconds = 3600;
       authResponse.refreshAfterInSeconds = 600;
   
       console.log('custom auth policy function called from http');
       console.log('authResponse --> ' + JSON.stringify(authResponse));
       console.log(authResponse.policyDocuments[0]);
   
       return authResponse;
   }
   ```

1. [**デプロイ**] を選択します。

1. **[変更がデプロイされました]** がエディタの上に表示されたら、次の操作を実行します。

   1. エディタの上にある **[関数の概要]** セクションまでスクロールします。

   1. このチュートリアルの後半で使用するために、**[関数 ARN]** をコピーして保存します。

1.  関数をテストします。

   1. **[テスト]** タブを選択します。

   1. デフォルトのテスト設定を使用して、**[呼び出し]** を選択します。

   1. テストが成功した場合は、**[実行結果]** で **[詳細]** ビューを開きます。関数が返したポリシードキュメントが表示されます。

      テストが失敗した場合、またはポリシードキュメントが表示されない場合は、コードを確認し、エラーを見つけて修正します。

## ステップ 2: カスタムオーソライザーのパブリックキーとプライベートキーのペアを作成する
<a name="custom-auth-tutorial-keys"></a>

カスタムオーソライザーでは、認証にパブリックキーとプライベートキーが必要です。このセクションのコマンドは、OpenSSL ツールを使用してこのキーペアを作成します。

**カスタムオーソライザーのパブリックキーとプライベートキーのペアを作成するには**

1. プライベートキーファイルを作成します。

   ```
   openssl genrsa -out private-key.pem 4096
   ```

1. 先ほど作成したプライベートキーファイルを検証します。

   ```
   openssl rsa -check -in private-key.pem -noout
   ```

   コマンドがエラーを表示しない場合、プライベートキーファイルは有効です。

1. パブリックキーファイルを作成します。

   ```
   openssl rsa -in private-key.pem -pubout -out public-key.pem
   ```

1. パブリックキーファイルを確認します。

   ```
   openssl pkey -inform PEM -pubin -in public-key.pem -noout
   ```

   コマンドがエラーを表示しない場合、パブリックキーファイルは有効です。

## ステップ 3: カスタムオーソライザーリソースとその承認を作成する
<a name="custom-auth-tutorial-authorizer"></a>

 AWS IoT カスタムオーソライザーは、前のステップで作成したすべての要素を結び付けるリソースです。このセクションでは、カスタムオーソライザーリソースを作成し、以前に作成した Lambda 関数を実行するためのアクセス許可を付与します。 AWS IoT コンソール、、または AWS API を使用して AWS CLI、カスタムオーソライザーリソースを作成できます。

このチュートリアルでは、1 つのカスタムオーソライザーを作成するだけで済みます。このセクションでは、 AWS IoT コンソールと を使用して を作成する方法について説明します。これにより AWS CLI、最も便利な メソッドを使用できます。どちらの方法でも作成されたカスタムオーソライザーリソースには違いはありません。

### カスタムオーソライザーリソースを作成する
<a name="custom-auth-tutorial-authorizer-resource"></a>

**オプションを選択してカスタムオーソライザーリソースを作成する**
+ [AWS IoT コンソールを使用してカスタムオーソライザーを作成する](#create-custom-auth-in-console)
+ [を使用してカスタムオーソライザーを作成する AWS CLI](#create-custom-auth-in-cli)

**カスタムオーソライザーを作成するには (コンソール)**

1. [AWS IoT コンソールのカスタムオーソライザーページ](https://console.aws.amazon.com//iot/home#/authorizerhub)を開き、**オーソライザーの作成**を選択します。

1. **[オーソライザーの作成]** で、次のように操作します。

   1. **[オーソライザーの名前]** に、**my-new-authorizer** と入力します。

   1. **[オーソライザーのステータス]** で、**[アクティブ]** にチェックを入れます。

   1. **[オーソライザー関数]** で、前に作成した Lambda 関数を選択します。

   1. **[トークン検証 - オプション]** で次の操作を実行します。

      1. **[トークン検証]** をオンにします。

      1. **[トークンキー名]** に、**tokenKeyName** を入力します。

      1. **[キーの追加]** を選択します。

      1. **[キー名]** で **FirstKey** を入力します。

      1. **[パブリックキー]** で、`public-key.pem` ファイルの内容を入力します。`-----BEGIN PUBLIC KEY-----` と `-----END PUBLIC KEY-----` を含むファイルの行を必ず含め、ラインフィード、キャリッジリターン、またはその他の文字をファイルの内容に追加したり、ファイルの内容から削除したりしないでください。入力する文字列は、この例のように表示されます。

         ```
         -----BEGIN PUBLIC KEY-----
         MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvEBzOk4vhN+3LgslvEWt
         sLCqNmt5Damas3bmiTRvq2gjRJ6KXGTGQChqArAJwL1a9dkS9+maaXC3vc6xzx9z
         QPu/vQOe5tyzz1MsKdmtFGxMqQ3qjEXAMPLEOmqyUKPP5mff58k6ePSfXAnzBH0q
         lg2HioefrpU5OSAnpuRAjYKofKjbc2Vrn6N2G7hV+IfTBvCElf0csalS/Rk4phD5
         oa4Y0GHISRnevypg5C8n9Rrz91PWGqP6M/q5DNJJXjMyleG92hQgu1N696bn5Dw8
         FhedszFa6b2x6xrItZFzewNQkPMLMFhNrQIIyvshtT/F1LVCS5+v8AQ8UGGDfZmv
         QeqAMAF7WgagDMXcfgKSVU8yid2sIm56qsCLMvD2Sq8Lgzpey9N5ON1o1Cvldwvc
         KrJJtgwW6hVqRGuShnownLpgG86M6neZ5sRMbVNZO8OzcobLngJ0Ibw9KkcUdklW
         gvZ6HEJqBY2XE70iEXAMPLETPHzhqvK6Ei1HGxpHsXx6BNft582J1VpgYjXha8oa
         /NN7l7Zbj/euAb41IVtmX8JrD9z613d1iM5L8HluJlUzn62Q+VeNV2tdA7MfPfMC
         8btGYladFAnitThaz6+F0VSBJPu7pZQoLnqyEp5zLMtF+kFl2yOBmGAP0RBivRd9
         JWBUCG0bqcLQPeQyjbXSOfUCAwEAAQ==
         -----END PUBLIC KEY-----
         ```

1. **[オーソライザーの作成]** を選択します。

1. カスタムオーソライザーリソースが作成された場合は、カスタムオーソライザーのリストが表示され、新しいカスタムオーソライザーがそのリストに表示されます。これで、次のセクションに進んでテストできます。

   エラーが表示された場合は、エラーを確認し、カスタムオーソライザーを再度作成して、エントリを再確認してください。各カスタムオーソライザーリソースには一意の名前が必要であることに注意してください。

**カスタムオーソライザーを作成するには (AWS CLI)**

1. `authorizer-function-arn` と `token-signing-public-keys` の値を置き換えてから、次のコマンドを実行します。

   ```
   aws iot create-authorizer \
   --authorizer-name "my-new-authorizer" \
   --token-key-name "tokenKeyName" \
   --status ACTIVE \
   --no-signing-disabled \
   --authorizer-function-arn "arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function" \
   --token-signing-public-keys FirstKey="-----BEGIN PUBLIC KEY-----
   MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvEBzOk4vhN+3LgslvEWt
   sLCqNmt5Damas3bmiTRvq2gjRJ6KXGTGQChqArAJwL1a9dkS9+maaXC3vc6xzx9z
   QPu/vQOe5tyzz1MsKdmtFGxMqQ3qjEXAMPLEOmqyUKPP5mff58k6ePSfXAnzBH0q
   lg2HioefrpU5OSAnpuRAjYKofKjbc2Vrn6N2G7hV+IfTBvCElf0csalS/Rk4phD5
   oa4Y0GHISRnevypg5C8n9Rrz91PWGqP6M/q5DNJJXjMyleG92hQgu1N696bn5Dw8
   FhedszFa6b2x6xrItZFzewNQkPMLMFhNrQIIyvshtT/F1LVCS5+v8AQ8UGGDfZmv
   QeqAMAF7WgagDMXcfgKSVU8yid2sIm56qsCLMvD2Sq8Lgzpey9N5ON1o1Cvldwvc
   KrJJtgwW6hVqRGuShnownLpgG86M6neZ5sRMbVNZO8OzcobLngJ0Ibw9KkcUdklW
   gvZ6HEJqBY2XE70iEXAMPLETPHzhqvK6Ei1HGxpHsXx6BNft582J1VpgYjXha8oa
   /NN7l7Zbj/euAb41IVtmX8JrD9z613d1iM5L8HluJlUzn62Q+VeNV2tdA7MfPfMC
   8btGYladFAnitThaz6+F0VSBJPu7pZQoLnqyEp5zLMtF+kFl2yOBmGAP0RBivRd9
   JWBUCG0bqcLQPeQyjbXSOfUCAwEAAQ==
   -----END PUBLIC KEY-----"
   ```

**各パラメータの意味は次のとおりです。**
   + `authorizer-function-arn` 値は、カスタムオーソライザー用に作成した Lambda 関数の Amazon リソースネーム (ARN) です。
   + `token-signing-public-keys` 値には、キーの名前、**FirstKey**、および `public-key.pem` ファイルの内容が含まれます。`-----BEGIN PUBLIC KEY-----` と `-----END PUBLIC KEY-----` を含むファイルの行を必ず含め、ラインフィード、キャリッジリターン、またはその他の文字をファイルの内容に追加したり、ファイルの内容から削除したりしないでください。

     注: パブリックキーの値を変更すると使用できなくなるため、パブリックキーの入力には注意してください。

1. カスタムオーソライザーが作成されている場合、コマンドは次のような新しいリソースの名前と ARN を返します。

   ```
   {
       "authorizerName": "my-new-authorizer",
       "authorizerArn": "arn:aws:iot:Region:57EXAMPLE833:authorizer/my-new-authorizer"
   }
   ```

   次のステップで使用するために `authorizerArn` 値を保存します。

   各カスタムオーソライザーリソースには一意の名前が必要であることに注意してください。

### カスタムオーソライザーリソースを承認する
<a name="custom-auth-tutorial-authorizer-permission"></a>

このセクションでは、作成したカスタムオーソライザーリソースに、Lambda 関数を実行するためのアクセス許可を付与します。アクセス許可を付与するには、[add-permission](https://docs.aws.amazon.com//cli/latest/reference/lambda/add-permission.html) CLI コマンドを使用できます。

**を使用して Lambda 関数にアクセス許可を付与する AWS CLI**

1. 値を挿入したら、次のコマンドを入力します。`statement-id` 値は一意でなければならないことに注意してください。このチュートリアルを以前に実行したことがある場合、または `ResourceConflictException` エラーが発生した場合は、`Id-1234` を別の値に置き換えてください。

   ```
   aws lambda add-permission  \
   --function-name "custom-auth-function" \
   --principal "iot.amazonaws.com" \
   --action "lambda:InvokeFunction" \
   --statement-id "Id-1234" \
   --source-arn authorizerArn
   ```

1. コマンドが成功すると、この例のようなアクセス許可ステートメントが返されます。次のセクションに進んで、カスタムオーソライザーをテストできます。

   ```
   {
       "Statement": "{\"Sid\":\"Id-1234\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"iot.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function\"}}}"
   }
   ```

   コマンドが成功しない場合は、この例のようなエラーが返されます。続行する前に、エラーを確認して修正する必要があります。

   ```
   An error occurred (AccessDeniedException) when calling the AddPermission operation: User: arn:aws:iam::57EXAMPLE833:user/EXAMPLE-1 is not authorized to perform: lambda:AddPer
   mission on resource: arn:aws:lambda:Region:57EXAMPLE833:function:custom-auth-function
   ```

## ステップ 4: test-invoke-authorizer を呼び出してオーソライザーをテストする
<a name="custom-auth-tutorial-test"></a>

すべてのリソースを定義したら、このセクションでは、コマンドラインから test-invoke-authorizer を呼び出して、認可パスをテストします。

コマンドラインからオーソライザーを呼び出す場合、`protocolData` は定義されていないため、オーソライザーは常に DENY ドキュメントを返すことに注意してください。ただし、このテストは、Lambda 関数を完全にテストしなくても、カスタムオーソライザーと Lambda 関数が正しく設定されていることを確認します。

**を使用してカスタムオーソライザーとその Lambda 関数をテストするには AWS CLI**

1. 前の手順で作成した `private-key.pem` ファイルがあるディレクトリで、次のコマンドを実行します。

   ```
   echo -n "tokenKeyValue" | openssl dgst -sha256 -sign private-key.pem | openssl base64 -A
   ```

   このコマンドは、次のステップで使用する署名文字列を作成します。署名文字列は次のようになります。

   ```
   dBwykzlb+fo+JmSGdwoGr8dyC2qB/IyLefJJr+rbCvmu9Jl4KHAA9DG+V+MMWu09YSA86+64Y3Gt4tOykpZqn9mn
   VB1wyxp+0bDZh8hmqUAUH3fwi3fPjBvCa4cwNuLQNqBZzbCvsluv7i2IMjEg+CPY0zrWt1jr9BikgGPDxWkjaeeh
   bQHHTo357TegKs9pP30Uf4TrxypNmFswA5k7QIc01n4bIyRTm90OyZ94R4bdJsHNig1JePgnuOBvMGCEFE09jGjj
   szEHfgAUAQIWXiVGQj16BU1xKpTGSiTAwheLKUjITOEXAMPLECK3aHKYKY+d1vTvdthKtYHBq8MjhzJ0kggbt29V
   QJCb8RilN/P5+vcVniSXWPplyB5jkYs9UvG08REoy64AtizfUhvSul/r/F3VV8ITtQp3aXiUtcspACi6ca+tsDuX
   f3LzCwQQF/YSUy02u5XkWn+sto6KCkpNlkD0wU8gl3+kOzxrthnQ8gEajd5Iylx230iqcXo3osjPha7JDyWM5o+K
   EWckTe91I1mokDr5sJ4JXixvnJTVSx1li49IalW4en1DAkc1a0s2U2UNm236EXAMPLELotyh7h+flFeloZlAWQFH
   xRlXsPqiVKS1ZIUClaZWprh/orDJplpiWfBgBIOgokJIDGP9gwhXIIk7zWrGmWpMK9o=
   ```

   この署名文字列をコピーして、次の手順で使用します。余分な文字を含めたり、省略したりしないように注意してください。

1. このコマンドで、`token-signature` 値を前のステップの署名文字列に置き換え、このコマンドを実行してオーソライザーをテストします。

   ```
   aws iot test-invoke-authorizer \
   --authorizer-name my-new-authorizer \
   --token tokenKeyValue \
   --token-signature dBwykzlb+fo+JmSGdwoGr8dyC2qB/IyLefJJr+rbCvmu9Jl4KHAA9DG+V+MMWu09YSA86+64Y3Gt4tOykpZqn9mnVB1wyxp+0bDZh8hmqUAUH3fwi3fPjBvCa4cwNuLQNqBZzbCvsluv7i2IMjEg+CPY0zrWt1jr9BikgGPDxWkjaeehbQHHTo357TegKs9pP30Uf4TrxypNmFswA5k7QIc01n4bIyRTm90OyZ94R4bdJsHNig1JePgnuOBvMGCEFE09jGjjszEHfgAUAQIWXiVGQj16BU1xKpTGSiTAwheLKUjITOEXAMPLECK3aHKYKY+d1vTvdthKtYHBq8MjhzJ0kggbt29VQJCb8RilN/P5+vcVniSXWPplyB5jkYs9UvG08REoy64AtizfUhvSul/r/F3VV8ITtQp3aXiUtcspACi6ca+tsDuXf3LzCwQQF/YSUy02u5XkWn+sto6KCkpNlkD0wU8gl3+kOzxrthnQ8gEajd5Iylx230iqcXo3osjPha7JDyWM5o+KEWckTe91I1mokDr5sJ4JXixvnJTVSx1li49IalW4en1DAkc1a0s2U2UNm236EXAMPLELotyh7h+flFeloZlAWQFHxRlXsPqiVKS1ZIUClaZWprh/orDJplpiWfBgBIOgokJIDGP9gwhXIIk7zWrGmWpMK9o=
   ```

   コマンドが成功すると、この例のように、カスタムオーソライザー関数によって生成された情報が返されます。

   ```
   {
       "isAuthenticated": true,
       "principalId": "principalId",
       "policyDocuments": [
           "{\"Version\":\"2012-10-17\",		 	 	 \"Statement\":[{\"Action\":\"iot:*\",\"Effect\":\"Deny\",\"Resource\":\"arn:aws:iot:Region:57EXAMPLE833:*\"}]}"
       ],
       "refreshAfterInSeconds": 600,
       "disconnectAfterInSeconds": 3600
   }
   ```

   コマンドからエラーが返された場合は、エラーを確認し、このセクションで使用したコマンドを再度確認します。

## ステップ 5: Postman を使用して MQTT メッセージの発行をテストする
<a name="custom-auth-tutorial-postman"></a>

1. コマンドラインからデバイスデータエンドポイントを取得するには、ここに示すように [describe-endpoint](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot/describe-endpoint.html) を呼び出します

   ```
   aws iot describe-endpoint --output text --endpoint-type iot:Data-ATS
   ```

   このアドレスを保存して、後のステップで *device\$1data\$1endpoint\$1address* として使用します。

1. 新しい Postman ウィンドウを開き、新しい HTTP POST リクエストを作成します。

   1. コンピュータで、Postman アプリケーションを開きます。

   1. Postman の **[ファイル]** メニューで、**[新規]** を選択します。

   1. **[New]** (新規) ダイアログボックスで、**[Request]** (リクエスト) を選択します。

   1. [Save] (保存) リクエストで、

      1. [**Request name**] (リクエスト名) で、**Custom authorizer test request** と入力します。

      1. **[保存先のコレクションまたはフォルダを選択:]** で、このリクエストを保存するコレクションを選択または作成します。

      1. **[*collection\$1name* に保存]** を選択します。

1. カスタムオーソライザーをテストするための POST リクエストを作成します。

   1. URL フィールドの横にあるリクエストメソッドセレクターで、**[POST]** を選択します。

   1. URL フィールドで、前のステップの *describe-endpoint* コマンドの [device\$1data\$1endpoint\$1address](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot/describe-endpoint.html) とともに次の URL を使用して、リクエスト用の URL を作成します。

      ```
      https://device_data_endpoint_address:443/topics/test/cust-auth/topic?qos=0&actionToken=allow
      ```

      この URL には、 AWS IoTへのアクセスを許可するポリシードキュメントを返すように Lambda 関数に指示する `actionToken=allow` クエリパラメータが含まれていることに注意してください。URL を入力すると、Postman の [**Params**] (パラメータ) タブにもクエリパラメータが表示されます。

   1. **[認証]** タブの **[タイプ]** フィールドで、**[認証なし]** を選択します。

   1. [Headers] (ヘッダー) タブで次の操作を行います。

      1. チェックが入っている **[ホスト]** キーがある場合は、このチェックを解除します。

      1. ヘッダーのリストの一番下に、これらの新しいヘッダーを追加し、チェックが入っていることを確認します。**Host** 値を *device\$1data\$1endpoint\$1address* に置き換え、**x-amz-customauthorizer-signature** 値を前のセクションの **test-invoke-authorize** コマンドで使用した署名文字列に置き換えます。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/custom-auth-tutorial.html)

   1. [Body] (本文) タブで、次の操作を行います。

      1. データ形式オプションボックスで、**[Raw]** を選択します。

      1. データ型リストで、**[JavaScript]** を選択します。

      1. テキストフィールドで、テストメッセージ用の次の JSON メッセージペイロードを入力します。

         ```
         {
             "data_mode": "test",
             "vibration": 200,
             "temperature": 40
         }
         ```

1. **[送信]** を選択してリクエストを送信します。

   リクエストが成功した場合、次を返します。

   ```
   {
       "message": "OK",
       "traceId": "ff35c33f-409a-ea90-b06f-fbEXAMPLE25c"
   }
   ```

   正常なレスポンスは、カスタムオーソライザーが への接続を許可 AWS IoT し、テストメッセージが のブローカーに配信されたことを示します AWS IoT Core。

   エラーが返された場合は、エラーメッセージ、*device\$1data\$1endpoint\$1address*、署名文字列、およびその他のヘッダー値を確認してください。

次のセクションで使用するために、このリクエストを Postman で保持します。

## ステップ 6: MQTT テストクライアントでメッセージを表示する
<a name="custom-auth-tutorial-testclient"></a>

前のステップでは、Postman AWS IoT を使用してシミュレートされたデバイスメッセージを に送信しました。成功した応答は、カスタムオーソライザーが AWS IoT への接続を許可し、テストメッセージが AWS IoT Coreのブローカーに配信されたことを示しました。このセクションでは、 AWS IoT コンソールで MQTT テストクライアントを使用して、他のデバイスやサービスと同様に、そのメッセージからのメッセージの内容を確認します。

**カスタムオーソライザーによって承認されたテストメッセージを表示するには**

1.  AWS IoT コンソールで、[MQTT テストクライアント](https://console.aws.amazon.com//iot/home#/test)を開きます。

1. [**Subscribe to topic**] (トピックへのサブスクライブ) タブの [**Topic filter**] (トピックフィルター) で、前のセクションの Postman の例で使用されているメッセージトピックである **test/cust-auth/topic** を入力します。

1. [**Subscribe**] を選択します。

   次のステップのために、このウィンドウを表示したままにします。

1. Postman で、前のセクションで作成したリクエストで、**[送信]** を選択します。

   応答を確認して、正常に完了したことを確認します。そうでない場合は、前のセクションで説明したようにエラーをトラブルシューティングします。

1. **[MQTT テストクライアント]** に、メッセージトピックを示す新しいエントリが表示され、展開すると、Postman から送信したリクエストからのメッセージペイロードが表示されます。

   **[MQTT テストクライアント]** にメッセージが表示されない場合は、次の点を確認してください。
   + Postman リクエストが正常に返されたことを確認します。が接続 AWS IoT を拒否し、エラーを返した場合、リクエスト内のメッセージはメッセージブローカーに渡されません。
   +  AWS IoT コンソールを開く AWS リージョン ために使用される AWS アカウント と が、Postman URL で使用しているものと同じであることを確認します。
   + カスタムオーソライザーに適切なエンドポイントを使用していることを確認してください。デフォルトの IoT エンドポイントは、Lambda 関数でのカスタムオーソライザーの使用をサポートしていない場合があります。その場合は、ドメイン設定を使用して新しいエンドポイントを定義し、そのエンドポイントをカスタムオーソライザーに指定できます。
   + **MQTT テストクライアント**にトピックを正しく入力したことを確認してください。トピックフィルターでは、大文字と小文字が区別されます。疑わしい場合は、 **\$1**トピックにサブスクライブすることもできます。このトピックは、メッセージブローカーを通過するすべての MQTT メッセージにサブスクライブ AWS アカウント し、 コンソールを開く AWS リージョン AWS IoT ために使用されます。

## ステップ 7: 結果と次のステップを確認する
<a name="custom-auth-tutorial-review"></a>

**このチュートリアルでは、次の作業を行いました。**
+ Lambda 関数をカスタムオーソライザーハンドラーとして作成しました
+ トークン署名を有効にしてカスタムオーソライザーを作成しました
+ **test-invoke-authorizer** コマンドを使用してカスタムオーソライザーをテストしました
+ [Postman](https://www.postman.com/) を使用して MQTT トピックを発行し、カスタムオーソライザーでリクエストを検証しました
+ Postman テストから送信されたメッセージを表示するために **[MQTT テストクライアント]** を使用しました

**次の手順**  
Postman からメッセージを送信してカスタムオーソライザーが機能していることを確認したら、このチュートリアルのさまざまな側面を変更すると結果にどのように影響するかを実験してみてください。手始めにいくつか例を紹介します。
+ 署名文字列を変更して、不正な接続の試みがどのように処理されるかを確認できないようにします。このようなエラー応答が返され、メッセージは **MQTT テストクライアント**に表示されないはずです。

  ```
  {
      "message": "Forbidden",
      "traceId": "15969756-a4a4-917c-b47a-5433e25b1356"
  }
  ```
+  AWS IoT ルールの開発中および使用中に発生する可能性のあるエラーを見つける方法の詳細については、「」を参照してください[モニタリング AWS IoT](monitoring_overview.md)。

## ステップ 8: クリーンアップする
<a name="custom-auth-tutorial-cleanup"></a>

このチュートリアルを繰り返したい場合は、カスタムオーソライザーの一部を削除する必要があります。では、一度に設定 AWS アカウント できるカスタムオーソライザーの数は限られており、既存のカスタムオーソライザーを削除せずに新しいオーソライザーを追加`LimitExceededException`しようとすると、 を取得できます。

**カスタムオーソライザーを削除するには (コンソール)**

1. [AWS IoT コンソールのカスタムオーソライザーページ](https://console.aws.amazon.com//iot/home#/authorizerhub)を開き、カスタムオーソライザーのリストで、削除するカスタムオーソライザーを見つけます。

1. [Custom authorizer details] (カスタムオーソライザーの詳細) ページを開き、[**Actions**] (アクション) メニューから [**Edit**] (編集) を選択します。

1. **[オーソライザーアクティブ化]** のチェックを解除し、**[更新]** を選択します。

   アクティブなカスタムオーソライザーを削除することはできません。

1. [Custom authorizer details] (カスタムオーソライザーの詳細) ページで、[**Actions**] (アクション) メニューを開き、[**Delete**] (削除) を選択します。

**カスタムオーソライザーを削除するには (AWS CLI)**

1. インストールしたカスタムオーソライザーの一覧を表示し、削除するカスタムオーソライザーの名前を見つけます。

   ```
   aws iot list-authorizers 
   ```

1. `Custom_Auth_Name` を、削除するカスタムオーソライザーの `authorizerName` に置き換えた後、このコマンドを実行してカスタムオーソライザーを `inactive` に設定します。

   ```
   aws iot update-authorizer --status INACTIVE --authorizer-name Custom_Auth_Name
   ```

1. `Custom_Auth_Name` を、削除するカスタムオーソライザーの `authorizerName` に置き換えた後、このコマンドを実行してカスタムオーソライザーを削除します。

   ```
   aws iot delete-authorizer --authorizer-name Custom_Auth_Name
   ```

# チュートリアル: AWS IoT と Raspberry Pi を使用した土壌湿度のモニタリング
<a name="iot-moisture-tutorial"></a>

このチュートリアルでは、[Raspberry Pi](https://www.raspberrypi.org/)、湿度センサー、 AWS IoT および を使用して、家の植物または庭の土壌湿度レベルをモニタリングする方法を示します。Raspberry Pi は、センサーから湿度レベルと温度を読み取り、データを送信するコードを実行します AWS IoT。湿度レベル AWS IoT がしきい値を下回ると、Amazon SNS トピックにサブスクライブしているアドレスに E メールを送信するルールを で作成します。

**注記**  
このチュートリアルは最新ではない可能性があります。このトピックの最初の公開以降に、いくつかの参照が置き換えられている可能性があります。

**Contents**
+ [前提条件](#iot-moisture-prereqs)
+ [セットアップ AWS IoT](iot-moisture-setup.md)
  + [ステップ 1: AWS IoT ポリシーを作成する](iot-moisture-policy.md)
  + [ステップ 2: AWS IoT モノ、証明書、プライベートキーを作成する](iot-moisture-create-thing.md)
  + [ステップ 3: Amazon SNS トピックおよびサブスクリプションを作成する](iot-moisture-create-sns-topic.md)
  + [ステップ 4: E メールを送信する AWS IoT ルールを作成する](iot-moisture-create-rule.md)
+ [Raspberry Pi と湿度センサーのセットアップ](iot-moisture-raspi-setup.md)

## 前提条件
<a name="iot-moisture-prereqs"></a>

このチュートリアルを完了するには、以下が必要です。
+  AWS アカウント。
+ 管理者権限を持つ IAM ユーザー。
+ [AWS IoT コンソール](https://console.aws.amazon.com/iot/home)にアクセスするための、Windows、macOS、Linux、または Unix を実行している開発用コンピュータ。
+ 最新の [Raspberry Pi OS](https://www.raspberrypi.com/software/operating-systems/) を実行する [Raspberry Pi 3B または 4B](https://www.raspberrypi.com/products/)。インストール手順については、Raspberry Pi ウェブサイトの「[Install an operating system](https://www.raspberrypi.com/documentation/computers/getting-started.html#installing-the-operating-system)」を参照してください。
+ Raspberry Pi 用のモニター、キーボード、マウス、Wi-Fi ネットワークまたはイーサネット接続。
+ Raspberry Pi 対応の湿度センサー。このチュートリアルで使用するセンサーは、[Adafruit STEMMA I2C 容量性湿度センサー](https://www.adafruit.com/product/4026)で、[JST 4 ピンからメスソケットへのケーブルヘッダー](https://www.adafruit.com/product/3950)を備えています。

# セットアップ AWS IoT
<a name="iot-moisture-setup"></a>

このチュートリアルを完了するには、次のリソースを作成する必要があります。デバイスを に接続するには AWS IoT、IoT モノ、デバイス証明書、および AWS IoT ポリシーを作成します。
+  AWS IoT モノ。

  モノは物理デバイス (この場合は Rasberry Pi) を表し、デバイスに関する静的メタデータを含みます。
+ デバイス証明書。

   AWS IoTに接続して認証するには、すべてのデバイスにデバイス証明書が必要です。
+  AWS IoT ポリシー。

  各デバイス証明書には、1 つ以上の AWS IoT ポリシーが関連付けられています。これらのポリシーは、デバイスがアクセスできる AWS IoT リソースを決定します。
+  AWS IoT ルート CA 証明書。

  デバイスやその他のクライアントは、 AWS IoT ルート CA 証明書を使用して、通信している AWS IoT サーバーを認証します。詳細については、「[サーバー認証](server-authentication.md)」を参照してください。
+  AWS IoT ルール。

  ルールには、クエリと 1 つ以上のルールアクションが含まれます。クエリは、デバイスメッセージからデータを抽出して、メッセージデータを処理する必要があるかどうかを判断します。ルールアクションにより、データがクエリに一致する場合の処理が指定されます。
+ Amazon SNS トピックおよびトピックサブスクリプション。

  このルールでは、Raspberry Pi からの湿度データがリッスンされます。値がしきい値を下回る場合、Amazon SNS トピックにメッセージを送信します。Amazon SNS は、トピックにサブスクライブしているすべての E メールアドレスにそのメッセージを送信します。

 



# ステップ 1: AWS IoT ポリシーを作成する
<a name="iot-moisture-policy"></a>

Raspberry Pi がメッセージを接続および送信できるようにする AWS IoT ポリシーを作成します AWS IoT。

1. [AWS IoT コンソール](https://console.aws.amazon.com/iot)で、[**今すぐ始める**] ボタンが表示された場合はそれをクリックします。それ以外の場合は、ナビゲーションペインで **[Security]** (セキュリティ) を展開し、**[Policies]** (ポリシー) を選択します。

1. [**ポリシーはまだ作成されていません**] ダイアログボックスが表示された場合は、[**ポリシーの作成**] を選択します。それ以外の場合は、[**Create (作成) **] を選択します。

1.  AWS IoT ポリシーの名前を入力します (例: **MoistureSensorPolicy**)。

1. [**Add statements (ステートメントの追加)**] セクションで、既存のポリシーを次の JSON に置き換えます。*region* と *account* を AWS リージョン と AWS アカウント number に置き換えます。  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "iot:Connect",
               "Resource": "arn:aws:iot:us-east-1:123456789012:client/RaspberryPi"
           },
           {
               "Effect": "Allow",
               "Action": "iot:Publish",
               "Resource": [
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/update",
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/delete",
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/get"
               ]
           },
           {
               "Effect": "Allow",
               "Action": "iot:Receive",
               "Resource": [
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/update/accepted",
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/delete/accepted",
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/get/accepted",
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/update/rejected",
                   "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/RaspberryPi/shadow/delete/rejected"
               ]
           },
           {
               "Effect": "Allow",
               "Action": "iot:Subscribe",
               "Resource": [
                   "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/RaspberryPi/shadow/update/accepted",
                   "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/RaspberryPi/shadow/delete/accepted",
                   "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/RaspberryPi/shadow/get/accepted",
                   "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/RaspberryPi/shadow/update/rejected",
                   "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/RaspberryPi/shadow/delete/rejected"
               ]
           },
           {
               "Effect": "Allow",
               "Action": [
                   "iot:GetThingShadow",
                   "iot:UpdateThingShadow",
                   "iot:DeleteThingShadow"
               ],
               "Resource": "arn:aws:iot:us-east-1:123456789012:thing/RaspberryPi"
           }
       ]
   }
   ```

1. **[作成]** を選択します。

# ステップ 2: AWS IoT モノ、証明書、プライベートキーを作成する
<a name="iot-moisture-create-thing"></a>

Raspberry Pi を表すモノを AWS IoT レジストリに作成します。

1. [AWS IoT コンソール](https://console.aws.amazon.com/iot/home)のナビゲーションペインで、[**管理**]、[**モノ**] の順に選択します。

1. [**まだモノがありません**] ダイアログボックスが表示された場合は、[**モノの登録**] を選択します。それ以外の場合は、[**Create (作成)**] を選択します。

1. ** AWS IoT モノの作成**ページで、**モノを 1 つ**作成する を選択します。

1. [**Add your device to the device registry (デバイスレジストリへのデバイスの追加)**] ページで、IoT モノの名前 (例: **RaspberryPi**) を入力し、[**次へ**] を選択します。作成後にモノの名前は変更できません。モノの名前を変更するには、新しいモノを作成して、新しい名前を付け、古いモノを削除する必要があります。

1. [**モノに証明書を追加**] ページで、[**証明書の作成**] を選択します。

1. [**ダウンロード**] リンクを選択して、証明書、プライベートキー、ルート CA 証明書をダウンロードします。
**重要**  
これは、証明書とプライベートキーをダウンロードできる唯一の時間です。

1. 証明書を有効にするには、[**Activate**] (有効化) を選択します。デバイスが AWS IoTに接続するには、証明書がアクティブである必要があります。

1. [**ポリシーのアタッチ**] を選択します。

1. [**Add a policy for your thing (モノのポリシーを追加)**] で、[**MoistureSensorPolicy**]、[**Register Thing (モノの登録)**] の順に選択します。

# ステップ 3: Amazon SNS トピックおよびサブスクリプションを作成する
<a name="iot-moisture-create-sns-topic"></a>

Amazon SNS トピックおよびサブスクリプションを作成します。

1. [AWS SNS コンソール](https://console.aws.amazon.com/sns/home)のナビゲーションペインで [**Topics**] (トピック) を選択し、[**Create topic**] (トピックの作成) を選択します。

1. タイプを **[標準]** として選択し、トピックの名前を入力します (例: **MoistureSensorTopic**）。

1. トピックの表示名を入力します (例: **Moisture Sensor Topic**)。これは、Amazon SNS コンソールでトピックに表示される名前です。

1. [**トピックの作成**] を選択します。

1. Amazon SNS トピックの詳細ページで、**[Create subscription]** (サブスクリプションの作成) を選択します。

1. [**Protocol (プロトコル)**] として [**Email (E メール)**] を選択してください。

1. [**エンドポイント**] に E メールアドレスを入力します。

1. [**Create subscription**] を選択します。

1. E メールクライアントを開き、**MoistureSensorTopic** という件名のメッセージを探します。E メールを開き、[**サブスクリプションを確認**] リンクを選択します。
**重要**  
サブスクリプションを確認するまで、この Amazon SNS トピックからの E メールアラートは受信されません。

入力したテキストが記載された E メールメッセージが届きます。

# ステップ 4: E メールを送信する AWS IoT ルールを作成する
<a name="iot-moisture-create-rule"></a>

 AWS IoT ルールは、デバイスからメッセージを受信したときに実行するクエリと 1 つ以上のアクションを定義します。 AWS IoT ルールエンジンは、デバイスによって送信されたメッセージをリッスンし、メッセージ内のデータを使用して何らかのアクションを実行する必要があるかどうかを判断します。詳細については、「[のルール AWS IoT](iot-rules.md)」を参照してください。

このチュートリアルでは、Raspberry Pi が `aws/things/RaspberryPi/shadow/update` にメッセージを発行します。これは、デバイスと Thing Shadow サービスで使用される内部 MQTT トピックです。Raspberry Pi は、次の形式のメッセージを発行します。

```
{
    "reported": {
        "moisture" : moisture-reading,
        "temp" : temperature-reading
    }
}
```

受信メッセージから湿度と温度データを抽出するクエリを作成します。また、湿度の読み取り値がしきい値を下回っている場合、データを受け取り、そのデータを Amazon SNS トピックのサブスクライバーに送信する Amazon SNS アクションも作成します。

**Amazon SNS ルールを作成する**

1. [[AWS IoT コンソール]](https://console.aws.amazon.com/iot/home) で、**[メッセージのルーティング]** を選択し、**[ルール]** を選択します。[**ルールはまだ作成されていません**] ダイアログボックスが表示された場合は、[**ルールの作成**] を選択します。それ以外の場合は、**[ルールを作成]** を選択します。

1. **[ルールプロパティ]** ページで、**MoistureSensorRule** などの **[ルール名]** を入力し、**Sends an alert when soil moisture level readings are too low** などの短い **[ルールの説明]** を入力します。

1. **[次へ]** を選択し、SQL ステートメントを設定します。**SQL バージョン**を **2016-03-23** として選択し、次の AWS IoT SQL クエリステートメントを入力します。

   ```
   SELECT * FROM '$aws/things/RaspberryPi/shadow/update/accepted' WHERE state.reported.moisture < 400
   ```

   このステートメントは、`moisture` の読み取り値が `400` より小さい場合にルールアクションをトリガーします。
**注記**  
別の値の使用が必要になる場合があります。Raspberry Pi でコードを実行したら、センサーに触れたり、水に入れたり、プランター内に置いたりすることで、センサーから取得した値を表示できます。

1. **[次へ]** を選択し、ルールアクションをアタッチします。**[アクション 1]** で、**[Simple Notification Service]** を選択します。このルールアクションの説明は **[SNS プッシュ通知としてメッセージを送信します]** です。

1. **[SNS トピック]** では、[ステップ 3: Amazon SNS トピックおよびサブスクリプションを作成する](iot-moisture-create-sns-topic.md)、、**MoistureSensorTopic** で作成したトピックを選択し、**[メッセージ形式]** を **[RAW]** のままにします。**[IAM role]** (IAM ロール) は、**[Create a new role]** (新しいロールの作成) を選択します。ロールの名前 (例: **LowMoistureTopicRole**) を入力し、**[ロールを作成]** を選択します。

1. **[次へ]** を選択して確認してから、**[作成]** を選択してルールを作成します。

# Raspberry Pi と湿度センサーのセットアップ
<a name="iot-moisture-raspi-setup"></a>



microSD カードを Raspberry Pi に挿入し、モニター、キーボード、マウスを接続し、Wi-Fi を使用していない場合はイーサネットケーブルも接続します。電源ケーブルはまだ接続しないでください。

JST ジャンパーケーブルを湿度センサーに接続します。ジャンパーの反対側には次の 4 本のワイヤがあります。
+ 緑: I2C SCL
+ 白: I2C SDA
+ 赤: 電源 (3.5 V)
+ 黒: アース

右側にあるイーサネットジャックで Raspberry Pi を保持します。この向きでは、上部に 2 列の GPIO ピンがあります。次の順序で、湿度センサーのワイヤをピンの下の列に接続します。左端のピンから、赤 (電源)、白 (SDA)、緑 (SCL) を接続します。1 つのピンをスキップし、黒い (アース) ワイヤを接続します。詳細については、「[Python Computer Wiring](https://learn.adafruit.com/adafruit-stemma-soil-sensor-i2c-capacitive-moisture-sensor/python-circuitpython-test)」を参照してください。

電源ケーブルを Raspberry Pi に接続し、もう一方の端をコンセントに接続して電源を入れます。

**Raspberry Pi を設定します。**

1. [**Welcome to Raspberry Pi**] で、[**Next**] を選択します。

1. 国、言語、タイムゾーン、キーボードレイアウトを選択します。[**Next**] を選択します。

1. Raspberry Pi のパスワードを入力し、[**Next**] を選択します。

1. Wi-Fi ネットワークを選択し、[**Next**] を選択します。Wi-Fi ネットワークを使用していない場合は、[**Skip**] を選択します。

1. [**Next**] を選択して、ソフトウェアの更新を確認します。更新が完了したら、[**Restart**] を選択して Raspberry Pi を再起動します。

Raspberry Pi が起動したら、I2C インターフェイスを有効にします。

1. Raspbian デスクトップの左上隅にある Raspberry アイコンをクリックし、[**Preferences**]、[**Raspberry Pi Configuration**] の順に選択します。

1. [**Interfaces**] タブの [**I2C**] で、[**Enable**] を選択します。

1. [**OK**] を選択します。

Adafruit STEMMA 湿度センサーのライブラリは、CircuitPython 向けに記述されています。それらのライブラリを Raspberry Pi で実行するには、最新バージョンの Python 3 をインストールする必要があります。

1. コマンドプロンプトから次のコマンドを実行して、Raspberry Pi ソフトウェアを更新します。

   `sudo apt-get update`

   `sudo apt-get upgrade`

1. 次のコマンドを実行して、Python 3 のインストールを更新します。

   `sudo pip3 install --upgrade setuptools`

1. 次のコマンドを実行して、Raspberry Pi GPIO ライブラリをインストールします。

   `pip3 install RPI.GPIO`

1. 次のコマンドを実行して、Adafruit Blinka ライブラリをインストールします。

   `pip3 install adafruit-blinka`

   詳細については、「[Installing CircuitPython Libraries on Raspberry Pi](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/installing-circuitpython-on-raspberry-pi)」を参照してください。

1. 次のコマンドを実行して、Adafruit Seesaw ライブラリをインストールします。

   `sudo pip3 install adafruit-circuitpython-seesaw`

1. 次のコマンドを実行して、 AWS IoT Device SDK for Python をインストールします。

   `pip3 install AWSIoTPythonSDK`

これで、必要なすべてのライブラリが Raspberry Pi にインストールされました。**moistureSensor.py** という名前のファイルを作成し、次の Python コードをファイルにコピーします。

```
from adafruit_seesaw.seesaw import Seesaw
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTShadowClient
from board import SCL, SDA

import logging
import time
import json
import argparse
import busio

# Shadow JSON schema:
#
# {
#   "state": {
#       "desired":{
#           "moisture":<INT VALUE>,
#           "temp":<INT VALUE>            
#       }
#   }
# }

# Function called when a shadow is updated
def customShadowCallback_Update(payload, responseStatus, token):

    # Display status and data from update request
    if responseStatus == "timeout":
        print("Update request " + token + " time out!")

    if responseStatus == "accepted":
        payloadDict = json.loads(payload)
        print("~~~~~~~~~~~~~~~~~~~~~~~")
        print("Update request with token: " + token + " accepted!")
        print("moisture: " + str(payloadDict["state"]["reported"]["moisture"]))
        print("temperature: " + str(payloadDict["state"]["reported"]["temp"]))
        print("~~~~~~~~~~~~~~~~~~~~~~~\n\n")

    if responseStatus == "rejected":
        print("Update request " + token + " rejected!")

# Function called when a shadow is deleted
def customShadowCallback_Delete(payload, responseStatus, token):

     # Display status and data from delete request
    if responseStatus == "timeout":
        print("Delete request " + token + " time out!")

    if responseStatus == "accepted":
        print("~~~~~~~~~~~~~~~~~~~~~~~")
        print("Delete request with token: " + token + " accepted!")
        print("~~~~~~~~~~~~~~~~~~~~~~~\n\n")

    if responseStatus == "rejected":
        print("Delete request " + token + " rejected!")


# Read in command-line parameters
def parseArgs():

    parser = argparse.ArgumentParser()
    parser.add_argument("-e", "--endpoint", action="store", required=True, dest="host", help="Your device data endpoint")
    parser.add_argument("-r", "--rootCA", action="store", required=True, dest="rootCAPath", help="Root CA file path")
    parser.add_argument("-c", "--cert", action="store", dest="certificatePath", help="Certificate file path")
    parser.add_argument("-k", "--key", action="store", dest="privateKeyPath", help="Private key file path")
    parser.add_argument("-p", "--port", action="store", dest="port", type=int, help="Port number override")
    parser.add_argument("-n", "--thingName", action="store", dest="thingName", default="Bot", help="Targeted thing name")
    parser.add_argument("-id", "--clientId", action="store", dest="clientId", default="basicShadowUpdater", help="Targeted client id")

    args = parser.parse_args()
    return args


# Configure logging
# AWSIoTMQTTShadowClient writes data to the log
def configureLogging():

    logger = logging.getLogger("AWSIoTPythonSDK.core")
    logger.setLevel(logging.DEBUG)
    streamHandler = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    streamHandler.setFormatter(formatter)
    logger.addHandler(streamHandler)


# Parse command line arguments
args = parseArgs()

if not args.certificatePath or not args.privateKeyPath:
    parser.error("Missing credentials for authentication.")
    exit(2)

# If no --port argument is passed, default to 8883
if not args.port: 
    args.port = 8883


# Init AWSIoTMQTTShadowClient
myAWSIoTMQTTShadowClient = None
myAWSIoTMQTTShadowClient = AWSIoTMQTTShadowClient(args.clientId)
myAWSIoTMQTTShadowClient.configureEndpoint(args.host, args.port)
myAWSIoTMQTTShadowClient.configureCredentials(args.rootCAPath, args.privateKeyPath, args.certificatePath)

# AWSIoTMQTTShadowClient connection configuration
myAWSIoTMQTTShadowClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTShadowClient.configureConnectDisconnectTimeout(10) # 10 sec
myAWSIoTMQTTShadowClient.configureMQTTOperationTimeout(5) # 5 sec

# Initialize Raspberry Pi's I2C interface
i2c_bus = busio.I2C(SCL, SDA)

# Intialize SeeSaw, Adafruit's Circuit Python library
ss = Seesaw(i2c_bus, addr=0x36)

# Connect to AWS IoT
myAWSIoTMQTTShadowClient.connect()

# Create a device shadow handler, use this to update and delete shadow document
deviceShadowHandler = myAWSIoTMQTTShadowClient.createShadowHandlerWithName(args.thingName, True)

# Delete current shadow JSON doc
deviceShadowHandler.shadowDelete(customShadowCallback_Delete, 5)

# Read data from moisture sensor and update shadow
while True:

    # read moisture level through capacitive touch pad
    moistureLevel = ss.moisture_read()

    # read temperature from the temperature sensor
    temp = ss.get_temp()

    # Display moisture and temp readings
    print("Moisture Level: {}".format(moistureLevel))
    print("Temperature: {}".format(temp))
    
    # Create message payload
    payload = {"state":{"reported":{"moisture":str(moistureLevel),"temp":str(temp)}}}

    # Update shadow
    deviceShadowHandler.shadowUpdate(json.dumps(payload), customShadowCallback_Update, 5)
    time.sleep(1)
```

このファイルを、見つけられる場所に保存します。以下のパラメータを使用して、コマンドラインから `moistureSensor.py` を実行します。

エンドポイント  
カスタム AWS IoT エンドポイント。詳細については、「[Device Shadow の REST API](device-shadow-rest-api.md)」を参照してください。

rootCA  
 AWS IoT ルート CA 証明書へのフルパス。

cert  
 AWS IoT デバイス証明書へのフルパス。

key  
 AWS IoT デバイス証明書のプライベートキーへのフルパス。

thingName  
モノの名前 (この場合は `RaspberryPi`)。

clientId  
MQTT クライアント ID。`RaspberryPi` を使用します。

コマンドラインは次のようになります。

`python3 moistureSensor.py --endpoint your-endpoint --rootCA ~/certs/AmazonRootCA1.pem --cert ~/certs/raspberrypi-certificate.pem.crt --key ~/certs/raspberrypi-private.pem.key --thingName RaspberryPi --clientId RaspberryPi`

センサーに触れたり、プランター内に置いたり、コップの水に入れたりして、センサーがさまざまなレベルの湿気にどのように反応するかを確認します。必要に応じて、`MoistureSensorRule` でしきい値を変更できます。湿度センサーの読み取り値がルールの SQL クエリステートメントで指定された値を下回ると、 は Amazon SNS トピックにメッセージ AWS IoT を発行します。湿度と温度データが含まれた E メールメッセージが届きます。

Amazon SNS からの E メールメッセージの受信を確認したら、**Ctrl\$1C** を押して Python プログラムを停止します。Python プログラムが、料金がかかる量のメッセージを送信することはほとんどありませんが、終了したらプログラムを停止することをお勧めします。