Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card
Данные носимых устройств в FHIR (Apple Health, Health Connect)
Загрузка данных с умных часов, колец и весов в запись FHIR: какие устройства достигают какого хранилища здоровья, таблица сопоставления LOINC, ежедневные сводки и протестированный upsert.
Чтобы получить данные с умных часов, кольца или умных весов в медицинскую запись, считайте их на телефоне из хранилища данных о здоровье операционной системы — Apple Health на iOS, Health Connect на Android — суммируйте их за день, сопоставьте каждую метрику с кодом LOINC и единицей UCUM, и запишите их как FHIR R4 Observations, помеченные как данные устройства. Чтение из хранилища данных о здоровье телефона вместо облака каждого поставщика позволяет одной интеграции охватить Apple Watch, Galaxy Watch, Pixel Watch, Garmin, Fitbit, Oura и Withings, при условии, что человек разрешил своему приложению поставщика делиться данными. На этой странице представлены путь к данным, таблица сопоставления, которую вы можете повторно использовать, проверенный пример FHIR и код, который был запущен на платформе.
Путь данных
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
Ни Apple Health, ни Health Connect не имеют серверного API: данные могут быть прочитаны только приложением на телефоне пользователя. Ваше приложение считывает их, отправляет сжатые ежедневные значения на ваш бэкенд, а бэкенд записывает их в запись.
Какие устройства достигают какого хранилища данных о здоровье
То, чем делится каждый поставщик, меняется с версиями приложений; документация самого поставщика является эталоном.
| Устройство или приложение | Apple Health (iOS) | Health Connect (Android) | Примечания |
|---|---|---|---|
| Apple Watch | Да, нативно | — | Все, что измеряет часы, попадает в Apple Health |
| Samsung Galaxy Watch, Samsung Health | — | Частично | Samsung Health решает, какие типы данных экспортировать и как часто; см. Samsung Health |
| Pixel Watch, Fitbit | Нет официальной синхронизации | Да, через приложение Fitbit (Google help) | |
| Garmin | Да, из Garmin Connect после каждой синхронизации устройства | Да, Garmin Connect поддерживает Health Connect на Android 14 и новее (Android Developers, August 2025) | Показатели, специфичные для Garmin, такие как Body Battery, не передаются |
| Oura | Да | Да (Oura) | Показатели Readiness и другие показатели Oura остаются в приложении Oura |
| Withings | Да, через Health Mate | Да (Android Developers blog) | Весы, тонометры, часы |
Два практических следствия. Во-первых, ваше приложение зависит от того, включил ли пользователь общий доступ в своем приложении поставщика; онбординг должен об этом сообщать. Во-вторых, хранилище данных о здоровье может содержать одни и те же шаги из двух источников (телефон и часы); читайте собственные ежедневные итоги хранилища, а не суммируйте выборки, поскольку Apple Health и Health Connect уже дедуплицируют перекрывающиеся источники.
Таблица соответствия: тип хранилища данных → FHIR Observation
Коды, которые Anpheros Daily использует при записи данных носимых устройств в запись FHIR:
| Метрика | Apple HealthKit | Health Connect | LOINC | UCUM unit | Категория |
|---|---|---|---|---|---|
| Частота сердечных сокращений | heartRate |
HeartRateRecord |
8867-4 | /min |
vital-signs |
| Частота сердечных сокращений в покое | restingHeartRate |
RestingHeartRateRecord |
40443-4 | /min |
vital-signs |
| Вариабельность сердечного ритма | heartRateVariabilitySDNN |
HeartRateVariabilityRmssdRecord |
80404-7 (только SDNN) | ms |
vital-signs |
| Кислород в крови (SpO₂) | oxygenSaturation |
OxygenSaturationRecord |
59408-5 | % |
vital-signs |
| Частота дыхания | respiratoryRate |
RespiratoryRateRecord |
9279-1 | /min |
vital-signs |
| Шаги в день | stepCount |
StepsRecord |
41950-7 | {steps} |
activity |
| Активная энергия | activeEnergyBurned |
ActiveCaloriesBurnedRecord |
41981-2 | kcal |
activity |
| Продолжительность сна | sleepAnalysis (категория) |
SleepSessionRecord |
93832-4; стадии 93831-6 глубокий сон, 93830-8 легкий сон, 93829-0 REM | min |
activity |
| Вес тела | bodyMass |
WeightRecord |
29463-7 | kg |
vital-signs |
| Артериальное давление | bloodPressure (корреляция) |
BloodPressureRecord |
85354-9 с 8480-6 и 8462-4 | mm[Hg] |
vital-signs |
| Уровень глюкозы в крови (глюкометр) | bloodGlucose |
BloodGlucoseRecord |
2339-0 | mg/dL |
vital-signs |
| Температура тела | bodyTemperature |
BodyTemperatureRecord |
8310-5 | Cel |
vital-signs |
Обратите внимание на строку "Вариабельность сердечного ритма": Apple Health хранит SDNN, а Health Connect — RMSSD. Это разные статистические показатели, и их нельзя записывать под одним и тем же кодом. LOINC 80404-7 — это SDNN; для RMSSD Anpheros Daily использует собственную систему кодирования, а не выдает одно за другое.
Сводки, а не каждая выборка
Устройство для отслеживания активности производит тысячи выборок частоты сердечных сокращений в день. Медицинская запись должна содержать то, что может прочитать человек или врач:
- Одно наблюдение (Observation) на метрику в день, с
effectivePeriod, охватывающими местный день человека, среднесуточное значение или сумму вvalueQuantityи, для скоростей, минимальное и максимальное значения в качестве компонентов. - Более детальные серии остаются там, где они полезны. Anpheros Daily сохраняет 4-часовые сводки частоты сердечных сокращений для своих собственных диаграмм и записывает ежедневные значения в запись FHIR.
- События отдельны. Уведомление о нерегулярном ритме или однократное измерение артериального давления является отдельным наблюдением (Observation) со своим собственным временем, а не частью среднесуточного значения.
Ежедневная сводка частоты сердечных сокращений в формате FHIR R4 (проходит валидатор 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)"}
}
Запись ежедневных значений без дубликатов
Телефоны синхронизируются несколько раз в день, и последнее значение за день меняется до полуночи. Присваивайте каждому Observation стабильный идентификатор — человек, день, метрика — и обновляйте его вместо создания нового. С помощью Anpheros TypeScript SDK на вашем бэкенде:
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 });
}
При выполнении на локальном экземпляре платформы с sandbox-ключом два ежедневных значения, за которыми последовала более поздняя синхронизация шагов за тот же день, привели к созданию двух Observations: один для шагов с версией 2 и новым значением, и provenance v1 device apple-health · v2 device. История сохраняет предыдущее значение, и каждый читатель может видеть, что данные поступили с устройства, а не от клинициста.
В продакшене используйте реальные границы дня в часовом поясе человека (в приведенном выше примере для краткости используется UTC), как это делает код HealthKit и Health Connect на страницах платформы.
Чтение данных с телефона
- iPhone и Apple Watch: Apple Health (HealthKit) в FHIR с кодом на Swift для ежедневной статистики.
- Android, Wear OS, Fitbit, Garmin, Oura, Withings: Health Connect в FHIR с кодом на Flutter, который работает на обеих платформах.
- Samsung Galaxy Watch и Samsung Health: Samsung Health в FHIR: что попадает в Health Connect и что требует собственного SDK от Samsung.
Правила, которым стоит следовать
- Читайте только то, что используете, и запрашивайте каждый тип данных отдельно; люди предоставляют частичные разрешения.
- Указывайте источник данных. Носимые устройства потребителей не являются диагностическими приборами. Обозначайте их данные как данные устройства (
author_type: device) и указывайте, из какого приложения они поступили, чтобы клиницист мог правильно их интерпретировать. - Соблюдайте правила платформы. Руководство по проверке приложений Apple (5.1.3) запрещает использовать данные о состоянии здоровья в рекламных целях и хранить личную медицинскую информацию в iCloud; Google Play требует декларацию о приложениях для здоровья для приложений, использующих Health Connect.
- Предоставьте пользователям возможность отключиться и решить, остаются ли уже скопированные данные в записи.
Что Anpheros делает и чего не делает
Платформа Anpheros сама по себе не подключается к Apple Health, Health Connect или каким-либо облачным сервисам поставщиков: ваше приложение считывает данные с телефона и записывает их через API. Собственное приложение Anpheros, Anpheros Daily, делает именно это: оно считывает данные из Apple Health на iPhone и Health Connect на Android, ведет ежедневные сводки и записывает их в FHIR-запись пользователя с указанными выше кодами. Подключение устройств является частью планов Plus и Max.
Часто задаваемые вопросы
Как получить данные Apple Watch на сервер FHIR?
Прочитайте их на iPhone из Apple Health с помощью HealthKit (серверного API нет), суммируйте их за день, и ваш бэкенд запишет каждую метрику как Observation с кодом LOINC и единицей измерения UCUM, пометив ее как данные устройства.
Существует ли облачный API для Health Connect или Apple Health?
Нет. Оба хранят данные на телефоне; приложение, установленное на телефоне, читает их с разрешения пользователя. Облачные сервисы поставщиков, такие как Garmin, Fitbit или Oura, имеют свои собственные API, но чтение хранилища данных о здоровье телефона охватывает большинство из них с помощью одной интеграции.
Какой код LOINC следует использовать для шагов?
41950-7, "Number of steps in 24 hour Measured", с ежедневным effectivePeriod. Для частоты сердечных сокращений используйте 8867-4, для SpO₂ 59408-5, для продолжительности сна 93832-4.
Следует ли мне хранить каждый образец сердечного ритма в FHIR?
Обычно нет. Ежедневная сводка со средним, минимальным и максимальным значением — это то, что читает пользователь или врач; отдельные показания должны быть в записи только тогда, когда они имеют значение сами по себе, например, событие нерегулярного ритма.
Могу ли я использовать один код для HRV из Apple Health и Health Connect?
Нет. Apple Health сообщает SDNN, а Health Connect сообщает RMSSD; они измеряют разные вещи и требуют разных кодов.
Связанные материалы
- API носимых устройств: Fitbit, Garmin, Oura и Withings
- API трекеров здоровья: хранение данных трекера на сервере с согласия пользователя
- Как создать приложение для персональной медицинской карты
- Интеграции в здравоохранении: устройства наряду с лабораториями, клиниками и приложениями
- Кодовые системы FHIR: LOINC и UCUM
- Происхождение медицинских данных: объяснение
- Как нормализовать медицинские данные
- Удаленный мониторинг пациентов с помощью FHIR: отдельные показания, веб-хуки и оповещения
Try it free in the sandbox · first FHIR call in 5 minutesFree · 30 synthetic patients · no card