最近Codex Cloudが新しくなり、OpenAI側のクラウド環境でGitHub連携をして手軽に開発ができるようになりました。
ちょうど土日に実家に帰らないといけない用事があり自宅のPCの電源を入れていなかったのですが、もうすぐ期限が切れてしまうリセット権がもったいなかったので、この機会にCodex Cloudを利用して趣味で制作してるプログラムのコード改修を試してみることに。
IT系と日常系の備忘録。三日坊主。
最近Codex Cloudが新しくなり、OpenAI側のクラウド環境でGitHub連携をして手軽に開発ができるようになりました。
ちょうど土日に実家に帰らないといけない用事があり自宅のPCの電源を入れていなかったのですが、もうすぐ期限が切れてしまうリセット権がもったいなかったので、この機会にCodex Cloudを利用して趣味で制作してるプログラムのコード改修を試してみることに。
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 です。

最初はプラグイン側で署名処理を肩代わりして簡単にAPIリクエストを行えるだけのものを作ったのですが、せっかくなので普段よく使う操作についてはAPIのURLやリクエスト本文を意識せず使えるようにアクションとして独立化させました。
プラグインはGitHubのReleasesから .streamDeckPlugin をダウンロードしてインストールできます。
利用するには、最初にSwitchBot OpenAPIのTokenとSecretを設定します。
STREAM DECKにこのプラグインのアクションをどれか1つ配置し、設定画面の一番下にある「認証」を開いてTokenとSecretを入力、「接続テスト」で正常に接続できれば準備完了です。
TokenとSecretはプラグイン全体で共有しているので、アクションを追加するたびに設定する必要はないようにしてます。
現時点では、
というアクションを用意しています。
例えば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リクエスト」機能もそのまま残しています。 今回自分が持っていないデバイスも含めてある程度SwitchBotの製品が操作できるようなアクションを作ったわけですが、全部が全部対応できているわけではなく、リクエスト本文の構造的にも対応が難しいものがあったので、そういったものはこちらで対応できるようにしました。
こちらでもHMAC-SHA256の署名生成などはプラグイン側で行うので、利用者は実行したいAPIのパスやリクエスト本文を設定するだけです。 よく使いそうなAPIについてはいくつかプリセットも用意しています。
というわけで、SwitchBotをSTREAM DECKから操作するためのプラグインを作ってみました。
GitHubで公開しているので、同じようにSwitchBotとSTREAM DECKを使っている人がいれば試してみていただけると嬉しいです。
普段仕事をする際、Slackのハドルミーティングを利用してディスカッションを行ったりしています。
話している最中にメモを取れないこともあるので、スピーカーの出力とマイクの入力を録音し、後から必要に応じて録音を聞き直すようにしてました。
これまでは有料の録音ソフトを利用しており、それなりに便利に使っていたんですが、いくつかどうしても使いづらいと思うところがあり、自作することに。
CodexやClaude Codeにいろいろ頑張ってもらいながら作ったソフトが実用レベルに至ったので、公開することにしました。
以前このブログの生成のためにお手製の静的サイトジェネレーターを作ったという話をしました。
oEmbedにも対応させて最低限自分が欲しい機能を載せたものの、oEmbedの処理の都合上ページ単位で情報を取得する必要があるため、oEmbed処理するページが増えるほどHTML生成に時間がかかるというジレンマがありました。
oEmbed処理がなければ数秒で生成されるだけにちょっとこの時間がもったいない。というわけでキャッシュ処理を追加したのですが、せっかくコードをいじるのだからということでリファクタリングすると同時に dotnet tools対応などを行ってみました。
前回自宅キッチンのシンク下を修繕した話を投稿したのですが、このブログをホスティングしているAzure Static WebAppsにデプロイしようとしたところ、エラーが出てしまいました。
エラーを確認したところ、デプロイ可能なサイズを超過しているとのこと。
Azure Static WebAppsは250MBまでをサポートしており、写真を載せる際にウェブ用に圧縮せずにいたので超過した模様。
とりあえず手作業で画像を圧縮することで取り急ぎブログ記事の公開をすることができたのですが、いちいち画像サイズを気にして置くのも面倒くさい。
ウェブサイト構築中にちょっとはまったのでメモ。
Formタグの中にSubmitを行うボタンをおけない場合、 input="submit" のボタンをFormタグ内にhidden状態で記載し、Formの外のボタンを置きたい場所にラベルタグとfor属性を利用してボタンを設けるという方法がありますが、これだとEnter押下時にSubmitが走ってしまうという問題があったため、 HTMLFormElement.submit()を利用して回避。
ただ、これはMDNにも記載されている通りsubmitイベントが発生せず、制約検証も行われない問題が。
HTML5.1から HTMLFormElement.reportValidity() という制約検証を行うための機能が追加されてた模様。知らなかった・・・。
これを HTMLFormElement.submit() 実行前に呼び出して結果が true だった場合にだけsubmit処理させるようにしてやればOK。
reportValidity() はエラーが存在する場合、required などの制約検証に対するメッセージが該当のフォーム要素に表示されるそう。
似たようなもので checkValidity() があり、こちらは制約検証結果をtrueかfalseかで返すだけ。エラーメッセージは表示されないので、独自にメッセージを調整したい場合などには有用。
セルフランナーでの挙動なので通常環境で起きるかどうか検証してないのですが、とりあえずメモとして。
とある案件でNuGetパッケージが更新されず、GitHub上のリポジトリは更新されているライブラリを利用するため、Submoduleを利用してました。
最近NuGetパッケージも更新されるようになり、Submoduleを利用する必要性が薄れたため、Submoduleを削除してNuGetパッケージを利用するプルリクエストを作成し、メインブランチにマージを行いました。
このメインブランチに反映したものを別のブランチにもマージしてプッシュしたところ、下記のエラーが。

GitHub Actionsのワークフローでは、actions/checkout@v2 の処理中にSubmoduleの処理をしているのですが、ここでなぜか削除したはずのライブラリの取得でエラーになってる様子。
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
セルフランナーのワーキングディレクトリを消してもらったりしてもうまくいかなかったのですが、最終的にメインブランチからマージして取得せず、rebaseする形で取り込むと問題なく動きました。
Submoduleの削除で.gitmoduleからライブラリのプロジェクト参照を消していたとしても、そのブランチのもととなる位置の段階でSubmoduleを参照している場合エラーとなる?
たまに使おうと思って度忘れしているのでメモ。
業務アプリで利用しているSDKを更新していてはまったので覚書。
タイトルがすべて。
Azure Functions v2がEOLとなり、FUNCTIONS_EXTENSION_VERSION の値を ~2.0 としていたアプリがありました。
当然EOL状態を放置することはできないため、v3に対応する修正を実施し、開発環境では正常に動くことを確認。
本番に向けステージング環境にデプロイ後、FUNCTIONS_EXTENSION_VERSION の値を ~3 に変更したうえでスワップを実施しました。
が、ここで本番環境でエラーが発生することが発覚し、急遽再スワップを実施して戻すことに。