Implement notetaking app, ST7796 display with touch support, audio beep navigation, and video streaming
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python3
|
||||
import socket
|
||||
import time
|
||||
import urllib.request
|
||||
import json
|
||||
import base64
|
||||
import os
|
||||
from PIL import Image, ImageDraw
|
||||
|
||||
ESP32_IP = "192.168.68.123"
|
||||
BROADCAST_IP = "192.168.68.255"
|
||||
PORT = 8082
|
||||
ARTIFACTS_DIR = "/Users/adolforeyna/.gemini/antigravity/brain/8b421e8b-10a8-4d06-a7d0-27bd82b42804"
|
||||
|
||||
def main():
|
||||
print(f"--- Starting UDP Broadcast Single-Frame Test ({BROADCAST_IP}) ---")
|
||||
|
||||
# 1. Generate a test frame with Pillow displaying "BROADCAST SUCCESS!"
|
||||
img = Image.new("1", (400, 300), 0)
|
||||
draw = ImageDraw.Draw(img)
|
||||
draw.text((100, 140), "BROADCAST SUCCESS!", fill=1)
|
||||
draw.rectangle([40, 110, 360, 180], outline=1, width=2)
|
||||
|
||||
# Map to Waveshare RLCD buffer format
|
||||
px = img.load()
|
||||
hw_buffer = bytearray(15000)
|
||||
for y in range(300):
|
||||
for x in range(400):
|
||||
if px[x, y]:
|
||||
inv_y = 299 - y
|
||||
bx = x // 2
|
||||
by = inv_y // 4
|
||||
idx = bx * 75 + by
|
||||
lx, ly = x % 2, inv_y % 4
|
||||
bit = 7 - (ly * 2 + lx)
|
||||
hw_buffer[idx] |= (1 << bit)
|
||||
|
||||
# 2. Open UDP socket with broadcast permission
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||
|
||||
# Send all 15 chunks representing the single frame
|
||||
print("Broadcasting chunks...")
|
||||
frame_id = 99
|
||||
for chunk_idx in range(15):
|
||||
packet = bytearray(1002)
|
||||
packet[0] = frame_id
|
||||
packet[1] = chunk_idx
|
||||
start = chunk_idx * 1000
|
||||
packet[2:1002] = hw_buffer[start : start + 1000]
|
||||
sock.sendto(packet, (BROADCAST_IP, PORT))
|
||||
time.sleep(0.002) # Small pacing delay
|
||||
|
||||
sock.close()
|
||||
print("Frame broadcast sent.")
|
||||
|
||||
# 3. Wait 1 second for ESP32 to render and display
|
||||
time.sleep(1.0)
|
||||
|
||||
# 4. Capture screenshot from ESP32
|
||||
print(f"Requesting screenshot from ESP32 ({ESP32_IP}) to verify broadcast reception...")
|
||||
payload = {
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"method": "tools/call",
|
||||
"params": {
|
||||
"name": "get_screenshot",
|
||||
"arguments": {}
|
||||
}
|
||||
}
|
||||
|
||||
req_data = json.dumps(payload).encode('utf-8')
|
||||
req = urllib.request.Request(
|
||||
f"http://{ESP32_IP}/api/mcp",
|
||||
data=req_data,
|
||||
headers={"Content-Type": "application/json"},
|
||||
method="POST"
|
||||
)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=10.0) as response:
|
||||
resp_body = response.read().decode('utf-8')
|
||||
resp_json = json.loads(resp_body)
|
||||
content = resp_json.get("result", {}).get("content", [{}])[0].get("text", "")
|
||||
|
||||
if content.startswith("__PBM_BASE64__:"):
|
||||
pbm_b64 = content.split(":", 1)[1]
|
||||
pbm_bytes = base64.b64decode(pbm_b64)
|
||||
|
||||
temp_pbm = "temp_capture_bcast.pbm"
|
||||
with open(temp_pbm, "wb") as pf:
|
||||
pf.write(pbm_bytes)
|
||||
|
||||
# Convert to PNG using Pillow
|
||||
img = Image.open(temp_pbm)
|
||||
dest_path = os.path.join(ARTIFACTS_DIR, "udp_broadcast_success.png")
|
||||
img.save(dest_path)
|
||||
os.remove(temp_pbm)
|
||||
print(f"Success: Broadcast screenshot saved to {dest_path}")
|
||||
else:
|
||||
print("Error: Invalid screenshot response format.")
|
||||
except Exception as e:
|
||||
print(f"Failed to capture screenshot: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user