Skip to content

Sensors & Real-Time Data Bus

BloomSpark includes a high-performance, real-time data bus and pre-built sensor rendering overlays designed to display environmental and telemetry streams without impacting UI performance.


📡 The Real-Time Data Bus (F22)

The DataBus is a unified network wrapper supporting four standard ingestion protocols:

typescript
export interface DataBusConfig {
  /** Ingestion transport selection. */
  protocol: 'mqtt' | 'websocket' | 'sse' | 'rest-poll';
  
  /** Server gateway endpoint URL. */
  endpoint: string;
  
  /** Polling frequency in milliseconds (only for REST poll). Default is 5000. */
  pollInterval?: number;
  
  /** Topic or channel paths to subscribe to. */
  topics: string[];
}

Backpressure Ring Buffer & RAF Batching

Environmental sensor streams can generate high packet volumes. To prevent main-thread blockages, the Data Bus implements a performance shield:

  1. Worker-Level Ingestion: Sockets are established and managed inside the Comlink Web Worker.
  2. Ring Buffer Caching: Incoming telemetry frames are queued in a high-capacity, circular Ring Buffer.
  3. rAF Batching: During each browser requestAnimationFrame cycle (every 16ms), the main thread requests only the latest state frame from the buffer, discarding intermediate telemetry spikes.
  4. Imperative State Injection: Updates are injected directly into the MapLibre canvas using map.setFeatureState(), avoiding costly React re-renders.

🌡️ Pre-Built Sensor Layers (F9)

The SDK provides declarative layers for common IoT building sensors:

tsx
import { SensorLayer } from '@bloomsparkagency/core';

export function BuildingIoT() {
  return (
    <>
      {/* Dynamic temperature layer rendered as color-changing spheres */}
      <SensorLayer
        kind="temperature"
        data={liveTelemetry} // Array of { id, position: { levelIndex, x, z }, value }
        unit="celsius"
        tooltipTemplate="Room {{ id }} is currently {{ formatNumber value fractionDigits=1 }}°C"
      />
    </>
  );
}

Supported sensor kinds:

  • temperature
  • humidity
  • co2
  • voc (Volatile Organic Compounds)
  • pressure
  • peopleCounter

📝 Handlebars Tooltip Templates

Custom labels and popup boxes are rendered using a built-in, secure subset of Handlebars compiled in the background:

Helper NameParametersUsage / Description
fallbackvalue, defaultReturns the fallback if the primary variable is missing: &#x7b;&#x7b; fallback temp "N/A" &#x7d;&#x7d;
formatDatevalue, formatParses epoch numbers and formats dates: &#x7b;&#x7b; formatDate ts "YYYY-MM-DD" &#x7d;&#x7d;
formatNumbervalue, fractionDigitsFormats floats: &#x7b;&#x7b; formatNumber value fractionDigits=2 &#x7d;&#x7d;
ifEqualsval1, val2Conditional block helper evaluating equality.
jsonvalueSerializes objects to strings for debugging: &#x7b;&#x7b; json meta &#x7d;&#x7d;

📊 <PopularTimesChart> (F21)

This component aggregates people-counter sensor data to render a Google-style "Popular Times" bar chart, helping teams analyze spatial utilization patterns:

tsx
import { PopularTimesChart } from '@bloomsparkagency/ui';

export function AnalyticsPanel() {
  return (
    <PopularTimesChart
      zoneId="meeting-room-hq-42"
      window="last-90d"              // 'last-30d' | 'last-90d' | 'all-time'
      granularity="hour-of-week"     // Summarizes peaks per hour across days (168 columns)
      style={{ height: 200 }}
    />
  );
}

Data is pulled directly from the timeseries telemetry logs (persisted using the TimescaleDB hypertable schema, see BACKEND_GUIDE), and parsed inside the Wayfinding/Search Web Worker.

Released under commercial licensing.