Implement notetaking app, ST7796 display with touch support, audio beep navigation, and video streaming

This commit is contained in:
Adolfo Reyna
2026-06-08 15:04:36 -04:00
parent 070390355e
commit 3356e5d4a2
30 changed files with 3983 additions and 71 deletions
+106
View File
@@ -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()