Expression syntax reference
This reference documents the complete syntax of the Navixy IoT Logic Expression Language, including literals, operators, functions, and data types. For conceptual information about how expressions work within IoT Logic, see the Expression language overview.
Basic syntax elements
The expression language uses JEXL (Java Expression Language) as its foundation, with IoT-specific enhancements for device data processing.
Literals
Integer
Digits 0-9
42
Float
Digits with decimal point, optional f or F suffix
3.14, 42.0f
Long
Digits with l or L suffix
42L
Double
Digits with decimal point and d or D suffix
42.0d
Hexadecimal
0x or 0X prefix, then hex digits
0xFF, 0x1A2B
Octal
0 prefix, then octal digits
010
Scientific notation
Standard scientific notation with e or E
1.5e-10
String (double quotes)
Text enclosed in double quotes
"Hello world"
String (single quotes)
Text enclosed in single quotes
'Hello world'
String escape sequences
Backslash escape character
"Line 1\nLine 2", "Quote: \"text\""
Boolean
Keywords true or false
true, false
Null
Keyword null
null
Identifiers and attribute names
Attribute names must exactly match names from device telemetry. To make sure you use correct names, you can:
Use the Autofill attribute names option
Lookup attribute names in Data Stream Analyzer
Attribute access
Short syntax (current values)
Direct attribute references provide the simplest way to access current device data in expressions. This syntax omits the value() function, using implicit default parameters for clean, readable formulas.
Use for: Simple calculations with current data
Syntax: attribute_name
How it works: Short syntax is a convenient shorthand that automatically uses value() function with default parameters:
temperatureis equivalent tovalue('temperature', 0, 'all')Default index:
0(current value)Default validation:
'all'(includes null values)
Examples:
temperature * 1.8 + 32
Unit conversion
speed > 80
Threshold check
fuel_level + reserve_tank
Combine attributes
Full syntax (historical and advanced)
The explicit value() function unlocks historical data access and precise control over null handling. This syntax is essential for trend analysis, change detection, and any calculation requiring data from previous readings.
Use for: Historical data access, trend analysis, null handling control
Function: value(attribute_name, index, validation)
How it works: Full syntax explicitly defines all parameters of the value() function, enabling access to historical data and control over null handling.
attribute_name
String
Attribute name from device
index
0-12
0=current, 1=previous, 12=oldest
validation
'all' | 'valid'
'all'=include nulls, 'valid'=skip nulls
Parameter behavior explained:
Given history: [25.5, null, 24.8, null, 23.2] (index 0 to 4)
value('temp', 1, 'all')
1
Include nulls
null
Returns value at exact index 1, which is null
value('temp', 1, 'valid')
1
Skip nulls
24.8
Skips null at index 1, returns first valid value
value('temp', 2, 'all')
2
Include nulls
24.8
Returns value at exact index 2
value('temp', 2, 'valid')
2
Skip nulls
23.2
Skips nulls at indices 1 and 3, returns second valid value
When to use each validation mode:
'all'- For time-based analysis where null indicates missing data at specific time.'valid'- For trend analysis where you need actual values regardless of gaps. Important: Returns the last non-null value, which can belong to another (earlier) reading. Consider it carefully when building expressions.
Formula examples:
Detect temperature change
temperature - value('temperature', 1, 'all')
Difference between current and previous reading, null if previous missing
Calculate acceleration
speed - value('speed', 1, 'valid')
Difference between current and last valid reading, ignoring gaps
Detect gradual trends
(temp - value('temp', 2, 'valid')) / 2
Average change per reading over last 2 valid readings
Sustained speeding alert
speed > 80 && value('speed', 1, 'valid') > 80
True if current AND previous valid reading both exceed 80
Smooth sensor fluctuations
(value('pressure', 0, 'valid') + value('pressure', 1, 'valid') + value('pressure', 2, 'valid')) / 3
Average of 3 most recent valid pressure readings
Operators
Arithmetic operators
+
Addition
temperature + 10
-
Subtraction
fuel_level - 5
*
Multiplication
temperature * 1.8
/
Division
distance / time
%
Modulus (remainder)
value % 100
Comparison operators
==
Equal
speed == 80
!=
Not equal
status != 0
<
Less than
temperature < 0
<=
Less than or equal
fuel_level <= 10
>
Greater than
speed > 80
>=
Greater than or equal
voltage >= 12.0
Logical operators
&&
and
Logical AND
speed > 80 && engine_on
||
or
Logical OR
temp < 0 || pressure_low
!
not
Logical NOT
!door_closed
Pattern matching operators
=~
Checks if the value of the left operand is in the set of the right operand. For strings, checks for regex pattern match
!~
Checks if the value of the left operand is not in the set of the right operand. For strings, checks for regex pattern mismatch
=^
Checks that the left string operand starts with the right string operand
!^
Checks that the left string operand doesn't start with the right string operand
=$
Checks that the left string operand ends with the right string operand
!$
Checks that the left string operand doesn't end with the right string operand
Ternary conditional
Syntax: condition ? value_if_true : value_if_false
Example: speed > 80 ? "Speeding" : "Normal"
Operator precedence
Operators are evaluated in order from highest to lowest precedence:
1 (highest)
( )
Parentheses
2
!, not, - (unary), + (unary)
Unary operators
3
*, /, %
Multiplication, division, modulus
4
+, -
Addition, subtraction
5
<, <=, >, >=
Comparison
6
==, !=
Equality
7
&&, and
Logical AND
8
||, or
Logical OR
9 (lowest)
? :
Ternary conditional
Core functions
Time and data access functions
value(attribute_name, index, validation)
attribute_name (String)
index (Integer, 0-12)
validation (String: 'all' or 'valid')
Attribute value at specified historical position
genTime(attribute_name, index, validation)
attribute_name (String
index (Integer, 0-12)
validation (String: 'all' or 'valid')
Device-side generation timestamp (milliseconds) for attribute value. Default: now()
srvTime(attribute_name, index, validation)
attribute_name (String
index (Integer, 0-12
validation (String: 'all' or 'valid')
Server-side reception timestamp (milliseconds) for attribute value. Default: now()
Usage examples:
Default timestamp (current time)
"server_time": "now()" or "generation_time": "now()"
Data age
now() - genTime('temperature', 0, 'all')
Transmission delay
srvTime('temperature', 0, 'all') - genTime('temperature', 0, 'all')
Time offset
genTime('temperature', 0, 'valid') + 120000
Bit-level operations
The util: namespace provides specialized functions for binary data processing, data format conversions, and string operations.
Bit-level functions
util:signed(n, bytesAmount)
n (Number): unsigned number
bytesAmount (int): bytes (1, 2, 4, 8)
Long
Converts an unsigned integer of bytesAmount bytes to a signed two's-complement value.
Note: It does not convert signed to unsigned.
util:checkBit(n, bitIndex)
n (Number): number to check
bitIndex (int): bit position (0=LSB)
Boolean
Check if bit is set (true) or not (false)
util:bit(n, bitIndex)
n (Number): number to check
bitIndex (int): bit position (0=LSB)
Integer
Get bit value (1 or 0)
util:bits(n, firstBitIndex, lastBitIndexInclusive)
n (Number): source number
firstBitIndex (int): start position
lastBitIndexInclusive (int): end position
Long
Extract bit range; reverse if lastBitIndexInclusive < firstBitIndex. Returns null if indexes are out of bounds.
util:bytes(n, firstByteIndex, lastByteIndexInclusive)
n (Number): source number
firstByteIndex (int): start position
lastByteIndexInclusive (int): end position
Long
Extract byte range; byte swap if lastByteIndexInclusive < firstByteIndex. Returns null if indexes are out of bounds.
Examples:
util:signed(65535, 2)
-1
Convert 0xFFFF to signed 16-bit
util:checkBit(4, 2)
true
Check status flag bit
util:bits(1321678, 0, 3)
14
Extract 4-bit sensor value
util:bytes(11189196, 1, 0)
52411
Little-endian byte swap
HEX string operations
Binary data is processed as HEX strings (uppercase) for readability and protocol compatibility.
util:hex(n)
n (Number): value to convert
String
Convert to HEX string; 16 chars for negative/float, variable for positive int; null if invalid
util:hex(n, bytesAmount)
n (Number): value to convertbytesAmount (int): byte length
String
Convert to fixed-length HEX (bytesAmount * 2 chars); pad/truncate as needed; null if invalid
util:hexToLong(s)
s (String): HEX string
Long
Convert HEX string to Long; null if invalid
util:hexToLong(s, firstByteIndex, lastByteIndexInclusive)
s(String): HEX string
firstByteIndex(int): start byte (0=left). Byte 0 is the leftmost (most-significant) byte of the HEX string.
lastByteIndexInclusive(int): end byte
Long
Extract bytes from HEX string to Long; reverse if lastByteIndexInclusive < firstByteIndex; null if invalid
Examples:
util:hex(127)
"7F"
Variable length conversion
util:hex(127, 6)
"00000000007F"
Fixed-width formatting
util:hexToLong("FF")
255
Parse HEX value
util:hexToLong("AABBCC", 1, 0)
48042
Little-endian parsing
Data format conversions
util:fromBcd(o)
o (Object): BCD number
Long
Convert BCD to decimal; null if invalid BCD
util:toBcd(o)
o (Object): decimal (0 to 9999999999999999)
Long
Convert decimal to BCD; null if out of range
util:toFloat(o)
o (Object): Long (IEEE 754 bits) or Double
Float
Convert to Float; interpret Long as IEEE 754 bits; null if invalid
util:toDouble(o)
o (Object): Long (IEEE 754 bits) or Double
Double
Convert to Double; interpret Long as IEEE 754 bits; null if invalid
Examples:
util:fromBcd(0x1234)
1234
Decode BCD device ID
util:toBcd(1234)
0x1234 (4660)
Encode for BCD protocol
util:toFloat(1065353216)
1.0
Decode IEEE 754 float
String padding functions
util:leftPad(o, length)
o (Object): value
length (int): target length
String
Pad left with "0" to length; null if input null
util:leftPad(o, length, padStr)
o (Object): value
length (int): target length
padStr (String): padding
String
Pad left with custom string; null if input null
util:rightPad(o, length)
o (Object): value
length (int): target length
String
Pad right with "0" to length; null if input null
util:rightPad(o, length, padStr)
o (Object): value
length (int): target length
padStr (String): padding
String
Pad right with custom string; null if input null
Examples:
util:leftPad(123, 5)
"00123"
util:leftPad(7, 3, "*")
"**7"
util:rightPad(123, 5)
"12300"
Data types and type handling
Supported data types
Integer
Whole numbers
42, -100, 0xFF
Long
Large integers with L suffix
42L, 9999999999L
Float
Floating-point with optional f suffix
3.14, 42.0f
Double
Double-precision floating-point
3.14, 42.0d
String
Text enclosed in quotes
"text", 'text'
Boolean
True or false values
true, false
HEX String
Uppercase hexadecimal representation
"FF", "1A2B"
Null
Absence of value
null
Null propagation
Rule: Null values propagate through expressions without errors. When any operand is null, the expression typically evaluates to null.
null + 5
null
Arithmetic with null
temperature + 10
null
If temperature is null
null == null
true
Null equality
null != 5
true
Null comparison
null > 0
false
Null in comparison
Error conditions resulting in null
Invalid function input
util:hexToLong("invalid")
null
Invalid BCD
util:fromBcd(0x99A0)
null
Missing historical data
value('temperature', 5, 'valid')
null (if < 5 valid readings)
Type mismatch
"text" + 123
null
Mismatched attribute names prevent calculation execution (no null returned; calculation skipped).
Expression patterns
Unit conversion
temperature * 1.8 + 32
Celsius to Fahrenheit
distance / 1.609
Kilometers to miles
volume * 0.264172
Liters to gallons
Change detection
temperature - value('temperature', 1, 'all')
Temperature change
value('fuel_level', 1, 'valid') - fuel_level
Fuel consumption
speed - value('speed', 1, 'valid')
Speed change
Binary parsing
util:signed(util:hexToLong(hex_data, 0, 1), 2) / 10.0
Signed temp from HEX
util:checkBit(status_flags, 0)
Check status flag
util:bits(status_word, 4, 7)
Extract sensor value
Time calculations
now() - genTime('temperature', 0, 'all')
Data age
srvTime('temp', 0, 'all') - genTime('temp', 0, 'all')
Transmission delay
genTime('temperature', 0, 'valid') + 120000
Time offset (2 min)
Quick reference tables
Core functions summary
value(attr, idx, val)
Any
Historical attribute value
genTime(attr, idx, val)
Long
Device generation time (default: now())
srvTime(attr, idx, val)
Long
Server reception time (default: now())
Bit operations summary
util:signed(n, bytes)
Long
Convert unsigned to signed
util:checkBit(n, bit)
Boolean
Check if bit is set
util:bit(n, bit)
Integer
Get bit value (0/1)
util:bits(n, firstBitIndex, lastBitIndexInclusive)
Long
Extract bit range
util:bytes(n, firstByteIndex, lastByteIndexInclusive)
Long
Extract byte range
HEX operations summary
util:hex(n)
String
Number to variable-length HEX
util:hex(n, bytes)
String
Number to fixed-length HEX
util:hexToLong(s)
Long
HEX string to number
util:hexToLong(s, firstByteIndex, lastByteIndexInclusive)
Long
Extract bytes from HEX string
Data conversion summary
util:fromBcd(o)
Long
BCD to decimal
util:toBcd(o)
Long
Decimal to BCD
util:toFloat(o)
Float
IEEE 754 bits to float
util:toDouble(o)
Double
IEEE 754 bits to double
String operations summary
util:leftPad(o, len)
String
Pad left with "0"
util:leftPad(o, len, pad)
String
Pad left with custom string
util:rightPad(o, len)
String
Pad right with "0"
util:rightPad(o, len, pad)
String
Pad right with custom string
Last updated
Was this helpful?