Computed attributes allow dynamic modification of position attributes. The most common use cases for computed attributes:
Computed attributes are applied to all incoming positions of a linked device. To link, go into settings, open the devices or groups page, and click on the link icon. Then select attributes in the dropdown.
The order in which computed attributes are applied is defined by the priority parameter. A higher value means it will be executed first. Negative priority values allow you to execute parameters early in the position processing pipeline, before filtering and other handling is done.
Each computed attribute contains 4 fields:
You can pick from a list of standard attributes with predefined types, but it is also possible to define your own custom attribute.
The expression is the core of the computed attributes feature. It uses a very flexible JEXL syntax to compute the result.
All position fields are mapped as primitive objects (latitude, longitude, speed, course etc); they are always defined. Position attributes are also mapped as primitive objects (satellites, battery, ignition, distance etc). The set of attributes depends on what the device is reporting.
An empty result of computation (null, but not an empty string) will not be stored in the position and will clear any existing attribute with the same name.
The expression can be tested on the last position of some device.

Using undefined variables will create warning messages in the log. If you are not certain that the device always reports an attribute, then it is recommended to wrap it in a ternary operator to check if the value is present. A ternary operator is a conditional check; examples of this are shown below.
You have a device connected to a vehicle's electrical system that reports its voltage in the "power" attribute, but does not have a separate ignition status input. You can try to use the following computed attribute to assign a value to the ignition attribute:
Ignition
power ? power > 13.2 : null
Boolean
You have a device with some configurable inputs and you connected the ignition wire to the second one.
It is reported as a boolean attribute "in2".
Ignition
in2 ? true : false
Boolean
or as 0/1
Ignition
in2 ? in2 == 1 : false
Boolean
or as a second bit in the flags attribute
Ignition
flags ? (flags & 2) != 0 : false
Boolean
You have a device with some configurable analog inputs and connected a fuel sensor to the first one. Let's say the analog input has 10-bit resolution (0..1024) and a maximum value of 20 volts. The fuel sensor reports the remaining fuel as a voltage from 0 to 12 volts, where 0 V is empty and 12 V is a full 40-liter tank.
Fuel
adc1 ? adc1 * 0.065 : null
Number
Here is a non-standard case. There is a device that does not have any inputs to determine ignition. It has an internal battery, and its charger is connected to the ACC wire inside the car. It was noticed that when the device is charging it reports 4.18 V battery voltage; if not charging, the voltage is usually less than 4.18 V. Sometimes it fluctuates and speed might be used for additional correction.

Ignition
battery < 4.18 && speed < 1 ? false : true
Boolean
Using new(), you can create new instances of various Java objects using a fully-qualified Java class name or Class. For example, new("java.lang.Double", 10) returns a 10.0 double value.
JEXL syntax allows the declaration of local variables within the expression using the var keyword followed by the variable name and its initial value. Local variables can be of any primitive data type, including boolean, numeric, and string types, as well as arrays of primitive types.
Local variables are disabled by default in Traccar and must be enabled in the server configuration file by adding the following line:
var maxSpeed = 90 // set the maximum allowed speed in km/h
speed > maxSpeed ? speed - maxSpeed : null
For example, you have a device connected to a vehicle's systems that reports its speed in the speed attribute. You can use the following computed attribute to signal a speeding alarm:
var x = 2;
while (x lt 1024) { x = math:pow(x,2); }
x
Loops in JEXL allow you to iterate over collections and perform operations on each element. However, they can only be used if enabled in the configuration file with the line:
var list = [1, 2, 3, 4, 5];
var result = 0;
for (var item : list) {
result += item;
}
result
JEXL supports for, do while and while loops. In addition, you can also use the break and continue keywords to control the flow of the loop.
Loop examples:
var x = 2; while (x lt 1024) { x = math:pow(x,2); } x
var list = [1, 2, 3, 4, 5]; var result = 0; for (var item : list) { result += item; } result