寝る前にMacをスリープさせるのにScript MenuからAppleScriptを呼び出して実行しています。もともとは、Apple Magic Mouseの充電用に作ったScriptでしたが、普通にマウスの充電を行わない場合にでも呼び出してスリープさせています。
そんなScriptに対して、
「マウスのバッテリー残量を調べて、残量が少ない場合には充電するようにメッセージを出せば便利なのでは?」
などと考えて、ありものの部品を組み合わせて作ろうとしたところ……動かない。
しばらく見ないうちに、system_profiler経由で取得したBluetoothデバイスの各種情報から直接バッテリー残量を取れなくなっていたもよう。
仕方がないので、シェルのioregコマンドから詳細情報を取得し、system_profilerで取得したBluetoothデバイス名(ただしApple純正に限る)の一覧と付け合わせを行なって、これらの周辺機器のバッテリー残量を取得するようにしてみました。
正直、やっつけで作ったので、プログラム自体はあんまり見るべきものはありません。1回作ったら、二度と見直したくないような出来です。Magic Track Padは持っていないので、同デバイスの電池残量レポートについては、お持ちの方はぜひお試しください。
system_profiler経由でBluetoothデバイス名を取得するあたりの処理をライブラリに追い出して、バンドルScript内に入れて呼び出しているので、下記リストは参考程度。実際に実行するには、添付のアーカイブを展開して実行してください。
–> Download script bundle archive
追加:
Apple Magic Trackpad(乾電池式、銀色)の中古を買ってきて試してみたら、
Bluetoothメニュー上でバッテリー残量表示は行われるのですが、本AppleScriptでバッテリー残量を取得することはできませんでした。
AppleScript名:Apple純正マウス、キーボードのバッテリー残量取得.scptd |
— – Created by: Takaaki Naganoya – Created on: 2024/01/11 — – Copyright © 2024 Piyomaru Software, All Rights Reserved — use AppleScript version "2.8" use framework "Foundation" use framework "AppKit" use scripting additions use btLib : script "btLib" set devList to getBTBatteryLifeByNameList() of btLib set aRes to (do shell script "ioreg -c AppleDeviceManagementHIDEventService -r -l") set aList to paragraphs of aRes set fromStr to " {" set toStr to " }" set statF to false set allList to {} set sNum to 0 set eNum to 0 set aCount to 1 –Step 1: ioregの実行結果からデバイスごとの情報に分割 repeat with i in aList set j to contents of i if statF = false then if j starts with fromStr then set statF to true set sNum to aCount end if else if j ends with toStr then set eNum to aCount set the end of allList to (items sNum thru eNum of aList) set statF to false copy {0, 0} to {sNum, eNum} end if end if set aCount to aCount + 1 end repeat –Step 2: Bluetoothのデバイス(Apple純正デバイス)の名称リストと、Addressをもとにioregの内容を照合 set devIList to {} set devCount to 1 repeat with i in devList set j to contents of i set tmpName to device_name of j set tmpAddr to device_address of j set tmpAddr to repChar(tmpAddr, ":", "-") of me repeat with ii in allList repeat with iii in ii set jjj to contents of iii ignoring case if jjj contains tmpAddr then set the end of devIList to {tmpName, devCount, contents of ii} set devCount to devCount + 1 exit repeat end if end ignoring end repeat end repeat end repeat –Step 3: 取得した名前、Indexをもとにバッテリー比率を求める set endList to {} repeat with i in devIList copy i to {tmpName, tmpIndex, dList} repeat with ii in dList set jj to contents of ii if jj contains "BatteryPercent" then set batNum to splitAfterAtmark(jj, "= ") of me set the end of endList to {tmpName, batNum as number} end if end repeat end repeat return endList –> {{"Takaaki Naganoya のキーボード #1", 46}, {"Takaaki Naganoya のマウス", 4}} –指定マーク文字以降の文字列を返す on splitAfterAtmark(anAdr, aMark) set atPos to offset of aMark in anAdr if atPos = 0 then return false set domainText to text (atPos + 1) thru -1 of anAdr return domainText end splitAfterAtmark –Written By Philip Aker –文字置換ルーチン on repChar(origText as string, targStr as string, repStr as string) set {txdl, AppleScript’s text item delimiters} to {AppleScript’s text item delimiters, targStr} set temp to text items of origText set AppleScript’s text item delimiters to repStr set res to temp as text set AppleScript’s text item delimiters to txdl return res end repChar |