NatureRemoで人感センサ等の値をデータベース化

#NatureRemoとは？
IoTという言葉が生まれて久しいですが、ここ2年くらい死の谷を超えたのでは？と思えるくらい便利な製品が次々と世に出ているように感じます。

その便利な製品の代表格の一つがスマートリモコン
その代表格である
**NatureRemo**
https://nature.global/

実はコレ、付属のセンサと公式APIを使用して、データロガーとしても使えるのです。
具体的には
**1.温度
2.湿度
3.照度
4.人感**
のデータが取得できます

#手順

※こちらを参考にさせて頂きました
https://qiita.com/t-chi/items/01b9a9b98fbccef880c3

人感センサの取得以外は上記参照させて頂いたページ内容と重複しますので、
**差分のみ本ページに記載いたします。**

###①Remo＆Googleアカウントの準備＆②NatureRemoのアクセストークン発行
上記参考ページご参照いただければと思います。

###③Googleスプレッドシート作成
下図のようなスプレッドシートを作成してください
（シート名は"log"で）
![Remoスプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/7065013e-978a-2758-e69f-705ed4d97280.png)

###④センサデータをスプレッドシートに書き込むGASコード作成
※GASについては下記リンクご参照ください
https://udemy.benesse.co.jp/development/intro-gas.html
※RemoのAPI仕様は下記公式サイトをご参照ください
http://swagger.nature.global/#/default/get_1_devices

ツール→スクリプトエディタでGASを起動し、
![GAS起動.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/4914887b-d54b-d8ec-34b3-f03ed170b3ae.png)
下記ソースコードを書き込んでください
（トークン、スプレッドシートIDの取得法はページ最上部の参考リンクご参照ください）

**ソースコード**

```javascript:GASコード
var access_token = '****'//←トークンを記入
var spreadsheetId = '****'//←スプレッドシートのIDを記入
function remo() {
  var data = getNatureRemoData();//APIを叩いてデータ取得
  var lastData = getLastData();//スプレッドシートの記載済最終行を取得
  //スプレッドシート末端に取得したデータを書き込む
  addToSpreadSheet(               
  {
    te:data[0].newest_events.te.val,   //温度
    hu:data[0].newest_events.hu.val,   //湿度
    il:data[0].newest_events.il.val,   //照度
    mo_last:data[0].newest_events.mo.created_at,//人感更新時刻
  },
  lastData.row + 1//記載済最終行+1行目にデータを書きこむ
  );
}

//RemoからGet（1/devices）でデータを取得するメソッド（Remoのapi使用）
function getNatureRemoData() {
  //アクセス先URL（1/devices）
  var url = "https://api.nature.global/1/devices";
  //ヘッダーに受取形式とトークン埋め込み
  var headers = {
    "Content-Type" : "application/json;",
    'Authorization': 'Bearer ' + access_token,
  };
  //オプションでGETメソッドであることと、ヘッダーを指定
  var options = {
    "method" : "get",
    "headers" : headers,
  };
  //UrlFetchAppを使ってGET(1/devices)を実行し、センサデータを取得
  var data = JSON.parse(UrlFetchApp.fetch(url, options));
  //取得したデータをログに記載
  Logger.log(data[0].newest_events)
  //取得したデータを出力
  return data;
}

//スプレッドシートの記載済最終行を取得するメソッド
function getLastData() {
  var datas = SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getDataRange().getValues()//logシートをゲットする
  var data = datas[datas.length - 1]
  return {
    totalpoint:data[1],
    coupon:data[2],
    row:datas.length,
  }
}

//データをスプレッドシートに書き込む
function addToSpreadSheet(data, row) {
  SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 1).setValue(new Date())//A列：取得した日時
  SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 2).setValue(data.te)//B列：温度追加
  SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 3).setValue(data.hu)//C列：湿度追加
  SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 4).setValue(data.il)//D列：照度追加
  SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 6).setValue(data.mo_last)//I列：人感更新時刻追加
  //前行の人感更新時刻を取得
  var previous_mo_last = SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row - 1, 6).getValue()
  //人感更新時刻が前行と異なる（人感センサ更新ある）とき、E列に「1」を記載
  if(row >= 2 && previous_mo_last != data.mo_last){
    SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 5).setValue(1)
  }
  //人感更新時刻が前行と同じ（人感センサ更新ない）とき、E列に「0」を記載
  else {
    SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 5).setValue(0)
  }
}
```

ここで注意いただきたいのが、
**人感センサのみ、他のセンサと値の取得方法が異なる**
ことです。

センサの値はAPIの GET 1/devicesで取得しますが、
取得されたデータのうち、
センサ値が格納された要素"newest_events"は下記のような構造となっております・

```javascript:GET"1/device"で取得したデータのnewest_eventsの中身
    "newest_events": {
      "te": {
        "val": 20.2,
        "created_at": "2020-04-14T15:50:13.911Z"
      },
      "hu": {
        "val": 38,
        "created_at": "2020-04-14T15:50:13.911Z"
      },
      "il": {
        "val": 22,
        "created_at": "2020-04-14T15:50:13.911Z"
      },
      "mo": {
        "val": 1,
        "created_at": "2020-04-14T15:50:13.911Z"
      }
    }
```

"te"(温度),"hu"(湿度),"il"(照度),"mo"(人感)がセンサの種類を表し、
それぞれ"val"(値),"created_at"(最終更新時刻)のデータを保持しています。

人感以外の3センサは"var"に測定値（上記の場合、温度=20.2℃）が記載されており、
この"var"の値をスプレッドシートに書き込むだけでよいのですが、
**人感センサ"mo"に関しては、"var"は常に1が記載された意味のないデータ**
となっています。

なので、最終更新時刻"created_at"が前回（前行）データと変わっているかで、
人感センサが前回更新後に反応したかを判定する必要があります。
上記コード内"addToSpreadSheet"メソッドの後半がこの処理に相当します。

###⑤トリガを設定し、定期更新する
GAS上で
編集 → 現在のプロジェクトのトリガー → トリガーの追加
![トリガー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/710bd07f-8cc6-963b-650b-8648a95a1f00.png)
下図のようにトリガを設定（間隔は適宜調整してください）
![トリガー設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/95e7df4d-22e9-42a4-6423-6c83da4510a6.png)

**これで、センサの値がスプレッドシートに定期入力されるはずです！**
（人感は、前回更新から反応があったときは"1"、反応がないときは"0"が記入されます）


#注意点
###1.人感センサの特性
当たり前ではありますが、
人感センサは
「同じ部屋に人がいること」
ではなく
「センサの前を人が通ったこと」
を検知します。
部屋内の人の有無を確実に見たいのであれば、センサを複数置いて死角をなくす必要があります。

###2.センサの向き
下の図の赤方向に感度があるようです
私は最初、青の方向を人がいる場所に向けていて全然反応せず、
壊れたと思って勝手にイライラを募らせておりました笑
![センサ方向.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610167/3205dc6a-830d-d13d-25b4-af6b2eac6931.png)

###3.トリガの間隔
間隔を短くして放置すると、保存されるデータ数が凄まじい事になるので注意して下さい
1分間隔で1日に1440行、1年で53万行溜まります。