Trigger Conditions Guide

Triggers help you act on specific events in a Lumeo pipeline. This guide walks you through understanding Triggers and creating them.

Background

Lumeo Pipeline carries metadata along with each video frame. Each Node in the pipeline add's it's own metadata for subsequent Nodes to use.

This metadata can be utilized to trigger actions in some nodes. For instance,

These events are specified using "Trigger Conditions" which evaluate each frame's metadata to determine whether or not to trigger that specific action.

Specifying Trigger Conditions

Trigger Conditions are written in a Dot-notation format, operating on top level properties in the metadata. They support the following operators:

  • Comparison operators on numeric and string properties : >, <, >=, <=, =, !=. ex. KEYPATH = "string" or KEYPATH > number
  • Booleans : KEY_PATH
  • Combining conditions : CONDITION and CONDITION, CONDITION or CONDITION

Consider a frame with the following example metadata:

{
  "nodes": {
    "annotate_queue1": {
      "rois": {
        "frontyard": {
          "coords": [
            [0, 0],
            [1280, 0],
            [1280, 720],
            [0, 720],
            [0, 0]
          ],
            "current_objects": {
              "7299581443955490816": {
                "first_seen": 3.8,
                "first_seen_utc": "2023-05-30T06:59:16.142772Z",
                "time_present": 0.0
              }
            },
            "current_queue_size": 1,
            "exited_objects": {},
            "max_queue_size": 1,
            "max_wait_time": 0,
            "mean_wait_time": 0,
            "min_queue_size": 0,
            "min_wait_time": 0,
            "objects_above_max_occupancy_count": 0,
            "objects_above_max_waiting_time_count": 0,
            "objects_above_max_waiting_time_delta": 0,
            "objects_entered_delta": 1,
            "objects_exited_delta": 0,
            "occupancy_above_max_threshold_delta": false,
            "occupancy_below_max_threshold_delta": false,
            "total_served": 0,
            "wait_alarms": 0
        }
      },
      "type": "annotate_queue"
    },
      "video1": {
        "extra_metadata": null,
        "source_id": "645f068b-37ce-4f1f-a062-5686beedb588",
        "source_name": "[email protected] video23-05-19_15-37-56-31_00071.mp4",
        "source_type": "file",
        "type": "video_source",
        "uri": "lumeo://0dd4533d-a64f-4a17-842b-f3ac5f6e14fe"
      }
  },
  "objects": [{
      "attributes": [],
      "class_id": 0,
      "id": 7299581443955490816,
      "label": "person",
      "probability": 0.65283203125,
      "rect": {
        "height": 82,
        "left": 461,
        "top": 394,
        "width": 37
      },
      "source_node_id": "model_inference1"
  }]
}

In the metadata example above, one could use the following condition:
nodes.annotate_queue1.rois.frontyard.current_queue_size > 0 to Trigger while there are non zero objects in a region

Trigger Types

🚧

Prefer "delta" Triggers instead of "non-delta" triggers

Most use cases work great with "Delta" Triggers.

If you find yourself using a "Non-Delta Trigger" condition, please check to ensure that the result doesn't lead to runaway actions (like snapshots or webhooks).

Trigger TypeExampleDescription
Delta Triggersnodes.annotate_queue2.rois.[roi_label].objects_entered_delta

This example represents number of new objects that entered the ROI specified by [roi_label] since the last frame.
These triggers end in _delta and represent a change in value between the previous frame and the current frame, and should be the ones used for a majority of use cases.

Think of these triggers as a "when" condition.

If you want to capture a snapshot or send a webhook whenever a new object enters the ROI, this is the trigger to use. In the next frame, it will be reset to 0 if no new objects have entered the ROI.
Non-Delta Triggersnodes.annotate_queue2.rois.[roi_label].current_queue_size

This will always be non zero while there is atleast one object in the ROI.
These triggers typically represent the current state, and end in _count, _size, _time, etc.

Think of these triggers as a "while" condition.

These are usually not a good fit for "when" type triggers since their value will continue to be set to non-zero as long as the current state meets that condition.

If you were to use this as a snapshot trigger or a webhook trigger, you would save a snapshot or trigger a webhook for every frame as long as there was an object in the ROI. Likely not the intended result!

Available Triggers

All Nodes that support Trigger Conditions now offer a dropdown with the set of available Trigger metadata.

Once you select the appropriate Trigger metadata, you should replace the [roi_label or [line_label placeholders with the corresponding ROI or Line label you wish the trigger to operate on.

Trigger Condition options

Trigger Condition options

Complex Triggers

If you need complex logic for the trigger, it is often easier to put that logic into a Function Node and add custom metadata to the frame :

if <complex_logic>:
    frame.meta().set_field('usermetadata', {'value': True})
else:
    frame.meta().set_field('usermetadata', {'value': False})
frame.meta().save()

.. which you can then use as a trigger in this node (ex. usermetadata.value)

Note: Custom Trigger metadata is not listed in the Trigger condition dropdowns, but you can override the suggestions and specify it nonetheless.