SwitchBotのAPIを叩くSTREAM DECK用プラグインを作った話

ChatGPTと要件の深堀をして、決まった内容をそのまま実装してもらう形でちまちまと個人的に欲しいものを作るのにはまっているひつじです。
構想はあったし自分で実装できるけど、時間がなくて後回しにしていたものなんかをAIに任せて楽をしてます。

そんなわけで今回、SwitchBotのAPIを叩いて、SwitchBot製品や赤外線リモコンの登録をしている家電の操作をSTREAM DECKで行うためのプラグインを作ってみました。

SwitchBotはAPIを公開しており、トークンさえ発行すればだれでも自分が持っているSwitchBot製品の操作が可能です。

v1.0 のころはAPI実行時にあらかじめ発行していたトークンを渡すだけの単純なものだったので、STREAM DECKのWebRequests プラグインで HTTP Requestを投げる形で割合簡単にAPI実行できてました。

ただ、最新のv1.1ではHMAC-SHA256署名が必須となり、単純にHTTP Requestでだけで対応するのが難しくなっていました。
一応v1.0もまだ提供されていますが、最新デバイスやLock Proでの開錠機能などといったセキュリティ上厳格な運用をしないといけない項目に対応していません。

そんなわけで作ったのが SwitchBot.StreamDeckPlugin です。

SwitchBotのSTREAM DECKプラグイン

最初はプラグイン側で署名処理を肩代わりして簡単にAPIリクエストを行えるだけのものを作ったのですが、せっかくなので普段よく使う操作についてはAPIのURLやリクエスト本文を意識せず使えるようにアクションとして独立化させました。

使い方

プラグインはGitHubのReleasesから .streamDeckPlugin をダウンロードしてインストールできます。

利用するには、最初にSwitchBot OpenAPIのTokenとSecretを設定します。
STREAM DECKにこのプラグインのアクションをどれか1つ配置し、設定画面の一番下にある「認証」を開いてTokenとSecretを入力、「接続テスト」で正常に接続できれば準備完了です。

TokenとSecretはプラグイン全体で共有しているので、アクションを追加するたびに設定する必要はないようにしてます。

現時点では、

  • Bot
  • 電源
  • 照明
  • 空調
  • セキュリティ
  • カーテン・ブラインド
  • 掃除
  • 赤外線リモコン
  • 状態取得
  • APIリクエスト

というアクションを用意しています。

例えばBotを操作したい場合は「Bot」をキーへ配置すると、自分のSwitchBotアカウントに登録されている対応デバイスが一覧に出てくるので、操作したいBotと「押す」「ON」「OFF」などの操作を選択しておきます。
あとはSTREAM DECKで該当のボタンを押せばAPIを叩いて処理されます。

SwitchBot Hubに登録してある赤外線リモコンについても「赤外線リモコン」アクションから操作できます。
SwitchBotのAPIだと赤外線リモコンで学習させたボタン情報を取得できないので、ここはリクエスト本文を手書きする必要があって面倒なんですが、致し方なし・・・。

デバイスの状態もキーに表示できる

操作するだけでなく、「状態取得」アクションを使ってSwitchBotデバイスの現在の状態を取得することもできます。

取得した結果はSTREAM DECKのキー上にも表示できます。
例えば温湿度計なら、

温度: {temperature}°C
湿度: {humidity}%

のようなテンプレートを指定しておけば、APIから取得した値をキー上に表示できるようにしています。

一度そのデバイスの状態を取得すると、利用可能な項目が設定画面に表示されるようになってます。表示された項目をクリックするとテキストボックスに追加されます。
テンプレートのテキストボックスを空欄にしておけば、取得した情報から主要な項目を自動的に選んで表示します。

状態はキーを押したときだけ取得することもできますし、1分、2分、5分、10分、30分、60分間隔で自動更新することもできます。

APIを直接叩く機能

最初に作った「APIリクエスト」機能もそのまま残しています。 今回自分が持っていないデバイスも含めてある程度SwitchBotの製品が操作できるようなアクションを作ったわけですが、全部が全部対応できているわけではなく、リクエスト本文の構造的にも対応が難しいものがあったので、そういったものはこちらで対応できるようにしました。

こちらでもHMAC-SHA256の署名生成などはプラグイン側で行うので、利用者は実行したいAPIのパスやリクエスト本文を設定するだけです。 よく使いそうなAPIについてはいくつかプリセットも用意しています。

おわりに

というわけで、SwitchBotをSTREAM DECKから操作するためのプラグインを作ってみました。

GitHubで公開しているので、同じようにSwitchBotとSTREAM DECKを使っている人がいれば試してみていただけると嬉しいです。

[oembed:"https://github.com/Ovis/SwitchBot.StreamDeckPlugin"]

Cloudflare Email Routing と Resendを利用した独自ドメインでのメール送受信環境の構築をした話

長らくOffice 365 Business Standardを契約し、そちらのExchangeを利用して独自ドメインでのメール環境を用意していた。

しかしながら昨今の各種値上がりや、そもそもでそこまでOffice 365を有効活用しきれていなかったことなどを鑑みて解約することを決意。
それに伴ってメール送受信の環境を調整することにした。

続きを読む

NextDNSのLinked IPをSynology NASで自動更新するようにした話

現在実家には父と母が二人で暮らしている。
あまりネットとかPC、スマホに詳しいわけでもないので、何かあった時に私が電話でサポートしている。
ここ数年迷惑系広告を踏んでしまって連絡をもらうことが何度かあったので、AdGuard Homeを実家で動かしているSynologyのNASで動かしていた。

これで特段困ってはいなかったが、このNASに何かがあった時に父母がネットに接続できなくなってしまう問題があった。
このために実家に帰るのも面倒くさい。
最近NextDNSを契約したので、この機会に実家のネットワークでもNextDNSを利用することにした。

一点問題があり、実家で利用しているTP-LINKのDecoはDNS-over-HTTPSやDNS-over-TLSには対応していないため、NextDNSの「Linked IP」機能を使う構成にする必要がある。
これについてはSynology NASのタスクスケジューラ機能でNextDNSが提供するグローバルIPアドレス更新のURLをCurlで叩くことで対応できる。

今回は単純にcurlで叩くだけでは味気なかったのでもう少しスクリプト化することにした。

なお、この記事ではSynologyのタスクスケジューラを使っているが、内容自体はcronなどでもそのまま応用できる。

続きを読む

オンライン通話の録音を行うためのソフトウェアを公開した話

普段仕事をする際、Slackのハドルミーティングを利用してディスカッションを行ったりしています。
話している最中にメモを取れないこともあるので、スピーカーの出力とマイクの入力を録音し、後から必要に応じて録音を聞き直すようにしてました。

これまでは有料の録音ソフトを利用しており、それなりに便利に使っていたんですが、いくつかどうしても使いづらいと思うところがあり、自作することに。
CodexやClaude Codeにいろいろ頑張ってもらいながら作ったソフトが実用レベルに至ったので、公開することにしました。

続きを読む

サブスクリプション棚卸をした話 2025

以前もやっていたサブスクリプションの棚卸。

しばた氏やアヤノフ氏がやっているのを見て思い出したので久しぶりに私も棚卸。

なお、サブスクリプションと言ってますが保険だとか投資信託とかの定期出費分も載せてます。

続きを読む

お手製静的サイトジェネレーターを改修してついでにdotnet toolsとして公開した話

以前このブログの生成のためにお手製の静的サイトジェネレーターを作ったという話をしました。

oEmbedにも対応させて最低限自分が欲しい機能を載せたものの、oEmbedの処理の都合上ページ単位で情報を取得する必要があるため、oEmbed処理するページが増えるほどHTML生成に時間がかかるというジレンマがありました。
oEmbed処理がなければ数秒で生成されるだけにちょっとこの時間がもったいない。というわけでキャッシュ処理を追加したのですが、せっかくコードをいじるのだからということでリファクタリングすると同時に dotnet tools対応などを行ってみました。

続きを読む

PNGファイル、JPEGファイルを圧縮するGitHub Actionsを作った話

前回自宅キッチンのシンク下を修繕した話を投稿したのですが、このブログをホスティングしているAzure Static WebAppsにデプロイしようとしたところ、エラーが出てしまいました。

エラーを確認したところ、デプロイ可能なサイズを超過しているとのこと。
Azure Static WebAppsは250MBまでをサポートしており、写真を載せる際にウェブ用に圧縮せずにいたので超過した模様。

とりあえず手作業で画像を圧縮することで取り急ぎブログ記事の公開をすることができたのですが、いちいち画像サイズを気にして置くのも面倒くさい。

続きを読む

自宅キッチンのシンク下を修繕した話

シンク下の床板がボロボロ

今住んでいる家は伯母の持ち家。
以前は伯母の両親が住んでたんですが、亡くなられて空き家になってしまい、腰を痛めている伯母が管理するのは厳しいということで、私が管理しながら住んでいる状況。

そんな家なんですが、前々から台所のシンク下収納に問題がありました。
どうもシンクから水漏れしている模様。

シンク下の汚れ 床板が腐ってる

収納棚についている茶色い汚れがシンクからこぼれたと思われる水汚れ。 普段は漏れてなくて何かの拍子に漏れている様子。
そして水漏れをたびたび起こしていたことで床板もボロボロになってました。写真だとわかりづらいですが、もうぶかぶか。
さらに排水のパイプが流し台の穴の位置からずれているので結構無理やり排水ホースを引っ張っていて、防臭キャップがきちんとはまっていないのか、下水の匂いがほんのりする状況。

こんな状態だったのであまりものを入れておく気にはなれず、ほとんどこの収納を使ってませんでした。

7年近くこの家で生活してきて、さすがにこれ以上この状況を放置しておきたくないなと思い、最初は流し台ごと新しいものに交換することを検討。

ただ、本体だけでも安くて5万円くらいかかり、業者に頼んだら二桁万円。DIYで取り付けまでやるにも、デカ物なのでさすがに一人だと厳しい。
というわけで、できる範囲で交換だけすることに。

続きを読む

自家製静的サイトジェネレータに移行した話

元々はWordPressで運用していたこのブログ。
その後ブログだけのためにVPSを運用するコストが高すぎてはてなブログに移行し、そして静的サイトジェネレータを利用したブログ構築が流行り始めたのでその波に乗ったのが3年ちょっと前。

以降ブログ更新が捗るか・・・といえばそうでもなく、中途半端にOEmbed対応した結果、ブログのビルドに10分近くかかってしまう(並列処理できてなかった)問題がありました。
後で直そうと思っていたもののずっと放置していたのですが、久しぶりに(1年ぶりに)ブログを書こうかと思ってみたら、エントリをGitHubにプッシュした後に動作するGitHub Actionsでエラーが。

ずっと放置していた関係で.NET SDKのバージョン指定が古く(.NET5だった)、処理不能になっていたのが原因だったんですが、それだけでなく指定されたURL遷移先がエラーだった場合のOEmbedの処理がよろしくなくて動作不全を起こしていることも発覚。

仕方がないので重い腰を上げて書き換えることに。

続きを読む