26 Mar 2024

Tandem Data API - Guide to Stream Creation

Building on what you learned about data ingestion in our last article, this guide shows Node.js developers how to create streams via an API, essential for scenarios like assigning sensors to rooms or assets in your facility. We'll cover:

  1. Identify the default model - where non-graphic elements like streams reside.
  2. Find the parent element - to attach your stream to (like a specific room).
  3. (Optional) Determine the level within the facility - for more precise placement.
  4. Creating the stream - with the necessary parameters.
  5. Resetting stream secrets - to enable data flow.

This streamlined approach lets you create and manage sensor data streams in your Tandem facility (digital twin).

Let's go through each of these 5 steps:


1. Identify the Default Model

The default model is the model where streams and other non-graphic elements are stored. It is easy to identify the default model because its URN is the same as the URN of the facility – only with a different prefix, i.e.:

  • Facility URN:
  • Default model URN:

In the list of sources, you will see the default model marked as: (Tandem hosted).

Default model

Tandem creates the default model dynamically when the user creates a stream using the UI. When using the API, you may experience the case that the default model doesn’t exist yet – in this case there is an API to create default model. You can also find a code sample here.


2. Find the Parent Element

The next step is to locate the parent element. In the example above, you might like to add a stream to the room. This requires the following steps:

  • Iterate through all models in the facility.
  • Locate the room to create stream. For example, you can select a room with a specific name or classification.

Note that rooms can be in different models. When iterating through models you need to remember the URN of the model plus the key of the room itself.

for (const link of facility.links) {
  // we need to query for refs because we want to know related level
  const rooms = await client.getRooms(link.modelId, [
    ColumnFamilies.Refs ]);
  const room = rooms.find(r => r[QC.Name] === roomName);

  if (room) {
    targetRoom = room;
    targetRoomModelId = link.modelId.replace('urn:adsk.dtm:', '');

In this case we will use the room as parent (= host) element and as the room reference. The room reference is used when generating heatmaps.


3. Determine the Level within the Facility (optional)

Optionally, you can also assign the stream to a level – this is not strictly required but it can be useful in the case of spatial filtering.
This is a bit simpler because default the model already contains a copy of levels from other models – you can simply locate the corresponding level by its name:

const levelDetails = await client.getElement(targetRoomModelId, targetRoom[QC.Level]);
const levels = await client.getLevels(defaultModel.modelId);
const targetLevel = levels.find(l => l[QC.Name] === levelDetails[QC.Name]);

Note that the levels are cloned into the default model by the Tandem UI behind the scenes.


4. Creating the Stream

To create a stream, you need to provide the following parameters when calling the API:

  • URN of the default model.
  • Name of the stream.
  • Uniformat Class ID – Tandem is using D7070 which represents Electronic Monitoring and Control.
  • Category ID – Tandem is using 5031 which refers to IoT Connections category.
  • Classification ID – this is the classification which contains stream parameters. This is part of a facility template. This parameter is optional.
  • Parent reference – this refers to the host element of the stream. In your case this is the xref key of room. This parameter is optional.
  • Room reference – this refers to the room element, which defines the location of the stream. In your case the room is identical with the parent, so you provide the same value as the parent reference. This parameter is optional.
  • Level reference – this refers to the key of the level. This parameter is optional.

What is an xref key?

In the section above we mentioned the xref key. In Tandem, elements are identified using an element key. An element key is a 24-byte long identifier encoded using Base64 encoding, for example:

  • AAAAAKARYtXf1U9-r4u2nRoiO0IAEB15

Because the room can be placed in another model, it is necessary to use a special version of the key which is called an xref (external reference) key. An xref key includes both the model URN and element key – technically it is a 40-byte long identifier encoded using Base64 encoding, for example:

  • CTmdTcAoSwaP79cLYjn8xQAAAACgEWLV39VPfq-Ltp0aIjtCABAdeQ

The sample function for encoding is available here.
So, now you have all the required parameters, and you can call the API. In our example there is a wrapper function for this API:

const streamId = await client.createStream(defaultModel.modelId,
  parentXref, // because stream is assigned to room we use same key for host & room

New stream


5. Resetting Stream Secrets

Now the stream exists but you need to do one more step before you can ingest data into it. To enable this, you need to reset stream secrets – this enables the stream to receive data. There is an API for this – in our example there is wrapper function to invoke it:

await client.resetStreamsSecrets(defaultModel.modelId, [ streamId ]);

After this it is possible to ingest stream data – feel free to use the preferred approach from the previous article.

Wrap up

This article walked you through creating streams with our API, with Javascript and Python examples to get you started. Additionally, you have several alternatives for stream creation:

  • The Tandem UI allows for creating multiple streams with a single command.
  • Streams can be imported from Azure IoT Hub using Tandem UI.
  • Tandem Connect can automatically establish streams from devices.

Should you have any questions or need further help with the Tandem API, don't hesitate to reach out to us at aps.help@autodesk.com or ask your questions on StackOverflow under the 'autodesk-tandem' tag.


Related Article