99import network
1010import gc
1111
12+ # ---------------------------------------------------------------------------
13+ # Standardized HTTP helper
14+ # ---------------------------------------------------------------------------
15+ # A tiny wrapper (`rq`) mimics the minimal subset of the urequests interface
16+ # used here (get/post + status_code/text/close) while keeping memory usage low.
17+
18+ try : # MicroPython-provided lightweight HTTP client
19+ from urllib .urequest import urlopen # type: ignore
20+ except ImportError : # Extremely unlikely on badge firmware; handled gracefully
21+ urlopen = None # type: ignore
22+
23+
24+ class _HTTPResponse :
25+ """Minimal response object exposing .status_code, .text, .close().
26+
27+ Text is lazily decoded to avoid allocating unless needed. If decoding fails,
28+ raw bytes are returned (repr-safe for small payloads)."""
29+
30+ def __init__ (self , raw , status = 200 ):
31+ self ._raw = raw
32+ self .status_code = getattr (raw , "status" , status )
33+ self ._text = None
34+
35+ @property
36+ def text (self ):
37+ if self ._text is None :
38+ try :
39+ # Some MicroPython builds return bytes; decode defensively.
40+ data = self ._raw .read ()
41+ if isinstance (data , bytes ):
42+ try :
43+ self ._text = data .decode ()
44+ except Exception :
45+ self ._text = data .decode ("utf-8" , "ignore" )
46+ else : # already str
47+ self ._text = data
48+ except Exception :
49+ self ._text = ""
50+ return self ._text
51+
52+ def close (self ):
53+ try :
54+ if hasattr (self ._raw , "close" ):
55+ self ._raw .close ()
56+ except Exception :
57+ pass
58+
59+
60+ class rq : # Mimic minimal urequests-like interface used by this app
61+ @staticmethod
62+ def get (url , timeout = 2 ): # timeout retained for signature compatibility
63+ if urlopen is None :
64+ raise ImportError ("urllib.urequest unavailable" )
65+ # MicroPython's urlopen may ignore timeout; acceptable for short badge calls.
66+ raw = urlopen (url )
67+ return _HTTPResponse (raw )
68+
69+ @staticmethod
70+ def post (url , data = None , headers = None , timeout = 2 ):
71+ if urlopen is None :
72+ raise ImportError ("urllib.urequest unavailable" )
73+ # Encode string payload to bytes when needed.
74+ if isinstance (data , str ):
75+ data_bytes = data .encode ()
76+ else :
77+ data_bytes = data
78+ # MicroPython's urlopen accepts headers as dict (not list of tuples)
79+ raw = urlopen (url , data = data_bytes , headers = headers )
80+ return _HTTPResponse (raw )
81+
1282# Load fonts - use smaller, more compact fonts
1383small_font = PixelFont .load ("/system/assets/fonts/ark.ppf" )
1484
@@ -224,20 +294,14 @@ def send_wled_command(data, timeout=2):
224294 try :
225295 import json
226296 url = f"http://{ WLED_HOST } /json/state"
227- try :
228- import urequests as rq
229- except ImportError :
230- from urllib import urequest as rq # type: ignore
231297 payload = json .dumps (data )
232298 headers = {"Content-Type" : "application/json" }
233299 resp = rq .post (url , data = payload , headers = headers , timeout = timeout )
234300 success = resp .status_code in (200 , 201 )
301+ # Ensure we release underlying resources early.
235302 resp .close ()
236303 in_flight = False
237- if success :
238- status_message = "Command sent"
239- else :
240- status_message = f"HTTP { resp .status_code } "
304+ status_message = "Command sent" if success else f"HTTP { resp .status_code } "
241305 return success
242306 except Exception as e :
243307 in_flight = False
@@ -261,18 +325,11 @@ def http_request(path, timeout=1):
261325 return None
262326 try :
263327 url = f"http://{ WLED_HOST } { path } "
264- try :
265- import urequests as rq
266- except ImportError :
267- from urllib import urequest as rq # type: ignore
268- # Use a short timeout so we don't freeze the render loop for long
269328 resp = rq .get (url , timeout = timeout )
270329 if resp .status_code == 200 :
271330 try :
272- # Try to read raw text first to see what we got
273- raw_text = resp .text
331+ raw_text = resp .text # Lazily decoded
274332 resp .close ()
275- # Now try to parse it
276333 import json
277334 data = json .loads (raw_text )
278335 wled_connected = True
0 commit comments