Arduino App Labのアプリ例(Web UI から MCU を操作)と「expose_api」機能

下記の記事では、Arduino UNO Qで、センサ値を Web UI に表示する例について調査を行ったが、本記事では、Web UI から MCU を操作する例を紹介する。ただし、その例では、「expose_api」機能という機能が使用されていたが、少し分かりにくい機能だったので、先にその機能についての調査結果を紹介する。

(注)本記事の内容は正確性を保証するものではない。

(2026年1月7日 追記)YouTube動画を追加しました。 https://youtu.be/A2ZlGtjNR8g

目次

expose_api機能について

Arduino UNO Q × Arduino App Lab における「expose_api」機能について教えてください

Gemini 3 Proの回答

Arduino UNO Q(Qualcomm QRB2210 MPU + STM32 MCU搭載のボード)と開発環境 Arduino App Lab における expose_api について解説します。

結論から言うと、expose_apiLinux側(MPU)で動作するPythonコードにおいて、特定の関数を「Web API(URL)」として外部に公開するための機能 です。

これにより、Webブラウザ上のUI(ダッシュボード)からデータを要求したり、外部のアプリからUNO Qを操作したりすることが可能になります。

1. expose_api の役割と位置づけ

Arduino UNO Qは「マイコン(MCU)」と「Linuxコンピュータ(MPU)」の2つの頭脳を持っています。
expose_api Linux(Python)側 の機能です。

  • 通常のデータの流れ(プッシュ型):
    • マイコンがセンサ値を読む → Pythonに送る → ui.send_message() でWeb画面に一方的に送りつける
      (リアルタイム表示向き)
  • expose_api の流れ(プル型):
    • Web画面(または外部アプリ)が「過去のデータが欲しい」とリクエストする
      expose_apiで設定したURLが反応するPythonがデータを返答する(グラフ描画や履歴取得向き)

2. 基本的な構文(Python側)

Arduino App Labの web_ui ブリック(ライブラリ)を使用する際に、以下のように記述します。

Python

# Linux側の Python コード (main.py)
from arduino.app_bricks.web_ui import WebUI

ui = WebUI()

# 1. APIとして公開したい関数を定義
def get_sensor_history(sensor_type, duration):
    # データベースからデータを取得する処理などをここに書く
    data = db.query(sensor_type, duration) 
    return {"result": data}

# 2. その関数をURLパスに紐付ける (これが expose_api)
# 書式: ui.expose_api("HTTPメソッド", "パス", 実行する関数)
ui.expose_api("GET", "/history/{sensor_type}/{duration}", get_sensor_history)

この例では、ブラウザから http://(UNO QのIP)/api/history/temp/1hour のようなアクセスがあると、自動的に get_sensor_history("temp", "1hour") が実行され、その結果がJSONとしてブラウザに返されます。

3. 具体的な使い分け

機能メソッド通信方向用途の例
expose_apiui.expose_api()Pull (要求→応答)・過去1時間の温度グラフを描画する

・設定値を読み込む

「今すぐ撮影」のようなコマンドを送る
send_messageui.send_message()Push (送信のみ)・現在の温度をリアルタイムで数字表示する

・異常検知アラートを即座にポップアップする

4. 全体の仕組み図解

Arduino App Labでの処理の流れは以下のようになります。

  1. MCU (Sketch): センサを読む sensor.read()
  2. Bridge: データをLinuxへ渡す Bridge.notify()
  3. MPU (Python): データを受け取りデータベースに保存 db.save()
  4. Web UI (Frontend): グラフ描画のためにデータを要求 fetch('/api/history/...')
  5. MPU (Python): expose_api で定義された関数が反応し、保存されたデータを返す

まとめ

expose_api は、Arduino UNO Q を単なるセンサ端末ではなく、「Webサーバー」として機能させるための重要なコマンドです。これを使うことで、ユーザーがボタンを押したタイミングで処理を実行したり、蓄積したログデータを画面に呼び出したりする高度なWebアプリ(ダッシュボード)が作れるようになります。

espose_apiがWebサーバーの代わりとなり、Webサーバーは無くてもよいのかなどの不明な点について追加質問した。

espose_apiとWebサーバーとの違い

espose_apiとWebサーバーとの違いを教えてください

Gemini 3 Proの回答

expose_apiWebサーバー は、対立するものではなく、「Webサーバーという『お店』」と「expose_apiという『メニュー』」のような親子関係にあります。

一言で言うと、「Webサーバー」は土台となる仕組み であり、「expose_api」はその仕組みを使って何をするかを決める命令 です。

1. イメージで理解する(レストランの例)

用語レストランでの役割Webシステムでの役割説明
Webサーバー
(ui = WebUI())
店舗とホールスタッフ土台・インフラお客さん(スマホやPC)からの注文を受け付けたり、商品を運んだりする「仕組み」そのものです。

これがないとお店が開けません。
expose_api
(ui.expose_api(...))
メニュー表と調理指示機能・サービス「『ハンバーグ』と注文されたら『肉を焼いて出す』」という具体的な指示です。

これがないと、スタッフ(サーバー)は何を出していいか分かりません。

2. 技術的な違い

Arduino App Lab における具体的な役割分担は以下の通りです。

Webサーバー (The Container)

  • コード: ui = WebUI() を実行した時点で、裏側で自動的に立ち上がります。
  • 仕事:
    • ネットワークのポート(通常は80番や8080番)を開いて待機する。
    • スマホやPCから「接続したい」という信号が来たら繋ぐ。
    • HTMLファイル(画面のデザイン)や画像ファイルを送り届ける。
  • ユーザーの作業: 基本的に「起動するだけ」で、中身の複雑な通信プログラムを書く必要はありません。

expose_api (The Content)

  • コード: ui.expose_api("GET", "/data", my_function)
  • 仕事:
    • Webサーバーに対して、「もし /data というURLにアクセスが来たら、my_function を実行して、その結果を返してね」と登録する。
    • 計算したり、センサの履歴データをDBから取り出したりする「中身の処理」を担当する。
  • ユーザーの作業: 自分のやりたいこと(グラフを出したい、LEDを消したい等)に合わせて具体的に記述します。

3. なぜ expose_api が必要なのか?

Webサーバーを立ち上げただけ(WebUI()のみ)では、Arduino UNO Qは単に「固定されたHTMLファイルを表示するだけ」の掲示板のような状態です。

expose_api を使うことで、以下のように動的なやり取りが可能になります。

  1. Webサーバー: 「お客様から注文が来ました!」(リクエスト受信)
  2. expose_api: 「それは『温度履歴』の注文だね。
    じゃあ、データベースから過去1時間の温度をまとめて渡すよ」(処理実行)
  3. Webサーバー: 「承知しました。お客様にお届けします」(レスポンス送信)

まとめ

  • Webサーバー は、Arduino UNO Q を外部と繋ぐための「受付窓口」です。
  • expose_api は、その窓口に来た依頼に対してどう答えるかを定義する「対応マニュアル」です。

Arduino App Labでは、面倒な「Webサーバー作り(受付の設営)」は自動化されており、あなたは「expose_api(マニュアル作り)」に専念すればよい、という設計になっています。

今回説明した「Webサーバー」機能も、実はWebUI Brickという部品の一つとして提供されており、それを自分のアプリに「カチッ」とはめ込むだけでサーバー機能が使えるようになるイメージが掴めるはずです。

expose_api 機能は、Webサーバーに代わるものかと思っていたが、WebサーバーはWebUI Brickに含まれていた。

expose_apiを使った例(Web UI から MCU を操作する)

Web UI から MCU を操作する例を紹介してください

ChatGPT 5.2 Instantの回答

以下は、Arduino UNO Q × Arduino App Lab
「Web UI から MCU を操作する“完全に動く最小~実用例”」です。

👉 ブラウザのボタン操作 → Python → MCU → 実機(LED/GPIO)
という一連の流れを、省略なしで説明します。

全体構成(最重要)

  • ボード:Arduino UNO Q
  • 開発環境:Arduino App Lab
[ Web Browser ]
      ↓  (HTTP / WebSocket)
[ Web UI (HTML+JS) ]
      ↓
[ Python (Linux) ]
      ↓  Bridge.call()
[ MCU (Arduino) ]
      ↓
[ LED / GPIO / リレー ]

デモ内容

  • ブラウザに
    ON / OFF ボタンスライダー
  • ボタン → LED ON/OFF
  • スライダー → MCU の制御値(例:PWM・しきい値)

1️⃣ app.yaml(Web UI Brick を追加)

App Lab の GUI で
WebUI – HTML Brick を追加すれば OK です。

概念的には以下が入っています:

bricks:
  - arduino:web_ui

2️⃣ MCU 側(Arduinoスケッチ)

役割

  • Python からの命令を受ける
  • GPIO を直接制御(リアルタイム)
#include <Arduino_RouterBridge.h>

const int LED_PIN = 13;
int level = 0;

void set_led(bool on) {
  digitalWrite(LED_PIN, on ? HIGH : LOW);
}

void set_level(int v) {
  level = constrain(v, 0, 255);
  analogWrite(LED_PIN, level);   // PWM制御例
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Bridge.begin();

  // Python から呼ばれる関数を登録
  Bridge.provide("set_led", set_led);
  Bridge.provide("set_level", set_level);
}

void loop() {
  // ループは空でもOK
}

3️⃣ Python 側(Web UI ↔ MCU の中継)

役割

  • Web UI の操作を受信
  • MCU 関数を呼び出す
from arduino.app_utils import App, Bridge
from arduino.app_bricks.web_ui import WebUI

ui = WebUI()

# --- Web UI → MCU ---
@ui.expose_api("POST", "/led")
def api_led(data):
    Bridge.call("set_led", bool(data["on"]))
    return {"status": "ok"}

@ui.expose_api("POST", "/level")
def api_level(data):
    Bridge.call("set_level", int(data["value"]))
    return {"status": "ok"}

App.run()

📌 ここが要点

  • expose_api()Web UI から HTTP で叩ける
  • Bridge.call()MCU の関数を直接呼ぶ

4️⃣ Web UI(assets/index.html)

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>UNO Q Control</title>
</head>
<body>
  <h1>MCU Control</h1>

  <button onclick="led(true)">LED ON</button>
  <button onclick="led(false)">LED OFF</button>

  <p>
    Level:
    <input type="range" min="0" max="255" value="0"
           oninput="setLevel(this.value)">
  </p>

  <script src="app.js"></script>
</body>
</html>

5️⃣ Web UI(assets/app.js

function led(on) {
  fetch("/led", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ on })
  });
}

function setLevel(value) {
  fetch("/level", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ value })
  });
}

6️⃣ 実行手順(最短)

  1. App Lab でプロジェクト作成
  2. WebUI Brick を追加
  3. sketch / python / assets を配置
  4. Deploy
  5. ブラウザで開く
http://<UNO Q の IP アドレス>:7000/

➡ ボタン操作で 実機 LED が即反応すれば成功 🎉

7️⃣ よくある応用パターン

✅ リレー・モータ制御

  • ボタン → Bridge.call("relay_on")

✅ パラメータ調整

  • スライダー → PID ゲイン / しきい値

✅ セーフ設計

  • Python 側で
    • 範囲チェック
    • 状態管理
  • MCU は単純化

8️⃣ 設計の鉄則(UNO Q らしい使い方)

役割担当
UI / ネットワークPython + Web UI
判断・制御ロジックPython
GPIO / 時間厳守処理MCU

👉 MCU は「手足」、Python は「頭」

まとめ

  • Web UI → MCU 操作は
    expose_api → Bridge.call が王道
  • Arduino UNO Q では
    Web操作・AI・制御を1台で完結できる
  • この例をベースにすれば
    設定画面付き機器・IoT制御盤がそのまま作れます
目次