Chapter 6
EHR/EMR connectivity, clinical workflow integration, care coordination platforms, billing systems, and health information exchanges for seamless healthcare ecosystem integration.
Remote patient monitoring data delivers maximum value when integrated into the broader healthcare ecosystem. Standalone RPM platforms that operate in isolation create data silos, require duplicate documentation, and fail to support seamless clinical workflows. The WIA-RPM standard emphasizes integration as a core requirement, specifying interfaces with electronic health records, care coordination platforms, billing systems, and health information exchanges.
Integration complexity varies significantly across healthcare organizations. Large health systems may operate multiple EHR platforms with varying integration capabilities. Smaller practices may lack technical resources for custom integration development. The standard addresses this diversity by specifying both baseline interoperability requirements and advanced integration patterns for organizations seeking deeper workflow integration.
Electronic Health Record integration represents the most critical integration for clinical adoption. Clinicians spend the majority of their documentation time within EHR systems; RPM data that requires accessing separate platforms will be underutilized. Effective EHR integration surfaces relevant RPM information within clinical workflows while supporting bidirectional data flow.
| Approach | Description | Pros | Cons |
|---|---|---|---|
| SMART on FHIR Apps | Embedded applications within EHR | Native experience, deep integration | EHR-specific development |
| FHIR API | Standardized data exchange | Standards-based, portable | Varies by EHR implementation |
| HL7 v2 Interface | Traditional message-based | Widely supported | Legacy, less flexible |
| CCD/C-CDA Exchange | Document-based exchange | Standard format | Not real-time |
| Direct Messaging | Secure healthcare email | Simple, widely available | Manual intervention needed |
SMART on FHIR provides the most seamless EHR integration experience, enabling RPM applications to run embedded within the EHR interface. Users access RPM functionality without context switching, and the application inherits the EHR's authentication and patient context.
// WIA Standard: SMART on FHIR Launch Handler
class SmartOnFhirApp {
constructor() {
this.client = null;
this.patient = null;
}
async launch() {
// Handle SMART launch from EHR
try {
this.client = await FHIR.oauth2.ready();
this.patient = await this.client.patient.read();
console.log(`Launched in context of patient: ${this.patient.id}`);
// Load RPM data for this patient
await this.loadRpmData(this.patient.id);
// Render RPM dashboard
this.renderDashboard();
} catch (error) {
console.error('SMART launch failed:', error);
this.handleLaunchError(error);
}
}
async loadRpmData(patientId) {
// Fetch recent observations from RPM platform
const observations = await this.fetchRpmObservations(patientId);
// Fetch alerts
const alerts = await this.fetchActiveAlerts(patientId);
// Fetch care plan
const carePlan = await this.fetchCarePlan(patientId);
return {
observations,
alerts,
carePlan
};
}
async writeObservationToEhr(observation) {
// Write RPM observation to EHR via FHIR
const fhirObservation = this.convertToFhir(observation);
try {
const result = await this.client.create(fhirObservation);
console.log(`Observation created: ${result.id}`);
return result;
} catch (error) {
console.error('Failed to write observation:', error);
throw error;
}
}
convertToFhir(rpmObservation) {
return {
resourceType: 'Observation',
status: 'final',
category: [{
coding: [{
system: 'http://terminology.hl7.org/CodeSystem/observation-category',
code: 'vital-signs'
}]
}],
code: {
coding: [{
system: 'http://loinc.org',
code: rpmObservation.loincCode,
display: rpmObservation.displayName
}]
},
subject: {
reference: `Patient/${this.patient.id}`
},
effectiveDateTime: rpmObservation.timestamp,
valueQuantity: {
value: rpmObservation.value,
unit: rpmObservation.unit,
system: 'http://unitsofmeasure.org',
code: rpmObservation.ucumCode
},
device: {
display: rpmObservation.deviceName
}
};
}
}
Beyond data exchange, effective integration requires embedding RPM into clinical workflows. Care teams should encounter RPM information at natural decision points without requiring separate workflow steps. The WIA standard identifies key workflow integration points.
Display RPM summary and active alerts when clinician opens patient chart. Surface most relevant recent data and trends.
Route RPM alerts to clinical inbox alongside other action items. Enable acknowledge and act from inbox without navigation.
Pre-populate visit notes with RPM data. Include trends, alert history, and compliance metrics relevant to visit reason.
Suggest relevant orders based on RPM findings. Link medication adjustments to supporting vital sign data.
Display RPM-derived progress toward care plan goals. Update care plans based on monitoring outcomes.
Include RPM metrics in population health views. Enable filtering and prioritization by monitoring status.
RPM programs typically operate within broader care management initiatives. Integration with care coordination platforms ensures RPM data informs care planning while care plans drive monitoring protocols.
// WIA Standard: Care Coordination Integration
class CareCoordinationIntegration {
async syncCarePlan(patientId) {
// Fetch care plan from care coordination platform
const carePlan = await this.careCoordClient.getCarePlan(patientId);
// Extract monitoring-relevant goals
const monitoringGoals = carePlan.goals.filter(g =>
g.category === 'PHYSIOLOGICAL' ||
g.category === 'BEHAVIORAL'
);
// Configure RPM monitoring based on care plan
for (const goal of monitoringGoals) {
await this.configureMonitoring(patientId, goal);
}
return {
goalsConfigured: monitoringGoals.length,
carePlanId: carePlan.id
};
}
async configureMonitoring(patientId, goal) {
// Map care plan goal to monitoring configuration
const monitoringConfig = {
'BP_CONTROL': {
parameters: ['systolic_bp', 'diastolic_bp'],
frequency: 'twice_daily',
target: { systolic: goal.targetValue.systolic, diastolic: goal.targetValue.diastolic },
alertThresholds: this.calculateThresholds(goal)
},
'WEIGHT_MANAGEMENT': {
parameters: ['weight'],
frequency: 'daily',
target: goal.targetValue,
alertThresholds: { gain_1day: 2, gain_3day: 4 }
},
'GLUCOSE_CONTROL': {
parameters: ['glucose'],
frequency: 'per_meal',
target: { fasting: goal.targetValue.fasting, postprandial: goal.targetValue.postprandial },
alertThresholds: { low: 70, high: 180 }
}
};
const config = monitoringConfig[goal.type];
if (config) {
await this.rpmClient.setMonitoringConfig(patientId, config);
}
}
async reportGoalProgress(patientId) {
// Calculate goal progress from RPM data
const rpmData = await this.rpmClient.getPatientSummary(patientId);
const carePlan = await this.careCoordClient.getCarePlan(patientId);
const progressReport = carePlan.goals.map(goal => ({
goalId: goal.id,
currentValue: this.getCurrentValue(rpmData, goal),
targetValue: goal.targetValue,
progressPercent: this.calculateProgress(rpmData, goal),
trend: this.calculateTrend(rpmData, goal),
lastUpdated: new Date()
}));
// Update care coordination platform
await this.careCoordClient.updateGoalProgress(patientId, progressReport);
return progressReport;
}
}
RPM reimbursement requires accurate documentation of services provided. Integration with billing systems automates charge capture, reduces missed billing, and ensures compliance with payer requirements.
| Code | Service | Documentation Requirements |
|---|---|---|
99453 |
Initial setup | Date of setup, device provided, education delivered |
99454 |
Device supply/transmission | 16+ days of data transmitted in month |
99457 |
Treatment management (20 min) | Time log, clinical staff, interactive communication |
99458 |
Additional 20 min | Time log showing additional 20 min increments |
99091 |
Data analysis (physician) | 30+ min physician/QHP time, interpretation documented |
// WIA Standard: Automated Billing Integration
class RpmBillingIntegration {
async generateMonthlyCharges(patientId, month) {
const charges = [];
// Check 99454 eligibility (device supply/transmission)
const transmissionDays = await this.countTransmissionDays(patientId, month);
if (transmissionDays >= 16) {
charges.push({
code: '99454',
description: 'RPM device supply with daily recording',
units: 1,
documentation: {
transmissionDays: transmissionDays,
deviceType: await this.getDeviceType(patientId)
}
});
}
// Check 99457 eligibility (treatment management)
const clinicalTime = await this.getClinicalTime(patientId, month);
if (clinicalTime.totalMinutes >= 20) {
const units = Math.floor(clinicalTime.totalMinutes / 20);
// First 20 minutes = 99457
charges.push({
code: '99457',
description: 'RPM treatment management, first 20 min',
units: 1,
documentation: {
timeMinutes: Math.min(clinicalTime.totalMinutes, 20),
activities: clinicalTime.activities.slice(0, this.getActivitiesFor(20)),
staffCredentials: clinicalTime.staffCredentials
}
});
// Additional 20-minute increments = 99458
if (units > 1) {
charges.push({
code: '99458',
description: 'RPM treatment management, additional 20 min',
units: units - 1,
documentation: {
additionalMinutes: clinicalTime.totalMinutes - 20,
activities: clinicalTime.activities.slice(this.getActivitiesFor(20))
}
});
}
}
// Submit to billing system
const billingResult = await this.billingClient.submitCharges({
patientId,
serviceMonth: month,
charges,
supportingDocs: await this.generateSupportingDocumentation(patientId, month, charges)
});
return billingResult;
}
async trackClinicalTime(patientId, activity) {
// Log clinical time for billing documentation
const timeEntry = {
patientId,
timestamp: new Date(),
duration: activity.durationMinutes,
activityType: activity.type,
description: activity.description,
staffId: activity.performedBy,
staffCredentials: await this.getStaffCredentials(activity.performedBy),
interactiveContact: activity.isInteractive,
alertsReviewed: activity.alertIds || []
};
await this.timeTrackingClient.logTime(timeEntry);
return timeEntry;
}
}
Health Information Exchanges enable RPM data to flow across organizational boundaries, ensuring all providers involved in a patient's care have access to monitoring information. HIE integration supports care transitions and enables RPM data to inform decisions across the care continuum.
| Network | Focus | RPM Relevance |
|---|---|---|
| CommonWell Health Alliance | Cross-vendor data sharing | Patient matching, document query |
| Carequality | Framework interoperability | Multi-network connectivity |
| eHealth Exchange | Federal/state connectivity | Government program integration |
| TEFCA (upcoming) | National framework | Standardized nationwide exchange |
RPM platforms must expose well-designed APIs enabling integration with diverse healthcare systems. The WIA standard specifies API requirements ensuring platforms can be integrated effectively.
// WIA Standard: RPM Platform API Specification
openapi: 3.0.0
info:
title: WIA RPM Platform API
version: 1.0.0
description: Standard API for RPM platform integration
paths:
/patients/{patientId}/observations:
get:
summary: Get patient observations
parameters:
- name: patientId
in: path
required: true
schema:
type: string
- name: code
in: query
description: LOINC code filter
schema:
type: string
- name: date
in: query
description: Date range (FHIR date format)
schema:
type: string
- name: _count
in: query
description: Page size
schema:
type: integer
responses:
200:
description: Bundle of Observation resources
content:
application/fhir+json:
schema:
$ref: '#/components/schemas/Bundle'
/patients/{patientId}/alerts:
get:
summary: Get patient alerts
parameters:
- name: patientId
in: path
required: true
schema:
type: string
- name: status
in: query
description: Alert status filter
schema:
type: string
enum: [active, acknowledged, resolved]
- name: priority
in: query
description: Priority level filter
schema:
type: string
enum: [critical, high, medium, low]
responses:
200:
description: List of alerts
content:
application/json:
schema:
$ref: '#/components/schemas/AlertList'
/patients/{patientId}/summary:
get:
summary: Get patient monitoring summary
description: Returns aggregated summary suitable for EHR display
responses:
200:
description: Patient monitoring summary
content:
application/json:
schema:
$ref: '#/components/schemas/PatientSummary'
/webhooks:
post:
summary: Register webhook for events
requestBody:
content:
application/json:
schema:
type: object
properties:
url:
type: string
format: uri
events:
type: array
items:
type: string
enum: [alert.created, alert.escalated, observation.critical]
secret:
type: string
responses:
201:
description: Webhook registered
Integration introduces security considerations as PHI flows between systems. The WIA standard specifies security requirements for all integration interfaces.
Healthcare system integration transforms RPM from standalone monitoring to an integral component of clinical care delivery. Through EHR integration, clinical workflow embedding, care coordination connectivity, and billing automation, RPM programs achieve the clinical adoption necessary for meaningful patient impact.
The WIA-RPM standard provides comprehensive integration specifications ensuring platforms can connect with diverse healthcare ecosystems. As interoperability standards mature and regulatory requirements evolve, adherence to standard integration approaches positions organizations for sustainable, scalable RPM deployments.
WIA-Official/wia-standards-public/tree/main/remote-patient-monitoring — open standard initiative providing source code for simulator, spec, API, and ebook assets cited throughout this volume; serves as the canonical verification record for all primary-source citations made by the WIA standard committee in this chapter. Canonical ENUM tokens used in this volume include HEART_RATE, BLOOD_PRESSURE, SPO2, GLUCOSE, ECG, EEG, BODY_TEMP, RESPIRATORY_RATE, ECG_PATCH, CGM, PULSE_OXIMETER, SMARTWATCH, ISO_13485, IEC_62366, ISO_14971, HL7_FHIR, DICOM, IEEE_11073, CONTINUA, FDA_510K, CE_MDR, MFDS_CLASS_2, BLUETOOTH_LE, MQTT, OAUTH2, FHIR_RESOURCE, LOINC, SNOMED_CT, ICD_11.