From 6cecf89def9f2c44268544517954d2f61d432e43 Mon Sep 17 00:00:00 2001 From: GabiZar Date: Mon, 29 Jun 2026 20:38:43 +0200 Subject: [PATCH] Basique web server with auth to turn on the computer --- main.py | 171 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 147 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index e6548da..8e2056f 100644 --- a/main.py +++ b/main.py @@ -1,33 +1,156 @@ import time import network +import uasyncio as asyncio + +from machine import Pin +from config import WIFI_SSID, WIFI_PASSWORD, PASSWORD + +led = Pin("LED", Pin.OUT, value=0) +computer = Pin(2, Pin.OUT) + +wlan = network.WLAN(network.STA_IF) + +HTML = """\ + + +Pico W Computer Management + +

Pico W - Computer Management

+%s +
+ + +
+ + +""" + +MSG_WRONG = "

Wrong password.

" +MSG_OK = "

Computer turned on/off

" + +def url_decode(s): + s = s.replace("+", " ") + out = [] + i = 0 + while i < len(s): + if s[i] == "%" and i + 2 < len(s): + out.append(chr(int(s[i + 1:i + 3], 16))) + i += 3 + else: + out.append(s[i]) + i += 1 + return "".join(out) + + +def parse_form(body): + params = {} + for pair in body.split("&"): + if "=" in pair: + k, v = pair.split("=", 1) + params[url_decode(k)] = url_decode(v) + return params + +async def toggleComputer(): + led.value(1) + computer.value(1) + await asyncio.sleep(0.5) + led.value(0) + computer.value(0) + +def _do_connect(): + wlan.active(True) + wlan.config(pm = 0xa11140) # disable power-save mode + wlan.connect(WIFI_SSID, WIFI_PASSWORD) + + for _ in range(10): + status = wlan.status() + if status == network.STAT_GOT_IP: + print("Wi-Fi connected:", wlan.ifconfig()[0]) + return True + if status < 0: + break + time.sleep(1) + + print("Connection failed (status=%d)" % wlan.status()) + return False -from config import ( - WIFI_PASSWORD, - WIFI_SSID, -) def connect_wifi(): - wlan = network.WLAN(network.STA_IF) - wlan.active(True) + while True: + print("Connecting to Wi-Fi…") + if _do_connect(): + return + wlan.disconnect() + time.sleep(3) + + +async def wifi_watchdog(): + while True: + await asyncio.sleep(5) + if wlan.status() != network.STAT_GOT_IP: + print("Wi-Fi lost - reconnecting…") + wlan.disconnect() + await asyncio.sleep(1) + while not _do_connect(): + wlan.disconnect() + await asyncio.sleep(3) + print("Wi-Fi restored:", wlan.ifconfig()[0]) + +async def serve_client(reader, writer): + try: + request_line = await reader.readline() + if not request_line: + return + + print("Request:", request_line.strip()) + + parts = request_line.decode().split() + method = parts[0] if parts else "GET" + path = parts[1] if len(parts) > 1 else "/" + + content_length = 0 + while True: + header = await reader.readline() + if header == b"\r\n": + break + if header.lower().startswith(b"content-length:"): + content_length = int(header.split(b":")[1].strip()) + + message = "" + if method == "POST" and path == "/computer" and content_length > 0: + body = await reader.read(content_length) + params = parse_form(body.decode()) + pwd = params.get("pwd", "") + + if pwd != PASSWORD: + message = MSG_WRONG + else: + asyncio.create_task(toggleComputer()) + message = MSG_OK + + writer.write("HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n") + writer.write(HTML % message) + await writer.drain() + + except OSError as e: + print("Client disconnected unexpectedly:", e) + finally: + await writer.wait_closed() + + +async def main(): + print("Connecting to network…") + connect_wifi() + + print("Starting web server on port 80…") + asyncio.create_task(asyncio.start_server(serve_client, "0.0.0.0", 80)) + asyncio.create_task(wifi_watchdog()) while True: - print("Connecting to Wi-Fi...") + await asyncio.sleep(60) - wlan.connect(WIFI_SSID, WIFI_PASSWORD) - - for _ in range(10): - if wlan.status() == 3: - print("connected :", wlan.ifconfig()[0]) - return wlan - - if wlan.status() < 0: - break - - time.sleep(1) - - print(f"network connection failed (status={wlan.status()})") - wlan.disconnect() - time.sleep(2) - -connect_wifi() +try: + asyncio.run(main()) +finally: + asyncio.new_event_loop() \ No newline at end of file