PRODUCTS実績紹介

Azure IoT HUBの接続文字列(SAS入り)を生成 (C#)

Azure IoT HUBに独自のデバイスを接続したいけど、Device ExplorerやVSから接続文字列を生成する方法は、サンプル的な確認では良いけど運用には向きません(SASの有効期限の問題があるからです)。MicrosoftのSDKを使うにしても「64KByte以上」のRAMを確保する必要があり、組み込み向けの小さなマイコンでは荷が重い。SDKから必要なもの以外を削ればいいという話もありますが、やりたいことは IoT HUBとつなぐことではなく、IoT HUBを利用して「目的を達成したい」です。なので、手段に過ぎない IoT HUBに「つなぐためだけ」に大きな労力を使うのは勿体ない。

色々なコマンド ベースのサンプルや実行モジュールがネット上では見受けられますが、いずれにしてもDevice ExplorerやVSから接続文字列を生成する方法と大差がありません。これでは、SASの有効期限の問題をクリアでません。

< 一つの解決方法 >
SASの有効期限内であれば、デバイス接続時に新たな接続文字列をデバイスに渡す(Azure IoT HUBのCloud to Deviceを利用)。もし、SASの有効期限が切れている場合は、USBかBLE経由でデバイス内の接続文字列を更新。

この方法で行う場合は、接続文字列の生成をAzure Functions、PC/Mac/モバイル デバイスのプログラムで行うことになります。これなら非力なマイコンで無理やり生成する必要はなくなります。
接続文字列の生成自体は簡単で、以下のようなメソッドを作成して呼び出すだけです。

/// <summary>
/// IoT HUB接続文字列の生成
/// </summary>
/// <param name=”iotHubHostName”>IoT HUBのホスト名</param>
/// <param name=”deviceID”>デバイスID</param>
/// <param name=”primarykey”>デバイスのプライマリー キー</param>
/// <param name=”ttlValue”>トークンの有効期限(単位=日)</param>
/// <returns>接続文字列</returns>
private String GenerateConnectionStrings(String iotHubHostName, String deviceID, String primarykey, Decimal ttlValue)
{
    var sasBuilder = new SharedAccessSignatureBuilder()
    {
        Key = primarykey,
        Target = String.Format(“{0}/devices/{1}”, iotHubHostName, WebUtility.UrlEncode(deviceID)),
        TimeToLive = TimeSpan.FromDays(Convert.ToDouble(ttlValue))
    };
    String result = String.Format(“HostName={0};DeviceId={1};SharedAccessSignature={2}”, iotHubHostName, deviceID, sasBuilder.ToSignature());
    return result;
}



PC上で以下のようなコードで、生成した接続文字列が正しいかを確認することができます(Azure IoT HUBにMQTTでJSONを投げています)。


String IoTHubHostName = “{IoT HUBのホスト名}”;
String DeviceID = “{デバイスID}”;
String Primarykey = “{主キー}”;

private async void ButtonTest_ClickAsync(object sender, EventArgs e)
{
    try
    {
        using (DeviceClient deviceClient = DeviceClient.CreateFromConnectionString(
            GenerateConnectionStrings(IoTHubHostName, DeviceID, Primarykey, 1),
            Microsoft.Azure.Devices.Client.TransportType.Mqtt))
        {
            // 適当なメッセージを作成
            String messageBody = JsonSerializer.Serialize(
                new
                {
                    temperature = 12.5,
                    humidity = 36.9,
                });
            var message = new Microsoft.Azure.Devices.Client.Message(Encoding.ASCII.GetBytes(messageBody))
            {
                ContentType = “application/json”,
                ContentEncoding = “utf-8”,
            };
            // オープン
            await deviceClient.OpenAsync();
            // 送る
            await deviceClient.SendEventAsync(message);
            // クローズ
            await deviceClient.CloseAsync();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(this, ex.Message, “ERROR”);
    }
}