Files
portal/leds/portal_sim.py
Jimmy 5094c7bcee Add portal web simulator, SPI bridges, and Pico firmware updates.
Bring the five-panel hex portal online with a browser 3D/schematic preview, Pi SPI backends, and renamed multi-panel Pico UDP firmware.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-30 14:54:51 +12:00

70 lines
1.8 KiB
Python

"""Render portal animations for the web simulator."""
from __future__ import annotations
from leds.animations import ANIMATIONS, DEFAULT_FPS
from leds.array_config import (
MATRIX_BRIGHTNESS,
PANEL_COUNT,
PANEL_FACE_BY_INDEX,
PANEL_POSITION_BY_INDEX,
PORTAL_PANEL_ORDER_CLOCKWISE,
TOP_PANEL_INDEX,
panel_layout,
panel_label,
)
from leds.panel_udp import HeadlessMatrix
def portal_config() -> dict:
panels = []
for index in range(PANEL_COUNT):
width, height = panel_layout(index)
panels.append(
{
"index": index,
"width": width,
"height": height,
"position": PANEL_POSITION_BY_INDEX.get(index),
"face": PANEL_FACE_BY_INDEX.get(index),
"label": panel_label(index),
}
)
return {
"panels": panels,
"topPanel": TOP_PANEL_INDEX,
"orderClockwise": list(PORTAL_PANEL_ORDER_CLOCKWISE),
"animations": list(ANIMATIONS.keys()),
"defaultFps": DEFAULT_FPS,
"defaultBrightness": MATRIX_BRIGHTNESS,
}
def render_portal_frame(
animation: str,
frame: int,
*,
brightness: float = MATRIX_BRIGHTNESS,
) -> dict:
if animation not in ANIMATIONS:
raise ValueError(f"unknown animation: {animation}")
draw = ANIMATIONS[animation]
panels = []
for index in range(PANEL_COUNT):
width, height = panel_layout(index)
matrix = HeadlessMatrix(width, height, brightness=brightness)
draw(matrix, frame)
panels.append(
{
"index": index,
"width": width,
"height": height,
"rgb": list(matrix.rgb_bytes()),
}
)
return {
"frame": frame,
"animation": animation,
"panels": panels,
}