🛏

Node-RED&SwitchBotAPI(v1.1)で柔軟に家電を制御する

2023/12/16に公開

TL;DR

  • Node-REDを基盤としたスマートホームの環境を作った
  • 使用デバイス:SwitchBot ハブ2, Google Nest mini
  • 使用ソフトウェア:Node-RED, SwitchBotAPI(v1.1), beebotte, IFTTT(beebotte, IFTTTは無料枠)
  • 暮らしを楽にするために以下のようなアプリを作ったところ自分が幸せになった
    • 平日7時になったら部屋の電気を点灯する
    • 平日23時になって部屋がまだ明るかったら常夜灯にしてタイマーをつける
    • 外出したら消灯,帰宅したら点灯する
    • 夜22時になってまだ部屋が明るかったら言葉で褒めてもらう

はじめに

なんか作ろうの会の原田です。

原田イメージ

あなたが「怠惰、短気、不遜」なエンジニアであるなら、日々忙しく過ごされていることでしょう。
忙しいからこそ、部屋の電気くらい自分の望んだタイミングで自動的に点いて欲しいわけです。
自動的にというのが大事なところです。既に「アレクサ、電気をつけて」というセリフで電気の点灯はできるでしょう。
しかしそれでは不足で、本当に欲しいものは「都度指示しなくても思い通り動いてくれる仕組み」でしょう。
人が機械に依頼をしなくても、機械が状況に応じてON/OFFをしてくれる仕組みが嬉しいはずです。
私は近頃「アレクサ、電気つけて」と口に出して言うのすら面倒と感じているのもあって、
時間や何らかの条件(トリガーという)を満たしたら、電気をON/OFFするといった家電の操作などの行動(アクションという)をしてくれるものを目指しました。

この記事はSwitchBotハブ2を買って赤外線リモコンを登録して声で制御するくらいはできたよ!という方向けの記事です。
この記事の通りに実行すると、Node-REDとSwitchBot APIを使って自由自在に家電を制御できるようになるでしょう。[1]
なお、全くの初心者にはつらいかもしれません。特に考察部分。アーキテクチャについての言及がほとんどなので、読み飛ばしていいですほんと。

記事の前提として、部屋にSwitchBotハブ2が置いていること、
天井ライトは赤外線リモコンで制御できることとします。
流石にリモコン制御できないものは面倒すぎます。

なお私の部屋の天井ライトは2008年製(瀧住電機 TXG-8748)でした。古すぎワロタw
リモコンはこちら。全灯、調光、豆球、消灯、タイマー30分、タイマー60分がすべて独立している形式です。
何よりいい感じの変色具合です。黄色いなぁw


天井ライトのリモコン、赤外線式

概要(やりたかったこと)

上にも書きましたが、Node-REDをスマートホームの基盤として、
部屋の天井ライトの操作をメインに以下の4つのことを実現します。説明は主にNode-RED上での操作にします。

  • 平日7時になったら部屋の電気を点灯する
  • 平日23時になって部屋がまだ明るかったら常夜灯にしてタイマーをつける
  • 外出したら消灯,帰宅したら点灯する
  • 夜22時になってまだ部屋が明るかったら言葉で褒めてもらう

この記事では割愛すること

初心者向きの内容ではないことをお断りして、以下の内容はばっさり割愛します。
ただし、キーとなる情報はリンクを載せておくので調べられるようにしておきます。

内容 備考(設定など)
Node-REDとは?インストール方法は? イベントドリブンなアプリケーションを作れるローコードプラットフォームです。(Node-REDユーザ会)
SwitchBotAPIとは? SwitchBotのデバイスを扱えるWeb(REST) APIです。API(v1.1API仕様) なお、Python等のクライアントのライブラリは無い模様。本記事は2023/12/16時点の仕様で書いています
モバイル端末にSwitchBotアプリをインストール iOS/Androidストアから入手してログインしてください。
SwitchBotアプリに家電を制御するための赤外線リモコン信号の登録 操作したいボタンの数だけ、赤外線リモコン信号を登録してください。これがカスタムコマンドとなります。その際コマンドで制御しやすいようにsnake_caseでボタン名を登録しておきましょう(全灯はon_bright, 調光はon_little_brightといった具合)
SwitchBotのトークン取得 トークン取得手順ページを参考に取得してください。トークンは2種類あり、トークン(OpenToken)とクライアントシークレット(ClientSecretKey)という2つの情報とも必要です。
SwitchBot ハブ2のデバイスID取得 SwitchBotアプリからハブ2のデバイスの設定->デバイス情報-> BLE MACの内容から途中すべてのコロン(:)を抜いた文字列
SwitchBotに赤外線リモコン信号を登録したボタンのデバイスID取得 参考ページを参考にデバイスリストの取得とのその実行を行うと、infraredRemoteListにdeviceIdがあるのでその値を取得する
beebotteとは? クラウド上に作られた、IoT向けのリアルタイムメッセージプラットフォームです。今回の用途では無料枠で十分。REST/WebSockets/MQTTで通信できて使いやすく便利です。公式サイト
beebotteの設定 ユーザ登録後、Create a new channelでhomecontrol, resourceをcommandでtypeをstringにしておきましょう。PrivateのままでOK。Tokenができるのでtokenをコピーしておきましょう。
IFTTTとは? If This Then Thatで、(あるとき)に(なにか)を行うというサービスをつなぐサービスです。イベントとしてあるときをトリガーとして処理がアクションとして行われるようにするというものです。公式サイト
IFTTTのユーザ登録 無料枠だと3つしかアプリを登録できませんが十分でしょう。うち1つを今回使います。
モバイル端末にIFTTTアプリをインストール iOS/Androidストアから入手してログインしておくだけです。アプリで位置情報を取らせるために使います。位置情報使用を常に許可する必要があります。

使った技術要素と環境

  • Node-RED version v3.1.0
  • Node.js version v18.18.2
  • Windows11 Pro 22H2 [2]

全体アーキテクチャ

4つすべてを含めて書いているのでいくつか登場技術がありますが、分解すると大したことはありません。


アプリケーション全体

次項から一つ一つ紹介していきます。

平日7時になったら点灯する

きっかけ

単純に朝眠いから7時になったら部屋の電気をつけて起こして欲しい。

構成

Node-REDではこうしています。

  1. トリガー:Node-REDのinjectionで「平日朝7時になったら」
  2. アクション:SwitchBot APIでカスタムコマンド「全灯(on_bright)」を実行

詳細設定値

Node-RED

  • 初期化:Initialization injectionノード、Node-REDが起動した際に設定される定数を決定し、フロー変数に代入する(SwitchBotのトークン情報2つ,デバイス操作のURL)
    • flow.switchbot_open_tokenにSwitchBotのOpenTokenの値
    • flow.switchbot_client_keyにSwitchBotのClientSecretKeyの値
    • flow.ceilinglight_command_urlにデバイス操作のURL https://api.switch-bot.com/v1.1/devices/XXXXXXXX/commands XXXXXXXXはdeviceId
  • トリガー:WeekDay 7:00AM injectionノードで繰り返し実行、曜日と時間を選ぶ(月~金 AM7:00)
  • 設定:Ceiling Light:on_bright changeノードでHTTPリクエストを送る設定を行う 他のボタンも同様に作成している
    • msg.payloadに電気を点灯するコマンドの内容{"command":"on_bright","parameter":"default","commandType":"customize"}
    • msg.urlにデバイス操作のURL flow.ceilinglight_command_url
    • msg.methodにHTTPメソッドPOST POST
  • 設定:Setup to call SwitchBotAPI functionノードで後続ノードにおいてAPIリクエストを投げるための設定を行う
    • functionノードの設定でcryptoモジュールを追加する
    • functionノードのコード以下を書く

    const token = flow.get("switchbot_open_token");
    const secret = flow.get("switchbot_secret_key");
    const t = Date.now();
    const N = 16;
    const nonce = crypto.randomBytes(N).toString('base64').substring(0, N);
    const data = token + t + nonce;
    const signTerm = crypto.createHmac('sha256', secret).update(Buffer.from(data, 'utf-8')).digest();
    const sign = signTerm.toString("base64");

    // header情報をmsgに入れて次の http request ノードに送信
    msg.token = token;
    msg.sign = sign;
    msg.t = t;
    msg.nonce = nonce;
    return msg;

  • アクション:Request to SwitchBot http requestノードで上で定義したコマンドやAPI呼び出し設定を元にカスタムコマンドをSwitchbotAPIで発行する
    • msg.method, msg.urlは定義済みであり設定しない(設定空のまま)
    • ヘッダを以下の通り設定する不足しているヘッダは追加すること
    • Content-Typeapplication/json
    • Authorizationmsg.token
    • signmsg.sign
    • tmsg.t
    • noncemsg.nonce
  • 動作確認 : debugノードで成功したかを確認する

感想

アラームだけだとスヌーズにして寝てしまうことがあるので、明るくすることで無理やり起こすようにしたところ、成功しました。
まだ暗ければ起きなくて良いのはいい感じです。

平日23時になって部屋がまだ明るかったら常夜灯にしてタイマーをつける

きっかけ

つい開発して没頭していると寝るのが遅くなるから、ある程度の時間になったら強制的に寝るよう導いてしてほしかった。

構成

Node-REDではこうしています。

  1. トリガー1:Node-REDのinjectionで、平日23時になったら
  2. アクション1:SwitchBot APIでハブ2の照度計のデータを読み取る
  3. トリガー2:明るいと判断されたら
  4. アクション2:SwitchBot APIでカスタムコマンド「常夜灯(on_night_light)」の信号を送り、ついでに5秒後に「タイマー60min(timer_60min)」を送る

詳細設定値

Node-RED

  • 初期化:Initialization injectionノード、Node-REDが起動した際に設定される定数を決定し、フロー変数に入れる(SwitchBotのトークン情報,デバイス操作のURL,ハブ2のステータスを確認するためのURL)
    • flow.hub2_status_urlにハブ2のステータスを確認するためのURL https://api.switch-bot.com/v1.1/devices/XXXXXXXX/status XXXXXXXXはハブ2のdeviceId
  • トリガー1:WeekDay 11:00PM injectionノードで繰り返し実行、曜日と時間を選ぶ(月~金 PM11:00)
  • 設定:Hub2 changeノードでHTTPリクエストを送る設定を行う
    • msg.urlにハブ2のステータスを確認するためのURL
    • msg.methodGET
  • 設定:Setup to call SwitchBotAPI functionノード前項目参照
  • アクション1:Request to SwitchBot http requestノード前項目参照、ハブ2の照度を取得する
  • 設定 : Parse results(json) : jsonノードでJavaScriptオブジェクトに変換する 動作を常にJavaScriptオブジェクトに変換
  • トリガー2(条件分岐) : Switch lightLevel : switchノードで明るさによって条件分岐させる
    • プロパティmsg.payload.body.lightLevel ここに明るさデータが入っている 明るさレベルは1~20で返ってくる[3]
    • ≧10の条件で1 「点灯しているレベルの明るさ」の場合
    • ≧4の条件で2 「常夜灯レベルの明るさ」の場合
    • <4の条件で3 「消灯時レベルの明るさ」の場合
  • アクション2 : 常夜灯(on_night_light)をつける トリガー2の「点灯しているレベルの明るさ」にのみ接続すること
  • 遅延 : Delay 5s
  • アクション2 : タイマー60min(timer_60min)をつける

感想

そろそろ寝ろよ、という妻からのありがたい指示だと思うようにしていますw
時間の感覚が生まれるし、睡眠リズムを崩したくない人向けには良い仕組みです。
もう寝ていた場合(既に暗くしていた場合)はなにも起きません。トリガー2の条件分岐で既に暗いと判断された場合になにも指定していないからです。

外出したら消灯,帰宅したら点灯する

きっかけ

外出する際に電気をつけっぱなしにしたことが何回かあったので、モバイル端末の自分の位置情報を見ていいから電気消してくれよと思った。
帰ってきたときに勝手に電気がついて欲しいと思った。

構成

ここはNode-RED内ではなく、モバイル端末の位置情報をIFTTTで検知し、自宅近くのエリアの出入りをトリガーにしています。(入:Enter,退:Exit)[4]
メッセージをNode-RED側に受け渡したいため、IFTTTからはbeebotte宛にメッセージを送るようにしています。
Node-REDではbeebotte宛にメッセージが届いたら、ということをきっかけにして処理が始まります。

Node-REDではこうしています。

  1. トリガー1:IFTTTのLocationで、自宅近くに入ったら、
  2. アクション1:beebotte宛にWebhookで出入りした内容のメッセージを送る
  3. トリガー2:beebotteにメッセージが届いたら
  4. アクション2:SwitchBot APIでカスタムコマンド「調光(on_little_bright)」の信号を送る

詳細設定値

IFTTT

  • IF Location で自宅近くを選択する[5]
    • Locationのenter or exit an areaを選択
  • then Webhook で以下値を設定する
    • URLにbeebotteデータ登録用URLを指定 https://api.beebotte.com/v1/data/publish/private-homecontrol/command homecontrol/commandはbeebotteのチャンネル作成時に設定した値[6]
    • MethodPOST
    • Content Typeapplication/json
    • Additional HeadersX-Auth-Token: XXXXXXXX XXXXXXXXはbeebotteのChannel Tokenの値。赤字で書かれているもの
    • Body{"data":"EnteredOrExited"} EnterOrExitedは「材料を追加する」から選択すること

Node-RED

  • 初期化:Initialization injectionノード、Node-REDが起動した際に設定される定数を決定し、フロー変数に入れる(SwitchBotのトークン情報,デバイス操作のURL)
  • 初期化:[beebotte/Sub]homecontrol/command mqtt inノード、beebotteに接続する設定を入れる
    • サーバ新規にmqtt-brokerを追加 サーバ設定が開くので各情報を入力する
      • サーバmqtt.beebotte.com
      • ポート8883
      • プロトコルMQTT V3.1.1
      • セキュリティタブに行き、ユーザ名token:XXXXXXXX XXXXXXXXはbeebotteのChannel Tokenの値。赤字で書かれているもの。[7]
      • 「更新」ボタンを押してmqtt inノード編集画面に戻る
    • 動作1つのトピックを購読
    • トピックhomecontrol/command
    • QoS1
    • 出力自動判定(JSONオブジェクト、文字列もしくはバイナリ)
  • トリガー2(条件分岐) : Switch homecontrol/command : switchノードでコマンドによって条件分岐させる
    • プロパティmsg.payload.data ここに出入りしたデータが入っている enterかexitのいずれかになる
    • キーを含むenterの条件で1 「エリアに入った」の場合
    • キーを含むexitの条件で2 「エリアから出た」の場合
    • その他で3 念のため入れておくと良い。debugにつなげる
  • アクション2 : 調光(on_little_bright)をつける トリガー2の「エリアに入った」にのみ接続すること
  • アクション2 : 消灯(off_light)する トリガー2の「エリアから出た」にのみ接続すること

感想

帰ってきたときにわざわざライトをつけなくても良い。
ちなみに家族が在宅して私が外出から帰ってくる状況だと、無人のはずの私の部屋の電気がいきなり点くので最初は驚いたらしい。そりゃそうだw

夜22時になってまだ部屋が明るかったら言葉で褒めてもらう

きっかけ

開発していてやっぱこうーーー褒めて欲しい瞬間ってありますよねw
夜遅くになってもなにか頑張っていたらいい感じに褒めて欲しいじゃないですか。
Google Homeが自分の部屋[8]にあったので、そこから自身を言葉で褒めるもらえるようにしました。
※Google Homeに発話させるためにnode-red-contrib-castを使います。
※褒める言葉が毎回同じにならないように3種類ほど用意しています。その振り分けのためにnode-red-node-randomを使います。

構成

Node-REDではこうしています。
node-red-node-randomnode-red-contrib-castというノードの追加が必要です。
Node-REDメニュー、パレットの管理、ノードの追加で2つのノードを追加してください。
Node-RED画面左のメニューにCastとrandomが追加されているはずです。
randomノードとcastノード

  1. トリガー1:Node-REDのinjectionで、22時になったら
  2. アクション1:SwitchBot APIでハブ2の照度計のデータを読み取る
  3. トリガー2:明るいと判断されたら
  4. アクション2:発話する内容を決めてGoogleHomeに喋らせる

詳細設定値

Node-RED

  • 初期化:Initialization injectionノード、Node-REDが起動した際に設定される定数を決定し、フロー変数に入れる(SwitchBotのトークン情報,ハブ2のステータスを確認するためのURL)
  • トリガー1:EveryDay 10:00PM injectionノードで繰り返し実行、曜日と時間を選ぶ(日~土 PM10:00)
  • 設定:Hub2 changeノードでHTTPリクエストを送る設定を行う
  • 設定:Setup to call SwitchBotAPI functionノード
  • アクション1:Request to SwitchBot http requestノード ハブ2の照度を取得する
  • 設定 : Parse results(json) : jsonノードでJavaScriptオブジェクトに変換する 動作を常にJavaScriptオブジェクトに変換
  • トリガー2(条件分岐) : Switch lightLevel : switchノードで明るさによって条件分岐させる
  • 設定:Reset msg.url changeノードで msg.urlを(空欄)にする 後続のGoogle Homeに送信する時に値が空である必要があるため
  • 設定:Random 1-3 randomノードで 整数値1-3の値をランダムで返す
    • プロパティmsg.payload
    • 生成整数-整数値
    • 最小1
    • 最大3
  • 条件分岐 : Switch Random Number : switchノードで数字によって条件分岐させる
    • プロパティmsg.payload
    • ==1の条件で1
    • ==2の条件で2
    • ==3の条件で3
  • 設定:Keep up the good work! 1,2,3 changeノードで 褒める言葉を設定(1,2,3にそれぞれ文字列を入れる)
    • msg.payloadがんばってますね、あなたは素晴らしい
  • アクション2 : Google Home says Castノード、以下設定を行う
    • IPXXX.XXX.XXX.XXX Google HomeのIPアドレス(IPv4)
    • Port8009
    • languageja
    • Volume30

感想

勉強してなくてYoutubeを見ている夜に「がんばってるねえ」聞くとなんだか焦燥感に駆られますw
煽られている感覚に陥りますねw

考察

なぜNode-REDをスマートホームの基盤としたか?

OSSであるし拡張性があるからです。今回の仕組みはSwitchBotだけでも部分的に満たせることは認めます。
ただその場合、一旦SwitchBotの中に入ってしまうと、そのSwitchBotプラットフォームより外の操作が出来なくなります。
自由度が失われてしまうので、そうならないようNode-REDが基盤、SwitchBotはある意味部品としてだけ使っています。

SwitchBotのアクションで選べるもの。この記事でいうGoogleHomeに発話させる操作のようなSwitchBot以外の操作ができない。

Node-REDを動かす環境はどこが良いか?

異論は認めますが、個人用途でNode-REDを動かす環境としてのベストはローカルのRaspberryPiだと思います。
beebotteなどと併用することで、屋外のイベントを基盤側に取り組むことができると幅が広がります。
RaspberryPi 3B+以降ならなんでもいいんじゃないでしょうか。省サイズなRaspberry Pi Zero Wでも動作するでしょう。

Node-RED以外のローコードプラットフォームは使わなかったのはなぜか?

できないわけではないです。beebotte~自宅NW内での動作を考えて採用しなかっただけです。
例えばクラウド側のローコードプラットフォームとしてMicrosoft AzureのLogic Appsが挙げられます。
これを用いれば、クラウド環境にトリガーを元に自由に用意して様々なアクションを起こすといった今回の形は構成できるでしょう。
今回はbeebooteというMQTTブローカーを監視するプロセスが自宅NWに常駐することもあって、自宅にNode-REDがあるほうがいいと判断したまでです。
消費するコンピューティングリソースも微々たるものだし、わざわざクラウドで動かす必要もないかなと。

トリガーの"外出したら"はSwitchBotの位置情報β版で出来ないか?

出来るでしょう。ただ、先程説明に上げたとおり、一度SwitchBotの中に入ってしまうと、それ以後SwitchBotプラットフォームより外側のリソースを呼び出せなくなります。
今回はSwitchBot以外に動かしたいものがあるからそうしました。SwitchBot製品を動作させるだけで十分という場合には標準のアプリを導入するだけでも良いでしょう。
シーンなどは便利だし、Alexaで声で制御するという仕組みもアプリで設定するだけで使えるので便利ですからね。


SwitchBotの位置情報ベータ版の画面。ジオフェンス(エリア指定)を円形で指定できます

トリガーの"外出したら"をエリア別にもっと細かく指定出来ないか?

位置情報をもっと細かく指定したいなら、Amazon Location ServiceのGeofence機能で設定すると良いでしょう。
トラッカー登録したデバイスを追跡して、Geofenceで定義したエリアにEnterまたはExitした際にイベントが発生するので、自分が定義上どのエリアにいるか細かく把握できると思います。
これを使って、例えば某映画のように埼玉県から東京都に入った人を検知してとてつもないアラートをですね(略)

トリガーの"外出したら"を位置情報以外の技術で検知出来ないか?

このやり方で良い手法を探しています。自分で試してみたこととして、自宅NWにモバイル端末が接続されていることをPingで検知する方法を試してみました。Pingの応答があったら在宅、応答がなかったら不在という具合ですね。
一見良さそうだったものの、モバイル端末を自宅NWに接続したまま使っていない時間(充電して画面を見ていない状態とか)にモバイル端末に対するPingがロストする瞬間があったことから不採用としました。在宅中に離席したと判断されてしまうことになるためです。モバイル端末は自宅NWに接続されていたとしても常時Pingに反応するわけではなく、モバイル端末も裏ではしっかり休んでいるということが分かりました。当たり前かな?なにか知見のある方ぜひコメントをお願いします。

なぜbeebotteを介したか?IFTTTのアクションでSwitchBotは選べるのにそうしなかったのは?

理由は2つあります。ひとつは拡張性です。IFTTTの無料版では、アクションを一つしか選べません。SwitchBotだけでなく他のデバイスの操作やソフトウェアの動作もさせたかったから直接IFTTTにしなかったという理由があります。別ルートでbeebotteにデータ投入するなども可能ですし。もう一つは自宅NW構成の変更が不要だからです。クラウド側からメッセージを受信するためだけに自宅NWの構成を変えたくなかったとも言えますね。MQTTブローカーを自宅NW外に設けて、ローカルのアプリケーションでMQTTブローカーの変化を検知するという仕組みを使えば、クラウド側から簡単にメッセージのやり取りができることになります。MQTTブローカーであるならばPublisherとSubscriber分離させ、かつそれぞれを複数設定できるので、1つの値を複数の仕組みが閲覧できるという意味でWebサービスにするよりも扱いがし易いです。

beebotte以外のMQTTブローカーの候補はないか?

メッセージ処理できるMQTTブローカーは、beebotteのようなSaaSでいくつか提供されています。SaaSで他の候補ならHiveMQ Cloud/AWS IoT Core/Azure IoT Hubあたりが該当します。いずれのサービスもなにかしらの制限がかかっているため、最新の情報はそれぞれ各自で調べて見て欲しいです。単位時間あたりのメッセージ量や同時接続数というパラメータに着目する必要があります。AWS IoT CoreではHTTPSメッセージURLも用意されているので、そのトピックに対してPOSTするとメッセージ発行ができるなどの特色がそれぞれあります。また、Azure IoT HubのFreeエディションはPoC的な使い方を想定しているとあるのでそのあたりは仕様をよく読んで扱うようにしてください。

リアルタイムメッセージ処理の方法は他にもあるか?

MQTTを外れても良いなら、NoSQL系のDBなどで各種サービスがありますね。
mBaaSとして使われているFirebaseのDB機能Cloud Firestore(旧Realtime Database)でも良いでしょう。
オフラインでも使えるし、オンライン復旧したら自動同期するなど使い勝手も良いです。

SwitchBotの制限で気をつけなければならない点は?

Request Limitが設定されており、API呼び出しの回数が最大10000回/日に制限されていることです。計算するとわかりますが、24時間ぶっ続けで使うとして、1分あたり6回(1時間あたり360回)程度が呼び出しの限度であることがわかります。
明るさの情報をポーリングしてSwitchBot APIから取得しようという場合、Request Limitにかからないよう、稼働時間帯などを決めることで1日あたりのAPI呼び出し回数を減らしておくと良いでしょう。

センシング情報をNode-REDに貯めておくことはできないか?

例えば11時のセンサー値をもって12時に動作するというリクエストがあるかもしれません。センシング情報を取るタイミングと、動作させたいタイミングが一致しないケースですね。代案が色々あるでしょうが、Node-REDで実現するならば、フロー変数を用いると良いでしょう。センサー値を得たらシンプルにフロー変数に保存しておくというものです。フロー変数はその名の通りフロー内での変数となるので、動作タイミングでこの値を参照するという意味です。

Node-REDで色々やろうとするとぐちゃぐちゃになりがちでは?

これはNode-REDでアプリケーションの設計/実装するとわかるのですが、確かにNode-REDではNodeを色々つなげられる反面、線だらけになって何がどうなったか非常に見通しが悪くなったりする場合があります。線だらけになると当然保守性が悪くなります。
基本は関数化というスタンスだと前置きした上で、私がやるならいっそNode-RED内にMQTTブローカーを立ててしまい、Publish(メッセージ送信)とSubscribe(メッセージ受信)のロジックを分けてしまうというやり方を採用しますね。これで少なくともトリガーのロジックとアクションのロジックを分割することができるからです。一家に一台MQTTブローカーがあるべきだと最近思いますw

スマートホームでやるべきではないことは?

これは余談ですが、人に尋ねられたらこう答えるようにしています。
事故になりそうなデバイスを動かすのはやめましょう
NGの例として自宅外からリモートで動かせるスイッチなどを使ってストーブを点けるなど。
無人の部屋でストーブが点くとか想像すると怖すぎるでしょう。リスクの高い家電操作の自動化は控えましょう。
なので取っ掛かりとしても部屋の電気操作は良い素材だと思います(誤って点灯し続けたところで事故になりにくい)

スマートロックなどもこの仕組みを使えば声掛けなしで部屋の鍵が開くとか未来感あっていいですね?

自宅の鍵などセキュリティを担保する必要のあるところでAPIを使うのはあまりおすすめしません。もちろんAPIの不具合ではなく自身のアプリ側のミスがあった場合を想定しています。
スマートロックについてはAPIから操作せず、標準のアプリからだけ操作するほうがいいでしょう。セキュリティが必要なところでバックドアを用意するようなものなので。

褒めてもらう言葉がランダムとはいえ単調では?

じゃあChatGPTでうまい褒め言葉を作ってもらいましょう。ChatGPTのAPIを叩くノードを繋げたらOK。

頭で考えたことがそのまま家電操作につながればもっと最高ですね

そうですね、脳に対して非侵襲的にそれが実現できれば最高ですね。
本当に期待しているのでその方面で研究されている方はぜひ頑張ってほしいですね。

なんでこんな考察が広がるんですか?

たぶん私が面倒くさがりだからだと思います。

SwitchBotのシーンなど使わないあたり、SwitchBotを嫌いなんですか?

好きですよ。APIで制御できるのもとても気に入っています。シーン自体をAPIで呼び出せるので便利ですよね。シーンで操作をまとめて、そのシーン呼び出しがAPI1つになるのはとても良いと思います。
ただ、私の場合ソフトウェアを色々動かすことで自分の生活を楽にしたいから、できるだけ制限のゆるい環境を基盤として構築するのが適切と思ったまでです。

SwitchBotのデバイスにはまだまだお世話になりそうです。
2024年の新製品としてSwitchBotロックProが出るのは気になりますね。
ここまで読んでいただきありがとうございました。

参考リンク

https://qiita.com/Chroma7p/items/8e1817d313beca2b2641

脚注
  1. 少なくとも赤外線リモコンの信号が届く範囲ならね ↩︎

  2. 動作環境はWindows11ではあるものの、環境依存の記述はないためRaspberry Pi環境でも問題なく動作するでしょう ↩︎

  3. 各部屋の標準的な明るさレベルをSwitchBotアプリで確認し、条件の明るさは適宜調整してください ↩︎

  4. 出入りを検知する方法なので、入ったまま/出たままの状態だとイベントは発生しません ↩︎

  5. 計測で居場所がずれることも考慮して、半径100m以上を指定すると良いです ↩︎

  6. privateチャネルの場合はprivate-を付与します ↩︎

  7. トークンがtoken_から始まるので、token:token_XXXという書き方になるはずです ↩︎

  8. Google HomeのIPは把握しているものとします。Google Homeアプリから調べられます ↩︎

Discussion