2020年12月19日土曜日

スマートプラグ(TP-Link HS105)をスプレッドシートからIFTTT経由でスイッチングする。

前回投稿の「アメダスのデータをGASのWebスクレイピングで自動取得する」で取得したデータを元に、スマートプラグを用いて湿度が一定の値を上回ったら扇風機の電源をON、下回ったらOFFに、自動で切り替わるようにしてみました。


今回使ったスマートプラグは「TP-Link HS105」です。1,600円で購入。2つセットだともう少しお得に販売していますね。

設定したタイマーやスケジュールによるON/OFFは、ややこしいことをしなくても専用アプリから自動化できます。便利ですね。


今回は、湿度の値によってON/OFFを切り替えたいため、アメダスのデータからGAS(Google Apps Script)でON/OFFの判定をしてスプレッドシートに入力、スプレッドシートをトリガーとしてIFTTT経由でスイッチングを行うようにしました。

IFTTTというのは、Webサービス間の連携をしてくれるWebサービスで、例えばBloggerに投稿をしたら自動でタイトルとURLをTwitterでシェアする、みたいなことができます。今回使うスマートプラグも対応しています(サービス名はTP-Link Kasa)。これまであまりしっかり使ったことがなかったので、これを機に。

以下、作り方です。


① スマートプラグのセッティング

TP-Link HS105の初期設定は公式のページにわかりやすく書いてあります(「アプリ「Kasa」でミニ スマートWi-Fiプラグの初期設定をするには」)。簡単でした。

注意点としては、プラグが左右で幅の違う極性付きプラグ(N極があるプラグ)になっているので、壁から直接でない場合は対応したコードが必要になります。見事に引っかかりました(笑)。壁は基本的にJIS規格で対応したものになっているとのこと。

安価なもので、こちらのコードが対応していました。ただ、合わせ買い対象商品なので何かのついでに買うのがいいですね。


② スプレッドシートの準備

IFTTTでトリガーとするスプレッドシートの表を作成します。

アメダスのデータを取得しているスプレッドシートとは別に新しいファイルを作成します。追加したシート(gid=0以外のシート)はIFTTTで指定できないようです。


B2、B3のセルをIFTTTのトリガーとして利用します。初期状態で空白だと動かないようなので、適当な値を入れておきます。

シート名は「control」にしておきます(コード作成時にこの名前で使います)。


③ GASでON/OFFの判定

アメダスのデータを取得するタイミングでON/OFFの判定もしたいので、前回投稿のアメダスのデータを取得するスクリプトに関数+αを追記します。

コードは以下の通りです。
var spreadsheet1 = SpreadsheetApp.openById("スプレッドシートID(アメダスデータ)");
var dataSheet = spreadsheet1.getSheetByName("data");

var spreadsheet2 = SpreadsheetApp.openById("スプレッドシートID(トリガー表)");
var conSheet = spreadsheet2.getSheetByName("control");
  
function getAmadasToday() {
  var dataLastRow = dataSheet.getLastRow();
  
  var opt = {"contentType":"text/html;","method":"get"};
  var dataAmd = "";
  var contentAmd = "";
  var postText = "";
  var urlAmd = "アメダスURL";
  
  var date_and_time = new Date();
  var dataDate = Utilities.formatDate(date_and_time, "JST", "yyyy/MM/d H");
  var time = Utilities.formatDate(date_and_time, "JST", "H");
  if(time == 0) {
    time = 24;
  }
  var min = Utilities.formatDate(date_and_time, "JST", "mm"); //参考(取得分)
  var conDate = Utilities.formatDate(date_and_time, "JST", "yyyy/MM/dd H:mm"); //control記載用

  var middleArr = [];
  var tableArr = [];

  dataAmd = UrlFetchApp.fetch(urlAmd ,opt);
  contentAmd = dataAmd.getContentText();
  postText = getStringSlice(contentAmd, '<td class="time left">' + time + '</td>','</tr>');
  postText = postText.replace(/<\/td>/g, '</td>,');
  postText = postText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, '');
  postText = postText.replace( /\r\n/g , "\n" );
  postText = postText.replace( /^(\n+)|(\n+)$/g , '');
  postText = postText.replace(/\/\/\//g, '');
  postText = postText.replace(/&nbsp;/g, '');
  middleArr = postText.split( /\n/g );
  tableArr[0] = middleArr[0].split(",");
  tableArr.splice(0,0);
  
  if(tableArr[0][0] != "" && dataDate != dataSheet.getRange(dataLastRow, 1).getValue()) {
    dataSheet.insertRows(dataLastRow + 1);
    dataSheet.getRange(dataLastRow + 1, 1).setValue(dataDate);
    dataSheet.getRange(dataLastRow + 1, 2, 1, 8).setValues(tableArr);
  
    control(tableArr[0][5], conDate);
  }
}

function getStringSlice(content, startStr, endStr) {
  var indexStart = content.indexOf(startStr);
  if(indexStart == -1){
    return "";
  } else {
    indexStart += startStr.length
    return content.slice(indexStart, content.indexOf(endStr, indexStart));
  }
}

function control(hu, time) {
  var staOn = conSheet.getRange(2, 4).getValue();
  var staOff = conSheet.getRange(3, 4).getValue();

  if(hu > 80 && staOn == "") {
    conSheet.getRange(2, 2).setValue(hu);
    conSheet.getRange(2, 3).setValue(time);
    conSheet.getRange(2, 4).setValue("ON");
    conSheet.getRange(3, 4).setValue("");
  } else if(hu < 70 && staOff == "") {
    conSheet.getRange(3, 2).setValue(hu);
    conSheet.getRange(3, 3).setValue(time);
    conSheet.getRange(3, 4).setValue("OFF");
    conSheet.getRange(2, 4).setValue("");
  }
}

書き換えが必要なのは次の通りです。

・1行目、4行目「スプレッドシートID」

1行目がアメダスのデータを入力しているスプレッドシート、4行目がトリガーとなる表のスプレッドシートです。スプレッドシートを開いた状態でURLの下記部分に表示されます。ちょっと長めです。

https://docs.google.com/spreadsheets/d/ここの値をコピペ/edit#gid=0


・14行目「アメダスURL」

https://www.jma.go.jp/jp/amedas_h/ より取得する地点を選んでください。

小名浜の場合ですと、 https://www.jma.go.jp/jp/amedas_h/today-36846.html になります(?より後ろにくっついている文字は必要ありません)。


・44行目「8」

取得する要素数によって変わります。要素数+1の値を入れてください。


・46行目「5」

取得する要素のうち、湿度の順番を0から数えて入れます。小名浜の場合ですと6番目なので5になります。


・64行目「hu > 80」、69行目「hu <= 70」

今回は湿度が80%を上回ったら電源をON、70%を下回ったらOFFという条件にしています。適宜変更してください。


以上です。


ON/OFFの判定は、アメダスのデータを取得するスクリプトとは分けてしまってもいいのですが、そうすると余計にGASのトリガーを設定しなければならないのと(制限がある)、アメダスの測定時(毎正時)〜アメダスのデータ取得〜ON/OFFの判定と、タイムラグが大きくなってしまうまめ、ひとつにまとめました。


④ IFTTTの設定

スプレッドシートの「Cell updated in spreadsheet」をトリガーに、スマートプラグを「Turn on」、もしくは「Turn off」にします。ON、OFF、それぞれアプレットが必要なので2つ作ることになります。

トリガーは「If This」より、

・「Google Sheets」 → 「Cell updated in spreadsheet」を選択
・「Or copy and paste the spreadsheet URL」 → https://docs.google.com/spreadsheets/d/スプレッドシートID(トリガー表)
・「Which cell to monitor?」 →  B2(Turn on) / B3(Turn off)


アクションは「Then That」より、

・「TP-Link Kasa」 → 「Turn on」 / 「Turn off」
・「Device」 → 今回設定したスマートプラグ


となります。


⑤ 動かしてみる

と言っても、条件が満たされないと動かないのですが……。

80%を上回ったのでON。



70%を下回ったのでOFF。



うまく動きましたでしょうか。

GASのログを見るとアメダスのデータは11分に取得しているようなので、IFTTTが動くまでに若干タイムラグがありますね。

***


ちなみに、そもそもなぜ湿度によって扇風機を回すのかというと、雨の日のような湿度が高い状態が続くとやはり椎茸も水分量が多くなってしまうのですね。そこで、扇風機で空気を動かすことで幾分でも緩和できないか、という実験をしています。

ハウス内の湿度が高すぎる状況というのは、外気の湿度が高すぎて換気で落とせないパターンなので、ハウス内のNature Remoではなくアメダスのデータを使用しました。



今回は単純に湿度の値でしたが、この方法ならスイッチングの条件を自由に作れます。スマート農業にも、いろいろと使えそうですね。

ただ、IFTTTの有料化にともない、無料アカウントではアプレットが3つまで、かつそれぞれ1時間毎に1回までしか起動できないようです。

この方法は、ON/OFFにアプレットを2つ使ってしまうため、2つ以上の機器、もしくは1時間に1回以上の頻度でON/OFFの切り替えを想定する場合には、有料版にする必要があります。あと、有料版であればIFTTTが動くまでのタイムラグも小さくなるみたいです。他にも機能的にはだいぶできることが増えるようなので、本格的なスマート化にあたっては有料化もありかもですね。


他の方法としては、今回使ったスマートプラグのTP-Linkには、公開されているAPIがあり、IFTTTを使わずに直接操作することも可能みたいです。ただ公式のAPIではない?ようなので、自己責任の範囲でという感じになるのですかね。

勉強しつつ、こちらもちょっと試してみようかと思います。




・関連投稿



Twitter(@nkkmd)、Instagram(@nkkmd)も日々更新中です。