Skip to content

Instantly share code, notes, and snippets.

@blz777
Last active April 11, 2024 11:33
Show Gist options
  • Star 39 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save blz777/57d897e7e10759abcff75a12a20799f1 to your computer and use it in GitHub Desktop.
Save blz777/57d897e7e10759abcff75a12a20799f1 to your computer and use it in GitHub Desktop.
Switch bluetooth devices between two macbook machines over SSH without password.
#!/bin/sh
# Switch bluetooth devices (e.g. mouse, keyboard, trackpad) from one macbook machine to another over SSH
#
# How to configure script?
# - Configure the source and destination variables to point to the username@host to the respective machines - machines should be accessible over SSH.
# The script identifies which machine it is running on depending on the username, so we can use the same script on both machines.
# If usernames are the same on both machines, we should modify the script to identify source and destination using another method,
# e.g. a hostname. Another option is to have different scripts on both machines which set directly $source and $destination.
#
# Install prerequisite tools:
# brew install blueutil
# brew install bluetoothconnector
#
# - Configure bluetoth addresses of bluetooth devices. To see the device addresses:
# ‚ùØ blueutil --paired
# address: xx-xx-xx-xx-xx-x1, connected (master, -60 dBm), not favourite, paired, name: "User’s Mouse", recent access date: 2021-03-09 19:14:55 +0000
# address: xx-xx-xx-xx-xx-x2, connected (master, -57 dBm), not favourite, paired, name: "User's Keyboard", recent access date: 2021-03-09 19:14:57 +0000
#
# Configure SSH to the destination machine to use SSH keys, so it does not require a password:
# https://www.ssh.com/ssh/copy-id
#
# Make sure the destinatino macbook pro will wake up when trying to ssh to it:
# Preferences -> Battery -> Power Adapter -> (check) Wake for network access
#
# How to use tool?
# 1. Run the script.
# 2. Wait for the prompt to hardware-restart bluetooth devices.
# 3. Turn off both bluetooth devices. Wait two seconds. Turn on both bluetooth devices.
# 4. Bluetooth devices should now be connected to the destination machine - enjoy! :)
mouse_bluetooth_sf_address="xx-xx-xx-xx-xx-x3"
keyboard_bluetooth_sf_address="xx-xx-xx-xx-x4"
mouse_bluetooth_blg_address="xx-xx-xx-xx-xx-x1"
keyboard_bluetooth_blg_address="xx-xx-xx-xx-xx-x2"
should_use_blg_addresses=false
is_blg_keyboard_connected=`BluetoothConnector --status $keyboard_bluetooth_blg_address`
if [[ $is_blg_keyboard_connected == "Connected" ]]; then
should_use_blg_addresses=true
fi;
username=$(whoami)
if $should_use_blg_addresses; then
mouse_bluetooth_address=$mouse_bluetooth_blg_address
keyboard_bluetooth_address=$keyboard_bluetooth_blg_address
if [[ $username == "user1" ]]; then
source="user1@air-m1-blg"
destination="user2@pro-blg"
else
source="user2@pro-blg"
destination="user1@air-m1-blg"
fi
else
mouse_bluetooth_address=$mouse_bluetooth_sf_address
keyboard_bluetooth_address=$keyboard_bluetooth_sf_address
if [[ $username == "user1" ]]; then
source="user1@air-m1"
destination="user2@pro"
else
source="user2@pro"
destination="user1@air-m1"
fi
fi
echo "Disconnecting devices..."
BluetoothConnector --disconnect $mouse_bluetooth_address
BluetoothConnector --disconnect $keyboard_bluetooth_address
sleep 1
blueutil --unpair $mouse_bluetooth_address
blueutil --unpair $keyboard_bluetooth_address
echo "Disabling bluetooth..."
blueutil -p 0
sleep 5
echo "Teleporting to $destination ..."
response=$( ssh -T $destination << EOF
blueutil -p 1
echo OK
EOF
)
if [[ $response == "OK" ]]; then
echo "Enabled bluetooth on $destination."
fi
wait_time=10
echo "Please hardware-restart bluetooth devices (waiting $wait_time seconds)..."
sleep $wait_time
response=$( ssh -T $destination << EOF
blueutil --unpair $mouse_bluetooth_address
blueutil --unpair $keyboard_bluetooth_address
sleep 1
blueutil --pair $mouse_bluetooth_address
blueutil --pair $keyboard_bluetooth_address
sleep 1
BluetoothConnector --connect $mouse_bluetooth_address
BluetoothConnector --connect $keyboard_bluetooth_address
echo OK
EOF
)
if [[ $response == "OK" ]]; then
echo "Teleporting completed! :)"
fi
@nchamow
Copy link

nchamow commented Jun 12, 2021

I would love to use this script! I have a new M1 MBP that I use as my primary machine but often times I have to run apps that don't work on Apple Silicon yet so I have to revert back to my 2015 MBP. I have a magic keyboard and mouse that I'd like to easily move between the two machines but I have the same username on both. Would you be able to help me set this up?

@sztokbant
Copy link

I would love to use this script! I have a new M1 MBP that I use as my primary machine but often times I have to run apps that don't work on Apple Silicon yet so I have to revert back to my 2015 MBP. I have a magic keyboard and mouse that I'd like to easily move between the two machines but I have the same username on both. Would you be able to help me set this up?

@nchamow
You could use hostname instead of whoami on line 31, something like this:

host=$(hostname)
if [[ $host == "air-m1" ]]; then
    source="user1@air-m1"
    destination="user2@pro"
else
    source="user2@pro"
    destination="user1@air-m1"
fi

@blz777
Copy link
Author

blz777 commented Aug 5, 2021

As I also mentioned in the mail to you, one can simplify the script to use only a specific single user and use 2 different scripts on the 2 machines. On the first machine, you configure the script to teleport to the second and vice versa. I.e., trade duplication for simplicity.

I would love to use this script! I have a new M1 MBP that I use as my primary machine but often times I have to run apps that don't work on Apple Silicon yet so I have to revert back to my 2015 MBP. I have a magic keyboard and mouse that I'd like to easily move between the two machines but I have the same username on both. Would you be able to help me set this up?

@Zaheer-A
Copy link

Step 3. Turn off both devices... Is this both MacBooks or do you mean the keyboard and trackpad?

My dad and I both have MBP's and one desktop with the magic keyboard and often switch places. It's annoying to delete and add the keyboard each time so this script might be super useful. (Unless I have to restart my laptop every time)

@blz777
Copy link
Author

blz777 commented Jan 17, 2022

Step 3. Turn off both devices... Is this both MacBooks or do you mean the keyboard and trackpad?

The keyboard and trackpad :)

@nekno
Copy link

nekno commented Jul 5, 2022

Thanks for this!

I'm having an issue where the script hangs on line 67, when attempting to pair the mouse on the remote machine.

SSH is working fine, the problem seems to be with the pairing. When I execute the commands manually, either remotely using SSH or locally in Terminal, it does the same thing. blueutil --pair just never returns, or at least doesn't return after several minutes.

I see blueutil has it's own --disconnect, --connect options. Is there a reason you went with BluetoothConnector for those steps instead?

I'm also curious if you tried the experimental blueutil --unpair option in your development/testing, or have any ideas on what might prevent the mouse/keyboard from re-pairing with the second machine?

I'm trying all the various combos of commands, but having no luck.

@blz777
Copy link
Author

blz777 commented Jul 6, 2022

Hell, @nekno,

I recently updated my teleport script because I also had issues with it.
Please see the updated gist above - it does use blueutil --unpair.

Is there a reason you went with BluetoothConnector for those steps instead?

When I was developing it the first time, blueutil --disconnect was not working for me so I had to use another tool as well.
Please feel free to optimize the script, if possible :)

I am also posting the current versions I am using of the tools, just for reference:

❯ blueutil --version
2.9.0

❯ brew info BluetoothConnector
bluetoothconnector: stable 2.0.0 (bottled), HEAD
Connect and disconnect Bluetooth devices
https://github.com/lapfelix/BluetoothConnector

Hope this helps.

@blz777
Copy link
Author

blz777 commented Jul 6, 2022

FWIW, the updated gist above also contains a tiny bit of logic for detecting which hostnames it should use for SSH based on which devices have been paired at the moment. This covers a use case I have with different mouse & keyboard pairs I use at different locations.

@hoblin
Copy link

hoblin commented Aug 6, 2022

I made a change which teleports devices to the mac you're currently on. It seems a bit more handy =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment