Skip to content

Professional bridge for receiving and processing real-time vital signs data from Vital Recorder with flexible transport options

License

Notifications You must be signed in to change notification settings

UTBM-Alison/vital-dispatch-server

Repository files navigation

VitalRecorderListener

A modular TypeScript listener for Vital Recorder data with flexible output options including medical monitoring systems.

npm version License: MIT TypeScript

Features

  • 🔌 Socket.IO v4.0.0 server for receiving Vital Recorder data
  • 📊 Real-time data processing and transformation
  • 🎯 Multiple output targets (Console, API endpoints, JSON files, Telegraf/InfluxDB)
  • ⏱️ Millisecond-precision timestamps (ISO format)
  • 🔄 Automatic retry logic for API outputs
  • 📁 File rotation and size management
  • 🏥 Medical system integration via Telegraf → InfluxDB
  • 🏥 ICU bed assignment and vital signs mapping
  • 📝 Full TypeScript support
  • 🚀 Fast, immediate data forwarding
  • ✅ Comprehensive test coverage

Installation

npm install vital-recorder-listener

Quick Start

Basic Usage

import { VitalRecorderListener } from 'vital-recorder-listener';

const listener = new VitalRecorderListener({
  port: 3000,
  outputs: [
    {
      type: 'console',
      verbose: true,
      colorized: true
    }
  ]
});

await listener.start();

Configure Vital Recorder

In Vital Recorder settings, set:

SERVER_IP=127.0.0.1:3000

Output Types

Console Output

{
  type: 'console',
          verbose?: boolean,      // Show detailed output (default: false)
          colorized?: boolean     // Use colors in output (default: true)
}

API Output

{
  type: 'api',
          endpoint: string,          // API endpoint URL
          headers?: object,          // Custom headers
          separateRooms?: boolean,   // Send each room separately
          retryAttempts?: number,    // Number of retry attempts (default: 3)
          retryDelayMs?: number      // Delay between retries (default: 1000)
}

File Output

{
  type: 'file',
          filepath: string,          // Path to output file
          format?: 'json' | 'jsonl', // JSON or JSON Lines format (default: 'json')
          prettify?: boolean,        // Pretty print JSON (default: false)
          rotateSize?: number,       // Max file size in MB before rotation
          maxFiles?: number,         // Max number of rotated files to keep
          includeTimestamp?: boolean // Include timestamp in filename
}

Telegraf Output (Medical Systems Integration)

{
  type: 'telegraf',
  host: string,              // Telegraf host (default: 'localhost')
  port: number,              // Telegraf HTTP listener port (default: 8094)
  endpoint?: string,         // HTTP endpoint path (default: '/telegraf')
  headers?: object,          // Custom HTTP headers
  retryAttempts?: number,    // Number of retry attempts (default: 3)
  retryDelayMs?: number,     // Delay between retries (default: 1000)
  timeoutMs?: number,        // Request timeout (default: 5000)
  maxBeds?: number,          // Max ICU beds for cycling (default: 20)
  assessor?: string          // Clinical assessor name (default: 'VitalRecorder')
}

Medical Systems Integration

The Telegraf output enables integration with medical monitoring systems by converting VitalRecorder data into medical format:

Vital Signs Mapping

VitalRecorder parameters are automatically mapped to standard vital signs:

  • HR, PLETH_HR → Heart Rate
  • NIBP_SBP, ART_SBP → Systolic Blood Pressure
  • NIBP_DBP, ART_DBP → Diastolic Blood Pressure
  • PLETH_SPO2, SO2_1, SO2_2 → Oxygen Saturation
  • BT → Body Temperature
  • RR, RR_CO2 → Respiratory Rate
  • Plus many more physiological parameters

ICU Bed Assignment

Data is automatically assigned to ICU beds (ICU-01, ICU-02, etc.) based on:

  • VitalRecorder code numbers
  • Room names/numbers
  • Timestamp-based cycling

InfluxDB Integration

Vital signs data only is sent to InfluxDB via Telegraf:

  • bed_vitals - Standard vital signs and physiological parameters from VitalRecorder

Note: EMG data and clinical scores (BPS/RASS) are not included in the Telegraf output, as these are expected to be provided to Telegraf separately through other channels.

Examples

Medical System Integration

const listener = new VitalRecorderListener({
  port: 3000,
  debug: true,
  outputs: [
    // Send to medical monitoring system
    {
      type: 'telegraf',
      host: 'telegraf-server',
      port: 8094,
      maxBeds: 20,
      assessor: 'ICU_System',
      retryAttempts: 5
    },
    // Local console monitoring
    {
      type: 'console',
      verbose: false,
      colorized: true
    }
  ]
});

await listener.start();

Multiple Outputs

const listener = new VitalRecorderListener({
  port: 3000,
  debug: true,
  outputs: [
    // Console for local monitoring
    {
      type: 'console',
      verbose: false,
      colorized: true
    },
    // Primary API endpoint
    {
      type: 'api',
      endpoint: 'https://api.example.com/vital',
      headers: {
        'Authorization': 'Bearer token'
      },
      separateRooms: true,
      retryAttempts: 5
    },
    // File logging with rotation
    {
      type: 'file',
      filepath: './logs/vital-data.json',
      format: 'jsonl',
      rotateSize: 10, // 10MB
      maxFiles: 5
    },
    // Medical system integration
    {
      type: 'telegraf',
      host: 'localhost',
      port: 8094,
      maxBeds: 10
    }
  ]
});

await listener.start();

File Output Examples

// JSON Lines format (recommended for streaming)
{
  type: 'file',
  filepath: './data/vital-stream.jsonl',
  format: 'jsonl'
}

// Pretty JSON with rotation
{
  type: 'file',
  filepath: './data/vital-data.json',
  format: 'json',
  prettify: true,
  rotateSize: 5, // Rotate after 5MB
  maxFiles: 10   // Keep last 10 files
}

// Timestamped files
{
  type: 'file',
  filepath: './archive/vital.json',
  includeTimestamp: true // Creates: vital_2024-01-01T12-00-00-000Z.json
}

Embedded in Application

const listener = new VitalRecorderListener({ port: 3000 });

// Start listener
await listener.start();

// Check status
const status = listener.getStatus();
console.log(status);
// {
//   isRunning: true,
//   port: 3000,
//   connections: 1,
//   hasData: true,
//   lastUpdate: "2024-01-01T12:00:00.123Z",
//   outputsCount: 2
// }

// Get last data
const data = listener.getLastData();
if (data) {
  console.log(`Tracks: ${data.allTracks.length}`);
}

// Stop listener
await listener.stop();

Medical System Setup

Telegraf Configuration

Create a telegraf.conf file for medical data collection:

[global_tags]
  environment = "medical_icu"
  facility = "vital_recorder_integration"

[agent]
  interval = "1s"

# HTTP Listener for VitalRecorder data
[[inputs.http_listener_v2]]
  service_address = ":8094"
  paths = ["/telegraf"]
  methods = ["POST"]
  data_format = "influx"

# Send to InfluxDB
[[outputs.influxdb_v2]]
  urls = ["http://influxdb:8086"]
  token = "your-influx-token"
  organization = "medical_org"
  bucket = "medical_data"
  namepass = ["bed_vitals"]  # Only vital signs from VitalRecorder

Docker Compose Example

version: '3.8'
services:
  influxdb:
    image: influxdb:2.7
    ports:
      - "8086:8086"
    environment:
      - DOCKER_INFLUXDB_INIT_MODE=setup
      - DOCKER_INFLUXDB_INIT_USERNAME=admin
      - DOCKER_INFLUXDB_INIT_PASSWORD=password123
      - DOCKER_INFLUXDB_INIT_ORG=medical_org
      - DOCKER_INFLUXDB_INIT_BUCKET=medical_data

  telegraf:
    image: telegraf:1.28
    volumes:
      - ./telegraf.conf:/etc/telegraf/telegraf.conf:ro
    ports:
      - "8094:8094"
    depends_on:
      - influxdb

  vital-listener:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - telegraf

API Endpoints

The listener provides several REST endpoints for data retrieval:

  • GET /health - Health check and status
  • GET /api/data - Get all processed data
  • GET /api/data/rooms - Get data organized by rooms
  • GET /api/data/tracks - Get all tracks (flattened)

Development

Installation

# Clone the repository
git clone https://github.com/yourusername/vital-recorder-listener.git
cd vital-recorder-listener

# Install dependencies
npm install

# Build TypeScript
npm run build

Running Tests

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

# Run specific test file
npx jest tests/unit/processors/DataProcessor.test.ts

# Run unit tests only
npx jest tests/unit

# Run integration tests only
npx jest tests/integration

Test Coverage

The package includes comprehensive test coverage:

  • Unit Tests: Test individual components in isolation

    • DataProcessor: Data decompression and transformation
    • FileOutput: File writing and rotation logic
    • ConsoleOutput: Console formatting
    • ApiOutput: HTTP requests and retry logic
    • TelegrafOutput: Medical data mapping and InfluxDB integration
    • TimeFormatter: Timestamp conversions
    • VitalRecorderListener: Core functionality
  • Integration Tests: End-to-end testing

    • Socket.IO communication with real data
    • Multiple concurrent connections
    • API endpoints functionality
    • Output integrations
    • Medical system integration
    • Error handling and recovery

Linting

# Run ESLint
npm run lint

# Fix linting issues
npx eslint . --ext .ts --fix

Examples

# Run basic example
npx ts-node example.ts basic

# Run multi-output example
npx ts-node example.ts multi

# Run embedded example
npx ts-node example.ts embedded

# Run advanced example
npx ts-node example.ts advanced

# Run Telegraf/medical example
npx ts-node example.ts telegraf

Data Format

Processed Data Structure

{
  vrcode?: string,              // Vital Recorder code
  timestamp: string,            // ISO timestamp with milliseconds
  rooms: [
    {
      roomIndex: number,
      roomName: string,
      tracks: [
        {
          name: string,
          value: string,        // Formatted display value
          rawValue: any,        // Original value
          unit: string,
          timestamp: string,    // ISO timestamp with ms
          roomIndex: number,
          roomName: string,
          trackIndex: number,
          recordIndex: number,
          type: 'waveform' | 'number' | 'string' | 'other'
        }
      ]
    }
  ],
  allTracks: [...]             // All tracks flattened
}

Medical Data Format

When using Telegraf output, data is converted to medical format:

Vital Signs (bed_vitals)

bed_vitals,bed_id=ICU-01 heart_rate=75,pleth_hr=76,nibp_sbp=120,nibp_dbp=80,art_sbp=118,art_dbp=78,pleth_spo2=98,rr=16,rr_co2=15,bt=37.2,etco2=35.5

Note: Only vital signs and physiological parameters from VitalRecorder are included. EMG data and clinical assessment scores (BPS/RASS) are intentionally excluded as they are expected to be provided to Telegraf through separate channels.

Supported VitalRecorder Parameters

The Telegraf output automatically maps these VitalRecorder parameters:

Cardiovascular:

  • HR, PLETH_HR, PVC

Blood Pressure:

  • NIBP_SBP, NIBP_DBP, NIBP_MBP
  • ART_SBP, ART_DBP, ART_MBP

Oxygenation & Saturation:

  • PLETH_SPO2, SO2_1, SO2_2, SPHB

Respiratory:

  • RR, RR_CO2, ETCO2, TV, PEEP, PIP

Temperature:

  • BT

Anesthesia & Gas:

  • GAS1_AGENT, GAS1_EXPIRED

Perfusion & Flow:

  • CO, TOTAL_VOL, FLOW_RATE, PVI, PSI

Neurological:

  • SEFL

Waveform Statistics:

  • ECG, PLETH, ART, CVP, EEG, CO2 (min, max, mean, std, rms, points)

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

MIT - see LICENSE file for details

Support

For issues, questions, or suggestions, please open an issue on GitHub.

About

Professional bridge for receiving and processing real-time vital signs data from Vital Recorder with flexible transport options

Resources

License

Stars

Watchers

Forks

Packages

No packages published