Lua API#

Mosaic controllers offer a Lua API providing access to system information, playback functions and trigger operations.

Standard Libraries#

The following standard Libraries are imported

Input and output (IO)#

Attention

It’s important to understand some of the limitations of writing to permanent storage when using the IO library.

Frequency and size of writes should be limited for reliability and performance.

Flash storage (i.e. SD Card) has an almost unlimited number of read operations, but a limited number of write operations. Exceeding the write count can degrade the storage device, leading to data loss or failure.

While flash storage is faster than legacy magnetic media (e.g. HDD, floppy disks), it’s markedly slower than RAM (aka Memory). To prevent performance degradation the IO library buffers the data in RAM until being committed to the storage at some point in the future by the underlying operating system (OS). While the standard IO library provides io.flush(), this function simply passes the buffer to the OS ready to be committed when the OS is ready.

Should the controller experience a power loss before the file is committed to disk, then at best the data is lost, at worst this could cause corruption to the underlying flash storage. To mitigate this, and to provide the designer control over when this process should happen, io.open() is provided with an extra mode flag. By including the mode flag c, the file will be committed to storage when an io.flush() or io.close() command is issued.

While this increases data integrity, it comes with performance degradation; large files may take a number of moments for the commit to complete, during this time you may experience a degradation of playback performance.

Note

For further advice, please contact our support team.

--[[ Without commit flag ]]--
local file = io.open('myFile.txt', 'w+')
file:write('TheQuickBrownFoxJumpsOverTheLazyDog')
file:close() -- The file is committed to storage at "some point" in the future.
--[[ With commit flag ]]--
local file = io.open('myFile.txt', 'w+c')
file:write('TheQuickBrownFoxJumpsOverTheLazyDog')
file:close() -- The file is committed to storage now.

Constants#

At various places throughout the Lua API, values are available as constants; that means there are pre-defined Lua variables which you can use in your code.

For example:

state = get_timeline(1).state

if state == Timeline.RELEASED then
  -- do something if the timeline is released
end

Although these constants are numeric values, it’s better to use the constant name as shown above for readability and future proofing.

Functions#

The following functions are available in trigger action scripts and in IO modules. In trigger action scripts they are added directly to the environment; in IO modules they are available in the controller namespace.

Queries#

get_current_project#

Returns a Project object.

For example:

project_name = get_current_project().name

get_current_replication#

Returns a Replication object.

For example:

rep_name = get_current_replication().name

get_location#

Returns a Location object.

For example:

lat = get_location().lat

get_timelines#

get_timelines(playbackGroup)

Returns a list of timelineNum for the matching playbackGroup. If playbackGroup is omitted, then all timelineNum will be returned.

playbackGroup can either be the playback group number, or playback group name.

For example:

-- get a list of all timelines
local allTimelines = get_timelines()
log('Timelines in project:')
for _, timelineNum in pairs(allTimelines) do
   log(timelineNum)
end

-- get a list of timelines in playback group 1
local timelinesInGroup1 = get_timelines(1)
log('Timelines in playback group 1:')
for _, timelineNum in pairs(timelinesInGroup1) do
   log(timelineNum)
end

-- get a list of all timelines in playback group named "A"
local timelinesInGroupA = get_timelines('A')
log('Timelines in playback group A:')
for _, timelineNum in pairs(timelinesInGroupA) do
   log(timelineNum)
end

get_timeline#

get_timeline(timelineNum)

Returns a single Timeline object for the timeline with user number timelineNum.

For example:

tl = get_timeline(1)
name = tl.name
state = tl.state

if (tl.source_bus == TCODE_1) then
  -- do something
end

get_scenes#

get_scenes(playbackGroup)

Returns a list of sceneNum for the matching playbackGroup. If playbackGroup is omitted, then all sceneNum will be returned.

playbackGroup can either be the playback group number, or playback group name.

For example:

-- get a list of all scenes
local allScenes = get_scenes()
log('Scenes in project:')
for _, sceneNum in pairs(allScenes) do
   log(sceneNum)
end

-- get a list of scenes in playback group 1
local scenesInGroup1 = get_scenes(1)
log('Scenes in playback group 1:')
for _, sceneNum in pairs(scenesInGroup1) do
   log(sceneNum)
end

-- get a list of all scenes in playback group named "A"
local scenesInGroupA = get_scenes('A')
log('Scenes in playback group A:')
for _, sceneNum in pairs(scenesInGroupA) do
   log(sceneNum)
end

get_scene#

get_scene(sceneNum)

Returns a single Scene object for the scene with user number sceneNum.

For example:

scn = get_scene(1)
name = scn.name
state = scn.state

get_group#

get_group(groupNum)

Returns a single Group object for the group with user number groupNum.

For example:

grp = get_group(1)
name = grp.name

Note

Passing 0 as groupNum will return Group for the All Fixtures group. This can also be used on Atlas family projects to master the intensity of the entire unit.

get_playback_groups#

get_playback_groups()

Returns a list of playbackGroupNum in the current project.

For example:

-- get a list of playback groups
local playbackGroups = get_playback_groups()
log('Playback groups in project:')
for _, playbackGroupNum in pairs(playbackGroups) do
   log(playbackGroupNum)
end

get_playback_group#

get_playback_group(playbackGroupNum)

Returns an Playback Group object for the playback group with user number playbackGroupNum.

For example:

-- Get playback group for playback group 1
playbackGroup = get_playback_group(1)
-- Log the name of playback group
log(playbackGroup.name)

get_fixtures#

get_fixtures(status)

Returns a table of fixture user numbers with a matching status, where status is the integer value of the constants:

  • STATUS_ONLINE Fixture marked as online

  • STATUS_PARTIALLY_OFFLINE Fixture marked as partially offline

  • STATUS_OFFLINE Fixture marked as offline

  • STATUS_LOADING Fixture marked as loading

  • STATUS_UNKNOWN Fixture marked as unknown status

  • STATUS_ALL All fixtures

If omitted, status will default to STATUS_ALL

For example:

-- get a list of all offline fixtures
local offlineFixtures = get_fixtures(STATUS_OFFLINE)
log('Offline fixtures in project:')
for _, fixtureNum in pairs(offlineFixtures) do
   log(fixtureNum)
end

get_fixture#

get_fixture(fixtureNum)

Returns a single Fixture object for the fixture with user number fixtureNum.

For example:

-- get a list of all offline fixtures
local offlineFixtures = get_fixtures(STATUS_OFFLINE)
log('Offline fixtures in project:')
for _, fixtureNum in pairs(offlineFixtures) do
   -- get details of fixture
   local fixture = get_fixture(fixtureNum)
   log('- Number: ' .. fixtureNum)
   log('- Name: ' .. fixture.name)
   if (fixture.protocol == PROTOCOL_DMX) then
      log('- Protocol: ' .. DMX)
   elseif (fixture.protocol == PROTOCOL_DALI ) then
      log('- Protocol: ' .. DALI)
   end
   log('- Last updated: ' .. tostring(fixture.updated_at))
end

get_fixture_override#

get_fixture_override(fixtureNum)

Returns an Override object for the fixture with user number fixtureNum.

For example:

-- Get override for fixture 22
override = get_fixture_override(22)
-- Set the override colour to red (and full intensity)
override:set_irgb(255, 255, 0, 0)

get_group_override#

get_group_override(groupNum)

Returns an Override object for the group with user number groupNum.

Note

Passing 0 as groupNum will return an Override for the All Fixtures group.

For example:

-- Get override for group 3
override = get_group_override(3)
-- Set the intensity to 50% in 2 seconds
override:set_intensity(128, 2.0)

get_current_controller#

Returns the Controller that the script is being executed on.

For example:

cont = get_current_controller()
name = cont.name

get_controllers#

Returns a table of Controller objects for this project.

For example:

for _, controller in pairs(get_controllers()) do
    log('Name: ' .. controller.name)
end

get_remote_devices#

Returns a table of remote devices on this controller. The keys are integers with values equal to the global constants which correspond to the remote device type (e.g. RIO44). The values are tables of integers representing the assigned device number.

For example, this code will log each RIO D associated with the current controller:

local remoteDevices = get_remote_devices()
for type, deviceTable in pairs(remoteDevices) do
   if type == RIOD then
      for _, number in pairs(deviceTable) do
         log('Found a RIO D, remote device number ' .. number)
      end
   end
end

Remote Device Type

Value

RIO80

101

RIO44

102

RIO08

103

BPS

104

RIOA

105

RIOD

106

BPI

107

EXT

108

EDN20

109

EDN10

110

RIOG4

114

RIOD4

115

TPS

116

TPS5

117

TPS8

118

get_input_count#

get_input_count()

Returns the number of general purpose input ports this controller has.

get_input_type#

get_input_type(inputNum)

Returns an integer equal to the one of the constants ANALOG, DIGITAL, CONTACT_CLOSURE according to the configuration of this controller’s general purpose input port with number inputNum, or nil if inputNum does not correspond to a port.

get_input_threshold#

get_input_threshold(inputNum)

Returns an InputThreshold object describing the threshold configurations for this controller’s general purpose input port with number inputNum, or nil if inputNum does not correspond to a port.

get_output_count#

get_output_count()

Returns the number of relay output ports this controller has.

get_network_primary#

Returns the Controller in the project that is set as the network primary.

is_controller_online#

is_controller_online(controllerNum)

Returns true if the controller with user number controllerNum has been discovered, or false otherwise.

For example:

if (is_controller_online(2)) then
  log("Controller 2 is online")
else
  log("Controller 2 is offline")
end

get_temperature#

Returns a Temperature object with measurements from the controller’s temperature sensors.

For example:

temp = get_temperature()
log(temp.ambient_temp)

get_rio#

get_rio(type, num)

Returns a RIO object representing a RIO matching the parameters:

  • type can be one of the constants RIO80, RIO44 or RIO80.

  • num is the remote device number within the Designer project.

For example:

rio = get_rio(RIO44, 1)
input = rio:get_input(1)
output_state = rio:get_output(1)

Note

The constants for type are in the controller namespace within IO modules, e.g. controller.RIO44.

get_bps#

get_bps(num)

Returns a BPS object with remote device number num.

For example:

bps = get_bps(1)
btn = bps:get_state(1)

get_touch_device#

get_touch_device(type, num)

Returns a Touch Device object representing a TouchDevice matching the parameters:

  • type can be one of the constants TPS, TPS5 or TPS8.

  • num is the remote device number within the Designer project.

For example:

tps = get_touch_device(TPS5, 1)
tps:set_interface_page(4, SNAP)

Note

The constants for type are in the controller namespace within IO modules, e.g. controller.TPS5.

get_text_slot#

get_text_slot(slotName)

Returns the value of the text slot with name slotName. If no such text slot exists in the project then an empty string will be returned.

For example:

log(get_text_slot("my text slot"))

get_dmx_universe#

get_dmx_universe(idx)

Returns a Universe object for the DMX universe with number idx.

For example:

uni = get_dmx_universe(1) -- get DMX Universe 1
level = uni:get_channel_value(1) -- get channel 1 from the returned universe

get_artnet_universe#

get_artnet_universe(idx)

Returns a Universe object for the Art-Net universe with number idx.

get_pathport_universe#

get_pathport_universe(idx)

Returns a Universe object for the Pathport universe with number idx.

get_sacn_universe#

get_sacn_universe(idx)

Returns a Universe object for the sACN universe with number idx.

get_kinet_universe#

get_kinet_universe(power_supply_num, port_num)

Returns a Universe object for the KiNET power supply port matching the parameters:

  • power_supply_num is the KiNET power supply number in the project.

  • port_num is the port number of the KiNET power supply.

get_edn_universe#

get_edn_universe(remote_device_type, remote_device_num, port_num)

Returns a Universe object for the EDN output matching the parameter:

  • remote_device_type is be one of the constants EDN10 or EDN20.

  • remote_device_num is the remote device number of the EDN in the project.

  • port_num is the DMX output port number of the EDN.

Note

The constants for remote_device_type are in the controller namespace within IO modules, e.g. controller.EDN20.

get_input#

get_input(idx)

Returns the state of the controller’s input numbered idx as a boolean (for digital inputs) or an integer (for analog inputs, 0-100).

For example:

in1 = get_input(1)

if in1 == true then
  log("Input 1 is digital and high")
elseif in1 == false then
  log("Input 1 is digital and low")
else
  log("Input 1 is analog at " .. in1)
end

get_dmx_input#

get_dmx_input(channel)

Returns the value of the DMX channel number as an integer. If no DXM input is detected then nil will be returned.

get_trigger_variable#

get_trigger_variable(idx)

Returns the trigger variable at index idx as a Variant.

For example:

-- Use with a Touch Colour Move Trigger
red = get_trigger_variable(1).integer
green = get_trigger_variable(2).integer
blue = get_trigger_variable(3).integer

-- Use with Serial Input "<s>\r\n"
input = get_trigger_variable(1).string

get_trigger_number#

get_trigger_number()

Returns the number of the trigger that ran this script. Will return nil if called from another context.

get_resource_path#

get_resource_path(filename)

Returns the path to the resource file, where filename is the name of a file on the controller’s internal storage.

For example:

dofile(get_resource_path("my_lua_file.lua"))

get_content_target#

Note

Only supported on Atlas and Atlas Pro.

On a Atlas: get_content_target(compositionNum)

On a Atlas Pro: get_content_target(compositionNum, type)

Returns a Content Target object representing the Content Target in the project that matches the parameters:

  • compositionNum is the user number of the composition containing the desired Content Target.

  • type describes the Content Target type and can be one of the constants PRIMARY, SECONDARY or TARGET_3TARGET_8.

Note

The constants for type are in the controller namespace within IO modules, e.g. controller.TARGET_5.

Will return nil if no matching Content Target exists in the project.

For example, on a Atlas:

target = get_content_target(1)
current_level = target.master_intensity_level

And on a Atlas Pro:

target = get_content_target(1, PRIMARY)
current_angle = target.rotation_offset

get_adjustment#

Note

Only supported on Atlas Pro.

get_adjustment(num)

Returns an Adjustment Target object representing the Adjustment Target in the project with the integer user number num:

Will return nil if no matching Adjustment Target exists in the project.

For example:

target = get_adjustment(1)
target:transition_x_position(10,1,5) -- Move 10 pixels right in 5 seconds
target:transition_y_position(10,1,5) -- Move 10 pixels down in 5 seconds
target:transition_rotation(90,1,5) -- Rotate by 90 degrees in 5 seconds

get_log_level#

Returns the current log level of the controller.

Log levels are integers, available as constants, but can be used for numeric comparisons as well, for example:

if get_log_level() >= LOG_NORMAL then
   log('Extra Logging for levels Normal, Terse and Debug')
end
  • LOG_DEBUG (5)

  • LOG_TERSE (4)

  • LOG_NORMAL (3)

  • LOG_EXTENDED (2)

  • LOG_VERBOSE (1)

  • LOG_CRITICAL (0)

Note

These constants are in the controller namespace within IO modules, e.g. controller.LOG_NORMAL.

get_syslog_enabled#

Returns true if Syslog is enabled, or false otherwise.

get_syslog_ip_address#

Returns the IP address of the Syslog server as a string.

get_ntp_enabled#

Returns true if NTP is enabled.

get_ntp_ip_address#

Returns the IP address of the NTP server as a string.

get_hash_string#

get_hash_string(string, method)

Returns hashed string using the one of specified cryptographic methods:

  • HASH_MD4 (0)

  • HASH_MD5 (1)

  • HASH_SHA1 (2)

  • HASH_SHA224 (3)

  • HASH_SHA256 (4)

  • HASH_SHA384 (5)

  • HASH_SHA512 (6)

get_hash_table#

get_hash_table(table, method)

Returns hashed byte table using the specified cryptographic method.

-- Hash the bytes using MD5
local bytes = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6}
local digest = get_hash_table(bytes, HASH_MD5)
-- 'digest' now contains '{0x6a, 0xc1, 0xe5, 0x6b, 0xc7, 0x8f, 0x03, 0x10, 0x59, 0xbe, 0x7b, 0xe8, 0x54, 0x52, 0x2c, 0x4c}'

Actions#

log#

log([level, ]message)

Write a message to the controller’s log according to the parameters:

Parameter

Value Type

Description

Value Example

level

Integer value of constants: LOG_DEBUG, LOG_TERSE, LOG_NORMAL, LOG_EXTENDED, LOG_VERBOSE, LOG_CRITICAL; defaults to LOG_NORMAL

Optional. The log level to apply to the message.

LOG_VERBOSE

message

string

The message to add to the log.

"Your log message"

For example:

log(LOG_CRITICAL, "This is a critical message!") -- logs a message at Critical log level
log("This is a normal message.") -- logs a message at Normal log level.

reset#

Reboots the controller.

set_log_level#

set_log_level(log_level)

Changes the log level of the controller, showing more or less detailed information, where log_level is an integer value of the constants:

  • LOG_DEBUG (5)

  • LOG_TERSE (4)

  • LOG_NORMAL (3)

  • LOG_EXTENDED (2)

  • LOG_VERBOSE (1)

  • LOG_CRITICAL (0)

pause_all#

Pause all timelines in the project.

resume_all#

Resume all timelines in the project.

release_all#

release_all([fade,] [group])

Release all timelines and scenes in the project.

Note

You can provide:
  • No arguments - this will release all with the default fade time.

  • A fade time, which will be used to release all.

  • Or, both a fade time and a group.

Parameter

Value Type

Description

Value Example

fade

float

Optional. Release fade time in seconds. If not provided, the default fade time will be used.

2.0

group

string

Optional. Group name or number. If name, prepend the name with ! to apply the action to all groups except the specified group.

"Group 1", "!Group 2" or 3

release_all_timelines#

release_all_timelines([fade,] [group])

Release all timelines in the project.

Note

You can provide:
  • No arguments - this will release all with the default fade time.

  • A fade time, which will be used to release all.

  • Or, both a fade time and a group.

Parameter

Value Type

Description

Value Example

fade

float

Optional. Release fade time in seconds. If not provided, the default fade time will be used.

2.0

group

string

Optional. Group name or number. If name, prepend the name with ! to apply the action to all groups except the specified group.

"Group 1", "!Group 2" or 3

release_all_scenes#

release_all_scenes([fade,] [group])

Release all scenes in the project.

Note

You can provide:
  • No arguments - this will release all with the default fade time.

  • A fade time, which will be used to release all.

  • Or, both a fade time and a group.

Parameter

Value Type

Description

Value Example

fade

float

Optional. Release fade time in seconds. If not provided, the default fade time will be used.

2.0

group

string

Optional. Group name or number. If name, prepend the name with ! to apply the action to all groups except the specified group.

"Group 1", "!Group 2" or 3

clear_all_overrides#

clear_all_overrides([fade])

Removes all overrides from all fixtures and groups. Optionally specify a fade time in seconds as a float, e.g. 2.0.

enqueue_trigger#

enqueue_trigger(num[,var...])

Queue trigger number num to be fired on the next controller playback refresh. The trigger’s conditions will be tested. Optional variables var can be passed in as additional arguments.

For example:

-- enqueue trigger 2, passing in three variables: 255, 4.0 and "string"
enqueue_trigger(2,255,4.0,"string")

enqueue_local_trigger#

enqueue_local_trigger(num[,var...])

Same behaviour as for enqueue_trigger but the trigger num will only be queued on the controller that ran the function - the trigger will not propagate to other controllers in the project.

force_trigger#

force_trigger(num[,var...])

Queue trigger number num to be fired on the next controller playback refresh without testing the trigger’s conditions - the trigger actions will always run. Optional variables var can be passed in as additional arguments.

For example:

-- force the execution of trigger 2's actions
-- pass in three variables: 255, 4.0 and "string"
force_trigger(2,255,4.0,"string")

force_local_trigger#

force_local_trigger(num[,var...])

Same behaviour as for force_trigger but the trigger num will only be queued on the controller that ran the function - the trigger will not propagate to other controllers in the project.

set_text_slot#

set_text_slot(name, value)

Set the value of the text slot named name in the project to value, for example:

-- Set "My slot" to value "Hello world!"
set_text_slot("My slot", "Hello world!")

set_control_value#

Same behaviour as for set_control_value, but acts on all touchscreens

set_control_state#

Same behaviour as for set_control_state, but acts on all touchscreens

set_control_caption#

Same behaviour as for set_control_caption, but acts on all touchscreens

set_touch_button_pressed#

Same behaviour as for set_touch_button_pressed, but acts on all touchscreens

is_touch_button_pressed#

Same behaviour as for is_touch_button_pressed, but acts on all touchscreens

set_interface_page#

Same behaviour as for set_interface_page, but acts on all touchscreens

set_interface_enabled#

Same behaviour as for set_interface_enabled, but acts on all touchscreens

set_interface_locked#

Same behaviour as for set_interface_locked, but acts on all touchscreens

push_to_web#

push_to_web(name, value)

Sends data as JSON to clients who are subscribed to the relevant WebSocket channel, e.g. custom web interfaces using subscribe_lua in the query.js library. The parameters are as follows:

Parameter

Value Type

Description

Value Example

name

string

JSON attribute name

"myVar"

value

Variant

Value for the JSON, which will be sent as a string.

"String value" or 1234

For example:

myData = 1234
-- Will push JSON object {"my_data":"1234"}
push_to_web("my_data", myData)

disable_output#

disable_output(protocol)

Disables the output of a single protocol from the controller, where protocol is the integer value of the constants:

  • DMX

  • PATHPORT

  • ARTNET

  • KINET

  • SACN

  • DVI

  • RIO_DMX

  • EDN_DMX

  • EDN_SPI

For example:

-- Disable the DMX output from the controller
disable_output(DMX)

enable_output#

enable_output(protocol)

Enables the output of a single protocol from the controller, where protocol is the integer value of the constants defined for disable_output.

For example:

-- Enable the DMX output from the controller
enable_output(DMX)

set_timecode_bus_enabled#

set_timecode_bus_enabled(bus[, enable])

Enable or disable a timecode bus, where bus is the integer value of the constants TCODE_1TCODE_6 and enable is a boolean, determining whether the bus is enabled (default true) or not.