From 2c098337a2fc3287d1bb7865250eed6745f7e24f Mon Sep 17 00:00:00 2001 From: Stephen Jefferson Date: Thu, 27 Apr 2023 19:04:21 +0100 Subject: [PATCH 1/5] New wifi connect and disconnect --- enviro/__init__.py | 149 ++++++++++++++++++++++++++------------ enviro/config_defaults.py | 5 ++ enviro/config_template.py | 1 + 3 files changed, 110 insertions(+), 45 deletions(-) diff --git a/enviro/__init__.py b/enviro/__init__.py index 236f280..12135d3 100644 --- a/enviro/__init__.py +++ b/enviro/__init__.py @@ -153,56 +153,106 @@ def stop_activity_led(): print(" - -- ---- -----=--==--=== hey enviro, let's go! ===--==--=----- ---- -- - ") print("") +def reconnect_wifi(ssid, password, country): + import time + import network + import math + import rp2 + import ubinascii + + start_ms = time.ticks_ms() + + # Set country + rp2.country(country) + + # Reference: https://datasheets.raspberrypi.com/picow/connecting-to-the-internet-with-pico-w.pdf + CYW43_LINK_DOWN = 0 + CYW43_LINK_JOIN = 1 + CYW43_LINK_NOIP = 2 + CYW43_LINK_UP = 3 + CYW43_LINK_FAIL = -1 + CYW43_LINK_NONET = -2 + CYW43_LINK_BADAUTH = -3 + + status_names = { + CYW43_LINK_DOWN: "Link is down", + CYW43_LINK_JOIN: "Connected to wifi", + CYW43_LINK_NOIP: "Connected to wifi, but no IP address", + CYW43_LINK_UP: "Connect to wifi with an IP address", + CYW43_LINK_FAIL: "Connection failed", + CYW43_LINK_NONET: "No matching SSID found (could be out of range, or down)", + CYW43_LINK_BADAUTH: "Authenticatation failure", + } + + wlan = network.WLAN(network.STA_IF) + + def wlog(message): #replace with enviro logging + print(f"[WLAN] {message}") + + def dump_status(): + status = wlan.status() + wlog(f"active: {1 if wlan.active() else 0}, status: {status} ({status_names[status]})") + return status + + def wait_status(expected_status, *, timeout=10, tick_sleep=0.5): + for i in range(math.ceil(timeout / tick_sleep)): + time.sleep(tick_sleep) + status = dump_status() + if status == expected_status: + return True + if status < 0: + raise Exception(status_names[status]) + return False -import network # TODO this was removed from 0.0.8 -def connect_to_wifi(): - """ TODO what it was changed to - if phew.is_connected_to_wifi(): - logging.info(f"> already connected to wifi") - return True - """ - - wifi_ssid = config.wifi_ssid - wifi_password = config.wifi_password - - logging.info(f"> connecting to wifi network '{wifi_ssid}'") - """ TODO what it was changed to - ip = phew.connect_to_wifi(wifi_ssid, wifi_password, timeout_seconds=30) - - if not ip: - logging.error(f"! failed to connect to wireless network {wifi_ssid}") - return False - - logging.info(" - ip address: ", ip) - """ - import rp2 - rp2.country("GB") - wlan = network.WLAN(network.STA_IF) - wlan.active(True) - wlan.connect(wifi_ssid, wifi_password) - - start = time.ticks_ms() - while time.ticks_diff(time.ticks_ms(), start) < 30000: - if wlan.status() < 0 or wlan.status() >= 3: - break - time.sleep(0.5) + wlan.active(True) + # Disable power saving mode - TODO only do this on USB power/config option + wlan.config(pm=0xa11140) - seconds_to_connect = int(time.ticks_diff(time.ticks_ms(), start) / 1000) + # Print MAC + mac = ubinascii.hexlify(wlan.config('mac'),':').decode() + wlog("MAC: " + mac) + + # Disconnect when necessary + status = dump_status() + if status >= CYW43_LINK_JOIN and status <= CYW43_LINK_UP: + wlog("Disconnecting...") + wlan.disconnect() + try: + wait_status(CYW43_LINK_DOWN) + except Exception as x: + raise Exception(f"Failed to disconnect: {x}") + wlog("Ready for connection!") + + # Connect to our AP + wlog(f"Connecting to SSID {ssid} (password: {password})...") + wlan.connect(ssid, password) + try: + wait_status(CYW43_LINK_UP) + except Exception as x: + raise Exception(f"Failed to connect to SSID {ssid} (password: {password}): {x}") + wlog("Connected successfully!") + + ip, subnet, gateway, dns = wlan.ifconfig() + wlog(f"IP: {ip}, Subnet: {subnet}, Gateway: {gateway}, DNS: {dns}") + + elapsed_ms = time.ticks_ms() - start_ms + wlog(f"Elapsed: {elapsed_ms}ms") + return elapsed_ms - if wlan.status() != 3: - logging.error(f"! failed to connect to wireless network {wifi_ssid}") +def connect_to_wifi(): + try: + logging.info(f"> connecting to wifi network '{config.wifi_ssid}'") + elapsed_ms = reconnect_wifi(config.wifi_ssid, config.wifi_password, config.wifi_country) + # a slow connection time will drain the battery faster and may + # indicate a poor quality connection + seconds_to_connect = elapsed_ms / 1000 + if seconds_to_connect > 5: + logging.warn(" - took", seconds_to_connect, "seconds to connect to wifi") + return True + except Exception as x: + logging.error(f"! {x}") return False - # a slow connection time will drain the battery faster and may - # indicate a poor quality connection - if seconds_to_connect > 5: - logging.warn(" - took", seconds_to_connect, "seconds to connect to wifi") - - ip_address = wlan.ifconfig()[0] - logging.info(" - ip address: ", ip_address) - - return True - # log the error, blink the warning led, and go back to sleep def halt(message): logging.error(message) @@ -464,6 +514,15 @@ def upload_readings(): logging.error(f"! cannot find destination {destination}") return False + finally: + # Disconnect wifi + import network + print("[WLAN] Disconnecting after upload") + wlan = network.WLAN(network.STA_IF) + wlan.active(True) + wlan.disconnect() + wlan.active(False) + return True def startup(): diff --git a/enviro/config_defaults.py b/enviro/config_defaults.py index cfdf5dd..63a5877 100644 --- a/enviro/config_defaults.py +++ b/enviro/config_defaults.py @@ -18,6 +18,11 @@ def add_missing_config_settings(): warn_missing_config_setting("usb_power_temperature_offset") config.usb_power_temperature_offset = DEFAULT_USB_POWER_TEMPERATURE_OFFSET + try: + config.wifi_country + except AttributeError: + warn_missing_config_setting("wifi_country") + config.wifi_country = "GB" def warn_missing_config_setting(setting): logging.warn(f"> config setting '{setting}' missing, please add it to config.py") diff --git a/enviro/config_template.py b/enviro/config_template.py index a345cc0..11404a9 100644 --- a/enviro/config_template.py +++ b/enviro/config_template.py @@ -11,6 +11,7 @@ # network access details wifi_ssid = None wifi_password = None +wifi_country = "GB" # how often to wake up and take a reading (in minutes) reading_frequency = 15 From 7a665b871db76bcd28a2540893eaf6ec9e5f5921 Mon Sep 17 00:00:00 2001 From: Stephen Jefferson Date: Mon, 21 Aug 2023 16:55:31 +0100 Subject: [PATCH 2/5] Disable power saving on wifi only on USB power --- enviro/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/enviro/__init__.py b/enviro/__init__.py index 12135d3..82044e9 100644 --- a/enviro/__init__.py +++ b/enviro/__init__.py @@ -194,6 +194,7 @@ def dump_status(): wlog(f"active: {1 if wlan.active() else 0}, status: {status} ({status_names[status]})") return status + # Return True on expected status, exception on error status (negative) and False on timeout def wait_status(expected_status, *, timeout=10, tick_sleep=0.5): for i in range(math.ceil(timeout / tick_sleep)): time.sleep(tick_sleep) @@ -205,8 +206,9 @@ def wait_status(expected_status, *, timeout=10, tick_sleep=0.5): return False wlan.active(True) - # Disable power saving mode - TODO only do this on USB power/config option - wlan.config(pm=0xa11140) + # Disable power saving mode if on USB power + if vbus_present: + wlan.config(pm=0xa11140) # Print MAC mac = ubinascii.hexlify(wlan.config('mac'),':').decode() From bf21ecd83e68d97a8b38e1f09e2af806b25f3b73 Mon Sep 17 00:00:00 2001 From: Stephen Jefferson Date: Mon, 21 Aug 2023 17:00:19 +0100 Subject: [PATCH 3/5] Adjust wlog to logging used elsewhere --- enviro/__init__.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/enviro/__init__.py b/enviro/__init__.py index 82044e9..ae07ecf 100644 --- a/enviro/__init__.py +++ b/enviro/__init__.py @@ -186,12 +186,9 @@ def reconnect_wifi(ssid, password, country): wlan = network.WLAN(network.STA_IF) - def wlog(message): #replace with enviro logging - print(f"[WLAN] {message}") - def dump_status(): status = wlan.status() - wlog(f"active: {1 if wlan.active() else 0}, status: {status} ({status_names[status]})") + logging.info(f"> active: {1 if wlan.active() else 0}, status: {status} ({status_names[status]})") return status # Return True on expected status, exception on error status (negative) and False on timeout @@ -212,33 +209,33 @@ def wait_status(expected_status, *, timeout=10, tick_sleep=0.5): # Print MAC mac = ubinascii.hexlify(wlan.config('mac'),':').decode() - wlog("MAC: " + mac) + logging.info("> MAC: " + mac) # Disconnect when necessary status = dump_status() if status >= CYW43_LINK_JOIN and status <= CYW43_LINK_UP: - wlog("Disconnecting...") + logging.info("> Disconnecting...") wlan.disconnect() try: wait_status(CYW43_LINK_DOWN) except Exception as x: raise Exception(f"Failed to disconnect: {x}") - wlog("Ready for connection!") + logging.info("> Ready for connection!") # Connect to our AP - wlog(f"Connecting to SSID {ssid} (password: {password})...") + logging.info(f"> Connecting to SSID {ssid} (password: {password})...") wlan.connect(ssid, password) try: wait_status(CYW43_LINK_UP) except Exception as x: raise Exception(f"Failed to connect to SSID {ssid} (password: {password}): {x}") - wlog("Connected successfully!") + logging.info("> Connected successfully!") ip, subnet, gateway, dns = wlan.ifconfig() - wlog(f"IP: {ip}, Subnet: {subnet}, Gateway: {gateway}, DNS: {dns}") + logging.info(f"> IP: {ip}, Subnet: {subnet}, Gateway: {gateway}, DNS: {dns}") elapsed_ms = time.ticks_ms() - start_ms - wlog(f"Elapsed: {elapsed_ms}ms") + logging.info(f"> Elapsed: {elapsed_ms}ms") return elapsed_ms def connect_to_wifi(): @@ -519,7 +516,7 @@ def upload_readings(): finally: # Disconnect wifi import network - print("[WLAN] Disconnecting after upload") + logging.info("> Disconnecting wireless after upload") wlan = network.WLAN(network.STA_IF) wlan.active(True) wlan.disconnect() From 21e0a1808cf382d43de24f9ca781f06547478565 Mon Sep 17 00:00:00 2001 From: Stephen Jefferson Date: Sun, 10 Sep 2023 16:44:37 +0100 Subject: [PATCH 4/5] Adjusted tabs to 2 spaces --- enviro/__init__.py | 152 ++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/enviro/__init__.py b/enviro/__init__.py index ae07ecf..415c1ed 100644 --- a/enviro/__init__.py +++ b/enviro/__init__.py @@ -154,89 +154,89 @@ def stop_activity_led(): print("") def reconnect_wifi(ssid, password, country): - import time - import network - import math - import rp2 - import ubinascii - - start_ms = time.ticks_ms() - - # Set country - rp2.country(country) - - # Reference: https://datasheets.raspberrypi.com/picow/connecting-to-the-internet-with-pico-w.pdf - CYW43_LINK_DOWN = 0 - CYW43_LINK_JOIN = 1 - CYW43_LINK_NOIP = 2 - CYW43_LINK_UP = 3 - CYW43_LINK_FAIL = -1 - CYW43_LINK_NONET = -2 - CYW43_LINK_BADAUTH = -3 - - status_names = { - CYW43_LINK_DOWN: "Link is down", - CYW43_LINK_JOIN: "Connected to wifi", - CYW43_LINK_NOIP: "Connected to wifi, but no IP address", - CYW43_LINK_UP: "Connect to wifi with an IP address", - CYW43_LINK_FAIL: "Connection failed", - CYW43_LINK_NONET: "No matching SSID found (could be out of range, or down)", - CYW43_LINK_BADAUTH: "Authenticatation failure", - } + import time + import network + import math + import rp2 + import ubinascii + + start_ms = time.ticks_ms() + + # Set country + rp2.country(country) + + # Reference: https://datasheets.raspberrypi.com/picow/connecting-to-the-internet-with-pico-w.pdf + CYW43_LINK_DOWN = 0 + CYW43_LINK_JOIN = 1 + CYW43_LINK_NOIP = 2 + CYW43_LINK_UP = 3 + CYW43_LINK_FAIL = -1 + CYW43_LINK_NONET = -2 + CYW43_LINK_BADAUTH = -3 + + status_names = { + CYW43_LINK_DOWN: "Link is down", + CYW43_LINK_JOIN: "Connected to wifi", + CYW43_LINK_NOIP: "Connected to wifi, but no IP address", + CYW43_LINK_UP: "Connect to wifi with an IP address", + CYW43_LINK_FAIL: "Connection failed", + CYW43_LINK_NONET: "No matching SSID found (could be out of range, or down)", + CYW43_LINK_BADAUTH: "Authenticatation failure", + } - wlan = network.WLAN(network.STA_IF) + wlan = network.WLAN(network.STA_IF) - def dump_status(): - status = wlan.status() - logging.info(f"> active: {1 if wlan.active() else 0}, status: {status} ({status_names[status]})") - return status - - # Return True on expected status, exception on error status (negative) and False on timeout - def wait_status(expected_status, *, timeout=10, tick_sleep=0.5): - for i in range(math.ceil(timeout / tick_sleep)): - time.sleep(tick_sleep) - status = dump_status() - if status == expected_status: - return True - if status < 0: - raise Exception(status_names[status]) - return False + def dump_status(): + status = wlan.status() + logging.info(f"> active: {1 if wlan.active() else 0}, status: {status} ({status_names[status]})") + return status - wlan.active(True) - # Disable power saving mode if on USB power - if vbus_present: - wlan.config(pm=0xa11140) + # Return True on expected status, exception on error status (negative) and False on timeout + def wait_status(expected_status, *, timeout=10, tick_sleep=0.5): + for i in range(math.ceil(timeout / tick_sleep)): + time.sleep(tick_sleep) + status = dump_status() + if status == expected_status: + return True + if status < 0: + raise Exception(status_names[status]) + return False - # Print MAC - mac = ubinascii.hexlify(wlan.config('mac'),':').decode() - logging.info("> MAC: " + mac) - - # Disconnect when necessary - status = dump_status() - if status >= CYW43_LINK_JOIN and status <= CYW43_LINK_UP: - logging.info("> Disconnecting...") - wlan.disconnect() - try: - wait_status(CYW43_LINK_DOWN) - except Exception as x: - raise Exception(f"Failed to disconnect: {x}") - logging.info("> Ready for connection!") - - # Connect to our AP - logging.info(f"> Connecting to SSID {ssid} (password: {password})...") - wlan.connect(ssid, password) + wlan.active(True) + # Disable power saving mode if on USB power + if vbus_present: + wlan.config(pm=0xa11140) + + # Print MAC + mac = ubinascii.hexlify(wlan.config('mac'),':').decode() + logging.info("> MAC: " + mac) + + # Disconnect when necessary + status = dump_status() + if status >= CYW43_LINK_JOIN and status <= CYW43_LINK_UP: + logging.info("> Disconnecting...") + wlan.disconnect() try: - wait_status(CYW43_LINK_UP) + wait_status(CYW43_LINK_DOWN) except Exception as x: - raise Exception(f"Failed to connect to SSID {ssid} (password: {password}): {x}") - logging.info("> Connected successfully!") + raise Exception(f"Failed to disconnect: {x}") + logging.info("> Ready for connection!") - ip, subnet, gateway, dns = wlan.ifconfig() - logging.info(f"> IP: {ip}, Subnet: {subnet}, Gateway: {gateway}, DNS: {dns}") - - elapsed_ms = time.ticks_ms() - start_ms - logging.info(f"> Elapsed: {elapsed_ms}ms") - return elapsed_ms + # Connect to our AP + logging.info(f"> Connecting to SSID {ssid} (password: {password})...") + wlan.connect(ssid, password) + try: + wait_status(CYW43_LINK_UP) + except Exception as x: + raise Exception(f"Failed to connect to SSID {ssid} (password: {password}): {x}") + logging.info("> Connected successfully!") + + ip, subnet, gateway, dns = wlan.ifconfig() + logging.info(f"> IP: {ip}, Subnet: {subnet}, Gateway: {gateway}, DNS: {dns}") + + elapsed_ms = time.ticks_ms() - start_ms + logging.info(f"> Elapsed: {elapsed_ms}ms") + return elapsed_ms def connect_to_wifi(): try: From de9510bea64399fd47cc01f32175cc4ea073414c Mon Sep 17 00:00:00 2001 From: Stephen Jefferson Date: Mon, 22 Apr 2024 13:57:04 +0100 Subject: [PATCH 5/5] Fix online check to keep connected in state 3 Online check was incorrectly including state 3 (Connected with IP) as a condition to disconnect and retry, adjusted to include only state numbers below this. --- enviro/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enviro/__init__.py b/enviro/__init__.py index 415c1ed..72d6df8 100644 --- a/enviro/__init__.py +++ b/enviro/__init__.py @@ -213,7 +213,7 @@ def wait_status(expected_status, *, timeout=10, tick_sleep=0.5): # Disconnect when necessary status = dump_status() - if status >= CYW43_LINK_JOIN and status <= CYW43_LINK_UP: + if status >= CYW43_LINK_JOIN and status < CYW43_LINK_UP: logging.info("> Disconnecting...") wlan.disconnect() try: