The LabVIEW streaming SDK can be found here on Github.
LabVIEW Stream SDK Overview
Like many other LabVIEW patterns, the Initial State LabVIEW Streaming SDK uses the pattern of Open > Do Something > Close. The abbreviation IS is used throughout the SDK, and it simply stands for Initial State. The critical VIs in this SDK are as follows:
Open Initial State Reference (IS Open Connection.vi)
This VI takes an Initial State Access Key and creates an HTTP session. The output is a IS Session, which is a cluster that contains the Keys and the HTTP session reference. The access key is the secret key (or set of keys) that is attached to your Initial State account. This allows data to enter your account and should be kept secret. Later, we will learn about the bucket, which also has a key. The bucket is the final destination for you data, and defines how it shows up in your Initial State account. To get an existing Access Key - and/or generate another one - go to your username (top right after login) >> my account >> Streaming Access Keys
Under the hood this VI opens a new HTTP session and begins to build up the HTTP request by adding the Access Key as a header to the HTTP session.
Create/Open Bucket (IS Create Bucket.vi)
This VI creates a new bucket or appends to an existing bucket via a Bucket Key. The VI takes the IS Session Cluster, which is originated in IS Open Connection.vi. Based on the other inputs, this VI will either create or append to a bucket. Let's look at the scenarios.
- Standard Bucket Creation - Provide a Bucket Name only and get a unique Bucket Key.
- Do not wire the bucket key - a random alpha Bucket Key will be generated.
- Supply a Bucket Name - a human readable name for the bucket to organize this new bucket on the bucket shelf in Initial State.
- Advanced Bucket Creation - Provide a Bucket Name and unique Bucket Key.
- Wire the Bucket Key with your own custom Bucket Key - If you want to create a new bucket and not append to an existing be sure this Bucket Key is sufficiently unique. The use-case is to create a systematic way to create Bucket Keys. For example, use a human-readable name and a today's date concatenated together, and you will get a new bucket each day, but it will append to the bucket during the same day.
- Append to Existing Bucket - Provide an existing Bucket Key
- Wire a known Bucket Key - Assuming there is a bucket key that matches your input, the Initial State system will append new data to an existing bucket.
The output of this VI is a bucket session wire that is used to address the newly created or appending Bucket when sending data.
Data Conversion to JSON Cluster (IS PolyVI DBL/String/Bool to JSON Cluster.vi)
This VI is a PolyVI with three polymorphic instances. Each instance accepts different data types for the data to send to Initial State - aka Stream Value. The Initial State API accepts strings, numbers, and booleans, so we have created those instances for this example. Ultimately, everything is flattened to a string, so you can create your own instances to convert your data to a JSON cluster.
Note: The format of the JSON cluster is important, because it ultimately is flattened to JSON and sent to the Initial State Streaming API. Therefore, you must keep the proper labels and data types intact for it to work properly. Under the hood, the SDK uses the LabVIEW primitives for flattening to JSON.
The other inputs to this VI are Stream Key and an Option Stream Time:
- Stream Key - This is the key to which data will be appended within your bucket. It should be both human-readable and something that names the signal. This will be the string that shows as the signal name in Tiles, Lines, and Waves.
- Stream Time - You can give each data point a time stamp if you prefer. If you give the data point a timestamp, Initial State will respect that time when plotting time-series graphs. If you do not apply a timestamp, Initial State will give it a server timestamp. Typically, it is sufficient to let Initial State assign timestamps if you are dealing with seconds or more. For sub-second resolution assign time yourself.
Initial State Send Stream Event (IS Send.vi)
This VI does the final API request/response for sending the data points you have collected. It takes the IS Session and IS Bucket Session wire, which are created via open sessions and addressing buckets. The primary input for this VI is the JSON Cluster Array. This is an array built from the outputs of the data conversion VIs. Each element of the array is the special JSON cluster destined for the Flatten To JSON.vi.
There are two limitations to be aware of when batching data and sending to the API - rate and bandwidth. You can learn more about these limitations here - API: Rate & Bandwidth Limitations
- Rate - the API is rate-limited at 3 calls per second, but is measured in 10 second intervals to allow bursting of up to 30 API calls in one second. The VI is equipped with a boolean output "Rate Limit Reached?" so that you can use this further batch data and retry when rate limiting is "settled." A simple version of this concept is shown in the example.
- Bandwidth - The SDK accepts an array of JSON data where each piece of data account for a number of bytes, which should be counted before the final string is sent to the API. The total payload of each API data transfer should be limited to 200KB. This limit is not enforced in the example, but should be monitored more closely in a real application that begins to encroach on the bandwidth limit.
Simple close VI for closing the IS connection. The primary job of this VI is to close the HTTP connection which releases some previously reserved memory.
Putting It All Together - LabVIEW Streaming SDK Example
The included example uses the SDK open a connection and send data to a newly generated bucket called LabVIEW Example Bucket. All you need to do to see it in action with your account is to replace the Access Key with one of your own.
Now you are ready to check out the Block Diagram. It is a standard usage of the SDK, that opens a connection, sets up a new bucket, collects some random data, and sends it through the Initial State Streaming API. It monitors the rate limit error output so that we can buffer the data and retry on the following loop iterations. It also clears the error when that specific issue happens. Get the full code saved back to LabVIEW 2013 here: LabVIEW Streaming SDK on Github
I could not help mapping some emojis to the random data. I'll bet this is the first time you have used emoji in a LabVIEW program, but maybe not, who knows...
Final Product in Initial State of the LabVIEW Example