Using widgets and REST sinks for traffic data retrieval

Learn how your applications can use the REST API to query for traffic data.

Widgets and REST sinks were introduced in the [general article][intro] as programming elements that allow your application to query the server for traffic data using its REST API. In this article, the concept is explored further.

As trajectories pass through operators, they change the operators’ internal values like statistical information about speeds and accelerations. These internal values are called attributes. Currently, all operators have the same kinds of attributes, but in the future, some new attributes will be relevant only for some types of operators. You'll find information about different attributes and their associated sink types in the dedicated articles about [widget types][wtypes] and [sink types][stypes].

The typical procedure for your application would be to request an array of all defined widgets or sinks and then periodically request data from outputs that are currently of interest to it. The following sections illustrate these steps using HTTP and JSON requests.

Working with widgets over the REST API is the same as with REST sinks. They just have different endpoints and widgets can be visualized on the FLOW Insights' dashboard. They share an ID pool, so it's impossible for a sink and a widget to have the same ID within the same analytic.

Getting a list of all widgets

Method: GET
URI:/cubes/{cube_id}/analytics/{analytic_id}/widgets Query string parameters:

  • timestamp_format—can only be empty or have the "iso8601" string value. If it's not set, all timestamps in the response body will be in the milliseconds since epoch format. If the "iso8601" value is set, all timestamps will be in the ISO 8601 format, specifically in the format yyyy-MM-ddTHH:mm:ss.zzzZ, where
    • yyyy is the year as a four-digit number
    • MM is the month as a number with a leading zero (01 to 12)
    • dd is the day of the month as a number with a leading zero (01 to 31)
    • T is a literal separator for the time part of the DateTime string
    • HH is the hour with a leading zero (00 to 23)
    • mm is the minute with a leading zero (00 to 59)
    • ss is the whole second, with a leading zero (00 to 59)
    • zzz is the fractional part of the second, to millisecond precision, including trailing zeroes where applicable (000 to 999)
    • Z is a literal character denoting the UTC timezone

Keep in mind that using the ISO 8601 format is computationally demanding for the FLOW block and may delay the response by a few milliseconds depending on the number of required timestamp conversions.

Example response body:

{
  "sequence_number": "36",
  "timestamp": "1745926459560",
  "widgets": [
    {
      "id": 0,
      "name": "No. of Speeding Vehicles",
      "output_value_type": "value",
      "operator_attribute": "object_count",
      "history": {
        "enabled": true,
        "policy": "fixed_interval",
        "interval": "1000"
      },
      "history_capacity": 100000,
      "history_start_timestamp": "0",
      "history_end_timestamp": "1745926459600",
      "history_records_count": 17614,
      "current_configuration_history_start_timestamp": "0",
      "current_configuration_history_end_timestamp": "1745926459600",
      "current_configuration_history_records_count": 17614,
      "tags": []
    },
    {
      "id": 1,
      "name": "Speed Statistical Widget - North Gate",
      "output_value_type": "statistical_value",
      "operator_attribute": "speed",
      "history": {
        "enabled": true,
        "policy": "on_value_change"
      },
      "history_capacity": 100000,
      "history_end_timestamp": "1745926376840",
      "history_records_count": 14,
      "history_start_timestamp": "1745921708760",
      "current_configuration_history_start_timestamp": "1745921708760",
      "current_configuration_history_end_timestamp": "1745926376840",
      "current_configuration_history_records_count": 14,
      "tags": []
    },
    {
      "id": 2,
      "name": "custom_heatmap",
      "output_value_type": "heatmap",
      "operator_attribute": "speed_map",
      "history": {
        "enabled": false
      },
      "tags": []
    }
  ]
}

Comments:

  • sequence_number refers to the current analytic. You can look at it as the analytic’s version—editing the analytic increments the number. Your application needs to send this number in all output requests. Obtaining the current sequence number is explained in the [article about the basics of FLOW's REST API][basic_comm]. Note that the sequence number will always be a string.
  • timestamp is the timestamp of the frame from which the data in the response have been evaluated. The frame (and its timestamp) is provided by the FLOW NODE. If e.g. the output's analytic would be disabled, this timestamp won't be updated.
  • The cubes and analytics part of the URI is explained in the [article about the basics of FLOW's REST API][basic_comm].
  • For details about individual widget types and their properties in this output, see their dedicated sections.
  • history describes whether history is being saved by the output and if yes, what policy is being used. History policies are described in a [later article][hist]. Possible values are on_value_change, on_time_change, and fixed_interval. If the policy is set to fixed_interval, then interval contains the interval length in milliseconds.
  • history_start_timestamp refers to the origin time of the oldest snapshot of this output stored in the BLOCK. A zero or an empty string means that history is being recorded since the start of the analytic when its time wasn't yet properly initialized. See the Getting the history of widget values section for more details.
  • Likewise, history_end_timestamp refers to the time of the most recent snapshot. history_records_count is the number of saved snapshots. Properties with the current_configuration_ prefix refer to the part of snapshot history that was created after the most recent analytic configuration change (sequence number change).
  • operator_attribute is the attribute of the operator to which the widget is attached. This attribute is read and sent by the widget. Attributes are further explained in the next guide .
  • tags is a list conatining all tags assigned to the widget. Currently, only one tag can be assigned to each widget. For information about tags and their usage, see their dedicated article .

Getting outputs of selected widgets

Method: POST
URI:/cubes/{cube_id}/analytics/{analytic_id}/widgets/data Query string parameters:

Example request body:

{
  "sequence_number": "36",
  "widgets": [
    {
      "id": 0
    },
    {
      "id": 1,
    }
  ]
}

Example response body:

{
  "sequence_number": "36",
  "settings_sequence_number": "0",
  "timestamp": "1619088804432",
  "widgets": [
    {
      "id": 0,
      "name": "Speed - Value",
      "output_type": "widget",
      "output_value_type": "value",
      "operator_attribute": "object_count",
      "output_value_sub_type": "unknown",
      "data_end_timestamp": "1619088804432",
      "data_start_timestamp": "1619088624709",
      "analytic_id": 0,
      "cube_id": 0,
      "tags_ids": [],
      "data": {
        "data_validity": "ok",
        "evaluation_validity":"ok",
        "object_count": 32,
        "value": 2
      }
    },    
    {
      "id": 1,
      "name": "Speed - Statistical value",
      "output_type": "widget",
      "output_value_type": "statistical_value",
      "operator_attribute": "speed",
      "output_value_sub_type": "unknown",
      "data_end_timestamp": "1619088804432",
      "data_start_timestamp": "1619088624709",
      "analytic_id": 0,
      "cube_id": 0,
      "tags_ids": [],
      "data": {
        "average": 11.363175912117441,
        "data_validity": "ok",
        "evaluation_validity":"ok",
        "maximum": 20.562898635864258,
        "median": 11.363175912117441,
        "minimum": 8.132431983947754,
        "object_count": 32,
        "size": 1
      }
    }
  ] 
}

Comments:

  • The server compares the received sequence_number to the analytic's current sequence number. If it's equal, it sends a standard response. If not, it returns an [Error object][error_ref] with the outdated_sequence_number reason. In that case, your application should request a new list of widgets and save the current sequence number. You must provide the sequence number as a string.
  • settings_sequence_number denotes information unimportant for the data retrieval and can be ignored.
  • For identifying widgets and sinks, only their ID is relevant. The user-defined name is intended mainly for easier response parsing. The ID is persistent as long as the output exists. However, the ID of a deleted output can be reused for a new one. It's recommended to reestablish mapping between the name of the output and its ID when the sequence number changes.
  • This example illustrates a situation where only outputs of widgets 0 and 1 are needed. You may ignore widgets where the output is not needed at the moment.
  • It might take a long time for the block to respond to a heavy data widget (e.g. the trajectory view widget) data request. Due to this, all heavy data widget data requests must be sent separately—without requests for any other widget data in the same message. See the [Overview of widget types][wtypes] for a list of light data and heavy data widgets.
  • If the widgets array in the request is empty or missing, the block sends outputs of all light data widgets.
  • The output's attributes data_start_timestamp and data_end_timestamp denote the time interval from which the output data originates. More specifically, they denote the time interval in which the trajectories from which the output has been calculated have been closed. Trajectory closure is explained in our article [Working with time in FLOW][time].
  • operator_attribute denotes which information the widget pulls and outputs from the operator to which it's attached. Attributes are explained in detail in the [next article][wtypes].
  • data_validity is an enumeration string referring to the rate at which available trajectories' time of existence intersects with the snapshot's [time interval or time block][hist]. Possible values are:
    • ok—the data fully intersects with the snapshot's time interval.
    • cropped—the data partially intersects with the snapshot's time interval. The data_start_timestamp and/or data_end_timestamp have been modified to match the trajectories' actual time of existence.
    • invalid—there is no intersection of the trajectories' time of existence with the snapshot's time interval.
  • evaluation_validity is an enumeration string describing whether there's a problem with an expression associated with a widget.
    • ok—there is no problem with expression evaluation. This should always be the case with sinks.
    • invalid—there's a syntactic or semantic problem (e.g. circular dependency on other expression widget) with the expression definition.
  • cube_id and analytic_id show the cube and analytic to which the widget belongs.

Getting the history of widget values

For certain types of outputs, the FLOW block saves snapshots of their output. For more details, refer to the article on [output history][hist]. Each output type has a different limit of snapshots. If the limit is exceeded, the oldest snapshot is replaced with the most recent one. You can find out the timestamp of the oldest snapshot from the history_start_timestamp property while getting the list of all widgets or sinks, or from the request below.

See [Overview of widget types][wtypes] for a list of widget types that support snapshots.

Method: POST
URI:/cubes/{cube_id}/analytics/{analytic_id}/widgets/history Query string parameters:

  • timestamp_format—see Getting a list of all widgets for details. The request body is also expected to contain the timestamps in the format set by this parameter.

Example request body:

{  
    "sequence_number": "36",  
    "widgets": [    
        {      
            "id": 0,
            "start_timestamp": "1619106105644",
            "end_timestamp": "1619106108644"        
        }
    ]
}

Example response body:

{
  "sequence_number": "36",
  "settings_sequence_number": "0",
  "timestamp": "1619106834779",
  "widgets": [
    {
      "id": 0,
      "name": "Speed - Value",
      "output_type": "widget",
      "output_value_type": "value",
      "operator_attribute": "object_count",
      "history": {
        "enabled": true,
        "interval": "1000",
        "policy": "fixed_interval"
      },
      "history_capacity": 10000,
      "history_records_count": 656,
      "history_start_timestamp": "1619106105644",
      "history_end_timestamp": "1619106834779",
      "current_configuration_history_records_count": 1429,
      "current_configuration_history_start_timestamp": "1619106804791",
      "current_configuration_history_end_timestamp": "1619106834779",
      "snapshots": [
        {
          "data": {
            "data_validity": "ok",
            "evaluation_validity":"ok",
            "object_count": 3,
            "value": 3
          },
          "data_end_timestamp": "1619106633167",
          "data_start_timestamp": "1619106103875",
          "timestamp": "1619106633167"
        },
        {
          "data": {
            "data_validity": "ok",
            "evaluation_validity":"ok",
            "object_count": 3,
            "value": 3
          },
          "data_end_timestamp": "1619106634168",
          "data_start_timestamp": "1619106103875",
          "timestamp": "1619106634168"
        },
        {
          "data": {
            "data_validity": "ok",
            "evaluation_validity":"ok",
            "object_count": 4,
            "value": 4
          },
          "data_end_timestamp": "1619106635169",
          "data_start_timestamp": "1619106103875",
          "timestamp": "1619106635169"
        }
      ]
    }
  ]
}

Comments:

  • You can query for multiple widget histories in the same request. The widget property is an array.
  • The request's start_timestamp and end_timestamp denote the time interval with which the response snapshots' data_start_timestamp and data_end_timestamp must have an overlap.
  • The timestamp property inside the elements of the snapshots array mostly contains the same value as the element's data_end_timestamp. If, however, the output's Time mode is set to Time Blocks, then the timestamp property contains the same value as the element's data_start_timestamp.
  • data_start_timestamp, data_end_timestamp attributes are explained in the section Getting outputs of selected widgets.
  • settings_sequence_number is an artifact and can be ignored.

Getting a list of all sinks

Method: GET
URI:/cubes/{cube_id}/analytics/{analytic_id}/sinks Query string parameters:

Example response body:

{
  "sequence_number": "16",
  "timestamp": "1745838906960",
  "sinks": [
        {
            "history": {
                "enabled": false
            },
            "id": 6,
            "name": "MOVEMENT 3 - Raw trajectories",
            "output_value_type": "raw_trajectories",
            "operator_attribute": "raw_trajectories",
            "tags": []
        },
        {
            "history": {
                "enabled": false
            },
            "id": 7,
            "name": "My survey file sink",
            "output_value_type": "file",
            "operator_attribute": "trajectories",
            "tags": []
        }
    ]
}

Comments:

  • Properties and their semantics are identical to widgets. Refer to Getting a list of all widgets for details.
  • See [here][stypes] for details about sink types.

Getting outputs of selected sinks

Method: POST
URI:/cubes/{cube_id}/analytics/{analytic_id}/sinks/data Query string parameters:

Example request body:

{
  "sequence_number": "16",
  "sinks": [
    {
      "id": 6
    },
    {
      "id": 7,
    }
  ]
}

Example response body:

{
    "sequence_number": "16",
    "settings_sequence_number": "10",
    "timestamp": "1745838190840",
    "sinks": [
        {
            "id": 6,
            "name": "MOVEMENT 3 - Raw trajectories",
            "output_type": "sink",
            "output_value_type": "raw_trajectories",
            "operator_attribute": "raw_trajectories",
            "data_end_timestamp": "1745838190880",
            "data_start_timestamp": "1745837296600",
            "analytic_id": 0,
            "cube_id": 0,
            "tags": [],
            "data": {
                "data_validity": "ok",
                "evaluation_validity": "ok",
                "object_count": 105,
                "trajectories": [
                    {
                        "category": "pedestrian",
                        "color": "undefined",
                        "duration": 80000,
                        "id": "0",
                        "last_detection_score": 0.4995228350162506,
                        "license_plate": "",
                        "section_speed": 1.420454502105713,
                        "timestamp": "1745837296600",
                        "trajectory_score": 0.7575777173042297
                        "state_data": {
                            "bounding_boxes": [
                                [
                                    0.9022210836410522,
                                    0.5912331342697144,
                                    0.9429348111152649,
                                    0.7736831903457642
                                ],
                                // ...
                            ],
                            "map_accelerations": [
                                0.19777706265449524,
                                -0.3259845972061157,
                                -0.6550215482711792,
                                // ...
                            ],
                            "map_positions": [
                                [
                                    616145.0725747823,
                                    5453500.069705306
                                ],
                                [
                                    616144.9350229837,
                                    5453499.78742568
                                ],
                                // ...
                            ],
                            "map_speed_angles": [
                                null,
                                5.077451229095459,
                                5.068471431732178,
                                // ...
                            ],
                            "map_speeds": [
                                0.13268446922302246,
                                0.2719743251800537,
                                0.3231255114078522,
                                // ...
                            ],
                            "sensor_positions": [
                                [
                                    0.922885537147522,
                                    0.7752178311347961
                                ],
                                [
                                    0.9211771488189697,
                                    0.7809019088745117
                                ],
                                // ...
                            ],
                            "timestamps": [
                                0,
                                5320,
                                5600,
                                5880,
                                // ...
                            ],
                            "wgs84_positions": [
                                [
                                    16.59509984737455,
                                    49.223265604686055
                                ],
                                [
                                    16.595097877332947,
                                    49.22326309257227
                                ],
                                // ...
                            ]
                        }
                    },
                    // ...
                ]
            }
        },
        // ...
    ]
}

Comments:

  • // ... here is used as an ellipsis for shortening long data outputs.
  • Properties and their semantics are identical to widgets. Refer to Getting outputs of selected widgets for details.

Need more help or have some questions?[Contact us!][contact]


What’s Next

See each sink type in detail, or read about UDP sinks for a subscription-based variant of sinks.