Coach DrépanoCoach DrépanoNuit, oxygène et mesures
Transparence des algorithmes

Nuit, oxygène et mesures

L'oxygène et le sommeil de la nuit, les mesures du quotidien et la zone habituelle de chaque valeur.

Chaque algorithme est décrit avec ce qu’il lit, ses étapes, les valeurs qu’il utilise (avec leur emplacement dans le code), ce qu’il affiche et ses limites.

Biais des capteurs et des algorithmes : ce que Trévor dit et les mesures proposéesMétéo et qualité de l'air de ton lieu de vieMesures du jour de la montre : pas, pouls, HRV, température, stress, et signaux repérésQuinze jours de « moments » : bilan de tes moments difficiles et de l'environnementMa nuit : ta normale, nuits plus basses, durées sous 90 % et alertesOxygène de la nuit : moyenne, creux, temps sous le seuil, indice de désaturationQualité d'une nuit, nuits ignorées et choix de la sourceSaisie à la main : oxygène de la nuit, oxymètre au doigt, nuit ressentie et heure du coucherSommeil de la nuit : durée, efficacité, éveilsEstimation de l'oxygène par l'appareil photo du téléphone (expérimentale)Qualité des mesures de la montre : bonne, moyenne ou insuffisanteSéries alignées du « tableau de bord de ta vie »Le seuil d'oxygène bas (92 %) et les seuils proches : où ils s'appliquent et comment les réglerZone habituelle de chaque mesure et alertes de valeurs

← Tous les algorithmes

Biais des capteurs et des algorithmes : ce que Trévor dit et les mesures proposées

Trévor explique que les oxymètres, les montres, les bagues et les caméras de téléphone peuvent afficher un oxygène plus haut que la réalité sur une peau foncée, et que ses propres calculs héritent de ce biais. Il propose cinq mesures pratiques. Ce texte est affiché et n'est pas un calcul.

Où tu le vois : Bot : bouton « ⚖️ Biais des capteurs, mesures possibles » de « Mon oxygène » et fin de l'écran « Ma nuit » ; application (GET /api/phone/nuit).

Ce que l’algorithme lit

Le calcul, étape par étape

Biais des capteursUn oxymètre estime l'oxygène à partir de la lumière qui traversela peauLa mélanine en absorbe une partie : sur peau foncée, l'oxygèneaffiché est en moyenne plus haut que la réalité et un vrai manquepeut passer inaperçuMontres, bagues et caméras reposent sur le même principe ; aupoignet s'ajoutent mouvement, bracelet lâche et tatouagesBiais des algorithmesLes calculs de Trévor partent de ces mesures et de repères tirésd'études qui ne représentent pas toutes les populationsIls héritent du même biais ; le risque affiché n'est pas validépour chaque couleur de peau : repère, jamais preuveMesures possiblesLire chaque valeur par rapport à sa propre zone habituelle etsuivre la tendance sur plusieurs nuitsMesurer plusieurs fois, au repos, mains chaudes et sans vernis ;comparer deux sites ou deux appareilsEssayer un oxymètre frontal (réflexion), moins sensible à lacouleur de peau selon certaines études, mais avec des donnéeslimitées et sans être exempt de biaisFaire confirmer une valeur douteuse par l'équipe soignante (gaz dusang)Donner la priorité aux symptômes (essoufflement, lèvres ou doigtsbleutés, vertiges)Rappel sur l'écran Ma nuit« Ta montre ou ta bague n'est ni un diagnostic ni un appareilmédical. Elle se trompe plus facilement quand tu bouges. Unchiffre normal ne veut donc pas dire que tout va bien. »
Logigramme : Biais des capteurs et des algorithmes : ce que Trévor dit et les mesures proposées

Ce qui est affiché

Trois messages fixes (« Biais des capteurs », « Biais des algorithmes », « Mesures possibles ») montrés avec le rappel sur la nuit. Aucune valeur n'est corrigée en fonction de la couleur de peau : Trévor n'applique aucune correction numérique du biais, ni pour la montre ni pour la caméra.

Ce que cet algorithme ne sait pas faire

Validation. Texte rédigé à partir de références listées dans docs/NUIT_SOMMEIL_OXYGENE.md : Sjoding 2020 (PMID 33326721, chiffres non relus), Wong 2021 (PMID 34730820), Fawzy 2022 (PMID 35639368), Gottlieb 2022 (PMID 35816344), Blaisdell 2000 (PMID 10980793) et Ortiz 1999 (PMID 9927356) sur l'oxymétrie dans la drépanocytose, et le projet de guide de la FDA du 7 janvier 2025. L'affirmation « les calculs de Trévor ne sont pas validés pour chaque couleur de peau » est exacte d'après le code : aucune validation par couleur de peau n'y figure.

Code : data/i18n/fr.json (textBiasWhy, textBiasAlgo, textBiasMeasures, textBiasBtn, textNightDisclaimer), src/trevor/conversation/night_screen.py (blocks), src/trevor/conversation/spo2_screens.py (on_spo2), src/trevor/media/ppg_spo2.py (docstring)

Météo et qualité de l'air de ton lieu de vie

Trévor récupère chaque jour la météo et la qualité de l'air de l'endroit où tu vis et en garde un résumé journalier, pour le mettre en regard de la façon dont tu vas. Il n'invente rien : sans position ou sans réponse du service, la série reste vide.

Où tu le vois : Courbes d'environnement du tableau de bord de la vie, bilan des quinze jours de moments, contexte du jour.

Ce que l’algorithme lit

Le calcul, étape par étape

Position connue ?ouinonAppel aux deux servicesRien n'est écrit (jamais lamétéo de Genève)Prévision (Open-Meteo)Par jour : température max et min, température ressentie min,humidité moyenne, pression moyenne, vent max, rafales max, pluie,UV max2 jours passés par défaut, 60 au premier appel, 92 au plusVariables calculéesBaisse de température = max(0, température max d'hier -d'aujourd'hui)Variation de pression = pression du jour - pression de la veilleÉcart dans la journée = max - minAltitude du lieuAir (Open-Meteo Air Quality)Moyenne du jour : PM2,5, PM10, poussièresMaximum du jour : dioxyde d'azote, ozone, indice européen dequalité de l'air, pollens (somme des maximums de six espèces)UV : celui de la prévision prime, celui de l'air complèteEnregistrementGarde les jours jusqu'à aujourd'hui et au plus 92 jours en arrièreAujourd'hui et hier sont rafraîchis à chaque appelUn échec réseau n'écrit rien
Logigramme : Météo et qualité de l'air de ton lieu de vie

Les valeurs utilisées

Nom dans le codeValeurRôleOù
MAX_PAST_DAYS92Plafond d'Open-Meteo pour les jours passéssrc/trevor/navigator/environment.py:23
BACKFILL_DAYS60Historique demandé à l'activationsrc/trevor/navigator/environment.py:24
place_key2 décimalesLieu arrondi à environ 1 kmsrc/trevor/navigator/environment.py:54
timeout10 sDélai de chaque appelsrc/trevor/navigator/environment.py:127
unités°C ; % ; hPa ; km/h ; mm ; µg/m³ ; grains/m³ ; mUnités des variablessrc/trevor/navigator/environment.py:28-48
niveau de preuvemodéré, faible, aucuneNiveau de preuve noté pour chaque variable d'après la recherche du 7 octobre 2026 (température min et max, baisse de température, température ressentie, vent, PM2,5 : modéré ; UV, poussières, pollens : aucune)src/trevor/navigator/environment.py:27-48

Ce qui est affiché

Une table jour par jour des variables, avec l'attribution « Open-Meteo, CAMS (Copernicus) ». Rien ne dit que ces variables causent une crise.

Un exemple chiffré

Calcul exécuté avec le code : le 4 novembre, maximum 12,0 °C, minimum 4,0 °C, pression 1015,0 hPa ; le 5 novembre, maximum 7,5 °C, minimum 1,0 °C, pression 1008,2 hPa. Pour le 5 novembre : baisse de température 4,5 °C, variation de pression -6,8 hPa, écart dans la journée 6,5 °C.

Ce que cet algorithme ne sait pas faire

Validation. Les niveaux de preuve par variable viennent d'une recherche du 7 octobre 2026 résumée dans le code ; aucune référence n'est citée dans environment.py (voir docs/NAVIGATEUR_PERSONNEL.md). Les formules (baisse, variation, écart) sont de simples différences.

Code : src/trevor/navigator/environment.py (fetch_days, parse_forecast, parse_air, record, location_of)

Mesures du jour de la montre : pas, pouls, HRV, température, stress, et signaux repérés

Trévor range chaque jour les mesures de ta montre ou de ta bague (une valeur par jour), écarte les valeurs impossibles, complète l'écart de température quand l'appareil donne seulement la température, puis compare tes 7 derniers jours aux 30 jours d'avant. Il liste aussi des signaux factuels (oxygène bas, pouls élevé, HRV basse, température, respiration, nuits courtes). Ce n'est pas un dispositif médical validé.

Où tu le vois : Récapitulatif « Tes mesures : moyenne des 7 derniers jours » et « Signaux repérés » du bot, courbes du journal, suivi du jour, écran « Ma santé » de la montre, phrases de coaching sans chiffre.

Ce que l’algorithme lit

Le calcul, étape par étape

Nettoyage d'une journéeGarde seulement les mesures connues, en nombresÉcarte : oxygène hors de 50 à 100 ; pouls hors de 25 à 250 ;sommeil hors de 0 à 1440 min ; pas hors de 0 à 200 000 ; HRV nulleou au-dessus de 400 ms ; fréquence respiratoire hors de 4 à 60 ;écart de température hors de -5 à 5 ; température cutanée hors de25 à 42 °CUne température absolue reçue comme écart (25 à 42) est rangéecomme températureJournée d'aujourd'hui ?ouinonMarquée « partielle » : sansles pas ni le pouls du momentdans les courbes, lesmoyennes et le modèle ;seules les mesures de la nuit(sommeil, nuit, HRV,température) comptentJournée complèteFusion des sourcesUne entrée par jour : pour une même mesure, la dernière sourcegagneOura et Fitbit passent en dernier, donc priment sur les fichierset l'oxymètre saisiUn jour complet reçu ensuite remplace la version « partielle »Écart de températureSi la montre donne seulement la température : écart = températurede la nuit moins la médiane des nuits des 30 jours précédents,avec au moins 3 nuitsUn écart fourni par l'appareil est gardé tel quelMoyennesMoyenne des 7 derniers jours et moyenne des 30 jours précédentspour dix mesures (pas, sommeil, pouls au repos, HRV, oxygène,récupération, écart de température, température, respiration,bruit)Une différence est écrite si elle atteint 5 % de la référence (ou1 si la référence vaut 0), sauf pour l'écart de températureSignaux repérés (si l'interprétation est activée)Oxygène nocturne d'un jour sous 92 %Pouls au repos d'au moins 10 bpm au-dessus de la médiane des 30jours d'avant (au moins 5 jours)HRV à 75 % ou moins de la médiane des 30 jours d'avant (au moins 5jours)Écart de température d'au moins +0,5 °CFréquence respiratoire de 20/min ou plusMoins de 5 h de sommeil 3 nuits de suite (nuits de 2 h ou plusseulement)Phrases sans chiffre pour le coachingJusqu'à trois phrases : sommeil plus court ou plus long de 45 minou plus, pas en baisse ou en hausse de 20 %, pouls au repos de 7bpm ou plus au-dessus ou en dessous, récupération sous 60 ou HRVen baisse de 15 %, oxygène récent sous 92 %, température d'aumoins 0,5 °C
Logigramme : Mesures du jour de la montre : pas, pouls, HRV, température, stress, et signaux repérés

Les valeurs utilisées

Nom dans le codeValeurRôleOù
SUMMARY_KEYSsteps, sleep_minutes, resting_hr, hrv, spo2, readiness, temp_deviation, skin_temp, respiratory_rate, noise_dbMesures résuméessrc/trevor/wearables/service.py:49
NIGHT_KEYSnight, sleep_minutes, hrv, skin_temp, temp_deviationMesures de la nuit gardées dans une journée partiellesrc/trevor/wearables/service.py:48
seuil de différence5 %Différence affichée si elle atteint 5 % de la référencesrc/trevor/wearables/service.py:399
TEMP_BASELINE_DAYS30Fenêtre de la médiane de la températuresrc/trevor/wearables/models.py:112
TEMP_BASELINE_MIN3Nuits minimales pour un écart de températuresrc/trevor/wearables/models.py:113
signal pouls+10 bpmPouls au repos vs médiane des 30 jours d'avant (5 jours minimum)src/trevor/wearables/service.py:488
signal HRV0,75 x référenceHRV d'au moins 25 % sous la médianesrc/trevor/wearables/service.py:490
signal température0,5 °CÉcart de température cutanéesrc/trevor/wearables/service.py:492
signal respiration20 /minFréquence respiratoiresrc/trevor/wearables/service.py:494
signal sommeil300 min, 3 nuits, 120 min minimumMoins de 5 h trois nuits de suite ; sous 2 h la nuit ne compte passrc/trevor/wearables/service.py:497-505
bruit ambiantdB(A)Exposition sonore lue par la montre ; aucun son n'est gardésrc/trevor/wearables/models.py:31
stress_score/100Score de stress de la montre (moyenne du jour pour Samsung) ; non repris dans le récapitulatif, lu par le modèle de risquesrc/trevor/wearables/files.py:314

Ce qui est affiché

Pour chaque mesure : valeur moyenne des 7 derniers jours, écart avec les 30 jours précédents si assez grand, et, si l'interprétation est activée, une liste de signaux factuels avec la date. Exemple de ligne : « Fréquence cardiaque au repos : 58 bpm (+6 vs 30 jours précédents) ». Les signaux sont présentés comme des faits à discuter avec ton équipe soignante.

Un exemple chiffré

Calcul exécuté avec le code, au 6 novembre 2026 : 24 jours à 60 bpm de pouls au repos, puis le 30 octobre 71 bpm et un oxygène de 91 %. Résultat : deux signaux le 30 octobre, « SpO2 nocturne 91 % » et « FC repos 71 bpm (référence 60) ». Autre exemple : 7 nuits de température cutanée alternant 33,1 et 32,9, puis 34,0 : écart calculé +0,9 °C (médiane des nuits d'avant : 33,1).

Ce que cet algorithme ne sait pas faire

Validation. Les bornes de plausibilité, les 5 %, 10 bpm, 25 % de HRV, 0,5 °C et 5 h sont des choix de Trévor. Le code indique que 20 respirations par minute est un seuil usuel de polypnée chez l'adulte, utilisé dans les scores d'alerte précoce (sans référence citée), et que 92 % est un seuil courant d'alerte des oxymètres grand public. La fenêtre de 30 jours pour la température est dite « comme Oura, Fitbit et Apple » dans le code, sans référence. Ce n'est pas un dispositif médical validé et ces signaux ne sont pas appris sur des données de personnes vivant avec la drépanocytose.

Code : src/trevor/wearables/service.py (_day_rows, series, summary, summary_text, qualitative_summary, grounded_values, signals, handle_webhook), src/trevor/wearables/models.py (clean_day, derive_temp_deviation, merge_days), src/trevor/storage/database.py (upsert_wearable_days, wearable_days), src/trevor/wearables/files.py, src/trevor/wearables/day_view.py

Quinze jours de « moments » : bilan de tes moments difficiles et de l'environnement

Si tu l'actives, Trévor te demande deux fois par jour pendant quinze jours comment tu te sens là, maintenant (bien, moyen, pas bien). À la fin, il compare les jours difficiles aux autres jours sur l'environnement et écrit au plus deux conditions qui diffèrent, sans parler de cause.

Où tu le vois : Questions du bot à 10 h–11 h et 16 h–17 h ; bilan envoyé le lendemain de la fin de la période.

Ce que l’algorithme lit

Le calcul, étape par étape

Activation explicite ?ouinonPériode de 15 jours à partird'aujourd'huiJamais par défaut : aucunequestionCréneauxMatin à 10 h ou 11 h, après-midi à 16 h ou 17 h (heure de Genève),au plus deux questions par jourAucune question à l'hôpital, après 3 rappels ignorés, pour uncompte bloqué ou non patientRéponsesBien = 2, moyen = 1, pas bien = 0 ; 120 réponses gardées au plusCréneau le plus difficileAvec au moins 4 réponses matin et 4 l'après-midi : si la part de «pas bien » diffère d'au moins 25 points, le créneau le plusdifficile est citéJours difficiles et autres joursJour difficile : au moins une réponse « pas bien » ; autre jour :aucune réponse « pas bien »Il faut au moins 3 jours de chaque sorteÉcart standardisé d'au moins0,5 pour une variable ?ouinonVariable retenue (au plus 2,les plus fortes) : moyennedes jours difficiles et desautres joursRien n'est cité
Logigramme : Quinze jours de « moments » : bilan de tes moments difficiles et de l'environnement

Les valeurs utilisées

Nom dans le codeValeurRôleOù
BURST_DAYS14Durée de la période (aujourd'hui + 14 jours = 15 jours)src/trevor/navigator/ema.py:20
SLOT_HOURSam 10-11, pm 16-17Heures de Genève où un créneau peut partirsrc/trevor/navigator/ema.py:21
MAX_LOG120Réponses gardéessrc/trevor/navigator/ema.py:22
MIN_DAYS_PER_GROUP3Jours minimaux par groupesrc/trevor/navigator/ema.py:23
MIN_EFFECT0.5Écart standardisé minimal (d de Cohen)src/trevor/navigator/ema.py:24
MAX_CONDITIONS2Conditions citées au plussrc/trevor/navigator/ema.py:25
SCOREgood 2, mid 1, bad 0Valeur des réponsessrc/trevor/navigator/ema.py:26
écart de créneau0.25Différence de part de « pas bien » pour citer un créneausrc/trevor/navigator/ema.py:122

Ce qui est affiché

« Sur N moments : X bien, Y moyen, Z pas bien », éventuellement le créneau le plus difficile, et au plus deux phrases du type « Les jours moins faciles, [condition] : moyenne A contre B ». Une dernière phrase rappelle que ces chiffres sont des repères sur quinze jours et n'indiquent jamais une cause. Les réponses ne servent pas aux alertes de crise.

Un exemple chiffré

Calcul exécuté avec le code : sur trois jours difficiles où la température maximale vaut 2, 4 et 3 °C et trois autres jours où elle vaut 8, 9 et 10 °C, l'écart standardisé est -1,93 ; sa valeur absolue dépasse 0,5, donc cette variable est retenue (moyenne 3,0 contre 9,0).

Ce que cet algorithme ne sait pas faire

Validation. Le principe d'évaluation écologique momentanée est cité dans le code ; 0,5 comme taille d'effet, 3 jours et 25 points sont des choix de Trévor sans étude citée. Pas de test statistique.

Code : src/trevor/navigator/ema.py (due_slot, answer, summary, _group_stats, summary_lines), src/trevor/navigator/environment.py (VARIABLES)

Ma nuit : ta normale, nuits plus basses, durées sous 90 % et alertes

Trévor compare l'oxygène moyen de chaque nuit à ta propre normale des 30 nuits précédentes et marque les nuits nettement plus basses. Il signale aussi les durées sous 90 %, une série de nuits basses et un oxygène très bas mesuré, et c'est alors la sécurité qui passe avant tout. Ce n'est pas un diagnostic.

Où tu le vois : Écran « Ma nuit » du bot et GET /api/phone/nuit ; alerte douce facultative (éteinte par défaut) envoyée au plus une fois par jour.

Ce que l’algorithme lit

Le calcul, étape par étape

Normale de la personnePour chaque nuit : médiane et écart robuste des moyennes des 30nuits précédentes (qualité non faible)Écart robuste = 1,4826 x MAD, au moins 0,7 pointAu moins 7 nuits, sinon pas de normalez de la nuit <= -1,5 ?ouinonNuit « plus basse que tanormale » (⚠️) ; z = (moyenne- médiane) / écart, plafonnéà ±4Nuit ordinaireCompteursNuits basses sur 14 joursSérie en cours : nuits basses de suite jusqu'à la dernière (lanuit du jour pas encore arrivée est sautée)Nuits avec du temps sous 90 % : p90 supérieur à 0Plus grande part sous 90 %Série de 3 nuits basses ouplus ?ouinonPhrase « parle-en à tonéquipe de soins dans lesprochains jours » ; alertedouce si tu l'as activéePas de phrase de répétitionMoyenne de la dernière nuitutilisable (hier ouaujourd'hui) <= 88 %, ouoxymètre <= 88 % ?ouinonMessage d'urgence en tête del'écran : appeler lesurgences sans attendre (lenuméro dépend de ton pays ;144 en Suisse)Message de sécurité généralen têteSueurs de la nuitPhrase affichée seulement avec au moins 10 nuits (90 jours) oùl'oxygène utilisable et la réponse sur les sueurs existent, aumoins 3 nuits basses avec sueurs, et une part de nuits basses avecsueurs au moins double de celle sans sueurs (au moins 5 %)
Logigramme : Ma nuit : ta normale, nuits plus basses, durées sous 90 % et alertes

Les valeurs utilisées

Nom dans le codeValeurRôleOù
NIGHT_TOO_FEW7Nuits mesurées nécessaires pour parler de « ta normale »src/trevor/wearables/service.py:1068
NIGHT_DROP_Z-1.5 (crisis.DROP_Z)Une nuit est « en baisse » à 1,5 écart ou plus sous la normalesrc/trevor/wearables/crisis.py:189
BASELINE_DAYS30Nuits antérieures de la normalesrc/trevor/wearables/crisis.py:121
MIN_SD oxy_mean0.7Écart minimal de la normale d'oxygène (points)src/trevor/wearables/crisis.py:166
night_spo2_very_low88 %Oxygène très bas : urgence (« à valider par les HUG »)data/emergency_thresholds.json:11
night_spo2_repeated3 nuitsNuits basses de suite avant la phrase de répétitiondata/emergency_thresholds.json:12
sweat n_both10Nuits minimales pour la phrase sur les sueurssrc/trevor/wearables/service.py:1136
fenêtre sueurs90 joursPériode de l'association entre sueurs et nuits bassessrc/trevor/wearables/service.py:1155
jours affichés14Nuits montrées à l'écransrc/trevor/conversation/night_screen.py:102

Ce qui est affiché

Un écran en deux messages : sécurité d'abord (urgence ou rappel), ta normale (« oxygène moyen X %, sur N nuits »), une ligne par nuit (date, oxygène moyen, sommeil, drapeaux ⚠️ 🔄 👍 👎 💦), puis les nuits plus basses, les durées sous 90 %, l'avertissement sur la qualité, la divergence montre et réponse, les sueurs, la série de nuits basses, l'avertissement sur les capteurs et les conseils généraux. Le seuil bas de ta normale s'affiche en interne (low_cut = médiane - 1,5 x écart) sans apparaître dans le texte.

Un exemple chiffré

Calcul exécuté avec le code : 8 nuits à 95, 95,5, 96, 95, 96,5, 95,5, 95 et 96 % donnent une médiane de 95,5 et un écart de 0,74. Une nuit à 94,0 % a z = (94 - 95,5) / 0,74 = -2,0, donc elle est marquée plus basse (seuil bas à 94,4 %). Une nuit à 95,0 % a z = -0,7 et n'est pas marquée.

Ce que cet algorithme ne sait pas faire

Validation. La médiane et l'écart robuste (MAD) sont des méthodes statistiques standard, mais les seuils (7 nuits, 30 nuits, -1,5 écart, 3 nuits de suite) sont des choix de Trévor : le fichier d'urgence dit pour 3 nuits « aucune étude ne fixe ce nombre ». Le seuil 88 % est décrit comme un seuil d'hypoxémie usuel en pneumologie, non propre à la drépanocytose, avec un capteur grand public non validé ; texte et seuil à valider par les HUG (M-OXY-1). Le lien entre hypoxémie nocturne et complications de la drépanocytose est documenté dans docs/NUIT_SOMMEIL_OXYGENE.md (par exemple Hargrave 2003, PMID 12393400 ; Quinn 2005, PMID 16173973), mais pas de règle chiffrée de Trévor en vient. Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/service.py (night_view, _night_pairs, _recent_oximeter, night_alert_due), src/trevor/conversation/night_screen.py (blocks, row, payload), src/trevor/wearables/crisis.py (_robust, _z, DROP_Z), data/emergency_thresholds.json, src/trevor/conversation/reminders.py (alerte douce, vers 1565)

Oxygène de la nuit : moyenne, creux, temps sous le seuil, indice de désaturation

Quand ta montre ou ta bague envoie une série de mesures d'oxygène pendant la nuit, Trévor la résume en quelques chiffres : moyenne, creux, part de la nuit sous 92, 90 et 88 %, et nombre de chutes par heure. Ces chiffres alimentent l'écran « Ma nuit » et ta normale. Ce n'est pas un dispositif médical validé.

Où tu le vois : Écran « Ma nuit » du bot (ligne de chaque nuit : oxygène moyen), application (GET /api/phone/nuit), courbes « Mes repères » (oxygène moyen, creux, temps sous 90 %, chutes par heure).

Ce que l’algorithme lit

Le calcul, étape par étape

Tri des mesuresGarde les valeurs de 50 à 100 %Trie par heure ; au plus 20 000 mesuresPas typique entre deux mesuresMédiane des écarts entre mesures successivesPas de plus de 5 minutes ?ouinonSérie trop espacée :seulement la moyenne simpleet la valeur la plus basse,sans pourcentage de temps niindice ; qualité au mieux «moyenne »Suite du calcul pondéré parle tempsPoids de chaque mesurePoids = durée jusqu'à la mesure suivante, si elle est de 5 minutesou moins, sinon 0Dernière mesure : pas typiqueDurée valide = somme des poidsMoyenne et creuxMoyenne pondérée par le tempsCreux = plus basse valeur tenue sur deux mesures de suite (la plushaute des deux, puis le minimum)Temps sous le seuilPourcentage du temps valide sous 92, sous 90 et sous 88 %Une mesure au moins chaqueminute et 2 h valides ?ouinonIndice de désaturation à 3points (odi3) et à 4 points(odi4), en événements parheure de mesure validePas d'indiceCouverture, mouvement, qualitéCouverture = durée valide / durée de la nuit (0 à 1)Qualité : bonne, moyenne ou faible (voir l'algorithme sur laqualité des nuits)
Logigramme : Oxygène de la nuit : moyenne, creux, temps sous le seuil, indice de désaturation

Les valeurs utilisées

Nom dans le codeValeurRôleOù
THRESHOLDS(92, 90, 88)Seuils du temps cumulé sous la saturationsrc/trevor/wearables/night.py:26
MAX_GAP_S300Au-delà de 5 minutes sans mesure, le temps n'est pas compté comme mesurésrc/trevor/wearables/night.py:27
ODI_MAX_STEP_S60Pas typique maximal pour calculer un indice de désaturationsrc/trevor/wearables/night.py:28
ODI_MIN_VALID_MIN120Minutes valides minimales pour un indicesrc/trevor/wearables/night.py:29
BASELINE_WINDOW_S120Niveau de référence d'un événement : maximum des 2 minutes précédentessrc/trevor/wearables/night.py:30
MAX_SAMPLES20000Nombre maximal de mesures luessrc/trevor/wearables/night.py:35
drop dans _count_events3 et 4 pointsUn événement est une baisse d'au moins 3 (odi3) ou 4 points (odi4) sous la référence, tenue sur deux mesuressrc/trevor/wearables/night.py:93-94,110-123

Ce qui est affiché

Un résumé par nuit : mean (moyenne, 1 décimale), min (creux), p92, p90, p88 (% du temps valide), odi3 et odi4 (par heure, seulement si le pas est de 60 s ou moins et la mesure valide d'au moins 2 h), valid_min, coverage, motion, qualité. Un événement se termine quand la saturation remonte à moins de (seuil - 1) points de sa référence ; une seule mesure basse isolée ne compte pas.

Un exemple chiffré

Calcul exécuté avec le code : 480 mesures, une par minute, à 96 %, dont 3 mesures à 91 % et 10 mesures à 89 %, nuit de 480 minutes. Résultat : moyenne 95,8 ; creux 89 ; p92 2,7 % ; p90 2,1 % ; p88 0 % ; odi3 et odi4 à 0,2 par heure ; couverture 1,0 ; qualité « bonne ».

Ce que cet algorithme ne sait pas faire

Validation. Les définitions de l'indice de désaturation (baisse de 3 ou 4 points sous le maximum des 2 minutes précédentes) suivent l'usage décrit dans docs/NUIT_SOMMEIL_OXYGENE.md (qui cite Berry 2012, règles AASM, PMID 23066376). Les seuils de qualité, les 5 minutes, les 2 minutes et la règle des deux mesures de suite sont des choix de Trévor posés sans étude propre. Les capteurs grand public sont jugés dans la littérature citée par le dépôt (Walzel 2023, PMID 38005550) sur de jeunes personnes en bonne santé, pas sur la drépanocytose. Ce n'est pas un dispositif médical validé.

Code : src/trevor/wearables/night.py (summarize_oxygen, _count_events, oxygen_from_aggregate), src/trevor/wearables/files.py (night_from_item), src/trevor/wearables/oura.py, src/trevor/wearables/fitbit.py

Qualité d'une nuit, nuits ignorées et choix de la source

Trévor note chaque nuit mesurée « bonne », « moyenne » ou « faible » selon la durée mesurée, la couverture et le mouvement. Une nuit « faible » reste visible mais n'entre dans aucun calcul (ta normale, nuits plus basses, courbes). Quand plusieurs sources décrivent la même nuit, il garde la meilleure.

Où tu le vois : Écran « Ma nuit » (avertissement sur la qualité quand une nuit est faible), courbes « Mes repères », modèle de risque (qui ignore aussi les nuits faibles).

Ce que l’algorithme lit

Le calcul, étape par étape

Attribuer la mesure à une nuitDe 20 h à minuit : la nuit se termine le lendemainDe minuit à 10 h : le jour mêmeDe 10 h à 20 h : mesure ignoréeSérie de mesures ?ouinonQualité faible si moins de120 min valides, oucouverture sous 50 %, oumouvement au-dessus de 30 %Résumé seul : faible dans lesmêmes cas, sinon jamais mieuxque « moyenne »Série : moyenne ou bonneMoyenne si couverture sous 80 %, ou mouvement au-dessus de 15 %,ou moins de 30 mesuresSinon bonnePlusieurs sources pour la même nuitPour l'oxygène : série avant résumé, puis meilleure qualité, puisplus de minutes validesPour le sommeil : stades de l'appareil avant sans stades, puisplus de champs, puis qualitéÀ égalité, la source arrivée en dernier gagne (Oura et Fitbitpassent après les autres)Qualité « faible » ?ouinonLa valeur devient absente(None) dans les calculs : nita normale, ni nuit basse, nicourbeLa nuit compte dans lescalculs
Logigramme : Qualité d'une nuit, nuits ignorées et choix de la source

Les valeurs utilisées

Nom dans le codeValeurRôleOù
MIN_VALID_MIN120Sous 2 h de mesure valide, qualité faiblesrc/trevor/wearables/night.py:31
MIN_COVERAGE0.5Sous 50 % de la nuit couverte, qualité faiblesrc/trevor/wearables/night.py:32
MOTION_HIGH0.30Plus de 30 % de la nuit en mouvement : qualité faiblesrc/trevor/wearables/night.py:33
MOTION_MID0.15Plus de 15 % en mouvement : qualité moyennesrc/trevor/wearables/night.py:34
couverture moyenne0.8Série couverte à moins de 80 % : qualité moyennesrc/trevor/wearables/night.py:131
nombre de mesures30Moins de 30 mesures : qualité moyennesrc/trevor/wearables/night.py:131
heures de nuit20 h à 10 hFenêtre d'attribution d'une mesure à une nuitsrc/trevor/wearables/night.py:50-58

Ce qui est affiché

Étiquette de qualité par nuit (bonne, moyenne, faible). `oxy_usable` et `sleep_usable` renvoient la nuit seulement si la qualité n'est pas « faible » (et, pour l'oxygène, si une moyenne existe). Une saisie à la main reçoit 480 minutes valides, donc « moyenne ».

Un exemple chiffré

Calcul exécuté avec le code : la série de 480 mesures de l'exemple précédent (couverture 1,0, 480 minutes valides, 480 mesures) donne « bonne ». Un résumé sans série (moyenne et minimum seuls) donne au mieux « moyenne ».

Ce que cet algorithme ne sait pas faire

Validation. Tous les seuils (2 h, 50 %, 30 %, 15 %, 80 %, 30 mesures) sont des choix de Trévor, sans étude citée dans le code ni dans docs/NUIT_SOMMEIL_OXYGENE.md pour ces valeurs précises. Ils ne viennent ni d'un clinicien ni d'un apprentissage sur des données.

Code : src/trevor/wearables/night.py (assign_night, quality_of, oxy_usable, sleep_usable, scalars, by_date, _oxy_rank, _sleep_rank, clean_night), src/trevor/wearables/service.py (night_records)

Saisie à la main : oxygène de la nuit, oxymètre au doigt, nuit ressentie et heure du coucher

Quand ta montre n'envoie pas l'oxygène de la nuit, tu peux l'écrire toi-même, ainsi qu'une valeur d'oxymètre au doigt, ta nuit ressentie et l'heure approximative du coucher. Trévor range ces saisies comme des mesures, sans les corriger.

Où tu le vois : Bot : « 🫁 Mon oxygène (SpO2) », « Ma nuit » (bouton de saisie), « Ma journée » (question sur la nuit).

Ce que l’algorithme lit

Le calcul, étape par étape

Oxygène de la nuitLit jusqu'à trois nombres de 2 ou 3 chiffres (virgule ou point)Refuse si moins de deux nombres ou si l'un est hors de 50 à 100Rangement des nombresTrie les nombres : le plus bas est le creux, le plus haut le pic,celui du milieu la moyenneAvec deux nombres : le plus haut est la moyenne, le plus bas lecreux, pas de picEnregistrementEnregistré au jour d'aujourd'hui (jour du réveil), source « manual», avec 480 minutes validesLe bloc passe par le même nettoyage que les autres sources :qualité « moyenne »Le pic est affiché mais ne pèse dans aucun calculOxymètre au doigtPremier nombre du texte entre 70 et 100Gardé dans le profil (60 valeurs) et dans les mesures du jour(source « oximeter »)Sous 92 % : message de sécurité ; il faut appeler les urgences (lenuméro dépend de ton pays) sans attendre si la valeur reste sous92 % après deux minutes de repos ou si tu as du mal à respirerNuit ressentie et coucherUne entrée par jour (la nouvelle remplace l'ancienne), 60 nuits auplusTrois nuits « mal » sur 7 jours : une phrase dans « Ma journée »,jamais une notificationSi la montre a déjà mesuré la durée, le bot la montre et ne poseque la question du ressenti
Logigramme : Saisie à la main : oxygène de la nuit, oxymètre au doigt, nuit ressentie et heure du coucher

Les valeurs utilisées

Nom dans le codeValeurRôleOù
plage de saisie nuit50 à 100Chaque nombre de la saisie de nuitsrc/trevor/conversation/night_screen.py:90
valid_min manuel480Minutes valides attribuées à une saisie manuellesrc/trevor/conversation/night_screen.py:132
plage oxymètre70 à 100Valeur d'oxymètre acceptéesrc/trevor/conversation/spo2_screens.py:41
LOW92.0 (ppg_spo2.LOW)Au-dessous, message de sécurité sur la valeur saisiesrc/trevor/conversation/spo2_screens.py:24
KEEP (oxymètre)60Valeurs d'oxymètre gardéessrc/trevor/conversation/spo2_screens.py:25
KEEP_NIGHTS60Nuits ressenties gardéessrc/trevor/navigator/sleep.py:22
BAD_NIGHTS_ADVICE / ADVICE_WINDOW_DAYS3 / 7Nuits « mal » sur 7 jours avant le conseilsrc/trevor/navigator/sleep.py:23-24
SELF_SLEEP_Zbien +1,0 ; moyen 0 ; mal -1,0Nuit déclarée vue comme un écart, sur l'échelle des mesures de la montre (utilisé par la forme du jour)src/trevor/navigator/sleep.py:26

Ce qui est affiché

Une nuit d'oxygène enregistrée (moyenne, creux, pic éventuel) visible dans « Ma nuit », une valeur d'oxymètre dans les courbes et les alertes de valeurs, une nuit ressentie rangée dans le profil. Sous 92 % : « Refais la mesure après deux minutes de repos, assis, les mains chaudes. Si la valeur reste sous 92 %, appelle maintenant. »

Un exemple chiffré

Calcul exécuté avec le code d'analyse du texte : « 94 88 97 » donne moyenne 94, creux 88, pic 97 ; « 93,5 90 » donne moyenne 93,5, creux 90, pas de pic ; « 96 » seul est refusé.

Ce que cet algorithme ne sait pas faire

Validation. Règles d'ergonomie et de plausibilité posées par Trévor, sans étude. Le conseil « trois nuits mal » s'appuie sur le lien entre sommeil et douleur cité dans navigator/sleep.py (NHLBI 2014 ; Moscou-Jackson et coll. 2015, PMID 25842346), mais le nombre trois est un choix de Trévor.

Code : src/trevor/conversation/night_screen.py (parse_night_values, on_night_enter), src/trevor/conversation/spo2_screens.py (parse_value, on_spo2_enter), src/trevor/navigator/sleep.py, src/trevor/conversation/daily_screen.py (screen_sleep_night, on_sleep_bed)

Sommeil de la nuit : durée, efficacité, éveils

Trévor reprend ce que ton appareil dit de ta nuit (durée endormie, temps au lit, éveils, stades) et calcule seulement ce qui peut l'être sans rien inventer, comme l'efficacité du sommeil. Il compare ensuite ta nuit à ta propre normale pour repérer une nuit fragmentée.

Où tu le vois : Écran « Ma nuit » (durée de sommeil de chaque nuit), courbes « Mes repères » (efficacité, éveils, sommeil profond), phrase de la forme du jour.

Ce que l’algorithme lit

Le calcul, étape par étape

Segments vers résuméTemps au lit = de la session (ou du premier au dernier segment)Temps endormi = somme des segments endormis (profond, léger,paradoxal, endormi)Latence = du début de session au premier segment endormi,seulement si la session commence éveillée ou au litÉveils (WASO) = segments éveillés après l'endormissement,seulement si la source fournit des segments « éveillé »Bornes plausiblesMinutes entre 0 et 1440 (latence 600, éveils 1000, profond 1000,paradoxal 1000)Nombre d'éveils entre 0 et 200L'appareil donnel'efficacité ?ouinonValeur gardée telle quelle (0à 100)Calculée = 100 x endormi / aulit, seulement si les deuxdurées existent et que letemps au lit est au moinségal au temps endormiÉtiquettesStades remplis : « staged »Qualité « moyenne » si stades, « bonne » si endormi et efficacitéconnus, sinon « moyenne »Repères de l'écranEfficacité 85 % ou plus : bonne ; moins de 75 % : mauvaise ; entreles deux : moyenne (montre)Nuit fragmentée : éveils au moins 1,5 écart au-dessus de tanormale ou efficacité au moins 1,5 écart en dessous
Logigramme : Sommeil de la nuit : durée, efficacité, éveils

Les valeurs utilisées

Nom dans le codeValeurRôleOù
watch_sleep bonne85Efficacité à partir de laquelle la montre est dite « bonne »src/trevor/wearables/service.py:1103
watch_sleep mauvaise75Efficacité sous laquelle la montre est dite « mauvaise »src/trevor/wearables/service.py:1103
seuil de fragmentation1.5Écarts de ta normale (éveils en hausse ou efficacité en baisse)src/trevor/wearables/service.py:1106-1107,1109
MIN_SD sleep_eff / sleep_waso3.0 / 10.0Écarts-types minimaux de la normale pour l'efficacité et les éveilssrc/trevor/wearables/crisis.py:164-165
BASELINE_DAYS30Nuits antérieures utilisées pour la normalesrc/trevor/wearables/crisis.py:121
MIN_BASELINE7Nuits mesurées nécessaires pour une normalesrc/trevor/wearables/crisis.py:122

Ce qui est affiché

Par nuit : durées en minutes, efficacité en %, nombre d'éveils, stades si connus. À l'écran : la durée endormie au format « 7 h 00 », un indicateur de fragmentation (utilisé dans la vue) et, avec la réponse « As-tu bien dormi ? », un signe 🔄 quand la montre et ta réponse divergent (réponse « oui » avec efficacité sous 75 %, ou « non » avec efficacité d'au moins 85 %).

Un exemple chiffré

Calcul exécuté avec le code : 480 minutes au lit et 420 minutes endormi, sans efficacité fournie, donnent une efficacité de 88 % (100 x 420 / 480) et une qualité « bonne ». 88 % est au-dessus de 85 %, donc la montre est « bonne ».

Ce que cet algorithme ne sait pas faire

Validation. L'efficacité (endormi sur au lit) est la définition usuelle. Le repère 85 % vient du rapport de la National Sleep Foundation (Ohayon 2017, PMID 28346153) ; docs/NUIT_SOMMEIL_OXYGENE.md précise que la valeur 85 % n'a pas été relue dans ce rapport (non vérifié). Le seuil 75 % et le seuil de 1,5 écart sont des choix de Trévor sans étude citée. La précision des montres grand public sur le sommeil est discutée dans Chinoy 2021 (PMID 33378539) et Haghayegh 2019 (PMID 31778122), cités dans ce document.

Code : src/trevor/wearables/night.py (sleep_summary, sleep_from_segments, normalise_stage), src/trevor/wearables/service.py (night_view), src/trevor/conversation/night_screen.py (row), src/trevor/wearables/oura.py, src/trevor/wearables/fitbit.py

Estimation de l'oxygène par l'appareil photo du téléphone (expérimentale)

Le téléphone pose ton doigt sur l'objectif et le flash, mesure comment la lumière pulse, et envoie à Trévor un rapport R, la qualité du signal et le pouls. Trévor convertit R en une estimation de SpO2 avec une fourchette, plus large tant que tu n'as pas calibré avec un oxymètre de référence. C'est expérimental et ce n'est pas un dispositif médical validé.

Où tu le vois : Application Coach Drépano (carte « SpO2 par la caméra ») et bot (« Mon oxygène » : dernière estimation, fourchette et phrase de verdict).

Ce que l’algorithme lit

Le calcul, étape par étape

R entre 0,2 et 2,5 ?ouinonSuiteMesure refusée (raison «signal »)Qualité d'au moins 0,5 ?ouinonSuiteMesure refusée (raison «qualité »)Référence hors de 70 à 100 ?ouinonMesure refusée (raison «référence »)SuiteCouples de calibrageCouples (R, valeur de référence) déjà gardés pour la même couleur,plus le couple de cette mesure si elle a une référence, un Rvalide et une qualité suffisanteAu moins 3 couplesexploitables et R variable ?ouinonDroite personnelle SpO2 = A -B x R par moindres carrés(pente décroissante exigée) ;marge = 2 x écart résiduel,au moins 2 pointsDroite universelle SpO2 = 110- 25 x R ; marge de 8 pointsValeur et fourchetteValeur = A - B x R, bornée entre 70 et 100Fourchette = valeur ± marge, bornée entre 70 et 100Valeur sous 92 ?ouinonVerdict « basse »Verdict « incertaine » si pasde calibrage personnel ou sile bas de la fourchette estsous 92, sinon « normale »RangementGarde les 90 dernières mesures dans le profil chiffré (date, R,qualité, pouls, référence, couleur, valeur, bornes, calibrée,verdict)
Logigramme : Estimation de l'oxygène par l'appareil photo du téléphone (expérimentale)

Les valeurs utilisées

Nom dans le codeValeurRôleOù
R_RANGE(0.2, 2.5)Plage plausible de Rsrc/trevor/media/ppg_spo2.py:24
DEFAULT_A, DEFAULT_B110.0, 25.0Droite universelle : SpO2 = 110 - 25 x Rsrc/trevor/media/ppg_spo2.py:25
DEFAULT_MARGIN8.0Demi-largeur de la fourchette sans calibrage (points de SpO2)src/trevor/media/ppg_spo2.py:26
MIN_QUALITY0.5Qualité minimale du signalsrc/trevor/media/ppg_spo2.py:27
MIN_PAIRS3Couples (R, oxymètre) pour une droite personnellesrc/trevor/media/ppg_spo2.py:28
LOW92.0Seuil du verdict « basse »src/trevor/media/ppg_spo2.py:29
KEEP90Mesures gardées par personnesrc/trevor/media/ppg_spo2.py:30
marge calibréemax(2, 2 x écart résiduel)Fourchette avec une droite personnelle (écart résiduel au moins 1)src/trevor/media/ppg_spo2.py:48,58
plage des couplesR 0,2 à 2,5 ; SpO2 70 à 100Couples gardés pour l'ajustementsrc/trevor/media/ppg_spo2.py:35

Ce qui est affiché

Une valeur arrondie, une fourchette (bas et haut), si elle est calibrée, et un verdict. Phrases du bot : « Valeur basse. », « La fourchette est trop large pour conclure. » ou « Aucune alerte. Cette estimation ne remplace pas un oxymètre de pouls. » Le verdict « normale » exige une droite personnelle et que le bas de la fourchette reste au moins à 92. Sous 92 ou en cas de malaise, un oxymètre de pouls puis l'équipe soignante ou le 144 passent avant tout.

Un exemple chiffré

Calcul exécuté avec le code : R = 0,6 et qualité 0,8 sans calibrage donnent 95 % (110 - 25 x 0,6), fourchette de 87 à 100 %, verdict « incertaine ». Avec quatre couples (0,5 ; 98), (0,7 ; 93), (0,9 ; 88), (0,6 ; 95,5), la droite devient 110,5 - 25 x R avec un écart résiduel de 1 ; R = 0,6 donne 96 % entre 94 et 98 %, verdict « normale » ; R = 0,95 donne 87 % entre 85 et 89 %, verdict « basse ».

Ce que cet algorithme ne sait pas faire

Validation. Le principe (rapport des rapports, droite décroissante) est celui de la photopléthysmographie décrite dans le code ; les constantes 110, 25 et la marge de 8 points sont des valeurs de Trévor, la droite universelle étant déclarée non validée. Le seuil 92 est aligné sur value_alerts. Aucune étude de validation n'est citée dans le code ou dans docs/SPO2_CAMERA.md pour cette méthode. Les écarts d'oxymétrie selon la couleur de peau sont documentés par Sjoding 2020 (PMID 33326721 ; chiffres non relus dans le dépôt) et Wong 2021 (PMID 34730820). Fonction expérimentale, pas un dispositif médical validé.

Code : src/trevor/media/ppg_spo2.py (fit, estimate, add_reading, view), src/trevor/signals.py (spo2_cam_reading, last_oximeter), src/trevor/conversation/spo2_screens.py (screen_spo2), docs/SPO2_CAMERA.md

Qualité des mesures de la montre : bonne, moyenne ou insuffisante

Trévor compte sur 14 jours combien de journées ont assez de mesures utiles, et en déduit si ta montre te donne des mesures « bonnes », « moyennes » ou « insuffisantes ». Cette étiquette sert à taire une conclusion fragile et à montrer la fiabilité au poignet et dans le bot.

Où tu le vois : Champ « measure_quality » de l'écran « Ma santé » au poignet et dans l'application.

Ce que l’algorithme lit

Le calcul, étape par étape

Journée exploitableAu moins 2 mesures utiles parmi : pouls au repos, HRV, températurecutanée, écart de température, oxygène, respirationEt sommeil, s'il est connu, d'au moins 120 minutesComptageNombre de journées exploitables sur 14 jours, jours sans rien, etprésence d'une journée exploitable aujourd'hui ou hier10 jours exploitables ouplus et une journée récente?ouinonBonne6 jours ou plus et unejournée récente : moyenne ;sinon insuffisante
Logigramme : Qualité des mesures de la montre : bonne, moyenne ou insuffisante

Les valeurs utilisées

Nom dans le codeValeurRôleOù
WINDOW_DAYS14Fenêtresrc/trevor/wearables/mesure.py:16
MIN_NIGHT_COVERAGE_MIN120Sommeil minimal d'une journée exploitablesrc/trevor/wearables/mesure.py:17
GOOD_DAYS10Journées pour « bonne »src/trevor/wearables/mesure.py:19
MEDIUM_DAYS6Journées pour « moyenne »src/trevor/wearables/mesure.py:20

Ce qui est affiché

Une étiquette (bonne, moyenne, insuffisante), le nombre de jours exploitables, les trous. L'étiquette ne dit rien de la justesse des valeurs, seulement de leur régularité.

Ce que cet algorithme ne sait pas faire

Validation. Seuils (14, 10, 6, 2 h) posés par Trévor sans étude citée.

Code : src/trevor/wearables/mesure.py (usable, assess), src/trevor/wearables/watch_summary.py (_measure_quality)

Séries alignées du « tableau de bord de ta vie »

Trévor met sur le même axe des jours ce que tu vis (douleur, humeur, forme, fatigue, jours de crise), ton corps (montre, nuits, laboratoire), l'environnement, tes soins et des repères d'événements. Il ne calcule ni moyenne ni interpolation : un jour sans mesure reste vide.

Où tu le vois : Vue santé (lifecourse/health_view.py, jusqu'à 366 jours), recommandations du navigateur (90 jours), associations de findings.py et recherche longitudinale (180 jours) ; les écrans exacts qui les affichent ne sont pas tous relus.

Ce que l’algorithme lit

Le calcul, étape par étape

Axe des joursEntre 14 et 180 jours jusqu'à aujourd'hui (366 pour la vue santé)RésultatsDouleur : le maximum du jour ; humeur : la dernière valeur ;fatigue : oui/non ou niveauJour de crise : épisodes déclarés, plus tout jour où la douleurnotée est de 7 ou plus ; un jour sans crise vaut 0 là où tu asnoté quelque choseCorpsPas, sommeil, pouls au repos, HRV, oxygène, respiration,température, bruit : une valeur par jour de la montre« Ma nuit » : une valeur par nuit, seulement si la qualité n'estpas faibleForme du jour : score de récupération de la montreLaboratoire et jaune de l'œil : points épars, jamais interpolésEnvironnement et soinsVariables météo et air du jourPrises de traitement : pris = 1, manqué = 0 ; doses manquées avecleur raison ; jours « supposés » marqués à part et jamais comptéscomme preuveAntalgique de secours : prises par jour ; gestes personnelsÉvénements et semaineRepères : début de crise, transfusion, hospitalisation,interventions, gestesScores hebdomadaires de questionnaires (PROMs, PREMs) ettrajectoire de fonctionnement (CIF)
Logigramme : Séries alignées du « tableau de bord de ta vie »

Les valeurs utilisées

Nom dans le codeValeurRôleOù
MAX_DAYS180Fenêtre maximale par défautsrc/trevor/navigator/series.py:21
MIN_DAYS14Fenêtre minimalesrc/trevor/navigator/series.py:22
seuil de douleur7Un jour avec une douleur notée de 7 ou plus compte comme jour de crisesrc/trevor/navigator/series.py:157
MAX_MISSED_LISTED300Doses manquées listéessrc/trevor/navigator/series.py:76
unitéspas ; min ; bpm ; ms ; % ; /min ; °C ; dB(A) ; /hUnités des séries de la montre et des nuitssrc/trevor/navigator/series.py:29-47

Ce qui est affiché

Pour chaque série, des valeurs par jour (seulement les jours mesurés), des libellés avec leur unité et leur groupe, des événements, l'attribution « Open-Meteo, CAMS (Copernicus) ». Aucun chiffre composite.

Ce que cet algorithme ne sait pas faire

Validation. Assemblage de données, sans modèle statistique. La règle « douleur de 7 ou plus = jour de crise » est un choix de Trévor sans étude citée dans le code.

Code : src/trevor/navigator/series.py (build), src/trevor/wearables/day_view.py (series, monitor), src/trevor/lifecourse/health_view.py (_nav), src/trevor/navigator/reco_flow.py (vers 243), src/trevor/research_longitudinal.py (vers 589)

Le seuil d'oxygène bas (92 %) et les seuils proches : où ils s'appliquent et comment les régler

Trévor utilise plusieurs seuils d'oxygène à des endroits différents : 92 % pour une valeur isolée, 90 % et 88 % pour le temps passé la nuit, et 88 % pour l'urgence. Le 92 % ne se règle pas ; tu peux seulement fixer ta propre zone habituelle, qui change quand une alerte part.

Où tu le vois : Messages de saisie d'oxymètre, estimation par caméra, alertes de valeurs, signaux de la montre, « Ma nuit ».

Ce que l’algorithme lit

Le calcul, étape par étape

Valeur d'oxymètre saisieSous 92 : message de sécurité (refaire la mesure après deuxminutes de repos ; appeler les urgences si elle reste sous 92 ousi tu as du mal à respirer)Estimation par caméraValeur sous 92 : verdict « basse » ; fourchette dont le bas passesous 92 : « incertaine »Alertes de valeursUne valeur journalière sous 92 est hors norme ; selon ta zonehabituelle : alerte, habituel pour toi, ou à surveillerSignaux de la montre« SpO2 nocturne » listé si la valeur d'un jour est sous 92 (unephrase du bot « ton oxygénation nocturne est parfois basse »apparaît si la moyenne récente est sous 92)Ma nuitTemps sous 92, 90 et 88 % calculé pour chaque nuit en série ;compteur des nuits avec du temps sous 90 % ; urgence si la moyennede la dernière nuit ou l'oxymètre est à 88 % ou moins ; modèle derisque : moyenne de nuit sous 92 %Veux-tu changer le seuil ?ouinonTu peux fixer une zonehabituelle personnelle (baset haut) : elle ne bouge nile 92 % ni le 88 %, maisdécide si une valeur sous 92est une alerte ou « habituelpour toi »Le seuil reste 92 % partout
Logigramme : Le seuil d'oxygène bas (92 %) et les seuils proches : où ils s'appliquent et comment les régler

Les valeurs utilisées

Nom dans le codeValeurRôleOù
LOW92.0Seuil de la caméra et du message d'oxymètresrc/trevor/media/ppg_spo2.py:29
Metric spo2 low92Norme générale de la saturation dans les alertes de valeurssrc/trevor/value_alerts.py:68
signals spo2< 92Signal « SpO2 nocturne »src/trevor/wearables/service.py:486
qualitative spo2< 92Phrase de tendance (moyenne récente)src/trevor/wearables/service.py:444
THRESHOLDS(92, 90, 88)Temps cumulé sous ces seuils chaque nuitsrc/trevor/wearables/night.py:26
ABS_LOW_NIGHT92.0Moyenne de nuit sous laquelle le modèle de risque compte une nuit bassesrc/trevor/wearables/crisis.py:190
night_spo2_very_low88Urgence : moyenne de nuit ou oxymètre à 88 % ou moinsdata/emergency_thresholds.json:11

Ce qui est affiché

Un même mot « bas » peut venir de seuils différents selon l'écran. Aucun écran ne te permet de changer 92 % ni 88 %. Ta zone habituelle personnelle (ou celle de ton soignant) modifie seulement le niveau de l'alerte de valeur.

Un exemple chiffré

Calcul exécuté avec le code : une valeur de 91 % sans zone fixée est une « alerte » ; avec une limite basse fixée à 90 %, la même valeur devient « habituel pour toi » ; avec une limite basse fixée à 94 %, elle reste « alerte ». Une valeur de 93 % avec une limite basse à 94 % est « à surveiller ».

Ce que cet algorithme ne sait pas faire

Validation. Le fichier d'urgence présente 88 % comme un seuil d'hypoxémie usuel en pneumologie, non propre à la drépanocytose, avec capteur grand public non validé, à valider par les HUG (M-OXY-1). Le code décrit 92 % comme le « seuil courant d'alerte des oxymètres grand public » et comme un repère de sécurité. Aucune étude citée dans le code ne fixe ces valeurs pour la drépanocytose, où une désaturation à l'état stable est décrite (Quinn 2005, PMID 16173973, cité dans docs/NUIT_SOMMEIL_OXYGENE.md) : c'est la raison d'être de la zone personnelle.

Code : src/trevor/media/ppg_spo2.py, src/trevor/conversation/spo2_screens.py (on_spo2_enter), src/trevor/value_alerts.py, src/trevor/wearables/service.py (signals, qualitative_summary, night_view), src/trevor/wearables/night.py, src/trevor/wearables/crisis.py, data/emergency_thresholds.json

Zone habituelle de chaque mesure et alertes de valeurs

Trévor lit ta dernière valeur face à deux repères : la norme générale de l'adulte et ta zone habituelle, apprise sur tes propres valeurs ou fixée par toi ou ton soignant. Selon que la valeur sort de l'un, des deux ou d'aucun, il affiche « alerte », « à surveiller », « habituel pour toi » ou « rien à signaler ». Ce n'est pas un diagnostic.

Où tu le vois : Carte « Alertes de valeurs » du tableau de bord (patient et soignant), message poussé du bot pour le niveau « alerte » (une fois par mesure et par date, désactivable), alertes du tableau de bord pour fatigue et laboratoire.

Ce que l’algorithme lit

Le calcul, étape par étape

Dernière valeurGarde la dernière valeur de la série, si elle date de 3 jours auplus (valeurs de laboratoire : délai propre à chaque mesure)Valeurs de montre hors plage plausible écartées (ex. oxygène horsde 50 à 100)Une limite fixée par toi outon soignant ?ouinonElle sert de zone habituelleZone apprise : médiane ± 2,5écarts robustes des valeursdes 90 jours précédents, àpartir de 10 valeursÉcart robuste1,4826 x MAD, jamais sous un plancher propre à la mesure (oxygène0,7 ; pouls 3 ; HRV 5 ; pas 1 500 ; sommeil 30 min)La borne basse ne descend pas sous zéro, sauf pour l'écart detempératureSens qui inquièteSeul le sens qui inquiète déclenche : oxygène, HRV, sommeil, pasvers le bas ; température et bruit vers le haut ; pouls etfréquence respiratoire dans les deux sensHors norme ET hors zonehabituelle ?ouinonNiveau « alerte » : àsignaler à l'équipe soignanteVoir les trois autres casAutres niveauxDans la norme, hors zone : « à surveiller »Hors norme, dans la zone : « habituel pour toi » (information)Hors norme sans zone connue : « à surveiller », mais « alerte »pour l'oxygène nocturne et la fatigueRien de hors : « rien à signaler »Croisement fatigue et pasFatigue en alerte ou à surveiller ET pas en baisse (alerte ousurveillance, sens bas) à 2 jours ou moins : niveau « alerte »combinéMessageLe bot envoie un message seulement pour les alertes non encoreenvoyées à cette date de mesure, sauf si tu as coupé le message
Logigramme : Zone habituelle de chaque mesure et alertes de valeurs

Les valeurs utilisées

Nom dans le codeValeurRôleOù
LEARN_K2.5Largeur de la zone apprise en écarts robustessrc/trevor/value_alerts.py:41
MIN_WEAR, WEAR_DAYS10, 90Valeurs de montre pour apprendre une zone et fenêtre en jourssrc/trevor/value_alerts.py:42
spo2norme basse 92 ; plancher 0,7 ; fraîcheur 3 j ; alerte si seuleSaturation nocturne : sous 92 % hors norme ; sans zone personnelle la lecture est déjà « alerte »src/trevor/value_alerts.py:68
resting_hr50 à 100 bpm, deux sens, plancher 3Pouls au repossrc/trevor/value_alerts.py:69
respiratory_rate12 à 20 /min, deux sens, plancher 1Fréquence respiratoiresrc/trevor/value_alerts.py:70
hrvsans norme, sens bas, plancher 5 msVariabilité cardiaque : seul l'écart à ta zone comptesrc/trevor/value_alerts.py:71
temp_deviationhaut 0,5 °C, sens haut, plancher 0,2Écart de température cutanéesrc/trevor/value_alerts.py:72
sleep_minutesbas 300 min, sens bas, plancher 30Sommeil : sous 5 hsrc/trevor/value_alerts.py:73
stepssans norme, sens bas, plancher 1 500Pas par joursrc/trevor/value_alerts.py:74
fatiguehaut 7/10, sens haut, plancher 1Fatigue déclarée : au-delà de 7/10 (repère à faire valider)src/trevor/value_alerts.py:75
noise_dbhaut 70 dB(A), plancher 3Bruit ambiant moyen du joursrc/trevor/value_alerts.py:76
PLAUSIBLEoxygène 50 à 100 ; pouls 25 à 250 ; sommeil 0 à 960 min ; pas 0 à 60 000Au-delà, la valeur n'entre pas dans la zone habituellesrc/trevor/value_alerts.py:98-99

Ce qui est affiché

Une ligne par mesure avec niveau (alerte, à surveiller, habituel pour toi, rien à signaler), sens (sous ou au-dessus), norme et zone habituelle, triée des plus préoccupantes aux moins. Exemple de phrase de niveau « alerte » : « Saturation en oxygène nocturne : 91 %, sous la norme (92 %) et sous ta zone habituelle (93,65 %). Parle-en à ton équipe soignante. »

Un exemple chiffré

Calcul exécuté avec le code : 12 nuits entre 95,0 et 96,0 % (médiane 95,5 ; zone apprise de 93,65 à 97,35) puis une valeur à 91 % : niveau « alerte ». Si tu fixes toi-même une limite basse à 90 %, la même valeur à 91 % devient « habituel pour toi » : elle est sous la norme de 92 mais au-dessus de ta limite, donc aucun message n'est envoyé. Avec une seule valeur à 91 % et aucun historique : « alerte » aussi, car la saturation est traitée à part.

Ce que cet algorithme ne sait pas faire

Validation. Les normes sont décrites dans le code comme des repères d'adulte à faire confirmer par l'équipe soignante. La médiane avec écart robuste est une méthode statistique standard ; le coefficient 2,5, les 10 valeurs, les 90 jours et les planchers sont des choix de Trévor sans étude citée. Le repère de fatigue à 7/10 et le bruit à 70 dB(A) sont marqués « à faire valider » dans le code. Le seuil 92 % est un « repère de sécurité » courant des oxymètres grand public selon value_alerts.py:16-17 et service.py:467, non une valeur propre à la drépanocytose. Ce n'est pas un dispositif médical validé.

Code : src/trevor/value_alerts.py (METRICS, learn, evaluate, set_limit, build, describe, unsent), src/trevor/dashboard/server.py (patient_limits, clinician_limits, vers 6939-6970), src/trevor/conversation/reminders.py (value_alerts)

Important. Ces calculs orientent, ils ne posent aucun diagnostic et ne remplacent pas l'avis de l'équipe soignante. En cas de douleur forte, de fièvre ou d'essoufflement, il faut appeler le 144 sans attendre.