Wi-Fi 接続とセットアップモード¶
デバイスがネットワークのパスワードを受け取る経路は 2 つあります。ケーブル経由の Web インストーラー(Improv プロトコル)と、Android / iOS 向けモバイルアプリ iDryer からの無線経由(ESPTouch v2 プロトコル)です。受け取ったパスワードは NVS に保存され、再起動しても残ります。
これを担当するのが EspTouchProvisioner(platform/arduino/)です。製品側から呼ぶものはありません。Link が起動して回します。コールバックは、セットアップの進行を画面に表示するためだけに存在します。
プロトコルはバージョン間で互換性がありません。アプリは必ず ESPTouch v2 を送る必要があります。初代ではデータをフレーム長で運んでいたため、ルーターが 2.4 GHz と 5 GHz の間でブロードキャストを中継すると壊れました。同じ名前を共有する 1 つのメッシュネットワークでは、成功したりしなかったりという状態になります。
この挙動を理解しておく理由は 1 つです。デバイスは、可能なときは黙って接続を回復し、どうにもならないときだけ持ち主を呼ぶべきだからです。誤りは両方向に起こります。ルーターがしゃっくりするたびに持ち主を煩わせるか、誤ったパスワードのまま黙ってオフラインで固まるかです。
4 つのフェーズ¶
プロビジョナーが生きているのは**最初の接続成功までだけ**です。Link::loop() は Wi-Fi が立ち上がるまで呼び出し、最初の WL_CONNECTED の後はクラウドステートマシンが引き継ぎます。セットアップモードは次の再起動まで二度と起動しません。
フェーズ 1. 起動時、パスワードがメモリにある¶
粘り強いモード、診断なし。
kBootRetryMs(6 秒)ごとに接続を試みます。これを kConnectFallbackMs(90 秒)続けます。つながれば動作開始、つながらなければセットアップモードを起動します。
診断しない理由: パスワードは新しいものではなく、以前は機能していました。電波が弱いのかパスワードが変わったのかを突き止める必要はありません。この時間内に接続できなければ持ち主を呼び、その場で判断してもらいます。
再試行が必要な理由: WiFi.begin() は Link::begin() から 1 回だけ呼ばれます。クラウドステートマシンは WL_CONNECTED の前には動かず、Arduino の自動再接続は reason 202 と 205 を対象にしていません。再試行がなければ試行はちょうど 1 回で、電波が弱いとデバイスは有効なパスワードを持ったままセットアップモードに入ってしまいます。
90 秒とした理由 — 停電から復旧してすべてが同時に立ち上がる最悪のケースから逆算しています。
- 最大 60 秒 — ルーターの起動。Broadband Forum の業界要件 TR-124 Issue 9 の
GEN.OPS.9「The RG MUST complete power up in 60 seconds or less」。ただし、この要件はゲートウェイ全体の起動を対象としており、SSID が現れるまでの個別の上限ではありません。一般的な機器の実測では電波が出るまで 34〜49 秒なので、60 は平均ではなく妥当な上限です。 - 加えて自機の接続 — 通常 2〜5 秒ですが、
RSSIが −85 dBm 程度になると 20 秒まで伸びます。
よって 90 秒です。ルーターに 60 秒、自機に 30 秒。これより短いと、ネットワークが現れる直前に持ち主を呼ぶ危険があります。大幅に長いと、持ち主は接続も説明もない機器を長々と眺めることになります。
同時に電源が入ったルーターとアクセスポイントは順番ではなく並行して起動するため、時間を足す必要はありません。「クライアントがアドレスを取得しインターネットに到達する」という厳しい基準なら 90〜120 秒になります。そこには WAN、DHCP または PPPoE、モデムの同期が加わるからです。それを待つ必要はありません。デバイスはローカルネットワークに入れれば十分です。
フェーズ 2. 起動時、パスワードがない¶
セットアップモードを即座に起動します。待つ理由がありません。
フェーズ 3. パスワードを受け取った直後¶
賢いモード、driveConnect()。
ここではパスワードが**新しく、誤っている可能性があります**。持ち主が打ち間違えたかもしれません。そのためプロビジョナーは失敗の原因を区別します。
- 連続した認証失敗を数えます(
kAuthFailLimit、8 回)。 - 5 回目の後に電波を調べ、最良の
RSSIを記憶します。 RSSIがkWeakRssi(−80 dBm)より悪ければ復帰は取り消されます。同じreason15 と 202 は、正しいパスワードでも auth フレームの喪失で発生し、接続に数分かかることがあるためです。そこでは別の期限kWeakSignalGiveUpMs(10 分)が使われます。- 電波が十分で 8 回失敗した場合はセットアップモードに戻ります。そうしないと打ち間違いから抜け出す手段が再書き込みしかなくなります。
さらに完全な沈黙に対するウォッチドッグ(kWatchdogMs、20 秒)があります。イベントも接続もない場合、esp_wifi_disconnect() でスタックをつつきます。
フェーズ 4. 動作中に接続が切れた¶
プロビジョナーはもう呼ばれません。接続はクラウドステートマシンが黙って回復し、セットアップモードは起動しません。持ち主を煩わせないためです。デバイスから見れば「夜間にルーターの電源を切った」と「ルーターを交換した」は区別できないため、推測しようとしません。
ネットワークが変わったことをデバイスに伝えるには¶
再起動します。
再起動するとフェーズ 1 が始まります。古いパスワードは合わず、90 秒が無駄に過ぎ、セットアップモードが起動します。そこで新しいパスワードをスマートフォンから送るか、ケーブルを挿します。推測は一切なく、電源を切って入れるだけです。
仕様: セットアップモードからは自力でネットワークに戻りません¶
電波を聴いている間、デバイスは保存済みネットワークへの**接続を試みません**。無線は受信で占有されており、新しいパスワードが届くまで接続の試行は止まります。
実際上の帰結: ルーターの起動に 90 秒以上かかり、デバイスがすでにセットアップモードに入っていた場合、後からネットワークが現れても自力では戻りません。パスワードを送るか、デバイスを再起動する必要があります。
これは見落としではなくモードの性質です。電波を聴きながら同時に接続を確立することはできません。
タイムアウト¶
| 定数 | 値 | 意味 |
|---|---|---|
kBootRetryMs |
6 秒 | フェーズ 1 の再試行間隔 |
kConnectFallbackMs |
90 秒 | 持ち主を呼ぶまでに試す時間 |
kReconnectDelayMs |
700 ミリ秒 | 切断後、次の試行までの待ち(フェーズ 3) |
kWatchdogMs |
20 秒 | スタックをつつくまでの沈黙時間 |
kAuthFailLimit |
8 | セットアップに戻るまでの連続認証失敗回数 |
kWeakRssi |
−80 dBm | 「電波が弱い」の境界 |
kWeakSignalGiveUpMs |
10 分 | 弱い電波をあきらめるまでの猶予 |
kRestartMs |
10 分 | パスワードが届かない場合のセットアップモード再起動 |
持ち主に見えるもの¶
セットアップモードに入ると Notice コールバックが呼ばれます。
Listening— 通常のセットアップ。ネットワークが未登録か、すでに接続実績がある場合です。CheckPassword— ネットワークは登録済みなのに一度も接続できていない場合。残る説明はパスワードの誤りだけです。
表示方法は製品側が決めます。idryer-touch では全画面の通知です。