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>
This commit is contained in:
@@ -3,11 +3,45 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from typing import Literal
|
||||
|
||||
MATRIX_WIDTH = 45
|
||||
MATRIX_HEIGHT = 9
|
||||
MATRIX_PIXELS = MATRIX_WIDTH * MATRIX_HEIGHT # 405
|
||||
|
||||
# --- Hexagonal portal -------------------------------------------------------
|
||||
# Bottom face = floor (no LEDs). Panels 0–4 numbered clockwise from bottom-left.
|
||||
# Panel 2 is the top face. All five panels are Pico UDP adapters.
|
||||
#
|
||||
# Viewed from outside:
|
||||
#
|
||||
# [2] TOP
|
||||
# [1] [3]
|
||||
# top-left top-right
|
||||
#
|
||||
# [0] [4]
|
||||
# bottom-left bottom-right
|
||||
#
|
||||
# Floor (no LEDs) is below.
|
||||
TOP_PANEL_INDEX = 2
|
||||
PORTAL_PANEL_ORDER_CLOCKWISE: tuple[int, ...] = (0, 1, 2, 3, 4)
|
||||
SIDE_PANEL_ORDER: tuple[int, ...] = (0, 1, 3, 4)
|
||||
PANEL_POSITION_BY_INDEX: dict[int, str] = {
|
||||
0: "bottom-left",
|
||||
1: "top-left",
|
||||
2: "top",
|
||||
3: "top-right",
|
||||
4: "bottom-right",
|
||||
}
|
||||
PortalFace = Literal["top", "side", "floor"]
|
||||
PANEL_FACE_BY_INDEX: dict[int, PortalFace] = {
|
||||
2: "top",
|
||||
0: "side",
|
||||
1: "side",
|
||||
3: "side",
|
||||
4: "side",
|
||||
}
|
||||
|
||||
# Per-panel width (height is always 9 rows). Edit to match your hardware.
|
||||
# Panel 4 may still be 38 or 39 — run: panel_sync_test.py --test width --panel-index 4
|
||||
PANEL_HEIGHT = 9
|
||||
@@ -21,6 +55,24 @@ PANEL_WIDTH_BY_INDEX: dict[int, int] = {
|
||||
DEFAULT_PANEL_WIDTH = 45
|
||||
PANEL_COUNT = 5
|
||||
|
||||
# Panels driven in-process by the animation script (SPI/PIO on this Pi).
|
||||
LOCAL_PANEL_INDICES: frozenset[int] = frozenset()
|
||||
|
||||
# Optional: Pi UDP→SPI bridge panels (examples/panel_spi_bridge.py). Empty = all Pico.
|
||||
PI_BRIDGE_PANEL_INDICES: frozenset[int] = frozenset()
|
||||
|
||||
# Optional: two panels on one Pico (GP27 + GP28).
|
||||
# Example — panels 0 and 1 on 10.1.1.10, strips 0 and 1:
|
||||
# PANEL_HOST_BY_INDEX = {0: "10.1.1.10", 1: "10.1.1.10"}
|
||||
# PANEL_STRIP_BY_INDEX = {0: 0, 1: 1}
|
||||
# PANEL_WS2812_PIN_BY_INDEX = {0: 28, 1: 27}
|
||||
PANEL_HOST_BY_INDEX: dict[int, str] = {}
|
||||
PANEL_STRIP_BY_INDEX: dict[int, int] = {}
|
||||
PANEL_WS2812_PIN_BY_INDEX: dict[int, int] = {}
|
||||
|
||||
# Optional SPI bus override per panel index (Pi 5: 0 = GPIO 10, 1 = GPIO 20).
|
||||
PANEL_SPI_BUS_BY_INDEX: dict[int, int] = {}
|
||||
|
||||
# SPI data line: bus 0 = GPIO 10 (MOSI), bus 1 = GPIO 20 (SPI1 MOSI)
|
||||
MATRIX_SPI_BUS = 0
|
||||
MATRIX_SPI_DEVICE = 0
|
||||
@@ -34,8 +86,9 @@ MATRIX_FLIP_Y = False
|
||||
|
||||
MATRIX_BRIGHTNESS = 0.25
|
||||
|
||||
# LED wire order for direct SPI on Pi (not used for Pico UDP — firmware packs GRB).
|
||||
WIRE_ORDER = os.environ.get("PORTAL_WIRE_ORDER", "grb").lower()
|
||||
# Optional wire reorder for direct SPI tests only (set PORTAL_WIRE_ORDER env).
|
||||
# UDP/bridge/firmware pass logical RGB through unchanged (default rgb = no swap).
|
||||
WIRE_ORDER = os.environ.get("PORTAL_WIRE_ORDER", "rgb").lower()
|
||||
|
||||
|
||||
def panel_width(panel_index: int) -> int:
|
||||
@@ -51,6 +104,22 @@ def panel_pixel_count(panel_index: int) -> int:
|
||||
return w * h
|
||||
|
||||
|
||||
def panel_face(panel_index: int) -> PortalFace | None:
|
||||
return PANEL_FACE_BY_INDEX.get(panel_index)
|
||||
|
||||
|
||||
def panel_label(panel_index: int) -> str:
|
||||
face = panel_face(panel_index)
|
||||
pos = PANEL_POSITION_BY_INDEX.get(panel_index)
|
||||
if face == "top":
|
||||
return f"panel {panel_index} (top / Pi)"
|
||||
if pos:
|
||||
return f"panel {panel_index} ({pos})"
|
||||
if face == "side":
|
||||
return f"panel {panel_index} (side wall)"
|
||||
return f"panel {panel_index}"
|
||||
|
||||
|
||||
def matrix_pixel_index(
|
||||
x: int,
|
||||
y: int,
|
||||
|
||||
Reference in New Issue
Block a user