Nature ソフトウェアエンジニアの桒山です。この記事は、第2回 Nature Engineering Blog 祭の13日目の記事になります!
Matter のコミッショニングで用いる QR コード生成を Wasm で実装して、Web ブラウザから QR コードを生成できるようにした話です。実装は以下です。
私、個人的な目的としては
- QR コードを颯爽と出力して、Commissionee 検証などの際に遊びたい
- Matter Spec について復習したい
- Rust を書きたい
です。Matter 開発を楽しんでいきましょう!
QR コードによる Matter のコミッショニング
Matter のコミッショニングについては、Nature Matter Kaigi の田井の発表資料が分かりやすいと思います。参照ください。
Matter のコミッショニングでは、MPC(Manual Pairing Code) を使う方法と QR コードを使う方法があります。matter_qrcode_generator では、この QR コードを出力します。QR コードの仕様については Matter 1.0 Core Specification 5.1.3. QR Code 1 を参照してください。
Wasm 2 って?
WebAssembly は現代のウェブブラウザーで実行できる新しい種類のコードです。ネイティブに近いパフォーマンスで動作する、コンパクトなバイナリー形式の低レベルなアセンブリー風言語です。さらに、 C/C++、C# や Rust などの言語のコンパイル先となり、それらの言語をウェブ上で実行することができます。 WebAssembly は JavaScript と並行して動作するように設計されているため、両方を連携させることができます。
- https://developer.mozilla.org/ja/docs/WebAssembly
- ウェブブラウザーなどの Wasm ランタイム上で実行可能なコード
- バイトコード
- ブラウザ以外にもランタイム有り
- Envoy、Fastly Terrarium(Lucet) や Wasmer など
- JavaScript から Wasm の関数を呼び出したり、Wasm から JavaScript の関数を呼び出し可能
- 例えば、Wasm にコンパイルすれば Rust で書いた関数を JavaScript から呼び出し可能
- ウェブブラウザーなどの Wasm ランタイム上で実行可能なコード
Wasm を JavaScript から読めるように実装
レポジトリ構成は、おおよそ下記です。
├── matter_qrcode_generator │ ├── Cargo.toml │ └── src │ ├── base38.rs │ ├── cli.rs │ ├── lib.rs │ ├── main.rs │ ├── onboarding_payload.rs │ └── qr.rs └── matter_qrcode_generator_wasm ├── Cargo.toml ├── src │ └── lib.rs └── www ├── css │ └── style.css ├── index.html └── js └── app.js
二つのディレクトリについて、それぞれ何をやっているか説明します。
- matter_qrcode_generator/
- matter_qrcode_generator_wasm/
- ../matter_qrcode_generator/ を用いて Wasm のコードを書き出すように実装
- lib.rs にて wasm_bindgen クレートを利用
- Wasm コードを JavaScript から参照して、フロントエンドにて QR コードを生成・表示
- ../matter_qrcode_generator/ を用いて Wasm のコードを書き出すように実装
つまり、依存関係は下記の通りです。
matter_qrcode_generator_wasm/src/lib.rs で用いられるクレートを紹介しておきます。
- wasm_bindgen
- JavaScript から Rust の関数を呼び出したり、Rust から JavaScript の関数を呼び出し可能にするための Wasm を書き出すようにコンパイルするためのクレート
#[wasm_bindgen]
- JavaScript から Rust の関数を呼び出したり、Rust から JavaScript の関数を呼び出し可能にするための Wasm を書き出すようにコンパイルするためのクレート
- js_sys
- JavaScript から呼び出せる Rust の関数を実装する際に、返り値を JavaScript の型として実装できるようにするクレート
JSValue
- JavaScript から呼び出せる Rust の関数を実装する際に、返り値を JavaScript の型として実装できるようにするクレート
#[wasm_bindgen] pub fn do_print_qr( vid: u16, pid: u16, passcode: u32, discriminator: u16, soft_ap: bool, ble: bool, on_ip_nw: bool, pixel: u32, ) -> Result<String, JsValue> { // QR コードを SVG として生成、HTML タグで書き出して文字列として返す
Github Actions にて .wasm と .js と index.html ファイルを公開用ブランチ上に配置
npm build <scripts>
からコマンドを実行できるようにしました。matter_qrcode_generator/public/ 以下に .wasm と .js と index.html が書き出されます。内部で利用しているツールは下記です。
- wasm-pack
- Rust から出力された .wasm を npm パッケージとして構築するためのツール
- webpack
$ npm install # 依存する .js 取得 $ npm run build # 以前のビルド結果掃除、wasm-pack、webpack 実行してビルド $ npm run start # http-server を立てて localhost:8080 をオープン
// 省略 "scripts": { "lint": "eslint www/index.html www/js", "build:pre": "rm -rf public", "build:wasm": "wasm-pack build --target web --no-typescript --features wee_alloc", "build:webpack": "webpack", "build": "run-s build:pre build:wasm build:webpack", "start": "cd public && http-server -o" } // 省略
Github Actions にて、main
ブランチに push があれば自動デプロイされるようにしています。
- github-pages-action
- Github Pages するための Github Actions
- ビルドした .wasm と .js と index.html だけを公開したい。その他の Rust のコードとかは公開する必要はない。matter_qrcode_generator/public/ 以下だけ公開するように設定するために利用
- デフォルトで
gh-pages
を上書きする形でデプロイ
- https://github.com/marketplace/actions/github-pages-action
- Github Pages するための Github Actions
- run: npm install working-directory: ./matter_qrcode_generator_wasm - run: npm run build working-directory: ./matter_qrcode_generator_wasm - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./matter_qrcode_generator_wasm/public
公開用ブランチを設定して Github Pages で公開
上記を用いて、Github Actions にて public に書き出された .wasm と .js と index.html を gh-pages
ブランチのルートから上書きして配置します。
GitHub のリポジトリから HTML、CSS、および JavaScript ファイル を直接取得し、任意でビルドプロセスを通じてファイルを実行し、ウェブサイトを公開できる静的なサイトホスティングサービスです。
- https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages
gh-pages
を Github Pages として公開設定しておけば https://thekuwayama.github.io/matter_qrcode_generator/ に公開- http(s)://<username>.github.io/<repository>
実際にコミッショニングしてみる
Commissionee は matter-rs の onoff_light を用います。手元に Rust 環境のある PC をご用意ください。手元の PC にて
$ git clone git@github.com:project-chip/matter-rs.git $ cd matter-rs $ cargo run --example onoff_light
matter-rs を書き換えずにそのまま実行しますと
- https://github.com/project-chip/matter-rs/blob/2fe66318ca4b80eb129d32f3f27918345fe967fc/examples/onoff_light/src/main.rs#L26-L41
- Vendor ID
- 65521
- Product ID
- 32768
- Passcode
- 123456
- Discriminator
- 250
- Vendor ID
で起動されます。上記を web にて入力して、 print
ボタンを押してください。QR コードが生成されます。
PC と同じ無線 LAN にて、Commissioner からコミッショニングしてみてください。コミッショニングが成功すると思います。下記は iPad から Home アプリを起動した場合のスクリーンショットです。
コミッショニング成功です。 🎉🎉
まとめ
Matter QR コード生成を実装し、そして Wasm にして Github Pages にて公開しました。もし Matter 開発において、QR コードが必要になった際に助けになれば幸いです。
Nature エンジニアコミュニティ
エンジニアコミュニティはじめました。Matter を使った Nature Remo nano の活用方法から Nature Remo could API の疑問など、Nature のエンジニアがお答えします! Discord への参加はこちらから。
Nature Remo nano 好評発売中!
Matter 対応の Nature Remo nano が定価3,980円で発売中!
- Matter Specification 1.0 5.1.3. QR Code pp.217-221↩
- https://webassembly.github.io/spec/core/intro/introduction.html#wasm↩