Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Dane z urządzeń noszonych w FHIR (Apple Health, Health Connect)
Przesyłanie danych z smartwatchy, pierścieni i wag do repozytorium FHIR: które urządzenia docierają do których sklepów z danymi zdrowotnymi, tabela mapowania LOINC, codzienne podsumowania i przetestowany mechanizm upsert.
Aby przenieść dane z smartwatcha, pierścionka lub inteligentnej wagi do rekordu medycznego, odczytaj je na telefonie z magazynu danych zdrowotnych systemu operacyjnego — Apple Health na iOS, Health Connect na Androidzie — podsumuj je dziennie, zmapuj każdą metrykę do kodu LOINC i jednostki UCUM, a następnie zapisz je jako obserwacje FHIR R4 oznaczone jako dane urządzenia. Odczyt z magazynu danych zdrowotnych telefonu zamiast z chmury każdego dostawcy pozwala na objęcie jedną integracją Apple Watch, Galaxy Watch, Pixel Watch, Garmin, Fitbit, Oura i Withings, pod warunkiem, że użytkownik zezwolił swojej aplikacji dostawcy na udostępnianie danych. Ta strona przedstawia ścieżkę danych, tabelę mapowania, którą można ponownie wykorzystać, zweryfikowany przykład FHIR oraz kod, który został uruchomiony na platformie.
Ścieżka danych
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
Zarówno Apple Health, jak i Health Connect nie posiadają API serwerowego: dane mogą być odczytywane jedynie przez aplikację na telefonie użytkownika. Twoja aplikacja odczytuje je, wysyła skompaktowane dzienne wartości do Twojego backendu, a backend zapisuje je w rekordzie.
Które urządzenia docierają do których repozytoriów danych o stanie zdrowia
To, czym dzieli się każdy dostawca, zmienia się wraz z wersjami aplikacji; dokumentacja samego dostawcy jest punktem odniesienia.
| Urządzenie lub aplikacja | Apple Health (iOS) | Health Connect (Android) | Uwagi |
|---|---|---|---|
| Apple Watch | Tak, natywnie | — | Wszystko, co mierzy zegarek, trafia do Apple Health |
| Samsung Galaxy Watch, Samsung Health | — | Częściowo | Samsung Health decyduje, jakie typy danych eksportuje i jak często; zobacz Samsung Health |
| Pixel Watch, Fitbit | Brak oficjalnej synchronizacji | Tak, za pośrednictwem aplikacji Fitbit (Pomoc Google) | |
| Garmin | Tak, z Garmin Connect po każdej synchronizacji urządzenia | Tak, Garmin Connect obsługuje Health Connect na Androidzie 14 i nowszych (Android Developers, sierpień 2025) | Wyniki specyficzne dla Garmin, takie jak Body Battery, nie są udostępniane |
| Oura | Tak | Tak (Oura) | Wyniki Readiness i inne wyniki Oura pozostają w aplikacji Oura |
| Withings | Tak, za pośrednictwem Health Mate | Tak (Blog Android Developers) | Wagi, monitory ciśnienia krwi, zegarki |
Dwie praktyczne konsekwencje. Po pierwsze, Twoja aplikacja zależy od tego, czy użytkownik włączył udostępnianie w swojej aplikacji dostawcy; proces onboardingu powinien o tym informować. Po drugie, repozytorium danych o stanie zdrowia może zawierać te same kroki z dwóch źródeł (telefon i zegarek); odczytaj własne dzienne sumy repozytorium, zamiast sumować próbki, ponieważ Apple Health i Health Connect już usuwają duplikaty nakładających się źródeł.
Tabela odwzorowania: typ magazynu danych zdrowotnych → FHIR Observation
Kody używane przez Anpheros Daily podczas zapisywania danych z urządzeń noszonych do rekordu FHIR:
| Metryka | Apple HealthKit | Health Connect | LOINC | Jednostka UCUM | Kategoria |
|---|---|---|---|---|---|
| Tętno | heartRate |
HeartRateRecord |
8867-4 | /min |
vital-signs |
| Tętno spoczynkowe | restingHeartRate |
RestingHeartRateRecord |
40443-4 | /min |
vital-signs |
| Zmienność rytmu serca | heartRateVariabilitySDNN |
HeartRateVariabilityRmssdRecord |
80404-7 (tylko SDNN) | ms |
vital-signs |
| Tlen we krwi (SpO₂) | oxygenSaturation |
OxygenSaturationRecord |
59408-5 | % |
vital-signs |
| Częstość oddechów | respiratoryRate |
RespiratoryRateRecord |
9279-1 | /min |
vital-signs |
| Kroki na dzień | stepCount |
StepsRecord |
41950-7 | {steps} |
activity |
| Aktywna energia | activeEnergyBurned |
ActiveCaloriesBurnedRecord |
41981-2 | kcal |
activity |
| Czas trwania snu | sleepAnalysis (kategoria) |
SleepSessionRecord |
93832-4; etapy 93831-6 głęboki, 93830-8 lekki, 93829-0 REM | min |
activity |
| Masa ciała | bodyMass |
WeightRecord |
29463-7 | kg |
vital-signs |
| Ciśnienie krwi | bloodPressure (korelacja) |
BloodPressureRecord |
85354-9 z 8480-6 i 8462-4 | mm[Hg] |
vital-signs |
| Poziom glukozy we krwi (glukometr) | bloodGlucose |
BloodGlucoseRecord |
2339-0 | mg/dL |
vital-signs |
| Temperatura ciała | bodyTemperature |
BodyTemperatureRecord |
8310-5 | Cel |
vital-signs |
Przyjrzyj się wierszowi zmienności rytmu serca: Apple Health przechowuje SDNN, Health Connect przechowuje RMSSD. Są to różne statystyki i nie należy ich zapisywać pod tym samym kodem. LOINC 80404-7 to SDNN; dla RMSSD, Anpheros Daily używa własnego systemu kodowania, zamiast udawać, że te dwie wartości są takie same.
Podsumowania, nie każdy próbki
Urządzenie do noszenia zegarka generuje tysiące próbek tętna dziennie. Dokumentacja medyczna potrzebuje czegoś, co człowiek lub lekarz może przeczytać:
- Jedna obserwacja na metrykę dziennie, z
effectivePeriodobejmującymi lokalny dzień osoby, średnią dzienną lub sumę wvalueQuantity, a dla wskaźników, minimum i maksimum jako komponenty. - Bardziej szczegółowe serie pozostają tam, gdzie są użyteczne. Anpheros Daily przechowuje 4-godzinne podsumowania tętna dla własnych wykresów i zapisuje dzienne wartości do rekordu FHIR.
- Zdarzenia są oddzielne. Powiadomienie o nieregularnym rytmie lub pojedynczy odczyt ciśnienia krwi to własna obserwacja z własnym czasem, nie będąca częścią średniej dziennej.
Dzienne podsumowanie tętna jako FHIR R4 (przechodzi przez walidator FHIR R4):
{
"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)"}
}
Zapisywanie codziennych wartości bez duplikatów
Telefony synchronizują się kilka razy dziennie, a ostatnia wartość dnia zmienia się do północy. Nadaj każdej obserwacji (Observation) stabilny identyfikator — osoba, dzień, metryka — i aktualizuj ją zamiast tworzyć nową. Korzystając z Anpheros TypeScript SDK, na swoim backendzie:
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 });
}
Uruchomienie na lokalnej instancji platformy z kluczem sandbox, dwie dzienne wartości, a następnie późniejsza synchronizacja kroków tego samego dnia pozostawiły dwie obserwacje (Observations), przy czym obserwacja kroków ma wersję 2 z nową wartością i proweniencję v1 device apple-health · v2 device. Historia zachowuje wcześniejszą wartość, a każdy czytelnik może zobaczyć, że dane pochodzą z urządzenia, a nie od klinicysty.
W środowisku produkcyjnym używaj rzeczywistych granic dnia w strefie czasowej osoby (powyższy przykład używa UTC dla zwięzłości), tak jak robi to kod HealthKit i Health Connect na stronach platformy.
Odczyt danych z urządzeń mobilnych
- iPhone i Apple Watch: Apple Health (HealthKit) do FHIR, z kodem w Swift dla dziennych statystyk.
- Android, Wear OS, Fitbit, Garmin, Oura, Withings: Health Connect do FHIR, z kodem w Flutter, który działa na obu platformach.
- Samsung Galaxy Watch i Samsung Health: Samsung Health do FHIR: co trafia do Health Connect, a co wymaga własnego SDK firmy Samsung.
Zasady, których warto przestrzegać
- Czytaj tylko to, czego używasz, i proś o każdy typ osobno; ludzie udzielają częściowych uprawnień.
- Oznacz źródło. Urządzenia noszone przez konsumentów nie są urządzeniami diagnostycznymi. Zapisuj ich dane jako dane urządzenia (
author_type: device) i podaj, z której aplikacji pochodzą, aby lekarz mógł je odpowiednio ocenić. - Przestrzegaj zasad platformy. Wytyczne Apple dotyczące przeglądu aplikacji (5.1.3) zabraniają wykorzystywania danych o stanie zdrowia do celów reklamowych i przechowywania osobistych informacji o stanie zdrowia w iCloud; Google Play wymaga deklaracji aplikacji zdrowotnych dla aplikacji korzystających z Health Connect.
- Pozwól użytkownikom odłączyć się i zdecydować, czy dane, które zostały już skopiowane, pozostaną w rekordzie.
Co Anpheros robi, a czego nie robi
Platforma Anpheros sama w sobie nie łączy się z Apple Health, Health Connect ani żadną chmurą dostawcy: Twoja aplikacja odczytuje dane z telefonu i zapisuje je za pośrednictwem API. Własna aplikacja Anpheros, Anpheros Daily, robi dokładnie to: odczytuje Apple Health na iPhonie i Health Connect na Androidzie, przechowuje codzienne podsumowania i zapisuje je w rekordzie FHIR danej osoby z powyższymi kodami. Łączenie urządzeń jest częścią planów Plus i Max.
Często zadawane pytania
Jak uzyskać dane z Apple Watch na serwer FHIR?
Odczytaj dane z Apple Health za pomocą HealthKit na iPhonie (nie ma API serwerowego), podsumuj je dziennie, a następnie backend zapisze każdą metrykę jako Observation z kodem LOINC i jednostką UCUM, oznaczoną jako dane urządzenia.
Czy istnieje API chmurowe dla Health Connect lub Apple Health?
Nie. Oba przechowują dane na telefonie; aplikacja zainstalowana na telefonie odczytuje je za zgodą użytkownika. Chmury dostawców, takie jak Garmin, Fitbit czy Oura, mają własne API, ale odczytanie lokalnego magazynu zdrowia telefonu obejmuje większość z nich jedną integracją.
Którego kodu LOINC powinienem użyć dla kroków?
41950-7, "Number of steps in 24 hour Measured", z dziennym effectivePeriod. Dla tętna użyj 8867-4, dla SpO₂ 59408-5, dla czasu trwania snu 93832-4.
Czy powinienem przechowywać każdą próbkę tętna w FHIR?
Zazwyczaj nie. Dzienny raport z wartością średnią, minimalną i maksymalną jest tym, co czyta użytkownik lub lekarz; pojedyncze odczyty należą do rekordu tylko wtedy, gdy mają znaczenie same w sobie, na przykład zdarzenie nieregularnego rytmu.
Czy mogę użyć jednego kodu dla HRV z Apple Health i Health Connect?
Nie. Apple Health raportuje SDNN, a Health Connect raportuje RMSSD; mierzą one różne rzeczy i wymagają różnych kodów.
Powiązane
- API urządzeń do noszenia: Fitbit, Garmin, Oura i Withings
- API trackerów zdrowia: przechowywanie danych z trackerów na serwerze, za zgodą użytkownika
- Jak zbudować aplikację osobistej dokumentacji medycznej
- Integracje opieki zdrowotnej: urządzenia obok laboratoriów, klinik i aplikacji
- Systemy kodowania FHIR: LOINC i UCUM
- Wyjaśnienie pochodzenia danych medycznych
- Jak normalizować dane medyczne
- Zdalne monitorowanie pacjentów z FHIR: pojedyncze odczyty, webhooks i alerty
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card