Part I : Scaling like a rock star with subflows in Prescient Designer

Why should you use subflows and how do they work with environment variables?

Table of Contents

Introduction

Prescient Designer is the leading platform for developing scalable industrial IoT solutions. With its fast and simple deployment to hundreds of devices, unified edge and cloud application view, and seamless device communications, it has never been easier or faster to develop complex IoT applications like predictive maintenance, digital twin and edge machine vision.

The key concept that enables easy deployment in Prescient Designer is the ability to associate any subflow, at any level in a flow’s hierarchy, to any number of provisioned devices[1]. A subflow associated to an edge device runs in that device, and all communication between that subflow and other devices (them being other edge devices or the cloud portion of Prescient Designer) are handled automatically by Prescient Designer. For example, one subflow template may be associated to three edge devices, which means that the same subflow template is instantiated and runs in those three edge devices.

An issue arises when each edge device running a given subflow template implements functionality that is parameterized, and those parameters may change from edge device to edge device. For example, a subflow template that is running in three devices may implement a predictive maintenance algorithm for a wind turbine which uses several wind turbine configuration parameters and sensor data to estimate the time-to-failure (TTF). How can a single configurable subflow template be implemented in Prescient Designer, so that there is no need to create three slightly different subflow templates, one for each turbine? The answer lies in the use of environment and context variables. Environment variables are treated in this post, context variables will be treated in the next post in the series.

Environment Variables

Environment variables can be defined for any subflow, either in the subflow template or in each subflow instance. Defining the environment variables in the template affords a few niceties: a) the variables appear in the “Properties” tab of the “Edit subflow instance” sidebar, which makes assigning or reviewing the environment variable values faster, b) it makes the environment variable name fixed for all subflow instances, thus avoiding typos and other errors, and c) it can be used to define default values for some or all of the environment variables defined.

In Prescient Designer each subflow has a reserved environment variable[2] defined, “deviceID” [3]. This environment variable is a string that contains the name of the device the subflow is running on, or it is an empty string if the subflow is not associated with any edge device (the subflow runs in the cloud portion of Prescient Designer). Note that the deviceID environment variable is defined in the entire subflow hierarchy, so if a subflow is associated with an edge device and includes other subflows, deviceID is defined in those too.

So how can deviceID and other environment variables be used to make each subflow instance unique, without changing the subflow template? Create an environment variable that is a JSON object whose keys are the deviceIDs being used and whose values are the parameter values (i.e. the arguments) for each device. Then, in the subflow template, select the appropriate configuration using the deviceID environment variable.

For example, let’s say that the predictive maintenance algorithm takes the turbine design type (direct or geared) and air temperature as its inputs to compute the TTF, then the subflow template would take the temperature data from a temperature sensor connected to the edge device, and the design type from a configuration environment variable, and output the estimated number of hours till the next failure. Figure 1 shows the top-level flow diagram of this example, where the “PM” (for predictive maintenance) subflow template is running in 3 wind turbines, generating TTF estimates, and displaying what wind turbine type is used in the estimation.

Figure 1: wind turbine predictive maintenance top flow diagram

The PM subflow template is assigned to three devices: “nvidia-nano”, “pi3-1” and “pi4”, as shown in Figure 2.

Figure 2: edge devices associated with PM subflow template.

Figure 3 shows that the PM subflow instance that is associated with the aforementioned devices has a “cfg” environment variable defined as a JSON object with the value {"nvidia-nano":"unknown", "pi3-2":"direct", "pi4":"geared"}. Note that the keys of this JSON object (nvidia-nano, pi3-2 and pi4) match the deviceIDs of the edge devices associated with the subflow instance.

Figure 3: environment variable defined for wind turbine predictive maintenance subflow instance associated with three edge devices: nvidia-nano, pi3-2 and pi4.


Figure 4 shows the subflow template. Temperature data is generated by a sensor (in this mock example it is an “inject” node), the design type is obtained from an environment variable, and those two pieces of information are fed to the predictive maintenance algorithm. The subflow output 1 sends the wind turbine type to the cloud portion of Prescient Designer, while the subflow output 2 sends the TTF estimate. Note that the communication between edge devices and the cloud is handled transparently by Prescient Designer, no need to add communication blocks.

Figure 4: wind turbine predictive maintenance algorithm subflow template.


The selection of the design type is done by a “change” node, as shown in Figure 5. A JSONata expression ($lookup function) is used to select the value associated with a key ($env(“deviceID”), the deviceID environment variable) from an object ($env(“cfg”), the configuration environment variable).

Figure 5: change node that selects the wind turbine configuration (direct, geared, or unknown).

A function node may be also be used instead of the change node to select the wind turbine type, as shown in Figure 6.

Figure 6: function node used to select wind turbine type, an alternative to the change node shown in Figure 5.

Prescient Designer automatically adds a “msg.src” property to any message coming out of an edge device, which can be used to verify that the correct wind turbine type is used in each edge device. Once the flow is deployed to the three devices, by simply clicking on the “Deploy” button in Prescient Designer, the mock temperature sensor (inject node) produces data, and the wind turbine types, “unknown” for device “nvidia-nano”, “direct” for device “pi3-2”, and “geared” for device “pi4”, are displayed in the debug sidebar, as shown in Figure 7.

Figure 7: output of the "WT type" debug node showing that each edge device is using the correct wind turbine type.


The preceding example has shown how to use environment variables to parameterize a single subflow template. This technique is simple, fast to implement, and ideal for low to medium number of devices that run a subflow with low to medium number of parameters. However, if each subflow has a large number of parameters (in the example there was only one, the wind turbine type), and/or there are a large number of edge devices associated with the subflow (hundreds or thousands), then getting all the parameters for all the devices in the environment variable value field (Figure 3), and making sure that the JSON object keys match the devices selected, can be tedious, time-consuming, and cumbersome, as it typically leads to having the configuration JSON object in a text file, database, or some other storage method, then manually retrieving it, verifying it, copying it, and pasting it in the value field. Context variables may be better suited for the scenario of subflows with large number of parameters and/or associated with a large number of devices. That, next time.

[Tutorial Video] Working with Context: Make Variables Persistent

[Tutorial Video] Working with Subflows: an Overview

References

[1] A provisioned device is an edge device that has Prescient Edge installed in it. Prescient Edge has three formats: native, which can be installed in any Debian/Ubuntu-based Linux distribution, docker container, or Canonical snap.

[2] A reserved environment variable cannot be deleted.

[3] The deviceID is chosen by the user when an edge device is provisioned.

Previous
Previous

A hybrid framework that focuses on distributed data

Next
Next

Why low-code is transforming data analytics in IIoT