組み込みUI開発実践:Air8101向け「日の出・日の入り時刻表示」アプリケーションの構築手順

組み込みUI開発の技術的障壁と解決アプローチ

組み込み機器向けのグラフィカルユーザーインターフェース開発において、初期段階で直面する主な課題は、環境構築の複雑性、ハードウェアの調達コスト、および低レベルハードウェア制御の難解さである。Air8101開発ボード、LuatOS、およびAirUIフレームワークを統合することで、これらのハードルを大幅に低減し、Webフロントエンドに近い開発体験を提供する。本ドキュメントでは、「日の出・日の入り時刻情報アプリ」を題材に、環境設定からAI駆動リソース生成、PCシミュレータ検証、および実装デバッグまでの技術的ワークフローを解説する。

開発環境の構成とリポジトリ構造

ハードウェアおよびソフトウェア要件

  • ホストマシン: Windows 10以降
  • ターゲットデバイス: Air8101開発ボード(Type-C接続)。ボード未所有時はPCシミュレータのみで検証可能。
  • ソースコード: LuatOS公式リポジトリのmasterブランチ。

リポジトリ内では、以下の3つのパスが本プロジェクトの核心となる。

  1. module/Air8101/project/AirUIFrame/engine_host: 標準ファームウェア。起動画面、待機UI、メニューシステム、ネットワーク設定などを提供するホスト層。
  2. module/Air8101/project/AirUIFrame/ui_play_board/app_store: サードパーティアプリ格納ディレクトリ。本記事で作成するモジュールはここに配置し、ホスト層のアプリマーケット経由でインストール可能となる。
  3. script/libs: LuatOS標準拡張ライブラリ群。

AIを活用したUIプロトタイピングとリソース生成

アプリケーションの初期仕様を定義し、AIコード生成ツールを用いてインタラクティブなHTMLプロトタイプを構築する。解像度480x800を指定し、表示ロジックとスタイリングを含む単一HTMLファイルを出力させる。生成されたファイルはブラウザで検証し、プロンプトの対話を通じてレイアウトの調整、不要要素の削除、配色の最適化を行う。

UIが確定した後、AIに対して以下の指示を出して静的アセットを抽出する。「生成したUI内の全画像要素を透過背景の30x30 PNG形式でエクスポートせよ」。出力された画像ファイル群は圧縮アーカイブとして保存し、ファイル名を半角英数に統一する(マルチバイト文字は組み込みファイルシステムで認識されないため)。

LuatOSアプリケーションのディレクトリ構造と規約

LuatOS/AirUI環境で実行可能なアプリは、厳格な階層構造とファイル命名規則に従う必要がある。

  • main.lua: エントリポイント。アプリ識別子、バージョン定義、UIモジュールのロード、システムイベントの発行を記述。
  • meta.json: メタデータ定義ファイル。アプリ名、バージョン、カテゴリ、説明、解像度、対応ファームウェア情報を含む。
  • user/: 業務ロジックおよびUI制御用Luaスクリプト。サブディレクトリ作成不可。
  • res/: 画像、フォント、音声などの静的リソース。コード内では/luadb/プレフィックスで参照。
  • libs/: ホストファームウェアに同梱されていない外部Lua拡張モジュール。

ファイルシステムマッピングルール

セキュリティとストレージ効率のため、パス解決は以下の通り自動変換される。

  • /luadb/icon.png → アプリ起動アイコン(特殊処理)
  • /luadb/xxx.luauser/ ディレクトリ内ファイル
  • /luadb/xxx (非lua) → res/ ディレクトリ内リソース
  • /luadb/xxx (lua優先順) → user/libs/ の順で解決

各アプリ内でLCDコントローラやタッチパネルの初期化を行う必要はない。ホスト層が起動時にこれらを初期化済みである。また、アプリは自身のfskv名前空間に対してのみ読み書き可能であり、他のアプリのデータ領域にはアクセスできない。

AIによるコード生成と実装例

開発環境としてAIエディタを準備し、LuatOSリポジトリのapp_storeディレクトリをプロジェクトルートとして開く。新規にSuntimeフォルダを作成し、userreslibsサブディレクトリを配置。取得したHTMLファイルと画像リソースを適切な位置に配置した後、以下のプロンプトを実行してフレームワーク準拠のコードを生成する。

「提供したHTMLのUI構造とインタラクションを参照し、AirUIフレームワーク準拠のLuaスクリプトをuser/以下に生成せよ。画像パスは/luadb/接頭辞を使用し、main.luameta.jsonおよび必要な設定ファイルを自動配置せよ。」

生成されたコードの骨格は以下の通り。

-- main.lua
APP_IDENTIFIER = "SUN_CYCLE_VIEWER"
APP_RELEASE = "1.0.0"
log.info("sys_boot", APP_IDENTIFIER, APP_RELEASE)

require "suntime_ui_bridge"
sys.publish("EVT_INVOKE_SUNTIME")
sys.run()
{
  "app_name_cn": "日の出・日の入り時刻",
  "app_name_en": "suntime-display",
  "version": "1.0.0",
  "publish_date": "2024-06-15 09:30:00",
  "category": "utility",
  "description": "現在位置の日出/日落時刻、昼間時間、およびカウントダウン情報を表示",
  "resolution": "480x800",
  "supported_models": {
    "Air8101": [{ "fw_id": 104, "min_ver": 2010 }]
  },
  "size_kb": 92
}

シミュレータ検証と反復デバッグフロー

生成したアプリディレクトリをPCシミュレータの実行パスに配置し、ターミナルから起動コマンドを投入する。

luatos-pc-64bit.exe ./base_firmware_path/ ./lib_script_path/

シミュレータ起動後、ホーム画面をスワイプしてアプリアイコンを起動する。初回実行時は、アセットパスの解決失敗やウィンドウ階層の不整合により、画像未表示やレイアウト崩れが発生しやすい。この段階では、出力されるコンソールログを抽出し、AIに対して具体的な修正指示を与える。

典型的なエラーパターンと解決策

  1. 画像レンダリング失敗: /luadb/プレフィックスの誤指定、またはres/ディレクトリへのファイル配置漏れ。ファイル名が半角英数であることを確認し、パスを再検証する。
  2. ウィンドウ制御の不整合: airui.create_window()に渡す親ハンドルや座標系が定義されていない場合、子要素が描画されない。生成されたUI制御スクリプト内のインスタンス化パラメータを修正し、z-indexとビューポート境界を調整する。
  3. CSSとAirUIの解釈差分: 生成元HTMLのFlexbox/Gridレイアウトが、組み込みUIエンジンと完全一致しない。AIに対し、AirUIのネイティブlayoutプロパティへの変換と、固定幅/高さの再計算を要求する。

修正精度を向上させるには、単なる現象報告ではなく、関連するログ出力、該当コードブロック、および期待されるレンダリング状態を明示的に指示する。AIが提示した差分を適用し、シミュレータプロセスを再起動して検証するサイクルを繰り返す。不要なテキスト要素の削除、コンポーネントの枠線追加、特定セクションの非表示化などの微調整も、同様のプロンプト駆動アプローチで迅速に反映できる。

上記の検証フローを経て、リソースパスの解決、ウィンドウ階層の最適化、およびUIコンポーネントのレンダリング調整が完了すれば、実機へのファームウェア書き込みおよびAir8101ボードでの動作確認フェーズへ移行可能となる。

タグ: LuatOS air8101 airui embedded-ui lua-embedded

9月11日 07:29 投稿