Interval counters — calculate interval messages

Interval counters are used to calculate specific parameters for each interval

Once the analytics engine has split device messages into intervals based on custom logic, it's time to calculate all messages within each interval and extract valuable information. This can be done with counters

A standard interval message is represented as a JSON object with a set of fields, where "begin", "end", and "duration" (also "id" for automated analytics mode) are always present and other fields appear only when a counter with such name is defined during the call:

  "begin": 1490347944,
  "end": 1490357948,
  "duration": 4,
"mileage": 190.2,
"work_hours": 0.12345,
"max_speed": 120,
  "stops": [{"begin":1490347944, duration:25}, {"begin":1490349944, duration: 33}, ...],
  "positions": [{"t":1490347944, "lat":53.0923, "lon":27.12}, {"t":1490347944, "lat":53.0923, "lon":27.12}, ...]

Here "mileage", "work_hours", "max_speed", "stops" and "positions" fields are defined by counters. Each counter configuration contains the "name" field specifying the name under which the counter will be placed into the interval's JSON.

flespi defines the following types of counters:

  • expression — the value of a counter is the result of expression evaluation for each message in the interval. The special "method" field defines how these results will be combined into one: 
    • first — take value from the first countable message (all value types accepted)
    • last — take value from the last countable message (all value types accepted)
    • average — take an average value (expression is evaluated as number)
    • minimum — take a minimum countable value (expression is evaluated as number)
    • maximum — take a maximum countable value (expression is evaluated as number)
    • summary — add all countable values (expression is evaluated as number)
    • difference — take a sum of all differences between neighbor messages (expression is evaluated as number)
    • duration — evaluate the expression as boolean and count duration for all non-zero results
  • dataset — the value of a counter (like "positions" in the sample above) is an array of objects, which field names and values are defined by the schema. The values for the fields are also evaluated as an expression. Dataset counter is used when you need to access each message field and present them in an interval usually in a compressed form, for example, to draw a movement track on the map or display certain inputs on a state diagram. Please note that intervals for the dataset counter can grow in size quite fast so we recommend using the shortest possible field names. If you just need latitude and longitude pairs for each message in the interval, please check the route counter.
  • route — dump "position.latitude" and "position.longitude" parameters for each message within the interval into Google-encoded polyline algorithm format. This is compressed string-based coordinates format with plenty of libraries to decode it into latitude/longitude pairs.
  • datetime — print the user-formatted begin or end time into the interval according to the specified timezone
  • parameteradd parameter value from the message into the interval. "method" defines which encountered valid message to use for the parameter source — either first, last, distinct or each. When distinct method is specified, the result of the counter will be an array of distinct parameter values encountered in device messages. When each method is specified, the result of the counter will be an array of parameter values for all device messages.
  • interval — evaluate the result of the expression that references already calculated interval parameters and attach it to the interval. This is useful when you want to calculate the average value, for example, an average speed which can be represented with the expression "mileage/duration", if mileage is already calculated for this interval using some special formula.
  • active — set counter value to "true"/"false" reflecting the current state of unfinished interval. Applicable only for automatic intervals calculation or in manual mode when the "to" border in the request is unset. Will always return "false" for all intervals except for the last one. Will return "true" for the last interval if it is not yet finished. Once the interval becomes inactive based on the selector criteria, the counter will return "false". It can be used to trigger events that should run when some action finishes or changes state — e.g. leaving the geofence, finishing a trip, etc. "true" value can automatically change to "false" for timed out intervals with non-zero max_inactive interval selector configuration property.
  • geofence — save the name of the triggered geofence (if available) into the interval field. Useful only with the corresponding geofence selector.
  • specified — save info into the interval field under specified name and value. Tagging calculators with custom fields can be used to identify the exact calculator when retrieving intervals in batch or in order to configure a special intervals' event handler.
  • accumulator — accumulate the value of another numeric counter across multiple intervals. For example, you can have a mileage counter (that will record the distance traveled for the given interval) and a mileage_total accumulating counter (that will record the total distance traveled until the end of the trip). Optionally it is possible to specify a special expression that will reset the accumulated value and/or set the interval for its resetting — e.g. daily, monthly, yearly, and so on.
  • variable - calculate some value according to provided expression and make it available to use it in subsequent expressions inside this and other counters. Variable value inside expressions is accessed with variable("counter-name") call. Last calculated value can be used to validate final interval JSON as well. This is a virtual counter to store some state that can be further used in other counters. State is updated with each next message pass.
  • calculator — the value of a counter (like "stops" in the sample above) is an array of intervals detected by another calculator within begin and end times of our interval. By default, only the intervals detected within the time bounds are loaded into the counter, but it is possible to configure overlap from each side. Also, it is possible to limit fields that will be dumped into an array, like "begin" and "duration" from the sample above. "method" defines which encountered valid interval to use — either first, last, each, aggregate or aggregate_by_field. For the first or last method the counter value will be the referenced interval JSON, if any. When each method is specified, the result of the counter will be an array of referenced calculator intervals. aggregate and aggregate_by_field methods allow to sum referenced interval fields. Aggregation will be useful when you need to calculate a time spent in different geofence within a day with detailed information about how much time was spent in each geofence.
    Please note that this counter type can not be used in on-demand intervals calculation due to its limitations and is available only in the standard analytics system which intervals are accessible via this call.
  • message — copy part or full JSON representation of the message into the interval. "method" defines which encountered valid message to copy  — either first, last or each. When each method is specified, the result of the counter will be an array of messages. With fields, you may limit the copy to contain only specified fields. And extremum field allows you to find message(s) with a specific minimum or maximum value, for example detect the time and position of the largest message latency or message with the highest speed.

All counter types except datetime, interval, and calc are dealing with device messages, calculating each message according to the interval selector one by one. calc counter querying the database for intervals generated by referenced calculator, datetime and interval counters use the generated interval message and run on top of it. Note: When using interval and accumulator types, pay attention to the order of counters — pre-calculated values used in the interval expression should all go above it.

If counter value could not be calculated due to some reason null value will be stored in interval JSON instead.

Maximum size of data inside each counter can not exceed 8MB. If it will be larger during interval generation the counter value will reset to null and corresponding log message will be added to calculator logs (event_code = 614).
Maximum total JSON size for the interval message can not exceed 16MB. If it will be larger during generation - calculated device will be disabled with the reason indicated in calculator logs (event_code = 615).

Some counters also contain a "validate_message" option, which checks whether the message is suitable for the counter and skips invalid messages. This can be used for example to skip all messages with high HDOP or low quantity of locked satellites.

If you want to access per-device data in counters you may use device metadata for this. This is an efficient method to configure per-device speed limit, controlling geofence, some fuel calculation method and so on.

See also
Using advanced intervals aggregation capabilities to solve non-trivial tasks with flespi calculators.
Adding information about BLE beacons, DTC codes or visited geofences to the calculator's interval JSON?