Type: how-to · Last reviewed: 2026-07-18
Applies to: Pulse Historian · edge/on-prem · managed cloud
Goal: read (and, from Python, write) tag data using the Pulse Historian SDKs instead of hand-rolling REST calls — with the fast binary formats decoded for you.
Prerequisites:
requests, pandas, and numpy available. JavaScript: Node 18+ (native fetch) or a browser.Which SDK for what: the Python SDK reads and writes. The JavaScript SDK is read/query-only (write methods were removed) — for writes from JS, use the REST API directly. All examples use the canonical dataset
acme-power / plant-1 / boiler-2.
Install the SDK wheel (from SDK/python/), then authenticate with the login classmethod — it POSTs to /exactapi/login and hands back a ready client:
from clarity_sdk import ClarityClient
client = ClarityClient.login(
"https://plant-server:3030",
"you@acme-power.com", "•••",
) # TLS verification is disabled by this convenience constructor
query_dataframe calls the fast binary endpoint and decodes into a wide pandas frame (one float64 column per tag):
df = client.query_dataframe(
["steam_pressure", "steam_temp"],
start=1720008000000, end=1720011600000,
)
print(df.head())
steam_pressure steam_temp
2024-07-03 12:00:00 78.4 512.0
2024-07-03 12:01:00 78.1 511.6
For raw points instead of a frame, use query_binary(...) → {tag: [(timestamp_ms, value), …]}. To aggregate server-side, pass a pipeline (see Aggregation API).
client.write(
organization="acme-power", site="plant-1", unit="boiler-2", grid="default_grid",
timestamps=[1720008060000],
tag_values={"steam_pressure": 78.1, "steam_temp": 511.6},
)
Full method list, decoders, and mapped_tags → Python SDK reference.
const { OptimizedClarityClient } = require('clarity-sdk'); // or: import { OptimizedClarityClient }
const client = new OptimizedClarityClient('https://plant-server:3030', token, { parallel: true });
Obtain token from POST /exactapi/login (see terminal guide).
Use queryBinary_v2 — it is the primary read and streams large responses automatically:
const data = await client.queryBinary_v2({
organization: 'acme-power', site: 'plant-1', unit: 'boiler-2', grid: 'default_grid',
tags: ['steam_pressure', 'steam_temp'],
start: 1720008000000, end: 1720011600000,
});
// → { steam_pressure: [[1720008000000, 78.4], …], steam_temp: [[…]] }
⚠️ Do not call the older
queryBinary(...)— it is now an empty stub that returnsundefined.batchQuery/preloadstill route un-format-tagged entries to that stub, so preferqueryOptimised(or setformat: 2) in batch queries, or callqueryBinary_v2directly. Detail → JS SDK reference.
write to see your point.queryBinary_v2 returns a non-empty array per tag.format_version), so values keep full resolution.| Symptom | Cause | Fix |
|---|---|---|
| TLS / cert error | Self-signed cert on-prem | Python login disables verification; for JS, trust the CA (GET /exactapi/ca-cert) |
401 |
Expired token | Re-login; tokens last 24 h |
JS queryBinary returns undefined |
Called the removed stub | Use queryBinary_v2 |
| Empty result | No data in range, or wrong scope | Widen start/end; confirm the unit is writing |
Python ImportError on DataFrame |
pandas/numpy missing | pip install pandas numpy |