Skip to main content

Telemetry and Timeseries

Beacon Tower collects, stores, and streams telemetry data from connected assets in real time. The platform provides both historical timeseries queries and live data streaming via SignalR.

Data Ingestion Flow

Telemetry data flows through the following pipeline:

  1. Provider Client pushes data using its respective protocol (Azure IoT Hub, file import, HTTP, etc.)
  2. Asset Processor (Orleans grain) receives the data, validates it against the asset's model definition
  3. Timeseries Storage persists validated data points to TimescaleDB

Each asset has a dedicated processor grain that handles validation and storage operations. The grain ensures incoming data conforms to the asset's model schema before persisting it.

Related: See Telemetry Ingestion for the NATS message format, required headers, and JSON payload structure. See Assets, Providers, and Bindings for details on how assets connect to data sources.

Timeseries Storage

Beacon Tower uses TimescaleDB, a PostgreSQL extension optimized for time-series workloads. Each data point is stored with the following metadata:

FieldDescription
timeTimestamp of the measurement
assetIdUnique identifier of the asset
componentIdOptional component identifier within the asset
timeseries_nameName of the telemetry signal (e.g., "temperature")
timeseries_typeType of data: "telemetry", "property", "command"
modelIdReference to the asset's model definition
messageIdUnique identifier for the ingestion message
valueThe actual measurement value

This schema enables efficient queries across time ranges, assets, and signal types.

Querying Historical Timeseries

The Beacon Tower API provides powerful endpoints for retrieving historical telemetry data with aggregation support.

Basic Timeseries Query

Use POST /timeseries/get to retrieve historical data. Note this uses POST (not GET) because it requires a JSON request body.

Request Body Schema (TimeseriesGet):

{
"assetId": "asset1",
"timeseriesName": ["temperature", "humidity"],
"searchSpanFrom": "2024-03-04T19:03:00.39+00:00",
"searchSpanTo": "2024-03-10T19:03:00+00:00",
"aggregationType": "avg",
"aggregationInterval": "PT5M"
}

Example Request:

curl -X POST https://api.beacontower.ai/timeseries/get \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"assetId": "pump-007",
"timeseriesName": ["pressure", "flow_rate"],
"searchSpanFrom": "2024-03-04T00:00:00Z",
"searchSpanTo": "2024-03-04T23:59:59Z",
"aggregationType": "avg",
"aggregationInterval": "PT15M"
}'

Aggregation Types

The aggregationType parameter supports:

  • avg — Average value over the interval
  • min — Minimum value
  • max — Maximum value
  • first — First value in the interval
  • last — Last value in the interval
  • sum — Sum of all values
  • median — Median value

Aggregation Intervals

The aggregationInterval parameter uses ISO 8601 duration format:

  • PT1M — 1 minute
  • PT5M — 5 minutes
  • PT15M — 15 minutes
  • PT1H — 1 hour
  • PT12H — 12 hours
  • P1M — 1 month
  • P1Y — 1 year

Custom intervals are also supported, such as "12 minutes".

Advanced Filtering with WHERE Clause

Use the optional whereClause parameter for SQL-like filtering on timeseries data:

curl -X POST https://api.beacontower.ai/timeseries/get \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"assetId": "pump-007",
"timeseriesName": ["pressure"],
"searchSpanFrom": "2024-03-04T00:00:00Z",
"searchSpanTo": "2024-03-04T23:59:59Z",
"whereClause": "value > 100 AND timeseries_type = '\''telemetry'\''"
}'

You can filter on: time, assetid, componentid, timeseries_name, timeseries_type, modelid, messageid, value.

Querying Latest Values

For the most recent value of each timeseries, use POST /timeseries/get/last.

Request Body Schema (TimeseriesGetLast):

{
"items": [
{
"assetId": "asset1",
"componentId": null,
"timeseries": null
},
{
"assetId": null,
"componentId": null,
"timeseries": [
{ "name": "temperature", "type": "telemetry" },
{ "name": "batterylevel", "type": "telemetry" }
]
}
]
}

Example Request:

curl -X POST https://api.beacontower.ai/timeseries/get/last \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"assetId": "pump-007",
"componentId": null,
"timeseries": [
{ "name": "pressure", "type": "telemetry" },
{ "name": "temperature", "type": "telemetry" }
]
}
]
}'

This endpoint is optimized for fetching current asset states without scanning historical data.

Real-Time Streaming with SignalR

For real-time telemetry updates, Beacon Tower provides a SignalR-based push notification system. This is more efficient than polling when you need live data updates.

1. Negotiate SignalR Connection

First, obtain a SignalR connection URL and access token:

curl -X POST https://api.beacontower.ai/push/negotiate \
-H "X-API-Key: your-api-key"

Response:

{
"url": "wss://beacon-signalr.service.signalr.net/client/?hub=push",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Use the returned url and accessToken to establish a SignalR client connection.

2. Create a Subscription

Once connected to SignalR, create a subscription to receive telemetry updates:

curl -X POST https://api.beacontower.ai/push/subscription \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"connectionId": "your-signalr-connection-id",
"topic": "telemetry",
"assets": ["pump-007", "pump-008"],
"samplingType": "none"
}'

Parameters:

  • connectionId — Your SignalR connection identifier
  • topic — Subscription topic: "telemetry" or "alarm"
  • assets — Array of asset IDs to monitor
  • samplingType"none" (send all updates) or "first" (send first update per interval)

Response:

{
"subscriptionId": "sub-12345",
"expiresAt": "2024-03-04T20:13:00Z"
}

3. Manage Subscriptions

Subscriptions have a TTL of 600 seconds (10 minutes). Renew them to keep receiving updates:

Renew Subscription:

curl -X PUT https://api.beacontower.ai/push/subscription/sub-12345 \
-H "X-API-Key: your-api-key"

Get Subscription Details:

curl -X GET https://api.beacontower.ai/push/subscription/sub-12345 \
-H "X-API-Key: your-api-key"

Delete Subscription:

curl -X DELETE https://api.beacontower.ai/push/subscription/sub-12345 \
-H "X-API-Key: your-api-key"

Subscription Topics

TopicDescription
telemetryReceive telemetry data updates from subscribed assets
alarmReceive alarm notifications from subscribed assets

Sampling Types

TypeBehavior
noneSend all telemetry updates immediately
firstSend only the first update within each sampling window

Dashboard Integration

Beacon Tower dashboards support both data access patterns:

  • Polling Mode: Periodically query POST /timeseries/get for updated data
  • Real-Time Mode: Establish SignalR connection and subscribe to live telemetry streams

Real-time mode is recommended for operational dashboards that require low-latency updates. Polling mode is suitable for historical analysis and custom aggregation windows.

Related: See Dashboards for details on creating and configuring visualizations.

Next Steps


API Endpoints Summary:

EndpointMethodPurpose
/timeseries/getPOSTQuery historical timeseries with aggregation
/timeseries/get/lastPOSTGet latest values for specified timeseries
/push/negotiatePOSTObtain SignalR connection credentials
/push/subscriptionPOSTCreate a new push notification subscription
/push/subscription/{id}GETGet subscription details
/push/subscription/{id}PUTRenew subscription TTL
/push/subscription/{id}DELETEDelete subscription