スマートメーターから取得した電力消費量を可視化する (3)IoTっぽく可視化する

#この記事について
ロームBP35C0-T01とESP-WROOM-32を使って、スマートメーターから取得した電力量を可視化します。
[スマートメーターから取得した電力消費量を可視化する (2)消費電力量を取得する](https://qiita.com/nara256/items/a9e7db7c14b51cd01885)の続き、今回は電力消費量を可視化します。

#可視化ツールを使う
今回は、取得した電力値を可視化ツールを使用してグラフ化させてみます。
可視化させるツールは数多くありますが、今回は手っ取り早く無料のサービスを使います。
無料の可視化サービスといえば、[ThingSpeak](https://thingspeak.com/)とか、[Ambient](https://ambidata.io/)とか、いろいろありますが、今回はIIJの[Machinist](https://machinist.iij.jp/)を使ってみます。
※実を言うと、これを書いている私自身もMachinistを使うのは今回が初めてだったりします。

#実際に可視化させてみる　
##事前準備
以下のことをやっておきます。

- [Machinist](https://machinist.iij.jp/)にサインアップして、アカウントを作成します（現時点では無料です）。
- Machinistのマニュアル([Getting Started](https://machinist.iij.jp/getting-started/))を軽く読んでおきます。
- Machinistにログインし、管理UIからプロフィールの画面からAPIキーを取得しておきます。
- Machinistの管理UIから、エージェントを1つ作成しておきます。

##可視化させる
###Machinistの仕様
Machinistに対して、httpsで特定のjson形式文字列を送るだけのシンプルなインターフェースのようです。
データの送信先は `https://gw.machinist.iij.jp/endpoint` で、このURIにjson文字列をPOSTします。
httpヘッダに、`Content-Type: application/json` と `Authorization: Bearer APIキー文字列` も一緒に送ります。

```json
{
  "agent": "事前に作成したエージェントの名称",
  "metrics": [
    {
      "name": "適当なname",
      "namespace": "適当なnamespace",
      "data_point": {
        "value": 数値
      }
    }
  ]
}
```

詳しくはMacinistの[機能仕様](https://machinist.iij.jp/getting-started/spec/data_format.html)を参照してください。

###ESP32からデータ送信してみる
前回同様に、Machinistにデータ送信する部分はESP32向けのライブラリを作成しておきました。
以下から取得してください。
https://github.com/nara256/IIJMachinistClient

[前回のソース](https://qiita.com/nara256/items/a9e7db7c14b51cd01885)をベースに、スマートメーターから取得した値をMachinistに送るように書き換えてみます。

```cpp
#include <WiFi.h>
#include <WiFiMulti.h>
#include "IIJMachinistClient.h"
#include "Bp35c0-broute.h"

#define WIFI_ID "YOUR WIFI SSID HERE"
#define WIFI_PASS "YOUR WIFI PASSWORD HERE"
#define MACHINIST_API_KEY "YOUR Machinist API KEY here"
#define MACHINIST_AGENT "YOUR Machinist Agent name here"

#define ID    "YOUR_B_ROUTE_ID_HERE"
#define PASS  "YOUR_B_ROUTE_PASSWORD_HERE"
#define LED 2

HardwareSerial uart(2);
Bp35c0_broute b(uart);

WiFiMulti wiFiMulti;
IIJMachinistClient c(MACHINIST_API_KEY);

void blink(int sec) {
  pinMode(LED,OUTPUT);
  digitalWrite(LED,HIGH);
  delay(sec);
  digitalWrite(LED,LOW);  
  delay(sec);
}

void blink(int sec, int count) {
  for(int i=0; i<count; i++)
    blink(sec);
}


void error() {
  pinMode(LED,OUTPUT);
  while(true) {
    blink(500);
  }  
}

void setup() {
  Serial.begin(115200);

  //----- initializing Wi-Fi
  WiFi.mode(WIFI_STA);
  wiFiMulti.addAP(WIFI_ID, WIFI_PASS);

  // wait for WiFi connection
  Serial.print("Waiting for WiFi to connect...");
  while ((wiFiMulti.run() != WL_CONNECTED)) {
    Serial.print(".");
  }
  Serial.println(" connected");
  c.init();

  //----- initializing B Route 
  uart.begin(115200);
  if(!b.available()) {
    error();
  }
  if(!b.open(ID,PASS)) {
    error();
  }
}

void loop() {
  blink(100);
  char u[32] = {'\0'}, d[32] = {'\0'};
  float uu, dd;
  
  b.waitForRecieve(d,&dd,u,&uu);
  c.post(MACHINIST_AGENT, "downside", "kWh", dd);
  c.post(MACHINIST_AGENT, "upside", "kWh", uu);
}
```

####実行結果
データ送信後、Machinistにログインしてみます。こんな感じでグラフ化できました。
![metrics.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169018/63e127f8-3cb6-22e4-a974-a139a90af6e4.png)

グラフをクリックすると、拡大表示もできます。
![metric.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169018/30e48635-ad3b-a42d-5f5a-a399bfc8d706.png)

####サンプルスケッチの説明
Machinistへの投稿部分に関して、ポイントを絞ってざっくり説明していきます。

#####ライブラリをインクルードします
```cpp
#include "IIJMachinistClient.h"
```
####Wi-Fiへの接続
```cpp
WiFiMulti wiFiMulti;

...(中略)...

void setup() {
  WiFi.mode(WIFI_STA);
  wiFiMulti.addAP(WIFI_ID, WIFI_PASS);

  // wait for WiFi connection
  Serial.print("Waiting for WiFi to connect...");
  while ((wiFiMulti.run() != WL_CONNECTED)) {
    Serial.print(".");
  }
  Serial.println(" connected");
```
この辺はESP32のお約束な感じなので、詳細はググってください（手抜きｗ）

####Machinist Clientの定義
```cpp
IIJMachinistClient c(MACHINIST_API_KEY);
```
MachinistのAPIキー（管理UIから事前にコピーしておいた文字列）を引数に、IIJMachinistClientのインスタンスをグローバル変数として生成します。

####電力値をMachinistに投稿する
```cpp
void loop() {
  blink(100);
  char u[32] = {'\0'}, d[32] = {'\0'};
  float uu, dd;
  
  b.waitForRecieve(d,&dd,u,&uu);
  c.post(MACHINIST_AGENT, "downside", "kWh", dd);
  c.post(MACHINIST_AGENT, "upside", "kWh", uu);
}
```

`loop()`関数内で取得した定時積算電力量計測値を、`c.post()`関数でMachinistにデータ送信しています。引数は、Agent(事前に作成しておいたもの), namespace, name, 送信する値, です。
本当は、スマートメーターから取得した計測日時も合わせてMachinistに送ればより正確な日時でグラフ化できるのですが、日時の文字列をunixtimeに変換する処理が面倒だったので手抜きしましたｗ

####ソースコードの改善案
スマートメーターから取得できる定時積算電力量計測値は、電力消費量がどんどん加算されていきますので、グラフは右肩上がりのつまらない(?)ものになってしまいます。
前回取得値との差分をデータ送信するようにすれば、該当時間帯にどれくらい電力を消費したのかがわかりやすくなって良いかもしれません。

###Machinistを使ってみて思ったこと
- すげー簡単に使えるね
- Webから参照するだけでなく、スマホからサクッと参照できるようにスマホアプリが欲しい
- グラフ化はすげー簡単だけど、グラフ化以上のことをしようとすると手詰まり感

#まとめ
ということで、3回に渡って、マイコンの配線、スマートメーターから電力消費量のデータを取得、Machinistでの可視化、をそれぞれまとめてみました。
ついでに、ESP32用のライブラリも実装してみました。
有効にお使いいただけると幸いです。

#ToDO
自分向けのToDO

- [Bルート用ライブラリ](https://github.com/nara256/Bp35c0_broute) のESP32以外での動作確認
- [IIJMachinistClient](https://github.com/nara256/IIJMachinistClient) のESP8266(WROOM-02)への対応