secubox-deb/remote-ui
CyberMind a3a918ed6f
remote-ui/square: 4 bugs caught at Pi 4B hardware bench (Phase 3 followup, ref #127) (#134)
* fix(remote-ui/square): 4 bugs caught at Pi 4B hardware bench (closes #133, ref #127)

Phase 3 (#132) merged with 82/82 pytest green and two-stage subagent
review on every task — but the kiosk crashed at hardware boot because
the review loop had no real /dev/fb0. All four fixes validated live
on a Pi 4B + official 7" DSI panel this session by hand-patching the
uSD, then ported here.

(1) /run/secubox not recreated on reboot
    Add remote-ui/square/files/etc/tmpfiles.d/secubox-eye-square.conf
    creating /run/secubox + /var/log/secubox at boot under the
    secubox-eye-square user. /run is tmpfs and the build-time mkdir
    didn't persist, so secubox-eye-square-helper.service crashed on
    Path.mkdir() at startup, which cascaded into the kiosk's
    HelperClient timeout-loop.

(2) fonts-dejavu-core missing from chroot apt-install
(3) draw.text() calls lacked font= argument
    Pillow on Bookworm (9.4) falls back to a latin-1 bitmap font when
    no font is passed. ring_dashboard.py draws "○ NOMINAL" (U+25CB)
    which raised UnicodeEncodeError. Fix on both ends: install
    fonts-dejavu-core in the chroot, expose theme.DEFAULT_FONT loaded
    from /usr/share/fonts/truetype/dejavu/DejaVuSans.ttf, and pass
    font=theme.DEFAULT_FONT to every draw.text() in the kiosk
    (25 call sites across 6 files — confirmed by AST walk).

(4) framebuffer.py hardcoded 32bpp BGRA but vc4drmfb is 16bpp RGB565
    The Pi 4B 7" DSI exposes /dev/fb0 as DRM_FORMAT_RGB565
    (16bpp, R in top 5 bits). framebuffer.py wrote 800*480*4=1.5MB
    of BGRA bytes into a 768KB fb. mmap silently truncated, dd ...
    of=/dev/fb0 confirmed smem_len=768KB by erroring "No space left
    on device" at exactly that offset. Pillow's RGB→RGB565 raw
    packers were removed in Pillow >=9.4 (tested 9.4 and 10.2,
    same behaviour), so we pack via numpy:
        pixels = ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | (B >> 3)
        pixels.astype("<u2").tobytes()
    Auto-detect bpp from /sys/class/graphics/<dev>/bits_per_pixel;
    for 32bpp paths, FBIOGET_VSCREENINFO ioctl picks the right
    Pillow raw mode (BGRA / RGBA / ARGB / ABGR). EYE_SQUARE_FB_MODE
    env var overrides for diagnostics. Adds python3-numpy to the
    chroot apt-install list.

Tests
- test_framebuffer.py rewritten: drops bpp= kwarg (now auto-detected),
  adds tests for env override, sysfs bpp=16 detection picking RGB565,
  numpy pack of pure red → 0xF800 (R in top 5 bits, LE bytes), and
  pure black → 0x0000.
- New test_theme.py: palette tuple shape + DEFAULT_FONT loads +
  Unicode glyph (U+25CB) rendering smoke.
- 68/68 kiosk tests green (was 61 + 7 new). Helper untouched.

Hardware validation (Task 23 / #127)
Same uSD with these patches renders correctly on Pi 4B + 7" DSI:
black background, six distinct ring colors (AUTH orange, WALL gold,
BOOT brown, MIND blue, ROOT teal, MESH blue), Unicode dot in tab
labels, frame-budget headroom (numpy pack ~5-10ms on Pi 4B).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(remote-ui/square): also auto-detect fb size, center-pad for HDMI on Pi 400 (ref #133)

Caught at Pi 400 + HDMI bench. The Pi 400 doesn't ship with the official
7" DSI panel, so /dev/fb0 is exposed at the HDMI monitor's native
resolution (e.g. 1920x1080) instead of 800x480. The kiosk hardcodes
800x480 and writes 800-wide rows; against a 1920-wide fb the writes
get sliced and tiled, producing rainbow stripes across the top.

Fix: in addition to the bpp + byte-order detection from the first
commit, read /sys/class/graphics/<dev>/virtual_size at __init__.
Mmap to actual fb size (not logical). Center-pad the kiosk's 800x480
canvas into a black canvas of the real fb size inside blit() before
encoding. Kiosk drawing code stays unchanged — same 800x480 design,
just letterboxed on larger displays.

API change
- FrameBuffer signature is now (path, logical_width=800, logical_height=480)
  instead of (path, width=800, height=480). width/height still exist as
  attributes but now hold the ACTUAL fb dimensions, with logical_width /
  logical_height holding the kiosk's design canvas.

Tests
- New autouse fixture _isolate_sysfs monkeypatches _read_sysfs_size to
  return the fallback. Otherwise tests on a host with a real /dev/fb0
  would pick up the laptop's display dimensions and mismatch the tmp
  fb file size.
- New tests:
  * test_fb_size_detection_uses_sysfs_when_available (1920x1080 fake fb)
  * test_blit_pads_into_larger_fb (red square center-painted into 1920x1080)
  * test_blit_no_pad_when_fb_equals_logical (fast path)
- 71/71 kiosk tests green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: CyberMind-FR <gandalf@Gk2.net>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 12:21:49 +02:00
..
common feat(remote-ui): Phase 1 — extract common/ shared core (ref #127) 2026-05-14 05:59:40 +02:00
round feat(remote-ui): Phase 1 — extract common/ shared core (ref #127) 2026-05-14 05:59:40 +02:00
square remote-ui/square: 4 bugs caught at Pi 4B hardware bench (Phase 3 followup, ref #127) (#134) 2026-05-14 12:21:49 +02:00
README.md feat(remote-ui): Phase 1 — extract common/ shared core (ref #127) 2026-05-14 05:59:40 +02:00

SecuBox-DEB — Remote UI

Interfaces utilisateur déportées pour SecuBox.


Modules

Module Description Hardware
common/ Shared core (JS/CSS/icons/shell) consumed by round/ + square/ hardware-independent
round/ Eye Remote Dashboard HyperPixel 2.1 Round + Pi Zero W
square/ Planned: dual-pane kiosk (round UI + native right column) Pi 4B / Pi 400 + 7" 800×480 (issue #127)

Round Edition

Dashboard kiosk circulaire 480×480 pour monitoring SecuBox.

Features

  • 6 anneaux de status (AUTH, WALL, BOOT, MIND, ROOT, MESH)
  • Transport OTG prioritaire, WiFi fallback
  • Mode simulation intégré
  • USB gadget composite (ECM + ACM + mass_storage)

Documentation

Voir round/README.md pour la documentation complète.


Build Scripts

Script Description
round/build-eye-remote-image.sh Build image Pi Zero W
round/build-storage-img.sh Build storage ESPRESSObin
round/install_zerow.sh Flash et config SD
round/deploy.sh Déployer dashboard

Pipeline complet

# Build complet (depuis racine du repo)
sudo bash build-eye-remote-full.sh

Cela exécute :

  1. Build des packages SecuBox (.deb)
  2. Build de storage.img ESPRESSObin
  3. Build de l'image Pi Zero W

Architecture

remote-ui/
├── round/                      ← Eye Remote Dashboard
│   ├── agent/                  ← Agent multi-SecuBox (v2.0)
│   ├── files/                  ← Fichiers système à installer
│   ├── host-install/           ← Scripts côté host SecuBox
│   ├── scripts/                ← Utilitaires
│   ├── build-eye-remote-image.sh
│   ├── build-storage-img.sh
│   ├── deploy.sh
│   ├── install_zerow.sh
│   ├── CLAUDE.md              ← Instructions Claude Code
│   └── README.md              ← Documentation complète
└── README.md                  ← Ce fichier

Planned Modules

Module Status Description
square/ Planned Dashboard rectangulaire 800×480
web/ Planned WebUI responsive
console/ Planned TUI ncurses

See Also


Author

Gerald KERMA devel@cybermind.fr