During the measurement
After the measurement has started, you can monitor the stage and progress of the measurement.
Checking the measurement state
To see what is happening underneath you can call the getMeasurementState() method. It returns the following enumeration informing you about the state of the measurement.
enum MeasurementState {
notStarted, // Measurement has not started yet
waitingForFace, // Waiting for face to be properly positioned in the frame
runningSignalShort, // Measurement started: Signal is too short for any conclusions
runningSignalGood, // Measurement proceeding: Signal quality is good
runningSignalBad, // Measurement stalled due to poor signal quality
runningSignalBadDeviceUnstable, // Measurement stalled due to poor signal quality (caused by unstable device)
finalizing, // Measurement capture has ended and final result computation is in progress
finished, // Measurement has finished successfully
failed, // Measurement has failed
}After a measurement has been started and the face is properly recognized, the measurement state is one of the RunningSignal* variants. Until at least four heartbeats are available, the measurement remains in RunningSignalShort. After this warm-up, RunningSignalGood means that the SDK has recently detected a heartbeat meeting the configured confidence threshold. If no such heartbeat is detected within the freshness timeout, the state changes to RunningSignalBad, or to RunningSignalBadDeviceUnstable when device instability is detected. These bad-signal states describe signal quality and metric availability, not a stopped measurement. RunningSignalGood does not guarantee that every real-time metric is already available: individual metrics can require additional warm-up time or a longer heartbeat history.
To monitor the end of a measurement, wait for Finished or Failed. Either state indicates that the measurement has concluded.
Tracking the measurement progress
To check the progress of the whole measurement you can call the getMeasurementProgressPercentage() method, returning a floating point number between 0 and 100.
Real-time metrics
During the measurement you can query the SDK for real-time metrics. These metrics are updated every second and calculated over their configured periods. If no heartbeat is detected within the freshness timeout, heartbeat-derived live metrics become unavailable. The embedded UI retains the last displayed values and marks them as stale until fresh metrics are available again.
Heart rate
You can query the real-time heart rate based on the last 10 seconds of the measurement. The provided value is the average heart rate over the specified time interval and is expressed in beats per minute (BPM), rounded to the nearest integer.
final hr10s = await ShenaiSdk.getHeartRate10s();Freshness timeout
The freshness timeout adapts to the recent heart rate and ranges from 3 to 6 seconds. A slower heart rate naturally produces longer intervals between heartbeats, so the SDK allows more time before treating metrics as stale. This avoids false interruptions at low heart rates while still making metrics unavailable promptly when new heartbeats stop arriving.
Measurement success
When the Shen.AI SDK engine enters the Finished state it means that the measurement has concluded and computed metrics are available.
See Results to see how to access the results.