components/PredictionCoreTempCard.ts

Purpose

This component renders a real-time “Predicted Core Body Temperature” card that combines:

  • environmental heat stress (WBGT)
  • user physiological profile data
  • recent physical activity intensity
  • ML/ONNX-based inference

to estimate a user’s current core body temperature and heat-risk state.

The component acts as a lightweight orchestration layer between:

  • persistent user profile storage
  • activity aggregation services
  • inference/model execution
  • UI state classification
  • periodic polling behavior

It continuously refreshes prediction inputs, executes inference on a fixed cadence, and presents the result as a compact dashboard card.

Primary responsibilities include:

  • loading and normalizing user profile inputs
  • collecting rolling activity CPM averages
  • executing core temperature inference
  • preventing duplicate inference runs
  • classifying heat-risk states
  • rendering inference metadata and diagnostics
  • handling inference failures gracefully

Invariants

Core Temperature Prediction Contract

The component only renders a valid prediction when all required inputs exist:

  • finite wbgt
  • loaded user profile
  • valid recent CPM activity history

If any required input is unavailable:

  • inference is skipped
  • output resets to placeholder values

Prediction Polling Cadence

Inference runs on a fixed interval:

pollMs (default: 5000ms)

The component guarantees:

  • only one active interval exists
  • intervals are cleaned up on unmount

Single Inference Execution

Concurrent inference runs are prevented through:

isInferenceRunning.current

This guarantees:

  • only one inference executes at a time
  • overlapping async executions cannot occur

Input De-Duplication

Inference only reruns when inputs materially change.

A deterministic serialized key is generated from:

  • WBGT
  • gender
  • age
  • BMI
  • activity history
  • CPM average

Repeated identical inputs are skipped.


Profile Normalization

Loaded profile data is normalized into bounded model-safe values.

BMI Bounds

BMI is clamped to:

10 ≤ BMI ≤ 60

using:

clamp()

Gender Encoding

User gender is normalized into model-compatible integer encodings:

Profile ValueEncoded
male1
female2
other/unknown0

Safe Defaults

If profile loading fails or data is incomplete, the component falls back to deterministic defaults:

FieldDefault
gender1
age25
BMI24.0
daysActive140

This guarantees inference always receives structurally valid inputs.


CPM Dependency

Inference requires a valid rolling 40-minute CPM average.

If CPM history is unavailable:

  • prediction is withheld
  • UI enters “Collecting…” state
  • no inference occurs

Alert De-Duplication

Repeated identical inference failures only display one alert.

Alerts are deduplicated using:

lastAlertKey.current

This prevents alert spam during repeated polling failures.


Focus Refresh Behavior

Whenever the screen regains focus:

  • profile data reloads
  • inference cache resets
  • next prediction is forced to recompute

This ensures predictions always reflect the newest profile state.


Risk Classification Thresholds

Predicted temperatures are classified into fixed severity bands:

TemperatureState
< 38.0°CNormal
38.0–38.9°CWarning
≥ 39.0°CHigh

These thresholds are deterministic and UI-only.


Variants

Model Backend Variant

Inference may execute through different model backends:

BackendMeaning
onnxML inference model
baselinefallback heuristic model
unavailable

The selected backend is surfaced in the UI footer.


BMI Source Variant

BMI may originate from multiple sources:

Calculated BMI

Computed from:

  • height
  • weight

using:

calcBMI()

Default BMI

Used when anthropometric data is unavailable.

Stored BMI

Reserved for future persisted BMI support.


Activity Availability Variant

CPM Available

  • prediction runs
  • core temp displayed
  • status shows “OK”

CPM Unavailable

  • prediction withheld
  • placeholder values shown
  • collection status displayed

Profile Loading Variant

Successful Load

Uses persisted user demographics and activity metadata.

Failed Load

Falls back to safe defaults.

The UI remains operational in both cases.


WBGT Availability Variant

Valid WBGT

Inference allowed.

Invalid WBGT

Prediction disabled and reported as missing input.


Prediction State Variant

The component supports several visual output states:

StateMeaning
placeholderprediction unavailable
normallow-risk core temperature
warningelevated heat strain
highdangerous heat strain

Each state maps to unique badge colors and labels.


Polling Lifecycle Variant

Inference lifecycle changes based on component state:

StateBehavior
mountedpolling active
unfocusedfocus refresh pending
unmountedpolling stopped

Exports

PredictionCoreTempCard

const PredictionCoreTempCard: React.FC<Props>

Primary exported component.

Responsibilities include:

  • profile hydration
  • activity retrieval
  • inference orchestration
  • polling management
  • result classification
  • prediction rendering

Props

Props

type Props = {
	wbgt: number;
	wbgtLabel?: string;
	title?: string;
	pollMs?: number;
};

wbgt

Precomputed WBGT input used for prediction inference.

Expected in Celsius.


wbgtLabel

Optional UI label for the WBGT field.

Examples:

  • "WBGT Sun"
  • "WBGT Shade"

title

Optional card title override.

Default:

Core Temp Prediction

pollMs

Inference refresh cadence in milliseconds.

Default:

5000

Internal State

Input State

Maintains normalized inference inputs:

  • gender
  • age
  • bmi
  • daysActive14
  • cpm

Output State

Tracks inference outputs:

  • formatted temperature string
  • numeric temperature
  • active model backend

Status State

Tracks operational metadata:

  • CPM collection status
  • BMI source
  • alert suppression state
  • profile load state

Internal Helper Logic

clamp(v, lo, hi)

Bounds numeric values into safe ranges.

Used primarily for BMI normalization.


loadProfileFromStorage()

Loads and normalizes persisted user profile data.

Responsibilities include:

  • demographic normalization
  • BMI computation
  • fallback handling
  • activity metadata extraction

buildInputKey(cpm40)

Builds a deterministic serialized inference signature.

Used to prevent redundant inference execution.


Rendering Architecture

The card is split into two primary sections:

SectionPurpose
Inputsdisplays inference inputs
Resultdisplays prediction output

Input Panel

Displays:

  • WBGT
  • activity CPM
  • gender
  • BMI
  • age
  • recent activity history

Result Panel

Displays:

  • predicted core temperature
  • severity badge
  • model backend
  • CPM collection status

Error Handling

Inference failures are:

  • logged through global.log
  • surfaced through Alert.alert
  • deduplicated to avoid repeated alerts

The component attempts to remain operational after failures rather than entering a fatal state.