Azure IoT Hubでデバイスを管理する

巷でIoTって流行ってますよね。モノがインターネットに繋がって云々というあれです。
IoTに分類されそうなプロダクトを作る場合、デバイスモニタリングは間違いなく必須になります。
Azureでは、Azure IoT Hubを使用することによって簡単にデバイスモニタリングのベースシステムを構築することができます。
そこで今回は、IoT Hubにデバイスを登録、管理の方法について触れてみようと思います。

## IoT Hubを作成する
まず初めにIoT Hubを作成します。この作業は、Azureポータルから行います。
ポータルの新規作成からIoT Hubで検索すると下図のようにIoT Hubが出てくるので選択します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/d313a860-6ccd-6776-d2c6-05b7a6258f92.png)
IoT Hubは、いくつかプランがあるので適当に選んで作成してください。
Freeプランもあるので適当に実験で使う程度ならFreeでもOKです。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/ca06d434-b041-acc4-8937-fd2c5ebc49a0.png)

作成すると下図のような画面が表示されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/40c984b9-4bac-d603-e1be-cf734a9bb414.png)

## 接続文字列を取得する。
次にIoT Hubに接続するための接続文字列を取得します。
接続文字列は、下図のように共有アクセスポリシーから取得します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/6038aeca-09ab-2fbc-d58d-27e32eecaf00.png)

デフォルトでアクセスポリシーはいくつか用意されています。
ポリシーは、
* レジストリ読み取り
* レジストリ書き込み
* サービス接続
* デバイス接続

の4つが用意されているので用途に応じてポリシーを作成します。(詳細については今回は割愛)
今回は、全ての権限が付与されているiothubownerを使用します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/4d2dd636-bc9b-eda4-8c14-526caf395d60.png)

必要な情報は、プライマリキーなので、接続文字列ープライマリキーを取得します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/a9200904-56b7-f370-6886-2ab355b84a29.png)

## IoT Hubと接続するコードを実装する
今回は、C\#で実装した例を示します。

### ライブラリをインストールする
ライブラリは、NuGetからインストールします。
NuGetでMicrosoft.Azure.Devicesで検索して出てくる下図のライブラリをインストールします。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/b7ca9b50-fc96-8870-e8fa-26a1772337ff.png)


### IoT Hubにデバイスを登録する
使用するNamespaceは、下記のものになります。

```csharp
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Common.Exceptions;
```

接続用のコードは、下記のような感じです。

```csharp
        private RegistryManager _registryManager;
        private string _connectionString = "{IoT Hubの接続文字列}";

        private async Task AddDeviceAsync()
        {
            var deviceId = Guid.NewGuid();
 　　　　　　_registryManager = RegistryManager.CreateFromConnectionString(_connectionString);
            Device device;
            try
            {
                device = await _registryManager.AddDeviceAsync(new Device(deviceId.ToString()));
            }
            catch (DeviceAlreadyExistsException)
            {
                device = await _registryManager.GetDeviceAsync(deviceId.ToString());
            }
            catch (Exception)
            {
                return;
            }

            Debug.WriteLine(device.Authentication.SymmetricKey.PrimaryKey);
        }
```
IoT Hubには、クライアント側で生成したデバイスIDを登録します。
デバイスIDは、大量のデバイスを扱う際は、被る可能性があるのでGUIDなどで被らないようにすると良いかと思います。
また、実際にアプリケーションを作る場合は、デバイスIDをどこかに保存するといった処理を追加してください。

### デバイスの有効無効を設定する
先ほどデバイスIDを生成してIoT Hubに登録しました。デフォルトでは、接続が有効になっていますが、それの切り替えを行ってみます。
切り替えは、ポータルから行えます。
IoT Hubの画面の上部にあるデバイスを選択します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/b89bd20d-4d1b-90ae-ddf6-0159ab18d583.png)
デバイスを選択すると、IoT Hubに登録されているデバイスが一覧表示されます。その中でステータスを変更したいデバイスを選択します。
選択すると下図のような画面になります。
ここで、デバイスごとの接続文字列や有効化、無効化などを設定します。
![image](https://qiita-image-store.s3.amazonaws.com/0/28367/65fc0066-87a5-2727-87e2-5f740d813928.png)

### デバイスを削除する
IoT Hubからデバイスを削除する場合は、下記のようなコードになります。

```csharp
        private async Task RemoveDeviceAsync()
        {
            var deviceId = "4337ddbf-9573-4875-869e-42356fc66a23";
            try
            {
                await _registryManager.RemoveDeviceAsync(deviceId);

            }
            catch (DeviceNotFoundException)
            {
                throw;
            }
            catch (Exception ex)
            {
                
                throw;
            }
        }
```

### デバイスの有効無効をプログラムから切り替える
先ほどデバイスの有効、無効をポータルから管理する方法を紹介しましたが、プログラム上から行う方法を下記に示します。

```csharp
        private async Task SwitchDeviceStatus()
        {
            var deviceId = "7eebdaa3-0fdd-49da-af68-a82602998c3a";
            Device device;
            try
            {
                device = await _registryManager.GetDeviceAsync(deviceId);
            }
            catch (Exception)
            {
                throw;
            }
            if (device == null)
            {
                return;
            }
            device.Status = device.Status == DeviceStatus.Enabled ? DeviceStatus.Disabled : DeviceStatus.Enabled;
            await _registryManager.UpdateDeviceAsync(device);
        }
```
ステータスを変更したらUpdateDeviceAsyncメソッドで、IoT Hubに変更を通知するのを忘れないようにしましょう。

## まとめ
今回説明したプログラムは、メッセージ送信などの処理というよりもデバイス管理のものなので、IoT Hubを使って何かを運用する際の管理ツールに仕込んだりするような用途のものです。
IoTなプロダクトの運用をするうえで、必ず必要になってくる実装なのでIoT Hubを使う場合は、参考にしてみてください。