fleetlessfleetlessdocs
Reference/SDK/Datapoints & history

SDK · Datapoints & history

Reading a datapoint once, subscribing to it over the realtime channel, and reading recorded history as samples or aggregated buckets.

Generated from the SDK’s own source. The SDK Reference is the narrative; this page is every member, in the order the SDK declares them.

DatapointsApi

A robot’s exposed values, reachable as client.datapoints: the latest one, a live subscription to it, and — for a datapoint configured with retention — its recorded history.

get()

ts
get(robotId: string, slug: string): Promise<{ slug: string; value: unknown; timestamp_ms: number }>

Reads the datapoint’s latest value over REST, once. It carries the bridge’s own capture time, so a caller can tell a fresh value from a stale one without a subscription.

Parameter Type Required Description
robotId string yes
slug string yes

Returns Promise<{ slug: string; value: unknown; timestamp_ms: number }>.

subscribe()

ts
subscribe(robotId: string, slug: string, handlers: DatapointSubscriptionHandlers): DatapointSubscription

Subscribes over the realtime channel. Reconnect and re-authentication are handled by the shared RealtimeChannel; this resends its subscribe frame after every (re)connect, so a network drop is invisible to the caller beyond a gap in events.

Reference-counted per (robotId, slug): two subscriptions to the same pair share one wire subscription. Unsubscribing one never affects the other — the unsubscribe frame is sent only when the last subscriber on that pair goes away. In practice: two widgets showing the same battery value, or a component mounted twice under React StrictMode, subscribe to the same key. That count is shared with actions.subscribe and services.call — a slug is one namespace across kinds, and so is its subscription.

Parameter Type Required Description
robotId string yes
slug string yes
handlers DatapointSubscriptionHandlers yes

Returns DatapointSubscription.

References: DatapointSubscriptionHandlers, DatapointSubscription

history()

ts
history(robotId: string, slug: string, options: HistoryOptions & { aggregate: HistoryAggregation }): Promise<{ slug: string; kind: "buckets"; window_ms: number; agg: "max" | "min" | "avg"; buckets: ({ bucket_start_ms: number; value: number | null; sample_count: number })[] }>

Reads recorded history for a retention: true datapoint over REST — no realtime channel involved, the same way cameras.snapshot isn’t. This overload is the aggregated one: aggregate is given, so it resolves with HistoryBucketsResponse (kind: 'buckets') — one row per window, reduced by aggregate.agg. Leave aggregate out and the other overload gives you raw samples instead.

Two overloads rather than one union, so a caller who already knows which one they asked for isn’t forced to narrow it. kind carries the same information either way, so dynamic code can still branch on it.

Rejects, does not silently empty out, two specific refusals — unlike cameras.snapshot’s absorption of no_snapshot_yet into a null read, these two must reach the caller as a rejected FleetlessError:

  • not_recorded — the slug exists and is granted, but is configured live-only. An empty result here would look exactly like “recorded, but nothing in this window”, and the two need opposite fixes: turn recording on, versus look at a different range.
  • not_aggregatable — aggregate was given for a value that isn’t a number and no numeric aggregate.field was named.
Parameter Type Required Description
robotId string yes
slug string yes
options HistoryOptions & { aggregate: HistoryAggregation } yes

Returns Promise<{ slug: string; kind: "buckets"; window_ms: number; agg: "max" | "min" | "avg"; buckets: ({ bucket_start_ms: number; value: number | null; sample_count: number })[] }>.

References: HistoryOptions, HistoryAggregation

ts
history(robotId: string, slug: string, options: HistoryOptions & { aggregate?: undefined }): Promise<{ slug: string; kind: "samples"; samples: ({ timestamp_ms: number; value: unknown })[]; truncated: boolean; truncated_by: "bytes" | "limit" | null }>

The same read without aggregate: resolves with HistorySamplesResponse (kind: 'samples'), every recorded sample in the window as a timestamp_ms and a value. timestamp_ms is the bridge’s own capture time, the same instant the live value carried, so a recorded point and a live one sit on one axis without apology.

Read truncated. The platform caps how much one read returns, by row count or by bytes, and truncated_by says which. A short array that does not admit it is indistinguishable from a quiet period, and the two lead to opposite conclusions. Refuses not_recorded the same way the aggregated overload does.

Parameter Type Required Description
robotId string yes
slug string yes
options HistoryOptions & { aggregate?: undefined } yes

Returns Promise<{ slug: string; kind: "samples"; samples: ({ timestamp_ms: number; value: unknown })[]; truncated: boolean; truncated_by: "bytes" | "limit" | null }>.

References: HistoryOptions

DatapointSubscription

A live datapoint subscription, returned by datapoints.subscribe.

unsubscribe()

ts
unsubscribe(): void

Stops this subscription. The unsubscribe frame reaches the server only when this was the last holder of the robot/slug pair and the channel is connected — subscriptions are reference-counted across kinds, so releasing this one while a datapoints.subscribe, actions.subscribe or in-flight services.call still holds the same pair leaves that one’s stream running. Safe to call more than once.

Returns void.

DatapointSubscriptionHandlers

The callbacks datapoints.subscribe reports through: one for values, one for a refusal. onEvent fires immediately with the current value and again on every change.

onEvent()

ts
onEvent(event: { type: "datapoint"; robot_id: string; slug: string; value: unknown; timestamp_ms: number }): void

Called with the current value on subscribe, then again on every change.

Parameter Type Required Description
event { type: "datapoint"; robot_id: string; slug: string; value: unknown; timestamp_ms: number } yes

Returns void.

onError()

ts
onError?(error: FleetlessError): void

Optional — a caller need not implement it.

Called once if the subscription is refused, e.g. forbidden or unknown_datapoint.

Parameter Type Required Description
error FleetlessError yes

Returns void.

References: FleetlessError

HistoryOptions

The window datapoints.history reads. aggregate decides whether the response is raw samples or aggregated buckets.

Property Type Required Description
from string yes now-30s / now-5m / now-1h, or absolute unix milliseconds — as a string either way, exactly as the wire query expects it. The SDK does not accept a Date or a number and stringify it for you: that would be a convenience that quietly decides which of the two forms you meant, and the next person reading the wire traffic would not know which of us made that call.
to string no Same two forms as from. Defaults to now.
limit number no The most rows to return. The platform applies its own ceiling regardless.
aggregate HistoryAggregation no Present: the result is aggregated buckets. Absent: raw samples.

References: HistoryAggregation

HistoryAggregation

Window aggregation for datapoints.history. window and agg always travel together on the wire — the cloud refuses one without the other rather than defaulting either, since a silently chosen aggregation is a chart that lies quietly — so they live in one object instead of two optional fields a caller could set only one of. Same reasoning as cameraSource’s discriminated union: make the impossible combination unrepresentable, not merely rejected.

Property Type Required Description
window string yes Bucket width, e.g. 10s, 1m.
agg "max" | "min" | "avg" yes How to reduce each bucket’s samples to one number.
field string no A numeric field inside an object value, e.g. pose.x. Only meaningful when the datapoint’s own value is not itself a number.

DatapointValue

The datapoint-value wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.

DatapointEvent

The datapoint-event wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.

HistorySamplesResponse

The history-samples-response wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.

HistoryBucketsResponse

The history-buckets-response wire schema, re-exported so app code and the SDK agree on the shape — see API Schemas for its fields.