開発部の金子です。
今回はWMC-600+FASTIO+サマリ―カスタマイズ機能を組み合わせて、
在室状況管理の仕組みを作ってみました。
WMC-600とは
4.3インチの液晶画面を搭載した親機が920MHz帯特定小電力無線を用いて子機からセンサー情報(人感、開閉、温湿度等)を自動で収集します。
収集したデータを内蔵のLTE通信モジュールを介しクラウドと連携することができる製品です。
以下のサイトをご覧ください。
サマリ―カスタマイズ機能
FASTIO LOGGERのサマリー表示にはカスタマイズ機能があります。
カスタマイズ画面
詳しくは割愛しますがざっくり説明するとJavascriptとCSSを独自に記述し読み込ませることで、従来の表示をカスタマイズしてオリジナルの見た目のサマリー画面を作成できる機能です。
画像などのファイルはまとめてZIP形式で圧縮しアップロードすることで利用が可能になります。
今回はこの機能を用いてWMC-600から取得した
- ドアの開閉
- 在室/空室
- 部屋の窓1~4の開閉
- 室温
- 湿度
- Co2濃度
の6項目のデータを可視化してみます。
データの取得
サマリ―カスタマイズ画面の入力欄に以下のようなプログラムを記述していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
var regular_data_tid = [tid];//[tid]は端末IDに置き換わります。 //指定された端末から最新データを取得します。 var url = "/?act=api_get_latest_data&term_id="+regular_data_tid; $.ajax({ type: "GET", url: url, dataType: "json", success: function(hRes){ if(hRes["result"] == "Error"){ $("#message_wrap").html(hRes["detail"]); return; } var aRes = hRes["response"]; if(aRes.length!=0){ // aResにはWMC-600が計測したデータが格納されています。 // ここで取得したデータを分解し可視化していきます。 // .... } } }); |
aResには以下のようなデータが格納されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
{ "att_serial": "1", "no": "1012", "name": "在室状況(入口)", "unit": "", "border_status": "0", "graph_sort": "1", "graph_type": "line", "graph_color": "7BB661", "graph_thickness": "1", "graph_ymin": "0", "graph_ymax": "5", "value": "空室", "date_measured": "" }, { "att_serial": "1", "no": "1006", "name": "入口ドア", "unit": "", "border_status": "0", "graph_sort": "2", "graph_type": "line", "graph_color": "C3682A", "graph_thickness": "1", "graph_ymin": "0", "graph_ymax": "5", "value": "閉", "date_measured": "" }, //以下略 |
これらのデータから必要な情報を抜き出し、以下のように変数に格納します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
// 計測データの取得 var occupancySt; var entranceDoorSt; var windowLock1; var windowLock2; var windowLock3; var windowLock4; var temperature = 0; var tempCount = 0; var humidity = 0; var humidityCount=0; var co2 = 0; for(var i in aRes) { if(aRes[i].no=="1012"){ //在室状況(入口) occupancySt = aRes[i].value; } if(aRes[i].no=="1006"){ //入口ドア entranceDoorSt = aRes[i].value; } if(aRes[i].no=="3"){ //温度(入口) temperature += parseFloat(aRes[i].value); tempCount++; } if(aRes[i].no=="4"){ //湿度(入口) humidity += parseFloat(aRes[i].value); humidityCount++; } if(aRes[i].no=="1007"){ //窓1施錠 windowLock1 = aRes[i].value; } if(aRes[i].no=="8"){ //温度(窓1) temperature += parseFloat(aRes[i].value); tempCount++; } if(aRes[i].no=="9"){ //湿度(窓1) humidity += parseFloat(aRes[i].value); humidityCount++; } if(aRes[i].no=="1008"){ //窓2施錠 windowLock2 = aRes[i].value; } if(aRes[i].no=="13"){ //温度(窓2) temperature += parseFloat(aRes[i].value); tempCount++; } if(aRes[i].no=="14"){ //湿度(窓2) humidity += parseFloat(aRes[i].value); humidityCount++; } if(aRes[i].no=="1009"){ //窓3施錠 windowLock3 = aRes[i].value; } if(aRes[i].no=="18"){ //温度(窓3) temperature += parseFloat(aRes[i].value); tempCount++; } if(aRes[i].no=="19"){ //湿度(窓3) humidity += parseFloat(aRes[i].value); humidityCount++; } if(aRes[i].no=="1010"){ //窓4施錠 windowLock4 = aRes[i].value; } if(aRes[i].no=="23"){ //温度(窓4) temperature += parseFloat(aRes[i].value); tempCount++; } if(aRes[i].no=="24"){ //湿度(窓4) humidity += parseFloat(aRes[i].value); humidityCount++; } if(aRes[i].no=="27"){ //温度(中央) temperature += parseFloat(aRes[i].value); tempCount++; } if(aRes[i].no=="28"){ //湿度(中央) humidity += parseFloat(aRes[i].value); humidityCount++; } if(aRes[i].no=="1"){ //人感(入口) } if(aRes[i].no=="26"){ //Co2 co2 = aRes[i].value; } } //温度と湿度は入口、各窓、部屋の中央で計測している為、平均とします。 temperature = temperature/tempCount; humidity = humidity/humidityCount; |
可視化
さて、ここまでで実際の計測データが取得ました。
次に可視化するための絵を用意します。
画面に必要な要素としては
- 会議室が利用中かどうかが一目で判断できる。
- ドアの開閉(意味合いとしては施錠されているか否か)状態が分かる。
- 会議室の窓の閉め忘れがないか判断できる。
- ついでに会議室の『空気も見える化』
です。
今回は製品として世に出すというよりコンセプトモデル的な要素が強いため自由にデザインしてみました。
手書きの図案をillustratorで書き起こし、全体像とドア/窓の開閉状態の部品を作成しました。
部品一覧
室温などの数字系部品についてはCSSで装飾した通常テキストで配置する事にしましょう。
グラフィックの配置
部品は用意できましたので配置をしていきます。
配置はJavascript+CSSで動的に行います。
要素ごとにDIVを用意しそれらをCSSのpositionを用いて目的の位置に配置します。
配置する要素の状況(開/閉など)を条件にDOMに設定するClassを変え、見た目部分をCSSで制御します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
var dom_custom = $("<div></div>", { id : "custom" }); var domInner = $("<div></div>", { class : "container" }); //空室/在室 if(occupancySt=="空室"){ domInner.append("<div class='vacancy'></div>"); }else{ domInner.append("<div class='presence'></div>"); } //ドア if(entranceDoorSt=="閉"){ domInner.append("<div class='door_cl'></div>"); }else{ domInner.append("<div class='door'></div>"); } //窓1 if(windowLock1=="閉"){ domInner.append("<div class='win1_cl'></div>"); }else{ domInner.append("<div class='win1'></div>"); } //窓2 if(windowLock2=="閉"){ domInner.append("<div class='win2_cl'></div>"); }else{ domInner.append("<div class='win2'></div>"); } //窓3 if(windowLock3=="閉"){ domInner.append("<div class='win3_cl'></div>"); }else{ domInner.append("<div class='win3'></div>"); } //窓4 if(windowLock4=="閉"){ domInner.append("<div class='win4_cl'></div>"); }else{ domInner.append("<div class='win4'></div>"); } //平均温度(toFixedをしないと小数点以下が酷いことになるので注意) domInner.append("<div class='nValue temperature'><span class='label'>平均室温</span><strong>"+temperature.toFixed(2)+"</strong><span class='unit'>℃</span></div>"); //平均湿度(上に同じ) domInner.append("<div class='nValue humidity'><span class='label'>平均湿度</span><strong>"+humidity.toFixed(2)+"</strong><span class='unit'>%</span></div>"); //Co2濃度 domInner.append("<div class='nValue co2'><span class='label'>Co2濃度</span><strong>"+co2+"</strong><span class='unit'>ppm</span></div>"); //タイトル domInner.append("<div class='title'>5階会議室利用状況</div>"); dom_custom.append(domInner); $("div#contentInner").append(dom_custom); |
CSSは以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
#custom{ width:100%; height:768px; background-color:#f2f2f2; background-repeat:no-repeat; background-position:center -60px; background-image:url([curdir]/summary_bg.png); } #custom .container{ width:1024px; height:768px; margin:0 auto; position:relative; } #custom .container div{ background-repeat:no-repeat; background-position:0 0; overflow:hidden; position:absolute; } #custom .container .presence, #custom .container .vacancy{ width:165px; height:358px; top:17px; left:-7px; } #custom .container .presence{ background-image:url([curdir]/presence.png); } #custom .container .vacancy{ background-image:url([curdir]/vacancy.png); } #custom .container .door, #custom .container .door_cl{ width:120px; height:227px; top:101px; left:397px; } #custom .container .door{ background-image:url([curdir]/door_op.png); } #custom .container .door_cl{ background-image:url([curdir]/door_cl.png); } #custom .container .win1, #custom .container .win1_cl{ width:190px; height:296px; top:343px; left:844px; } #custom .container .win1{ background-image:url([curdir]/window1_op.png); } #custom .container .win1_cl{ background-image:url([curdir]/window1_cl.png); } #custom .container .win2, #custom .container .win2_cl{ width:152px; height:228px; top:379px; left:693px; } #custom .container .win2{ background-image:url([curdir]/window2_op.png); } #custom .container .win2_cl{ background-image:url([curdir]/window2_cl.png); } #custom .container .win3, #custom .container .win3_cl{ width:117px; height:174px; top:406px; left:578px; } #custom .container .win3{ background-image:url([curdir]/window3_op.png); } #custom .container .win3_cl{ background-image:url([curdir]/window3_cl.png); } #custom .container .win4, #custom .container .win4_cl{ width:89px; height:134px; top:428px; left:491px; } #custom .container .win4{ background-image:url([curdir]/window4_op.png); } #custom .container .win4_cl{ background-image:url([curdir]/window4_cl.png); } #custom .container .nValue{ font-size:35px; } #custom .container .nValue span.label{ font-size:70%; } #custom .container .nValue span.unit{ font-size:55%; } #custom .container .nValue strong{ padding:0 5px; } #custom .container .co2{ top:489px; left:25px; } #custom .container .temperature{ top: 150px; left: 745px; } #custom .container .humidity{ left: 745px; top: 199px; } #custom .container .title{ font-size: 30px; position: absolute; top: 19px; left: 568px; font-weight: bold; letter-spacing: 4px; border-bottom: 1px solid #333; } |
完成品がこちら
ついでにビューの切り替えボタンなんかも配置していますが完成品は以下になります。
『会議室は使用されていて窓が2か所開いている』ことがぱっと見で把握できます。
逆に「空室なのに窓が開いている」「空室なのにドアが開いている」などが会議室に行かなくとも把握できるので管理も楽々ですね。
おわりに
いかがでしょうか。アイデア次第で色々な用途に対応できる画面を作成できるFASTIO LOGGER サマリ―カスタマイズ機能。
是非ご利用になってみてはいかがでしょうか。