スマートメーターから取得した電力使用量をグラフ化する（Elasticsearch + kibana）

## はじめに
rukihenaさんの下記の記事に触発され、スマートメーターから取得した家庭の電力使用量をグラフ化してみました。
http://qiita.com/rukihena/items/82266ed3a43e4b652adb

こんな感じで、1分ごとに瞬時電力使用量を確認できます。

![スクリーンショット 2016-06-14 17.35.34.png](https://qiita-image-store.s3.amazonaws.com/0/49448/64126b15-24eb-70f8-07a3-a8eb7930b8d0.png "こんな感じのグラフが！")


## グラフ化されると何がうれしいか
#### **節約意識が高まる**
電気を節約しよう！と思って意気込んでも、本当に節約できているのかは分かりにくいもの。
電力使用量がリアルタイムで分かると、節約意識が高まるかもしれません。

#### **よく電気を使用している時間帯/曜日が把握できるので、時間帯別で割安になる電力プランを選ぶときの参考になる**
電気を使う傾向は体感で分かっているかと思いますが、グラフ化することでさらに正確に分かります。

#### **不在の時間帯に電力使用量が急増した場合、空き巣に入られた可能性があることが分かる**
誰もいないはずなのに電気をたくさん使っている・・・？ということは空き巣に入られていう可能性があるかもしれません。
しかし、急激に電力使用量が高くなる場合は、空き巣がドライヤーとか電気ケトルなど、高出力の電気製品を使った時ですし、空き巣がまずそんなことを行わないでしょう。
そして分かったところでどうしようもできません。異なるアプローチでのおうちハックが必要になります。
 
#### **なんとなくうれしい**
いい感じにグラフ化されていると、なんとなくうれしいものです。


## 準備
まずは下記の3つを準備しましょう。

##### **1. 電力メーター情報発信サービス（Bルートサービス）への申し込み**
スマートメーターからデータを取得するには、上記サービスに加入する必要があります。（無料です）
3週間ほどすると、認証用のID/Passが送られてきます。 ※ 東京電力の場合

##### **2. Wi-SUNプロトコルで通信可能な機器**
スマートメーターとはWi-SUNというプロトコルで通信します。Wi-SUNを扱うには専用の機器を用意する必要があります。USB機器の[WSR35A1-00](http://www.rohm.co.jp/web/japan/news-detail?news-title=2014-10-02_news&defaultGroupId=false)を用意するのが手っ取り早いです。（定価が￥15,000と、少々高いですが）

##### **3. サーバ**
Bルート通信およびグラフを表示させるサーバが必要です。我が家ではBルート通信用サーバにRaspberry pi 2、グラフ表示用サーバには、クラウドサービスであるAWSのEC2（プラン：t2.micro）を利用しています。このプランであれば、1年間は利用無料です。


処理の流れとしては、自宅にあるにBルート通信用サーバがスマートメーターからWi-SUNプロトコル経由で電力使用量を引っ張ってきて、クラウド上のグラフ表示用サーバに格納し、PCやスマホなどのWebブラウザからアクセスしてグラフを確認する、という感じです。


## サーバの環境構築

##### **Bルート通信用サーバ（Raspberry pi 2）**
[rukihenaさんの記事](http://qiita.com/rukihena/items/82266ed3a43e4b652adb)と同じ構成です。
シリアル通信用にpyserial、電力使用量取得プログラム用にPythonの環境があればOKです。
Raspberry pi 2であれば、どちらもデフォルトでインストールされています。

##### **グラフ表示用サーバ（AWS EC2）**
グラフ化にはElasticsearchとkibanaを用いました。
Elasticsearchは全文検索用エンジンですが、kibanaと組み合わせることで簡単にデータをグラフ化できます。どちらもOSSですので、気軽に利用できます。

Elasticsearchの動作にはJDKが必要ですので、ない場合はインストールします。

```
$ sudo yum install java-1.8.0-openjdk-devel.x86_64
```

JDKが用意できたら、Elasticsearch、kibanaをインストールします。

```
$ sudo rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
$ sudo vi /etc/yum.repos.d/elastic.repo
---------------------------------------
[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=http://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1

[kibana-4.4]
name=Kibana repository for 4.4.x packages
baseurl=http://packages.elastic.co/kibana/4.4/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1
---------------------------------------
$ sudo yum install elasticsearch -y
$ sudo yum install kibana -y
$ sudo service elasticsearch start
$ sudo service kibana start
```

Elasticsearchに適切な形式（kibanaでグラフ化できる形式）でデータが格納されるよう、マッピングの設定をしておきます。
まず、マッピングのスキーマを定義したファイルを作成します。

```json:elasticsearch_mapping.json
{
  "mappings": {
    "elec": {
      "properties": {
        "inst":  {
          "type":   "integer",
          "index":  "not_analyzed"
        },
        "timestamp":  {
          "type":   "date",
          "format": "YYYY/MM/dd'T'HH:mm:ssZ"
        }
      }
    }
  }
}
```

作成したファイルを指定し、Elasticsearchに投入します。

```
$ curl -XPOST 'http://localhost:9200/home' -d @elasticsearch_mapping.json | jq
```

なお、AWSのデフォルトのセキュリティ設定では22番以外のポートは外部からアクセスできないため、5601番(kibanaのポート)と9200番(Elasticsearchのポート)は開けておく必要があります。
ですが、長期間運用するのであれば、アクセス元IPを絞るなど、適宜セキュリティを高めておいたほうが無難です。

## 実装

##### **Bルート通信用サーバ（Raspberry pi 2）**
[rukihenaさんのサンプルプログラム](http://qiita.com/rukihena/items/82266ed3a43e4b652adb#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)に、瞬時電力使用量を1分ごとにElasticsearchに書き込む処理を追加しています。

```python:smartmeter_to_elasticsearch_aws.py

# Elasticsearch接続用の設定を追加
> from elasticsearch import Elasticsearch
> es = Elasticsearch(host='<AWSのグローバルIP>', port=9200)
> from datetime import datetime

：
：

# 元のプログラムでは瞬時電力使用量を標準出力に表示している箇所を、Elasitcsearchに書き込むように変更
<      print(u"Data:{0}[W]".format(intPower))
---
## 瞬時電力使用量と現在時刻を格納
> 		elec_inst = {
> 		    'inst': intPower,
> 		    'timestamp': datetime.now().strftime('%Y/%m/%d'+"T"+'%H:%M:%S'+"+0900")
> 		}
## RDBだと「home」データベースの「elec」テーブルに「elec_inst」のデータを格納するイメージ
> 		res = es.index(index="home", doc_type='elec', body=elec_inst)
>
## 1分sleep
> 		time.sleep(60.0)

```

エラーなく動けばOKです。

```
$ python smartmeter_to_elasticsearch_aws.py
```

永続的に動かすために、supervisordなどでデーモン化しましょう。

## kibanaで見てみる
##### **初期設定**

Webブラウザでkibanaにアクセスします。

```
http://<AWSのグローバルIP>:5601/
```

無事kibanaが動いていれば、こんな画面が出てきます。

![スクリーンショット 2016-07-16 17.42.59.png](https://qiita-image-store.s3.amazonaws.com/0/49448/0051e430-4fcd-35aa-6061-70c633b7607d.png "まずは最初の画面")


まずは、電力使用量のデータが格納されている、Elasticsearchのインデックス名を指定します。"Index name or pattern"のフォーム"home*"と入力してみましょう。
問題なくデータが格納されている場合、"Create"ボタンが活性化するのクリックします。

![index.png](https://qiita-image-store.s3.amazonaws.com/0/49448/99629a01-265d-e8b8-bf02-119acba62618.png "インデックスを設定")


画面が遷移し、データが格納されてるっぽいグラフが表示されていればOKです。


![スクリーンショット 2016-07-16 17.44.21.png](https://qiita-image-store.s3.amazonaws.com/0/49448/944c2523-6464-623c-b907-1d92a8a8e00e.png "縦棒が表示されていればおｋ")



##### **コンフィグファイルのインポート**
冒頭のようなグラフを表示させるには、Visualizeの設定をこねくり回す必要があるのですが、ある程度kibanaに慣れないと分かりにくいです。
取り急ぎ、冒頭と同じグラフを表示できるよう、コンフィグファイルを用意しました。

"Settings" -> "Objects"に移動し、"Import"ボタンからコンフィグファイルをインポートします。

![スクリーンショット 2016-07-16 17.44.49.png](https://qiita-image-store.s3.amazonaws.com/0/49448/526649cc-3ee9-372d-1d63-ac24f87dfe5a.png "インポーート")

下記の二つのコンフィグを適当なファイル名で保存し、インポートしてください。

```home_dashboard.json
[
  {
    "_id": "家",
    "_type": "dashboard",
    "_source": {
      "title": "家",
      "hits": 0,
      "description": "",
      "panelsJSON": "[{\"col\":1,\"id\":\"瞬時電力量（W）\",\"panelIndex\":1,\"row\":1,\"size_x\":12,\"size_y\":3,\"type\":\"visualization\"}]",
      "optionsJSON": "{\"darkTheme\":false}",
      "uiStateJSON": "{\"P-1\":{\"vis\":{\"legendOpen\":false}}}",
      "version": 1,
      "timeRestore": false,
      "kibanaSavedObjectMeta": {
        "searchSourceJSON": "{\"filter\":[{\"query\":{\"query_string\":{\"analyze_wildcard\":true,\"query\":\"*\"}}}]}"
      }
    }
  }
]
```

```elec_visualize.json
[
  {
    "_id": "瞬時電力量（W）",
    "_type": "visualization",
    "_source": {
      "title": "瞬時電力量（W）",
      "visState": "{\"title\":\"New Visualization\",\"type\":\"line\",\"params\":{\"shareYAxis\":true,\"addTooltip\":true,\"addLegend\":true,\"showCircles\":true,\"smoothLines\":false,\"interpolate\":\"linear\",\"scale\":\"linear\",\"drawLinesBetweenPoints\":true,\"radiusRatio\":9,\"times\":[],\"addTimeMarker\":false,\"defaultYExtents\":false,\"setYExtents\":false,\"yAxis\":{}},\"aggs\":[{\"id\":\"1\",\"type\":\"max\",\"schema\":\"metric\",\"params\":{\"field\":\"inst\"}},{\"id\":\"2\",\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"timestamp\",\"interval\":\"auto\",\"customInterval\":\"2h\",\"min_doc_count\":1,\"extended_bounds\":{}}}],\"listeners\":{}}",
      "uiStateJSON": "{}",
      "description": "",
      "version": 1,
      "kibanaSavedObjectMeta": {
        "searchSourceJSON": "{\"index\":\"home*\",\"query\":{\"query_string\":{\"query\":\"*\",\"analyze_wildcard\":true}},\"filter\":[]}"
      }
    }
  }
]
```


##### **グラフ表示**

エラーなくインポートできたら、いよいよグラフが見られるようになります。
"Dashboard"に移動し、画面右上にあるフォルダアイコン(カーソルを乗せると"Load Saved Dashboard"と表示されます)をクリックします。

![スクリーンショット 2016-07-16 17.45.57.png](https://qiita-image-store.s3.amazonaws.com/0/49448/cd0655a8-1968-e48f-698a-f5d79b32d4ef.png "Ready to get started?")


"家"というそのまんまなメニューが表示されるのでクリックします。

![スクリーンショット 2016-07-16 17.46.39.png](https://qiita-image-store.s3.amazonaws.com/0/49448/e896684c-b3e0-72db-8d8e-3690088a3d67.png "やったね")

ようやく、電力使用量がグラフ化されました！

表示する期間の変更や自動更新設定などは、画面右上の時計マークをクリックし、色々と触ってみてください。

## おわりに
初期投資がそれなりにかかりましたが、電力使用量のグラフ化ができました。
Elasticsearchにさえデータを格納できればkibanaでグラフ化できるので、気温や湿度などを電力使用量と同時に表示すれば何か楽しそうですね。

家電メーカーが販売しているHEMSシステムを使えば同じことを実現できるわけですが、メーカー間の互換性がないため、拡張性に難があるかと思います。
このあたりをオープンな仕様にしない限り、HEMSはなかなか広がらないのでしょうねー。