HN 日本語サマリー

← 一覧へ戻る
AI・機械学習

iroh搭載スマートファン

An iroh powered smart fan (iroh.computer)

143 pointsby surprisetalk42 コメント

要約

この記事では、irohネットワークライブラリとESP32マイクロコントローラーを使用して、クラウドコンポーネントなしで動作するスマートファンを構築する方法を紹介しています。ESP32は温度センサーを読み取り、ファンを制御し、WebAssemblyで動作する小さなウェブサイトを通じて世界中どこからでもアクセス可能です。PSRAM搭載のESP32-WROVER開発キットをベースに、ローカルネットワークとリレー接続を利用して、デバイスがグローバルに到達可能になるプロセスを解説しています。

全文翻訳

もしあなたがヨーロッパ、北半球にお住まいなら、今まさに熱波に苦しんでいるかもしれません。irohを使って、涼しさをもたらす何かをしましょう。以前のESP32の例では、エコープロトコルを実演しました。しかし、通常ESP32は単なるデータのエコー以上のことに使われます。センサーを読み取り、アクチュエーターを駆動するための安価な手段としてESP32を使用します。そこで、ESP32を使って温度を測定し、ファンを制御する、非常にシンプルなエンドツーエンドの例を作成します。ほとんどのIoTデバイスとは異なり、クラウドコンポーネントは一切ありません。WebAssemblyをサポートする任意のブラウザから、世界中どこからでも使用できる小さなウェブサイトだけです。ベースとして、4MiBのPSRAMを搭載したESP32-WROVER開発キットを使用します。これにより、リレー接続を含むirohのすべてのネットワーク機能が利用可能になり、世界中どこからでもリモート制御できます。M5StickC-Plus2も使用できますが、GPIOピンを調整する必要があります。PSRAMなしのESP32開発キットしかない場合でも、irohを使用できます。ただし、リレー接続を無効にし、メモリ不足にならないようにQUICバッファを調整する必要があります。iroh-esp32-examplesから適切な例をベースに使用してください。 基本セットアップ 最初のステップとして、iroh-esp32-examplesからエコー例をコピーします。ESP32バイナリにはserver-esp32-psramを使用します。クライアント側は単にclientを使用します。これはデスクトップPCで動作し、非常に標準的なものです。これはスマートファン用なので、server-esp32-psramをserver-smart-fanに、clientをsmart-fan-cliにリネームします。異なるツールチェーンが必要であり、ESP32バリアントにirohのパッチを使用するオプションを維持したいので、2つのディレクトリは完全に分離したRustプロジェクトです。ワークスペースは使用しません。 初期状態 最初のフラッシュ 変更を加える前に一度試してみましょう。サーバープロジェクトでcargo runを実行すると、USB経由で接続されたESP32が検索され、フラッシュされます。そこで、ESP32をUSB-Cケーブルで接続します。最初のリリースビルドには時間がかかります。irohだけでなく、オペレーティングシステムもxtensaアーキテクチャにコンパイルするためです。その後のビルドは、コンパイル結果が.embuildディレクトリにキャッシュされるため、より速くなります。フラッシュ自体は、チップへのデータレートが非常に限られているため、決して速くはありません。ESPF LASH_BAUD環境変数を設定することで、少し速くすることができます。私のチップは230400ボーをサポートしていますが、あなたのチップは異なるかもしれません。うまくいかない場合は、環境変数なしで実行してください。安全なデフォルトが使用されます。ESP32にWLANへの接続方法を指示する必要があります。例では、別の環境変数WIFI_CONFIG=SSID:PASSWORDを使用します。これをローカルWLANに設定してください。毎回渡す必要がないように、単一のexport WIFI_CONFIG=SSID:PASSWORDを実行できます。 ESPF LASH_BAUD=230400 WIFI_CONFIG=myap:mypass cargo run --release ❯ cargo run --release Finished `release` profile [optimized] target(s) in 0.56s Running `espflash flash --monitor target/xtensa-esp32-espidf/release/esp32-psram` [2026-07-01T07:14:23Z INFO ] 🚀 A new version of espflash is available: v4.4.0 [2026-07-01T07:14:23Z INFO ] Serial port: '/dev/cu.usbserial-210' [2026-07-01T07:14:23Z INFO ] Connecting... [2026-07-01T07:14:30Z INFO ] Using flash stub Chip type: esp32 (revision v3.1) Crystal frequency: 40 MHz Flash size: 4MB Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None MAC address: 00:70:07:19:c8:4c App/part. size: 3,953,296/4,128,768 bytes, 95.75% [00:00:00] [========================================] 17/17 0x1000 Skipped! (checksum matches) [00:00:00] [========================================] 1/1 0x8000 Skipped! (checksum matches) [00:04:11] [========================================] 2295/2295 0x10000 Verifying... OK! [2026-07-01T07:18:43Z INFO ] Flashing has completed! フラッシュ出力からわかるように、フラッシュサイズの限界にかなり近づいています。App/part. size: 3,953,296/4,128,768 bytes, 95.75% コードの1行追加ごとに制限を超えてしまうのではないかと思うかもしれませんが、そうではありません。追加の純粋なRust依存関係(irpcなど)は、サイズをほとんど増やしません。 試してみる これで、ESP32上でシンプルなエコーサーバーが実行されているはずです。 エンドポイントID まず、エンドポイントIDをどのように割り当てるのでしょうか?エンドポイントIDを割り当てる能力が欲しいのですが、たとえ割り当てなくても、再起動後にエンドポイントIDが安定することを望みます。そのため、ESP32は起動ごとにランダムなIDを生成すべきではありません。代わりに、初回起動時に不揮発性メモリに秘密鍵を生成して保存し、それ以降の起動で再利用します。不揮発性メモリはフラッシュでは上書きされないため、不揮発性メモリを明示的に削除しない限り、同じデバイスに対して同じエンドポイントIDが得られます。 起動 起動時に、デバイスは指定された認証情報を使用してWiFiに接続しようとします。それがうまくいかない場合、ハングします。これは、irohエンドポイントのセットアップ前に行われます。実際の製品では、2つの代替WiFi設定と何らかのリカバリオプションが必要になるでしょうが、例ではこれを省略します。ESP32上のエンドポイントが起動すると、非常に馴染みのある出力が得られます。 I (7413) server_esp32_psram: Iroh endpoint bound I (7413) server_esp32_psram: Listening on: 192.168.0.186:51831 I (7413) server_esp32_psram: Endpoint ID: 03b43add965a3eaa2d20d3b60dcb1aa2fa8fdd36cdc1544511af11c26f45fd4b I (7423) server_esp32_psram: Short ticket: endpointaab3iow5sznd5krnedj3mdoldkrpvd65g3g4cvcfcgxrdqtpix6uwaa I (7433) server_esp32_psram: Long ticket: endpointaab3iow5sznd5krnedj3mdoldkrpvd65g3g4cvcfcgxrdqtpix6uwaibadakqaf266kag I (7443) server_esp32_psram: Router started, accepting connections デバイスはルーターのDHCPによってローカルIPアドレス192.168.0.186:51831を割り当てられました。長短両方のチケットが出力されますが、現時点ではIPアドレスを含む長いチケットを使用してローカルからのみ到達可能です。次に、QADを使用して世界のどこにあるかを特定しようとします。 W (7473) iroh::net_report: QADv4; relay_url=https://aps1-1.relay.n0.iroh.link./ W (7473) iroh::net_report: QADv4; relay_url=https://euc1-1.relay.n0.iroh.link./ W (7483) iroh::net_report: QADv4; relay_url=https://use1-1.relay.n0.iroh.link./ W (7493) iroh::net_report: QADv4; relay_url=https://usw1-1.relay.n0.iroh.link./ インターネットに接続されていると仮定すると、しばらくすると最も近いリレーを特定し、それをホームリレーとして設定します。 I (8963) iroh::socket::transports::relay::actor: home is now relay https://euc1-1.relay.n0.iroh.link./, was None この時点で、エンドポイントIDのみを含む短いチケットを使用して、世界中どこからでも到達可能になります。 接続 それでは、クライアントバイナリを使って試してみましょう。 ❯ cargo run endpointaab3iow5sznd5krnedj3mdoldkrpvd65g3g4cvcfcgxrdqtpix6uwaa ... Discovery: relay=on, mdns=on Connecting to ESP32... Connected! Sent: Hello from iroh! Received: Hello from iroh! Echo OK — crates.io iroh <-> ESP32! ローカルでは長いチケットを使用してリレーをバイパスできますが、エンドポイントがホームリレーを公開すると、グローバルに到達可能になるはずです。クライアントにはリレーを無効にするオプションがあります。それを無効にすると、長いチケットしか使用できなくなります。mDNS用のオプションもありますが、このプロジェクトではmDNSを使用していません。 シャットダウン cargo run --releaseを停止するとバイナリが停止すると思うかもしれませんが、そうではありません。単にデバイスへの接続が停止するだけです。エンドポイントは、電源がある限り happily 実行を続けます。切断して別のUSB-C電源に接続することもできます。そうすれば、同じエンドポイントIDで再び起動します。これがポイントです。ESP32は完全に自己完結型の組み込みコンピュータです。電源が必要なだけです。本当にシャットダウンしたい場合は、 unplug するか、espflash erase-flash を使用してフラッシュを削除してください。 センサーの追加 エコーサーバーがESP32で動作していることを確認したので、