KAKEHASHI Tech Blog

カケハシのEngineer Teamによるブログです。

スマートホームで職場(自室)環境を改善してみた

こんにちは、カケハシでMusubi Insight のバックエンドエンジニアをしている高田です。

私はカケハシへの入社と同時に兵庫県移住し、現在フルリモートで勤務しています。

そのため自室=職場であり、より生産性が上がり、気持ちよく働けるよう環境を改善したいと前々から考えていました。

そこで、冬休み使って職場(自室)の環境改善を行なったので、その内容をご紹介できればと思います。

解決したい課題

とくに冬場になり、仕事開始時の室温が低く、集中し始めるまでに時間がかかるという点を課題に感じていました。

実際に快適な室温を保つことで、タイピングミスが減ったり、一定時間内のタイプ量が増えるなど、生産性が上がるという調査結果 も報告されています。

もともと寒がりな体質ということもあり、こちらを重要課題として取り組むことにしました。

解決策

今回課題を解決するにあたり、以下のような要件を設けました。

  1. なるべく低コストで実現できること
  2. できるだけ楽に構築できること
  3. 運用が楽なこと

これらの用件を実現するために色々と考えた結果、かなり今更感はありますが、自室をスマートホーム化することに決めました。

また、部屋を移動したがまだ暖まりきっていない、といった状態を避けたかったので、部屋が温まったら通知を受け取り、それを確認した上で確実に暖かい部屋に入れるようにしていきます。

流れとしてはこんな感じです。

  1. リビングからAlexaに対してエアコンをつける指示を出す
  2. Alexaからスマートリモコンに連携され、仕事部屋のエアコンが稼働する
  3. スマートリモコンの温度センサーがエアコンの設定温度になったらLINEに通知が来る
  4. LINE通知を見てから部屋を移動し、快適な室温で仕事を開始する

実際に自分で行う必要があるのは、Alexaへの声かけとLINE通知の確認のみで、あとは全て自動化できる算段です。

スマートリモコン選び

スマートホーム化すると決めたので、スマートリモコンを選ぶ必要があります。

今回のやりたいことを解決するためには少なくとも以下の機能が必要になります。 - スマートスピーカーと連携できること - 温度センサーが付いていること - APIが充実しており、拡張や連携が容易なこと

有名どころでいくとNature RemoSwitchBot Hub がありますが、どちらも上記機能を満たしていそうでしたので、よりレビューが良かったNature Remoを導入しました。

スクリーンショット 0004-01-03 9 09 18

Nature Remoの設定とAlexaとの接続

Nature Remoが届いたので、早速初期設定します。

基本的にアプリの指示に従っていけば、簡単に設定できるようになっていますが、困ったことがあれば公式チュートリアル にも、動画付きで非常に詳しくセットアップ方法が解説されています。

アプリに従って、初期設定、エアコンの登録、スマートスピーカーとの連携を完了させました。

Nature RemoではAmazon Alexa、Google Assistant、Siriなどの大手スマートスピーカーに対応しています。

学生時代にRaspberryPiと電子部品を買って、赤外線の受発信機を作ったことがありますが、なかなか苦戦した記憶があり、この楽さには感激しました(笑)

設定の確認としてリビングから「Alexa、エアコンつけて!」と言うと、仕事部屋のエアコンが起動していることが確認できました。

温度検知からのLINE通知

NatureRemoにはオートメーションの機能があり、たとえば温度が○度以下になった場合にエアコンをつける、といった制御ができます。

しかし、その条件から外部に通知を出すといったことができなかったので、その部分は自前で実装することにしました。

低コストかつなるべく楽に、ということでサーバーを立てたりはせず、Google Apps Script(GAS)を使って実装していきます。

ステップとしては、4つの作業が必要でした。 1. Nature RemoのAPIトークンを取得 2. LINE NotifyのAPIトークンを取得 3. Nature Remoから現在の温度を取得し、条件を元にLINE通知する部分の実装 4. 定期的に実行されるようトリガーに登録

1. Nature RemoのAPIトークンを取得

Nature Remoの情報を外部から取得するには、APIによる通信が必要になります。 API通信にはトークンが必要なので、まずはNature RemoのAPIトークンを取得します。 Nature Remoの開発者用ページ からログインし、トークンを発行します。

ログインが完了すると、このようにスマートスピーカーのトークンが登録された状態となっているかと思います。 「Generate access token」をクリックし、自前のプログラム用のトークンを生成します。 スクリーンショット 0004-01-03 9 08 57

必要な情報を入力し、以下のようにトークンが表示され、Client nameがMeの行が追加されていればNature Remoのトークン生成は完了です。 スクリーンショット 0004-01-03 9 09 18

なお、Nature RemoのAPIはswagger で公開されており、インターフェースを確認したり、ちょっとした動きを確認したりするのに大変便利です。

2. LINE NotifyのAPIトークンを取得

LINE連携をするためには、LINE Notify のAPIトークンも必要になります。

LINE Notifyは、外部WebサービスやアプリケーションからAPI経由でLINEアカウントに通知メッセージを配信できるサービスです。

個別に開発をすることなく、天気情報や特定の言葉を含んだメールの受信などさまざまなサービスの通知をLINE上で受け取ることが可能になります。

LINE Notifyのページにログインすると、このような画面が表示されるので、「トークンを発行する」をクリックします。

スクリーンショット 0004-01-03 8 31 08

次に、トークン名の設定と通知を送信するトークルームを選択します。ここでグループを選択すると複数人にまとめて通知することもできます。

リビングで使う場合などで家族に通知するといったユースケースでは便利そうです。

今回は自分の仕事部屋なので、自分を選択します。

スクリーンショット 0004-01-03 8 33 32

そして、「発行する」をクリックするとトークンが発行され、LINE側にも通知きます。

スクリーンショット 0004-01-03 8 33 53

スクリーンショット

3. Nature Remoから現在の温度を取得し、条件を元にLINE通知する部分の実装

Nature RemoとLINE NotifyのAPIトークンが取得できたので、実際のロジックを実装していきます。

今回部屋が適温になったかどうかの判定は、リモコンの設定情報と、Nature Remoの温度センサーの温度の差分から計算します。 どちらもNature Remo APIから取得することが可能です。

差分が0度、つまり室温がリモコンの設定温度と一致した場合のみ通知を送るという条件にすると、設定温度まで到達せずなかなか通知が来ないということが発生したので、 室温と設定温度がプラスマイナス1.5度で通知が来るように調整しました。

完成したコードはこちらです。

const REMO_TOKEN = "NatureRemoのトークン";
const LINE_TOKEN = "LINE Notifyのトークン";
const REMO_DEVICE_API_URL = "https://api.nature.global/1/devices";
const REMO_APPLIANCE_API_URL = "https://api.nature.global/1/appliances";
const LINE_NOTIFY_API_URL  = "https://notify-api.line.me/api/notify";

function moderateTemperatureNotifier() {
  // 現在の設定を取得
  const applianceData = fetch(REMO_APPLIANCE_API_URL, "get", REMO_TOKEN);
  const airconSettings = applianceData.filter(function(val) {
    return val["aircon"] != null
  })[0]["settings"];
  const isOff = airconSettings["button"] == "power-off";
  const settingTemperature = airconSettings["temp"]

  // エアコンがOFFの場合は終了
  if (isOff) {
    Logger.log("エアコンがOFFになっています")
    return;
  }

  // 現在の室温を取得
  var remoData = fetch(REMO_DEVICE_API_URL, "get", REMO_TOKEN);
  var latestTemperature = remoData[0]["newest_events"]["te"]["val"];
  Logger.log("現在の室温:{0}");
  Logger.log(latestTemperature);

  // 適温になったらLINE通知
  if (isModerateTemperature(settingTemperature, latestTemperature)) {
    const payload = {
      message: "\nオフィスが適温になりました。\n仕事を開始してください。"
    }
    const result = fetch(LINE_NOTIFY_API_URL, "post", LINE_TOKEN, payload);
    Logger.log(result);
    
    // トリガーを削除して処理を止める
    delTrigger();
  }
}

function fetch(url, method, token, postData = {}) {
  var headers = {
    "accept": "application/json",
    "Authorization": "Bearer " + token,
  };

  var options = {
    "method" : method,
    "headers" : headers,
    "payload": postData,
  };
  
  return JSON.parse(UrlFetchApp.fetch(url, options));
}

function isModerateTemperature(settingTemperature, latestTemperature) {
  // 適温かどうかを判定するロジック
  const temperatureRange = 1.5;
  return Math.abs(settingTemperature - temperatureRange) <= temperatureRange
}

こちらを実行し、適温だと判定されるとこのような通知がLINEに届きます。

スクリーンショット 0004-01-03 9 08 57

4. 定期的に実行されるようトリガーに登録

ここまででLINE通知までができるようになったので、最後に定期的に実行されるようトリガーに登録します。

また、上記の適温検知のコードは、実行時に一度しか判定を行わないので、まだ適温になっていない場合、数分待って再度実行させる必要があります。

今回は5分おきに実行し、適温になったら定期実行を止める、という作りにします。

このあたり、GASのトリガーで完結すればよかったのですが、なかなか柔軟性がなく実現が難しかったので、5分おきに実行するジョブをセットするsetTriggerを作成することで実現しました。

トリガー用のコードがこちらです。

function setTrigger() {
  const now = new Date();
  ScriptApp.newTrigger("moderateTemperatureNotifier").timeBased().everyMinutes(5).create();
}

function delTrigger() {
  const triggers = ScriptApp.getProjectTriggers();
  for(const trigger of triggers){
    if(trigger.getHandlerFunction() == "moderateTemperatureNotifier"){
      ScriptApp.deleteTrigger(trigger);
    }
  }
}

だいたい9:00~10:00の間に仕事を開始することが多いので、その間で通知が来るようにしていきます。

このsetTriggerが毎朝8:00~9:00に実行されるようセットします(GASの時間イベントは固定時間が設定できずレンジがある)。

setTriggerが実行されたタイミングから、5分間隔で適温検知ジョブがキックされ、適温になったらLINEに通知が来るようになります。

スクリーンショット 0004-01-04 9 12 39

ただし、setTriggerでセットされた適温検知ジョブは、明示的に止めない限りLINE通知が来続けてしまいます。

そのため一度適温を検知するか、10:00になっても適温になっていない場合は、 delTriggerを使って適温検知ジョブを削除します。

スクリーンショット 0004-01-04 9 13 29

以上で、快適な温度の中、仕事を開始できるようになりました。

最後に

最後まで記事をご覧いただき、ありがとうございます。

本記事では、リモートワークを快適にするために私が取り組んだ内容をご紹介しました。

カケハシは地方移住に対して非常に理解があり、私以外にも地方からフルリモートで勤務している社員が多数在籍しています。

今後さらに、全国各地の様々なバックグラウンドを持った方々と一緒に仕事ができるようになると嬉しいです!