Display Magic Mouse Battery in Touch bar using BetterTouchTool

柔情痞子 提交于 2019-12-13 03:01:41

问题


I'm using this BetterTouchToll for make my touch bar more interesting, what is very cool.

He accept some Apple Scripts for more dynamic, so I start to study this scripts.

Now I wanna to display my Magic Mouse Battery on my touch bar, for this I was trying this code, but is not working.

if application "Mouse" is running then
    tell application "Mouse"
        return (get Battery)
    end tell
end if
return "no mouse"

My guess is that Mouse is not a application, but don't know what to put in the place


回答1:


The traditional means of getting the battery level is to use ioreg on the command line. However, the traditional means of doing this no longer seem to work as of at least macOS High Sierra/10.13.4; that is, they no longer allow choosing to display just the battery percentage of a single bluetooth device.

So this is a hack that assumes that the Magic Mouse is always the last device displayed by ioreg. This is likely to fail, if not across different installations of macOS, then across different versions.

ioreg -c AppleDeviceManagementHIDEventService | grep BatteryPercent | tail -1 | sed 's/[^[:digit:]]//g'

In an AppleScript, this would be:

do shell script "ioreg -c AppleDeviceManagementHIDEventService | grep BatteryPercent | tail -1 | sed 's/[^[:digit:]]//g'"

You have your code setup to also detect when the Magic Mouse is not connected. The product name is in the property “Product” in ioreg. For example:

ioreg -c AppleDeviceManagementHIDEventService | grep '"Product" ='

So to make sure that this final device is the Mouse, you could do:

set finalDevice to do shell script "ioreg -c AppleDeviceManagementHIDEventService | grep '\"Product\" =' | tail -1"
if finalDevice contains "Magic Mouse" then
    set remaining to do shell script "ioreg -c AppleDeviceManagementHIDEventService | grep BatteryPercent | tail -1 | sed 's/[^[:digit:]]//g'"
    remaining & "%"
else
    "no mouse"
end if

The basic logic:

  1. Grab the list of all products using ioreg.
  2. Use tail to get only the final product in the list.
  3. If the final product is a Magic Mouse, then:
    1. Grab the list of all battery percentages using ioreg.
    2. Use tail to get only the final battery percentage in the list.
    3. Use sed to get only the actual number from that line.
    4. Append a percentage symbol to the number.
  4. Otherwise, there is no mouse. (Or the mouse is not the final item in the list.)

For the older means of using ioreg, see, for example:

  • Reporting on Bluetooth Mouse/Keyboard battery status
  • Read Magic Mouse and Apple Wireless Keyboard Battery percentage



回答2:


Thanks so much for the solution. Very inspiring. As I have multiple devices I made my own script based on your solutions. I want to share it here in case it could be useful to others.

As I have more than one bluetooth device, the order of them in ioreg is based on the order they were connected. Which means I cannot assume that the mouse is the last device.

I made most of it in shell, not in applescript, since I am more experienced in shell and therefore it was quicker that way. Using Applescript for filtering the output from ioreg would properly have been a 'cleaner' solution :p

WARNING: I know this code is pretty crappy, but it was quick to write and it does the job, don't assume this to be a way of doing things properly.

My solution

From BTT the following script calls the shell script

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

As seen the code pretty much just calls the shell script. The name provided in the variable "devicename" is used as a argument to the script and is the name that the script will look for in ioreg. If the shell script outputs an empty script no widget will be displayed. For me this was preferred over displaying "No device".

The script in "~/.dotfiles/shell/device_battery_level.sh" then looks like this:

#!/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

The basic logic is the same as the above answer. Except instead of grabbing the last line from ioreg with tail egrep is used to only output relevant lines. The egrep code is based on another post here: https://apple.stackexchange.com/questions/293502/how-can-i-determine-the-battery-level-of-my-magic-mouse-from-the-command-line/293505#293505 Based on this the line which mentions the devicename is found. The logic is that since the battery level information is always below the devicename in ioreg the next line in the extracted list must be the battery level.



来源:https://stackoverflow.com/questions/50190787/display-magic-mouse-battery-in-touch-bar-using-bettertouchtool

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!