Core Concepts
This page covers the fundamental building blocks you'll work with across every Plexus SDK.
Sources
A source represents a single device or data origin. Each source has a unique source_id — a URL-safe string like esp32-001, test-rig-A, or drone.alpha.
px = Plexus(source_id="test-rig-01")plexus_client_t* px = plexus_init("plx_key", "esp32-001");Rules for source IDs:
- Only
a-z A-Z 0-9 . _ -characters allowed (no spaces) - Use the slug shown in the Plexus dashboard, not the display name
- Keep them consistent — the same physical device should always use the same ID
Metrics
A metric is a named value sent from a source. Metric names use dot notation for hierarchy:
px.send("engine.rpm", 3450)
px.send("coolant.temperature", 82.3)
px.send("position.x", 1.5)Supported Value Types
| Type | Example | Use Case |
|---|---|---|
| number | 72.5, -40, 3.14159 | Sensor readings (most common) |
| string | "running", "error" | Status, state labels |
| boolean | true, false | On/off, enabled/disabled |
| object | {"x": 1.2, "y": 3.4} | Vectors, structured data |
| array | [1.0, 2.0, 3.0] | Waveforms, joint angles |
Tags
Tags are key-value labels attached to data points for filtering and grouping:
px.send("temperature", 72.5, tags={"location": "lab", "unit": "A"})Tags are indexed and searchable in the dashboard. Use them for:
- Location:
building,room,rack - Device metadata:
firmware_version,hardware_rev - Experiment labels:
trial,batch,operator
Sessions
A session groups related data points for analysis and playback. Use sessions for test runs, experiments, or any bounded recording:
with px.session("thermal-cycle-001"):
while running:
px.send("temperature", read_temp())plexus_session_start(px, "motor-test-001");
// ... send data ...
plexus_session_end(px);Sessions enable:
- Playback — Replay sensor data at original speed or faster
- Comparison — Overlay multiple sessions on the same chart
- Export — Download session data as CSV or Parquet
Commands
Commands let you send typed instructions from the dashboard to a device. The dashboard auto-generates UI controls (sliders, dropdowns, toggles) from the command schema.
@px.command("set_speed", description="Set motor speed")
@param("rpm", type="float", min=0, max=10000, unit="rpm")
async def set_speed(rpm):
motor.set_rpm(rpm)
return {"actual_rpm": motor.read_rpm()}Commands are sent over WebSocket and executed in real time on the device.
Authentication
Plexus uses API keys (prefixed plx_) for all authentication. Get a key from API Keys (opens in a new tab)
export PLEXUS_API_KEY=plx_xxxxxOr pass it directly:
px = Plexus(api_key="plx_xxxxx")Data Flow
┌─────────────┐ HTTP POST ┌──────────────────┐ Store ┌────────────┐
│ Device │ ──────────────────→ │ /api/ingest │ ───────────→ │ ClickHouse │
│ (Python/C) │ │ (Next.js API) │ │ (timeseries)│
└─────────────┘ └──────────────────┘ └────────────┘
│
│ WebSocket
▼
┌──────────────────┐ Broadcast ┌────────────┐
│ PartyKit Server │ ───────────────→ │ Dashboard │
│ (real-time) │ │ (browser) │
└──────────────────┘ └────────────┘- HTTP path: Used by the
Plexus()client and C SDK for data ingestion. Data is stored in ClickHouse. - WebSocket path: Used by
plexus runfor real-time streaming. Data flows through PartyKit to connected browsers. - Both paths: When recording a session, both are used — WebSocket for live view, HTTP for persistence.
Next Steps
- Python Agent Quickstart — Send data from a Raspberry Pi
- ESP32 Quickstart — Send data from an ESP32
- HTTP API Reference — Direct HTTP integration