GadgeteerとAzureで作る簡易温度計 - Part 1

最近方々で見せている、GadgeteerとAzure、Store Apps、そしてExcel Power Query/Viewを組合せた温度計デモを紹介します。これ、GadgeteerとAzureの部分だけだと、20~30分で完成します。

システム構成は、

です。.NET Gadgeteerで測った温度、湿度をAzureのMobile Serviceのテーブルに格納しながら、Web Siteに転送して、SignalRに送る。Mobile ServiceのテーブルからExcel Power Queryでデータをダウンロードしてグラフ化する。というもの。

Gadgeteerは、以下の部品を使います。

リレーは、電気屋さんで買ってきた100V用のタップを写真の様にケーブル接続しておきます。※Relay X1 Moduleの裏側は、配線ピンむき出しなのでくれぐれも感電しないように注意しましょう。

開発の手順は以下の通りです。

  1. Azure Mobile Serviceを作成
  2. Gadgeteerのアプリ開発
  3. Excel Power Queryで可視化
  4. Excel Power Viewで分析
  5. Azure Web Siteを作成
  6. Azure Mobile Serviceを改造 - Web Siteへのデータ転送
  7. Store アプリ開発
  8. Azure Mobile Serviceを改造 - Push 通知の追加

では早速最初から解説していきます。

1. Azure Mobile Service を作成

https://manage.windowsazure.com で、Azureの管理ポータルを開きます。※まだAzureのサブスクリプション契約をしていない方は、https://azure.microsoft.com から契約しちゃってください。

左側のタブで”モバイルサービス”を選択し、左下の新規ボタンをクリックします。

モバイルサービスの名前を付けて、データベースの設定などを行って、作成完了です。クラウド側で準備ができると、モバイルサービスのリストに作成したサービスが表示されます。作成されたサービスをクリックします。

表示されたページで、上手の上から、クリックして選択していって、下の黒い帯で隠れている部分に表示されるC#のコードをテキストファイルにコピペしておきます。このコードに含まれる、URLと、キーは、後程、.NET Gadgeteerの開発で使います。

このステップはこれで完了です。

2. Gadgeteerアプリの開発

次は、Gadgeteerボードで、温度と湿度を測ってAzure Mobile Serviceにデータを定期的にアップロードしながら、30度を超えたらリレーをONにするアプリを開発します。

※開発環境がアップデートされた関係で、以下の記述は古くなっています。最新は、https://blogs.msdn.com/b/hirosho/archive/2014/12/24/logicoffeztemphumid20141224.aspx を参考にしてくださいまし。

先ず、https://1drv.ms/1rG4JoF からNETMFCloud.zipと、Microsoft.Azure.Zumo.MicroFramework.zipの二つのZIPファイルをダウンロードして、どこか適当なところに解凍してください。
※これらのファイルはあくまでもサンプルです。自己責任で使ってくださいね。ちなみに、Microsoft.Azure.Zumo.NetMicroFrameworkは、Gitで公開されている、https://github.com/nickharris/Microsoft.Azure.Zumo.MicroFramework のコードを若干修正、機能追加したものです。

それから、予め、https://blogs.msdn.com/b/hirosho/archive/2014/06/04/getting_5f00_started_5f00_net_5f00_micro_5f00_framework_5f00_and_5f00_gadgeteer_5f00_again.aspx を参考にして、Gadgeteer開発環境を準備しておいてください。

さてと、Visual Studio 2012を起動して、メニューから、”ファイル”→”新規作成”→”プロジェクト”を選択します。Visual C#のGadgeteerカテゴリーで、”.NET Gadgeteer Application”を選択して、プロジェクトを作成します。表示されたダイアログ、

FEZ CerbuinoNetを選択して”Create”ボタンをクリックします。

 プロジェクトが作成され、Program.gadgeteerというファイルが開きます。ツールボックスから、”Relay X1”、”TemperatureHumidity"を、赤いCPUボードが表示されたエディタ領域にドラッグ&ドロップします。そして、エディタ上で右クリックして、”Connect All Module”を選択してください。

この図に従って、TemperatureHumidityセンサーと、リレーをボードにコネクタでつなぎます。

次に、ソリューションフォルダーで、作成したソリューションに、先ほどOneDriveからダウンロードした二つのプロジェクトを追加します。ソリューションエクスプローラで、ソリューションを右クリックし、”追加”→”既存プロジェクト”を選択し、Microsoft.Azure.Zumo.MicroFramework.csprojとNETMFCloud.csprojを選択すれば追加可能です。

更に、Gadgeteerプロジェクトの”参照設定”フォルダーを右クリックし、”参照の追加”で、この二つのプロジェクトを選択し、参照設定に追加してください。

次はコーディングです。Program.csファイルを開いてください。

先ずは、ファイルの先頭のusing宣言がされている最後に、

using Microsoft.WindowsAzure.MobileServices.Utility;

を加えます。

次に、Proguramクラスのメンバーとして、

        SensorMobileService mobileService;
        double lastTemp;
        double lastHumidity;

を追加します。2番目と3番目のdouble変数は、センサーで計測した値を一時的に保持しておくためのバッファーです。
次にProgramStarted()メソッドに、以下のコードを追加します。

            // ① ネットワーク初期化
            var ipAddress = NETMFCloud.NetworkUtility.Current.SetupNetwork();
            Debug.Print(ipAddress);

            // ② Mobile Serviceアクセスライブラリ初期化
            mobileService = new SensorMobileService("URL", "KEY");

            // ③ 温度湿度センサー初期化
            temperatureHumidity.MeasurementComplete += temperatureHumidity_MeasurementComplete;
            temperatureHumidity.StartContinuousMeasurements();

            // ④ タイマー初期化
            var timer = new GT.Timer(2000);
            timer.Tick += timer_Tick;
            timer.Start();

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

赤字で書いた②のURLとKEYは、ステップ1で記録しておいたMobile ServiceのURL(httpsをhttpに書き換えること)とアクセスキーを記入してください。ボードで実行した時、①のipAddressが”0.0.0.0"だった場合は、ネットワークに上手く接続できていない証拠なのでイーサネットケーブルがボードに挿入されているか、イーサネットケーブルがインターネットにつながっているか確認してください。③のコードで、温度湿度センサーが値を計測するたびに、temperatureHumidity_MeasurementCompleteメソッドがコールされるようになります。更に④で、2秒単位でtimer_Tickメソッドがコールされるようになります。

初期化コードは以上です。

次に、温度湿度センサーのイベントハンドラですが、

        void temperatureHumidity_MeasurementComplete(TemperatureHumidity sender, double temperature, double relativeHumidity)
        {
            lock (this)
            {
                lastTemp = temperature;
                lastHumidity = relativeHumidity;
            }
            if (temperature > 30)
            {
                relay_X1.TurnOn();
            }
            else
            {
                relay_X1.TurnOff();
            }
        }

このようにコーディングしてください。計測した値は引数で渡されるので、lastTemp,lastHumidityに格納しておきます。代入ロジックをlock(this){...}で囲んでいるのは、このハンドラがコールされるスレッドと、タイマーハンドラ―のスレッドが別物だからです。温度が30度を超えた場合にリレーをONに、30度以下の場合は、リレーをオフにするコードは説明しなくても明快ですね。

次にタイマーハンドラ―です。

        void timer_Tick(GT.Timer timer)
        {
            lock (this)
            {
                var tempString = mobileService.RoundDecimalPoint(lastTemp, 5);
                mobileService.Upload("gadgeteer", "temperature", tempString);
                var humidityString = mobileService.RoundDecimalPoint(lastHumidity, 5);
                mobileService.Upload("gadgeteer", "humidity", humidityString);
            }
        }

RoundDecimalPointは、倍精度の数値を指定の桁数に丸めるユーティリティメソッドです。全体をlock(this){...}で囲んでいるのは、センサーのハンドラ―とこのスレッドが異なるので排他しているのと、アップロードに時間がかかった場合のこのメソッドへの再入を防いでいます。Uploadメソッドはリエントラントではないのでご注意ください。

Gadgeteerアプリの開発はこれでお終い。あとは、ハードウェアをUSBでPCにつないで、F5デバッグ実行するだけで、Mobile Serviceにデータを2秒単位でアップロードを始めます。この作業、慣れると、5分ぐらいで終了します。実際にデータがMobile Serviceのテーブルに格納されているかどうかは、Azureの管理ポータルのモバイルサービスのテーブルを実際に開いてみて確認してみてください。

ここまでの作業で、まぁ、20分ぐらい?

3. Excel Power Query/View で可視化

さて、ステップ2までだと、単に蓄積するだけですね。これ以降、色々と加えていきます。先ずは、皆さんが普段よく使っているExcelによる可視化をしてみます。先ず、ExcelにAzureのテーブルからデータをダウンロードするアドオン Excel PowerQueryを、

https://www.microsoft.com/ja-jp/download/details.aspx?id=39379

からダウンロードしてインストールしてください。

次に、後(Part 2以降)で色々試すためにPOWER VIEWを有効化しておきます。
Excelを起動してファイルを一つ作り、メニューのファイルタブをクリックして、左下の”オプション”を選択します。開いたダイアログで下図の様に、左のパンで”アドイン”を選択し、下の”管理”で”COMアドイン”を選択し、”設定”をクリックします。

”Microsoft Office Power Pivot for Excel 2013”と”Power View”にチェックを入れて”OK”をクリックします。

Excelのシートで、”POWER QUERY”タブを選択します。

リボンの”データベースから”をクリックし、”Windows Azure SQL データベースから”を選択します。表示されたダイアログの”サーバー”に、Azureの管理ポータルの”SQLデータベース”タブをクリックして、センサーデータを格納しているデータベースを選択し、”データベースに接続する”の欄に表示された、XXXX.database.windows.net をコピー&ペーストします。認証を経て、ナビゲータに表示された、テーブルの一覧(モバイルサービス名.テーブル名)からダウンロードしたいテーブルを選択します。これで、計測&蓄積されたデータがダウンロードできました。しかし、実はMeasuredValueは、汎用性を考えて文字列型になっているので、右端のMeasuredValueを右クリックして、”型の変更”を選択、”10進数”に変えます。リボンの左側の”適用して閉じる”をクリックします。これでAzure Mobile Serviceのテーブルデータがダウンロードされるので、後は、数値の部分をグラフ化などすれば、可視化が完了します。

これで、Part 1はお終い。続きはまた後ほど。

待ってるぜ、ちゃお(By 林風)