1313from adafruit_esp32spi import adafruit_esp32spi
1414from adafruit_matrixportal .matrix import Matrix
1515from digitalio import DigitalInOut
16+ from adafruit_httpserver import Server , Request , Response
17+ import adafruit_esp32spi .adafruit_esp32spi_socketpool as socketpool
1618
1719# Get wifi details and more from a secrets.py file
1820try :
4345 continue
4446print ("Connected to" , str (radio .ap_info .ssid , "utf-8" ), "\t RSSI:" , radio .ap_info .rssi )
4547
46- # Initialize a requests session
47- pool = adafruit_connection_manager . get_radio_socketpool (radio )
48+ # Initialize socket pool and requests session
49+ pool = socketpool . SocketPool (radio )
4850ssl_context = adafruit_connection_manager .get_radio_ssl_context (radio )
4951requests = adafruit_requests .Session (pool , ssl_context )
5052
@@ -115,137 +117,49 @@ def load_and_display_bitmap(bitmap_url):
115117print ("Loading default bitmap..." )
116118load_and_display_bitmap (DEFAULT_BITMAP_URL )
117119
118- # Print IP address for testing
119- print ("=" * 50 )
120- print (f"MatrixPortal HTTP Server Ready!" )
121- print (f"IP Address: { radio .pretty_ip (radio .ip_address )} " )
122- print (f"Test with: curl -X POST http://{ radio .pretty_ip (radio .ip_address )} -d \" <bitmap-url>\" " )
123- print ("=" * 50 )
120+ # Create HTTP server
121+ http_server = Server (pool , debug = True )
122+
123+ @http_server .route ("/display" , methods = ["POST" ])
124+ def display_bitmap_handler (request : Request ):
125+ """Handle POST requests with bitmap URL in body"""
126+ print (f"\n Received POST request to /display" )
127+
128+ try :
129+ # Extract URL from raw POST body
130+ body_bytes = request .body
131+ bitmap_url = body_bytes .decode ('utf-8' , errors = 'ignore' ).strip ()
124132
125- # Create HTTP server using ESP32 SPI API
126- print ("Creating server socket..." )
127- socket_num = radio .get_socket ()
128- print (f"Allocated socket number: { socket_num } " )
133+ if not bitmap_url :
134+ print ("Empty URL in POST body" )
135+ return Response (request , "Empty URL in POST body" , status = 400 )
129136
130- # Start server on port 80
131- radio .start_server (port = 80 , socket_num = socket_num )
132- print (f"Server started on port 80, socket { socket_num } " )
137+ print (f"Received URL: { bitmap_url } " )
133138
134- # Verify server is listening
135- state = radio .server_state (socket_num )
136- print (f"Server state: { state } " )
137- print ("Listening for HTTP requests on port 80..." )
139+ # Load and display the bitmap
140+ load_and_display_bitmap (bitmap_url )
138141
139- # Socket state constants
140- SOCKET_CLOSED = 0
141- SOCKET_LISTEN = 1
142- SOCKET_ESTABLISHED = 4
142+ print ("Bitmap loaded and displayed successfully" )
143+ return Response (request , "Bitmap displayed successfully" , status = 200 )
143144
144- # Buffer for accumulating request data
145- request_buffer = b""
145+ except Exception as e :
146+ print (f"Error loading bitmap: { e } " )
147+ return Response (request , f"Error loading bitmap: { e } " , status = 500 )
148+
149+ # Start HTTP server
150+ ip = radio .pretty_ip (radio .ip_address )
151+ print ("\n " + "=" * 50 )
152+ print (f"Starting HTTP server at { ip } :80" )
153+ http_server .start (str (ip ), port = 80 )
154+ print (f"MatrixPortal HTTP Server Ready!" )
155+ print (f"Test with: curl -X POST http://{ ip } /display -d \" <bitmap-url>\" " )
156+ print ("=" * 50 )
146157
147- # Main server loop - poll for incoming connections
148- print ("Waiting for client connections ..." )
158+ # Main server loop
159+ print ("Listening for HTTP requests ..." )
149160while True :
150161 try :
151- # Check the server socket state
152- state = radio .server_state (socket_num )
153-
154- # Only process data if a client is connected (SOCKET_ESTABLISHED)
155- if state != SOCKET_ESTABLISHED :
156- # No client connected, continue polling
157- time .sleep (0.1 )
158- continue
159-
160- # Client is connected! Check if data is available
161- available = radio .socket_available (socket_num )
162-
163- if available <= 0 :
164- # No data available yet, continue polling
165- time .sleep (0.05 )
166- continue
167-
168- # Data available - read it
169- print (f"\n Client connected, reading { available } bytes..." )
170- chunk = radio .socket_read (socket_num , available )
171- request_buffer += chunk
172-
173- # Check if we have complete headers
174- if b"\r \n \r \n " not in request_buffer :
175- # Wait for more data if headers are incomplete
176- continue
177-
178- # We have a complete HTTP request (headers + body)
179- print (f"Received request ({ len (request_buffer )} bytes)" )
180-
181- try :
182- # Parse HTTP request
183- request_str = request_buffer .decode ('utf-8' , errors = 'ignore' )
184- lines = request_str .split ('\r \n ' )
185-
186- # Check if it's a POST request
187- if lines [0 ].startswith ('POST' ):
188- # Find Content-Length header
189- content_length = 0
190- for line in lines :
191- if line .lower ().startswith ('content-length:' ):
192- content_length = int (line .split (':' )[1 ].strip ())
193- break
194-
195- # Extract body
196- header_end = request_buffer .find (b"\r \n \r \n " )
197- body = request_buffer [header_end + 4 :]
198-
199- # Check if we have the complete body
200- if len (body ) >= content_length :
201- # Extract URL from body
202- bitmap_url = body [:content_length ].decode ('utf-8' , errors = 'ignore' ).strip ()
203-
204- if bitmap_url :
205- print (f"Received URL: { bitmap_url } " )
206-
207- try :
208- # Load and display the bitmap
209- load_and_display_bitmap (bitmap_url )
210-
211- # Send success response
212- response = b"HTTP/1.1 200 OK\r \n Content-Type: text/plain\r \n Connection: close\r \n \r \n Bitmap displayed successfully\r \n "
213- radio .socket_write (socket_num , response )
214- print ("Bitmap loaded and displayed successfully" )
215-
216- except Exception as e :
217- print (f"Error loading bitmap: { e } " )
218- response = f"HTTP/1.1 500 Internal Server Error\r \n Content-Type: text/plain\r \n Connection: close\r \n \r \n Error loading bitmap: { e } \r \n " .encode ()
219- radio .socket_write (socket_num , response )
220- else :
221- print ("Empty URL in POST body" )
222- response = b"HTTP/1.1 400 Bad Request\r \n Content-Type: text/plain\r \n Connection: close\r \n \r \n Empty URL in POST body\r \n "
223- radio .socket_write (socket_num , response )
224-
225- # Clear buffer for next request
226- request_buffer = b""
227- else :
228- # Not a POST request
229- print (f"Not a POST request: { lines [0 ]} " )
230- response = b"HTTP/1.1 400 Bad Request\r \n Content-Type: text/plain\r \n Connection: close\r \n \r \n Only POST requests are supported\r \n "
231- radio .socket_write (socket_num , response )
232- request_buffer = b""
233-
234- except Exception as e :
235- print (f"Error parsing request: { e } " )
236- response = b"HTTP/1.1 500 Internal Server Error\r \n Content-Type: text/plain\r \n Connection: close\r \n \r \n Error processing request\r \n "
237- try :
238- radio .socket_write (socket_num , response )
239- except :
240- pass
241- request_buffer = b""
242-
243- gc .collect ()
244-
245- # Small delay to prevent busy-waiting
246- time .sleep (0.1 )
247-
162+ http_server .poll ()
248163 except Exception as e :
249164 print (f"Server error: { e } " )
250- request_buffer = b""
251165 time .sleep (1 )
0 commit comments