Calculated Channels
Process live telemetry with calculated channels.
Calculated channels derive real-time data from existing channels. They enable live data processing and analysis, such as:
- Scaling, converting or filtering raw data
- Implementing sensor voting algorithms
- Creating channels to conditionally trigger alarms or warnings.
Creating Channels
To create a calculated channel, open the Command Palette and run the “Create Calculated Channel” command.
- Click the search bar at the top and type
>
to open the palette. - Alternatively, press
Ctrl+Shift+P
(Windows) /Cmd+Shift+P
(macOS).
Channel Parameters
When creating a calculated channel, you will be prompted to fill in the following fields:
Field | Description |
---|---|
Name | A name for the channel. |
Data Type | The type of data the channel stores. |
Expression | The Lua expression that calculates the value to be written to the calculated
channel. This expression must end with a |
Requires | The existing Synnax channels used in the calculation. A calculated channel must reference at least one existing channel in its expression. |
Calculated channels are virtual, meaning data written to them will not be stored permanently.
Rules for Calculations
Use Lua for expressions
Calculated channels use Lua to define expressions. If you are unfamiliar with Lua, check out our short primer for an overview of its syntax and features.
Use return
to specify the final value
Your expression can include intermediate variables, but it must end with a return
statement.
Example: Scaling two channels before summing them:
local scaled1 = channels.channel1 * 10
local scaled2 = channels.channel2 * 10
return scaled1 + scaled2 -- The final value written to the calculated channel
Access channels using get()
for special names
If a channel name contains hyphens or spaces, use the get()
method instead of direct
property access:
return get("channel-1") + get("channel-2")
Editing Calculations
To edit a calculated channel, right-click it in the Resources Toolbar and select “Edit Calculation” from the context menu:
Writing Expressions in Lua
You can define calculations using any valid Lua expression. Below is a brief primer on Lua syntax:
Basic Syntax
Variables
local a = 1 -- declared with the local keyword
If Statements
if channels.temperature < 32 then
return "freezing"
elseif channels.temperature < 70 then
return "cool"
else
return "warm"
end
Tables
Tables in Lua work like key-value dictionaries in Python and are created using {}
:
local thresholds = {
max = 100,
min = 0
}
return channels.temperature > thresholds.max
Tables can also serve as arrays. Lua arrays start at 1, not 0.
local readings = { pressure1, pressure2, pressure3, pressure4 }
local count = #readings -- Returns 4 (table length)
local first = readings[1] -- Gets pressure1 value
local last = readings[4] -- Gets pressure4 value
You can loop through a table in two common ways:
local readings = { pressure1, pressure2, pressure3, pressure4 }
-- Method 1: Using ipairs (recommended for arrays)
local sum = 0
for i, value in ipairs(readings) do
sum = sum + value
end
-- Method 2: Using numeric indices
local sum = 0
for i = 1, #readings do
sum = sum + readings[i]
end
Functions
Functions are created with the function
keyword
function add(a, b)
return a + b
end
Supported Operators
Operator Type | Operators | Description |
---|---|---|
Arithmetic | + , - , * , / , // , % , ^ | Addition, subtraction, multiplication, float division, floor division, modulo, exponentiation |
Relational | == , ~= , < , > , <= , >= | Equal to, not equal to, less than, greater than, less than or equal to, greater than or equal to |
Logical | and , or , not | Logical AND, OR, and NOT |
Concatenation | .. | String concatenation |
Bitwise | & , | , ~ , << , >> , ~ | Bitwise AND, OR, XOR, left shift, right shift, unary bitwise NOT |
Length | # | Gets the length of a string or table |
You can also use Lua’s built-in math
library:
Function Type | Functions |
---|---|
Constants | math.pi , math.huge , math.maxinteger , math.mininteger |
Basic Math |
|
Power/Logarithmic | math.sqrt() , math.pow() , math.exp() , math.log() , math.log10() |
Trigonometry |
|
Angle Conversion | math.deg() , math.rad() |
Random | math.random() , math.randomseed() |
Structure | Syntax | Description |
---|---|---|
If Statement |
| Conditional execution with optional else and elseif branches |
Numeric For | for i=start,end,step do ... end | Loops from start to end, optional step (defaults to 1) |
Generic For | for k,v in pairs(table) do ... end | Iterates over table elements using pairs() or ipairs() |
While | while condition do ... end | Loops while condition is true |
Repeat | repeat ... until condition | Runs at least once, then repeats until condition is met |
Break | break | Exit the innermost loop |
Example: Scaling and Finding the Maximum
The following Lua script scales four channels and returns the highest value:
-- Function to apply linear scaling
function linearScale(value, offset, slope)
if value == nil then
return nil
end
return (value * slope) + offset
end
-- Function to find the maximum value in a table
function findMax(t)
local max_val
for _, value in ipairs(t) do -- Use ipairs for array-like tables
if max_val == nil or value > max_val then
max_val = value
end
end
return max_val
end
-- Fuel pressure channels
local channels = {fuel_pt_1, fuel_pt_2, fuel_pt_3, fuel_pt_4}
-- Corresponding scale parameters (slope and offset)
local scale_params = {
{slope = 2.0, offset = 10},
{slope = 1.5, offset = -5},
{slope = 3.0, offset = 0},
{slope = 0.5, offset = 15}
}
-- Apply scaling to each channel
local scaled_values = {}
for i, value in ipairs(channels) do
local params = scale_params[i]
scaled_values[i] = linearScale(value, params.offset, params.slope)
end
return findMax(scaled_channels)