diff --git a/python_payload/mypystubs/network.pyi b/python_payload/mypystubs/network.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..13d68ef5c702ccdca562169e8fc7f08d173bf71e
--- /dev/null
+++ b/python_payload/mypystubs/network.pyi
@@ -0,0 +1,13 @@
+from st3m.goose import Optional
+
+STA_IF: int
+
+class WLAN:
+    def __init__(self, mode: int) -> None:
+        pass
+    def active(self, active: bool) -> bool:
+        return False
+    def connect(self, ssid: bytes, key: Optional[bytes] = None) -> None:
+        pass
+    def isconnected(self) -> bool:
+        return False
diff --git a/python_payload/st3m/run.py b/python_payload/st3m/run.py
index 8f7dfec2d7afc640e6788180fcac040d4afa8a56..48708f4a774b5a3460e0f096b0d6bf74379d2028 100644
--- a/python_payload/st3m/run.py
+++ b/python_payload/st3m/run.py
@@ -13,7 +13,7 @@ from st3m.ui.view import View, ViewManager, ViewTransitionBlend
 from st3m.ui.elements.menus import SimpleMenu, SunMenu
 from st3m.application import discover_bundles, BundleMetadata
 from st3m.about import About
-from st3m import settings, logging, processors
+from st3m import settings, logging, processors, wifi
 
 import captouch, audio, leds, gc
 import os
@@ -35,6 +35,9 @@ def _make_reactor() -> Reactor:
 
     settings.onoff_button_swap.subscribe(_onoff_button_swap_update)
     _onoff_button_swap_update()
+
+    settings.onoff_camp_wifi.subscribe(wifi._onoff_camp_wifi_update)
+    wifi._onoff_camp_wifi_update()
     return reactor
 
 
diff --git a/python_payload/st3m/wifi.py b/python_payload/st3m/wifi.py
new file mode 100644
index 0000000000000000000000000000000000000000..b30efcaa2297122d0e764997f87f322b7551d87c
--- /dev/null
+++ b/python_payload/st3m/wifi.py
@@ -0,0 +1,30 @@
+import network
+from st3m import settings
+
+iface = None
+
+
+def setup_camp_wifi() -> None:
+    global iface
+    iface = network.WLAN(network.STA_IF)
+    iface.active(True)
+    iface.connect(b"Camp2023-open")
+
+
+def disable() -> None:
+    if iface is not None:
+        iface.active(False)
+
+
+def is_connected() -> bool:
+    if iface is not None:
+        return iface.isconnected()
+    else:
+        return False
+
+
+def _onoff_camp_wifi_update() -> None:
+    if settings.onoff_camp_wifi.value:
+        setup_camp_wifi()
+    else:
+        disable()
diff --git a/sim/fakes/network.py b/sim/fakes/network.py
new file mode 100644
index 0000000000000000000000000000000000000000..1ff7b268e4d402669cb8d41f66bdc6a382ed1b07
--- /dev/null
+++ b/sim/fakes/network.py
@@ -0,0 +1,15 @@
+STA_IF = 1
+
+
+class WLAN:
+    def __init__(self, mode):
+        pass
+
+    def active(self, active):
+        return False
+
+    def connect(self, ssid, key=None):
+        pass
+
+    def isconnected(self):
+        return False