SmartSpectra SDK

Configuring Metrics on Node.js

Request pulse, breathing, HRV and EDA metric groups from the SmartSpectra Node.js SDK, and read the samples its event handlers deliver.

The Node.js SDK passes requested metric codes through to the native SmartSpectra C++ SDK. Omitting requestedMetrics uses the default breathing bundle.

Breathing and Pulse

Request Metrics

Request the breathing bundle plus the cardio bundle (pulse rate, arterial pressure trace, HRV):

import { SmartSpectraSDK, breathingMetrics, cardioMetrics } from '@smartspectra/node-sdk';

const sdk = new SmartSpectraSDK({
  apiKey: 'YOUR_API_KEY',
  requestedMetrics: [...breathingMetrics, ...cardioMetrics],
});

The bundle exports (breathingMetrics, cardioMetrics, faceMetrics, edaMetrics) contain the MetricType integer codes defined in metric_types.proto. defaultSupportedMetrics is the bundle used when requestedMetrics is omitted (currently equal to breathingMetrics).

Read Metrics

Read the latest breathing and pulse samples from the metrics event:

import { decodeMetrics } from '@smartspectra/node-sdk';

sdk.on('metrics', (buf, timestampUs) => {
  const metrics = decodeMetrics(buf) as any;
  if (Buffer.isBuffer(metrics)) return;

  const breathingRate = metrics.breathing?.rate?.at(-1)?.value;
  const chestTrace = metrics.breathing?.upperTrace?.at(-1)?.value;
  const abdomenTrace = metrics.breathing?.lowerTrace?.at(-1)?.value;
  const pulseRate = metrics.cardio?.pulseRate?.at(-1)?.value;
});

Cardio fields are empty unless you request a cardio metric such as PULSE_RATE.

Requested metrics are validated against your subscription during SDK startup. If a metric is not authorized it is omitted from the output — the field is simply empty, with no error — so treat a persistently empty metric as a possible authorization gap rather than a signal-quality problem. If the authorization request itself fails, startup reports an error.

Advanced

Combine bundles or hand-pick MetricType codes for finer control:

import {
  SmartSpectraSDK, breathingMetrics, cardioMetrics, faceMetrics, edaMetrics,
} from '@smartspectra/node-sdk';

const sdk = new SmartSpectraSDK({
  apiKey: 'YOUR_API_KEY',
  requestedMetrics: [
    ...breathingMetrics,
    ...cardioMetrics,
    ...faceMetrics,
    ...edaMetrics,
  ],
});

Read the advanced fields from the same decoded metrics object:

sdk.on('metrics', (buf, timestampUs) => {
  const metrics = decodeMetrics(buf) as any;
  if (Buffer.isBuffer(metrics)) return;

  const pressureTrace = metrics.cardio?.arterialPressureTrace?.at(-1)?.value;
  const hrvRmssd = metrics.cardio?.hrv?.at(-1)?.rmssd;

  const edaTrace = metrics.eda?.trace?.at(-1)?.value;

  const faceLandmarks = metrics.face?.landmarks?.at(-1)?.value;
  const blinking = metrics.face?.blinking?.at(-1)?.detected;
  const talking = metrics.face?.talking?.at(-1)?.detected;
  const expression = metrics.face?.expression?.at(-1);
});

Advanced Payload Shape

decodeMetrics returns the generated protobuf payload as a JavaScript object. Requested advanced metrics populate these fields:

type Metrics = {
  breathing?: Breathing;
  eda?: Eda;
  face?: Face;
  cardio?: Cardio;
};

type Cardio = {
  pulseRate?: MeasurementWithConfidence[];
  arterialPressureTrace?: MeasurementWithConfidence[];
  hrv?: Hrv[];
};

type Hrv = {
  rmssd: number;
  meanNn: number;
  sdnn: number;
  baevsky: number;
  timestamp: number;
  confidence: number;
  stable: boolean;
};

type Eda = {
  trace?: Measurement[];
};

type Face = {
  landmarks?: Landmarks[];
  blinking?: DetectionStatus[];
  talking?: DetectionStatus[];
  expression?: Expression[];
};

EDA may take longer to produce its first sample than breathing or cardio outputs. See Data Types for the complete protobuf schema.

On this page