ブログ

κυσο βλογ

SwitchBot API v1.1 を node-red から叩く

この文書の目的

switchbot の Web API は現時点(2023年3月)から6ヶ月前に version 1.1 が公開され、旧バージョンの 1.0 は今後新製品への対応がなされないと告知された。

blog.switchbot.jp

注意事項

APIご利用の際は以下の点にご注意ください

  1. 開発者はv1.0 APIインターフェースを引き続き使用することが可能。

  2. API v1.1の検証に必要なシークレットキーを取得するために、開発者はアプリをV6.14以降にアップデートする必要があります。

  3. v1.0は、新製品への対応を停止します。例えば、ロック・キーパッドキーパッドタッチの新機能を使用する場合、v1.1にアップデートする必要があります。

  4. このアップデートはカスタマイズユーザー用APIであり、ビジネスユーザー用カスタムAPIにへの影響はありません。

今後はv1.1の利用が標準となるようだが、現時点で、node-redから switchbot の Web API v1.1 を叩く方法を解説した文書がweb上に無いようである。

そのような状態でいろいろ試して失敗しながら数時間にわたって 401 Unauthorized エラーに悩まされ続けた末に成功した。

同じようなことをやろうとする人が費やすことになる無駄な時間を無くすためにこれを書いた。

実行環境

OS: windows 10 64bit 22H2

node.js: v18.15.0

node-red: v3.0.2

モジュールの準備

switchbot API v1.1 のリクエストヘッダを構成するには crypto モジュールを使う必要がある。

色々と試した現在の環境では、npm で crypto モジュールをインストールする必要は無いように見えるが、環境によってはインストールする必要があるかもしれない。

フロー配置

フロー配置

上図のように、inject -> function -> http request -> debug をシリーズでつなぐ。

inject (開始トリガ)

デフォルトのままでOK。

inject

function (リクエストヘッダ生成)

まず設定タブを開き、

設定タブ

追加 をクリックして

追加

crypto モジュールを追加する。GUIでモジュール追加ができるようになっていたのは知らなかった。

crypto

次に コード タブを開き、以下のようにコードを追加する。

code

const token = "switchbotアプリで取得できる トークン をここに記入";
const secret = "switchbotアプリで取得できる クライアントシークレットをここに記入";
const t = Date.now();

const N = 16;
const nonce = crypto.randomBytes(N).toString('base64').substring(0, N);

// const nonce = ""; //でも問題ない。

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;

http request

下図のように構成する。なお、URLの v1.1 を v1.0 に変更しても問題なく動作する。今回はデバイスのリストを見たいだけなのでメソッドにGET、URLの最後に devices を指定する。

http request

debug

出力を全部見たいので下図のように構成する。

debug

実行

デプロイをクリックして

デプロイ

inject(タイムスタンプ)ノードの□ボタンを押すと

inject

debugノードの statusCode が 100 に変わって成功したことが分かる。

debug

http リクエストに失敗すると、statusCode が 100 以外のエラーになって悲しい。

画面右のdebugタブを開くと

debug

msg オブジェクトの概略が表示されており、これをクリックすると

msg 詳細

様々なデバイスのIDなどが確認できる。このIDを使って、適切にPOSTリクエストを構成すればデバイスの操作などを行うことができる。ここまで成功していれば失敗する要因はほぼ無い。

nonce についての補足

ここから先は読まなくて良い蛇足である。

function ノードの nonce は定数や固定文字列でも問題ないようである。公式のAPIの説明でも

const nonce = "requestID";

と固定文字列が指定されている。

語源は何なのか

nonce とは何なのか日本語のwikipediaで調べてみて、意味はわかったが語源はわからなかった。

英語のwikipediaに語源を含めた答えがあった。

en.wikipedia.org

a nonce is an arbitrary Number that can be used just ONCE in a cryptographic communication.

(NとONCEのキャピタル化は筆者による)

日本語に訳すと:

「nonceとは、暗号通信で一度だけ使用できる任意の数値のことです。」

というわけで、せっかく node-red で crypto モジュールを使えるようにしたので、nonce の意味ないし目的に従って毎回ランダムに変化する文字列を指定するようにしたのが今回のサンプルコードである。

matter 対応には関係するか?

知らない。

いろいろな業種で様々な規格が乱立している。

switchbot が関連するであろう「スマートホーム」のコンテクストの中で、 matter と称される団体の標準化活動がある。

csa-iot.org

switchbot もその標準化活動の一員として名を連ねているようだ。

Web API も標準化されていくのだろうか?

まとめ

switchbotのAPIのドキュメントと、node-redのドキュメントはよく書けていて、賢い人間が見れば何の問題もなくアプリを書けるようにはなっていると思う。

しかし、俺のようなアホはこれらを見ても数時間の試行錯誤を要するのが現状である。

このへんは AI がなんとかするのかもしれないが、AIが今よりもう少しだけ賢くなってしまったら、そもそも俺のようなアホがコードを書くという行為が必要無くなるのかもしれない。