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:

FieldDescription
NameA name for the channel.
Data TypeThe 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 return statement.

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 TypeOperatorsDescription
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

Logicaland, or, notLogical 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 TypeFunctions
Constantsmath.pi, math.huge, math.maxinteger, math.mininteger
Basic Math

math.abs(), math.ceil(), math.floor(), math.max(), math.min(), math.fmod(), math.modf()

Power/Logarithmicmath.sqrt(), math.pow(), math.exp(), math.log(), math.log10()
Trigonometry

math.sin(), math.cos(), math.tan(), math.asin(), math.acos(), math.atan(), math.atan2()

Angle Conversionmath.deg(), math.rad()
Randommath.random(), math.randomseed()
StructureSyntaxDescription
If Statement

if ... then ... end


if ... then ... else ... end


if ... then ... elseif ... then ... else ... end

Conditional execution with optional else and elseif branches
Numeric Forfor i=start,end,step do ... endLoops from start to end, optional step (defaults to 1)
Generic Forfor k,v in pairs(table) do ... endIterates over table elements using pairs() or ipairs()
Whilewhile condition do ... endLoops while condition is true
Repeatrepeat ... until conditionRuns at least once, then repeats until condition is met
BreakbreakExit 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)