# Données des appareils portables en FHIR (Apple Health, Health Connect)

> Intégrer les données des montres connectées, des bagues et des balances dans un enregistrement FHIR : quels appareils atteignent quel magasin de santé, une table de mappage LOINC, des résumés quotidiens et une opération d'insertion/mise à jour testée.

Source: https://developers.anpheros.com/fr/guides/wearable-data-fhir

**Pour intégrer les données d'une montre connectée, d'une bague ou d'une balance connectée dans un dossier médical, lisez-les sur le téléphone à partir du magasin de santé du système d'exploitation — Apple Health sur iOS, Health Connect sur Android — résumez-les par jour, mappez chaque métrique à un code LOINC et à une unité UCUM, et écrivez-les sous forme d'Observations FHIR R4 marquées comme données d'appareil.** Lire à partir du magasin de santé du téléphone au lieu du cloud de chaque fournisseur permet à une seule intégration de couvrir Apple Watch, Galaxy Watch, Pixel Watch, Garmin, Fitbit, Oura et Withings, tant que la personne a autorisé son application fournisseur à partager. Cette page présente le chemin des données, une table de mappage réutilisable, un exemple FHIR validé et le code qui a été exécuté sur la plateforme.

## Le chemin des données

```
 watch, ring, scale ──► vendor app (Garmin Connect, Fitbit, Oura, Withings, Samsung Health…)
                              │  shares, with the person's permission
                              ▼
                 Apple Health (iOS)  /  Health Connect (Android)
                              │  your app reads, with the person's permission, on the phone
                              ▼
                 your app ──► your backend ──► FHIR R4 Observations in the person's record
```

Ni Apple Health ni Health Connect ne disposent d'une API serveur : les données ne peuvent être lues que par une application sur le téléphone de la personne. Votre application les lit, envoie des valeurs journalières compactes à votre backend, et le backend les écrit dans le dossier.

## Quels appareils atteignent quels magasins de santé

Ce que chaque fournisseur partage change avec les versions des applications ; la documentation du fournisseur lui-même fait foi.

| Appareil ou application | Apple Health (iOS) | Health Connect (Android) | Notes |
|---|---|---|---|
| Apple Watch | Oui, nativement | — | Tout ce que la montre mesure est stocké dans Apple Health |
| Samsung Galaxy Watch, Samsung Health | — | Partiellement | Samsung Health décide quels types il exporte et à quelle fréquence ; voir [Samsung Health](https://developers.anpheros.com/fr/guides/samsung-health-fhir) |
| Pixel Watch, Fitbit | Pas de synchronisation officielle | Oui, via l'application Fitbit ([Aide Google](https://support.google.com/fitbit/answer/14506680)) | |
| Garmin | Oui, depuis Garmin Connect après chaque synchronisation de l'appareil | Oui, Garmin Connect prend en charge Health Connect sur Android 14 et versions ultérieures ([Android Developers, août 2025](https://developer.android.com/health-and-fitness/community/newsletters/2025/08)) | Les scores spécifiques à Garmin tels que Body Battery ne sont pas partagés |
| Oura | Oui | Oui ([Oura](https://ouraring.com/blog/data-sharing-partner-integrations/)) | Readiness et autres scores Oura restent dans l'application Oura |
| Withings | Oui, via Health Mate | Oui ([Blog Android Developers](https://android-developers.googleblog.com/2023/03/withings-reduces-data-sync-code-with--health-and-fitness-api-health-connect.html)) | Pèse-personnes, tensiomètres, montres |

Deux conséquences pratiques. Premièrement, votre application dépend de la personne ayant activé le partage dans son application fournisseur ; l'intégration devrait le mentionner. Deuxièmement, le magasin de santé peut contenir les mêmes pas provenant de deux sources (un téléphone et une montre) ; lisez les totaux quotidiens du magasin plutôt que d'additionner les échantillons, car Apple Health et Health Connect dédupliquent déjà les sources qui se chevauchent.

## Tableau de mappage : type de magasin de santé → FHIR Observation

Les codes utilisés par Anpheros Daily lors de l'écriture de données de portables dans un enregistrement FHIR :

| Métrique | Apple HealthKit | Health Connect | LOINC | Unité UCUM | Catégorie |
|---|---|---|---|---|---|
| Fréquence cardiaque | `heartRate` | `HeartRateRecord` | 8867-4 | `/min` | vital-signs |
| Fréquence cardiaque au repos | `restingHeartRate` | `RestingHeartRateRecord` | 40443-4 | `/min` | vital-signs |
| Variabilité de la fréquence cardiaque | `heartRateVariabilitySDNN` | `HeartRateVariabilityRmssdRecord` | 80404-7 (SDNN uniquement) | `ms` | vital-signs |
| Oxygène sanguin (SpO₂) | `oxygenSaturation` | `OxygenSaturationRecord` | 59408-5 | `%` | vital-signs |
| Fréquence respiratoire | `respiratoryRate` | `RespiratoryRateRecord` | 9279-1 | `/min` | vital-signs |
| Pas par jour | `stepCount` | `StepsRecord` | 41950-7 | `{steps}` | activity |
| Énergie active | `activeEnergyBurned` | `ActiveCaloriesBurnedRecord` | 41981-2 | `kcal` | activity |
| Durée du sommeil | `sleepAnalysis` (catégorie) | `SleepSessionRecord` | 93832-4 ; stades 93831-6 profond, 93830-8 léger, 93829-0 REM | `min` | activity |
| Poids corporel | `bodyMass` | `WeightRecord` | 29463-7 | `kg` | vital-signs |
| Pression artérielle | `bloodPressure` (corrélation) | `BloodPressureRecord` | 85354-9 avec 8480-6 et 8462-4 | `mm[Hg]` | vital-signs |
| Glycémie (lecteur) | `bloodGlucose` | `BloodGlucoseRecord` | 2339-0 | `mg/dL` | vital-signs |
| Température corporelle | `bodyTemperature` | `BodyTemperatureRecord` | 8310-5 | `Cel` | vital-signs |

Regardez la ligne de variabilité de la fréquence cardiaque : Apple Health stocke **SDNN**, Health Connect stocke **RMSSD**. Ce sont des statistiques différentes et ne doivent pas être écrites sous le même code. LOINC 80404-7 est SDNN ; pour RMSSD, Anpheros Daily utilise son propre système de codes plutôt que de prétendre que les deux sont identiques.

## Résumés, pas chaque échantillon

Une montre produit des milliers d'échantillons de fréquence cardiaque par jour. Un dossier médical a besoin de quelque chose qu'une personne ou un médecin peut lire :

- **Une Observation par métrique et par jour**, avec `effectivePeriod` couvrant le jour local de la personne, la moyenne ou le total journalier dans `valueQuantity` et, pour les débits, le minimum et le maximum en tant que composants.
- **Les séries plus fines restent là où elles sont utiles.** Anpheros Daily conserve des résumés de fréquence cardiaque sur 4 heures pour ses propres graphiques et écrit les valeurs journalières dans le dossier FHIR.
- **Les événements sont séparés.** Une notification de rythme irrégulier ou une seule mesure de tension artérielle est sa propre Observation avec sa propre heure, et non une partie d'une moyenne journalière.

Un résumé journalier de la fréquence cardiaque en tant que FHIR R4 (il passe le [validateur FHIR R4](https://developers.anpheros.com/tools/fhir-validator)) :

```json
{
  "resourceType": "Observation",
  "status": "final",
  "identifier": [{"system": "https://your-app.test/fhir/sid/daily-wearable", "value": "p-123:2026-10-01:heart_rate"}],
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "vital-signs"}]}],
  "code": {"coding": [{"system": "http://loinc.org", "code": "8867-4", "display": "Heart rate"}]},
  "subject": {"reference": "Patient/p-123"},
  "effectivePeriod": {"start": "2026-10-01T00:00:00-04:00", "end": "2026-10-02T00:00:00-04:00"},
  "valueQuantity": {"value": 71.4, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"},
  "component": [
    {"code": {"text": "minimum"}, "valueQuantity": {"value": 52, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"}},
    {"code": {"text": "maximum"}, "valueQuantity": {"value": 138, "unit": "/min", "system": "http://unitsofmeasure.org", "code": "/min"}}
  ],
  "device": {"display": "Apple Watch (via Apple Health)"}
}
```

## Écrire des valeurs quotidiennes sans doublons

Les téléphones se synchronisent plusieurs fois par jour, et la dernière valeur d'une journée change jusqu'à minuit. Donnez à chaque Observation un identifiant stable — personne, jour, métrique — et mettez-la à jour au lieu d'en créer une nouvelle. Avec le SDK TypeScript Anpheros, sur votre backend :

```ts
import { Anpheros, apiKey } from '@anpheros/sdk';

const anpheros = new Anpheros({ auth: apiKey(process.env.ANPHEROS_KEY!) });

// What the phone sends: one value per metric per local day
type DailyValue = { metric: 'heart_rate' | 'steps'; day: string; value: number; min?: number; max?: number };

const CODES = {
  heart_rate: { code: '8867-4', display: 'Heart rate', unit: '/min', category: 'vital-signs' },
  steps: { code: '41950-7', display: 'Number of steps in 24 hour Measured', unit: '{steps}', category: 'activity' },
} as const;

// One Observation per person, metric and day: re-sending a day updates it instead of adding a copy.
async function upsertDaily(patientId: string, v: DailyValue, source: string) {
  const c = CODES[v.metric];
  const identifier = { system: 'https://your-app.test/fhir/sid/daily-wearable', value: `${patientId}:${v.day}:${v.metric}` };
  const resource: any = {
    resourceType: 'Observation', status: 'final',
    identifier: [identifier],
    category: [{ coding: [{ system: 'http://terminology.hl7.org/CodeSystem/observation-category', code: c.category }] }],
    code: { coding: [{ system: 'http://loinc.org', code: c.code, display: c.display }] },
    subject: { reference: `Patient/${patientId}` },
    effectivePeriod: { start: `${v.day}T00:00:00Z`, end: `${v.day}T23:59:59Z` },
    valueQuantity: { value: v.value, unit: c.unit, system: 'http://unitsofmeasure.org', code: c.unit },
  };
  if (v.min !== undefined && v.max !== undefined) {
    resource.component = [
      { code: { text: 'minimum' }, valueQuantity: { value: v.min, unit: c.unit, system: 'http://unitsofmeasure.org', code: c.unit } },
      { code: { text: 'maximum' }, valueQuantity: { value: v.max, unit: c.unit, system: 'http://unitsofmeasure.org', code: c.unit } },
    ];
  }
  const found = await anpheros.fhir.search('Observation', { identifier: `${identifier.system}|${identifier.value}` });
  const existing = found.entry?.[0]?.resource;
  return existing
    ? anpheros.fhir.update({ ...resource, id: existing.id }, { author_type: 'device' })
    : anpheros.fhir.create(resource, { author_type: 'device', source_system: source });
}
```

L'exécution sur une instance locale de la plateforme avec une clé sandbox, deux valeurs quotidiennes suivies d'une synchronisation ultérieure des pas du même jour a laissé **deux** Observations, celle des pas à la version 2 avec la nouvelle valeur, et la provenance `v1 device apple-health · v2 device`. L'historique conserve la valeur précédente, et chaque lecteur peut voir que les données proviennent d'un appareil, et non d'un clinicien.

En production, utilisez les véritables limites de journée dans le fuseau horaire de la personne (l'exemple ci-dessus utilise l'UTC pour plus de concision), comme le font le code HealthKit et Health Connect sur les pages de la plateforme.

## Lecture sur téléphone

- **iPhone et Apple Watch :** [Apple Health (HealthKit) vers FHIR](https://developers.anpheros.com/fr/guides/apple-health-fhir), avec du code Swift pour les statistiques quotidiennes.
- **Android, Wear OS, Fitbit, Garmin, Oura, Withings :** [Health Connect vers FHIR](https://developers.anpheros.com/fr/guides/health-connect-fhir), avec du code Flutter qui fonctionne sur les deux plateformes.
- **Samsung Galaxy Watch et Samsung Health :** [Samsung Health vers FHIR](https://developers.anpheros.com/fr/guides/samsung-health-fhir) : ce qui est accessible via Health Connect et ce qui nécessite le SDK propre à Samsung.

## Règles à suivre

- **Lisez uniquement ce que vous utilisez**, et demandez chaque type séparément ; les utilisateurs accordent des permissions partielles.
- **Étiquetez la source.** Les appareils portables grand public ne sont pas des dispositifs de diagnostic. Écrivez leurs données comme des données d'appareil (`author_type: device`) et indiquez l'application dont elles proviennent, afin qu'un clinicien puisse les évaluer en conséquence.
- **Respectez les règles de la plateforme.** Les directives d'examen des applications d'Apple (5.1.3) interdisent l'utilisation des données de santé à des fins publicitaires et le stockage d'informations personnelles de santé dans iCloud ; Google Play exige une déclaration des applications de santé pour les applications qui utilisent Health Connect.
- **Laissez les utilisateurs se déconnecter** et décider si les données déjà copiées restent dans le dossier.

## Ce que Anpheros fait et ne fait pas

La plateforme Anpheros ne se connecte pas à Apple Health, Health Connect ou à un cloud fournisseur par elle-même : votre application lit les données sur le téléphone et les écrit via l'API. L'application propre à Anpheros, **Anpheros Daily**, fait exactement cela : elle lit Apple Health sur iPhone et Health Connect sur Android, conserve des résumés quotidiens et les écrit dans le dossier FHIR de la personne avec les codes ci-dessus. La connexion des appareils fait partie de ses plans Plus et Max.

## Foire aux questions

### Comment intégrer les données Apple Watch dans un serveur FHIR ?
Lisez-les sur l'iPhone depuis Apple Health avec HealthKit (il n'y a pas d'API serveur), résumez-les par jour, et faites en sorte que votre backend écrive chaque métrique comme une Observation avec un code LOINC et une unité UCUM, marquée comme données d'appareil.

### Existe-t-il une API cloud pour Health Connect ou Apple Health ?
Non. Les deux conservent les données sur le téléphone ; une application installée sur le téléphone les lit avec la permission de la personne. Les clouds de fournisseurs tels que Garmin, Fitbit ou Oura ont leurs propres API, mais la lecture du magasin de santé du téléphone couvre la plupart d'entre eux avec une seule intégration.

### Quel code LOINC dois-je utiliser pour les pas ?
41950-7, « Nombre de pas en 24 heures mesuré », avec un `effectivePeriod` quotidien. Pour la fréquence cardiaque, utilisez 8867-4, pour la SpO₂, 59408-5, pour la durée du sommeil 93832-4.

### Dois-je stocker chaque échantillon de fréquence cardiaque dans FHIR ?
Généralement non. Un résumé quotidien avec la moyenne, le minimum et le maximum est ce qu'une personne ou un clinicien lit ; les lectures individuelles n'appartiennent au dossier que lorsqu'elles ont une importance en soi, comme un événement de rythme irrégulier.

### Puis-je utiliser un seul code pour la VRC (Variabilité de la Fréquence Cardiaque) d'Apple Health et de Health Connect ?
Non. Apple Health signale le SDNN et Health Connect signale le RMSSD ; ils mesurent des choses différentes et nécessitent des codes différents.

## Liens connexes

- [APIs pour appareils portables : Fitbit, Garmin, Oura et Withings](https://developers.anpheros.com/fr/guides/wearable-apis)
- [API de suivi de santé](https://developers.anpheros.com/fr/guides/health-tracker-api) : stockage des données de suivi sur un serveur, avec consentement
- [Comment créer une application de dossier de santé personnel](https://developers.anpheros.com/fr/guides/personal-health-record-app)
- [Intégrations de soins de santé](https://developers.anpheros.com/fr/guides/healthcare-integrations) : appareils à côté des laboratoires, cliniques et applications
- [Systèmes de codes FHIR](https://developers.anpheros.com/fr/guides/fhir-code-systems) : LOINC et UCUM
- [Provenance des données médicales expliquée](https://developers.anpheros.com/fr/guides/medical-data-provenance)
- [Comment normaliser les données médicales](https://developers.anpheros.com/fr/guides/normalize-medical-data)
- [Surveillance à distance des patients avec FHIR](https://developers.anpheros.com/fr/guides/remote-patient-monitoring-fhir) : lectures individuelles, webhooks et alertes
