IoT Kitハンズオンセミナーで実演している、センサーデータ収集とExcelによる表示の仕組みについて
2月のデベロッパーサミットのハンズオンで初披露し、3/15のIoTあるじゃん(https://www.facebook.com/groups/ioytjp/)コミュニティ設立イベントでのハンズオン、それと、最近地方で開催しているIoT Kitハンズオンセミナーで、もれなく使っている、参加者の皆さんが各自のGR SAKURA+センサーボードやGR PEACH+センサーボードでの実習で計測したデータを、集めて、ExcelのPower Mapでの表示に関する説明です。
この右側の赤の点線で囲んだ部分です。
この部分は大きく分けて二つのパーツから構成されています。一つ目は、受講者各自が作成したASP.NET WebアプリからSignalRで送信されたセンサーデータを受信しAzure StorageのTableに格納する部分、二つ目は、そのTableからExcel Power Queryでデータを取り出し、Excel PowerMapで表示する部分です。
1つ目は図の4番目のステップで、SignalRというプロトコルを使って、私が作って動かしているASP.NET Webアプリケーションにデータを送っています。作り方は、https://aka.ms/IoTKitHoL から公開中のハンズオントレーニングのStep 4 表示の、4.1節で解説している方法で作っています。手順書を見ながら以下の説明を読んでください。
SignalR?なんか難しそう…と思っている方、大丈夫です。簡単です。先ず、ハンズオントレーニングのStep1 接続の1.1節で説明された方法で、Azure上にWebアプリを作成します。出来上がったら、Step 4表示の4.1節で説明された方法で、SignalRのハブを”SensorHub”という名前で作成します。
で、ここでは、Azure Storageを使うので、NuGetパッケージで、Windows Azure Storeage SDKをインストールします。やり方は、ハンズオントレーニングのStep 3蓄積の1.2、1.3節に書いてあります。Azure上でのストレージアカウントの作成や、Web.configへのストレージへのConnectionString設定などは手順書を見て適宜やってください。
作成したSensorHubクラスに、以下の様なメソッドとクラスを追加します。
public void Update(SensorReading data)
{
Clients.Others.NotifyTemperature(data);
var storeCS = CloudConfigurationManager.GetSetting("StorageConnectionString");
var storageAccount = CloudStorageAccount.Parse(storeCS);
var tableClient = storageAccount.CreateCloudTableClient();
var sensorReadingTable = tableClient.GetTableReference("SensorReading");
sensorReadingTable.CreateIfNotExistsAsync().Wait();
var query = new TableQuery<SensorReadingTable>().Where(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, data.DeviceId));
bool unstored = true;
foreach (var stored in sensorReadingTable.ExecuteQuery(query))
{
// 登録されていたら新しい温度で更新
stored.LastUpdatedTime = data.Timestamp;
stored.SensorValue = data.Temperature.ToString();
stored.SensorValueD = data.Temperature;
stored.Count = stored.Count + 1;
sensorReadingTable.ExecuteAsync(TableOperation.Replace(stored)).Wait();
unstored = false;
}
if (unstored)
{
// 未登録なら、新しいレコードを追加
var sr = new SensorReadingTable(data.DeviceId, DateTime.Now);
sr.Timestamp = data.Timestamp;
sr.SensorType = "Temperature";
sr.SensorValue = data.Temperature.ToString();
sr.SensorValueD = data.Temperature;
sr.CreatedTime = data.Timestamp;
sr.LastUpdatedTime = data.Timestamp;
sr.Count = 1;
sensorReadingTable.ExecuteAsync(TableOperation.Insert(sr)).Wait();
}
}
public class SensorReading
{
public string DeviceId { get; set; }
public DateTime Timestamp { get; set; }
public double Temperature { get; set; }
}
public class SensorReadingTable : TableEntity
{
public SensorReadingTable(){
}
public SensorReadingTable(string deviceId, DateTime time)
{
PartitionKey = deviceId;
RowKey = deviceId + time.Ticks.ToString();
}
public string SensorType { get; set; }
public string SensorValue { get; set; }
public double SensorValueD { get; set; }
public DateTime CreatedTime { get; set; }
public DateTime LastUpdatedTime { get; set; }
public int Count { get; set; }
}
これで、「4.SignalR送信用Webアプリ作成」で追加したコードが実行され、SignalRでセンサーデータが送信されたときに受信するHubのロジックが出来上がります。一見複雑そうですが、やっていることは簡単で、Updateメソッドの引数dataが受講者が作ったWebアプリから送られてくるデータ、それを受けて、テーブルを準備して、送られてきたDeviceIdに関するセンサーデータのレコードがあれば、最新情報で更新、なければ新規にレコードを追加、という処理です。
後は、Startup.csにあるConfigurationメソッドを
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
app.MapSignalR();
}
の様にapp.MapSignalR()を追加すれば実装終了。あとはVisual StudioでAzureに発行すれば準備完了。受講者のGR SAKURAやGR PEACH、FEZで各自のMobile Serviceにセンサーデータを送ると、このHubのUpdateメソッドがどんどんコールされ、各参加者毎の計測データが逐次蓄積されていきます。SensorReadingTableのプロパティ群(PartitionKey、RowKey、SensorType、SensorValue(文字列形式)、SensorValueD(数値形式)、CreatedTime、LastUpdatedTime、Count)がテーブルの各カラムになります。PartitionKeyにはDeviceIdが格納されます。
3/15に実施したGR PEACHを使ったハンズオンの場合は、https://1drv.ms/1xuYj1k からGR SAKURAを使ったハンズオン資料をダウンロードして、Mobile Service、Webアプリを作ってください。WebアプリのSignalRの転送先のURLを変えれば動きます。
修正が終わったらAzureに”発行”してください。
GR PEACHやGR SAKURAで温度を測ってクラウドに送信してください。温度を送信するとテーブルが出来上がります。逆にいうと、温度が送られない限りテーブルは作成されないので、発行したら、必ずボードをイーサネットに接続して温度センサーの値をクラウドに送ってくださいね。
次にExcelでの表示です。これはハンズオントレーニングのStep 5 分析の1.1、1.2で解説している手順がベースになります。Power Qeury、Power Mapのセットアップはこちらの手順書を参考にしてください。
Power QueryとPower Mapのアドインを入れたら、ExcelでHeatmapを作っていきます。
先ず、Excelを起動して、新しいシートを作成します。
リボンのPOWER QUERYタブをクリックします。
図の様に”Azureからインポート”をクリックし、”Microsoft Azureテーブルストレージから”を選択します。
ストレージアカウント名を入力して”OK"をクリックするとナビゲーターペインにテーブル名が表示されます。※今回は事情により”SensorReading2”がターゲットとしています。
インポートするテーブルをクリックすると、クエリエディターでAzureストレージに格納されているデータが表示されます。
Contentの右側の矢印ボタンをクリックするとSensorReadingTableで定義されたプロパティ名のデータが表示されます。クエリエディタを閉じればクラウド上のデータがダウンロードされて表示されます。
次に、POWER PIVOTタブをクリックして、
データモデルに追加をクリック。で、テーブルツールを閉じます。
各参加者の温度を棒グラフで表示する場所を次に定義します。
ここでは簡単のため4人の場合を想定しています。要は位置をPositionというシートにべた決めってことです。図は左上を原点(0,0)として、右方向がX軸の正方向、下方向がY軸の正方向です。01、02、03、04というラベルがついたセルの100×100ピクセルの画像を想定しています。DeviceIdと各座標を書いたら、マウスで選択して、POWER PIVOTの”データモデルを追加”をクリックします。
テーブルの作成ダイアログの”先頭行をテーブルの見出しとして使用する”にチェックを入れて”OK”をクリックします。
Power Pivot for Excelのページが表示されるので、”ダイアグラムビュー”をクリックします。
表示されたら、テーブルの名前を変えて、PositionのDeviceIdとSensorReadingのPartitionKeyをつなぎます。
これでPower Mapで表示するためのデータモデルが完成しました。POWER PIVOTのページを閉じて、
挿入タブをクリックし、”マップ”→”Power Mapの起動”を選択します。
図の様に、”シーンのオプション”をクリックして、表示する画像を選択します。
背景画像を設定し、”ピクセル領域”ボタンをクリックして”完了”をクリックして背景画像が設定されます。
位置情報は、
PositionのX,Yにチェックを入れて、ペインの下でX座標とY座標にマップします。
SensorValueD、Timestampにチェックを入れて完成です。
リボンの”データの更新”をクリックすると最新の情報で表示が更新されます。時系列でのアニメーションも可能です。
さて、クラウドからのデータのダウンロードですが、定期的に更新した場合には、以下の設定をしてください。