Turn wifi on/off based on ethernet status?

Recently I acquired a docking station with an ethernet port. I’d like to setup my Mac to automatically disable WiFi when my laptop is connected to the dock (and thus to an ethernet connection).

I’m aware that I can set the network interface order so that traffic will preferentially travel over ethernet when it’s available, but I’d like to disable the WiFi.

Seems like there should be something that does this? I found this thread, but I don’t believe any of these options work under BigSur.

Many thanks for any suggestions,
Adam.

I believe if you want to use features like AirDrop and Apple Watch unlocking, you’d need to keep wifi active.

However, if you don’t want these features, you should be able to use Keyboard Maestro (KM) and Network Locations to achieve this. If you create a new network location in the Network preferences pain that only has Ethernet/Dock enabled, you can have KM switch between network locations when you plug the dock in to the Mac.

@drezha is absolutely right: Keyboard Maestro is the way to go — at least this worked well for me. :slight_smile:

Regarding Wi-Fi toggle based on Ethernet status
Two rules come into play: both with “This USB devices with name containing {{LAN}}” is attached/detached. If this happens, a shell script action runs.

networksetup -setairportpower en0 on

{{LAN}} may be different with your dock/Ethernet, but I’d give it a try. “en0 on” is respectively “en0 off” within the subsequent rule. More info regarding networksetup: GitHub - kendfinger/MacHack: Hidden Tools in macOS

Unlock with Apple Watch, despite attached Ethernet cable
This was a bit trickier for me and might differ with your use case / behavior. This also utilizes two rules, the first addressing the scenario that Ethernet is active.

Using the idle trigger after {{n Minutes}} networksetup does its work and activates Wi-Fi (same line as quoted above). Then a small pause gives KM some time and a variable named “SystemLockActive” is set to 1. Then I run a shell script which starts the screensaver:

/System/Library/CoreServices/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine

The second rule addresses the scenario that I log in, and the device uses Ethernet. As a trigger, I use my most performed behavior after login: Alfred activates. Granted: this might not happen immediately but that’s no problem for me. When it happens an if statement checks if the USB device {{LAN}} exists and if the Variable “SystemLockActive” is set to 1. If all this is true networksetup comes into play again:

networksetup -setairportpower en0 off

Finally: The variable SystemLockActive needs to be set to 0 so the next time the dance works out again.

For me, this works fine since Big Sur and also on Monterey. It has not caused any troubles or hiccups. I just didn’t want to miss the experience of unlocking with Apple Watch. Good luck with your endeavor.

Just a tip that en0 is usually the port used for built-in Ethernet.

For a laptop, your AirPort (Wi-Fi) will be en0. For a Mac Mini (and I assume iMac/Mac Pro), it will be your wired Ethernet port, and Wi-Fi will be en1

If you aren’t sure, you can use:

networksetup -listallhardwareports

to show a list of all the ports that the Mac has.


I used to do this with a launchd trigger that looked for changes to a particular folder, but with AirDrop, I want to leave Wi-Fi on, and don’t see much point in turning off Wi-Fi when Ethernet is enabled anyway, so I haven’t checked to see if it still works. That said, if anyone is interested in seeing it, I can dig it out.

This should do it, and assumes some comfort with Terminal commands and the like.
You can use this script to set Wi-Fi based on the status of the Ethernet port (here assumed to be en0).

#!/bin/bash

ETHERNET_DEVICE=en0

NETWORKSETUP=/usr/sbin/networksetup
IFCONFIG=/sbin/ifconfig

WiFi=$($NETWORKSETUP -listallhardwareports | grep -A1 "Wi-Fi" | grep Device | cut -f2 -d' ')

echo "Run $0"
echo "Wifi interface $WiFi"
echo "Ethernet interface $ETHERNET_DEVICE"

EthernetStatus=$($IFCONFIG | grep -A5 $ETHERNET_DEVICE | grep status | cut -f2 -d' ')
echo "Ethernet is currently $EthernetStatus"

if [ "$EthernetStatus" == "inactive" ]; 
then 
	$NETWORKSETUP -setairportpower $WiFi on
	echo "Wi-Fi set on"
else
	$NETWORKSETUP -setairportpower $WiFi off
	echo "Wi-Fi set off"
fi

Now the problem is doing this automatically.
You could use KeyboardMaestro to run the script periodically.
Or you could use crontab.
Your crontab job (use crontab -e to edit it) would look like this to have the script run every minute:

*/1 * * * * ~/.local/bin/set_wifi_based_on_ethernet.sh

(I saved my set_wifi_based_on_ethernet.sh script into my ~/.local/bin folder. Be sure to make it executable.)

1 Like

Thank you all, that’s very helpful!

A cronjob running every minute would be good enough, but I’ve been looking for a reason to play with Keyboard Maestro and never found one … now I do! Fun! :slight_smile:

1 Like