#!/bin/sh # Monitorink — boucle d'affichage e-ink sur Kobo Libra 2. # # Overlay sur https://github.com/usetrmnl/trmnl-kobo : réutilise ses binaires ARM # (bin/fbink, bin/busybox_kobo) et ses helpers WiFi (scripts/*.sh). On remplace l'appel # API TRMNL par un simple fetch de notre image de dashboard. # Lancé par monitorink.sh (via NickelMenu). Logs -> ../monitorink.log BASE="$(dirname "$0")" cd "$BASE" || exit 1 IMAGE_URL="${MONITORINK_URL:-https://monitorink.homelab.nestor-server.fr/image.png}" REFRESH="${MONITORINK_REFRESH:-600}" TMP="/tmp/monitorink.png" FBINK="./bin/fbink/fbink" BUSYBOX="./bin/busybox_kobo" log() { echo "[$(date '+%H:%M:%S')] $*"; sync; } read_battery() { # Renvoie "CAP|CHG" (ex. "85|0"), CHG=1 si en charge. Vide si introuvable. # On lit capacity + status dans le même dossier /sys/class/power_supply/*. for d in /sys/class/power_supply/*/; do [ -r "${d}capacity" ] || continue cap=$(cat "${d}capacity" 2>/dev/null) chg=0 if [ -r "${d}status" ]; then case "$(cat "${d}status" 2>/dev/null)" in Charging|Full) chg=1 ;; esac fi echo "${cap}|${chg}" return 0 done echo "" } fetch() { # On pousse la batterie de la Kobo en paramètres d'URL (le backend la mémorise). url="$IMAGE_URL" bat="$(read_battery)" if [ -n "$bat" ]; then cap="${bat%%|*}"; chg="${bat##*|}" case "$url" in *\?*) sep="&" ;; *) sep="?" ;; esac url="${url}${sep}bat=${cap}&chg=${chg}" 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 } # 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() { "$FBINK" -g file="$TMP",valign=CENTER,halign=CENTER -c -f log "fbink rc=$?" } frontlight_off() { # Éteint le rétroéclairage (frontlight). Le nœud sysfs exact dépend du modèle Kobo, # donc on écrit 0 dans tous les contrôleurs présents. for b in /sys/class/backlight/*/brightness; do [ -w "$b" ] && echo 0 > "$b" 2>/dev/null done } suspend_for() { # Séquence Kobo éprouvée (trmnl-kobo) : state-extended=1 AVANT rtcwake, puis # suspend manuel (echo mem) si rtcwake n'a pas vraiment suspendu. secs="$1" sync echo 1 > /sys/power/state-extended 2>/dev/null start=$(date +%s) "$BUSYBOX" rtcwake -a -s "$secs" -m mem 2>/dev/null elapsed=$(( $(date +%s) - start )) log "rtcwake elapsed=${elapsed}s" if [ "$elapsed" -le 10 ]; then log "suspend manuel via echo mem" sleep 1; sync; sleep 2 m_start=$(date +%s) echo mem > /sys/power/state 2>/dev/null log "echo mem elapsed=$(( $(date +%s) - m_start ))s (≈${secs}=OK, ≈0=USB branché/suspend bloqué)" fi echo 0 > /sys/power/state-extended 2>/dev/null # Repli : si rien n'a réellement suspendu (USB branché, etc.), on attend le temps # restant en sleep pour ne pas boucler en continu (martèlement backend + batterie). total=$(( $(date +%s) - start )) if [ "$total" -lt "$secs" ]; then rem=$(( secs - total )) log "suspend incomplet (${total}s) -> sleep ${rem}s" sleep "$rem" fi } has_ip() { ip addr show 2>/dev/null | grep -o 'inet [0-9.]*' | grep -qv '127.0'; } wifi_up() { ./scripts/enable-wifi.sh >/dev/null 2>&1 ./scripts/force-wifi-connection.sh >/dev/null 2>&1 # Attend l'association + bail DHCP (jusqu'à ~24 s). i=0 while [ "$i" -lt 12 ]; do ./scripts/obtain-ip.sh >/dev/null 2>&1 has_ip && return 0 sleep 2; i=$((i + 1)) done return 1 } wifi_down() { # Coupe la radio avant le suspend (helpers trmnl, env Nickel siphonné en amont). ./scripts/release-ip.sh >/dev/null 2>&1 ./scripts/disable-wifi.sh >/dev/null 2>&1 } # MODE PROD : frontlight éteint, WiFi cyclé (off pendant le suspend), rtcwake mem. frontlight_off while true; do log "--- itération ---" frontlight_off # réaffirme après chaque réveil ./scripts/ledToggle.sh on 2>/dev/null wifi_up if fetch; then log "fetch OK ($(wc -c < "$TMP" 2>/dev/null) octets)" display else # WiFi peut-être tombé : on tente une reconnexion puis un re-essai. log "fetch 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 fi ./scripts/ledToggle.sh off 2>/dev/null wifi_down # coupe la radio avant le suspend suspend_for "$REFRESH" # rtcwake -m mem, WiFi éteint pendant ~5 min done