1923

都内と業界の隅っこで生活しているエンジニアのノート

Azure IoT Hub でメッセージの送信と受信を試してみた

IoT Hubでメッセージの送信と受信を試したメモです。 UWPアプリからIoT Hubにメッセージを送信して、 Functions で受信したメッセージをそのままデバイスに送信しているだけです。

公式サイトのドキュメントや、サンプルも豊富にあるので簡単に試すことできます。

作業はこんな感じです。

  • Azure にリソース作成
  • IoT Hubにデバイスを登録
  • Functions で動作させるEcho Function作成
  • Device用アプリの作成
  • 動作確認

Azure にリソース作成

IoT Hub と Functions を作成。cloud-to-device メッセージングを使うので、IoT Hub は無料又はStandard。

Azure IoT Hubにデバイスを登録

IoT Hubにデバイスを登録します。

Azure Cloud Shell を使用する を参考にコマンド、

az extension add --name azure-iot
az iot hub device-identity create --hub-name HubName11--device-id device1

AzureポータルからGUIAzure IoT エクスプローラーなどで簡単に作成。

Functions で動作させるEchoプログラムを作成

受信した値をそのまま送信しているだけです。

    public static class Function1
    {
        private static readonly ServiceClient ServiceClient = ServiceClient.CreateFromConnectionString("接続文字列");

        [FunctionName("Function1")]
        public static async Task Run(
            [EventHubTrigger("HubName11", Connection = "EventHubConnectionAppSetting")] EventData[] events, ILogger log)
        {
            foreach (var eventData in events)
            {
                var id = eventData.SystemProperties.FirstOrDefault(m => m.Key == "iothub-connection-device-id");
                var commandMessage = new Message(eventData.Body.Array);
                await ServiceClient.SendAsync(id.Value.ToString(), commandMessage);
                await Task.Yield();
            }
        }
    }

"接続文字列"は、Azureポータルの「設定」> 「共有アクセス ポリシー」にある「接続文字列」の値。EventHubConnectionAppSettingは、「設定」 > 「組み込みのエンドポイント」の「イベントハブ互換エンドポイント」の値です。

Device用アプリ作成

ここにあるサンプルを参考に、今回はUWPアプリでメッセージの送信と受信アプリを作成。

MainPage.xaml.cs

    public sealed partial class MainPage : Page
    {
        private readonly DeviceClient _deviceClient = DeviceClient.CreateFromConnectionString("接続文字列", TransportType.Http1);
        private readonly bool _receiving = true;

        public MainPage()
        {
            InitializeComponent();
            ReceiveMessagesAsync();
        }

        private readonly ObservableCollection<string> _contacts = new ObservableCollection<string>();

        public ObservableCollection<string> Contacts => this._contacts;

        private async void SendButton_Click(object sender, RoutedEventArgs e)
        {
            var msg = new Message(Encoding.UTF8.GetBytes(SendMessageTextBox.Text));
            await _deviceClient.SendEventAsync(msg);
            var s = "送信:" + SendMessageTextBox.Text + " >>";
            _contacts.Insert(0, s);
        }

        private async void ReceiveMessagesAsync()
        {
            while (_receiving)
            {
                var receivedMessage = await _deviceClient.ReceiveAsync();

                if (receivedMessage != null)
                {
                    var s = "受信:" + "<< " + Encoding.UTF8.GetString(receivedMessage.GetBytes());
                    _contacts.Insert(0, s);
                    await _deviceClient.CompleteAsync(receivedMessage);
                }
            }
        }

        private void MessageTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            SendButton.IsEnabled = !string.IsNullOrEmpty(SendMessageTextBox.Text);
        }

    }

MainPage.xaml

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Width="1000"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid HorizontalAlignment="Left" Width="1000">
        <TextBox HorizontalAlignment="Left" 
                 Margin="57,56,0,0" 
                 Name="SendMessageTextBox" 
                 Text="" 
                 TextWrapping="Wrap"
                 VerticalAlignment="Top" 
                 Header="送信メッセージ" 
                 Width="726" 
                 TextChanged="MessageTextBox_TextChanged"/>
        <Button Content="送信" 
                Margin="800,80,0,0" 
                VerticalAlignment="Top" 
                Name="SendButton" 
                IsEnabled="False"
                Click="SendButton_Click"/>

        <ListView x:Name="FruitsList" Margin="57,157,57,80" ItemsSource="{x:Bind Contacts}">
            <UIElement.RenderTransform>
                <MatrixTransform/>
            </UIElement.RenderTransform>
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="x:String">
                    <Grid>
                        <TextBlock Text="{x:Bind}" FontSize="14" Grid.Column="0"/>
                    </Grid>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </Grid>
</Page>

動作確認

Functions をAzureにデプロイし、Deviceアプリからメッセージの送信・受信を確認して完了です。

f:id:taka1923:20201105164749p:plain

参考

クイック スタート:デバイスから IoT ハブに利用統計情報を送信してバックエンド アプリケーションで読み取る (.NET)

Azure-Samples/azure-iot-samples-csharp