消費電力を計測してGoogleスプレッドシートに書き出すIoT機器を作ってみた

![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/52086/d1bdc50a-68d1-4074-d343-0f94a741495d.png)


[mbed Advent Calendar 2015](http://www.adventar.org/calendars/843)の11日目の記事です。
[7日目のじぇーけーそふと](https://media.dmm-make.com/item/3643/)さんと同じSimple IoT board使った記事です。

[Simple IoT board](http://www.runele.com/ca1/41/)と電力計測モジュール([INA226PRC](https://strawberry-linux.com/catalog/items?code=12226))を使って、電力のログをGoogleスプレッドシートに書き出すものを作りました。

サンプリングは0.1秒刻みで、10秒間（100回計測）したら電圧、電流、電力それぞれについて平均、最大値、最小値を計算してサーバに送る仕様になっています。

※電池がどのくらい持つのか調べるのに使えそう


# 材料
|種類|商品名| URL |
|:-----------|:------------:|:------------:|
|メインボード|Simple IoT board|http://www.runele.com/ca1/41/|
|ライター|mbed LPC1114FN28|https://www.switch-science.com/catalog/1714/|
|電力計測モジュール|INA226PRC|https://strawberry-linux.com/catalog/items?code=12226|
|ケーブル|GROVE - 4ピン-ジャンパメスケーブル 20cm (5本セット)|https://www.switch-science.com/catalog/1048/|

# ハードウェア注意点

## INA226PRC
![IMG_20151211_184437.jpg](https://qiita-image-store.s3.amazonaws.com/0/52086/d138a3fc-858e-590d-cfca-fd37a92f762b.jpeg)
### I2Cのアドレス設定
INA226はI2Cのアドレスを結線で変えられるようになっているので、上の写真の様に**GのA1、A0**を半田づけしておきます。

### Groveの接続
[GROVEのジャンパーメスケーブル](https://www.switch-science.com/catalog/1048/)を上の写真のように配線してください。

* 黒：GND
* 白：SDA
* 黄：SCL
* 赤：3.3V

# 通信概要

**Simple IoT Board  --(http)->  IFTTTのMakerチャネル --(https)-> Googleスプレッドシート**

*https*通信するプログラムをのせるにはSimple IoT Boardのリソースでは足らないので、IFTTTのMakerチャネルで中継してhttpsに変換して送ってます。
スプレッドシート側のサーバはGoogle Apps Script（以後GAS）を使って実装してます。

# 実装
## Googleスプレッドシート側の準備
### スプレッドシートを新規作成してスクリプトエディタを開く
![WattLogger_-_Google_スプレッドシート.png](https://qiita-image-store.s3.amazonaws.com/0/52086/64f10a1f-f6ed-5717-e1d3-d4355c71411c.png)

### プロジェクト名の変更とソースコードの貼り付け
![無題のプロジェクト.png](https://qiita-image-store.s3.amazonaws.com/0/52086/47731df7-0061-d290-659f-edfdab5743d8.png)

サーバのソースコード

```js
/**
 * スプレッドシートのIDをプロパティに保存する
 * @return {number}
 */
function setup(){
  var id = SpreadsheetApp.getActiveSpreadsheet().getId();
  Logger.log(id);
  PropertiesService.getScriptProperties().setProperty('SPREADSHEET_ID', id);
  return id;
}

/**
 * スプレッドシートを返す
 * @return {SpreadsheetApp.Spreadsheet}
 */
function getSpreadsheet(){
  var SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_ID');
  
  if(!SPREADSHEET_ID){
    Logger.log("Not found SPREADSHEET_ID.\nPlease call setup().");
    return;
  }
  
  Logger.log(SPREADSHEET_ID);
  return SpreadsheetApp.openById(SPREADSHEET_ID);
}

/**
 * httpsのGETのリクエストを受けた時に呼び出される
 */
function doGet(e){
  if(e){
    // クエリーストリングのvalue1に入っているデータをシートに追記
    appendLog(e.parameter.value1);
  }
  
  // ”OK"という文字列を返す
  var content = {mime:ContentService.MimeType.TEXT,  content: "OK"};
  return ContentService.createTextOutput(content.content).setMimeType(content.mime);
}

/**
 * スプレッドシートにログを追記する
 * @params csv CSV形式の文字列
 **/
function appendLog(csv) {
  var spreadSheet = getSpreadsheet();
  var sheet = spreadSheet.getSheetByName("シート1");

  // カンマ区切りを配列に変換  
  var values = csv.split(",");
  
  // シートの末尾にデータを追記
  var range = sheet.getRange(sheet.getLastRow()+1, 1, 1, values.length);
  range.setValues([values]);
}
```

### setupの実行
![WattLogger.png](https://qiita-image-store.s3.amazonaws.com/0/52086/e3d35610-f6e2-d55a-0614-29c20d9c55a2.png)
認証のダイアログが２回ぐらい出るので全部許可してください。

これを実行するとソースコードに書いてあるsetup関数が実行されます。setupを実行するとスプレッドシートのIDがプロパティに保存されます。
これ忘れるとサーバのデータ受信時にエラーが出るので忘れずに。

### ウェブアプリケーションの設定
公開 -> ウェブ アプリケーションとして導入... をクリック
![WattLogger 2.png](https://qiita-image-store.s3.amazonaws.com/0/52086/2318f6f5-b230-5e53-e010-0a3e1e4e2f3d.png)

アプリケーションにアクセスできるユーザーを"全員（匿名ユーザーを含む）"に設定して導入
![WattLogger 3.png](https://qiita-image-store.s3.amazonaws.com/0/52086/c33f0b99-02d0-6016-ee08-04bf719b2b53.png)

URLをメモしておく
![WattLogger 4.png](https://qiita-image-store.s3.amazonaws.com/0/52086/51d73dcb-41a2-4023-4508-55518d25c2c8.png)

以上でスプレッドシート側の設定は終わりです。

### テスト
メモしておいたURLの末尾に``?value1=12,321,321,3213``こんな感じで付け加えてブラウザのURLの入力欄に入力してアクセスする。

![https___script_googleusercontent_com_macros_echo_user_content_key_o4DPtLTDFR-HMYqcicNBToWjP3ZkWWS7wrtNq4CjLK8IlHsern-TknYI7W0ViaPzTQFRk0s5quU_fak_w0Z5vJiiSzBQCPkDm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnJojaDP-0zpH_zYj_8HiE721aq 2.png](https://qiita-image-store.s3.amazonaws.com/0/52086/7a419428-de52-6e7a-825d-76cfe6f420db.png)

スプレッドシートの画面に戻ってデータが入力されていれば成功です。
![image](https://qiita-image-store.s3.amazonaws.com/0/52086/f83a6b2e-ed65-bb85-f6ee-bff8a88df6ce.png)

## IFTTT側の設定
IFTTTユーザ登録は割愛。
### レシピの作成
[My Recipesページ](https://ifttt.com/myrecipes/personal)で**Create Recipes**をクリック

#### ifの設定
1. ifに**Maker**を設定
2. **Receive a web request**を選択
3. Event Nameを設定（ここでは仮に**WattLogger**としておきます）

#### thenの設定
1. thenに**Maker**を設定
2. **Make a web request**を選択
3. メモしておいたスプレッドシートのURLの末尾に``?value1={{Value1}}``をつけたものを入力
4. Methodを**GET**に設定
![Create_Recipe_-_IFTTT 6.png](https://qiita-image-store.s3.amazonaws.com/0/52086/a307b9cb-8e1f-69d9-0d9b-076cd4d0eafc.png)

※本当はMethodにPostを使いたかったんですが、送信エラーになってしまって何度も同じデータを送ってしまいます。スプレッドシート側のURLがリダイレクトになってるのが影響してるのかもしれないけど、Makerチャネルでは詳しいログが出ないので妥協してGETを使ってます。

### Makerチャネルの設定
[Makerチャネル](https://ifttt.com/maker)にアクセスしてKeyをメモ
![Connect_Maker_to_hundreds_of_apps_-_IFTTT_2.png](https://qiita-image-store.s3.amazonaws.com/0/52086/5f55af40-9f25-0ee4-21a8-14b20e07ca72.png)


### テスト
ターミナルを立ち上げて下のコマンドを実行

```
curl -d "value1=1,2,3,4,5" https://maker.ifttt.com/trigger/{event}/with/key/{key}
```

``{event}``は上では仮にWattLoggerとしてたやつに置き換え
``{key}``はMakerチャネルの設定でメモしておいたやつに置き換え

IFTTTだと最大15分ぐらいラグが発生するらしいのでレシピのところで**Check now**を実行すると即時反映されます。
![Recipe_30920620_-_IFTTT.png](https://qiita-image-store.s3.amazonaws.com/0/52086/ec615bec-0166-1453-1f7f-51eb22374dde.png)

スプレッドシートに追加されてればOK
![WattLogger_-_Google_スプレッドシート 2.png](https://qiita-image-store.s3.amazonaws.com/0/52086/9c303dfd-c7df-4170-d909-230a5b2b7baa.png)


## mbed側
プロジェクトをこちらに公開しました。
https://developer.mbed.org/users/leibun/code/SITB_INA226PRC/

### 仕様
サンプリングは0.1秒刻みで、10秒間（100回計測）したら電圧、電流、電力それぞれについて平均、最大値、最小値を計算してIFTTTに送る仕様になっています。

IFTTTに投げられるデータは

```
電圧平均[mV],電圧最大[mV],電圧最小[mV],電流平均[mA],電流最大[mA],電流最小[mA],電力平均[mW],電力最大[mW],電力最小[mW]
```
の順でcsv形式でvalue1に格納されて送られます。

### 使い方
#### プログラムのインポート
[プロジェクトサイト](https://developer.mbed.org/users/leibun/code/SITB_INA226PRC/)を開いて**Import this program**して使ってください。

#### ソースコードの編集 
Main.cppの14~17行目を各自の環境に書き換え

```c
// Please change your enviroment.
const char WIFI_SSID[] = "ssid";
const char WIFI_PASSWORD[] = "password";
const char IFTTT_EVENT_NAME[] = "event_name";
const char IFTTT_SECRET_KEY[] = "secret_key";
```

#### プラットフォームの設定
プラットフォームは**mbed LPC1114FN28**を選択してコンパイルして焼き込んで差し込んで完成！

#### ログの見方
Simple IoT BoardをUSBでPCとつないでボーレートを**9600**で接続するとログが見れます。

### 参考にしたソースコード

* [Simple IoT BoardのIFTTTのサンプル](https://developer.mbed.org/users/jksoft/code/SITB_IFTTTSample/)
* [INA226のライブラリ](https://developer.mbed.org/users/tosihisa/code/INA226/)


# おまけ（ゼロプレッシャーソケット）
Simple IoT BoardにLPC1114FN28を抜き差しするのが面倒くさかったので[ゼロプレッシャーソケット](http://akizukidenshi.com/catalog/g/gP-05435/)を使ってみました。

mbed LPC1114FN28にも[別のゼロプレッシャーソケット](http://akizukidenshi.com/catalog/g/gP-00025/)を使ってます。
こちらの方がごっついけど長く使える。Simple IoT Boardでも使いたかったけどスペースの問題で断念しました。

|種類|商品名| URL |
|:-----------|:------------:|:------------:|
|Simple IoT board用|ゼロプレッシャーソケット28pin|http://akizukidenshi.com/catalog/g/gP-05435/|
|mbed LPC1114FN28用|ゼロプレッシャーソケット28pin|http://akizukidenshi.com/catalog/g/gP-00025/|