Azure IoT Hubを使ってみた

2017年4月2日　追記

長らくUWP用DeviceClientではMQTTの利用ができなかったのですが、最新のVersion 1.2.6で利用できるようになりました。
TransportTypeにMqttを選ぶだけです。

------------------------------------------------------------------------------------------------------------------------
先日9月29日のAzureConにてAzure IoT Suite 及び Azure IoT Hubの提供がアナウンスされました。
さっそくAzure IoT Hub（以下 IoT Hub）を試してみました。
デバイスとIoT Hubとの間でメッセージを送受信できるところまでやってみます。

##用意するもの
1.何かデバイス RaspberryPi2等　今回はUWPアプリのみで動作させるのでなくても大丈夫。

2.VisualStudio2015 （Community版でOK）

3.Windows8.1以上 UWPアプリを作成する都合でWindows10の方がいいと思います。

4.Microsoft Azure サブスクリプション。

##Azure IoT Hubの作成
まずAzure 新ポータルにアクセスします。
10/3現在、日本語表示の場合にIoT Hubのデプロイに失敗することがあるので、ポータルの設定で言語をEnglishに変更しておきます。
![IoTHub1-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/07cab8a6-ac65-a697-9623-bfaf843faaf3.png)

1.画面左上のNewをクリックします。

2.Internet of Thingsをクリックします。

3.Azure IoT Hub をクリックします。

4.Nameに好きな名前を入力します。アドレス名になるのでユニークな名前になるようにします。

5.料金およびスケールを選択します。最初なのでFreeを選択します。

6.リソースグループを選択するか、新規で作成します。On Create newをクリックすると新規作成できます。

7.ロケーションを選択します。現時点でヨーロッパ北部、東アジア、米国東部が選択できます。好きなところを選択してください。

8.最後にCreateをクリックするとIoT Hubが作成されます。

##IoT Hubにデバイスを登録
次に作成したIoT Hubにデバイスを登録します。今回はAzure IoT SDKに含まれているDevice Explorer を使います。

1.次のサイトにアクセスします。
https://github.com/Azure/azure-iot-sdks/blob/master/tools/DeviceExplorer/doc/how_to_use_device_explorer.md

2.サイトの中ほどに DeviceExplorer.msi とリンクがあるので、クリックしてダウンロードします。

3.ダウンロードした SetupDeviceExplorer.msi をダブルクリックしてインストールします。

4.新ポータルからIoT Hubを選択し、All settingsをクリックします。続いてShared access policiesをクリックします。
![IoTHub2-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/e29c921f-488c-3f53-e5a0-acf9098a0232.png)

5.POLCYのiothubownerをクリックします。![IoTHub3-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/9795e687-e1de-d31f-79a5-078fdaaf453d.png)

6.Connection string-primary keyをクリップボードにコピーします。

7.C:\Program Files (x86)\Microsoft\DeviceExplorer中の DeviceExplorer.exe を起動します。![deviceexplorer2-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/ae3ff75b-2158-3ec7-1536-5d49f4dc7230.png)

8.IoT Hub Connection Stringに先ほどコピーした内容をペーストしてからUpdateボタンを押します。

9.Shared Access SignatureにConnection Stringの内容が表示されます。![deviceexplorer2-3.png](https://qiita-image-store.s3.amazonaws.com/0/62606/82a1a593-becb-8e4b-fb02-6330e9dd702a.png)

10.Managementタブを選択し、Createボタンをクリックします。![deviceexplorer3-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/15ad8a76-93ec-ac73-caf0-216a8171b9d8.png)

11.Device ID:に好きな名前を入力します。Primary Key、Secondary Keyは自動的に生成されます。![deviceexplorer4-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/0c16d00b-6291-afdc-48c1-8b3883bbf7bc.png)

12.CreateボタンをクリックしてDeviceを登録します。
![deviceexplorer5-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/de36783e-58d5-490c-a68f-33cad043ee46.png)

##Device用プログラム
Device用のプログラムを作成します。

1.VisualStudio2015で新規プロジェクトを作成します。テンプレートは空白のアプリ（ユニバーサル Windows）を選択してください。
![VS2015-1-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/6b215a21-947e-8c97-13b1-17c28e0b8252.png)

2.IoT Hubにアクセスするためのクライアントライブラリをインストールします。チュートリアルではNuGetパッケージマネージャーから検索してライブラリをインストールするように説明していますが、現時点では検索しても見つからないのでメニューからツール＞NuGetパッケージマネージャー＞パッケージマネージャーコンソールを選択して、「Install-Package Microsoft.Azure.Devices.Client -Pre」と入力してクライアントライブラリをインストールします。

3.ソリューションエクスプローラーからMainPage.xaml.csを開いて次のプログラムを入力します。

```MainPage.xaml.cs
using System;
using Windows.UI.Xaml.Controls;

//追加
using System.Text;
using Microsoft.Azure.Devices.Client;
using System.Diagnostics;

namespace IoTHub
{
    /// <summary>
    /// 
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private const string cnString = "[device connection string]";
        private DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(cnString, TransportType.Http1);

        public MainPage()
        {
            this.InitializeComponent();
            SendDataToAzure();
            ReceiveDataFromAzure();           
        }

        /// <summary>
        /// 
        /// </summary>
        private async void ReceiveDataFromAzure()
        {
            Message receivedMessage;
            string messageData;

            while (true)
            {
                receivedMessage = await deviceClient.ReceiveAsync();

                if (receivedMessage!= null)
                {
                    messageData = Encoding.UTF8.GetString(receivedMessage.GetBytes());
                    Debug.WriteLine(messageData);
                    await deviceClient.CompleteAsync(receivedMessage);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private async void SendDataToAzure()
        {
            
            var text = "Send from Device";
            var msg = new Message(Encoding.UTF8.GetBytes(text));

            await deviceClient.SendEventAsync(msg);
        }
    }
}
```

4.Device ExplorerのManagementタブで先ほど登録したデバイスがリストに表示されているので、右クリックをして一番下の「Copy connection string for selected device」を選びます。![deviceexplorer6-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/ff6ade07-7e12-33d4-11fd-801fbf42e666.png)

5.プログラム上の[device connection string]の箇所を今コピーした内容にペーストして置き換えます。

##動作確認
Device Explorerと先ほど入力したプログラムでメッセージの送受信の動作確認をしてみます。

1.Device ExplorerのDataタブに切り替えます。Monitorボタンをクリックします。
![deviceexplorer7-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/fdbf1277-7372-80a1-011e-1dc0ee94b722.png)

2.VisualStudio2015でプログラムを実行します。
![VS2015-3-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/1312856e-4654-04ad-1ae9-1ef7869e9f3c.png)

3.しばらくするとDevice ExplorerのEvent Hub DataのところにDeviceからのメッセージが表示されます。![deviceexplorer10.PNG](https://qiita-image-store.s3.amazonaws.com/0/62606/a3fffc94-2b0a-f240-f853-35a95f191b47.png)

4.次にMessages To Deviceタブに切り替えます。

5.Message:テキストボックスに自由に入力してください。ただし半角英数のみになります。Add Time Stampにチェックを入れると送信時にタイムスタンプが追加されます。
![deviceexplorer11-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/7abf79dd-fd38-5b8f-408a-59f8f3cddea6.png)

6.入力ができたらSendボタンをクリックします。

7.VisualStudioに切り替えて、出力ウインドウに先ほど送信したメッセージが表示されているいるのを確認してください。
![VS2015-4-1.png](https://qiita-image-store.s3.amazonaws.com/0/62606/07558aac-252a-5c9d-edfd-1f44a3b62d54.png)

##次は
これでDeviceからIoT Hubへのデータ送信および受信ができるようになりました。
DeviceからのデータはIoT Hubで受け取ってからStream Analyticsで処理をしてDBやBlob等に蓄積していくことになります。
IoT Hubからのメッセージ送信はWebJobで行うことになるかと思います。

[Azure IoT Developer Center](https://azure.microsoft.com/ja-jp/develop/iot/)サイトのConnect your deviceをクリックするとチャート式で自分が持っているDeviceを接続するためのサンプルプログラムを見ることができます。

今回は特にDeviceを使いませんでしたがプログラムはUWPアプリなので、ビルドプラットフォームをARMに変更するだけでWindows10 IoT Coreが動作するRPi2でもそのまま動作します。もしかすると.NET Micro Frameworkが動作するDevice（GR-SakuraとかNetduinoなど）もほとんど変更せずに動作するかもしれません。

クライアントライブラリもC、Node.js、JAVAと用意されているので色々なDeviceで利用できるのではないかと思います。