Ce que le mode gestes COÛTE, et comment il cesse de le coûter (§83).
Spatial Mesh, gestes — 25 août 2026. Le §78 dit qu'une caméra ne guette pas
en permanence, et quatre chemins d'extinction le tiennent déjà. Le §83 dit
autre chose : même armée, la caméra ne doit pas coûter le même prix selon
qu'on s'en sert ou non.
Jusqu'ici la cadence était figée à douze images par seconde, du premier
instant au désarmement. Armer le mode et aller lire un document, c'était
douze captures, douze encodages JPEG et douze appels à Vision par seconde,
pendant dix minutes, pour filmer une chaise.
Quatre états, et un seul chiffre en sort — la cadence que l'interface doit
appliquer. C'est le SERVEUR qui décide, parce qu'il est le seul à savoir si
une main a été vue ; l'interface obéit et ne devine rien.
Ce que ce module refuse de faire : baisser la cadence pendant qu'une main
est suivie. Le geste se mesure en IMAGES (« ≤ 10 images pour un attraper »,
figé par un test), donc une cadence qui tombe au milieu d'un geste allonge
ce geste en secondes sans que personne l'ait demandé. On économise entre les
gestes, jamais pendant.
Functions:
etat_energie
etat_energie(
*,
armee: bool,
depuis_derniere_main_s: Optional[float],
sur_batterie: bool = False,
batterie_pct: Optional[int] = None,
) -> Energie
L'état d'énergie, à partir de ce qui est CONSTATÉ.
depuis_derniere_main_s vaut None tant qu'aucune main n'a jamais été
vue : une session qu'on vient d'armer n'est pas « active », elle attend.
Source code in src/diapason/desktop/energie_gestes.py
| def etat_energie(
*,
armee: bool,
depuis_derniere_main_s: Optional[float],
sur_batterie: bool = False,
batterie_pct: Optional[int] = None,
) -> Energie:
"""L'état d'énergie, à partir de ce qui est CONSTATÉ.
``depuis_derniere_main_s`` vaut None tant qu'aucune main n'a jamais été
vue : une session qu'on vient d'armer n'est pas « active », elle attend.
"""
if not armee:
return Energie.ETEINT
# UNE MAIN SUIVIE PRIME SUR TOUT, batterie faible comprise.
#
# L'en-tête de ce module déclare : « Ce que ce module refuse de faire :
# baisser la cadence pendant qu'une main est suivie. » La batterie était
# pourtant consultée EN PREMIER, donc à 18 % un geste en cours tombait de
# douze à deux images par seconde — et le geste casse, puisqu'il se
# mesure en IMAGES (« ≤ 10 images pour un attraper », figé par un test) et
# non en secondes. Le module faisait le contraire de ce qu'il annonçait
# (constaté le 26 août 2026).
#
# Ce que cela coûte est borné : un geste dure quelques secondes, pas la
# session. Ce que l'inverse coûtait ne l'était pas — un geste qui échoue
# se recommence, à pleine cadence, autant de fois qu'il échoue.
suivie = (
depuis_derniere_main_s is not None
and depuis_derniere_main_s <= SANS_MAIN_AVANT_VEILLE_S
)
if suivie:
return Energie.ACTIF
if sur_batterie and batterie_pct is not None and batterie_pct <= BATTERIE_BASSE_PCT:
return Energie.ECONOMIE
return Energie.PRET
|
cadence
cadence(etat: Energie, *, pointeur: bool = False) -> int
Les images par seconde que l'interface doit appliquer.
Source code in src/diapason/desktop/energie_gestes.py
| def cadence(etat: Energie, *, pointeur: bool = False) -> int:
"""Les images par seconde que l'interface doit appliquer."""
if pointeur and etat is Energie.ACTIF:
return CADENCE_POINTEUR
return {
Energie.ETEINT: 0,
Energie.PRET: CADENCE_PRETE,
Energie.ACTIF: CADENCE_ACTIVE,
Energie.ECONOMIE: CADENCE_ECONOMIE,
}[etat]
|
batterie
batterie(
*, maintenant: Optional[float] = None
) -> Optional[tuple[int, bool]]
(pourcentage, sur batterie) — en cache, ou None si illisible.
Source code in src/diapason/desktop/energie_gestes.py
| def batterie(*, maintenant: Optional[float] = None) -> Optional[tuple[int, bool]]:
"""(pourcentage, sur batterie) — en cache, ou None si illisible."""
global _batterie_vue
maintenant = time.monotonic() if maintenant is None else maintenant
if (
_batterie_vue is not None
and maintenant - _batterie_vue[0] < _RELECTURE_BATTERIE_S
):
return _batterie_vue[1]
try:
from diapason.heartbeat.tick import lire_batterie
mesure = lire_batterie()
except Exception: # noqa: BLE001 - une machine sans batterie n'est pas en panne
mesure = None
_batterie_vue = (maintenant, mesure)
return mesure
|
oublier_la_batterie
oublier_la_batterie() -> None
Vider le cache — pour les tests, et pour un réveil de veille.
Source code in src/diapason/desktop/energie_gestes.py
| def oublier_la_batterie() -> None:
"""Vider le cache — pour les tests, et pour un réveil de veille."""
global _batterie_vue
_batterie_vue = None
|