Azure IoT HubのREST APIを使ってM5ATOM Liteからデータを送信するメモ

![IMG_1071.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90087/2c9c06a3-a92b-d54c-ba07-20c9e3aea75b.jpeg)

## はじめに

Azure IoT Hub に M5ATOM Lite からデータを送信するメモです。
IoT Hub の REST API を利用します。

ソースコードは GitHub に公開しています。
https://github.com/tmitsuoka0423/m5stack-azure-iot-http-post

## Azure IoT Hub周りの作業

### Azure IoT Hubをデプロイする

[公式のクイックスタート](https://docs.microsoft.com/ja-jp/azure/iot-hub/quickstart-send-telemetry-node#create-an-iot-hub)を参考に IoT Hub のインスタンスを作成します。

- スケールは`F1`を選択（無料版）

### Azure IoT HubのREST APIエンドポイントのルート証明書を取得する

ESP32 で HTTPS 通信を行う場合は、ルート証明書を指定してあげる必要があります。

こちらの記事([Arduino – ESP32 WiFiClientSecure ライブラリで、安定して https ( SSL )記事をGETする方法](https://www.mgo-tec.com/blog-entry-arduino-esp32-ssl-stable-root-ca.html))を参考にさせていただき、ルート証明書を取得します。

`https://<Iot Hubの名前>.azure-devices.net/`を Chrome で開いて証明書を取得します。
（実際に開くと Bad Request になりますが、ルート証明書を取るだけなので問題なし）

### IoTデバイスを登録する

Azure IoT Hub のコンソールを開き、`IoTデバイス > 新規`からデバイスを登録します。
<a href="https://gyazo.com/219c958f9bf0e9864416c77998565e9f"><img src="https://i.gyazo.com/219c958f9bf0e9864416c77998565e9f.png" alt="Image from Gyazo" width="1264"/></a>
デバイス ID は好きな値を指定し、その他は変更なしで OK です。
<a href="https://gyazo.com/ed8e53e484d03c0997c824db6146cdc1"><img width="600px" src="https://i.gyazo.com/ed8e53e484d03c0997c824db6146cdc1.png" alt="Image from Gyazo" width="746"/></a>

## M5ATOM Liteのプログラム

### サンプルコード

[前記事(M5ATOM LiteでHTTP POSTするシンプルなサンプルコード)](https://qiita.com/tmitsuoka0423/items/bc8bd589442b5c2279a7)で作成したコードを変更していきます。
`test`という文字列を送信してみます。

`arduino-esp32`の`HTTPClient.h`を見ると、`begin`メソッドに`URL`と`ルート証明書`を渡せば良さそうです。

> https://github.com/espressif/arduino-esp32/blob/dd513df124bd39736e96c2b03b23dd48bdae0c97/libraries/HTTPClient/src/HTTPClient.h#L160

```cpp
bool begin(String url, const char* CAcert);
```

コードは以下のようになります。

```cpp
#define FASTLED_INTERNAL

#include <M5Atom.h>
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

const char *url = "https://<IoT Hubの名前>.azure-devices.net/devices/<デバイスID>/messages/events?api-version=2018-06-30";
const char* azure_iot_hub_root_ca =
    "-----BEGIN CERTIFICATE-----\n" \
    "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n" \
    "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n" \
    "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n" \
    "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n" \
    "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n" \
    "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n" \
    "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n" \
    "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n" \
    "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n" \
    "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n" \
    "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n" \
    "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n" \
    "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n" \
    "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n" \
    "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n" \
    "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n" \
    "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n" \
    "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n" \
    "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n" \
    "-----END CERTIFICATE-----\n";

const char *sasToken = "SharedAccessSignature sr=xxxxxxxxxx&sig=xxxxxxxxxxxxxxxx&se=xxxxxxxxxxxxxxx&skn=xxxxxxxxxxxxxxxxxx";

void post() {
  HTTPClient http;
  http.begin(url, azure_iot_hub_root_ca);
  http.addHeader("Content-Type", "application/json");
  http.addHeader("Authorization", sasToken);
  http.POST("test");
  Serial.println(http.getString());
  http.end();
}

void setup() {
  M5.begin();
  Serial.begin(115200);

  Serial.print("WiFi connecting.");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }

  post();
}

void loop() { /* 起動時のみ送信するため、ループでは何もしない。*/ }
```

実際に利用する場合は、Wi-Fi の設定と Azure のパラメータを設定してください。
Azure のパラメータの詳細は以下の通りです。

| 名前 | 内容 | 備考 |
| :-: | :-: | :-: |
| url | Azure IoT HubのREST APIのURL | 作成したIoT Hubインスタンスの名前と、登録したデバイスIDを指定 |
| sasToken | SASトークン | [SASトークンを発行する](https://qiita.com/tmitsuoka0423/items/bfcc91d50cd0fe312f6c#sas%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%82%92%E7%99%BA%E8%A1%8C%E3%81%99%E3%82%8B)で発行できます |

## 動作確認

[公式のサンプルコード](https://github.com/Azure-Samples/azure-iot-samples-node/releases/tag/234607)を利用して、受信できているか確認します。

サンプルコードをダウンロード後、[Node.jsでAzure IoT Hubにテレメトリを送信するサンプルコードを動かすメモ/送信したデータを受信する](https://qiita.com/tmitsuoka0423/items/bbc5ea0f462752e31c1f#%E9%80%81%E4%BF%A1%E3%81%97%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%8F%97%E4%BF%A1%E3%81%99%E3%82%8B)の手順に従って、プログラムを実行します。

// TODO 画像

## まとめ

M5ATOM Lite から Azure IoT Hub の REST API を使ってデータを送信しました。
HTTP POST で送信すると、割とシンプルなコードで送信できました。

今回、SAS トークンは PC で発行してから M5ATOM Lite に書き込んでいるので、時間が経つと期限が切れてしまいます。
マイコン上で SAS トークンを発行する方法も調べていきます。