mac+Node.jsでBLEを使いたい
IoT関連だとBLEを使いたいよねって話題が定期的に出てきますが、Node.jsでBLEを制御するnobleというライブラリがmacだと使えなくなっていた問題が数年前くらいにありました。
そこに対して、以前書いた記事で@abandonware/noble
を使うと使えるようになったという話までが2021年春頃の話題です。
macOS Montereyで問題再発
当時はBigSurだったのですがMontereyに上げてから試したらインストールでこける事象に。
$ npm i @abandonware/noble
npm ERR! code 1
npm ERR! path /Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble
npm ERR! command failed
npm ERR! command sh -c node-gyp rebuild
npm ERR! CC(target) Release/obj.target/nothing/node_modules/node-addon-api/nothing.o
npm ERR! LIBTOOL-STATIC Release/nothing.a
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@7.1.2
npm ERR! gyp info using node@15.14.0 | darwin | x64
npm ERR! gyp info find Python using Python version 3.9.10 found at "/usr/local/opt/python@3.9/bin/python3.9"
npm ERR! gyp info spawn /usr/local/opt/python@3.9/bin/python3.9
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args '/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py',
npm ERR! gyp info spawn args 'binding.gyp',
npm ERR! gyp info spawn args '-f',
npm ERR! gyp info spawn args 'make',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble/build/config.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/addon.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/Users/n0bisuke/Library/Caches/node-gyp/15.14.0/include/node/common.gypi',
npm ERR! gyp info spawn args '-Dlibrary=shared_library',
npm ERR! gyp info spawn args '-Dvisibility=default',
npm ERR! gyp info spawn args '-Dnode_root_dir=/Users/n0bisuke/Library/Caches/node-gyp/15.14.0',
npm ERR! gyp info spawn args '-Dnode_gyp_dir=/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp',
npm ERR! gyp info spawn args '-Dnode_lib_file=/Users/n0bisuke/Library/Caches/node-gyp/15.14.0/<(target_arch)/node.lib',
npm ERR! gyp info spawn args '-Dmodule_root_dir=/Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble',
npm ERR! gyp info spawn args '-Dnode_engine=v8',
npm ERR! gyp info spawn args '--depth=.',
npm ERR! gyp info spawn args '--no-parallel',
npm ERR! gyp info spawn args '--generator-output',
npm ERR! gyp info spawn args 'build',
npm ERR! gyp info spawn args '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! gyp info spawn make
npm ERR! gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
npm ERR! env: python: No such file or directory
npm ERR! make: *** [Release/nothing.a] Error 127
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack at ChildProcess.onExit (/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
npm ERR! gyp ERR! stack at ChildProcess.emit (node:events:369:20)
npm ERR! gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
npm ERR! gyp ERR! System Darwin 21.4.0
npm ERR! gyp ERR! command "/Users/n0bisuke/.volta/tools/image/node/15.14.0/bin/node" "/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
npm ERR! gyp ERR! cwd /Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble
npm ERR! gyp ERR! node -v v15.14.0
npm ERR! gyp ERR! node-gyp -v v7.1.2
npm ERR! gyp ERR! not ok
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/n0bisuke/.npm/_logs/2022-05-13T03_31_42_891Z-debug.log
らしいです。
ふむふむ... ちなみにNode.jsのバージョンはv18系で試してましたが、エラーでたのでこの時のv15系まで落としてみましたが、エラーは変わらず。
Pythonコマンドが使えなくなっている件
普段Python使わないので気づいてなかったですが、どうやらMontereyからデフォのPythonが消えてるらしいです。
参考: Python 2.7が削除される「macOS 12.3 Monterey」では、Python 3の同梱もされないもよう。
$ python
command not found
たしかにいない。気付いてなかった...
とはいえエラーログみると
/usr/local/opt/python@3.9/bin/python3.9
に3系はいるらしいです。
$ /usr/local/opt/python@3.9/bin/python3.9
Python 3.9.12 (main, Mar 26 2022, 15:51:15)
[Clang 13.1.6 (clang-1316.0.21.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
いますね。ということはPython3ではなく2系を入れないといけない模様です。
pyenvでPython2系をインストール
調べると出てきたpyenvを使ってPython2系をインストールしていきます。
brew update && brew upgrade
~/.zshrc
の1番下に追記しました。
(省略)
# pyenv
alias brew='env PATH="${PATH//$(pyenv root)\/shims:/}" brew'
export PYENV_ROOT="$HOME/.pyenv"
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
$ source ~/.zshrc
pyenvが使えるかチェックします。
$ pyenv
pyenv 2.3.0
Usage: pyenv <command> [<args>]
Some useful pyenv commands are:
(省略)
動いた模様です。調べると2系はv2.7.18が最新らしいのでインストールしてみます。
$ pyenv install 2.7.18
次にパスを通します。
$ pyenv global 2.7.18
確認してみます。
$ python --version
Python 2.7.18
きたー v2.7.18のPythonが無事にmacOS Montereyにインストールされました。
@abandonware/nobleのインストールに再チャレンジするもエラー
再度インストールしてみます。
$ npm i @abandonware/noble
しかし、またエラー出ました。。。↓
npm ERR! code 1
npm ERR! path /Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble
npm ERR! command failed
npm ERR! command sh -c node-gyp rebuild
npm ERR! CC(target) Release/obj.target/nothing/node_modules/node-addon-api/nothing.o
npm ERR! LIBTOOL-STATIC Release/nothing.a
npm ERR! gyp info it worked if it ends with ok
npm ERR! gyp info using node-gyp@7.1.2
npm ERR! gyp info using node@15.14.0 | darwin | x64
npm ERR! gyp info find Python using Python version 3.9.12 found at "/usr/local/opt/python@3.9/bin/python3.9"
npm ERR! gyp info spawn /usr/local/opt/python@3.9/bin/python3.9
npm ERR! gyp info spawn args [
npm ERR! gyp info spawn args '/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py',
npm ERR! gyp info spawn args 'binding.gyp',
npm ERR! gyp info spawn args '-f',
npm ERR! gyp info spawn args 'make',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble/build/config.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/addon.gypi',
npm ERR! gyp info spawn args '-I',
npm ERR! gyp info spawn args '/Users/n0bisuke/Library/Caches/node-gyp/15.14.0/include/node/common.gypi',
npm ERR! gyp info spawn args '-Dlibrary=shared_library',
npm ERR! gyp info spawn args '-Dvisibility=default',
npm ERR! gyp info spawn args '-Dnode_root_dir=/Users/n0bisuke/Library/Caches/node-gyp/15.14.0',
npm ERR! gyp info spawn args '-Dnode_gyp_dir=/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp',
npm ERR! gyp info spawn args '-Dnode_lib_file=/Users/n0bisuke/Library/Caches/node-gyp/15.14.0/<(target_arch)/node.lib',
npm ERR! gyp info spawn args '-Dmodule_root_dir=/Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble',
npm ERR! gyp info spawn args '-Dnode_engine=v8',
npm ERR! gyp info spawn args '--depth=.',
npm ERR! gyp info spawn args '--no-parallel',
npm ERR! gyp info spawn args '--generator-output',
npm ERR! gyp info spawn args 'build',
npm ERR! gyp info spawn args '-Goutput_dir=.'
npm ERR! gyp info spawn args ]
npm ERR! gyp info spawn make
npm ERR! gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
npm ERR! env: python: No such file or directory
npm ERR! make: *** [Release/nothing.a] Error 127
npm ERR! gyp ERR! build error
npm ERR! gyp ERR! stack Error: `make` failed with exit code: 2
npm ERR! gyp ERR! stack at ChildProcess.onExit (/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:194:23)
npm ERR! gyp ERR! stack at ChildProcess.emit (node:events:369:20)
npm ERR! gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
npm ERR! gyp ERR! System Darwin 21.4.0
npm ERR! gyp ERR! command "/Users/n0bisuke/.volta/tools/image/node/15.14.0/bin/node" "/Users/n0bisuke/.volta/tools/image/node/15.14.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
npm ERR! gyp ERR! cwd /Users/n0bisuke/Documents/ds/playground/insmart/node_modules/@abandonware/noble
npm ERR! gyp ERR! node -v v15.14.0
npm ERR! gyp ERR! node-gyp -v v7.1.2
npm ERR! gyp ERR! not ok
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/n0bisuke/.npm/_logs/2022-05-13T05_01_53_341Z-debug.log
ずっとPython3を見に行ってるような表示ですよね。
python2系をインストールして後にNode.jsをインストールしてみたらどうだろうと思い、Node.jsのインストールからやってみした。
$ volta install node@18
かつゴミを消してみました。ファイルを消せてなかったのでこっちが原因だったかも?
$ rm -rf node_modules
$ rm package-lock.json
@abandonware/nobleを再度インストール
3度目の正直... ということで、
$ npm i @abandonware/noble
added 12 packages, and audited 13 packages in 19s
2 low severity vulnerabilities
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
やっと うまくいった模様......!
うごいたー。
周辺のBLE機器が表示されました。
コードは変わらず以下の通りです。
'use strict';
const noble = require('@abandonware/noble');
const knownDevices = [];
//discovered BLE device
const discovered = (peripheral) => {
const device = {
name: peripheral.advertisement.localName,
uuid: peripheral.uuid,
rssi: peripheral.rssi
};
knownDevices.push(device);
console.log(`${knownDevices.length}:${device.name}(${device.uuid}) RSSI${device.rssi}`);
}
//BLE scan start
const scanStart = () => {
noble.startScanning();
noble.on('discover', discovered);
}
if(noble.state === 'poweredOn'){
scanStart();
}else{
noble.on('stateChange', scanStart);
}
まとめ: Node.jsでBLEを使うためにPythonを入れた
macOS Montereyでnobleを使うのにPython2系のインストールが必要でした。
(元々依存関係はあったんですね。)