Skip to content

Instantly share code, notes, and snippets.

@w568w
Last active March 29, 2024 12:49
Show Gist options
  • Select an option

  • Save w568w/36a482fa08a4ef5613e9e5c0a8ce6c96 to your computer and use it in GitHub Desktop.

Select an option

Save w568w/36a482fa08a4ef5613e9e5c0a8ce6c96 to your computer and use it in GitHub Desktop.
Network Manager Auto Reconnect

Network Manager Auto Reconnect

Motivition

I have an Orange Pi that connects to the network via WiFi, and since my network is not very stable, the wireless router side often forcefully disconnects all devices, requiring manual reconnection. This is an annoying thing when I'm out: first, I have to figure out how to SSH to my Pi!

The network manager I use is NetworkManager, which is very modern and user-friendly. Unfortunately, until today its developers were not interested in adding an option to automatically reconnect to hotspots.

In this issue, some developers have suggested using the dispatcher to accomplish this. Well... I wrote a simple script to do this. It will try to restart the NetworkManager service 3 times when the network is disconnected (down event received).

Usage

There's not much hard-coding in the script, so it should work on anyone's device.

Note that the script requires at least Python 3.10 because it uses match statement, which was introduced since Python 3.10.

Put it under your /etc/NetworkManager/dispatcher.d/:

sudo cp network-manager-auto-reconnect.py /etc/NetworkManager/dispatcher.d/
sudo chmod +x /etc/NetworkManager/dispatcher.d/network-manager-auto-reconnect.py

And it is all set. You should not need to restart your device or any service to make it effective. It takes effects immediately.

You can trigger a disconnection and see if it works:

sudo nmcli connection down <connection name. Usually your SSID name>
#!/bin/env python3
import os
import sys
import subprocess
import time
def run_command(command):
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
return result.stdout
def get_device_type(interface_name):
output = run_command(f'nmcli --terse --fields GENERAL.TYPE device show "{interface_name}"')
return output.replace('GENERAL.TYPE:', '').strip()
if __name__ == '__main__':
interface_name = sys.argv[1]
action = sys.argv[2]
if "wifi" not in get_device_type(interface_name):
print(f'Skip {interface_name} as it is not a wifi device', file=sys.stderr)
exit(0)
match action:
case 'down':
retry_time = 0
while retry_time < 3:
# retry
exit_code = os.system(f'systemctl restart NetworkManager')
retry_time += 1
if exit_code == 0:
print(f'Successfully execute reconnection to {interface_name}', file=sys.stderr)
exit(0)
else:
print(f'Failed to reconnect {interface_name}, exit code: {exit_code}', file=sys.stderr)
time.sleep(10)
print(f'Failed to reconnect {interface_name} after 3 retries', file=sys.stderr)
case _:
print(f"Unknown action {action}", file=sys.stderr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment