Files
portal/leds/wire.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

48 lines
1.4 KiB
Python

"""Map logical RGB to WS2812 wire byte order."""
from __future__ import annotations
from leds.array_config import WIRE_ORDER
# wire[i] = rgb_channel[perm[i]] where rgb = (r, g, b)
_PERM: dict[str, tuple[int, int, int]] = {
"rgb": (0, 1, 2),
"grb": (1, 0, 2),
"rbg": (0, 2, 1),
"brg": (2, 0, 1),
"bgr": (2, 1, 0),
"gbr": (1, 2, 0),
}
def normalize_wire_order(order: str | None = None) -> str:
key = (order or WIRE_ORDER).lower()
if key not in _PERM:
raise ValueError(f"unknown wire order {key!r}; use one of {sorted(_PERM)}")
return key
def rgb_to_wire(r: int, g: int, b: int, order: str | None = None) -> tuple[int, int, int]:
perm = _PERM[normalize_wire_order(order)]
ch = (r, g, b)
return ch[perm[0]], ch[perm[1]], ch[perm[2]]
def rgb_bytes_to_wire(rgb: bytes, order: str | None = None) -> bytes:
perm = _PERM[normalize_wire_order(order)]
out = bytearray(len(rgb))
for i in range(0, len(rgb), 3):
ch = rgb[i], rgb[i + 1], rgb[i + 2]
out[i] = ch[perm[0]]
out[i + 1] = ch[perm[1]]
out[i + 2] = ch[perm[2]]
return bytes(out)
def swap_rg_bytes(rgb: bytes) -> bytes:
"""Swap R and G channels (hardware examples only — not the web simulator)."""
out = bytearray(rgb)
for i in range(0, len(out), 3):
out[i], out[i + 1] = out[i + 1], out[i]
return bytes(out)