まえがき
この記事は ちょっとした工夫で効率化!パソナテック Advent Calendar 2020 の10日目の記事です。
昨日は @yoshikyoto さんのCURL の代わりに IntelliJ でカンタン API の動作確認【JetBrains IDE】でした。
Bluetooth機器の接続をTerminalからやりたい
複数の端末で1つのBluetooth機器を使いまわしている場合、大体のBluetooth機器は最後に接続されたデバイスのみ自動で接続してくれる。
例えばAirpodsをiPhoneとMacで使いまわしてる場合、
iPhoneで接続
↓
接続解除
↓
Macで接続
とするとMacでは接続ボタンを再度押さないといけない。
結構この作業をやることが多いので、Terminalから接続のON/OFFをできるようにする。
AppleScript in ShellScriptで実現
fzfでデバイスを選択できるようにした。previewにはなんとなくデバイスの情報を出している。
fzfでの選択時、Tabで複数選択すれば一撃で複数のBluetooth機器に接続してくれる。
ちゃちゃっと試したい人は以下
$ brew tap Rasukarusan/tap
$ brew install Rasukarusan/tap/fzf-bluetooth-connect
$ bluetooth-fzf
ソース
#!/bin/bash
pairedDevices() {
osascript << EOF
use framework "IOBluetooth"
use scripting additions
set _results to {}
repeat with device in (current application's IOBluetoothDevice's pairedDevices() as list)
if device's isPaired()
set _address to device's addressString as string
set _name to device's nameOrAddress as string
set _isConnected to device's isConnected as string
if _isConnected = "1"
set _isConnected to "✔"
else
set _isConnected to "✗"
end if
set end of _results to {_address, "\t", _name, "\t", _isConnected, "\n"}
end if
end repeat
return _results as string
EOF
}
connect() {
local address=$1
osascript << EOF
use framework "IOBluetooth"
use scripting additions
repeat with device in (current application's IOBluetoothDevice's pairedDevices() as list)
set _address to device's addressString() as string
if _address = "${address}"
if device's isConnected()
device's closeConnection()
else
device's openConnection()
end if
end if
end repeat
EOF
}
main() {
local selected=("$(pairedDevices \
| sed '/^$/d' \
| fzf \
--delimiter $'\t' --with-nth 2,3 \
--preview \
'system_profiler SPBluetoothDataType -json 2>/dev/null \
| jq -r ".SPBluetoothDataType[].device_title[]["\"{2}\""]
| select(type != \"null\")"' \
)")
echo "${selected[@]}" | while read line; do
local address name
read address name <<< $(echo "$line" | cut -f1-)
echo "${name}"
connect ${address} >/dev/null
done
}
main "$@"
AppleScriptでframework読み込めるの知らんかった
実はAppleScript内ではuse framework "フレームワーク名"
とすることでCocoaの機能が使える。
今回はBluetooth関連をいじりたかったのでuse framework "IOBluetooth"
を使っている。
pairedDevices() {
osascript << EOF
use framework "IOBluetooth"
use scripting additions
...
EOF
SwiftやObjective-Cとは若干使い方が異なるが、ほとんど直感的にいける。
例えばBluetoothのペアリング済みのデバイスを取得したいときは下記のような感じ。
(IOBluetoothのpairedDevices()を使用)
pairedDevices() {
osascript << EOF
use framework "IOBluetooth"
use scripting additions
current application's IOBluetoothDevice's pairedDevices() as list
EOF
}
# 実行すると下記のような出力が得られる
# «class ocid» id «data optr0000000070F2E86AB97F0000», «class ocid» id «data optr000000002006E96AB97F0000»
application's IOBluetoothDevice's pairedDevices()
のように〇〇's
で繋いでいくだけでOK。
Bluetoothの接続情報はコマンドでも取得可能
今回はペアリング済みのデバイスを取得する際にAppleScriptを使っているが、下記コマンドでも取得できる。
$ system_profiler SPBluetoothDataType -json
jsonで吐き出すことができるので、あとはjq
でイージーですね。
system_profiler
で取得できる情報はSPBluetoothDataType
の他にもあり、system_profiler -listDataTypes
で一覧が出る。
終わり
GUIではなくCUIでサクッと接続することで人生の何秒間は節約できますね!!ヤッタネ!