Keep trying to connect to a WiFi network in Python even if it is not available

671 Views Asked by At

I would like to write a script in which it keeps on trying to connect to a network, even if it is not available so as soon at it becomes available it will connect to it. This is what I have now

def connect_to_yeelight(ssid, iface):
sys.setrecursionlimit(2000)
iface_channel = f"sudo iwconfig {iface} channel 6"
os.system(iface_channel)
connect_yeelight_cmd = f"nmcli d wifi connect {ssid} ifname {iface} > /dev/null 2>&1"

def try_connection():
    if os.system(connect_yeelight_cmd) != 0:
            try_connection()
            time.sleep(1)
    else:
        return True

try_connection()

as you can probably tell with this code I get a "RecursionError: maximum recursion depth exceeded in comparison". Is there any other way I could achieve such script, I feel like Im looking at this from a wrong angle.

2

There are 2 best solutions below

0
On

First use can us the sleep() or schedule functionality to achieve the continues call of your function.

I wrote a function that executes the console commands and returns you the output:

def _executeConsoleCommand(command):
    '''Executes the linux command line arguments and returns the output if needed'''
     try:
         stream = os.popen(command)
         return stream.read().strip()
     except:
         return ''

Now you just need a function that connects you if the wifi is availiable. Note that you can only call the nmcli rescan function each 10 to 20 seconds - otherwise it will just refuse to scan anything for the next time. Thats why i recommend scanning with iw module.

def tryConnect():
    yourSSID = 'TestWifi'
    yourPassword = '12345678'
    ssids = _executeConsoleCommand('sudo iwlist wlan0 scan | grep "SSID" | awk \'!a[$0]++\' | cut -d \':\' -f2').split(os.linesep) # scans your deviceses 
    ssids = [ssid.replace('"', '') for ssid in ssids] # remove the exclaimation marks
    if yourSSID in ssids:
        _executeConsoleCommand('sudo nmcli device wifi rescan ifname wlan0 ssid {}'.format(yourSSID)) #you have to call this before you connect  - thats a thing of nmcli
        _executeConsoleCommand('sudo nmcli dev wifi connect {} password "{}" ifname wlan0'.format(yourSSID, yourPassword))
        # now check if your connected 
        ssid_on_interface_wlan0 = 'sudo iw wlan0 info | grep ssid | awk \'{{ print $2 }}\'' 
        if yourSSID in _executeConsoleCommand(ssid_on_interface_wlan0):
            return True
    return False

now you just have to call it frequently.... e.g.:

def run():
    connected = False
    while not connected:
        connected = tryConnect
        time.sleep(10)
run()
0
On
cmd = ["nmcli", "-f",  "SSID,BSSID,ACTIVE", "dev", "wifi", "list"] 
networks = subprocess.Popen(cmd, stdout=subprocess.PIPE)
output, errors = networks.communicate()
print(output.decode("utf-8"))

This will return all active Wi-Fi if your Wi-Fi comes online in this list you can try connecting to it.