見出し画像

初めての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」が登場したことで、性能・価格とも優位な状況ですね。おすすめです。


この記事が気に入ったらサポートをしてみませんか?