2018-07-15 06:53:48 -04:00
|
|
|
"""Handles connecting to a wifi access point based on a valid wifi.json file"""
|
|
|
|
|
|
|
|
___license___ = "MIT"
|
2018-08-18 17:18:22 -04:00
|
|
|
___dependencies___ = ["dialogs", "sleep"]
|
2018-07-15 06:53:48 -04:00
|
|
|
|
2018-08-18 17:18:22 -04:00
|
|
|
import network, os, json, dialogs, sleep, time
|
2018-07-15 06:53:48 -04:00
|
|
|
|
|
|
|
_nic = None
|
|
|
|
|
|
|
|
def nic():
|
|
|
|
global _nic
|
|
|
|
if not _nic:
|
2018-08-18 17:18:22 -04:00
|
|
|
_nic = network.WLAN()
|
|
|
|
_nic.active(True)
|
2018-07-15 06:53:48 -04:00
|
|
|
return _nic
|
|
|
|
|
|
|
|
def connection_details():
|
|
|
|
data = None
|
|
|
|
try:
|
|
|
|
if "wifi.json" in os.listdir():
|
|
|
|
with open("wifi.json") as f:
|
|
|
|
data = json.loads(f.read())
|
|
|
|
if 'ssid' not in data or not data['ssid']:
|
|
|
|
data = None
|
|
|
|
except ValueError as e:
|
|
|
|
print(e)
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
def ssid():
|
|
|
|
return connection_details()["ssid"]
|
|
|
|
|
|
|
|
def connect(wait=True, timeout=10, show_wait_message=False, prompt_on_fail=True, dialog_title='TiLDA'):
|
2018-08-21 15:47:39 -04:00
|
|
|
while True:
|
2018-08-18 17:18:22 -04:00
|
|
|
if nic().isconnected():
|
2018-07-15 06:53:48 -04:00
|
|
|
return
|
|
|
|
|
|
|
|
details = connection_details()
|
|
|
|
if not details:
|
|
|
|
if prompt_on_fail:
|
|
|
|
choose_wifi(dialog_title=dialog_title)
|
|
|
|
else:
|
|
|
|
raise OSError("No valid wifi configuration")
|
|
|
|
|
|
|
|
if not wait:
|
|
|
|
connect_wifi(details, timeout=None, wait=False)
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
if show_wait_message:
|
|
|
|
with dialogs.WaitingMessage(text="Connecting to '%s'...\n(%ss timeout)" % (details['ssid'], timeout), title=dialog_title):
|
|
|
|
connect_wifi(details, timeout=timeout, wait=True)
|
|
|
|
else:
|
|
|
|
connect_wifi(details, timeout=timeout, wait=True)
|
|
|
|
except OSError:
|
|
|
|
if prompt_on_fail:
|
|
|
|
retry_connect = dialogs.prompt_boolean(
|
|
|
|
text="Failed to connect to '%s'" % details['ssid'],
|
|
|
|
title=dialog_title,
|
|
|
|
true_text="Try again",
|
2018-08-21 15:47:39 -04:00
|
|
|
false_text="Change it",
|
2018-07-15 06:53:48 -04:00
|
|
|
)
|
|
|
|
if not retry_connect:
|
|
|
|
os.remove('wifi.json')
|
|
|
|
os.sync()
|
2018-08-18 17:18:22 -04:00
|
|
|
|
2018-07-15 06:53:48 -04:00
|
|
|
else:
|
|
|
|
raise
|
|
|
|
|
|
|
|
def connect_wifi(details, timeout, wait=False):
|
2018-08-29 10:06:51 -04:00
|
|
|
if 'user' in details:
|
2018-08-29 14:13:03 -04:00
|
|
|
nic().connect(details['ssid'], details['pw'], enterprise=True, entuser=details['user'], entmethod=nic().EAP_METHOD_PEAP0_MSCHAPv2, entserverauth=False)
|
2018-08-29 10:06:51 -04:00
|
|
|
elif 'pw' in details:
|
2018-08-18 17:18:22 -04:00
|
|
|
nic().connect(details['ssid'], details['pw'])
|
2018-07-15 06:53:48 -04:00
|
|
|
else:
|
2018-08-18 17:18:22 -04:00
|
|
|
nic().connect(details['ssid'])
|
2018-07-15 06:53:48 -04:00
|
|
|
|
|
|
|
if wait:
|
2018-08-21 15:47:39 -04:00
|
|
|
wait_until = time.ticks_ms() + timeout * 1000
|
2018-08-18 17:18:22 -04:00
|
|
|
while not nic().isconnected():
|
|
|
|
#nic().update() # todo: do we need this?
|
|
|
|
if (time.ticks_ms() > wait_until):
|
2018-08-21 15:47:39 -04:00
|
|
|
raise OSError("Timeout while trying to connect to wifi")
|
2018-08-18 17:18:22 -04:00
|
|
|
sleep.sleep_ms(100)
|
|
|
|
|
2018-07-15 06:53:48 -04:00
|
|
|
|
|
|
|
def is_connected():
|
2018-08-18 17:18:22 -04:00
|
|
|
return nic().isconnected()
|
2018-07-15 06:53:48 -04:00
|
|
|
|
2018-08-31 09:22:55 -04:00
|
|
|
# returns wifi strength in %, None if unavailable
|
2018-08-29 07:38:59 -04:00
|
|
|
def get_strength():
|
|
|
|
n = nic()
|
|
|
|
if n.isconnected():
|
2018-08-31 09:22:55 -04:00
|
|
|
v = n.status("rssi");
|
|
|
|
if v:
|
|
|
|
# linear range: -60 =100%; -100= 20%
|
|
|
|
# todo: it's probably not linear, improve me.
|
|
|
|
return v * 2 + 220
|
|
|
|
return None
|
2018-08-29 07:38:59 -04:00
|
|
|
|
2018-07-15 06:53:48 -04:00
|
|
|
def get_security_level(ap):
|
2018-08-21 15:47:39 -04:00
|
|
|
#todo: fix this
|
2018-07-15 06:53:48 -04:00
|
|
|
n = nic()
|
2018-08-29 07:38:59 -04:00
|
|
|
levels = {
|
|
|
|
n.SCAN_SEC_OPEN: 0, # I am awful
|
|
|
|
n.SCAN_SEC_WEP: 'WEP',
|
|
|
|
n.SCAN_SEC_WPA: 'WPA',
|
|
|
|
n.SCAN_SEC_WPA2: 'WPA2',
|
|
|
|
}
|
2018-07-15 06:53:48 -04:00
|
|
|
|
|
|
|
return levels.get(ap.get('security', None), None)
|
|
|
|
|
|
|
|
def choose_wifi(dialog_title='TiLDA'):
|
|
|
|
filtered_aps = []
|
|
|
|
with dialogs.WaitingMessage(text='Scanning for networks...', title=dialog_title):
|
2018-08-21 15:47:39 -04:00
|
|
|
visible_aps = None
|
|
|
|
while not visible_aps:
|
|
|
|
visible_aps = nic().scan()
|
|
|
|
print(visible_aps)
|
|
|
|
sleep.sleep_ms(300)
|
|
|
|
#todo: timeout
|
|
|
|
visible_aps.sort(key=lambda x:x[3], reverse=True)
|
2018-07-15 06:53:48 -04:00
|
|
|
# We'll get one result for each AP, so filter dupes
|
|
|
|
for ap in visible_aps:
|
2018-08-21 15:47:39 -04:00
|
|
|
title = ap[0]
|
|
|
|
security = "?" # todo: re-add get_security_level(ap)
|
2018-07-15 06:53:48 -04:00
|
|
|
if security:
|
|
|
|
title = title + ' (%s)' % security
|
|
|
|
ap = {
|
|
|
|
'title': title,
|
2018-08-21 15:47:39 -04:00
|
|
|
'ssid': ap[0],
|
|
|
|
'security': ap[4],
|
2018-07-15 06:53:48 -04:00
|
|
|
}
|
|
|
|
if ap['ssid'] not in [ a['ssid'] for a in filtered_aps ]:
|
|
|
|
filtered_aps.append(ap)
|
|
|
|
del visible_aps
|
|
|
|
|
|
|
|
ap = dialogs.prompt_option(
|
|
|
|
filtered_aps,
|
|
|
|
text='Choose wifi network',
|
|
|
|
title=dialog_title
|
|
|
|
)
|
|
|
|
if ap:
|
|
|
|
key = None
|
|
|
|
if ap['security'] != 0:
|
|
|
|
# Backward compat
|
|
|
|
if ap['security'] == None:
|
|
|
|
ap['security'] = 'wifi'
|
|
|
|
|
2018-08-29 07:38:59 -04:00
|
|
|
key = dialogs.prompt_text("Enter %s key" % ap['security'])
|
2018-07-15 06:53:48 -04:00
|
|
|
with open("wifi.json", "wt") as file:
|
|
|
|
if key:
|
|
|
|
conn_details = {"ssid": ap['ssid'], "pw": key}
|
|
|
|
else:
|
|
|
|
conn_details = {"ssid": ap['ssid']}
|
|
|
|
|
|
|
|
file.write(json.dumps(conn_details))
|
|
|
|
os.sync()
|
2018-08-18 17:18:22 -04:00
|
|
|
# todo: last time we had to hard reset here, is that still the case?
|