この記事はAkerun Advent Calendar 20日目の記事です。
今回はファームウェアエンジニア いとう が担当です。今回はWeb Bluetoothでウェブエンジニアデビューします。目指せフルスタック!
目的
今月行われたエンジニア日帰り合宿での出来事です
誰か 「Akerunの初期設定、スマホ持ってなかったりPCに専用アプリインストールできないお客様もいる。どうしようか?」
私 「Web Bluetoothでブラウザだけで設定できればよくね?(ウェブエンジニア賢い人多そうだからサクッと作ってくれそう)」
誰か「ほな、お前やってな」
私 「・・・」
Web Bluetooth
無茶振りされましたがWeb Bluetoothなんてqiitaで何度か記事を目にしただけで海のものとも山のものともついてない私です。仕様書はここみたいです。
設定
色々な Web Bluetooth記事をみていると必ず https接続が必要!と書いてあります。まずは環境を用意することにしました。
serveo
私はサーバーとか何にもわかりませんのでSlackに流れていたローカルファイルをhttpsで公開できるserveoを使ってみます。
死んどる・・・(2019年12月20日現在serveoはダウンしていうようです)
ngrok
改めて弊社の優秀なウェブエンジニアーズに聞いたところ ngrok
が良さげだったのでここを参考にインストールします。ngrokはスムーズにインストール&登録できました。
nginx
ngrokさえインストールできればローカル環境でウェブサーバーを立てれば準備完了です。macOSのシステム環境設定の共有からWeb共有を有効にしま・・・・え!?ない!。随分前からWeb共有はなくなっているようです。歳はとりたくないですね。
ということでqiitaの記事にもあるようにnginxをインストールしてみましょう。
brew install nginx nginx
上記だけで可能とのことでしたが3つほどつまずきました。
- インストール時に権限関連で怒られる
- brewのエラーに解決方法でてますのでその通りに実施してOK
- 実行時に
nginx: [emerg] mkdir() "/usr/local/var/run/nginx/client_body_temp" failed (2: No such file or directory)
と怒られる- ここをみて解決
- 実行時に
nginx: [warn] 1024 worker_connections exceed open file resource limit: 256
と怒られる- ここをみて解決
それではngrok
を起動してみましょう
./ngrok http 8080
ngrok by @inconshreveable (Ctrl+C to quit) Session Status online Account waiwai@supaahakaa.co.jp (Plan: Free) Version 2.3.35 Region United States (us) Web Interface http://127.0.0.1:4040 Forwarding http://xxxxxxxx.ngrok.io -> http://localhost:8080 Forwarding https://xxxxxxxx.ngrok.io -> http://localhost:8080 Connections ttl opn rt1 rt5 p50 p90 0 0 0.00 0.00 0.00 0.00
このhttps://xxxxxxxx.ngrok.io
にアクセスすると・・・
あれ?だめです。結論から言うと下記のコマンドでないと動きませんでした。何故かはイマイチわかってません。
./ngrok http -host-header=rewirte 127.0.0.1:8080
これでようやくhttps接続でローカルファイルを公開できるようになりました!
結局
ここまでhttps接続環境を揃えてスクリプトをしこしこ書いていたのですが、検証のためhttps接続でなければどのようなエラーとなるのかを確認したくFinderからChromeにindex.htmlをDnDすると・・・動くやん!誰やhttpsいるっていうたん!というわけで2019年12月20日現在はhttps接続は必須ではないようです。(後述:Windows環境では必須でした)
処女作
これで私もフロントエンドエンジニアデビュー。長編大作のhtmlファイルです。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Akerun web door sensor</title> <script src="akerun.js"></script> </head> <body> <button id="close">Close</button> </body> </html>
JavaScriptです。今回はAkerun付属ドアセンサーの通信を模してみました。(セキュリティ処理を外した特別なファームウェアをAkerun側に書き込んでいます。皆様がご利用のAkerunは下記の処理では動作したりしません。念の為)
var Akerun = function() {}; Akerun.prototype = { // AKerun AKERUN_SERVICE_UUID: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", UUID_AKERUN_RX: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", close: function() { navigator.bluetooth .requestDevice({ filters: [{ namePrefix: "akerun_******xx" }], optionalServices: [this.AKERUN_SERVICE_UUID] }) .then(device => { console.log("device", device); return device.gatt.connect(); }) .then(server => { console.log("server", server); return server.getPrimaryService(this.AKERUN_SERVICE_UUID); }) .then(service => { console.log("service", service); return service.getCharacteristic(this.UUID_AKERUN_RX); }) .then(chara => { var buffer = new Uint8Array(xxx); buffer[0] = CMD_0; buffer[1] = CMD_1; buffer[2] = CMD_2; buffer[3] = CMD_3; // 中略 buffer[xxx-1] = CMD_XXX; chara.writeValue(buffer); console.log("Akerun:", chara); }) .catch(error => { console.log(error); }); } }; window.onload = function() { var akerun = new Akerun(); document .getElementById("close") .addEventListener("click", akerun.close.bind(akerun), false); };
結果
- BLE通信はすんなりできたのでAkerunの初期設定ぐらいであれば十分可能
- ただしJavaScriptコードが丸見えなのでセキュアな仕組みを別途構築する必要がある
- 初期設定限定で以降は口を閉じるような仕組み?
実運用では環境の縛りキツい
- Chrome縛り
- PCに詳しくないユーザーはPCにBLE搭載しているかどうか判断できなさそうでサポートが難しい
JavaScript完全に理解した
2019年12月20日追記
- Windowsから実行するときには
chrome://flags/#enable-experimental-web-platform-features
のフラグを有効にしてもらわないといけない- このフラグへのURLはリンククリックでもセキュリティのため遷移しないのでまず一般ユーザーに使ってもらうのは厳しいでしょう
- 将来に期待
参考にしたサイト
- Qiita: ngrokが便利すぎる
- Qiita: 新しいmacにbrewを使ってnginxをインストールする
- Qiita: micro:bitとWebBluetoothで通信してみました
- 今回のコードはほぼここを参考にしてかかせてもらいました!
2019年12月20日追記、編集
・・・
株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co
Akerun Proの購入はこちらから akerun.com