🌟

【MicroPython】Raspberry Pi Pico W向けWebサーバー

2023/08/15に公開

Raspberry Pi Pico WでWebサーバーを!

Raspberry Pi Pico W (以下PicoW)で、Webサーバーを動かしたいことあると思います。いくつかの方法があると思いますが、MicroPythonの上で動く手軽なものが欲しかったので自作しました。

自作したWebサーバーはこちらのリポジトリで公開しています。
https://github.com/techmadot/TMiniWebServer

ちなみにPicoWで動くWebサーバーは他にも選択可能です。

TMiniWebServer

TMiniWebServerはRaspberryPi Pico W上で動作させることを目的としたWebサーバーです。MicroPythonの上で動作します。他のプロダクトに似た記述の仕方を採用しており、他のWebサーバー実装と交換しやすくしています。

並列動作実現のためにasyncioを使用しており、スレッドは未使用です。そのためPicoWの1コアは自由に使うことが可能となっています。

特徴

TMiniWebServerは以下の特徴があります。

  • asyncio(uasyncio)を用いた複数のリクエストの同時処理を実現
  • デコレーターによるhttpルーティングハンドラの指定
    • Flaskで使用できた基本的な記述が利用可能
  • WebSocketに対応し、双方向のリアルタイム通信を実現可能
  • 少ないファイル数で、組み込みしやすく

実装の例

Flaskのようなルーティングハンドラの設定

以下のような記述でハンドラーを実装します。ここでは '/hello' にアクセスに来た時にこの関数が実行されます。

@TMiniWebServer.route('/hello', method='GET')
async def webHandlerHello(client):
  data = 'Hello,world'
  await client.write_response(data, http_status=HttpStatusCode.OK)

このとき、レスポンスを返す際、headers={ 'myheader': 'sample_value'} のようにして任意のヘッダを追加することが可能です。

URLに指定した特定のパス部分をパラメータとして受け取ることができます。次のように指定して "<, >"で区切られた部分をパラメータのキー名として使用します。

@TMiniWebServer.route('/sample/<id>/<kind>')
async def test_get_with_path_params(client, args):
  ## URL のパスに指定されたパラメータをキーワードで取得.
  id = args['id']
  kind = args['kind']
  ....

WebSocketの使用

WebSocketを使うには次のように記述します。@TMiniWebServer.with_websocketで設定した関数は、指定されたURLでWebSocket通信が確立された後で呼び出されます。

@TMiniWebServer.with_websocket('/ws/')
async def websockcet_handler(websocket):
  while not websocket.is_closed():
    data, msg_type = await websocket.receive()
    print(data)
    await websocket.send("Hello,world!!", type = TMiniWebSocket.MessageType.TEXT)

ここでwith_websocketに指定するパスについては、先の説明で登場したhttpのルーティングハンドラ設定と同じ記述が使用可能です。ですので、パラメータを受け取ることができます。

スタティックファイルの配信

特定のフォルダに置かれたファイルを配信することもできます。デフォルトでは /wwwroot フォルダにあるファイルをクライアントの要求によって返却します。

PicoWのフラッシュメモリの容量だと、Vue.jsを使用したプロジェクトをビルドしても若干の余裕があるかなというところでした。

開発の経緯

ワットチェッカーを作りたい

SwitchBotプラグミニを使って、ワットチェッカーを作りたいと思ったのが始まりです。リアルタイムに近いデータのサンプリングをしてグラフを作ってくれるものが欲しかったのです。

SwitchBotプラグミニはBluetoothを使用して、現在使用中のデバイスの消費電力を通知します。これをRaspberry Pi Pico Wで受けて、ブラウザでグラフにすれば目的が達成できると考えました。
また、一度作ってしまえば、データの保存やグラフの保存といった目的に合うような改良も検討できます。

既存のWebサーバーへの不満

既存のWebサーバーのプログラムではいくつかの点に不満がありました。以下の点を実現するべく、自作の道を選択しました。

  • Flask のようなURLのルーティングを書きたい
  • WebSocket を使用した双方向リアルタイムの通信をサポートしたい
  • 最小限のファイルで他プロジェクトで再利用しやすいものにしたい
  • 複数のリクエストを同時に処理したい

まとめ

PicoWで動くコンパクトなWebサーバー機能が欲しかったので作成しました。
PicoWは各種センサーや他のデバイスなどとやり取りができ、さらにWi-Fiによるネットワーキング機能があるので、大変活躍が期待できるものです。値を外部のクラウドに送信するのも悪くないですが、PicoW自身をWebサーバーとしてローカルで完結させてしまうのも1つの選択にできると思います。

https://github.com/techmadot/TMiniWebServer

使用実績など

最後に使用実績や将来について少しだけ紹介します。

自分で使うのに作成したTMiniWebServerは、以下のワットチェッカーアプリで使用しています。およそうまく動いていますが、もしかするとまだ不具合があるかもしれません。

https://github.com/techmadot/mini-watt-checker-2

ワットチェッカーの機能自体はこちらのスマートプラグミニを使用して実現しています。

https://www.amazon.co.jp/dp/B07TVSGJT4?tag=technicalistaz00-22&linkCode=ogi&th=1&psc=1

この先に作ってみたいもの

シリアルコンソールをWebブラウザ経由で使うということを以前にやっていたので、それを本サーバーを用いて再度実現したいなと考えています。

Discussion