1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GAS】IFTTT無しで自室の照明操作(Webhook→GAS→Nature Remo Cloud API)

Posted at

はじめに

2024年2月15日より、IFTTTでのWebhook実行が有料化されたみたいです。
image.png

我が家はNature Remo nanoを導入しており、自室の照明はNature Remo Cloud API経由で操作できます。
僕は睡眠解析アプリ(Sleep as Androidってやつです)で「就寝時に部屋の照明を常夜灯に」「起床時に部屋の照明をONに」するようにしていたのですが、
これは 睡眠解析アプリ→IFTTT→Webhook→Nature Remo→家電操作 で実現していたため、IFTTTでのWebhookが使用できなくなると動かなくなります。

このままでは朝起きられなくなってしまうので、IFTTTを使わず上記フローを実現してみようと思います。

作ってみる

本記事のゴールは上記フローのIFTTT部分をGASで置き換え、
睡眠解析アプリ→GAS内でWebhookへPOST→Nature Remo→家電操作 の流れを実現することとします。

Webhookの連携内容を確認(睡眠解析アプリ→Webhook)

Sleep as AndroidのWebhookでのPOST内容はここのページで確認できます。
見る限りevent: event_nameからイベント内容を取得できそうなので、
sleep_tracking_startedで照明を常夜灯」「sleep_tracking_stoppedで照明をON」とするように組んでみます。

ぶっちゃけトリガーは睡眠解析アプリである必要も無いので、やりたいことに応じてフロント側を実装するで良いと思います。

IFTTTの代わりにGASでWebhookの受け口を作る(GAS→Nature API)

無料で簡易なWebアプリを作れるでおなじみ、Google Apps Scriptにお世話になることとします。

Nature APIのアクセストークンを取得

Nature APIの操作にはアクセストークンが必要なので、事前に取得しておきます。
Access Tokens ページから Generate Access Token でアクセストークンを取得します。
一度ページを離れると再表示できないので、確実にメモっておきます。

このトークンがあれば家電操作できてしまうため、第三者には絶対見られないようにしましょう。
もし見られてしまった場合、上記ページから Client name : me となっている行の Revoke を押してトークンを無効化してから再発行しましょう。
image.png

GASでプロジェクトを作成し、 プロジェクトの設定 > スクリプト プロパティ から先ほどのトークンをプロパティに入力しておきます。
APPLIANCE_ID は後ほど入れます)
image.png

ソースコードに直書きしても動きはしますが、今回はトークンの流出防止としてこのような作りにしてみます。

Appliance ID(家電1つに紐づくID)を取得

Nature APIはここのページで内容確認できます。
今回は照明操作なので 1/appliances/{applianceid}/light へPOSTすることになりますが、
applianceid(家電1つに紐づくID)とbutton(操作するボタンの種類)が必要なのでまずはそれを取得します。

/**
 * 家電操作用のAPPLIANCE_IDを取得
 */
function getApplianceId () {
  const appliances = getNatureApi_('/1/appliances').filter((appliance) => appliance.type === 'LIGHT');
  Logger.log(appliances.map(appliance => ({
    nickname: appliance.nickname,
    id: appliance.id,
    buttons: appliance.light.buttons})
    ));

}

/**
 * Nature API(GET)を実行
 * @params apiPath : APIのパス(https://swagger.nature.global/#/)
 */
const getNatureApi_ = (apiPath) => {
  const options = {
    headers: {'Authorization': `Bearer ${PropertiesService.getScriptProperties().getProperty('NATURE_API_ACCESS_TOKEN')}`},
  };
  return JSON.parse(UrlFetchApp.fetch(`https://api.nature.global${apiPath}`, options).getContentText());
};

getApplianceId()を実行するとGASのログにJSONとして出力されます。
ここからapplianceidbuttonをメモっておき、
applianceidはアクセストークンと同様にスクリプトプロパティに登録しておきます。

getNatureApi_()の関数名末尾にアンダースコアがついていますが、これをつけることでprivate関数扱いになるみたいです。
サーバー側の関数呼び出しの対象外になったり、GASのエディター上からも直接実行できないようにできるので
外部から呼び出す想定のある関数以外はアンダースコアをつけたほうがいいのかもしれないです。

POSTの受け口を作る

doPost関数を用意することでWebhookを受けられるようになる、みたいです。
睡眠解析アプリからのPOST内容をもとに「どのイベントがあったかを判別→リモコンの信号を送信」といったソースを組んでみます。

/**
 * Webhookトリガーで照明を操作
 */

// Sleep側のイベントと押すボタンの種類の対応
const watchActions = [
  {event: 'sleep_tracking_started', button: 'night'},
  {event: 'sleep_tracking_stopped', button: 'on'},
];


/**
 * POSTの受け口
 */
const doPost = (e) => {
  const payload = JSON.parse(e.postData.getDataAsString());
  Logger.log(payload);

  // 行動が照明操作対象であれば、ボタンを操作する
  const action = watchActions.filter(action => action.event === payload.event);
  if (action.length) {
    postNatureApi_(`/1/appliances/${PropertiesService.getScriptProperties().getProperty('APPLIANCE_ID')}/light`, {button: action[0].button});
  }
};

/**
 * Nature API(POST)を実行
 * @params apiPath : APIのパス(https://swagger.nature.global/#/)
 */
const postNatureApi_ = (apiPath, args) => {
  const options = {
    method: 'post',
    headers: {'Authorization': `Bearer ${PropertiesService.getScriptProperties().getProperty('NATURE_API_ACCESS_TOKEN')}`},
    payload: args,
    };
  UrlFetchApp.fetch(`https://api.nature.global${apiPath}`, options);
};

watchActionsでどのイベントを拾ってどんな信号を送信するかを定義しています。
本当はこの定義はスプレッドシートでやりたかったのですが、GASからのスプレッドシート値取得ってたまに失敗するんですよね……。
確実に動作させたかったので今回はソースに直書きしています。

デバッグとして、e.postData.getDataAsString()でPOSTされたRequest Bodyを取り出した段階でログ出力しています。
ですがdoPost()の内容はこのままではログで確認できません。
以下ページを参考に、Google Cloud Platform(GCP)でログを出力できるようにしてみました。ここが一番大変だった。
Google Apps ScriptでdoPost関数のログを出力する方法3選 | prtn-blog

Webアプリとして発行

GASのページ右上の デプロイ > 新しいデプロイ から、作成したコードをWebアプリとして発行できます。
image.png

アクセスできるユーザー : 全員にした状態でデプロイし、ウェブアプリのURLをメモっておきます。
image.png

あとはこのURLにWebhookをPOSTすれば動くはずです。
もしうまく動かない場合はログを確認し、ソースを適切に修正した上で再デプロイしましょう。
その際はデプロイを管理 > 右上の編集ボタンを押下し、バージョン : 新バージョンを選んで再デプロイします。

おわりに

デバッグが一番苦労しましたが、無事IFTTT無しで以前と同様のことが実現できて良かったです。
タイムラグとしても1~2秒ほどで、感覚としては「睡眠解析を始めたらすぐ暗くなる」感じ。

ソースとしてはかなりシンプルなので、やりたいことに応じて適宜改変すれば色々できそうですね。
温度センサーと組み合わせて空調を操作させたり、フロント部分をSlackやDiscordなんかに変えても良いですね。何ならWebhookさえ投げられれば物理ボタンでも良いし。

参考にさせて頂いたHP

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?