SwitchBotAPIで遊んでみた
この記事は、tacoms Advent Calendar 2024の21日目です!
他メンバーのAdvent Calendarはこちらからご覧ください!👇
はじめに
Switchbot導入したらスマートホームに目覚めた鹿島です
数えたら30個くらい登録されていたのでその一部を紹介してみたいと思います
ちょっとだけAPI連携を検証します
わが家のボットたち
リモコン
窓のシャッターのリモコンにボットをつけて操作しています
SwitchBotのボットという商品です(紛らわしい名前ですねw)
シャッターの他には扇風機、床暖など遠隔操作したいものにつけています
基本的に設定した時刻に起動させるかAlexaから操作します
このボットですが、要件を満たせるならQOLは上がるかもしれないですが、
取り付けたときの見た目が微妙なので割り切りと覚悟が必要そうですw
ポスト
ポストにふたが付いているので開閉センサーをつけて投函を検知しています
毎日ポスト見ないので何か入ったら取りに行く運用にしています
地味ですが便利で気に入っています
ライト
ベットの木枠にLEDのテープを貼り付けて人が通ったら足元を照らすようにしています
程よい明るさで足元が見えて安心なのと、布団に入ったら勝手に消えるので便利です
同じ仕組みでデスクの天板の淵にLEDつけて着席したらつくようにしてます
こちらはただの飾りで利便性はありません
API連携
SwitchBotはAPIが豊富なので本当に動くのか試してみたくなりました
Webhookの受信とデバイスの起動を検証します
Step1. サーバー
とりあえず一番楽そうなのでHonoで
今回は検証なのでngrokで外部に公開してローカルで確認します
import { Hono } from 'hono'
const app = new Hono()
app.post('/', async (c) => {
console.log(await c.req.text())
return c.text('ok')
})
export default app
Step2. Webhookの登録
公式のサンプルコードを参考にStep1で公開したURLをWebhook送信先に登録します
認証のtokenはSwitchbotアプリから取得します(👉手順)
import "dotenv/config";
import crypto from "crypto";
import { v4 as uuidv4 } from "uuid";
const token = process.env.SWITCHBOT_TOKEN;
const secret = process.env.SWITCHBOT_SECRET_KEY;
const t = Date.now();
const nonce = uuidv4();
const sign = crypto
.createHmac("sha256", secret)
.update(`${token}${t}${nonce}`)
.digest()
.toString("base64");
const headers = {
Authorization: token,
sign: sign,
nonce: nonce,
t: t,
"Content-Type": "application/json",
};
// Webhook登録
await fetch("https://api.switch-bot.com/v1.1/webhook/setupWebhook", {
method: "POST",
headers: headers,
body: JSON.stringify({
action: "setupWebhook",
url: "https://ea14-240d-1a-5f5-c600-b4b0-49f7-7fdf-4413.ngrok-free.app",
deviceList: "ALL",
}),
}).then((response) =>
response.json().then((data) => console.log(JSON.stringify(data))),
);
// Webhook確認
await fetch("https://api.switch-bot.com/v1.1/webhook/queryWebhook", {
method: "POST",
headers: headers,
body: JSON.stringify({
action: "queryUrl",
}),
}).then((response) =>
response.json().then((data) => console.log(JSON.stringify(data))),
);
実行結果
% node src/configure_webhook.js
{"statusCode":100,"body":{},"message":"success"}
{"statusCode":100,"body":{"urls":["https://ea14-240d-1a-5f5-c600-b4b0-49f7-7fdf-4413.ngrok-free.app"]},"message":"success"}
Honoのログ
{"eventType":"changeReport","eventVersion":"1","context":{"battery":100,"detectionState":"NOT_DETECTED","deviceMac":"DA9A2DDF8344","deviceType":"WoPresence","timeOfSample":1734530728198}}
[wrangler:inf] POST / 200 OK (5ms)
{"eventType":"changeReport","eventVersion":"1","context":{"battery":100,"detectionState":"DETECTED","deviceMac":"DA9A2DDF8344","deviceType":"WoPresence","timeOfSample":1734530738135}}
[wrangler:inf] POST / 200 OK (9ms)
しばらく待つといろいろ飛んでくるようになりました 🎉
WoPresence
はモーションセンサーが認識したイベントのようです
とりあえずSlackにパスしてみました
これらのイベントを記録したりハンドリングすることでいろいろと捗りそうです
Step3. コマンド実行
ライトのON/OFFやってみます
デバイスIDを取得
% node src/devices.js | jq '.body.deviceList[2]'
{
"deviceId": "C04E30953102",
"deviceName": "ライト",
"deviceType": "Plug Mini (JP)",
"enableCloudService": true,
"hubDeviceId": "000000000000"
}
// ライトON/OFF
await fetch("https://api.switch-bot.com/v1.1/devices/C04E30953102/commands", {
method: "POST",
headers: headers,
body: JSON.stringify({
command: "toggle",
parameter: null,
}),
}).then((response) =>
response.json().then((data) => console.log(JSON.stringify(data))),
);
% node src/toggle_light.js
{"statusCode":100,"body":{},"message":"success"}
% node src/toggle_light.js
{"statusCode":100,"body":{},"message":"success"}
💡つきました💡
認証の仕組みを作ってしまうとあとは楽勝です
アカウント持ってるだけで誰でもAPI使えるの便利ですね
まとめ
- SwitchBotは導入すると止まらない 💨
- SwitchBotはたまに動かないことがある 😢
- SwitchBotは購入しやすい 💸
- SwitchBotは楽しい 🎉
Discussion