Magic Mouseの電池残量警告ツール

## Magic Mouseの電池残量が設定以下になったときに何等かの警告をしてほしい
私の普段の開発マシンはM1搭載のMac miniでして、キーボードはLogicoolのMX Keys M Mac、マウスはApple Magic Mouse2という入力デバイスを使用しております。
キーボードのほうは電池残量が少なくなってきたらUSB Type-Cケーブルで充電させながら使うので使い心地は有線キーボードのようになります。
マウスのほうもLightningケーブルを繋いで有線マウスのような使い心地になってくれれば何の問題も無いのですが、Magic Mouse2はLightningコネクタがマウス底面にあり、Lightingケーブルを繋ぐと使えなくなってしまいます。
仕事が終わる直前に電池残量警告がきてくれればいいのですが、朝一番にくると仕事中のどこかのタイミングでマウスが止まります。そんなときは仕事を中断して休憩を取るのが良いのかもしれませんが、なんとなくストレスではあります。
あと、マウスの電池残量警告のレベルをどこかで変えるという手もあるのかもしれませんが、この際なのでマウス電池残量を調べて、ある値未満になったら警告を出すツールを作りました。

```shell
#!/bin/sh
MOUSE_BATTERY_FILE=$HOME/.__MOUSE_BATTERY_FILE__
if [ -e $MOUSE_BATTERY_FILE ]; then
	exit
fi

MAGIC_MOUSE_BATT=`/usr/sbin/ioreg -r -d 1 -k BatteryPercent -c AppleDeviceManagementHIDEventService | grep BatteryPercent`

for COLUMN in $MAGIC_MOUSE_BATT
do
	LAST_ELEMENT=$COLUMN
done

LOW_BATTERY_LEVEL=25
if [ $LAST_ELEMENT -lt $LOW_BATTERY_LEVEL ]; then
	echo "MOUSE BATTERY warning less than $LOW_BATTERY_LEVEL: actually: $LAST_ELEMENT" > $MOUSE_BATTERY_FILE
	cat $MOUSE_BATTERY_FILE | 警告送信シェルスクリプトのパス
fi
```
#### ioreg
ioregというツールがありまして、このツールのパラメータを色々と設定するとMagic Mouse2の電池残量がわかるみたいなのでこれを使ってみました。シェルスクリプトはcronで使う前提でして /bin や /usr/bin にしかパスが通っていないのでioregをフルパスで指定しています。
ここではクラス名が"AppleDeviceManagementHIDEventService"で、"BatteryPercent"という名のキーがあるものを出力してくれ、というパラメータになっていまして、-dオプションで階層の深さ、-rオプションでその内容の詳細を出力するというものです。実行すると、
```console
$ ioreg -r -d 1 -k BatteryPercent -c AppleDeviceManagementHIDEventService
+-o AppleDeviceManagementHIDEventService  <class AppleDeviceManagementHIDEventService, id 0x100000a97, registered, matc$
    {
      "IOMatchedAtBoot" = Yes
      "LowBatteryNotificationPercentage" = 2
      "PrimaryUsagePage" = 65280
      "BatteryFaultNotificationType" = "MOBatteryFault"
      "HasBattery" = Yes
      "VendorID" = 76
      "VersionNumber" = 0
      "Built-In" = No
      "DeviceAddress" = "48-4b-aa-ec-9a-a9"
      "WakeReason" = "Host (0x01)"
      "Product" = "Magic Mouse"
      "SerialNumber" = "48-4b-aa-ec-9a-a9"
      "Transport" = "Bluetooth"
      "BatteryLowNotificationType" = "MOLowBattery"
      "Manufacturer" = "Apple Inc."
      "ProductID" = 617
      "DeviceUsagePairs" = ({"DeviceUsagePage"=65280,"DeviceUsage"=11},{"DeviceUsagePage"=65280,"DeviceUsage"=20})
      "IOPersonalityPublisher" = "com.apple.driver.AppleTopCaseHIDEventDriver"
      "MTFW Version" = 0
      "BD_ADDR" = <484baaec9aa9>
      "BatteryPercent" = 35
      "BatteryStatusNotificationType" = "BatteryStatusChanged"
      "CriticallyLowBatteryNotificationPercentage" = 1
      "ReportInterval" = 11250
      "RadioFW Version" = 402
      "VendorIDSource" = 1
      "STFW Version" = 2144
      "CFBundleIdentifier" = "com.apple.driver.AppleTopCaseHIDEventDriver"
      "IOProviderClass" = "IOHIDInterface"
      "LocationID" = 720149161
      "BluetoothDevice" = Yes
      "IOClass" = "AppleDeviceManagementHIDEventService"
      "HIDServiceSupport" = No
      "CFBundleIdentifierKernel" = "com.apple.driver.AppleTopCaseHIDEventDriver"
      "ProductIDArray" = (617)
      "BatteryStatusFlags" = 0
      "ColorID" = 0
      "IOMatchCategory" = "IODefaultMatchCategory"
      "CountryCode" = 0
      "IOProbeScore" = 7175
      "PrimaryUsage" = 11
      "IOGeneralInterest" = "IOCommand is not serializable"
      "BTFW Version" = 402
    }
```
という感じで出力されます。
必要なのは"BatteryPercent"の行なのでこれをgrepで抜き出すと、
```console
kageyama@vixen:~ $ ioreg -r -d 1 -k BatteryPercent -c AppleDeviceManagementHIDEventService | grep BatteryPercent
      "BatteryPercent" = 35
```
となります。
シェルスクリプトの for in do.. ループで回すと最後が電池残量の値になるので、スクリプトでは$LAST_ELEMENT変数にそのまま一つ一つ代入して、最後の値を取るという雑なやり方をしています。
私の場合は ~/.\_\_MOUSE_BATTERY_FILE\_\_ というファイルに警告内容を格納し、標準入力から本文を作ってメール送信するperlスクリプトにファイルの内容を渡すようにしています。一日に何度も来ないように ~/.\_\_MOUSE_BATTERY_FILE\_\_ ファイルが存在しない場合にだけメールを送信するようにシェルスクリプトを書きました。

#### crontabの設定
crontabの内容はだいたいこんな感じになります。
```console
$ crontab -l
@reboot rm -f .__MOUSE_BATTERY_FILE__ ファイルのパス
3 * * * * シェルスクリプトのパス
```
マシンの起動時に .\_\_MOUSE_BATTERY_FILE\_\_ ファイルを削除し、毎時3分にMagic Mouse2の電池残量チェックシェルスクリプトを起動します。

#### 使い方
私は平日はMac miniで仕事して、週末はあまりMac miniを触らないという生活パターンになっておりますが、仕事用のMac mini以外にも休日にネット等を使うためのLinuxノートPCやiPhone等でIMAPをメールを見れるようにしておりまして、電池残量警告メールが残っていたらMagic Mouse2にLightningケーブルを繋ぐ使い方を想定しています。
電池残量警告が25%というのが妥当な数値であるかどうかはわかりませんが、色々と設定を試していただければ幸いです。
Magic Mouse2の他にApple KeyboardやTrackPadをお使いの方はioregのパラメータや$MAGIC_MOUSE_BATT変数の処理方法をさらに工夫することになると思います。