CodeZine(コードジン)

特集ページ一覧

IoTの計測データをWindowsストアアプリで可視化してみよう

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加
2015/03/06 14:00

 Arduino、Intel Galileo 、FEZ Spiderなどの名前を聞いたことのある人も多いと思います。Internet of Thingsの注目度が高くなるのと時を同じくして、各種センサーからの測定値を扱う小型デバイスにも注目が集まり始めています。今回は、.NET Micro Frameworkが動作するFEZ Spiderで温湿度を測定し、それをMicrosoft Azure Mobile Servicesを経由してWindowsストアアプリでグラフ化する方法を確認します。もちろんグラフ化するのに使うコンポーネントは、「ComponentOne Studio Chart for WinRT XAML」(以下、C1Chart)です。

Microsoft Azure Mobile Serviceの用意

 まずはセンサー値を送受信するためのクラウド側を用意します。Microsoft Azureであれば、MSDNに無料特典がありますし、無料お試しも用意されています。Microsoft Azure管理ポータルに接続したら、cz1501serviceという名前でMobile Servicesを新規作成します。この名前はMobile Servicesの中で別々の名前になっていないといけないので、それぞれ独自の名前で作成してください。

図1 Microsoft Azure Mobile Services
図1 Microsoft Azure Mobile Services

 作成ができたらサービスに対するアクセス権を得るためのアプリケーションキーを取得します。

図2 アプリケーションキー
図2 アプリケーションキー

 一番左の雲アイコンをクリックして「既存のWINDOWSアプリまたはWINDDOWS PHONEアプリに接続する」リンクをクリックして内容を表示すると、C#のコードの中にアプリケーションキーが表示されるのでメモ帳などにコピーしておきましょう。

センサー側の用意

 .NET Micro Frameworkの最新版は4.3です。今回はこの.NET Micro Framework 4.3を使います。

図3 .NET Micro Framework SDK
図3 .NET Micro Framework SDK

.NET Gadgeteer

 FEZ Spiderの特徴は.NET Micro Frameworkが動作するという点以外にも、.NET Gadgeteerにも対応しているという点があります。.NET Gadgeteerがどのようなものか実際に作成していましょう。

 新規プロジェクト作成で[Gadgeteer]-[.NET Gadgeteer Application]テンプレートを選択します。

図4 .NET Gadgeteer Aplicationテンプレートの選択
図4 .NET Gadgeteer Aplicationテンプレートの選択

 このテンプレートで作成するプロジェクトは、.NET Micro Framework上で動くアプリのプロジェクトになりますが、さらに、実際に使用するメインボードを選択することで、さまざまな恩恵にあずかれます。今回使用するのはFEZ Spiderなのでプロジェクト作成時に表示されるウィザードでもFEZ Spiderを選択しましょう。

図5 .NET Gadgeteer Aplicationウィザード
図5 .NET Gadgeteer Aplicationウィザード

 .NET Gadgeteer対応のボードであれば、それは.NET Micro Frameworkが動き、さらに.NET Gadgeteerにも登録されているボードということになります。別々の関係というよりも含有関係になるので単なる.NET Micro Framework対応のボードよりも,NET Gadgeteer対応のボードの方が何かと便利です。

.NET Gadgeteerデザイナ

 .NET Gadgeteerのいいところは.NET GadgeteerデザイナによりVisual Studio上でメインボードや各種モジュール(メインボードと接続可能なセンサーなどの部品)との接続を設計できる点です。例えば今回のサンプルでは次のような接続を行います。

図6 .NET Gadgeteerデザイナ
図6 .NET Gadgeteerデザイナ

 左上の赤いモジュールはUSBモジュールのUSB Client DPです。USBポートは電源供給やPCからアプリの転送、Visual Studioからのリモートデバッグなどにも使用できます。USB Client DPは1番ソケットに接続します。なお、PCからアプリ転送後は不揮発性メモリ上にアプリが配置されるのでPCからUSBを切り離して電源につなぎかえれば自動的にアプリがブートします。

 メインボードの右横にあるのがLANモジュールのethernetJ11Dです。このモジュールは7番ソケットに接続します。今回は有線LANを使いましたが、LANモジュールの代わりにWiFiモジュールを使ってさらにUSB Client DPへの電源供給をモバイルバッテリーなどにすればコードレスセンサーが完成します。

 ボードの左側にあるのが今回のセンサーである温湿度モジュールのtempHumidS170になります。これを4番ソケットに接続します。

実機の配線

 .NET Gadgeteerのいいところはコード上の表現だけではありません。デザイナ上できれいに配置しておけば、大きさなどの比率もあっていますので、実際のメインボードとモジュールを配置して同じように配置と配線できます。

図7 メインボードとモジュール
図7 メインボードとモジュール

センサー値の取得

 デザイナ上で配線と実際のモジュールの配線を同じにすることで、例えばtempHumidS170からセンサー値を取得したいときは、コード上で「4番ソケットから取得」ではなく「tempHumidS170から取得」のように記述が可能になります。

リスト1 センサー値の取得
Private Sub MeasureTimer_Tick(timer As GT.Timer) Handles MeasureTimer.Tick
    Me.MeasureTimer.Stop()
    Dim th = tempHumidSI70.TakeMeasurement       '(1)
    SyncLock (Me)
        Me.LastTemperature = th.Temperature      '(2)
        Me.LastHumidity = th.RelativeHumidity    '(3)
    End SyncLock
    Me.MeasureTimer.Start()
End Sub
  • (1)センサー値の取得
  • (2)温度の取得
  • (3)湿度の取得

センサー値をクラウド側に送信

 Microsoft Azure Mobile Servicesとの間はREST/JSONでデータ送信を行います。そのままコードを書いて実装してもいいのですが.NET Micro Framework向けの便利なライブラリがGitHubにありますので、それを使って省力化します。

図8 ms-iotkithol-jp/Library/EGIoTKit.Utility
図8 ms-iotkithol-jp/Library/EGIoTKit.Utility

 GitHubからzipファイルを取得したら解凍してEGIoTKit.Utilityをプロジェクトに追加して参照設定を行います。

図9 ソリューション構成
図9 ソリューション構成

 準備が完了したらProgram.vbファイルにコードを記述します。まずはLANモジュールの回線をオープンします。

リスト2 LAN接続
If (Not ethernetJ11D.NetworkInterface.Opened) Then    '(1)
    ethernetJ11D.NetworkInterface.Open()              '(2)
End If
  • (1)オープンされていないかを確認
  • (2)オープンされていなかったらオープン

 次にデータ送信する部分を作成します。

リスト3 データ送信
Mainboard.SetDebugLED(True)                                                          '(1)
Try
    Dim request = CType(HttpWebRequest.Create(UrlString + "tables/Item"), HttpWebRequest)
    Dim json = New EGIoTKit.Utility.SimpleJSON()
    request.Headers.Add("X-ZUMO-APPLICATION", "pQLVzEcLxynxQpHscpTmYtCGbqojTr76")    '(2)
    request.Accept = "application/json"
    request.ContentType = "application/json"
    request.Method = "POST"

    json.Add("id", "")                                 '(3)
    json.Add("DeviceId", DeviceId.ToString())          '(3)
    SyncLock (Me)                                      '(3)
        json.Add("Temperature", Me.LastTemperature)    '(3)
        json.Add("Humidity", Me.LastHumidity)          '(3)
    End SyncLock                                       '(3)
    Dim JsonStringParams = json.GetResult                                     '(4)
    Dim postDataBytes As Byte() = Encoding.UTF8.GetBytes(JsonStringParams)    '(4)
    request.ContentLength = postDataBytes.Length                              '(4)
    Using reqStream = request.GetRequestStream()                              '(4)
        reqStream.Write(postDataBytes, 0, postDataBytes.Length)               '(4)
    End Using                                                                 '(4)
    Using res = CType(request.GetResponse, HttpWebResponse)                   '(5)
        If (res.StatusCode = HttpStatusCode.OK) Then                          '(6)
            Using reader = New StreamReader(res.GetResponseStream())          '(6)
                Dim message = reader.ReadToEnd()                              '(6)
        Debug.Print(message)
End Using
        End If
    End Using
Catch ex As Exception
    Debug.Print(ex.Message)
End Try
Mainboard.SetDebugLED(False)                           '(7)
  • (1)メインボード上のLEDを点灯してデータ送信開始を合図
  • (2)アプリケーションキーを設定
  • (3)JSONデータを作成
  • (4)JSONデータを本文として設定
  • (5)POSTメソッドを実行
  • (6)応答内容を取得

実行

 PCとUSBで接続してVisual Studioで実行を開始すると、まず、メインボードへアプリを転送し、その後に実行が開始されます。その流れはイミディエイトウィンドウに表示されます。

図10 実行結果
図10 実行結果

 クラウドまで正しくデータが届いていれば、Azure管理ポータルで送信されてきたデータが表示できます。

図11 テーブル参照
図11 テーブル参照

情報活用端末の作成

 それでは、いよいよComponentOne Studio Chart for WinRT XAMLを使った温湿度の時系列グラフ表示アプリを作成してみましょう。

表示部分の作成

 Windowsストアアプリを選択して新規プロジェクト作成すると、ツールボックスにはすでにComponentOne Studioのコンポーネントが登録されています。ツールボックスから「C1Chart」をXAMLデザイナにドラッグ&ドロップすれば必要な設定込みで配置が完了します。

 あとはX軸を日時表示したり、Y軸を2軸にして温度と湿度を表示するように調整します。

リスト4 データ送信
<Chart:C1Chart ChartType="Line">
    <Chart:C1Chart.View>
        <Chart:ChartView>
            <Chart:ChartView.AxisX>
                <Chart:Axis AnnoFormat="yyyyMMdd HH" AnnoAngle="-90" IsTime="True"/>  <!--(1)-->
            </Chart:ChartView.AxisX>
            <Chart:ChartView.AxisY>
                <Chart:Axis AnnoFormat="#0.##0">                                      <!--(2)-->
                    <Chart:Axis.Title>
                        <TextBlock Text="温度" />
                    </Chart:Axis.Title>
                </Chart:Axis>
            </Chart:ChartView.AxisY>
            <Chart:ChartView.Axes>
                <Chart:Axis Name="H" AxisType="Y" Position="Far" AnnoFormat="#0.##0"> <!--(3)-->
                    <Chart:Axis.Title>
                        <TextBlock Text="湿度" />
                    </Chart:Axis.Title>
                </Chart:Axis>
            </Chart:ChartView.Axes>
        </Chart:ChartView>
    </Chart:C1Chart.View>
    <Chart:C1Chart.Data>
        <Chart:ChartData ItemsSource="{Binding Items}">
            <Chart:ChartData.Children>                                                <!--(4)-->
                <Chart:XYDataSeries  Label="Temperature" ValueBinding="{Binding Temperature}" XValueBinding="{Binding __createdAt}"/>
                <Chart:XYDataSeries  Label="Humidity" ValueBinding="{Binding Humidity}" XValueBinding="{Binding __createdAt}" AxisY="H"/>
            </Chart:ChartData.Children>
        </Chart:ChartData>
    </Chart:C1Chart.Data>
    <Chart:C1ChartLegend Position="Bottom"/>
</Chart:C1Chart>
  • (1)X軸が時間であることを指定
  • (2)Y軸の1つ目を気温として指定
  • (3)Y軸の2つ目を湿度として指定
  • (4)データを表示するクラスとプロパティを指定してBinding

 これで表示部分は完成です。

ロジック部分の作成

 次にMicrosoft Azure Mobile Servicesからデータを取得する部分を作成します。ソリューションエクスプローラでプロジェクトを右クリックして[NuGetパッケージの管理]メニューをクリックし、NuGetダイアログで「Azure Mobile Services」を検索して追加します。

リスト5 データ受信
Public Items As New ObservableCollection(Of Item)               '(1)

Public Async Function GetData() As Task
    Using mobileService = New MobileServiceClient(UrlString)    '(2)
        Dim qTable = mobileService.GetTable(Of Item)()         '(3)
        Dim recs = Await qTable.ReadAsync                       '(4)
        Me.Items.Clear()
        For Each rec In recs
            Me.Items.Add(rec)                                   '(5)
        Next
    End Using
End Function
  • (1)データ表示用クラスの定義
  • (2)Mobile Services(cz1501service)との接続
  • (3)テーブルの指定(取得クラス名はテーブル名と同じにする)
  • (4)データ取得
  • (5)取得したデータを表示用クラスに設定

 あとは表示部分とロジック部分をつなげるViewModel部分を作成すれば完成です。

実行

 実行してみるとデバッグ中や実行確認を行っていてデータ抜け(グラフでまっすぐ右下がりしている部分)している部分もありますが、急速に気温と湿度が下がっているのが一目で分かります。また湿度はあるところから横ばいで必ずしも気温と連動しているばかりではないということも発見できます。

図12 実行結果
図12 実行結果

 自室内なのですがエアコンを使っていない部屋なので、ほぼ外気の影響下にある測定結果といえるでしょう。

まとめ

 このようにセンサーを使ってクラウドで収集してタブレットで確認するということは数年前まで個人ベースで行えることではありませんでした。最近の傾向が後押ししていることは確実ですが、センサー&デバイスを駆使してIoTに注目していくと、やはり、データのビジュアライズというのが非常に重要であることが再確認できます。

 タブレットと相性のいいWindowsストアアプリで見栄えの良いグラフが表示できるComponentOne Studio Chart for WinRT XAMLが活躍する曲面は今後ますます増えていく事でしょう。

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 初音玲(ハツネアキラ)

     国内SIerのSEでパッケージ製品開発を主に行っており、最近は、空間認識や音声認識などを応用した製品を手掛けています。  個人的には、仕事の内容をさらに拡張したHoloLensなどのMRを中心に活動しています。  Microsoft MVP for Windows Development...

All contents copyright © 2005-2020 Shoeisha Co., Ltd. All rights reserved. ver.1.5