SONY MESHの温度・湿度タグのデータをAWS Amazon ElasticSearchに送信してグラフ化する

# 1.概要
SONY MESHの温度・湿度タグで取得した値をクラウドに送信してグラフ化できるようにします。
クラウドはAWSのAmazon Elasticsearchを使用して、kibanaでデータを可視化します。
前提としてAWS環境はなるべく無料枠で収まる設定になるようにし、送信データ量も個人で試してみるレベルという想定で書いています。

全体のシステム構成としては以下のイメージになります。
![system.png](https://qiita-image-store.s3.amazonaws.com/0/191873/28fa3d38-a572-1ec2-1049-a942774d521d.png)

# 2.環境
実施時の環境は以下の通りです。
## 2.1.AWS環境
Elasticsearchのバージョン 5.3
Kibana Version: 5.3.2
## 2.2.MESHアプリ利用環境
Ipad iOS 10.3.2
MESHアプリ  ver. 1.8.0

# 3.手順
## 3.1.AWS環境
※AWSアカウントは開設済みとします

### 3.1.1. Amazon Elasticsearch環境の準備
Amazon Elasticsearch serviceを開き「**新しいドメインの作成**」を選択。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-24-23_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/2ffba0e0-dcd1-663a-cb32-62f6e7df655d.png)


任意のドメイン名を入力する。ここでは「mydomain」と入力することにする。またElasticsearchのバージョンはデフォルトの5.3のままとする。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-25-18_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/9b70ed94-04e6-91f3-2636-3c080f2a13b7.png)

ノードの設定ではAWS無料利用枠に収まるようにインスタンスタイプを「**t2.small.elasticsearch**」にする。インスタンス数は1、ストレージタイプはEBSでデフォルトのまま。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-25-38_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/8bdb66a5-32fe-7488-a600-73da13811544.png)

EBSボリュームサイズは最小の「**10**」（デフォルト）とする。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-25-43_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/7c3b8888-ee7b-70a7-561c-5720cffdde09.png)

アクセスポリシーの設定ではテンプレートの中から「**特定のIPからのドメインのアクセスを許可**」を選択。自身が使用しているグローバルIPアドレスを入力する。今回はあくまで個人で試すのが目的のため、利用想定としては自分の家からのみアクセスできればよしとする。なお複数のIPアドレスをリスト上で記載することも可能。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-26-4_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/37bd3df2-f565-76f6-1618-6b5d4e012000.png)
 
最後に設定内容に間違いがないか確認したら「**確認**」ボタンを押して完了。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-26-30_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/4737a026-3880-893e-7478-06fc32cae958.png)

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-26-34_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/36c57c81-b052-a38d-9185-ec842a8eee02.png)

### 3.1.2. Amazon Elasticsearchを利用する
Amazon Elasticsearch Serviceを開くと以下のように作成済みのドメインが表示される。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-59-9_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/8422ba33-1f5b-fad3-2ab9-81116b0f6dc1.png)

さきほど作成した「**mydomain**」をクリックすると、以下の画面に遷移し「エンドポイント」にElasticsearchのURLが「Kibana」にデータを可視化してくれるKibanaのURLが書いてある。「エンドポイント」のURLはMESHから温湿度データを送信する際にアクセスするURL。Kibanaはブラウザから温湿度のグラフを見たい時にアクセスするURL。

![SnapCrab_Amazon Elasticsearch Service Management Console と 15 ページ ‎- Microsoft Edge_2017-7-14_14-59-14_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/191873/19a8239e-d6ae-4eda-6ab7-7b431892668a.png)

### 3.1.3. Amazon ElasticSearchにデータを送信する
上記のエンドポイントに対してhttpでPOSTメッセージを送るとAmazonES(Elasticsearch)にデータを蓄えることができる。試してみたい場合、例えば以下のようにJSON形式でデータを送ればよい。

```
curl -XPOST https://search-mydomain-xxx.ap-northeast-1.es.amazonaws.com/indexname/typename/ ¥
-d '{"temp":26.5, "humid":63, "@timestamp":"2017-07-08T10:27:00+0900"}'
```

※温度を`temp`、湿度を`humid`、送信日時を`@timestamp`として格納する場合

### 3.1.4. AmazonESに送信したデータをKibanaで確認する
上記「Kibana」のURLにブラウザでアクセスすると、初回以下のような画面が表示される。
※表示されない場合はメニューの「Management」を選択

![スクリーンショット 2017-07-18 13.44.26.png](https://qiita-image-store.s3.amazonaws.com/0/191873/6429da6a-667d-7d7e-280a-1060cab10544.png)

ここでさきほどcurlコマンドで送信した時に指定したindex（今回は"indexname"）を指定すると「Time-field name」で`「@timestamp」`が以下のように選択できる。

![indexname.png](https://qiita-image-store.s3.amazonaws.com/0/191873/970f60e4-8142-b74a-9c42-aa551db5110c.png)

そして「Create」する。
その後はメニューの「Discover」を選択することで送信されたデータ1つ1つを確認することができる。

以上でAWS側の準備は完了です。

## 3.2.MESHアプリ
次はMESHアプリ側での作業です。
MESHやMESHアプリの基本については以下を参照ください。
MESH
https://meshprj.com/jp/

MESH SDK マニュアル ※要SONY MESH SDKユーザーアカウント
https://meshprj.com/sdk/doc/ja/

MESHの温度・湿度タグを使い、MESH SDKを活用してカスタムタグを作成してAmazonESに温湿度データを送信します。
手順としては以下のようになります。

### 3.2.1. MESHアカウントで以下MESH開発サイトにサインインする
https://meshprj.com/signin/

### 3.2.2. サインインしたら「Create New Tag」を選択
![スクリーンショット 2017-07-18 16.44.06.png](https://qiita-image-store.s3.amazonaws.com/0/191873/af416483-b5e5-8ce1-cc25-10350b8ed285.png)

### 3.2.3. 湿度データ送信用のカスタムタグを作成
任意のカスタムタグの名前をつけます。ここではHumidMonitorとしました。
![スクリーンショット 2017-07-18 18.03.06.png](https://qiita-image-store.s3.amazonaws.com/0/191873/c5b4aaba-72f4-00b0-ba25-96ee44751bdc.png)


「New Function」の左側にある三角を押して詳細設定を開いて、「Execute (0)」をクリック ※New Functionという記載は任意の名前に変更する。ここでは「sendToES」とします。
![スクリーンショット 2017-07-18 16.45.54.png](https://qiita-image-store.s3.amazonaws.com/0/191873/1bbb545e-c348-c2a8-d317-136a3546da54.png)

ここにカスタムタグ実行時のプログラムを書きます
温度・湿度タグから受け取った**湿度データ**をAmazonESに送信するコードは以下になります。

```js
//endpoint
var endPointURL = "https://search-mydomain-xxxx.ap-northeast-1.es.amazonaws.com/indexname/typename/";

var nowdate=new Date();

//年・月・日・曜日を取得する
var year = nowdate.getFullYear();
var month = nowdate.getMonth()+1;
var day = nowdate.getDate();
var hour = nowdate.getHours();
var minute = nowdate.getMinutes();
var second = nowdate.getSeconds();

if ( month < 10 ) {
    month = "0" + month;
}
if ( day < 10 ) {
    day = "0" + day;
}
if ( hour < 10 ) {
    hour = "0" + hour;
}
if ( minute < 10 ) {
    minute = "0" + minute;
}
if ( second < 10 ) {
    second = "0" + second;
}

var nowtime = year + "-" + month + "-" + day + "T" + hour + ":" +
minute + ":" + second + "+0900";

log(nowtime + "  " + messageValues.humidity);

//APIを叩く際のパラメータ
//プロパティの値を渡す
var jsonData = {
    "humid" : messageValues.humidity,
    "@timestamp":nowtime
};

var sendData = JSON.stringify(jsonData);
log(sendData);

ajax ({
    url : endPointURL,
    type : "post",
    data : sendData,
    contentType : "application/json",
    dataType : "json",
    timeout : 5000,
    success : function ( contents ) {
        log("POST success");
        log(JSON.stringify(contents));
    callbackSuccess( {
        resultType : "continue"
        } );
    },
    error : function ( request, errorMessage ) {
        log("POST error");
        log("detail: " +  JSON.stringify(request));
        callbackSuccess( {
            resultType : "continue"
        } );
    }
});

return {
    resultType : "pause"
};
```

### 3.2.4. 温度データ送信用のカスタムタグを作成
同様に再度「Create New Tag」から実施し、**温度データ**を送信するプログラムを書きます。以下がコードです。

```js
//endpoint
var endPointURL = "https://search-mydomain-xxxx.ap-northeast-1.es.amazonaws.com/dataindex/thtype/";

var nowdate=new Date(); 

//年・月・日・曜日を取得する
var year = nowdate.getFullYear();
var month = nowdate.getMonth()+1;
var day = nowdate.getDate();
var hour = nowdate.getHours();
var minute = nowdate.getMinutes();
var second = nowdate.getSeconds();

if ( month < 10 ) {
	month = "0" + month;
}
if ( day < 10 ) {
	day = "0" + day;
}
if ( hour < 10 ) {
	hour = "0" + hour;
}
if ( minute < 10 ) {
	minute = "0" + minute;
}
if ( second < 10 ) {
	second = "0" + second;
}

var nowtime = year + "-" + month + "-" + day + 	"T" + hour + ":" + minute + ":" + second + "+0900";

log(nowtime + "  " + messageValues.temperature);
 
//APIを叩く際のパラメータ
//プロパティの値を渡す
var jsonData = {
    "temp" : messageValues.temperature,
	"@timestamp":nowtime
};

var sendData = JSON.stringify(jsonData);
log(sendData);

ajax ({
    url : endPointURL,
    type : "post",
    data : sendData,
    contentType : "application/json",
    dataType : "json",
    timeout : 5000,
    success : function ( contents ) {
		log("POST success");
		log(JSON.stringify(contents));
		callbackSuccess( {
            resultType : "continue"
        } );
    },
    error : function ( request, errorMessage ) {
		log("POST error");
        log("detail: " +  JSON.stringify(request));
        callbackSuccess( {
            resultType : "continue"
        } );
    }
});
 
return {
    resultType : "pause"
};
```

### 3.2.5. iOSのMESHアプリ上で設定する
以下のようにタイマータグと組み合わせて、以下のようにMESHタグを構成する。

![スクリーンショット 2017-07-18 15.59.37.png](https://qiita-image-store.s3.amazonaws.com/0/191873/9e00131d-820a-b33e-979c-c414ea46b03e.png)

タイマーは1分間隔としています。データ量と精度のバランスを見て間隔は調整してください。
作成したカスタムタグはMESHアプリ上でメニューからダウンロードできます。
※詳細は[MESH SDKマニュアル](https://meshprj.com/sdk/doc/ja/)を参照

以上でMESH側の作業は完了です。

## 3.3. Kibanaでグラフ化された温湿度データを確認する
上記AmazonESの「Kibana」のURLにブラウザでアクセスする。
「Visualize」を選択。
![スクリーンショット 2017-07-18 17.25.50.png](https://qiita-image-store.s3.amazonaws.com/0/191873/400462b4-9e4b-b0a2-d072-8806b1fdb0fa.png)

今回は「Area chart」を選択。
![スクリーンショット 2017-07-18 17.26.38.png](https://qiita-image-store.s3.amazonaws.com/0/191873/af9589a6-2eea-6c51-d66c-4d556c7dd6d1.png)

作成したindex（indexname）を選択し、グラフの詳細設定画面を開きます。
まずY軸（Y-Axis）を設定します。「Aggregation」は`「Average」`を選択肢、「Field」は`「humid」`とする。続いてX軸（X-Axis）を設定します。

![スクリーンショット 2017-07-18 17.33.42.png](https://qiita-image-store.s3.amazonaws.com/0/191873/e644ed3c-ac2b-6c3a-70ef-8cc135892cb5.png)

「Aggregation」は`「Date Historgram」`を選択肢、「Field」は`「@timestamp」`とする。

![スクリーンショット 2017-07-18 17.34.12.png](https://qiita-image-store.s3.amazonaws.com/0/191873/b2a72963-43ff-e337-ed34-c4000fbc5f2d.png)

そして上部にある再生ボタン？（右向き三角形のボタン）を押すと以下のようにグラフが表示されます。
![スクリーンショット 2017-07-18 17.39.57.png](https://qiita-image-store.s3.amazonaws.com/0/191873/09e8326d-4eee-66a9-28ef-e5a738067394.png)

同様に温度の方もVisualizeの設定をします。

2つのグラフが作成できたら、最後にDashboardに作成したグラフを並べて一覧できるようにします。
Kibanaのメニューから「Dashboard」を選択し、「Add」から上記で作成したVisualizeを選択して、Dashboardに表示していきます。
これでKibanaのDashboardで温度と湿度のデータを一覧できるようになりました。
このDashboardのURLにアクセスすればいつでもグラフを確認できます。

# 4.まとめ
本稿ではMESHの温度・湿度タグのデータをAWSのAmazon Elasticsearchに送信し、Kibanaでグラフ化したデータをブラウザから閲覧できるようにする手順を書きました。

# 5.参考
[Interface 2017年 7月号](https://www.amazon.co.jp/gp/product/B06XZCCXRT/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B06XZCCXRT&linkCode=as2&tag=mixi080-22&linkId=f88a95e2c82575b9d65215449dcd872f)「IOTセンシング初体験」