HomekitでPCのUSBを接続・切断する

# やりたいこと
1つの無線イヤホンで複数(PCとiPhone)の音源をいい感じに再生したい

# 現状
- 再生側はBluetoothレシーバー(Fiio BTR5)から2台へマルチポイント
- PCとはBluetoothドングル(BT-W3)とapt-x接続
- iPhoneとはBluetooth接続(AAC)

https://jp.creative.com/p/accessories/creative-bt-w3

https://www.fiio.jp/products/btr5/

# 不満点
コーデック差分により、マルチポイント接続においてPC側の接続が常に優先されるため、iPhone側の音を聞きたいとき、PC側のドングルを都度物理的に抜く必要がある。

# 解決策
## 用意するもの(物理)

遠隔でUSBの電源を落とすやつ

http://www.centech.jp/?p=660


## 用意するもの(論理)

iPhone(Homekit)から接続対象を弄りたいので、以下を構築

### 1.HomeBridgeインストール

CentOS上にHomeBridgeをインストールし、HomeKitで捌くためのサーバを用意。参考URLのコマンド打ったらなんかするっと入った。


https://homebridge.io/

https://pentan.info/server/homebridge/install_centos.html

※nodeのverが古かったので、アップデートだけは以下を参考に実施。

https://qiita.com/daichi_pd/items/b3d8d968f36e6197bec4



※OS内でコマンド実行するアクセサリを構築するため、以下もインストール

https://qiita.com/hiro2do/items/ff336cb70eb2b1cb1e6b


### 2.HomeBridgeサーバ設定

- サーバのローカルIP固定設定、Windowsとの共有フォルダ設定(/etc/fstab)、homebridgeユーザのsudore設定(Windows領域にフラグファイルをsudoでtouchできるようにする)、を実施

- コンフィグは以下で書いたら動いた。シェルはフラグファイルをWindows領域にtouchしてるだけ。
※`sudo touch /<<フラグファイル共有フォルダ>>/BT_W3_ON`

```json

{
    "bridge": {
        "name": "Homebridge XXXX",
        "username": "XX:XX:XX:XX:XX:XX",
        "port": XXXXX,
        "pin": "XXX-XX-XXX",
        "advertiser": "bonjour-hap"
    },
    "accessories": [
        {
            "accessory": "CMD",
            "name": "BT-W3",
            "on_cmd": "/home/homebridge/BT-W3.sh ON",
            "off_cmd": "/home/homebridge/BT-W3.sh OFF"
        }
    ],
    "platforms": [
        {
            "name": "Config",
            "port": XXXX,
            "platform": "config"
        }
    ]
}

```

```bash
#!/bin/bash

# フラグファイル配置先ディレクトリ
FLG_DIR="/sf/HomeBridgeServer"

# デバイス名(＝スクリプト名)
DEV_NAME=$(basename "$0" .sh)

# 実行時引数をチェックする
if [ "$1" = "ON" ]; then

    # "${FLG_DIR}/${DEV_NAME}-OFF"ファイルが存在する場合は削除する
    if [ -f "${FLG_DIR}/${DEV_NAME}-OFF" ]; then
        sudo mv "${FLG_DIR}/${DEV_NAME}-OFF" "${FLG_DIR}/${DEV_NAME}-ON"
    else
        # "${FLG_DIR}/${DEV_NAME}-ON"ファイルを生成する
        sudo touch "${FLG_DIR}/${DEV_NAME}-ON"
    fi

elif [ "$1" = "OFF" ]; then

    # "${FLG_DIR}/${DEV_NAME}-ON"ファイルが存在する場合は削除する
    if [ -f "${FLG_DIR}/${DEV_NAME}-ON" ]; then
        sudo mv "${FLG_DIR}/${DEV_NAME}-ON" "${FLG_DIR}/${DEV_NAME}-OFF"
    else
        # "${FLG_DIR}/${DEV_NAME}-OFF"ファイルを生成する
        sudo touch "${FLG_DIR}/${DEV_NAME}-OFF"
    fi

else

    echo "Usage: $0 [ON|OFF]"
    exit 1

fi

```


### 3.USB Troubleshooter制御用(接続・切断・切替)APの作成


cppわからん...やったことは以下

- 「Microsoft Visual C++ 2010 再頒布可能パッケージ (x86) 」をインストール
- Visual Studio(2022) と C++の開発ツールを一式インストール
- 製品URLのサンプルソースをDL
- `USB_Check.vcxproj`を開く
- プロジェクトを再ターゲット
- ビルドをトライ＆エラーして、実行前提となる諸々をインストール。これとか。

https://learn.microsoft.com/ja-jp/visualstudio/msbuild/errors/msb8041?view=vs-2022

- `USB_CheckDlg.cpp`に以下の処理を追記

```cpp

// CUSB_CheckDlg メッセージ ハンドラー
BOOL CUSB_CheckDlg::OnInitDialog()
{

	CDialogEx::OnInitDialog();

	// このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
	//  Framework は、この設定を自動的に行います。
	SetIcon(m_hIcon, TRUE);			// 大きいアイコンの設定
	SetIcon(m_hIcon, FALSE);		// 小さいアイコンの設定

	// TODO: 初期化をここに追加します。
	AutoCheckExecute = FALSE;
	InitGrid();
	UpdateUSBInfo();

//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓追加した処理 ここから↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓//

	//デバイス情報入れるstructsを定義
	USB_1PORT_HUB_DEVICE_INFO devinfo;
    //デバイス情報を取得
	Hub_GetDeviceInfo(&devinfo);

    //USB_On.exe の場合、以下によりUSBデバイスを接続
	Hub_SetStatus(devinfo.CtrlSerial, 1);//ON

    //USB_Off.exe の場合、以下によりUSBデバイスを切断
	Hub_SetStatus(devinfo.CtrlSerial, 0);//OFF

	//USB_Switch.exeの場合、以下によりUSBデバイスの接続・切断をスイッチ
	if (devinfo.ConnectionStatus) {
		Hub_SetStatus(devinfo.CtrlSerial, 0);//OFF
	} else {
		Hub_SetStatus(devinfo.CtrlSerial, 1);//ON
	}

    //付属のGUIは要らないので、ここでAP自体を終了させる
	EndDialog(0);

//↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑追加した処理 ここまで↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑//

	return TRUE;  // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}

```


- ↑をビルドして、`USB_On.exe,USB_Off.exe,USB_Switch.exe`の3つのexeを作って、AHKに呼ばせる


### 4.APの実行設定

Autohotkeyの常駐スクリプト内に以下を追加(3秒おきにTimerで実行される場所に記載)。WSLのcrontabとかタスクスケジューラーとか使ってもよいかも。

```autohotkey

	;USB_Connect用
	if ( FileExist("C:\<<フラグファイル共有フォルダ>>\BT-W3-OFF") ){
		FileDelete, C:\<フラグファイル共有フォルダ>>\BT-W3-OFF
		run, "C:\<<USB Troubleshooterの実行ファイル配置先>>\USB_Off.exe"
	}
	if ( FileExist("C:\<<フラグファイル共有フォルダ>>\BT-W3-On") ){
		FileDelete, C:\<<フラグファイル共有フォルダ>>\BT-W3-On
		run, "C:\<<USB Troubleshooterの実行ファイル配置先>>\USB_On.exe"
	}

```