サ終したIRKitを非クラウド化で蘇らせる

Homebridgeとのセットでうちでも活躍してくれたIRKit。開発者の方がクラウド経由で操作可能なサービスをひっそり提供していたらしいんだけど、これが2022年12月10日頃をもってサービス終了。
赤外線信号のやり取りはHTTPサーバーでも根っこの部分ではクラウドに依存していたのか、各地のIRKitが一斉に動作しなくなるという事件が発生。うちでも思いっきり引っかかり、数日間IRKitが全く使えなくなるという中々しんどい状況に置かれてしまった。

クラウド機能を無効化するファームウェア自体は前から公開されていたが、まさかの既存のWi-Fiに参加させるときに用いる公式iOSAppでは設定時にクラウドサーバーを使用するため機能しないという事実が判明。ファームウェアを書き換えても設定を進められないためIRKitと通信させられず、使用不可能になるという事態に。

これ自体は実は、設定用にIRKit自身が構築するLANにサーバー機を接続しつつそこから使用することで一応の対策は可能だった。とはいえ不便極まりないので解消法について記録を残しておくための記事。
今後中古で流通しているIRKitを入手して設定で詰まっても、LAN内で使用可能な状態まで持っていける・・・はず。

経緯

・・・っていう内容をツイートしたところ、ありがたいことに現役プログラマーの方からお返事を頂き解決策を見つけ出すことが出来た。ぶっちゃけこの人のおかげでIRKitが不滅となったと言っても過言ではない。上記ツイートのリプ欄から試行錯誤の過程(とわたしがふんふん言ってるところ)が見れる。

また開発者の方にコンタクトを取っていたらこちらもお返事を頂けたほか、非クラウド化ファームについていくつか修正点をまとめてくださったので、それも含めてこの記事で紹介していく。
しかも非クラウド環境で使えてWi-Fi設定をお手軽に出来るツールまで作ってくださっていた。控えめに言って神。

IRKitという素晴らしいものをこの世に生み出した開発者様、そしてこの延命計画に大きく貢献された御二方にマジで感謝。あとクラウドに依存しない不滅のIRKitという存在が生まれた歴史的瞬間にリアルタイムで立ち会えたことにも感謝。

発見、解決された問題点まとめ

まずクラウドへのアクセスを停止させるために改造ファームウェアを使用。
しかしそのままではこれはArduinoIDE1.0.6というクッソ古いバージョンでしかコンパイル出来ず、IDE1.0.6は32bitアプリなのでmacOS Catalina以降で使用不可という罠が存在。これはソースの一部を改変することで、最新のIDEでコンパイル可能になり解決する。

そして改造ファームウェアでクラウドアクセスを止めても、公式iOSAppなしではWi-Fi設定が困難だった。
接続先のWi-Fi情報はEEPROMとかいうIRKit内部のメモリに保存されているんだけど、いじるためにはIRKitに書き込むよう指示をしないといけない。本来はHTTPリクエストを投げることで書き込み指示が可能だったが、それをお手軽に行えるiOSAppがクラウド依存してたため事実上死んでしまい困難に。
ArduinoIDEを使って起動時にEEPROMに保存するようソースコードに直接書き込むことで対処可能だが、公式iOSAppと同じ仕組みを使って書き込むツールを公開してくださったのでそちらを使えばよりお手軽に解決。この記事では手軽な後者をメインに、補足として前者も紹介する。

ちなみに副産物としてIRKitの初期パスワードをソースコード内で自由に弄れるので、初期パスワードを忘れたり前の所有者から聞けなかった場合の復旧が可能。
また超眩しいLEDの動作を簡単に制御出来る。信号を流す時だけ光るようにしたり、起動時以外は全く光らないようにしたり。ちなみにわたしは光らせない派。

手順

必要な環境の用意

今回はMacBookPro(M1,2020)とmacOS Ventura(13.0.1)で進める。つまり32ビットアプリであるArduino IDE 1.0.6が使えないので、それに頼らず完成させる。
仮想マシン引っ張ったりWine使ったり色々試したけど、この方法が一番楽で確実だった。

前準備:ファイルのダウンロード

まずArduino IDE(→リンク)をDL。最新版で多分OK、この記事では2.0.3のmacOS/Apple Silicon版を使用。
macOSではドライバのインストールも一切不要でお手軽。

WindowsやLinux環境・macOS Mojave以下ならおそらくIDE1.0.6を使うことで一部のエラーを回避できるが、今回はソース改変で対処するためスルー。一応1.0.6推奨ではあるとのこと。

続いてWi-Fi設定用のツール(→リンク)を確保。そのままブラウザで実行すると大半の場合セキュリティ機能に引っ掛かってブロックされるので(開発機能でコンソールを見るとよく分かる)、一度ローカルとして保存してから。特にSafariではブロックを解除する方法が一切ないので、Apple信者はどう足掻いても必須。
保存方法としてはChromeでアクセスし、完全なウェブページとしてダウンロードするのが正解。今回はこれで動作確認を取った。

最後に改造ファームウェアをGitHub(→リンク)から引っ張る。

左上で「settings-led-cloud」であることを確認し、右上のCode→Download ZIPでダウンロード。そのまま解凍しておく。
解凍したフォルダのfirmware→src→IRKitフォルダの中身がファームウェア本体。

そしてこのフォルダにある「version.template」を「version.c」にリネームして拡張子を変更する。

リネーム完了後、ArduinoIDEでIRKit.inoを開くとフォルダ内の全ファイルを編集可能になる。

ファームウェアの修正

ぽちぽち修正。

1-1:log.h、IrCtrl.cpp

まずはlog.hの修正から。IRKitは基本容量カツカツなので、不要部分をコメントアウト(ソースコードには残るけどプログラムには残さない)して容量節約。
log.h22行目から26行目、#define ○○LOGの部分をごっそりコメントアウト。開始点に「/*」・終了点に「*/」を入れると範囲指定してコメントアウト出来る。

次にIrCtrl.cpp。435行目にクラウドサーバーに接続する処理が記載されているので、死体蹴りこれもコメントアウト。

これで完了。

1-2:version.c、config.h

version.cから。17行目にバージョンの文字列があるので、これを任意の文字列に変更しておくといい。後でソースコードを見返した時の識別方法にもなる。
過去にはiOSAppで確認できたが、現在はコマンドでHTTPリクエストを送信した時に確認できるのみとなっている。

続けてconfig.h。34行目にLEDのパターンを設定できる項目があるので、お好みに応じて変更しておく。
変更箇所の少し上にまんま英語で説明があるのでそちらを参照。LED_VERBOSEがデフォルト、LED_QUIETが常時点灯のみオフ、LED_SETUP_ONLYが起動時以外だいたいオフ、LED_OFFが全部無効。

続けて40行目。これがクラウド機能をオフにするオプションなので当然変更。
trueでクラウド機能有効、falseで無効。今後使わないと思われるためfalse安定。trueにしていると現状では起動不可能に陥る。

終わり。

1-3:GSwifi.cpp

IRKitの名前(Bonjour等で使用)・IRKit自身のSSIDとパスワード(初期設定用)を変更する。
SSIDと名称は同一。1096行目で設定可能なので、お好みの文字列に変更。以前使っていた設定に合わせておくと色々楽。

今後この情報を忘れたままリセットしてしまっても、この部分を変更することで自由に復旧が可能。覚えておくと便利。

1-4:IRKit.ino

318行目から始まるif関数の下に追記。

ここまででソースの修正は全て完了。IDE1.0.6以外の場合、次の1-5の修正も必要になる。

1-5:cert.h、pgmStrToRAM.c、pgmStrToRAM.h

これら3ファイルの修正はArduino1.0.6以外でコンパイル・書き込みを行う際に必要。1.0.6環境ならこの手順(1-5)は飛ばしてOK。内容はこれ(GiuHubリンク)の引用。
書き込む環境がmacOS Catalina以降の場合32bitアプリ起動不可制限の影響でIDE1.0.6が使えないため、必須の変更になる。

まずはcert.hの23行目、prog_ucharをconst unsigned charに置き換える。

続けてpgmStrToRAM.cの29行目、PROGMEM charをconst PROGMEM charに置き換え。

最後にpgmStrToRAM.hの29行目、こちらもPROGMEM charをconst PROGMEM charに置き換え。

これで修正完了。IDE1.0.6以外でもコンパイル可能になる。

ファームウェアの書き込みと初期設定

2-1:IRKitのリセット

リセットボタンからリセットをかけることで、EEPROMを初期化する。

本体背面、microUSB端子と反対側にある穴にボールペンか何か細いものをを差し込むとリセットボタンが押せる。microUSBケーブルを繋いだ(=通電した)状態でこれを長押しして、ランプが数秒間赤く点灯し続ける(=起動し直す)まで押し続ける。
上手くいけばEEPROMが初期化されてランプが赤く点滅し始める。赤点滅は未設定を表すランプで、つまりはEEPROMが空っぽになった証。

2-2:コンパイル・書き込み

右上から書き込み。microUSBケーブルぶっ刺してPCに繋いでからArduino Leonardoを選択、右矢印(→)で書き込みスタート。

書き込みが完了するとIRKitが再起動する。

2-3:Wi-Fi設定

赤点滅中のIRKitは自力でWi-Fiを構築しているので、これにPCを接続する。GSwifi.cppで設定したIRKitから始まるSSIDに、同じく設定したパスワードを入力すればIRKitの構築したLANに繋がる。

この状態のまま、事前にダウンロードした設定ツールのHTMLを開く。1と2はクラウドサービスに関するものなので飛ばしてOK、3はここに書いたIRKitへの接続の話なので完了済みで飛ばしてOK。

今回使用するのは4のみ

4の入力欄に、今後IRKitを接続させたいネットワーク(=自宅のWi-Fi)の情報を打ち込んでいく。それぞれSSID・パスワード・暗号化方式。一番下のDevice keyはクラウドサービス用なので空欄でOK。

入力が終わったらSend to IRKitをポチッと。IRKitに今入力したWi-Fiの情報が送信され、IRKitは入力したWi-Fiへと接続を始める。
HTMLとして保存せず実行した場合、ほとんどのブラウザはこの時点でエラーを吐く。これはセキュリティ設定によるもので、macOSのSafariだと解除不可能なため保存した上でローカルからの実行が必須。
それ以外でエラーを吐く場合、初期化→ファーム書き込みの流れに沿っていない(EEPROMが空でない)。

正常に接続できたらconfig.hの設定次第で青点灯(=信号指示待機状態のLED)したり消灯(=待機状態LEDを消灯する設定の場合)したりするので完成。これでLAN内のHTTPサーバー機能のみでIRKitが運用可能になったはず。
もちろんPCは元通りに自宅のWi-Fiに接続し直しておこう。(大体は自動でなると思うけど)

おまけ

IrCtrl.cppの処理をconfig.hによって変える

説明ではクラウドサービス関係の機能をソースコードからごっそり削っているが、今回使ったファームウェアは本来クラウド機能の有効/無効をconfig.h内に記載出来るようになっている。
これをより徹底することで、config.h次第でクラウドサービスの有効/無効を完全に切り替えられる完成度の高いファームウェアに出来る。

具体的にはIrCtrl.cppにconfig.hを読み込ませ、それに応じて切り替えるコードを仕込む。まずはIrCtrl.cppの29行目。

log.hを読み込むコードの下に、同じようにconfig.hを読み込むコードを追記する。

ファームウェアにWi-Fi情報を書き込む

IRKit.inoの292行目keys.load();の下に追記することで、起動時にEEPROMにWi-Fi情報を書き込ませることが出来る。

WPA2_PSK(暗号化方式)・SSID(自宅のネットのSSID)・PASSWORD(パスワード)は環境に応じて変更。

EEPROMが空の状態で一度起動させた後、すぐ緑点滅(=設定済み、接続試行中)になることが分かる。
設定・接続が出来たのを確認したら、今度は追記した部分を削除orコメントアウトして再度書き込み。これをやらないと起動するたびにEEPROMに書き込んじゃうので、microSDとかUSBメモリみたいに秒速で死にそうだしたぶんやっといた方がいい。

294行目と298行目で囲んでコメントアウト

ブラウザを使わずArduino IDEのみで完結するので、ソースコードを見ても頭ぐるぐるしない人はこっちの方がお手軽かもしれない。

Homebridgeプラグインの話

homebridge-irkitプラグインで連続で指示を送ったりシーン機能で複数機器を組み合わせたりすると、結構な頻度でsocket hang upとかいう処理落ちみたいなエラーを起こす。
これを解消したHomebridge用プラグインhomebridge-irkit-mod(→npmjsリンク)があるので、そちらに切り替えると快適。わたしはこれで1年以上シーン機能を乱用しているが、今のところsocket hang upで動作しなかったところは一度も見ていない。処理落ち頻度が激減するため、IRKit経由で操作する赤外線デバイスをかなり信頼できるようになる。

照明・テレビロボット掃除機等。ロボット掃除機は変な会社のクラウドに頼るよりも、LAN内のIRKit+HomebridgeとHomekit+ホームハブ+Appleのクラウドに依存する方が安全という判断。クラウドに頼らないIRKit+HomebridgeとHomekitをベースにスマートホームを組み上げると、AppleがHomekit関連をサ終しない限りずっと使えるので非常に安心。

IRKitが構築したネットワークを流用する

未設定で赤点滅中のIRKitは自力でWi-FiアクセスポイントとLANを作る。そこに接続しているデバイスからHTTPリクエストを送ればふつーに赤外線信号の指示が出来るので、実は未設定のままでも使えたりする。

当然インターネットには繋がらないしHomebridgeサーバー等の場合サーバー機のWi-Fiがこれに割かれることになるので、基本的には有線LANとの併用を推奨。サーバー機側で有線LANを優先するように(激ウマギャグ)設定しておいて、有線LANでインターネットに接続しつつWi-FiでIRKitに接続すればHomebridgeくらいなら簡単に使える。
ついでにIRKitが構築したネットワークにサーバー機を参加させる場合、サーバー機から見たIRKitのIPアドレスは常に「192.168.1.1」で固定になる。よってHomebridgeのconfigではこのIPアドレスを書けばOK。
BonjourアドレスでもいいけどIP直打ちの方がレスポンスは圧倒的に早く、ホームAppやSiriでの指示にもほぼノータイムで反応する。

ルーター側からIPアドレスを固定する必要がないので結構お手軽だったりする。
更にこの方法だとEEPROMの書き換えを必要としない(ただしEEPROMが空であること=リセットは必須)ので、万が一の場合のための保険として覚えておくと役立つかも。
わたしは今回の事象が発生した時、解決するまでの間は一旦この方法で凌いでいた。

ランプについて

この方法では未設定のまま運用することになるので、基本は赤点滅しっぱなし・・・かと思いきや、意外とそうでもないみたい。

IRKitはまず起動時に赤点灯・その後にEEPROMが空なら赤点滅・空でないなら緑点滅しながらEEPROMに保存されたWi-Fiに接続、以降青点灯。そして赤外線指示を受けて飛ばす時に青点滅、といった挙動を取る。
これは「そのシーンに入るごとにLEDのパターンを設定する」というプログラムが書かれているからで、赤点滅中だろうが赤外線指示を投げると青点滅のパターン設定のプログラムが割り込む。そして割り込まれた後に戻ることはないので、未設定のはずなのに赤外線指示を受けた瞬間に消灯するという珍現象が起こる。

つまり未設定のままIRKitが構築したネットワーク内で運用する場合でも、IRKitが起動した後に一度指示を投げてやれば消灯させられるのである。もちろんconfig.hのledFeedbackをLED_QUIET以下にしていれば、赤外線指示を受け取った瞬間青点滅すらせずに一瞬で消灯し以後光らなくなる。

スマートコンセント等でIRKit自身の自動再起動を定期的に挟んでいる場合、ダミーの赤外線デバイスを1つ用意しておき、自動起動の1分後とかにダミーの赤外線デバイスを作動させるように設定すれば自動でIRKitのランプを消灯させることも出来る。

もちろん黒ビニテでランプ部分をごっそり覆ってもいい。でもこれだと穴からちょっと光が漏れる。

仮想マシンやWineでのArduino IDE 1.0.6利用

上に書いた通り、Arduino IDE 1.0.6は32bitアプリ。macOS Catalinaでの32bitアプリ排除の影響をモロに受けているため、これを回避するには仮想マシンや変換レイヤーを備えたWine環境でWindows版を動かす必要がある。ちなみにmacOS用の32bit版はどうやってもCatalina以降で動かせないみたい。

MacminiのVMwareFusionで作った仮想マシンのWindows10を使えば、一応IDE1.0.6を使った書き込みはこなせた。Catalina以降でIDE1.0.6を使いたい場合は選択肢として使える。

Wineは互換レイヤーを含んでいるWineskinserverで試したんだけど、なんか普通にIRKitが繋がらなくて詰まったので没。

Wineskinserverでは作成したWrapperの.appパッケージの中、Contents/SharedSupport/prefixにdosdevicesがあり、ここにコマンドで作ったシンボリックリンクファイルを貼ることで接続できるらしいことまでは特定したんだけど、なんか普通にダメだった(無知)。ちなみにリンクファイルはコマンドで作れた。

usbDeviceNameはArduino IDEで見えてるやつ。またはHomebrewからインストール出来るlsusbを使って特定可能。

でも作ったリンクファイルをパッケージ内部に放り込んでもダメだったのでよくわかんない。
あとめっちゃ文字化けしたしフォント放り込んでもどうにもならなかったので、出来たとしても書き込み専用の環境になる。M1Mac上のVMwareFusion仮想マシンのARM版Windows11ではUSBがまだ使えない的な話をチラッと見たので、現状M1Mac単体でIRKitに改造ファームウェアを書き込むにはこの記事の手順通りにArduino IDEの最新版へ適合するようにソースを改変するしかなさそう。

あと1.0.6はソースの行数見れないし使いづらい。あと2.0.3の高コントラストダークモードが見やすいので正直1.0.6あんま使いたくないです。

まとめ

サービス終了してもなお延命は可能で、LAN内のHTTPリクエストで動くので非常に快適。Homebridgeと合わせれば爆速レスポンスで赤外線デバイスが使える上に、HomeKitとホームハブを通せば現在でもクラウド化・外出先からの家電操作が実現出来る。
独自のクラウドサービスが終了してもソース改変で役目を与えられるなど、IRKitのポテンシャルの高さを改めて実感した。

余談だけど、この記事を書いている最中にSwitchBot HubのMatter対応版が発表された(→公式リンク)。既存のSwitchBotカーテン等をMatter対応させるために使えるけど、Hub内蔵の赤外線リモコン機能は使えないらしい。
赤外線リモコン機能は今まで通りSwitchBot側のクラウドサービスでのみ動作し、Matter環境では無効化されるとのこと。

Matterのメリットの1つにHomeKit対応があるが、HomeKit環境での赤外線リモコンは今後もIRKitが安定かつ最速であり延命する価値があることが証明された。
うちでもテレビ・照明・ロボット掃除機を全てIRKitに任せているので、出番がなくなることはしばらくなさそう。基本的に独自クラウドよりIRKit+LAN内Homebridgeの方が信用出来るし早いので、不安定なクラウドサービスに頼るより確実。

カテゴリー: Homekit/Homebridge, ガジェット, 周辺機器 タグ: パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です