Refresh e-ink: multi-régions + full toutes les 2h (basé temps)
Le full refresh apparaissait trop souvent: getbbox() renvoyait un seul rectangle englobant tous les pixels modifiés, donc météo (haut) + heure de MaJ (ailleurs) qui changeaient au même cycle produisaient un rectangle quasi plein écran -> ratio > partial_max_ratio -> full forcé. - frame.py: détection des bandes horizontales modifiées disjointes (_changed_regions), refresh partiel serré par zone. Full basé sur le temps écoulé (last_full_at + time.monotonic) au lieu d'un compteur de cycles. État pngs/regions en liste, get_png(client, region). - config.py: full_refresh_interval_minutes (MONITORINK_FULL_INTERVAL_MIN, défaut 120). Suppression de partial_max_ratio. - app.py: /frame.meta renvoie un bloc multi-ligne "MODE SEQ N" + N régions "i x y w h"; /frame.png?region=i. - monitorinkloop.sh: display_meta parse le bloc et fait N fbink partiels.
This commit is contained in:
@@ -51,20 +51,25 @@ async def image(fresh: int = 0, bat: int | None = None, chg: int = 0) -> Respons
|
||||
async def frame_meta(
|
||||
client: str = "kobo", bat: int | None = None, chg: int = 0, reset: int = 0
|
||||
) -> Response:
|
||||
# Refresh partiel : rend l'image, calcule la zone modifiée vs le dernier frame de ce client,
|
||||
# et renvoie une ligne "MODE X Y W H SEQ" triviale à parser en shell busybox.
|
||||
# MODE ∈ {full, partial, noop}. Le PNG correspondant est récupéré via /frame.png.
|
||||
# Refresh partiel : rend l'image, calcule les zones modifiées vs le dernier frame de ce client,
|
||||
# et renvoie un bloc texte trivial à parser en shell busybox :
|
||||
# MODE SEQ NREGIONS
|
||||
# i x y w h (NREGIONS lignes, i = index pour /frame.png?region=i)
|
||||
# MODE ∈ {full, partial, noop}. Les PNG correspondants sont récupérés via /frame.png.
|
||||
# reset=1 (1er cycle après un (re)démarrage Kobo) -> oublie l'état et force un full refresh.
|
||||
kobo.record(bat, bool(chg))
|
||||
info = await frame.compute_frame(client, reset=bool(reset))
|
||||
line = f"{info['mode']} {info['x']} {info['y']} {info['w']} {info['h']} {info['seq']}"
|
||||
return PlainTextResponse(line, headers={"Cache-Control": "no-store"})
|
||||
regions = info["regions"]
|
||||
lines = [f"{info['mode']} {info['seq']} {len(regions)}"]
|
||||
lines += [f"{i} {x} {y} {w} {h}" for i, (x, y, w, h) in enumerate(regions)]
|
||||
return PlainTextResponse("\n".join(lines), headers={"Cache-Control": "no-store"})
|
||||
|
||||
|
||||
@app.get("/frame.png")
|
||||
async def frame_png(client: str = "kobo") -> Response:
|
||||
# PNG décidé lors du dernier /frame.meta (crop en partial, image pleine en full).
|
||||
png = frame.get_png(client)
|
||||
async def frame_png(client: str = "kobo", region: int = 0) -> Response:
|
||||
# PNG de la région `region` décidée lors du dernier /frame.meta (un crop par zone modifiée en
|
||||
# partial, image pleine en full).
|
||||
png = frame.get_png(client, region)
|
||||
if png is None:
|
||||
return Response(status_code=503)
|
||||
return Response(content=png, media_type="image/png", headers={"Cache-Control": "no-store"})
|
||||
|
||||
Reference in New Issue
Block a user