Zenn
🍾

SwitchBotAPIで遊んでみた

2024/12/21に公開

この記事は、tacoms Advent Calendar 2024の21日目です!
他メンバーのAdvent Calendarはこちらからご覧ください!👇
https://qiita.com/advent-calendar/2024/tacoms

はじめに

Switchbot導入したらスマートホームに目覚めた鹿島です
数えたら30個くらい登録されていたのでその一部を紹介してみたいと思います
ちょっとだけAPI連携を検証します

わが家のボットたち

リモコン


窓のシャッターのリモコンにボットをつけて操作しています
SwitchBotのボットという商品です(紛らわしい名前ですねw)
シャッターの他には扇風機、床暖など遠隔操作したいものにつけています
基本的に設定した時刻に起動させるかAlexaから操作します

このボットですが、要件を満たせるならQOLは上がるかもしれないですが、
取り付けたときの見た目が微妙なので割り切りと覚悟が必要そうですw

ポスト


ポストにふたが付いているので開閉センサーをつけて投函を検知しています
毎日ポスト見ないので何か入ったら取りに行く運用にしています
地味ですが便利で気に入っています

ライト


ベットの木枠にLEDのテープを貼り付けて人が通ったら足元を照らすようにしています
程よい明るさで足元が見えて安心なのと、布団に入ったら勝手に消えるので便利です

同じ仕組みでデスクの天板の淵にLEDつけて着席したらつくようにしてます
こちらはただの飾りで利便性はありません

API連携

SwitchBotはAPIが豊富なので本当に動くのか試してみたくなりました
Webhookの受信とデバイスの起動を検証します

https://github.com/OpenWonderLabs/SwitchBotAPI

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は楽しい 🎉
tacomsテックブログ

Discussion

ログインするとコメントできます