Expressions

DevicePilot has a rich expression language, based on JavaScript

Expressions are used in DevicePilot to create Filters and Calculated Properties, and also in KPIs.

Although based on JavaScript, these are limited to simple expressions - you can't write lines of code, assign variables, perform loops or any more complicated constructs: you can simply return a value.

Comparison operators

The where expression supports the following operators for inspecting properties:

  • ==, equal
  • !=, not equal
  • <, less than
  • >, greater than
  • <=, less than or equal
  • >=, greater than or equal

Further documentation can be found on the mozilla website.

Values.

Values passed into where must be JSON strings, numbers, booleans or null which is used to determine whether a property has a value or not.

  • Example numbers, 12345, -10.32
  • Example strings, "thing", "a string"
  • Example booleans, true, false

Comparing against null either checks for a properties existence by using the == operator or non-existence by using the != operator.

Arithmetic operators

The right hand side of an expression can be a calculation or alteration of a properties value. This is done by applying arithmetic operators to the right handside property. The arithmetic operators are:

  • + addition
  • - subtraction
  • * multiplication
  • / division

For example current >= capacity * 0.1 would include devices which have a current property set to less than below 10% of their capacity property.

Further documentation can be found on the mozilla website.

Logical operators

More complex expressions may be created by combining simpler expressions using the following logical operators:

  • &&, AND
  • ||, OR
  • !, NOT

For example ((temperature>=10)||(type=="fridge")) would retrieve devices with a temperature greater than or equal to 10, or of type "fridge".

Further documentation can be found on the mozilla website.

Conditional (ternary) operator

The "?" operator tests the value before it and if it's true then returns the first value after it, otherwise the second one (after the ":").  It's like an if-then-else clause which returns a value.  The syntax is:

  • condition ? ValueIfTrue : valueIfFalse

For example, this can be used to normalise data from different fields in different device types:

deviceType == "tmpSensorV1" ? temp : temperatureC

Further documentation can be found on the mozilla website.

Numeric functions

Many of the numerical functions in Javascript's Math library are available, such as round() for converting floating-point numbers to integers (this can be useful for quantising a continuous value into a countable set of discrete values, for example for use with the "Percentage of time in each value of" KPI metric).

String functions

String functions can be performed to find devices that partially match a property value to a substring. All of these operations have case sensitive function names, although they return case insensitive results (apart from regex()).

  • contains(property, substring), retrieves devices that contain the substring anywhere inside the value of the property
  • doesNotContain(property, substring), retrieves devices that do not contain the substring anywhere inside the value of the property
  • startsWith(property, substring), retrieves devices that contain the substring at the start of value of the property
  • doesNotStartWith(property, substring), retrieves devices that do not contain the substring at the start of the value of the property
  • endsWith(property, substring), retrieves devices that contain the substring at the end of the value of the property
  • doesNotEndWith(property, substring), retrieves devices that do not contain the substring at the end of the value of the property
  • regex(property, regex), retrieves devices that match the given regex pattern. Use JS style regular expressions including slashes and any flags that you want. Good documentation for these can be found here.

Type conversion

DevicePilot respects the JSON types: number, string and boolean. If you happen to have a numeric value in a string type, you can convert it to a number using:

  • number (stringpropertyname)

Macros

Where expressions may contain macros (calls to in-built functions).

  • ago(seconds), the current time (in UNIX epoch seconds) minus seconds. Using the macro a query can find timed out devices with $ts < ago(60)

Escaping

If a property name used in an expression has characters other than alphanumeric (for example, a space or a dot), then it needs escaping using quotes and squiggly brackets:

  • "{property.name}"