Большое спасибо за решение. Очень вдохновляюще. Поскольку у меня есть несколько устройств, я сделал свой собственный сценарий на основе ваших решений. Я хочу поделиться этим здесь на случай, если это может быть полезно для других.
Поскольку у меня более одного устройства Bluetooth, их порядок в ioreg основан на порядке их подключения. Это означает, что я не могу предположить, что мышь - последнее устройство.
Я сделал большую часть этого в оболочке, а не в appleScript, так как у меня больше опыта в оболочке, и поэтому так было быстрее. Использование Applescript для фильтрации выходных данных из ioreg было бы правильным решением: p
ВНИМАНИЕ: я знаю, что этот код довольно дурацкий, но его быстро написать, и он справляется со своей задачей, не думайте, что это способ работать правильно.
Мое решение
Из BTT следующий скрипт вызывает скрипт оболочки
set devicename to "Magic Mouse 2" -- The name of the device in ioreg
set displayname to "Mouse" -- The name to display on the touchbar
set remaining to do shell script "~/.dotfiles/shell/device_battery_level.sh" & " " & quoted form of devicename
if remaining is "" then
"" --No device present = no output to touchbar
else
displayname & " " & remaining & "%" -- Show output on touchbar
end if
Как видно, код в значительной степени просто вызывает скрипт оболочки. Имя, указанное в переменной «devicename», используется в качестве аргумента сценария и является именем, которое сценарий будет искать в ioreg. Если скрипт оболочки выводит пустой скрипт, виджет не будет отображаться. Для меня это было предпочтительнее, чем отображение «Нет устройства».
Сценарий в «~ / .dotfiles / shell / device_battery_level.sh» выглядит следующим образом:
#!/bin/sh
DEVICES=$(ioreg -r -l -n AppleHSBluetoothDevice | egrep '"BatteryPercent" = |^ \| "Bluetooth Product Name" = ') #Lets get a list of all bluetooth devices
DEVICELINE=$(grep -n "$1" <<< "$DEVICES") #$1 is the device that this script was called with. Lets extract only the line with that device
if [$DEVICELINE = ""] #If DEVICELINE is empty the name of the device was not in the output and it is properly not connected.
then
echo "" #Device not present, lets give BTT an empty string
else
LINENR="${DEVICELINE:0:1}" #Then we find out where the line of the device is located
NEXTLINE=$(expr $LINENR + "1") #The battery level is at the next line therefore we increment the line number
SEDCOMMAND="p"
BATTERYLINE=$(echo "$DEVICES" | sed -n $NEXTLINE$SEDCOMMAND) # Now we can extract the line with the battery percent
echo $BATTERYLINE | sed 's/[^[:digit:]]//g' #Finally we just need to get the digit and echo that to BTT
fi
Основная логика та же, что и в ответе выше. За исключением того, что вместо получения последней строки из ioreg с tail, egrep используется только для вывода соответствующих строк. Код egrep основан на другом посте здесь: https://apple.stackexchange.com/questions/293502/how-can-i-determine-the-battery-level-of-my-magic-mouse-from-the-command-line/293505#293505
На основании этого найдена строка, в которой упоминается имя устройства. Логика заключается в том, что, поскольку информация об уровне заряда батареи всегда ниже имени устройства в ioreg, следующей строкой в извлеченном списке должен быть уровень заряда батареи.