Nature Remoの照明スイッチを作ってみた

本投稿は TECOTEC Advent Calendar 2024 の24日目の記事です。

決済認証システム開発事業部の下江です。普段はBEエンジニアとして主にPHPでWebアプリケーションシステムの開発をしています。

今回はNature Remoという所謂スマートリモコンを物理ボタンから操作する過程と作り方を書いていこうと思います。 経緯とかもつらつらと書いてますが、やったことが気になる方は実装まで読み飛ばして大丈夫です!

はじめに

皆さんスマートリモコンを使ってますか?
自分はかれこれ2年くらいNature Remo mini 2とアレクサを連携させて使ってます。
非常に便利です。ありがとうございます。
ただ時々思うことがありました。

Natureでもswitch botのリモートボタンのような製品がほしいなあと...

SwitchBot リモートボタン – SwitchBot (スイッチボット)SwitchBot リモートボタンwww.switchbot.jp

なぜリモートボタンが欲しいのか

ざっくりと言うと通話中の照明/エアコンのオンオフがしたいというのが主。
ミュート中にオンオフすれば良いという話ではあるのですが、ミュートミスがあったり、裏画面に通話が行っていてミュートを探すのが個人的には結構面倒だと感じています。
あとリモコンを手元に置いておけばいいという話でもあるのですが、リモコンが気づいたらどこかに消えてる質なので常設できるようなものが欲しいというのも

一応switch botに乗り換えてしまえば実現可能、

ただハブとスイッチで7000円

高え…
あと家電繋ぎ直すのめんどくさい...

方針

ということで上記の問題点である

  • 値段が高い

  • リモコンは消える

を解決するため半額の3500円以下、常設しても邪魔にならない、を実現できそうな方法を考えます。
幸いにも現在使っているNature remoはAPIが公開されており、小型のスイッチを押した時にAPIを叩くことが出来れば実現できそうなので今回はその方向で進めました。

デバイス

ボタンを押した時にAPIを叩くことが出来ればよいので、マイコンで実現するのが手っ取り早そうだとなり、wifiモジュールが乗ってて技適が付いている使えそうなものを適当に買いました。 Freenove ESP32-S3-WROOM

ブラックフライデーで3584円!大体3500円!

環境構築

ESP32を触ったことなかったのですが、Arduino IDE 互換と商品欄に書いてあったのでありがたく使わせてもらいます。

Arduino IDEの導入

Arduino IDE 互換ということでArduino IDEをインストールをします。
ダウンロードはこちらから。

www.arduino.cc

Arduino IDEの設定

実装にあたりいくつか細かい設定の変更を行ったのでまとめておきます。

  • [ツール] > [ボード] > [ボードマネージャ]からesp32をインストール

  • [ツール] > [ボード] > [esp32] > ESP32S3 Dev Module を選択

  • [ツール] > [ポート] から現在マイコンに繋いでいるポートを選択

    • 繋いでいるポートがわからない場合usbケーブルを抜き差しすると良いかも
  • [ツール] > [シリアルモニタ] からbaud rateを115200に変更

    • コードのSerial.beginの値に合わせてください、変更しなくても動作には影響ありませんがシリアルモニタが文字化けします。

  • [ツール] > [Partition Scheme] > Huge APP (3MB No OTA/1 MB SPIFFS)を選択
    • 今回の内容だとおそらく影響が無いですが、処理が大きくなるとエラー原因になるので回避のために入れました

関連ライブラリのインストール

APIを叩くためのライブラリはいくつかあるのですが、今回はHTTPClientを利用するのでそのインストールが必要になります。 基本的には設定同様GUIで完結してます。

  • [ツール] > [ライブラリを管理] > HTTPClientを選択

サンプルコードの実行

さて上記でここまでで一通り設定が終わったはずなので、GETリクエストのサンプルコードをインターネットとの疎通確認の意味も含めて動かしてみます。 サンプルコードは

  • [ファイル] > [スケッチ例] >[HTTPClient] > BasicHTTPClientを選択

そうすると以下と同様のファイルが開かれると思います garretlab.web.fc2.com

65行目の
wifiMulti.addAP("SSID", "PASSWORD");
に使用しているWifi のssid/passwordを入れて、
左上のマークからビルドの完了を待ちます。

動作確認

無事ビルドが通ったら動作確認です。

  • [ツール] > [シリアルモニタ]

から確認できます。

それっぽい応答があるのでヨシ!

実装

いきなり全部実装はハードルが高かったので

  • Nature API部分の実装

  • スイッチ部分の実装

をそれぞれ分けて実装し最後に合体させる方針で進めました。

Nature API

トークンの発行

NatureのAPIを叩くためにはトークンが必要なので、こちらからトークンの発行を行います。 home.nature.global ①を押すと②にトークンが出てきます。

発行後ページを離れるとトークンを確認できなくなるので注意してください。

API一覧

NatureのAPI一覧は以下から見れます。 swagger.nature.global
思ってたより多いですね。
GETでは
https://api.nature.global/1/appliances
POSTでは
https://api.nature.global/1/appliances/{appliance_id}/light
を使ってベースのコードを作ろうと思います。

GET

アプライアンス一覧API ( https://api.nature.global/1/appliances ) でGETの動作確認を行います。
サンプルコードをベースにしつつ複数回呼ぶ必要も一旦無いのでシンプルにsetupだけで実行するように変えました。
loopに制御を入れずに書いてしまうとすぐにNatureのAPI制限(5分30回)に引っ掛かってしまうので気を付けましょう。(一敗)
トークンによる認証はBearerでできるのでhttp.addHeaderを追加して対応しています。

  • コード
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>

#define SSID "{ssid}"
#define PASSWORD "{password}"

#define API_PATH "https://api.nature.global/1/appliances"
#define API_TOKEN "{api_token}"

WiFiMulti wifiMulti;

void setup() {
  Serial.begin(115200);
  wifiMulti.addAP(SSID, PASSWORD);

  if (wifiMulti.run() == WL_CONNECTED){
    HTTPClient http;

    http.begin( API_PATH ); 
    http.addHeader("Authorization", "Bearer " API_TOKEN);

    int httpCode = http.GET();

    if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        Serial.println(payload);
    } 
    http.end();  
  }
}

void loop() {
 
}

手元で試す際は
ssid/password/api_tokenを埋めてください。

  • 動作確認

それっぽい応答が見えます。

適当に整形するとIDとかいろいろ見て取ることができます。 今回は照明の切り替えがしたいので、typeがLIGHTになっている場所のidをメモしておきます。(POSTで使います)

POST

照明制御API( https://api.nature.global/1/appliances/{appliance_id}/light )でPOSTの動作確認を行います。
実装内容に関してはほぼほぼGETと同一です。
差異としては、GETと異なりPOSTはHTTPClientの仕様上引数必須なので http.POST("") とします。
リクエストパラメータにはURLを用いているようなので特に何か入れる必要ありません。

  • コード
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>

#define SSID "{ssid}"
#define PASSWORD "{password}"

#define API_PATH "https://api.nature.global/1/appliances/{appliance_id}/light?button=off"
#define API_TOKEN "{api_token}"

WiFiMulti wifiMulti;

void setup() {
  Serial.begin(115200);
  wifiMulti.addAP(SSID, PASSWORD);

  if (wifiMulti.run() == WL_CONNECTED){
    HTTPClient http;

    http.begin( API_PATH ); 
    http.addHeader("Authorization", "Bearer " API_TOKEN);

    int httpCode = http.POST("");

    if (httpCode == HTTP_CODE_OK) {
        String payload = http.getString();
        Serial.println(payload);
    } 
    http.end();  
  }
}

void loop() {
 
}

手元で試す際は
ssid/password/appliance_id/api_tokenを埋めてください。
appliance_idはGETの項でメモしたIDになります。

  • 動作確認

部屋が暗くなったのでヨシ!

スイッチ制御

最低限電圧を読めればいいので以下のように実装しました。
PIN_NOを9にした理由は特にないので自由に変えて大丈夫です。

  • 配線

  • コード

#include <Arduino.h>

#define PIN_NO 9

void setup() {
  Serial.begin(115200);
}

void loop() {
  Serial.println(analogRead(PIN_NO));
  delay(500);
}
  • 動作確認

押したときの表示は2400前後
押してないときの表示は150前後なので、上手く行っていそうです。

合体

Nature APIのPOSTコードとスイッチコードを合体させて
スイッチが押された後APIが飛ぶように実装を変更します。
スイッチ制御の動作確認で押されたときの電圧表示が2400前後、押されていない時の電圧表示が150前後だったので、 2000を越えたらAPIを呼ぶフローに入るように実装します。

  • コード
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>

#define SSID "{ssid}"
#define PASSWORD "{password}"

#define API_PATH "https://api.nature.global/1/appliances/{appliance_id}/light?button=off"
#define API_TOKEN "{api_token}"

#define PIN_NO 9
#define THRESHOLD_VOLTAGE 2000

WiFiMulti wifiMulti;
int api_flg = 0;

void setup() {
  Serial.begin(115200);
  wifiMulti.addAP(SSID, PASSWORD);
}

void loop() {
  if ((wifiMulti.run() == WL_CONNECTED) && api_flg == 1) {
    HTTPClient http;

    http.begin( API_PATH ); 
    http.addHeader("Authorization", "Bearer " API_TOKEN);

    int httpCode = http.POST("");
    
    if (httpCode == HTTP_CODE_OK) {
      String payload = http.getString();
      Serial.println(payload);
    }

    api_flg = 0;
    http.end();
  }

  if(analogRead(PIN_NO) > THRESHOLD_VOLTAGE){
    api_flg = 1;
  }

  delay(500);
}

手元で試す際は
ssid/password/appliance_id/api_tokenを埋めてください。
またしきい値(THRESHOLD_VOLTAGE)は各々の環境で変動すると思うので適切と思う値を入れてください。

  • 動作確認

動いた!!

おわりに

ここで終わるのかよ!ってなった人すみません。
時間なくてここまでしかできませんでした。
一応ここまで出来ていればAPIで状態取ってきてオンオフしたり、基板実装して小型化したりは何とかなるはず...

ESP32は初めて触ったのですが、一応学生のころArduino を少しだけ触ってたので思ってたより取っつきやすかったです。
今回は触る余裕が無かったのですが、この今回購入したESP32+色々セット、カメラモジュールついてたり、スピーカついてたり、照度センサついてたりと意外と付属品が多くまだまだ遊べそうだなとなってます。
今回十分に実装しきれなかったので、諸々込みでまた実装したモノをブログにでも書ければなあと思います。

途中で予算オーバーしてそうなこと書きましたが、調べてみると付属品要らねえよって人には500円を切る勢いの値段でESP32の互換が売っていたので、今回のブログの範囲であれば1000円以下で全部できちゃうと思います。
気になった人はぜひやってみてはどうでしょうか?

テコテックの採用活動について

テコテックでは新卒採用、中途採用共に積極的に募集をしています。
採用サイトにて会社の雰囲気や福利厚生、募集内容をご確認いただけます。
ご興味を持っていただけましたら是非ご覧ください。 tecotec.co.jp