How to keep a MacBook Air from connecting to a Bluetooth speaker when its lid is closed

bluetoothsleep-wake

The MacBook Air automatically connects to a (previously paired) Bluetooth speaker even when the lid is closed, which prevents the device I'm actually using at the moment from connecting to the speaker.

How do I configure the MacBook Air to not automatically connect to a bluetooth speaker when the lid is closed? I want everything to work as-is when the lid is open.

Best Answer

Building on other answers and giving most/all puzzle pieces but not a whole solution:

  1. Make sure to check if you want to have Bluetooth devices wake your Mac
    • If you don't want that, uncheck it in system preferences and check if the undesired behaviour persist (It's in BluetoothAdvanced…Allow Bluetooth devices to wake this computer)
  2. If you need/want to wake your Mac by Bluetooth devices or this keeps happening despite turning off the option follow these steps:

Install a helper program to check for system sleep (if you want to distinguish only lid open/closed without the Mac sleeping, it seems there is currently no easy way – i.e. I didn't find out how to detect that), and toggle Bluetooth depending on sleep/wake events.

Helpers to detect sleep/wake (check the various options in this post):

Possible to run scripts on sleep and wake?

See also this post about "Automatically turn bluetooth on or off depending on current network (MBP running Lion)" mentioning ControlPlane

Toggle bluetooth from scripts:

How to control Bluetooth wireless radio from the command line?

My recommendation: install blueutil via homebrew

Run blueutil power 0 upon sleep

And blueutil power 1 upon wake

Now about my contribution to this problem: If power nap causes a wake event try this script for wake to distinguish between other wake reasons and lid opening:

#!/bin/bash
limitSec=3
currentEpoch=$(date "+%s")
wakeEpoch=$(cat /var/log/system.log | grep LidOpen | tail -n 1 | date -j -f "%b %d %T" "$(cut -c1-15)" "+%s")
wakeSeconds=$(( $currentEpoch - $wakeEpoch ))

if [[ $wakeSeconds -lt $limitSec ]]; then
    logger "Enabling bluetooth again due to lid open"
    blueutil power 1
fi

It sets a timeout of 3 seconds (limitSec), gets the current time and the last time of wake with Wake reason: EC.lidOpen, and if that was less than 3 seconds ago it will re-enable Bluetooth