You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
WiFi app: delegate to WiFiService where possible
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
import time
|
||||
import lvgl as lv
|
||||
import _thread
|
||||
@@ -6,25 +5,24 @@ import _thread
|
||||
from mpos.apps import Activity, Intent
|
||||
from mpos.ui.keyboard import MposKeyboard
|
||||
|
||||
import mpos.config
|
||||
import mpos.apps
|
||||
from mpos.net.wifi_service import WifiService
|
||||
|
||||
class WiFi(Activity):
|
||||
|
||||
prefs = None
|
||||
saved_access_points={}
|
||||
class WiFi(Activity):
|
||||
"""
|
||||
WiFi settings app for MicroPythonOS.
|
||||
|
||||
This is a pure UI layer - all WiFi operations are delegated to WifiService.
|
||||
"""
|
||||
|
||||
last_tried_ssid = ""
|
||||
last_tried_result = ""
|
||||
have_network = True
|
||||
try:
|
||||
import network
|
||||
except Exception as e:
|
||||
have_network = False
|
||||
|
||||
scan_button_scan_text = "Rescan"
|
||||
scan_button_scanning_text = "Scanning..."
|
||||
|
||||
scanned_ssids=[]
|
||||
scanned_ssids = []
|
||||
busy_scanning = False
|
||||
busy_connecting = False
|
||||
error_timer = None
|
||||
@@ -39,25 +37,25 @@ class WiFi(Activity):
|
||||
print("wifi.py onCreate")
|
||||
main_screen = lv.obj()
|
||||
main_screen.set_style_pad_all(15, 0)
|
||||
self.aplist=lv.list(main_screen)
|
||||
self.aplist.set_size(lv.pct(100),lv.pct(75))
|
||||
self.aplist.align(lv.ALIGN.TOP_MID,0,0)
|
||||
self.error_label=lv.label(main_screen)
|
||||
self.aplist = lv.list(main_screen)
|
||||
self.aplist.set_size(lv.pct(100), lv.pct(75))
|
||||
self.aplist.align(lv.ALIGN.TOP_MID, 0, 0)
|
||||
self.error_label = lv.label(main_screen)
|
||||
self.error_label.set_text("THIS IS ERROR TEXT THAT WILL BE SET LATER")
|
||||
self.error_label.align_to(self.aplist, lv.ALIGN.OUT_BOTTOM_MID,0,0)
|
||||
self.error_label.align_to(self.aplist, lv.ALIGN.OUT_BOTTOM_MID, 0, 0)
|
||||
self.error_label.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
self.add_network_button=lv.button(main_screen)
|
||||
self.add_network_button.set_size(lv.SIZE_CONTENT,lv.pct(15))
|
||||
self.add_network_button.align(lv.ALIGN.BOTTOM_LEFT,0,0)
|
||||
self.add_network_button.add_event_cb(self.add_network_callback,lv.EVENT.CLICKED,None)
|
||||
self.add_network_button_label=lv.label(self.add_network_button)
|
||||
self.add_network_button = lv.button(main_screen)
|
||||
self.add_network_button.set_size(lv.SIZE_CONTENT, lv.pct(15))
|
||||
self.add_network_button.align(lv.ALIGN.BOTTOM_LEFT, 0, 0)
|
||||
self.add_network_button.add_event_cb(self.add_network_callback, lv.EVENT.CLICKED, None)
|
||||
self.add_network_button_label = lv.label(self.add_network_button)
|
||||
self.add_network_button_label.set_text("Add network")
|
||||
self.add_network_button_label.center()
|
||||
self.scan_button=lv.button(main_screen)
|
||||
self.scan_button.set_size(lv.SIZE_CONTENT,lv.pct(15))
|
||||
self.scan_button.align(lv.ALIGN.BOTTOM_RIGHT,0,0)
|
||||
self.scan_button.add_event_cb(self.scan_cb,lv.EVENT.CLICKED,None)
|
||||
self.scan_button_label=lv.label(self.scan_button)
|
||||
self.scan_button = lv.button(main_screen)
|
||||
self.scan_button.set_size(lv.SIZE_CONTENT, lv.pct(15))
|
||||
self.scan_button.align(lv.ALIGN.BOTTOM_RIGHT, 0, 0)
|
||||
self.scan_button.add_event_cb(self.scan_cb, lv.EVENT.CLICKED, None)
|
||||
self.scan_button_label = lv.label(self.scan_button)
|
||||
self.scan_button_label.set_text(self.scan_button_scan_text)
|
||||
self.scan_button_label.center()
|
||||
self.setContentView(main_screen)
|
||||
@@ -66,11 +64,9 @@ class WiFi(Activity):
|
||||
print("wifi.py onResume")
|
||||
super().onResume(screen)
|
||||
|
||||
if not self.prefs:
|
||||
self.prefs = mpos.config.SharedPreferences("com.micropythonos.system.wifiservice")
|
||||
# Ensure WifiService has loaded saved networks
|
||||
WifiService.get_saved_networks()
|
||||
|
||||
self.saved_access_points = self.prefs.get_dict("access_points")
|
||||
print(f"loaded access points from preferences: {self.saved_access_points}")
|
||||
if len(self.scanned_ssids) == 0:
|
||||
if WifiService.wifi_busy == False:
|
||||
WifiService.wifi_busy = True
|
||||
@@ -83,26 +79,16 @@ class WiFi(Activity):
|
||||
print(f"show_error: Displaying error: {message}")
|
||||
self.update_ui_threadsafe_if_foreground(self.error_label.set_text, message)
|
||||
self.update_ui_threadsafe_if_foreground(self.error_label.remove_flag, lv.obj.FLAG.HIDDEN)
|
||||
self.error_timer = lv.timer_create(self.hide_error,5000,None)
|
||||
self.error_timer = lv.timer_create(self.hide_error, 5000, None)
|
||||
self.error_timer.set_repeat_count(1)
|
||||
|
||||
def hide_error(self, timer):
|
||||
self.update_ui_threadsafe_if_foreground(self.error_label.add_flag,lv.obj.FLAG.HIDDEN)
|
||||
self.update_ui_threadsafe_if_foreground(self.error_label.add_flag, lv.obj.FLAG.HIDDEN)
|
||||
|
||||
def scan_networks_thread(self):
|
||||
print("scan_networks: Scanning for Wi-Fi networks")
|
||||
if self.have_network:
|
||||
wlan=network.WLAN(network.STA_IF)
|
||||
if not wlan.isconnected(): # restart WiFi hardware in case it's in a bad state
|
||||
wlan.active(False)
|
||||
wlan.active(True)
|
||||
try:
|
||||
if self.have_network:
|
||||
networks = wlan.scan()
|
||||
self.scanned_ssids = list(set(n[0].decode() for n in networks))
|
||||
else:
|
||||
time.sleep(1)
|
||||
self.scanned_ssids = ["Home WiFi", "Pretty Fly for a Wi Fi", "Winternet is coming", "The Promised LAN"]
|
||||
self.scanned_ssids = WifiService.scan_networks()
|
||||
print(f"scan_networks: Found networks: {self.scanned_ssids}")
|
||||
except Exception as e:
|
||||
print(f"scan_networks: Scan failed: {e}")
|
||||
@@ -110,7 +96,7 @@ class WiFi(Activity):
|
||||
# scan done:
|
||||
self.busy_scanning = False
|
||||
WifiService.wifi_busy = False
|
||||
self.update_ui_threadsafe_if_foreground(self.scan_button_label.set_text,self.scan_button_scan_text)
|
||||
self.update_ui_threadsafe_if_foreground(self.scan_button_label.set_text, self.scan_button_scan_text)
|
||||
self.update_ui_threadsafe_if_foreground(self.scan_button.remove_state, lv.STATE.DISABLED)
|
||||
self.update_ui_threadsafe_if_foreground(self.refresh_list)
|
||||
|
||||
@@ -126,28 +112,35 @@ class WiFi(Activity):
|
||||
|
||||
def refresh_list(self):
|
||||
print("refresh_list: Clearing current list")
|
||||
self.aplist.clean() # this causes an issue with lost taps if an ssid is clicked that has been removed
|
||||
self.aplist.clean() # this causes an issue with lost taps if an ssid is clicked that has been removed
|
||||
print("refresh_list: Populating list with scanned networks")
|
||||
for ssid in set(self.scanned_ssids + list(ssid for ssid in self.saved_access_points)):
|
||||
|
||||
# Combine scanned SSIDs with saved networks
|
||||
saved_networks = WifiService.get_saved_networks()
|
||||
all_ssids = set(self.scanned_ssids + saved_networks)
|
||||
|
||||
for ssid in all_ssids:
|
||||
if len(ssid) < 1 or len(ssid) > 32:
|
||||
print(f"Skipping too short or long SSID: {ssid}")
|
||||
continue
|
||||
print(f"refresh_list: Adding SSID: {ssid}")
|
||||
button=self.aplist.add_button(None,ssid)
|
||||
button.add_event_cb(lambda e, s=ssid: self.select_ssid_cb(s),lv.EVENT.CLICKED,None)
|
||||
button = self.aplist.add_button(None, ssid)
|
||||
button.add_event_cb(lambda e, s=ssid: self.select_ssid_cb(s), lv.EVENT.CLICKED, None)
|
||||
|
||||
# Determine status
|
||||
status = ""
|
||||
if self.have_network:
|
||||
wlan=network.WLAN(network.STA_IF)
|
||||
if wlan.isconnected() and wlan.config('essid')==ssid:
|
||||
status="connected"
|
||||
if status != "connected":
|
||||
if self.last_tried_ssid == ssid: # implies not connected because not wlan.isconnected()
|
||||
status = self.last_tried_result
|
||||
elif ssid in self.saved_access_points:
|
||||
status="saved"
|
||||
label=lv.label(button)
|
||||
current_ssid = WifiService.get_current_ssid()
|
||||
if current_ssid == ssid:
|
||||
status = "connected"
|
||||
elif self.last_tried_ssid == ssid:
|
||||
# Show last connection attempt result
|
||||
status = self.last_tried_result
|
||||
elif ssid in saved_networks:
|
||||
status = "saved"
|
||||
|
||||
label = lv.label(button)
|
||||
label.set_text(status)
|
||||
label.align(lv.ALIGN.RIGHT_MID,0,0)
|
||||
label.align(lv.ALIGN.RIGHT_MID, 0, 0)
|
||||
|
||||
def add_network_callback(self, event):
|
||||
print(f"add_network_callback clicked")
|
||||
@@ -159,36 +152,28 @@ class WiFi(Activity):
|
||||
print("scan_cb: Scan button clicked, refreshing list")
|
||||
self.start_scan_networks()
|
||||
|
||||
def select_ssid_cb(self,ssid):
|
||||
def select_ssid_cb(self, ssid):
|
||||
print(f"select_ssid_cb: SSID selected: {ssid}")
|
||||
intent = Intent(activity_class=EditNetwork)
|
||||
intent.putExtra("selected_ssid", ssid)
|
||||
intent.putExtra("known_password", self.findSavedPassword(ssid))
|
||||
intent.putExtra("known_password", WifiService.get_network_password(ssid))
|
||||
self.startActivityForResult(intent, self.edit_network_result_callback)
|
||||
|
||||
|
||||
def edit_network_result_callback(self, result):
|
||||
print(f"EditNetwork finished, result: {result}")
|
||||
if result.get("result_code") is True:
|
||||
data = result.get("data")
|
||||
if data:
|
||||
ssid = data.get("ssid")
|
||||
editor = self.prefs.edit()
|
||||
forget = data.get("forget")
|
||||
if forget:
|
||||
try:
|
||||
del self.saved_access_points[ssid]
|
||||
editor.put_dict("access_points", self.saved_access_points)
|
||||
editor.commit()
|
||||
self.refresh_list()
|
||||
except Exception as e:
|
||||
print(f"WARNING: could not forget access point, maybe it wasn't remembered in the first place: {e}")
|
||||
else: # save or update
|
||||
WifiService.forget_network(ssid)
|
||||
self.refresh_list()
|
||||
else:
|
||||
# Save or update the network
|
||||
password = data.get("password")
|
||||
hidden = data.get("hidden")
|
||||
self.setPassword(ssid, password, hidden)
|
||||
editor.put_dict("access_points", self.saved_access_points)
|
||||
editor.commit()
|
||||
print(f"access points: {self.saved_access_points}")
|
||||
WifiService.save_network(ssid, password, hidden)
|
||||
self.start_attempt_connecting(ssid, password)
|
||||
|
||||
def start_attempt_connecting(self, ssid, password):
|
||||
@@ -200,58 +185,32 @@ class WiFi(Activity):
|
||||
else:
|
||||
self.busy_connecting = True
|
||||
_thread.stack_size(mpos.apps.good_stack_size())
|
||||
_thread.start_new_thread(self.attempt_connecting_thread, (ssid,password))
|
||||
_thread.start_new_thread(self.attempt_connecting_thread, (ssid, password))
|
||||
|
||||
def attempt_connecting_thread(self, ssid, password):
|
||||
print(f"attempt_connecting_thread: Attempting to connect to SSID '{ssid}' with password '{password}'")
|
||||
result="connected"
|
||||
print(f"attempt_connecting_thread: Attempting to connect to SSID '{ssid}'")
|
||||
result = "connected"
|
||||
try:
|
||||
if self.have_network:
|
||||
wlan=network.WLAN(network.STA_IF)
|
||||
wlan.disconnect()
|
||||
wlan.connect(ssid,password)
|
||||
for i in range(10):
|
||||
if wlan.isconnected():
|
||||
print(f"attempt_connecting: Connected to {ssid} after {i+1} seconds")
|
||||
break
|
||||
print(f"attempt_connecting: Waiting for connection, attempt {i+1}/10")
|
||||
time.sleep(1)
|
||||
if not wlan.isconnected():
|
||||
result="timeout"
|
||||
if WifiService.attempt_connecting(ssid, password):
|
||||
result = "connected"
|
||||
else:
|
||||
print("Warning: not trying to connect because not self.have_network, just waiting a bit...")
|
||||
time.sleep(5)
|
||||
result = "timeout"
|
||||
except Exception as e:
|
||||
print(f"attempt_connecting: Connection error: {e}")
|
||||
result=f"{e}"
|
||||
self.show_error("Connecting to {ssid} failed!")
|
||||
result = f"{e}"
|
||||
self.show_error(f"Connecting to {ssid} failed!")
|
||||
|
||||
print(f"Connecting to {ssid} got result: {result}")
|
||||
self.last_tried_ssid = ssid
|
||||
self.last_tried_result = result
|
||||
# also do a time sync, otherwise some apps (Nostr Wallet Connect) won't work:
|
||||
if self.have_network and wlan.isconnected():
|
||||
mpos.time.sync_time()
|
||||
self.busy_connecting=False
|
||||
|
||||
# Note: Time sync is handled by WifiService.attempt_connecting()
|
||||
|
||||
self.busy_connecting = False
|
||||
self.update_ui_threadsafe_if_foreground(self.scan_button_label.set_text, self.scan_button_scan_text)
|
||||
self.update_ui_threadsafe_if_foreground(self.scan_button.remove_state, lv.STATE.DISABLED)
|
||||
self.update_ui_threadsafe_if_foreground(self.refresh_list)
|
||||
|
||||
def findSavedPassword(self, ssid):
|
||||
ap = self.saved_access_points.get(ssid)
|
||||
if ap:
|
||||
return ap.get("password")
|
||||
return None
|
||||
|
||||
def setPassword(self, ssid, password, hidden=False):
|
||||
ap = self.saved_access_points.get(ssid)
|
||||
if ap:
|
||||
ap["password"] = password
|
||||
if hidden is True:
|
||||
ap["hidden"] = True
|
||||
return
|
||||
# if not found, then add it:
|
||||
self.saved_access_points[ssid] = { "password": password, "hidden": hidden }
|
||||
|
||||
|
||||
class EditNetwork(Activity):
|
||||
|
||||
@@ -259,14 +218,14 @@ class EditNetwork(Activity):
|
||||
|
||||
# Widgets:
|
||||
ssid_ta = None
|
||||
password_ta=None
|
||||
password_ta = None
|
||||
hidden_cb = None
|
||||
keyboard=None
|
||||
connect_button=None
|
||||
cancel_button=None
|
||||
keyboard = None
|
||||
connect_button = None
|
||||
cancel_button = None
|
||||
|
||||
def onCreate(self):
|
||||
password_page=lv.obj()
|
||||
password_page = lv.obj()
|
||||
password_page.set_style_pad_all(0, lv.PART.MAIN)
|
||||
password_page.set_flex_flow(lv.FLEX_FLOW.COLUMN)
|
||||
self.selected_ssid = self.getIntent().extras.get("selected_ssid")
|
||||
@@ -275,31 +234,31 @@ class EditNetwork(Activity):
|
||||
# SSID:
|
||||
if self.selected_ssid is None:
|
||||
print("No ssid selected, the user should fill it out.")
|
||||
label=lv.label(password_page)
|
||||
label = lv.label(password_page)
|
||||
label.set_text(f"Network name:")
|
||||
self.ssid_ta=lv.textarea(password_page)
|
||||
self.ssid_ta = lv.textarea(password_page)
|
||||
self.ssid_ta.set_width(lv.pct(90))
|
||||
self.ssid_ta.set_style_margin_left(5, lv.PART.MAIN)
|
||||
self.ssid_ta.set_one_line(True)
|
||||
self.ssid_ta.set_placeholder_text("Enter the SSID")
|
||||
self.keyboard=MposKeyboard(password_page)
|
||||
self.keyboard = MposKeyboard(password_page)
|
||||
self.keyboard.set_textarea(self.ssid_ta)
|
||||
self.keyboard.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
|
||||
|
||||
# Password:
|
||||
label=lv.label(password_page)
|
||||
label = lv.label(password_page)
|
||||
if self.selected_ssid is None:
|
||||
label.set_text("Password:")
|
||||
else:
|
||||
label.set_text(f"Password for '{self.selected_ssid}':")
|
||||
self.password_ta=lv.textarea(password_page)
|
||||
self.password_ta = lv.textarea(password_page)
|
||||
self.password_ta.set_width(lv.pct(90))
|
||||
self.password_ta.set_style_margin_left(5, lv.PART.MAIN)
|
||||
self.password_ta.set_one_line(True)
|
||||
if known_password:
|
||||
self.password_ta.set_text(known_password)
|
||||
self.password_ta.set_placeholder_text("Password")
|
||||
self.keyboard=MposKeyboard(password_page)
|
||||
self.keyboard = MposKeyboard(password_page)
|
||||
self.keyboard.set_textarea(self.password_ta)
|
||||
self.keyboard.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
|
||||
@@ -316,24 +275,24 @@ class EditNetwork(Activity):
|
||||
buttons.set_style_border_width(0, lv.PART.MAIN)
|
||||
# Delete button
|
||||
if self.selected_ssid:
|
||||
self.forget_button=lv.button(buttons)
|
||||
self.forget_button = lv.button(buttons)
|
||||
self.forget_button.align(lv.ALIGN.LEFT_MID, 0, 0)
|
||||
self.forget_button.add_event_cb(self.forget_cb, lv.EVENT.CLICKED, None)
|
||||
label=lv.label(self.forget_button)
|
||||
label = lv.label(self.forget_button)
|
||||
label.set_text("Forget")
|
||||
label.center()
|
||||
# Close button
|
||||
self.cancel_button=lv.button(buttons)
|
||||
self.cancel_button = lv.button(buttons)
|
||||
self.cancel_button.center()
|
||||
self.cancel_button.add_event_cb(lambda *args: self.finish(), lv.EVENT.CLICKED, None)
|
||||
label=lv.label(self.cancel_button)
|
||||
label = lv.label(self.cancel_button)
|
||||
label.set_text("Close")
|
||||
label.center()
|
||||
# Connect button
|
||||
self.connect_button = lv.button(buttons)
|
||||
self.connect_button.align(lv.ALIGN.RIGHT_MID, 0, 0)
|
||||
self.connect_button.add_event_cb(self.connect_cb,lv.EVENT.CLICKED,None)
|
||||
label=lv.label(self.connect_button)
|
||||
self.connect_button.add_event_cb(self.connect_cb, lv.EVENT.CLICKED, None)
|
||||
label = lv.label(self.connect_button)
|
||||
label.set_text("Connect")
|
||||
label.center()
|
||||
|
||||
|
||||
@@ -42,6 +42,9 @@ class WifiService:
|
||||
# Dictionary of saved access points {ssid: {password: "..."}}
|
||||
access_points = {}
|
||||
|
||||
# Desktop mode: simulated connected SSID (None = not connected)
|
||||
_desktop_connected_ssid = None
|
||||
|
||||
@staticmethod
|
||||
def connect(network_module=None):
|
||||
"""
|
||||
@@ -54,15 +57,8 @@ class WifiService:
|
||||
Returns:
|
||||
bool: True if successfully connected, False otherwise
|
||||
"""
|
||||
net = network_module if network_module else network
|
||||
wlan = net.WLAN(net.STA_IF)
|
||||
|
||||
# Restart WiFi hardware in case it's in a bad state
|
||||
wlan.active(False)
|
||||
wlan.active(True)
|
||||
|
||||
# Scan for available networks
|
||||
networks = wlan.scan()
|
||||
# Scan for available networks using internal method
|
||||
networks = WifiService._scan_networks_raw(network_module)
|
||||
|
||||
# Sort networks by RSSI (signal strength) in descending order
|
||||
# RSSI is at index 3, higher values (less negative) = stronger signal
|
||||
@@ -104,9 +100,18 @@ class WifiService:
|
||||
"""
|
||||
print(f"WifiService: Connecting to SSID: {ssid}")
|
||||
|
||||
net = network_module if network_module else network
|
||||
time_mod = time_module if time_module else time
|
||||
|
||||
# Desktop mode - simulate successful connection
|
||||
if not HAS_NETWORK_MODULE and network_module is None:
|
||||
print("WifiService: Desktop mode, simulating connection...")
|
||||
time_mod.sleep(2)
|
||||
WifiService._desktop_connected_ssid = ssid
|
||||
print(f"WifiService: Simulated connection to '{ssid}' successful")
|
||||
return True
|
||||
|
||||
net = network_module if network_module else network
|
||||
|
||||
try:
|
||||
wlan = net.WLAN(net.STA_IF)
|
||||
wlan.connect(ssid, password)
|
||||
@@ -323,20 +328,115 @@ class WifiService:
|
||||
return list(WifiService.access_points.keys())
|
||||
|
||||
@staticmethod
|
||||
def save_network(ssid, password):
|
||||
def _scan_networks_raw(network_module=None):
|
||||
"""
|
||||
Internal method to scan for available WiFi networks and return raw data.
|
||||
|
||||
Args:
|
||||
network_module: Network module for dependency injection (testing)
|
||||
|
||||
Returns:
|
||||
list: Raw network tuples from wlan.scan(), or empty list on desktop
|
||||
"""
|
||||
if not HAS_NETWORK_MODULE and network_module is None:
|
||||
# Desktop mode - return empty (no raw data available)
|
||||
return []
|
||||
|
||||
net = network_module if network_module else network
|
||||
wlan = net.WLAN(net.STA_IF)
|
||||
|
||||
# Restart WiFi hardware in case it is in a bad state (only if not connected)
|
||||
if not wlan.isconnected():
|
||||
wlan.active(False)
|
||||
wlan.active(True)
|
||||
|
||||
return wlan.scan()
|
||||
|
||||
@staticmethod
|
||||
def scan_networks(network_module=None):
|
||||
"""
|
||||
Scan for available WiFi networks.
|
||||
|
||||
Args:
|
||||
network_module: Network module for dependency injection (testing)
|
||||
|
||||
Returns:
|
||||
list: List of SSIDs found, or mock data on desktop
|
||||
"""
|
||||
if not HAS_NETWORK_MODULE and network_module is None:
|
||||
# Desktop mode - return mock SSIDs
|
||||
time.sleep(1)
|
||||
return ["Home WiFi", "Pretty Fly for a Wi Fi", "Winternet is coming", "The Promised LAN"]
|
||||
|
||||
networks = WifiService._scan_networks_raw(network_module)
|
||||
# Return unique SSIDs, filtering out empty ones and invalid lengths
|
||||
ssids = list(set(n[0].decode() for n in networks if n[0]))
|
||||
return [s for s in ssids if 0 < len(s) <= 32]
|
||||
|
||||
@staticmethod
|
||||
def get_current_ssid(network_module=None):
|
||||
"""
|
||||
Get the SSID of the currently connected network.
|
||||
|
||||
Args:
|
||||
network_module: Network module for dependency injection (testing)
|
||||
|
||||
Returns:
|
||||
str or None: Current SSID if connected, None otherwise
|
||||
"""
|
||||
if not HAS_NETWORK_MODULE and network_module is None:
|
||||
# Desktop mode - return simulated connected SSID
|
||||
return WifiService._desktop_connected_ssid
|
||||
|
||||
net = network_module if network_module else network
|
||||
try:
|
||||
wlan = net.WLAN(net.STA_IF)
|
||||
if wlan.isconnected():
|
||||
return wlan.config('essid')
|
||||
except Exception as e:
|
||||
print(f"WifiService: Error getting current SSID: {e}")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def get_network_password(ssid):
|
||||
"""
|
||||
Get the saved password for a network.
|
||||
|
||||
Args:
|
||||
ssid: Network SSID
|
||||
|
||||
Returns:
|
||||
str or None: Password if found, None otherwise
|
||||
"""
|
||||
if not WifiService.access_points:
|
||||
WifiService.access_points = mpos.config.SharedPreferences(
|
||||
"com.micropythonos.system.wifiservice"
|
||||
).get_dict("access_points")
|
||||
|
||||
ap = WifiService.access_points.get(ssid)
|
||||
if ap:
|
||||
return ap.get("password")
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def save_network(ssid, password, hidden=False):
|
||||
"""
|
||||
Save a new WiFi network credential.
|
||||
|
||||
Args:
|
||||
ssid: Network SSID
|
||||
password: Network password
|
||||
hidden: Whether this is a hidden network (always try connecting)
|
||||
"""
|
||||
# Load current saved networks
|
||||
prefs = mpos.config.SharedPreferences("com.micropythonos.system.wifiservice")
|
||||
access_points = prefs.get_dict("access_points")
|
||||
|
||||
# Add or update the network
|
||||
access_points[ssid] = {"password": password}
|
||||
network_config = {"password": password}
|
||||
if hidden:
|
||||
network_config["hidden"] = True
|
||||
access_points[ssid] = network_config
|
||||
|
||||
# Save back to config
|
||||
editor = prefs.edit()
|
||||
@@ -346,7 +446,7 @@ class WifiService:
|
||||
# Update class-level cache
|
||||
WifiService.access_points = access_points
|
||||
|
||||
print(f"WifiService: Saved network '{ssid}'")
|
||||
print(f"WifiService: Saved network '{ssid}' (hidden={hidden})")
|
||||
|
||||
@staticmethod
|
||||
def forget_network(ssid):
|
||||
|
||||
Reference in New Issue
Block a user