#######################################
# Multiple WiFi Networks with CP 9.x.x
#######################################

import os
import wifi
import random
import binascii

#######################################
# Diagnostic
#######################################
print('\f')
print('\t*** Program Start ***')
print('')

#######################################
def scan_sort_wifi(sort_by=1, order=True):
#######################################
    _ = 0
    print("\tAvailable CYW43439KUBG WiFi networks:")
    print(" Seq\tSSID\t\t\t\b\b\bPower  Channel")
    access_points = []
    # Scan for WiFi networks
    for networks in (wifi.radio.start_scanning_networks()):
        s = "."*(20-len(str(networks.ssid, "utf-8")))
        if (len(s)==0):
            s = "*Hidden_SSID*"
            access_points.append((s, networks.rssi, networks.channel))
        else:
            access_points.append((networks.ssid, networks.rssi, networks.channel))
        _ += 1
        #print("%3d\t%s%s %d      %2d" % (_, str(networks.ssid, "utf-8"), s, networks.rssi, networks.channel))
    wifi.radio.stop_scanning_networks()
    # Sort the found networks  Sort by [0]=name, [1]=power, [2]=channel, [3]=No Sort
    if sort_by < 3: sorted_networks = (sorted(access_points, key=lambda _: _[sort_by], reverse=order))
    else: sorted_networks = access_points # Unsorted found networks
    print('')
    # Print the list to REPL
    for _ in range(len(sorted_networks)):
        s = "."*(20-len(str(sorted_networks[_][0], "utf-8")))
        print("%3d\t%s %s %d     %2d" % (
            _+1,
            str(sorted_networks[_][0], "utf-8"),
            s,
            sorted_networks[_][1],
            sorted_networks[_][2]))
    print('')

#######################################
def connect_to_wifi():
#######################################
    # Pick an access point at random 
    ptr = random.randint(0, os.getenv("WIFI_ROUTERS"))
    # Attempt to connect to the WiFi networks in settings.toml
    while not wifi.radio.connected: # Loop while not connected
        try:
            SSID, PASSWORD = os.getenv("WIFI_SSID"+str(ptr)), os.getenv("WIFI_PASSWORD"+str(ptr))
        except:
            SSID, PASSWORD = 'Null', 'Null'
        if(SSID == None) or (PASSWORD == None):
            SSID, PASSWORD = 'Nope', 'Nope'
        s = 30-(len(SSID) + len(PASSWORD))
        if ptr < 10: print(' ', end='')
        print(ptr, SSID, PASSWORD, '.'*s, end=' ')
        try:
            print('WiFi Connecting.', end='')
            wifi.radio.connect(SSID, PASSWORD)
        except:
            ptr += 1
            ptr = (ptr % os.getenv("WIFI_ROUTERS"))
            print('\b\b\bon Failed.')
    print('\b\b\b\bed, Hurray!') # We are connected
    IP      = wifi.radio.ipv4_address
    Mask    = wifi.radio.ipv4_subnet
    Gateway = wifi.radio.ipv4_gateway
    DNS     = wifi.radio.ipv4_dns
    hostname= wifi.radio.hostname
    power   = wifi.radio.tx_power
    print("\n\t\tWiFi Connection Information:\n    SSID:", SSID, ' ~  IP:', IP, ' ~  Mask:', Mask, ' ~')
    print('\tGateway:', Gateway, ' ~  DNS:', DNS, ' ~  HostName:', wifi.radio.hostname, ' ~')
    print('\tRadiated Power: '+str(power)+'mw ~ MAC addr:', end=' ')
    res = (binascii.hexlify(bytearray(wifi.radio.mac_address)))
    for _ in range(0, len(res), 2):
        print(str(res[_:_+2])[2:4].upper(), end=':')
    print('\b \n') # Cleanup

#######################################
# Start of Your code
#######################################
wifi.radio.enabled = True

#######################################
# Scan and show the available WiFi networks, Sort Optional
#######################################
scan_sort_wifi(1, True) # Sort by | 0>name, False | 1>power, True | 2>channel, False, | 3> No Sort 

#######################################
# Attempt to connect
#######################################
# Optional unique HostName
#wifi.radio.tx_power = 63.0 # 1 through 63, 31.75 default
#wifi.radio.hostname = "MultiWiFi"
# Lets go connect to WiFi
connect_to_wifi()

#######################################
# Diagnostics
#######################################
import time
import board
import digitalio
GreenLED = digitalio.DigitalInOut(board.LED)
GreenLED.direction = digitalio.Direction.OUTPUT
GreenLED.value = True

import ipaddress
import supervisor
import microcontroller
addr = "71.179.161.1"#"192.168.12.1"
ip1 = ipaddress.ip_address(addr)
print("pinging", ip1)#, end=' ')
print("ping round trip time:", wifi.radio.ping(ip1), "Seconds")
t = time.time()
while True:
    GreenLED.value = not GreenLED.value
    if (wifi.radio.connected and ((t+10) > time.time())):
        print(' ', time.time(), '\tWe are Good ', end='\r')
        time.sleep(1)
    else:
        print('\n\t\aTimeout/Lost Connection\a')
        time.sleep(1)
        supervisor.reload() # Like Ctrl-C, Ctrl-D
        microcontroller.reset() # Like RESET button or remove/connect power
print('')
print('\t*** Program Finis ***')
'''
>>> import wifi
>>> dir(wifi)
['__class__', '__init__', '__name__', 'AuthMode', 'Monitor', 'Network', 'Packet', 'Radio', 'Station', '__dict__', 'radio']

>>> dir(wifi.radio)
['__class__', 'ap_active', 'connect', 'connected', 'enabled', 'hostname', 'ipv4_address', 'ipv4_address_ap', 'ipv4_dns', 'ipv4_gateway', 'ipv4_gateway_ap', 'ipv4_subnet', 'ipv4_subnet_ap', 'mac_address', 'mac_address_ap', 'ping', 'set_ipv4_address', 'set_ipv4_address_ap', 'start_ap', 'start_dhcp', 'start_dhcp_ap', 'start_scanning_networks', 'start_station', 'stations_ap', 'stop_ap', 'stop_dhcp', 'stop_dhcp_ap', 'stop_scanning_networks', 'stop_station', 'tx_power']
>>>
'''