IR、温湿度計などのGroveデバイスをREST風API化して、活用するESP32C3-IoT-Server-Boardを作った

tl;dr

  • 複数のGroveデバイスを接続可能なESP32-C3基板を作って、REST風API化したよ
  • お家のインテリアに合うようにケースも作ったよ
  • IR、温湿度計を付けて、お家の複数箇所にデプロイしたよ
  • Streamlitから便利に制御して使っているよ、マイコンでやるよりも楽そうだよ
  • Boothで販売中、つくまたにも展示するよ

ESP32-C3が安くて便利で使いまくっている

ESP32は非常に安価なWiFi、BLE付きマイコンモジュールですが、その中でも特に安いシリーズであるESP32-C3があります。秋月では310円で販売されています。安価ながらArduinoフレームワークに対応し、IOの数やメモリ、Flashが若干少ないですが、小さい用途であれば十分です。

akizukidenshi.com

加えて、汎用的なUSBデバイスコントローラ機能はありませんが、USB Serialのコントローラを付属しています。これにより、別のUSB Serialを用意しなくても、書き込みを行うことができます。非常に手軽です。

基本戦略、制御処理の多くは自宅サーバ(SBC)に持って行く

我が家には、OrangePi5+を自宅サーバとして使っています(かつてはミニPC(MacMini)を使っていましたが、ラズパイ4の頃からSBCに移りました)。そこではメディアサーバ等と動かしており、いつでもスマホから利用できるサーバリソースとして活用しています。

この背景から、確かに全ての処理をマイコン上のファームウェアで実現すると便利ですが、慣れているサーバサイドプログラミングで行った方が自在にクラウド連携や制御を記述できると思い、マイコン側はシンプルなHTTPサーバとして実現することを思いました。

Firmware設計: ArduinoでREST風APIを実現する

ESP32のArduinoを使って、HTTPサーバを立てるのは非常に簡単できます。このあたりは「アナログ電圧計を使って、ヘッドレスPCのCPU使用率表示を作る」という記事で軽く紹介しました。この記事ではArduinoJsonというライブラリを使って、JSONのパースの処理もしています。

74th.hateblo.jp

これと同じ要領で、REST風APIを設計しました。

  • POST /ir/send : 赤外線リモコンの送信
  • GET /sht31 : 温湿度センサの読み取り

実際に以下のようなデータを/ir/send にPOSTで送ります。

{
  "type": "MITSUBISHI_AC",
  "hex": "0x23CB260100205808164000000000080000F3"
}

すると、ESP32-C3に繋がれたM5 IRモジュールからエアコンの電源を制御できるようになりました。

今回のコード自体は、以下のリポジトリにMITライセンスで置いてあります。

github.com

基板設計: Grove3ポートと、インジケータがほしい

GroveデバイスをつなぐIoTを作るのであればM5Stack製品を用いるのが簡単です。 しかし、画面等を必要としない、電池も使う予定はないため、もっと安価に家中にばら撒きたく、専用の基板を設計することにしました。

  • Groveは3ポート用意し、I2C用のプルアップもできるようにする
  • Groveはデバイスに応じて、5V/3.3Vの電源を接続可能にする
  • インジケータ用のRGB LEDを付ける
  • おまけでボタンを追加しておく
  • 取り付け用の穴を開けておく

以下のものができました。

基板自体は、OSSとして以下で公開しています。

github.com

特に、注意したところとしては以下があります。

  • ESP32のガイドの通り、アンテナエリアの左右のベタを一定以上取り除く

設計に当たり、躓いたところは以下がありました。最終バージョンでは全て解決済みです。

  • USB電源保護ICのCH213Kを入れてみたのですが、電流過多でリセッタブルフィーズが働いてしまうのか期待通り動作せず、CH217Kに変更しました。
  • USB DM/DPのピンをマイコンに直結させていたのですが、安定しませんでした。ダンピング抵抗10Ωを付けたところ、安定しました。データシートにもその指摘がありました。
  • SK6812-MINI-Eに、データシート通りVDDに5Vで接続していたのですが、3.3Vの信号では制御できませんでした。VDDに3.3Vを繋いだところ制御できました。

インテリアになじませるようにケースを作る

このプロダクトは、「お家のそこら中に実際にデプロイする」ことを目的にしていました。そのため、家族に怒られないようにインテリアになじむケースに収めることにしました。

このケースの製作については、別途既に記事にしています。

74th.hateblo.jp

Streamlitから制御する

Streamlitはデータ可視化Webツール作成フレームワークです。本業はデータエンジニアであり、本業でとても活用しているものです。

streamlit.io

StreamlitはPythonで記述し、Pythonのコードで取得したデータをst.write(df)とか書くとそれを表示したり、st.button("OK")とか書くとPythonプログラムを実行するためのボタンが簡単に記述できます。以下は実際に私の家で動作するコードです。

# pages/sample.py
import requests

import streamlit as st

sht31 = requests.get("http://192.168.1.109/sht31").json()
st.text(f"""温度: {sht31["data"]["temperature"]:.1f} ℃""")
st.text(f"""湿度: {sht31["data"]["humidity"]:.1f} %""")

if st.button("TV ON"):
    requests.post("http://192.168.1.104/ir/send", json={"type": "SONY", "hex": "0xA90"})
    st.success("TV ON 信号を送信しました")

基本はこのようなコードを、使いやすいように作り込んでいきます。

エアコン操作画面

Pythonマイコンの外でできることにより、より複雑な命令を記述することができます。たとえば、 以下のようなユースケースを考えています。

  • 室温と一緒に、外気温や、天気をWebAPIから取得して表示する
  • 出かけるので、全てのエアコンをオフにする
  • TVの画面を、TV横PCに変更するため、「チャンネル1」「入力切り替え」「入力切り替え」を順に送る。現在何番目の入力が表示されているかわからないため、「チャンネル1」を介して、入力切り替えで確実に期待の画面を表示できるようにする。

これを構築していきました。

なお、Streamlitは家の外からもアクセスできるように公開サーバになっていますが、Streamlit自体には認証の仕組みはありません。そのため、Google認証がかかるOAuth2 Proxyを介するようにしました。ちなみにこのStreamlit自体はOCIコンテナ化してあり、OrangePi5+に構築したKubernetes(k3s)上で動かしています。このOAuth2 ProxyとKubernetesについては、これを構築したときにQiita記事にしています。

qiita.com

ESP32C3-IoT-Server-Boardがデプロイされた姿

実際に寝室のエアコンにデプロイされている様子を写真に撮りました。

インジケータLED用のケース窓の裏には紙がはってあるため、LEDが眩しすぎることはありません。

既に以下の箇所にデプロイしています。

  • リビングのエアコン
  • 寝室のエアコン
  • 客間のエアコン
  • リビングのTV前

超便利! 応答速度はGoogle Homeには勝てない…

リモコンを探す手間もなく、スマホから操作で対応した家電が操作でき、非常に便利になりました。

Streamlitによって、マイコンだけでは難しかった(面倒だった)制御もすることができました。

ただ、よくよく考えてみると、今まで家電の電源を消すだけであれば「OK Google、リビングのエアコン消して!」と指示していました。この便利さにはなかなか勝てませんね。

このESP32C3-IoT-ServerとケースはBoothにて販売中! 『つくまた』にて展示、販売予定

今回作成したESP32C3-IoT-Serverのキットと、対応ケースはBoothにて販売中です。

74th.booth.pm

また、2024-08-03に開催される『つくまた』でも、展示、販売します!以下のような使い方を想起させる展示も行います。ぜひ寄っていただければと思います。

w.atwiki.jp

次の展望

組み合わせたくなる使いたくなるGroveデバイスを増やしていきたいと思います!

できればGoogle Homeから動かせるようにMatterデバイス化したいですね。