Refresh partiel e-ink : ne redessine que la zone changée, full refresh ~1h
Backend : endpoints /frame.meta (ligne 'MODE X Y W H SEQ') + /frame.png qui servent un crop de la zone modifiée (diff PIL par client) ou l'image pleine. Full refresh forcé tous les N cycles (MONITORINK_FULL_EVERY=12, ~1h) ou si la zone change sur plus de 60% de l'écran. Mode 'noop' quand rien ne change. Anti-429 : l'usage Claude est mis en cache (MONITORINK_USAGE_TTL=120s) avec repli sur la dernière valeur connue en cas d'erreur transitoire. Kobo : monitorinkloop.sh récupère meta puis png et fait un fbink partiel (-g file=,x=,y=) sans flash, full refresh (-c -f) en mode full. Refresh 5 min.
This commit is contained in:
@@ -15,7 +15,8 @@ cd "$BASE" || exit 1
|
||||
|
||||
# --- Configuration ---
|
||||
export MONITORINK_URL="http://192.168.0.43:8899/image.png"
|
||||
export MONITORINK_REFRESH=300 # PROD: refresh 5 min
|
||||
export MONITORINK_REFRESH=300 # PROD: refresh partiel 5 min
|
||||
# Cadence du full refresh : côté SERVEUR via MONITORINK_FULL_EVERY (PROD=12 ~1 h à 5 min/cycle).
|
||||
|
||||
echo "===== monitorink start $(date) =====" >> "$LOG"; sync
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@ BASE="$(dirname "$0")"
|
||||
cd "$BASE" || exit 1
|
||||
|
||||
IMAGE_URL="${MONITORINK_URL:-https://monitorink.homelab.nestor-server.fr/image.png}"
|
||||
# Endpoints du refresh partiel, dérivés de l'URL image (.../image.png -> .../frame.meta|frame.png).
|
||||
BASE_URL="${IMAGE_URL%/image.png}"
|
||||
META_URL="$BASE_URL/frame.meta"
|
||||
FRAME_URL="$BASE_URL/frame.png"
|
||||
CLIENT="${MONITORINK_CLIENT:-kobo}"
|
||||
REFRESH="${MONITORINK_REFRESH:-600}"
|
||||
TMP="/tmp/monitorink.png"
|
||||
|
||||
@@ -36,30 +41,73 @@ read_battery() {
|
||||
echo ""
|
||||
}
|
||||
|
||||
fetch() {
|
||||
# On pousse la batterie de la Kobo en paramètres d'URL (le backend la mémorise).
|
||||
url="$IMAGE_URL"
|
||||
bat_query() {
|
||||
# Renvoie "bat=CAP&chg=CHG" pour pousser la batterie au backend (vide si introuvable).
|
||||
bat="$(read_battery)"
|
||||
if [ -n "$bat" ]; then
|
||||
cap="${bat%%|*}"; chg="${bat##*|}"
|
||||
case "$url" in *\?*) sep="&" ;; *) sep="?" ;; esac
|
||||
url="${url}${sep}bat=${cap}&chg=${chg}"
|
||||
echo "bat=${cap}&chg=${chg}"
|
||||
fi
|
||||
}
|
||||
|
||||
http_get() {
|
||||
# $1=url, $2=fichier de sortie ("-" = stdout). busybox wget puis fallback curl.
|
||||
url="$1"; out="$2"
|
||||
if [ "$out" = "-" ]; then
|
||||
"$BUSYBOX" wget -q -T 30 -O - "$url" 2>/dev/null && return 0
|
||||
command -v curl >/dev/null 2>&1 && curl -fsSL -m 30 "$url" 2>/dev/null && return 0
|
||||
else
|
||||
"$BUSYBOX" wget -q -T 30 -O "$out" "$url" 2>/dev/null && return 0
|
||||
command -v curl >/dev/null 2>&1 && curl -fsSL -m 30 -o "$out" "$url" 2>/dev/null && return 0
|
||||
fi
|
||||
# busybox wget (toujours présent), fallback curl si dispo dans le PATH.
|
||||
"$BUSYBOX" wget -q -T 30 -O "$TMP" "$url" 2>/dev/null && return 0
|
||||
command -v curl >/dev/null 2>&1 && curl -fsSL -m 30 -o "$TMP" "$url" 2>/dev/null && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
fetch_meta() {
|
||||
# Récupère la ligne "MODE X Y W H SEQ" du backend (avec batterie + client). Vide si KO.
|
||||
murl="$META_URL?client=$CLIENT"
|
||||
q="$(bat_query)"; [ -n "$q" ] && murl="$murl&$q"
|
||||
http_get "$murl" -
|
||||
}
|
||||
|
||||
# Ferme les FD hérités pour ne pas bloquer l'éjection USB.
|
||||
exec 3>&- 2>/dev/null
|
||||
|
||||
log "boucle démarrée — BASE=$BASE URL=$IMAGE_URL refresh=${REFRESH}s"
|
||||
log "fbink présent: $([ -x "$FBINK" ] && echo oui || echo NON) ; busybox: $([ -x "$BUSYBOX" ] && echo oui || echo NON)"
|
||||
|
||||
display() {
|
||||
display_full() {
|
||||
# Full refresh : clear + waveform complète (le "flash" e-ink), efface le ghosting.
|
||||
"$FBINK" -g file="$TMP",valign=CENTER,halign=CENTER -c -f
|
||||
log "fbink rc=$?"
|
||||
log "display full rc=$?"
|
||||
}
|
||||
|
||||
display_partial() {
|
||||
# Refresh partiel : dessine le crop à l'offset (x,y) ; ni -c ni -f -> seule cette zone est
|
||||
# rafraîchie, en waveform partielle (sans flash). $1=x $2=y (coords portrait, origine HG).
|
||||
"$FBINK" -g file="$TMP",x="$1",y="$2"
|
||||
log "display partial x=$1 y=$2 rc=$?"
|
||||
}
|
||||
|
||||
offline() {
|
||||
log "hors ligne"
|
||||
"$FBINK" -pmh "Monitorink hors ligne ($(date '+%H:%M'))"
|
||||
}
|
||||
|
||||
show_frame() {
|
||||
# Récupère le crop/full image stocké côté serveur et l'affiche selon le mode.
|
||||
# $1=mode $2=x $3=y
|
||||
if ! http_get "$FRAME_URL?client=$CLIENT" "$TMP"; then
|
||||
log "frame.png KO (mode=$1)"
|
||||
[ "$1" = "full" ] && offline
|
||||
return 1
|
||||
fi
|
||||
log "frame.png OK ($(wc -c < "$TMP" 2>/dev/null) octets)"
|
||||
if [ "$1" = "partial" ]; then
|
||||
display_partial "$2" "$3"
|
||||
else
|
||||
display_full
|
||||
fi
|
||||
}
|
||||
|
||||
frontlight_off() {
|
||||
@@ -129,20 +177,27 @@ while true; do
|
||||
|
||||
wifi_up
|
||||
|
||||
if fetch; then
|
||||
log "fetch OK ($(wc -c < "$TMP" 2>/dev/null) octets)"
|
||||
display
|
||||
else
|
||||
meta="$(fetch_meta)"
|
||||
if [ -z "$meta" ]; then
|
||||
# WiFi peut-être tombé : on tente une reconnexion puis un re-essai.
|
||||
log "fetch KO -> reconnexion WiFi"
|
||||
log "meta KO -> reconnexion WiFi"
|
||||
wifi_up
|
||||
if fetch; then
|
||||
log "fetch OK après reco ($(wc -c < "$TMP" 2>/dev/null) octets)"
|
||||
display
|
||||
else
|
||||
log "fetch ECHEC (hors ligne)"
|
||||
"$FBINK" -pmh "Monitorink hors ligne ($(date '+%H:%M'))"
|
||||
fi
|
||||
meta="$(fetch_meta)"
|
||||
fi
|
||||
|
||||
if [ -n "$meta" ]; then
|
||||
# shellcheck disable=SC2086
|
||||
set -- $meta # MODE X Y W H SEQ
|
||||
mode="$1"; mx="$2"; my="$3"
|
||||
log "meta: mode=$mode x=$mx y=$my w=$4 h=$5 seq=$6"
|
||||
case "$mode" in
|
||||
noop) log "aucun changement -> pas de refresh" ;;
|
||||
partial) show_frame partial "$mx" "$my" ;;
|
||||
*) show_frame full ;; # full ou valeur inattendue -> full refresh sûr
|
||||
esac
|
||||
else
|
||||
log "meta ECHEC"
|
||||
offline
|
||||
fi
|
||||
|
||||
./scripts/ledToggle.sh off 2>/dev/null
|
||||
|
||||
Reference in New Issue
Block a user