Formula Language

You can compute values derived from raw tag values by writing formulae similar to JavaScript expressions. The formulae are continuously evaluated as input tag values change. Currently, Clarity supports using formulae for notification conditions, but it may support them for more uses in the future.

Examples

Test if either tag1 or tag2 is not available (null):

tagValue("tag1") === null || tagValue("tag2") === null

Test if flow is less than 10 (in whatever units the tag has) while pumping, assmuing that the pumping tag is a boolean:

tagValue("pumping") && tagValue("flow") < 10

Test if flow has been above 10 (in whatever units the tag has) for at least an hour:

conditionHoldsFor(tagValue("flow") > 10, 1h)

Test if the max of three tags is above another tag:

max(
  tagValue("pressure1"),
  tagValue("pressure2"),
  tagValue("pressure3")
) > tagValue("pressureLimit")

Language Reference

Data Types

Formulae support JavaScript number, boolean, and string data types, as well as null (used when a value isn't available for a tag or an expression on that tag). Numbers are represented as 64-bit floating point values, although when performing bitwise operations, they are first converted to 32-bit integer values, then the result is converted back to a 64-bit floating point value.

No Coercion to Number or Boolean

Unlike JavaScript, formula won't automatically coerce other data types to number or boolean values, and any operation on mismatched data types (except for string concatenation with +) will be flagged as an error.

null propagation

Unlike JavaScript, the result of an arithmetic, bitwise, or comparison operation will be null if one of the operands is null. For example the expression tagValue("a") + tagValue("b") will be null if the value of either of the two tags is null (not available).

No NaN

Unlike JavaScript, there is no NaN constant; null is returned instead, for example from 0 / 0.

Keywords

true, false, and null have the same values as in JSON.

Number Literals

As in JSON, a number may consist of decimal digits 0-9, optional digits after a decimal place ., and and optional positive or negative exponent e8 or e-8.

String Literals

As in JSON, a string literal consists of text between double quotes ("), for example:

"hello world"

The backslash (\) allows you to escape special characters:

Time Intervals

Some functions accept time intervals as arguments; a time interval is a number with a time unit suffix, for example:

Built-in Functions

tagValue(<tag>)

Gets the value of the given <tag> at the current time. <tag> must be a string literal, for example:

tagValue("Site 1/battery/1/lifetimeWh")

tagValue(<tag>) may evaluate to a number, string, boolean, depending on the data type of the given tag, or null if a value for the given tag is not available at the current time.

tagIsNAFor(<tag>, <interval>)

Evaluates to true if the given <tag> has been unavailable for at least the given amount of time. If there is or was a value available for the tag more recently than the given amount of time before the present, evaluates to false.

<tag> must be a string literal and <interval> must be a time interval, for example:

tagIsNAFor("Site 1/battery/1/lifetimeWh", 5m)

maxChange(<expression>, <interval>)

Evaluates to the maximum amount the given <expression> has changed over the given <interval> of time since the present. Always evaluates to a positive number, the absolute difference between the minimum and maximum values of <expression> over the past <interval>.

<expression> can be any expression that evaluates to a number or null.

<interval> must be a time interval no greater than one day.

conditionHoldsFor(<expression>, <interval>)

Evaluates to true if the given <expression> has remained true over the given <interval> of time since the present. Otherwise, evaluates to false.

<expression> can be any expression that evaluates to a boolean or null.

<interval> must be a time interval no greater than one day.

Math functions

The following JavaScript Math functions are available:

Operators

All operators are computed as in JavaScript, except that no coercion to number or boolean is supported.

When performing bitwise operations, the operands are first converted to 32-bit integer values, then the result of the operation is converted back to a 64-bit floating point value.

Equality and Strict Equality

Unlike JavaScript, the non-strict == and != operators evaluate to null if either operand is null. That is, whereas in JavaScript, null == null is true, in Clarity formulae, null == null is null.

If you want to test for null, use the === and !== operators; null === null is true.

Last updated