4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ちょっとした工夫で効率化!01【PR】パソナテックAdvent Calendar 2020

Day 10

ShellScriptでBluetooth機器にサクッと接続する

Last updated at Posted at 2020-12-09

まえがき

この記事は ちょっとした工夫で効率化!パソナテック Advent Calendar 2020 の10日目の記事です。
昨日は @yoshikyoto さんのCURL の代わりに IntelliJ でカンタン API の動作確認【JetBrains IDE】でした。

Bluetooth機器の接続をTerminalからやりたい

複数の端末で1つのBluetooth機器を使いまわしている場合、大体のBluetooth機器は最後に接続されたデバイスのみ自動で接続してくれる。

例えばAirpodsをiPhoneとMacで使いまわしてる場合、

iPhoneで接続

接続解除

Macで接続
とするとMacでは接続ボタンを再度押さないといけない。
20200610184825.png
結構この作業をやることが多いので、Terminalから接続のON/OFFをできるようにする。

AppleScript in ShellScriptで実現

fzfでデバイスを選択できるようにした。previewにはなんとなくデバイスの情報を出している。

fzfでの選択時、Tabで複数選択すれば一撃で複数のBluetooth機器に接続してくれる。

ちゃちゃっと試したい人は以下

$ brew tap Rasukarusan/tap
$ brew install Rasukarusan/tap/fzf-bluetooth-connect
$ bluetooth-fzf
ソース
[Github](https://github.com/Rasukarusan/fzf-bluetooth-connect)
#!/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でサクッと接続することで人生の何秒間は節約できますね!!ヤッタネ!

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?