mathoudebine / mathoudebine/turing-smart-screen-python

Feature request: page carousel — rotate multiple stat pages, with diff-based partial rendering (working implementation available)

Open
#1,011 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Rich Text Format
Stars
2.3k
Forks
412
Avg merge
21h 10m
Merged PRs (30d)
7

Description

Is your feature request related to a problem?

A single theme can only show as many stats as fit on the panel. If you want more (e.g. a host page, a Kubernetes page, a network page), today's options are running one process per screen or hacky theme-swapping via restart — which re-inits the device and repaints the whole panel.

Full-frame redraws are also visibly slow on these serial-attached panels (~300 KB/frame over CDC-ACM ≈ 1–2 s top-down "wipe").

Describe the solution you'd like

Two complementary pieces, both implemented and running (REV A / TURING_3_5, Linux, Python 3.14):

  1. Page carousel — one process rotates through multiple YAML-defined pages (dwell/refresh configurable, file live-reloaded so edits apply without restart). Widgets so far: bar, metric, radial, text. A page can use any existing theme background, and radial can trace ring art — e.g. live gauges over the stock Cyberdeck theme's rings.

  2. Diff-based partial rendering — each new frame is diffed (PIL.ImageChops) against the last pushed frame and only changed horizontal bands are sent. In-page value updates become wipe-free (a few tiny rectangles instead of a full repaint); page transitions still repaint the content that differs, but skip unchanged chrome and blank space, so they complete noticeably faster than a full-frame push. This part could benefit every user of slow serial panels, independent of the carousel.

Working implementation: https://github.com/JacquesBronk/turing-smart-screen-python/tree/display-platform — docs in DISPLAY.md. It's purely additive (no upstream files modified); the stock engine remains available untouched via a small dispatcher.

Two REV A quirks discovered along the way, documented in DISPLAY.md, that may be worth noting upstream: Clear() leaves the panel in PORTRAIT (its trailing no-arg SetOrientation() restores the default, not the previous orientation), and clean_stop()'s ScreenOff() means any external replacement process must explicitly ScreenOn().

Describe alternatives you've considered

Theme-swapping with process restarts (flicker + device re-enumeration risk), one fat theme (doesn't fit), forking permanently (would rather contribute).

Additional context

Happy to adapt naming/structure/scope to your preferences and split this into smaller PRs — e.g. diff rendering first, carousel second. The branch also contains more niche extras (Prometheus data source, network-map page) that I'd expect to stay out of scope; the PR would cover the carousel + widgets + diff rendering core, with homelab-specific config replaced by generic psutil-only example pages.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the working implementation on the display-platform branch and read DISPLAY.md, then inspect how its small dispatcher leaves the stock engine untouched. Confirm the upstream scope for the carousel, widgets, and diff rendering while excluding the Prometheus and network-map extras; done means an agreed, maintainable upstream integration, potentially split into smaller PRs.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
embedded-iot
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.