import json import gc import time import uasyncio as asyncio # Import config value from config import TANK_CAPACITY_L, VERSION class WebServer: def __init__(self, wlan, sensors, start_time, max_conn): self.wlan = wlan self.sensors = sensors self.start_time = start_time self.max_conn = max_conn self.current = 0 self.lock = asyncio.Lock() async def handle(self, reader, writer): async with self.lock: if self.current >= self.max_conn: writer.close() return self.current += 1 try: request = await reader.readline() path = request.decode().split(" ")[1] # Discard headers while await reader.readline() != b"\r\n": pass # ---------- SENSOR JSON ---------- if path == "/sensor": uptime = int(time.time() - self.start_time) days = uptime // 86400 hours = (uptime % 86400) // 3600 minutes = (uptime % 3600) // 60 seconds = uptime % 60 uptime_text = f"{days}d {hours:02}h {minutes:02}m {seconds:02}s" data = { "pressure": self.sensors.pressure, "tank_percent": self.sensors.tank_percentage, "cpu_temp": self.sensors.cpu_temp(), "rssi": self.wlan.status("rssi"), "uptime": uptime_text, "mem": gc.mem_free(), "footer": "Powered by Raspberry Pi Pico W & HX710B (" + VERSION + ")" } writer.write( b"HTTP/1.1 200 OK\r\n" b"Content-Type: application/json\r\n\r\n" + json.dumps(data).encode() ) # ---------- TARE ---------- elif path == "/tare": self.sensors.set_tank_full() writer.write( b"HTTP/1.1 200 OK\r\n" b"Content-Type: application/json\r\n\r\n" + json.dumps({"ok": True}).encode() ) # ---------- JAVASCRIPT (CONFIG INJECTED) ---------- elif path == "/app.js": with open("/html/app.js") as f: js = f.read() injected = ( "// injected by webserver.py\n" f"const TANK_CAPACITY_L = {TANK_CAPACITY_L};\n\n" ) writer.write( b"HTTP/1.1 200 OK\r\n" b"Content-Type: application/javascript\r\n" b"Cache-Control: no-store\r\n\r\n" + injected.encode() + js.encode() ) # ---------- HTML ---------- else: with open("/html/index.html") as f: html = f.read() writer.write( b"HTTP/1.1 200 OK\r\n" b"Content-Type: text/html\r\n\r\n" + html.encode() ) await writer.drain() finally: writer.close() await writer.wait_closed() async with self.lock: self.current -= 1