bluetooth
node-gyp
Scratch
noble
microbit

micro:bit を Scratch 2 + Bluetooth で使う(ビルド編1:noble-uwp)

micro:bit を Scratch 2 + Bluetooth で使う(ビルド編1)

以下のような話題についてまとめます。

  1. ネイティブアドオンを使う Electron アプリケーションのビルドと配布可能なパッケージ化の方法
  2. 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.jsrequire('noble')require('noble-uwp') に差し替えるようです。
これは忘れそうです。このページを参考に、以下のように postinstall のスクリプトを設定しておきます。

package.json(該当部)
  "scripts": {
    "postinstall": "node noble-uwp-replace.js"
  },
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 のヘルパー(コンソール版))を例にまとめておきます。

  1. インストールに先立って、上で述べたような node-gyp のビルド環境(VC++ Build Tools 2015 と Python 2.7)を用意しておきます。
  2. 以下のように 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 のバインディングが使えるようになれば成功です。

使用方法

  1. s2microbit-ble-console のリポジトリにある hex ファイルを micro:bit に書き込んでおきます。
  2. 同じくリポジトリにある Scratch 2 のプロジェクト (.sb2) をダウンロードして開いておきます。(Scratch 2 を開き、シフトを押しながらファイルを押して「実験的なHTTP拡張を読み込み」から拡張ブロックの定義ファイル (.s2e) ファイルを開いても使えます。
  3. npm start とすると node で s2microbit.js を実行します。
  4. 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