【ITニュース解説】OTA Python updates with ESP-Now
2025年09月27日に「Dev.to」が公開したITニュース「OTA Python updates with ESP-Now」について初心者にもわかりやすく解説しています。
ITニュース概要
ESP32デバイスのPythonコードなどを、ESP-Nowを使って無線で遠隔更新する技術を紹介。ファイルを小さなデータに分割して送り、デバイス上で一時保存・検証後に適用する仕組みを解説する。これにより、複数のファイルを安全に一括更新でき、システムの不整合を防ぎながら効率的にプログラムを更新できる。
ITニュース解説
この記事は、ESP32という小型のコンピュータとESP-Nowという通信技術を利用して、複数のデバイスが連携するネットワークシステムを構築し、その上でデバイスのソフトウェアを無線で更新する方法について解説している。具体的には、マスター(親機)とスレーブ(子機)に分かれたネットワークにおいて、スレーブデバイス上のPythonプログラムやその他の設定ファイルを、遠隔から安全に書き換える(Over-The-Air、略してOTA)仕組みを詳しく説明している。
まず、このシステムの基盤となっているのは、ESP32というマイクロコントローラだ。これは非常に小さなコンピュータでありながら、Wi-FiやBluetoothといった無線通信機能を内蔵しており、冷蔵庫や照明など、身の回りの様々なモノをインターネットに接続するIoTデバイスの制御によく使われている。ESP-Nowは、このESP32などが持つWi-Fiチップの特殊な通信モードで、通常のWi-Fiのようにルーターを介さずに、デバイス同士が直接、高速かつ少ない電力で短いメッセージをやり取りできる点が特徴だ。これにより、親機が子機に直接指示を送ったり、子機が親機に状態を報告したりする「マスター・スレーブネットワーク」を効率的に実現できる。
このネットワークにおけるスレーブデバイスの主要な処理を行うのが、「Handler」というクラスだ。このクラスの主な役割は、マスターデバイスから送られてくる様々なメッセージを受け取り、そのメッセージの内容に応じた適切な処理を実行し、その結果をマスターに返すことにある。例えば、「リレーをオンにする」「現在のデバイスの稼働時間を報告する」「デバイスをリセットする」といった多岐にわたる指示をこのHandlerクラスが処理する。
Handlerクラスが初期化される際には、「Config」という別のクラスからシステムに必要な設定情報を受け取る。Configクラスは、どの入出力ピンがどんな役割を持つかといったシステム固有の設定データを一元的に管理しているだけでなく、他のクラスが必要とする機能を提供するハブのような役割も果たしている。これにより、Handlerクラスは、Configクラスが提供するリレー制御用のオブジェクトなどを使って、具体的なリレーの操作方法を知ることなく、必要な機能を簡単に呼び出すことができる。
Handlerクラスの中でも特に重要なのが、「handleMessage()」というメソッドだ。このメソッドは、受信したメッセージの内容を解析し、それに応じて様々な処理を実行する。例えば、「uptime」というメッセージが来ればデバイスの稼働時間を返し、「on」や「off」というメッセージが来ればリレーの状態を制御するといった具合だ。また、「delete」で特定のファイルを削除したり、「mkdir」で新しいディレクトリを作成したりするような、より高度なファイルシステム操作を指示するメッセージも処理できる。
そして、この記事の核心であるOTAファイルアップデーターの機能も、このhandleMessage()メソッド内で実現されている。ESP-Nowは一度に送れるデータ量に制限があるため(約200バイト強)、大きなPythonスクリプトのようなファイルは一度に転送できない。そこで、ファイル全体を約100バイトずつの小さな塊(パート)に分割し、それぞれを順番にマスターからスレーブへ送る仕組みが採用されている。
具体的には、「part:{パート番号},text:{データのヘックスエンコード値}」のような形式でメッセージが送られてくる。handleMessage()メソッドは、このメッセージからパート番号と実際のデータ(ヘックスエンコードされたものを元のテキスト形式に戻す)を抽出し、期待するパート番号と一致するかどうかを確認する。もし順序が正しければ、そのデータを内部のバッファ(一時的なデータを保持するリスト)に追加していく。データが正常に受信できたことをマスターに通知するため、受信したパート番号とデータのサイズを返信する。これにより、マスター側はデータの送信が正しく行われたかを確認できる。
すべてのデータパートがスレーブに送られ、バッファに格納されたら、次は「save」コマンドを使ってこのデータをデバイス上のストレージに一時ファイルとして保存する。この時、元のファイル名に「t-」というプレフィックスを付けた一時的なファイル名で保存される。
ファイルが一時的に保存された後、次のステップはデータが転送中に破損していないかを確認することだ。「checkFile()」というメソッドがその役割を担う。このメソッドは、保存されたばかりの一時ファイルを一文字ずつ読み込み、それをバッファに格納されている元のデータと比較する。もし読み込んだファイルの内容がバッファの内容と完全に一致すれば、データが正しく転送され、破損なく保存されたと判断できる。
しかし、複数のPythonファイルや設定ファイルを同時に更新する場合、一つのファイルだけが更新され、途中でエラーが発生したり、何らかの理由で更新が停止したりすると、システム全体が不整合な状態になり、デバイスが正常に動作しなくなる可能性がある。このような問題を避けるため、ファイルを一つずつ更新するのではなく、全てのファイルを一度にバッチ処理として更新することが重要だ。
そのために、「update」コマンドが用意されている。このコマンドが実行されると、まず一時ファイルとして保存されていた全ての「t-ファイル」(例えば「t-main.py」)が、元のファイル名(「main.py」)にリネームされる。これにより、全ての更新ファイルが同時に有効化され、システム全体の整合性が保たれる。つまり、全てのファイルが一時的に保存され、かつそのデータが正しく転送されていることが確認できてから初めて、実際のプログラムに反映される、という仕組みだ。
もしファイル転送の途中でエラーが検出され、マスター側に報告された場合、このシステムはその保存プロセス全体をやり直すことができるようになっている。実際の運用では、特に電波状況が悪い場所や電波干渉が多い環境では、大きなファイルを転送するのに数回の試行が必要になることもある。このシステムでは、最大10回の再試行を許容し、それでも成功しない場合は更新を諦める、といった堅牢なエラー処理も考慮されている。
このように、このシステムはESP32とESP-Nowを活用し、マスター・スレーブネットワークにおいて、Pythonプログラムを含む様々なファイルを安全かつ効率的に無線で更新するための包括的なソリューションを提供している。データの分割送信、バッファリング、整合性チェック、そしてバッチ更新といった多層的なアプローチにより、信頼性の高いOTAアップデートを実現しているのだ。