micro:bit を Scratch 2 + Bluetooth で使う(ビルド編1)
以下のような話題についてまとめます。
- ネイティブアドオンを使う Electron アプリケーションのビルドと配布可能なパッケージ化の方法
- Scratch2(オフライン版)から Bluetooth Low Energy 経由で BBC micro:bit を使うためのヘルパーアプリケーション作成方法
前半は node-gyp の環境準備とネイティブアドオンのビルドの話、後半は electron-builder を用いたビルドと配布用パッケージの作り方です。長いので2つに分け、ここでは前半をビルド編1としてまとめておきます。後半のビルド編2はこちら。
動機
Scratch 2 のヘルパーアプリケーションを https://github.com/memakura/s2microbit-ble で公開していますが、このコンソール版のビルド方法が前半(ビルド編1)、Electron版のビルド・パッケージ化の方法が後半(ビルド編2)に対応します。Scratch 2 で子供にビジュアルプログラミングをしてもらうときに、Node や Python などの環境を準備してもらうのは大変なので、ビルド編2のまとめにあるような実行形式で配布したいのです。Github 上の s2microbit-ble(-console) を clone して使うだけなら、前半、後半いずれも「まとめ: ... 」と書かれたセクションを確認してください。
あと、なぜ Node + Electron でパッケージ化することにしたかは、micro:bit を Scratch 2 + Bluetooth で使う(調査編) にまとめています。また、s2microbit-ble の中身の話はまとめ編でまとめる予定です。
noble-uwp モジュールのインストール
noble-uwp と bbc-microbit
Node で Bluetooth を扱うには noble というモジュールがよく使われます。Windows 10 でも、以前は特定のBluetooth USBドングルやドライバを用意する必要がありましたが、2017年春ごろのバージョン1703・ビルド15063(いわゆるCreators Update)からは、多くのUSBもしくはPC内臓のBluetoothアダプタでも動くようになりました。ただし、これには noble を入れた後にその一部を noble-uwp (Windows 10 UWP binding) にアップデートする必要があります。なお、UWP は異種デバイスの動作プラットフォームを共通化するために Windows 10 から導入されたもので、 Universal Windows Platform の略です。
Bluetooth + JavaScript というと、Web Bluetooth API とどっちにするかという話もありますが、Windows で動作実績があるので noble API にしています(Web Bluetooth API も wrapping されると期待)。
以下ではこの noble-uwp のインストールと注意点をまとめます。具体的には、noble から Bluetooth Low Energy 経由で BBC micro:bit を使うための bbc-microbit というモジュールのインストールを行い、これに依存してインストールされた noble を差し替えることで noble-uwp を使えるようにします。
node-gyp には実行環境が必要
ここでは以下のバージョンを使います。
> node -v
v8.10.0
> npm -v
5.6.0
まずは bbc-microbit をインストールします。
> npm init(適当に答えて package.json を作成する)
> npm install --save bbc-microbit
こうすると node-pre-gyp install --fallback-to-build
が実行され、必要なバインディング(ネイティブモジュール)をビルドしようとします。node-gyp や node-pre-gyp は Node でネイティブアドオンモジュールをビルドするための、クロスプラットフォームのコマンドラインツールで、GYP (Generate Your Project) とは、Google Chrome の元になった Chromium の開発チームで使われていた(メタ)ビルドシステムらしいです。
しかし、いくつかのモジュール(usb モジュールなど)はビルドされず、以下のようにリモートからダウンロードされます。
[usb] Success: "<現在のフォルダ>\node_modules\usb\src\binding\usb_bindings.node" is installed via remote
リモートにビルド済みバインディングがすでにあり、Node用についてはローカルではビルドしなくてよい ということです。(ビルド編2で述べるように、Electron用にはビルドは必要になります。)
一方、bluetooth-hci-socket は node-gyp rebuid
で怒られます。リモートからダウンロードできないときは、ローカルでビルドが必要ですが、node-gyp でのビルドに必要な Python 2.7 もしくは VC++ 2015 の環境がないためです。詳しくは node-gyp のページ の Installations > On Windows あたりを見ながら設定しておきます。(後々 Electron を使うときには、noble-uwp もビルドが必要です。)
node-gyp の実行環境の準備
node-gyp のページ の Option 1: windows-build-tools を、管理者権限のコンソール(Cmd)から入れてしまうのが楽です。VC++ Build Tools 2015 と Python が自動でダウンロード、インストールされます。
- Python は
c:\Users\.windows-build-tools
の下に入ります。 - Pythonへのパスはデフォルトでは npm の globalconfig に追加されるだけのようです。自分は Python (Anaconda) や Visual Studio 2017 は入っていましたが、これならコンフリクトはしなさそう。
- 通常はこの作業は不要かもしれないですが、自分は Python 環境をいくつも入れたくないため、windows-build-tools で入った Python は
c:\Users\.windows-build-tools\python-2.7.14.amd64.msi
を実行してアンインストールし、npm config -g delete python
で npm のパスからも消してしまいました。
以下では、Python 2.7 は Anaconda の仮想環境で py27という名前で設定してあるとします。つまり、
> conda info -e
# conda environments:
#
py27 * C:\Program Files\Anaconda3\envs\py27
root C:\Program Files\Anaconda3
のような環境です。
> activate py27
(py27)> npm install --save bbc-microbit
これで bluetooth-hci-socket のビルドが成功します。(windows-build-tools で入れた Python をそのまま使うなら activate 不要です。)
noble-uwp のビルド
まずはインストールしてみます。
(py27)> npm install --save noble-uwp
すると、
Installing NodeRT UWP adapter for Windows.Foundation
[windows.foundation] Success: "<現在のパス>\node_modules\noble-uwp\uwp\windows.foundation\binding\node-v57-win32-x64\binding.node" is installed via remote
のようなメッセージがいくつも出てきます。usb と同様、node-uwp のバインディングもリモートからダウンロードされるため、ローカルでビルドしなくてよいようです。ビルド編2で説明する Electron のときには変わってきます。
noble の代わりに noble-uwp を使うように設定
noble-uwpのリポジトリのREADMEにあるように、noble-uwp を使うには、モジュールインストール後に、node_modules/noble-device/lib/util.js
の require('noble')
を require('noble-uwp')
に差し替えるようです。
これは忘れそうです。このページを参考に、以下のように postinstall のスクリプトを設定しておきます。
"scripts": {
"postinstall": "node noble-uwp-replace.js"
},
const os = require('os');
if (os.platform() === 'win32') {
// https://github.com/jasongin/noble-uwp
console.log("### noble is replaced by noble-uwp");
var fs = require('fs');
var f = 'node_modules/noble-device/lib/util.js';
fs.writeFileSync(f, fs.readFileSync(f).toString().replace('require(\'noble\')', 'require(\'noble-uwp\')'));
}
これで npm install
とした際にスクリプトが走るようになります。
まとめ: s2microbit-ble-console の使用方法
要件
Windows 10 バージョン1703・ビルド15063 以降
インストール方法
noble-uwp + bbc-microbit を使ったアプリケーションのインストール方法を、こちらで公開している s2microbit-ble-console (BLE 経由で BBC microbit を使う Scratch 2 のヘルパー(コンソール版))を例にまとめておきます。
- インストールに先立って、上で述べたような node-gyp のビルド環境(VC++ Build Tools 2015 と Python 2.7)を用意しておきます。
- 以下のように
npm install
します。
> git clone https://github.com/memakura/s2microbit-ble-console.git
> cd s2microbit-ble-console
> activate py27 (npm config のpython にパスがあればこれは不要)
(py27)> npm install
py27
はAnacondaの環境名ですが、あくまで例です。windows-build-tools でインストールした場合など、すでに Python 2.7 にパスが通っていれば activate
の部分は不要です。
### noble is replaced by noble-uwp
というメッセージが最後の方に出て、noble-uwp のバインディングが使えるようになれば成功です。
使用方法
- s2microbit-ble-console のリポジトリにある hex ファイルを micro:bit に書き込んでおきます。
- 同じくリポジトリにある Scratch 2 のプロジェクト (.sb2) をダウンロードして開いておきます。(Scratch 2 を開き、シフトを押しながらファイルを押して「実験的なHTTP拡張を読み込み」から拡張ブロックの定義ファイル (.s2e) ファイルを開いても使えます。
-
npm start
とすると node で s2microbit.js を実行します。 - micro:bit 側はLEDマトリクスが「ハート」を経て「チェックマーク」に変わり、Scratch 2 側は「その他」のs2microbit-ble の横にある赤丸が緑色になれば接続完了で使用できます。
補足
bbc-microbit のパッチ
bbc-microbit のモジュールはそのままだと scanning に失敗するとすぐにエラーで終了してしまうため、見つかるまで scanning し続けるように、postinstall で node_modules\bbc-microbit\lib\bbc-microbit.js を一部書き換えています。
Scratch 2 ヘルパーの作成方法
Scratch 2 オフライン版のヘルパーアプリケーションは、Scratch 2 側のGETリクエストに答えるようなHTTPサーバです(詳細はこちらの記事)。s2microbit-ble では、LED の点灯やセンサー情報の取得(GETポーリング)を Express サーバで受け、noble を使って micro:bit 側と通信します。詳しくはまとめ編で説明します。
Electron版へ
以上から分かるように、この s2microbit-ble のコンソール版を使うには環境構築が大変です・・
次回は Electron版のビルド方法を述べて、実行形式をインストーラで配布できるようにします。
つづく:ビルド編2