# Dati indossabili in FHIR (Apple Health, Health Connect)

> Ottieni dati da smartwatch, anelli e bilance in un record FHIR: quali dispositivi raggiungono quale archivio sanitario, una tabella di mappatura LOINC, riepiloghi giornalieri e un upsert testato.

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

**Per inserire dati da uno smartwatch, un anello o una bilancia intelligente in un record medico, leggili sul telefono dall'archivio sanitario del sistema operativo — Apple Health su iOS, Health Connect su Android — riassumili per giorno, mappa ogni metrica a un codice LOINC e a un'unità UCUM, e scrivili come FHIR R4 Observations contrassegnati come dati del dispositivo.** Leggere dall'archivio sanitario del telefono invece che dal cloud di ciascun fornitore consente a un'unica integrazione di coprire Apple Watch, Galaxy Watch, Pixel Watch, Garmin, Fitbit, Oura e Withings, a condizione che la persona abbia autorizzato la condivisione da parte della propria app del fornitore. Questa pagina fornisce il percorso dei dati, una tabella di mappatura riutilizzabile, un esempio FHIR validato e il codice eseguito sulla piattaforma.

## Il percorso dei dati

```
 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
```

Né Apple Health né Health Connect dispongono di un'API server: i dati possono essere letti solo da un'app sul telefono della persona. La tua app li legge, invia valori giornalieri compatti al tuo backend e il backend li scrive nel record.

## Quali dispositivi raggiungono quali health store

Ciò che ogni fornitore condivide cambia con le versioni delle app; la documentazione del fornitore stesso è il riferimento.

| Dispositivo o app | Apple Health (iOS) | Health Connect (Android) | Note |
|---|---|---|---|
| Apple Watch | Sì, nativamente | — | Tutto ciò che l'orologio misura finisce in Apple Health |
| Samsung Galaxy Watch, Samsung Health | — | Parzialmente | Samsung Health decide quali tipi esporta e con quale frequenza; vedere [Samsung Health](https://developers.anpheros.com/it/guides/samsung-health-fhir) |
| Pixel Watch, Fitbit | Nessuna sincronizzazione ufficiale | Sì, tramite l'app Fitbit ([Guida di Google](https://support.google.com/fitbit/answer/14506680)) | |
| Garmin | Sì, da Garmin Connect dopo ogni sincronizzazione del dispositivo | Sì, Garmin Connect supporta Health Connect su Android 14 e versioni successive ([Android Developers, agosto 2025](https://developer.android.com/health-and-fitness/community/newsletters/2025/08)) | Punteggi specifici di Garmin come Body Battery non vengono condivisi |
| Oura | Sì | Sì ([Oura](https://ouraring.com/blog/data-sharing-partner-integrations/)) | Readiness e altri punteggi Oura rimangono nell'app Oura |
| Withings | Sì, tramite Health Mate | Sì ([blog di Android Developers](https://android-developers.googleblog.com/2023/03/withings-reduces-data-sync-code-with--health-and-fitness-api-health-connect.html)) | Bilance, misuratori di pressione sanguigna, orologi |

Due conseguenze pratiche. Primo, la tua app dipende dal fatto che la persona abbia attivato la condivisione nella propria app del fornitore; l'onboarding dovrebbe indicarlo. Secondo, l'health store potrebbe contenere gli stessi passi da due fonti (un telefono e un orologio); leggere i totali giornalieri dell'store stesso anziché sommare i campioni, poiché Apple Health e Health Connect già deduplicano le fonti sovrapposte.

## Tabella di mappatura: tipo di archivio sanitario → FHIR Observation

I codici utilizzati da Anpheros Daily quando scrive dati indossabili in un record FHIR:

| Metrica | Apple HealthKit | Health Connect | LOINC | Unità UCUM | Categoria |
|---|---|---|---|---|---|
| Frequenza cardiaca | `heartRate` | `HeartRateRecord` | 8867-4 | `/min` | vital-signs |
| Frequenza cardiaca a riposo | `restingHeartRate` | `RestingHeartRateRecord` | 40443-4 | `/min` | vital-signs |
| Variabilità della frequenza cardiaca | `heartRateVariabilitySDNN` | `HeartRateVariabilityRmssdRecord` | 80404-7 (solo SDNN) | `ms` | vital-signs |
| Ossigeno nel sangue (SpO₂) | `oxygenSaturation` | `OxygenSaturationRecord` | 59408-5 | `%` | vital-signs |
| Frequenza respiratoria | `respiratoryRate` | `RespiratoryRateRecord` | 9279-1 | `/min` | vital-signs |
| Passi al giorno | `stepCount` | `StepsRecord` | 41950-7 | `{steps}` | activity |
| Energia attiva | `activeEnergyBurned` | `ActiveCaloriesBurnedRecord` | 41981-2 | `kcal` | activity |
| Durata del sonno | `sleepAnalysis` (categoria) | `SleepSessionRecord` | 93832-4; stadi 93831-6 profondo, 93830-8 leggero, 93829-0 REM | `min` | activity |
| Peso corporeo | `bodyMass` | `WeightRecord` | 29463-7 | `kg` | vital-signs |
| Pressione sanguigna | `bloodPressure` (correlazione) | `BloodPressureRecord` | 85354-9 con 8480-6 e 8462-4 | `mm[Hg]` | vital-signs |
| Glucosio nel sangue (misuratore) | `bloodGlucose` | `BloodGlucoseRecord` | 2339-0 | `mg/dL` | vital-signs |
| Temperatura corporea | `bodyTemperature` | `BodyTemperatureRecord` | 8310-5 | `Cel` | vital-signs |

Osserva la riga della variabilità della frequenza cardiaca: Apple Health memorizza **SDNN**, Health Connect memorizza **RMSSD**. Sono statistiche diverse e non devono essere scritte sotto lo stesso codice. LOINC 80404-7 è SDNN; per RMSSD, Anpheros Daily utilizza il proprio sistema di codifica piuttosto che fingere che i due siano uguali.

## Riepiloghi, non ogni campione

Un orologio produce migliaia di campioni di frequenza cardiaca al giorno. Un referto medico necessita di qualcosa che una persona o un medico possa leggere:

- **Una Observation per metrica al giorno**, con `effectivePeriod` che copre il giorno locale della persona, la media o il totale giornaliero in `valueQuantity` e, per le frequenze, il minimo e il massimo come componenti.
- **Serie più dettagliate rimangono dove sono utili.** Anpheros Daily mantiene riepiloghi della frequenza cardiaca di 4 ore per i propri grafici e scrive i valori giornalieri nel referto FHIR.
- **Gli eventi sono separati.** Una notifica di ritmo irregolare o una singola misurazione della pressione sanguigna è una Observation a sé stante con il proprio orario, non parte di una media giornaliera.

Un riepilogo giornaliero della frequenza cardiaca come FHIR R4 (supera il [validatore 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)"}
}
```

## Scrittura di valori giornalieri senza duplicati

I telefoni si sincronizzano più volte al giorno e l'ultimo valore di un giorno continua a cambiare fino a mezzanotte. Assegna a ogni Observation un identificatore stabile — persona, giorno, metrica — e aggiornalo invece di crearne uno nuovo. Con l'SDK TypeScript di Anpheros, sul tuo 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 });
}
```

Eseguendo contro un'istanza locale della piattaforma con una sandbox key, due valori giornalieri seguiti da una sincronizzazione successiva dello stesso giorno per i passi hanno lasciato **due** Observation, quella dei passi alla versione 2 con il nuovo valore e la provenienza `v1 device apple-health · v2 device`. La cronologia conserva il valore precedente e ogni lettore può vedere che i dati provengono da un dispositivo, non da un clinico.

In produzione, utilizza i confini del giorno reali nel fuso orario della persona (l'esempio sopra utilizza UTC per brevità), come fanno il codice HealthKit e Health Connect nelle pagine della piattaforma.

## Lettura sul telefono

- **iPhone e Apple Watch:** [Apple Health (HealthKit) to FHIR](https://developers.anpheros.com/it/guides/apple-health-fhir), con codice Swift per le statistiche giornaliere.
- **Android, Wear OS, Fitbit, Garmin, Oura, Withings:** [Health Connect to FHIR](https://developers.anpheros.com/it/guides/health-connect-fhir), con codice Flutter che funziona su entrambe le piattaforme.
- **Samsung Galaxy Watch e Samsung Health:** [Samsung Health to FHIR](https://developers.anpheros.com/it/guides/samsung-health-fhir): cosa raggiunge Health Connect e cosa necessita dell'SDK proprietario di Samsung.

## Regole da seguire

- **Leggi solo ciò che utilizzi** e richiedi ogni tipo separatamente; le persone concedono permessi parziali.
- **Etichetta la sorgente.** I dispositivi indossabili dei consumatori non sono dispositivi diagnostici. Scrivi i loro dati come dati del dispositivo (`author_type: device`) e indica da quale app provengono, in modo che un clinico possa valutarli di conseguenza.
- **Rispetta le regole della piattaforma.** Le linee guida per la revisione delle app di Apple (5.1.3) vietano l'uso di dati sanitari per la pubblicità e la memorizzazione di informazioni sanitarie personali su iCloud; Google Play richiede una dichiarazione per le app sanitarie per le app che utilizzano Health Connect.
- **Permetti alle persone di disconnettersi** e decidere se i dati già copiati rimangono nel record.

## Cosa fa e cosa non fa Anpheros

La Piattaforma Anpheros non si connette autonomamente ad Apple Health, Health Connect o a qualsiasi cloud di vendor: la tua app legge i dati sul telefono e li scrive tramite l'API. L'app di Anpheros, **Anpheros Daily**, fa esattamente questo: legge Apple Health su iPhone e Health Connect su Android, mantiene riepiloghi giornalieri e li scrive nel record FHIR della persona con i codici sopra. La connessione dei dispositivi fa parte dei suoi piani Plus e Max.

## Domande frequenti

### Come si inseriscono i dati di Apple Watch in un server FHIR?
Leggerli sull'iPhone da Apple Health con HealthKit (non esiste un'API server), riassumerli giornalmente e far scrivere al proprio backend ogni metrica come Observation con un codice LOINC e un'unità UCUM, contrassegnata come dati del dispositivo.

### Esiste un'API cloud per Health Connect o Apple Health?
No. Entrambi conservano i dati sul telefono; un'app installata sul telefono li legge con il permesso della persona. I cloud dei fornitori come Garmin, Fitbit o Oura hanno le proprie API, ma la lettura dello store sanitario del telefono copre la maggior parte di essi con una singola integrazione.

### Quale codice LOINC dovrei usare per i passi?
41950-7, "Number of steps in 24 hour Measured", con un `effectivePeriod` giornaliero. Per la frequenza cardiaca usare 8867-4, per SpO₂ 59408-5, per la durata del sonno 93832-4.

### Devo memorizzare ogni campione di frequenza cardiaca in FHIR?
Di solito no. Un riassunto giornaliero con media, minimo e massimo è ciò che una persona o un clinico legge; le singole letture appartengono al record solo quando hanno un valore di per sé, come un evento di ritmo irregolare.

### Posso usare un codice per l'HRV da Apple Health e Health Connect?
No. Apple Health riporta SDNN e Health Connect riporta RMSSD; misurano cose diverse e necessitano di codici diversi.

## Correlati

- [API per dispositivi indossabili: Fitbit, Garmin, Oura e Withings](https://developers.anpheros.com/it/guides/wearable-apis)
- [API per il monitoraggio della salute](https://developers.anpheros.com/it/guides/health-tracker-api): archiviazione dei dati del tracker su un server, con consenso
- [Come creare un'app di cartella clinica personale](https://developers.anpheros.com/it/guides/personal-health-record-app)
- [Integrazioni sanitarie](https://developers.anpheros.com/it/guides/healthcare-integrations): dispositivi accanto a laboratori, cliniche e app
- [Sistemi di codifica FHIR](https://developers.anpheros.com/it/guides/fhir-code-systems): LOINC e UCUM
- [Spiegazione della provenienza dei dati medici](https://developers.anpheros.com/it/guides/medical-data-provenance)
- [Come normalizzare i dati medici](https://developers.anpheros.com/it/guides/normalize-medical-data)
- [Monitoraggio remoto dei pazienti con FHIR](https://developers.anpheros.com/it/guides/remote-patient-monitoring-fhir): letture individuali, webhook e avvisi
