Tasks and Templates


Template Designer

Rules are created using a visual programming environment with drag­ and ­drop functionality, see the screenshot below. Once rules have been created, they are saved as JSON files. The visual programming environment allows the developer to make use of the library of sensors and actuators, logical gates as well as mathematical function blocks. It also has a extensive debugging features.



In the Waylay terminology, tasks are instantiated rules. There are two ways tasks can be instantiated:

  • one-off tasks, where sensors, actuators, logic and task settings are configured at the time the task is instantiated
  • tasks instantiated from templates, where task creation is based on the template (which describes sensors, actuators and logic) and the task settings

Task also defines a “master clock” of the rule, like polling frequency, cron expressions etc. (these settings can be inherit by sensors as well). Before any sensor or actuator is invoked, the engine makes a copy of the task context, providing, if required, results and data from all sensors executed (till that moment in time) to the calling sensor or actuator.

Any time sensors are executed their results (in the form of both sensor’s data and sensor’s state) are inferred by the rule engine, which may result in execution of actuators or other sensors.


Let’s look a little bit closer to the picture above. With blue arrows we label the information flow, with red arrows the control flow and with green arrows we label decisions. Two sensors are shown on the left side of the picture and on the right we find two actuators. Every sensor is composed of three parts:

  • Node settings that define the control flow (when the function is executed):
  • Sensor settings - input arguments for the function
  • 𝛌 function code itself, which returns back states and data

In the picture below we see sensor settings and 𝛌 function code: task

Control flow

Sensor, a 𝛌 function, can be invoked:

  • Via polling frequency, cron expression or one time (defined either on the node level, or via the inheritance, using the “master clock” of the task settings).
  • On new data arriving. If the node can be addressed via resource, e.g. if the node is a labeled as a testresource any time data arrives for that resource function will be called. Payload, which triggered the sensor is available to the calling function (blue arrow).
  • As the result of other function calls (sensors), via state transitions of the attached sensor (depicted as the red arrow that goes from the top sensor to the other one)
  • As the outcome of multiple function executions via inference (via logical gates)

And of course, with all different conditions combined if needed!

Node settings are defined the moment the rule is configured: task

In this example, we decided to invoke the sensor only when data arrives for testresource and we have also configured eviction time of 10 seconds. This way we decide for how long each sensor information is valid. That is also an elegant way of merging different event streams where information is valid only for a short period of time, which is a very important aspect to take into consideration when making decisions as is explained here.

Information flow

Sensors can use as the input arguments:

  • Input settings (e.g. city, database record etc.)
  • Task context (result of any other sensor)
  • Runtime data (which triggered sensor execution)


Decisions are modelled via attaching one or multiple actuators to sensor state (or state transitions), or combination of multiple nodes/states. More about rules you can find on this link

Template representation in simplified JSON

Waylay templates can be represented in two different formats: Bayesian Network JSON and simplified JSON format, the one we will further describe here. Here is one simple example of the rule that takes as the input two input streams and sends a SMS if both values are above the threshold:


As you can see from the JSON below, the rule can be split in 4 different entities:

  • sensors
  • actuators
  • relations (how sensory inputs should be combined, via AND, OR or GENERAL combination of states)
  • triggers (conditions that trigger actuations)

This rule can be either saved as a template, or instantiated directly.

  "sensors": [
      "label": "streamingDataSensor_1",
      "name": "streamingDataSensor",
      "version": "1.1.3",
      "dataTrigger": true,
      "tickTrigger": false,
      "position": [
      "properties": {
        "parameter": "temperature",
        "threshold": "21"
      "label": "streamingDataSensor_2",
      "name": "streamingDataSensor",
      "version": "1.1.3",
      "dataTrigger": true,
      "tickTrigger": false,
      "position": [
      "properties": {
        "parameter": "humidity",
        "threshold": "80"
  "actuators": [
      "label": "TwilioSMS_1",
      "name": "TwilioSMS",
      "version": "1.1.1",
      "position": [
      "properties": {
        "message": "Hello",
        "to": "+111111"
  "relations": [
      "label": "ANDGate",
      "type": "AND",
      "position": [
      "parentLabels": [
      "combinations": [
  "triggers": [
      "destinationLabel": "TwilioSMS_1",
      "sourceLabel": "ANDGate",
      "invocationPolicy": 0,
      "statesTrigger": [
  "name": ""

Template configuration settings

Actuator configuration panel

Each time one of the sensors in a task is invoked and outputs new data and/or state, it is evaluated whether any of the actuators should trigger. Note that the system behaves asynchronously, so data output is not synchronised between different sensors. For example, if you have 5 sensors that pull info from the Internet and there is a small delay between the arrival of data for each of these, logic will evaluate 5 times. This feature is great for scalability as it avoids that the complete system gets locked when for example one of the sensors is not responsive or suffers from large latencies. However, when the logic evaluates multiple times, it could also lead to actuators being triggered multiple times. In case this is not desired, there are ways around that as explained below.

When you have multiple independent graphs in one task, the output of data and/or state in one graph will not trigger any actuator in another graph in the same task.

State trigger

Whenever the logic of the task gets evaluated it is checked whether the sensor, function or gate to which the actuator is attached is in one of the selected states. If it is, the actuator gets triggered, independent of previous states of the sensor, function or gate. This is applicable to all actuators in a task, independent of which sensor has output new data and/or state.

State change trigger

Whenever the logic of a task is evaluated, it is checked whether the sensor to which the actuator is attached has gone through a state change, e.g. from state A to state B.

There is a special symbol *:

  • For a state change : * -> A, the actuator will trigger if the state changes from any state different from A to A (so it will not trigger if the previous state was A). The actuator will also trigger if the previous state was not 100% known , e.g. before the first sensor observation or because the eviction time of the sensor was exceeded (see below for more details on eviction time).
  • For a state change : A-> *, the actuator will trigger if the state changes from state A to any other state (so it will not trigger if the new state is A).

Combining state trigger and state change trigger

State trigger and state change trigger can be combined. In that case, the logic will be evaluated and the actuator will trigger once (and only once) if any condition is met.

Trigger policy

The trigger policy allows you to control the frequency of execution of the actuators.

  • Every time : the actuator will trigger whenever a condition is met for it to be triggered, as explained above.
  • Only once : the actuator will trigger only once and never after, independent of whether conditions are met or not.
  • Frequency : the actuator will trigger at most once within the specified time window.

Sensor configuration panel

Sensor configuration panel is very similar to the actuation panel. If you need conditional sensor execution, you can decide to do it:

  • Always (every time previous sensor succeeds) by leaving all options empty or
  • trigger the execution on a particular sensor state or
  • use the state trigger feature.
  • one more way you can achieve this (if you use periodic or cron task) is via sequence number attached to the sensors.

State change trigger

Assume a sensor_y that should be triggered upon a state change of sensor_x. This can be done by connecting sensor_x to sensor_y and specifying the desired state change in the right panel for sensor_y, e.g. state change from state A to state B.

There is a special symbol * :

  • For a state change : * -> A, the sensor_y will execute if the sensor_x state changes from any state different from A to A (so it will not execute if the previous state was A). The sensor_y will also execute if the previous state of sensor_x was not 10% known, e.g. because the eviction time of the sensor_x was exceeded.
  • For a state change : A-> *, the sensor_y will execute if the sensor_x state changes from state A to any other state (so it will not execute if the new state is A).

Sensor advanced settings panel


The resource is a unique identifier of a ‘thing’. When a ‘thing’ pushes streaming data to the Waylay platform, it provides its unique identifier, i.e. a resource name. Each resource can push multiple parameters to the Waylay broker. The Waylay framework will automatically distribute the resource parameters to the tasks and nodes with the corresponding resource name. E.g. with the ‘execute on data’ option described below, the sensors with the corresponding resource name will automatically get invoked when new streamed data with the same resource name becomes available. Before any sensor execution, payload streaming data will be provided to the calling node. That way, sensor (𝛌 function code) will at the moment of invocation have access to the streaming data. The resource name can be specified at the task level and at the node level. In case you have many sensors in your task that share the same resource name, you may want to specify it at the task level and inherit it at the node level via the $ symbol.

  • Execute on data: The sensor will be invoked if new data is available. That data needs to be linked to a resource that is also attached to the sensor. For example, if data from resource ‘machine1’ is streamed to Waylay, and the sensor has as resourcename ‘machine1’, the sensor will be invoked as soon as new streaming data gets available. This feature allows the framework to react in real-time on real-time streaming data.

  • Execute on tick: The sensor or function get invoked on the task tick. This setting is disabled in case of a conditional execution of the sensor, since such sensors are meant to be executed only when a condition is met and not on the task tick.

  • Eviction time: The eviction time defines the time after which a sensor goes back to its priors. For example, in case a sensor has N states, by default, the system assumes that the sensor is in each of the N states with a probability 1/N after the eviction time.The eviction time is specified in seconds. If left empty, the sensor will never go back to its priors. Eviction time is a useful feature to cope with things like broken sensors, intermittent connectivity or non-responsive APIs. It allows you to specify the period of time during which you can still rely on previous state information.

  • Polling period: The polling period defines the frequency of the tick at which the sensor is invoked. When the polling period per node is defined, the sensor will not be invoked at the task tick. When left empty, the polling period defined at task level will define the tick at which the sensor is invoked. Note that the polling period is ignored for sensors that are conditionally executed based on the state of another sensor, function node or gate. The per node polling period is useful when you combine semi-static with highly dynamic sensors in one task. In such cases, it is useful to define different polling frequencies for the different sensors.

  • Sequence number: By default, all sensors and function nodes are executed in parallel at the task tick. In some cases you may want to impose a certain order, e.g. you want to collect new data first before executing the function node. This order is implied by the sequence number. Sensors and function nodes with a low sequence number are executed first. In case multiple nodes have the same sequence number, they are executed in a random order, but before nodes with a higher sequence number.

Task settings

In case that the task is deployed as “one-off”, where sensors, actuators, logic and task settings are configured at the time the task is instantiated, you can deploy the task either via waylay designer or REST calls. In the screenshot below, you can see how this can be done from UI.

As mentioned earlier, tasks can also be instantiated from templates, via REST.

In both cases, the following settings apply:

  • Task name: the name of the task, it does not need to be unique, as Waylay assigns a unique taskID to each task
  • Task resource: the resource name defined at the task level. Please see the section ‘Advanced Settings” in the Sensor section on how to inherit the task resource at the node level
  • Start task: will start the task immediately upon creation. This is the default behaviour.
  • Task type:
    • Periodic: the task tick is at a configurable periodicity.
    • Cron: allows to execute tasks according to a cron expression.
    • One-time: the task is only executed once.
    • Reactive: reactive tasks do not have a task tick. Reactive tasks are typically used for tasks that require actions based on streaming data.
  • Advanced settings:
    • Execute in parallel: execute all sensors and functions in parallel. When sequence numbers are defined, this option will be unchecked. When still selecting this option, it will override the sequence number and still execute sensors in parallel.
    • Reset observations on each invocation: will reset the states of sensors to their default values right before the next task tick. This feature is useful in scenarios where you do not need to maintain states across task ticks. When you invoke sensors, the state updates provided as output of the sensor invocations may arrive asynchronously. In order to avoid accidental actuator triggering based on old states (from the previous task tick), you may need to reset observations before each task tick.

Assigning roles to resources in a template

Sometimes you may need to model automation logic that takes inputs from multiple resources at the same time. For example, a restaurant cold storage area can be equipped with multiple sensor devices that measure different environment variables: e.g. the state of the access door, the inside temperature, movement inside the area, power etc. In this case, there are multiple sensor device data feeds that need to be logically combined before an action is taken, e.g. send sms, store log entry.

You can use the dollar sign in templates to use the task resource as resource on a node. However this does not work if you want to create a template that runs on multiple resources. It is possible to override the actual resources when starting a task from these templates, but this requires in depth knowledge of the template (i.e. what is the intended role/which resource is wanted for a certain node).

Instead, the template designer can create a master template and assign roles to each resource. When starting a task for this (task) template, all templated resources can be assigned at runtime.

For example, in the below picture we show a template that handles multiple sensor devices associated with a cold storage room. Without going into the specifics of the actual business logic, you can see that the rule designer has assigned a specific role to each sensor input: $MainPower, $BackupPower, $DoorSensor, $ColdStorageRoom, etc.


When you deploy this template as a task, you can now assign specific resources to their respective roles within the template’s business logic. In the picture below, you can see the dialog box to deploy the template as a task and assign individual resource ids to the previously defined roles ($MainPower, $BackupPower, $DoorSensor, etc).


Task Forking

When you select the tasks tile in the Waylay dashboard, a list of running, stopped or failed tasks is displayed. The Commands column lists the possible actions that you can take on these tasks.


The following action items are available: