Nature Remo + Google App Script で部屋の温度・湿度・照度記録
Nature Remo API を動かしてみるところまではこちら。続いて、時系列データとして記録して、みんな大好き”視える化”していきたい。
自身が見るのみなので、Google SpreadSheetのグラフ公開機能で簡単にできないかな、と調べてみるとこちらも先駆者がおり大いに助かります、参考こちら。
なおここでは、湿度と照度は、温度と同様に取得するだけなので(略)。
Google App Script (GAS)の作成
初めに、新規のgoogle spreadsheetで、グラフ表示用とデータログ用2つのシートを作成し、”ツール” > "スクリプト エディタ"からGASを作成開始。
spreadsheetidは、spreadsheet URLの最も長い文字列がそう、ググってみるよろし。
var accessToken = 'yourToken' //Nature Remoアクセス用トークン
var spreadsheetId = 'xxx' //google spreadsheetのユニークID
var sheetName_graphed = 'log' //グラフ表示用シート
var sheetName_archived = 'log_archived' //データログ用シート
//データログの方にもデータをセットもしくはコピーし、
//その後グラフ表示用のシート2行目を削除する。
function main() {
// Nature Remoから最新データ取得
var data = getNatureRemo();
// Nature Remoの時刻データをJSTへ変換
var recordTime = transformDateData(data);
// 取得データをグラフ表示用シートへ記録
setLatestData(data, recordTime, sheetName_graphed);
// 取得データをデータログ用シートへ記録
archiveData(data, recordTime, sheetName_archived);
// グラフ表示用シートから古いデータを除去
// 1450行程度データがたまってからこの行を追加した(*)。
deleteOldData(sheetName_graphed);
}
// Nature Remoからデータを取得
function getNatureRemo(){
var url = "https://api.nature.global/1/devices";
var headers = {
"Content-Type" : "application/json",
"Authorization" : 'Bearer ' + accessToken,
};
var options = {
"method" : "get",
"headers" : headers,
};
var data = JSON.parse(UrlFetchApp.fetch(url, options));
return data;
}
// spreadsheetの最終セルの取得
function getLastRow(sheetName){
var datas = SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getDataRange().getValues();
var data = datas[datas.length - 1];
return datas.length;
}
// NatureRemoのデータ取得時刻も念のため記録する
function transformDateData(data){
//NatureRemoのデータ取得時刻をフォーマット変換&&JST化
recordTime = data[0].newest_events.te.created_at;
var localizedRecordTime = Utilities.formatDate(new Date(recordTime), "JST", "YYYY-MM-dd HH:mm:ss");
return localizedRecordTime;
}
// 最新データを表示用シートへ書き込み
function setLatestData(data, rcdTime, sheetName){
var row = getLastRow(sheetName);
row = row +1;
// spreadsheetの最終セルへNatureRemoのデータをセット
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 1).setValue(new Date());
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 2).setValue(data[0].newest_events.te.val);
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 3).setValue(rcdTime);
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 4).setValue(data[0].newest_events.te.created_at);
}
// 最新データをデータログ用シートも書き込み
function archiveData(data, rcdTime, sheetName){
var row = getLastRow(sheetName);
row = row +1;
// spreadsheetの最終セルへNatureRemoのデータをセット
// 各行順に、実行時刻, 温度, NetureRemo記録時刻(JST), NetureRemo記録時刻
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 1).setValue(new Date());
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 2).setValue(data[0].newest_events.te.val);
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 3).setValue(rcdTime);
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).getRange(row, 4).setValue(data[0].newest_events.te.created_at);
}
// グラフ表示用データより1行のみ削除
// 1行目は項目名が記載されているため、2行目が対象。
function deleteOldData(sheetName){
SpreadsheetApp.openById(ssid).getSheetByName(sheetName).deleteRow(2);
}
注意点として、
Nature Remoでは一定時間ごとに測定が行われるが、一定以上の差がある場合のみにデータが更新される。Remoのみのデータなら、これをそのまま使っても問題ない。
また個人的な味付けとして、表示用シートとデータログ用シートで分けた。両シートにデータを記録し、グラフ表示には表示用シートのデータを用いる。ある一定数*(約30日分(後述))のデータのみを記録し、古くなったデータは、GASが最新データ取得するたびに削除(*)。
理由は単純で、半年ほど稼働させるとデータがたまりすぎてグラフが見えづらくなったため。データログ用は将来解析や他IoTデバイス追加に向けて。
何回か実行して、下記のようにいくつかデータが取れたらグラフを挿入して公開してみる。1行目の項目名はご自由に。
グラフを選択→右クリック→公開、で完了。(ホント革命的!見た目とかシンプルだけど)
発行されたURLにアクセスしてグラフが表示されていればOK。
Google App Scriptの定期実行設定
次に、作成したGASが定期的に自動実行するよう設定する。マイトリガーかGASプロジェクトのトリガーから下記設定をする。
実行する関数: main
イベントソース: 時間主導型
時間ベースのトリガータイプ: 分ベースタイマー
時間間隔: 30分おき(お好みで)
*ある一定数: 前述の通りおよそ最新30日分のデータのみ保持したい。30分おきのデータ取得では、ざっくり1450行程度だ。
おおよそのデータがたまった時点で、削除する処理を実行するように追加し、グラフのデータ範囲も指定し直してあげればOK。
最終的に、下記のようなグラフが公開表示される。(とある30日分)
いつかログ用シートのデータも使う日が来るといいな。。。