初めてのAPI&GAS体験〜Nature Remoで温度の自動計測アプリを作ってみた
部屋の片付けをしていたときに、2年前に購入していたスマートリモコン(Nature Remo Mini 2)を見つけました。
この機器については、こちらの記事をどうぞ。
付属しているiPhoneアプリには温度がリアルタイムで表示されており、もしかしたら自作のWebアプリにも温度を自動で取り込めるのではないかな、と考えました。
最初はRuby on Railsで作成しようと思ったけど、調べたらGAS(Google Apps Script)でされていた方がいたので、そちらを参考にしてやってみました。
GASについては全くやったことなかったので、コードは丸々コピペですが、一つずつ調べながらやったので、今回はその記録も兼ねて。
補足:
参考サイトはNature Remo 3なので温度・湿度・人感センサーがついているですが、私の所持品はその下位機種(Nature Remo mini 2)のため温度センサーのみになっています。
アプリの概要
Google スプレッドシートにApp Scriptを追加する方法もあったけど、今回はそれぞれを独立させることにしました。
このプログラムは、Nature Remo APIを使用してデータを取得し、Google スプレッドシートに記録するためのものです。
スクリプトを実行するには、Google Apps Script エディタ内でスクリプトを新規作成し、適切なアクセストークンとスプレッドシートのIDを設定し、main() 関数を実行する必要があります。
アクセストークンの発行は、https://home.nature.globalから行っておいてください。
スプレッドシートも新規作成し、A1に時刻、B1に温度、と入力しておきます。
Nature Remoからデータ取得するプログラム
var access_token = 'XXX' // XXXにはアクセストークンを代入
var spreadsheetId = 'XXX' // XXXにはスプレッドシートIDを代入
function main() {
var data = getNatureRemoData();
var lastRow = getLastRow();
setLatestData(data, lastRow+1);
}
// Nature RemoへGETリクエストを送信します。
function getNatureRemoData() {
var url = "https://api.nature.global/1/devices";
var headers = {
"Content-Type" : "application/json;",
'Authorization': 'Bearer ' + access_token,
};
var options = {
"method" : "get",
"headers" : headers,
};
var data = JSON.parse(UrlFetchApp.fetch(url, options));
return data;
}
// スプレッドシートの最終セルを取得します。シート名をlogに変更しておくこと!
function getLastRow() {
var datas = SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getDataRange().getValues()
var data = datas[datas.length - 1]
return datas.length;
}
function setLatestData(data, row) {
SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 1).setValue(new Date())
SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 2).setValue(data[0].newest_events.te.val)
}
プログラムの解説
全体で使用する変数を設定
var access_token = 'XXX' // Nature Remo APIのアクセストークン
var spreadsheetId = 'XXX' // Google スプレッドシートのID
プログラム全体で使用する変数を2つ設定しておきます。
変数 access_token は、Nature Remo API のアクセストークン
変数spreadsheetId は、データを記録するための Google スプレッドシートのID
を表しています。
これらの値は、それぞれ適切な値に置き換える必要があります。
main()関数
function main() {
var data = getNatureRemoData(); // Nature Remoからデータ取得
var lastRow = getLastRow(); // データがあるスプレッドシート最終行を取得
setLatestData(data, lastRow+1); // 最終行の1つ下に最新データを代入
}
main() 関数はプログラムのエントリーポイントであり、Nature Remoからデータを取得し、最終行に最新のデータをセットします。
getNatureRemoData() 関数
// Nature RemoへGETリクエストを送信します。
function getNatureRemoData() {
var url = "https://api.nature.global/1/devices";
var headers = {
"Content-Type" : "application/json;",
'Authorization': 'Bearer ' + access_token,
};
var options = {
"method" : "get",
"headers" : headers,
};
var data = JSON.parse(UrlFetchApp.fetch(url, options));
return data;
}
getNatureRemoData() 関数は、Nature Remoデバイスからデータを取得するためのGETリクエストを送信する関数です。
変数url には、APIのエンドポイントを指定します。
変数headers には、リクエストに必要なヘッダー情報を格納します。
変数options には、リクエストのメソッドとヘッダーを指定します。
変数data には、UrlFetchApp.fetch(url, options) を呼び出すことでリクエストが送信され、取得したデータを格納されます。
getLastRow() 関数
// スプレッドシートの最終セルを取得します。
function getLastRow() {
var datas = SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getDataRange().getValues()
var data = datas[datas.length - 1]
return datas.length;
}
getLastRow() 関数は、指定されたスプレッドシートの 'log' シートの最終行を取得する関数です。
SpreadsheetApp.openById(spreadsheetId) を使用してスプレッドシートを開き、getSheetByName('log') を使用して 'log' シートを取得します。
getDataRange().getValues() を呼び出すことで、シートのデータ範囲を取得し、変数datas に格納します。
datas.length - 1 のインデックスを使用して最後の行のデータを取得し、その行番号を返します。
※初期設定のままの人は、スプレッドシートのシート名を「log」にしておいてください。そうしないとシート名が合わなくてエラーが出ます。
setLatestData() 関数
function setLatestData(data, row) {
SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 1).setValue(new Date())
SpreadsheetApp.openById(spreadsheetId).getSheetByName('log').getRange(row, 2).setValue(data[0].newest_events.te.val)
}
setLatestData() 関数は、受け取ったデータと行番号を使用して、スプレッドシートの指定された行に最新のデータをセットする関数です。SpreadsheetApp.openById(spreadsheetId) を使用してスプレッドシートを開き、getSheetByName('log') を使用して 'log' シートを取得します。getRange(row, 1) を呼び出すことで、指定された行と1列目のセルを取得し、setValue(new Date()) を呼び出すことで、現在の日時をセルにセットします。
同様に、getRange(row, 2) を呼び出して2列目のセルを取得し、setValue(data[0].newest_events.te.val) を呼び出してデータの特定の値をセットします。
15分ごとに実行させる設定
App Script の左側に「トリガー」があるので、選択します。
その後、画面右下に「トリガーを追加」ボタンがあるので選択します。
トリガー追加画面で、
「分ベースのタイマー」「15分おき」
を選択します。
これで15分おきに定期実行してくれます。
たったこれだけで、すごい。ちょっと感動しました。
最初に実行してから15分おきに実行されるので、毎時00分とかに設定したい人は調べてやってみてください。
まとめ
Ruby on Railsの勉強をしてきたけど、外部センサーからデータを取り込んで操作したことがなく、いつかやってみたいと思っていました。
たまたま手元に Nature Remo があったので、今回はそちらを使ったけど、Raspberry PI を使ったりしてみたいです。
設置したセンサーからクラウドにデータをアップして、それをWebアプリから拾って集計し、操作もできるといろいろなことに応用できるんだろうな。
今回、初めてAPIを使ってみたのですが、初歩中の初歩だと思います。
あと感動したのが、GAS(Google Apps Script)です。
サーバーレスで定期的にデータを収集までやってくれるなんて。
しかも無料。
GASって便利だよ、とは聞いていたものの…。
もっといろいろできるんだろうな、と感じたので、また勉強してみます。
あと、今回できていないリモート操作にも挑戦してみたいです。
Nature Remo に似たものとして、SwitchBot があります。
2023年3月に「SwitchBot ハブ2」が登場したことで、性能・価格とも優位な状況ですね。おすすめです。
この記事が気に入ったらサポートをしてみませんか?