An EOS Preset Auto Photo Script

This script is an example script of how you may automatically photograph a preset. The aim is to recall all the channels for the selected preset in the Preset Documentation view that have their ‘Auto’ checkbox checked, turn them on, and take a preset photo. It will then step through all the channels one at a time and take a channel photograph for each.

-- TriggerType=Menu
-- Define Functions

Two comments; this first is a comment option for the script.
We define functions that can be called from within the script. In this script, we define a series of functions that are called at key points of the script. There are functions that are called at the start and end of the script, before and after taking a preset photo, and before and after taking a channel photo. The idea is that you would put in these functions, the actions that you would like to send to the console. This makes it easier to customise what you tell the console to do, and to also allow it to be changed to other types of console such as the MA2. You will find a lot of io.write function calls in the script. This is used for debugging purposes and allows you to see what you doing or sending to the console. You could remove them if you wanted to.

-- Adapt to get ready to take photographs for Preset and its channels
function PrePhotoSession()
io.write("Started", “\n")

In the PrePhotoSession function, we perform the actions on the console we want to happen when the script starts. We call the Moving Light Assistant function: OSC:EOS_SendNewCommandLine. The EOS_SendNewCommandLine accepts a single parameter which must be a string, which is the string sent to the console. The string is specific to the EOS console. Sending a new command line will clear anything previously on the command line. We tell it to ‘Sneak’ followed by the hash character which will tell the EOS to terminate the command.

-- Adapt to do any clean up after taking Preset and Channel photos.
function PostPhotoSession()
io.write("Finished", "\n")

We now define a function in the same way as the PrePhotoSession, but this one is named PostPhotoSession and will be called after all the photos have been taken.

-- Adapt this function to however to want to recall the preset and turn on the channels ready to take preset photograph. 
function PreTakePresetPhoto (inChannelList, inPresetID)

We now define a function that is to be called before the preset photo is taken. It is passed two parameters when it is called. inChannelList is a string containing a channel selection of all the channels to be photographed. It will look something like: "61 + 62 + 65". inPresetID is a string with the number of the preset to be photographed.

-- Select the channels.
commandLine = "Chan " .. inChannelList .. “#"

We now construct a string variable called commandLine. In LUA, variables do not need to be defined before they are used. The = is an assignment operator, meaning that the variable is assigned the value after the = sign. In this case we are assigning several items to commandLine. Anything in quotes is considered a string. So we start by assigning “Chan” to commandLine. The .. essentially means to append to the string the following item, in this case the parameter inChannelList. Finally we append to the string the hash character which tells the EOS to terminate the command. The variable will probably end up containing a string something like:

“Chan 61 + 62 + 65#”

If your were using an MA2 console you could modify the commandLine variable to build a slightly different command to suit that console:

commandLine = “Channel “ .. inChannelList .. “\r”

The “\r” is a return character which for the MA2 will terminate the command line entry.

io.write(commandLine, “\n")

We write out the value of the commandLine variable and an new line character to the output window. This is useful for debugging.


We now send the value on the commandLine variable to the EOS console via OSC as a new command line entry.

-- Recall Preset
commandLine = "Preset " .. inPresetID .. "#"
io.write(commandLine, "\n")

We now assign to the commandLine variable a new set of strings to build a command that will recall the preset specified in the inPresetID variable (the parameter passed to the function). We write out the value of the commandLine variable to the output window as before, but this time we send the commandLine variable to the console using OSC:EOS_SendCommandLine function. This version of the OSC command will extend the command on the command line as you would if you typed it on the console as opposed to starting a new command line entry which would clear the command line (and thus the channel selection). We have a wait function call to wait for one second.

-- Turn on or highlight
commandLine = "At Full#"
io.write(commandLine, "\n")

We now turn on the selected channels to photograph them. You could use highlight or simply put the channel at full. The method of creating a string variable commandLine is only to assist in debugging. You could write:

-- Turn on or highlight
OSC:EOS_SendCommandLine("At Full#")

You can customise the function PreTakePresetPhoto function to do what ever you like. You
may wish to home the channels first or recall them from a cue. The function PreTakePresetPhoto ends here.

-- Adapt to what ever you want to do after taking the Preset photo.
function PostTakePresetPhoto( inChannelList, inPresetID)
-- Turn off or un-highlight
commandLine = "At 0#"
io.write(commandLine, "\n")

Once the preset photo has been taken, the PostTakePresetPhoto function will be called. Hopefully everything in this function should make sense now. In the case here, we simply turn off the selected channels.

-- Adapt to what ever you need to do to turn on or highlight the specified channel to before the channel photo is taken.
function PreTakeChannelPhoto(inChannelNum)
commandLine = "Chan " .. inChannelNum .. " At Full#"
io.write(commandLine, "\n")

Before each channel is photographed, the function PreTakePresetPhoto is called. Note it has a single parameter inChannelNum which is a string of the channel number to be photographed. We simply build a command line entry to put the channel at full. Again, this can be modified if you wish to highlight, or do something else to turn on the channel.

-- Adapt to what ever you want to do after taking the Channel photo.
function PostTakeChannelPhoto(inChannelNum)
commandLine = "Chan " .. inChannelNum .. " At 0#"
io.write(commandLine, "\n")

Once the channel photograph has been taken, the PostTakeChannelPhoto function is called. Like the PreTakeChannelPhoto, it is passed a parameter of the channel number that has been photographed. In this case, we turn off the channel.

Now all the functions are defined we enter the main body of the script.

-- Define Variables
channelList = ""
firstChannelDone = 0
presetID = ""

We start by defining some global variables. These variables are available to the whole script from this point onwards.

The channelList variable is assigned an empty string indicated by the double set of quotes with nothing between them.

The firstChannelDone variable is assigned the numeric value 0. This is not a string, but an integer.

The presetID variable is again a string assigned as empty.

-- Lets get started

The function we defined, PrePhotoSession is now called which will run the code in the function.

-- Get the currently selected preset.
presetInfo = PresetInfo:GetSelectedPreset()

We need to get information about the currently selected preset in the preset list. We call the Moving Light Assistant function ‘PresetInfo:GetSelectedPreset()’. It will return a structure (in this case assigned to the variable presetInfo) that contains the data for the preset.

channelCount = PresetDocView:GetChannelCount()

We then need to get the number of channels in the selected preset. We call the Moving Light Assistant function ‘PresetDocView:GetChannelCount()’ which will return the number of channels displayed for the selected preset. This number is assigned to the variable channelCount.

presetID = presetInfo.PresetID

We now want to know the ID or number of the preset. The presetInfo variable which was assigned the data for the currently selected preset will contain that data. The structure contains a series of variables for the data (details of all the variables can be found on the MLA wiki).


You could access the name of the Preset with


io.write("Preset ID: ", presetInfo.PresetID, " Name: ", presetInfo.PresetName, “\n")

For debug purposes we write out to the output window some of the Preset data.

if channelCount > 0 then

We use an ‘if then else’ statement to check the channelCount variable. If the channelCount variable is greater than zero then proceed with the code following the then statement, until you reach the end statement.

-- If there are channels, then iterate through them to build a channel list string.
PresetDocView:DispatchAction("Select First Channel”)

Now we are inside the ‘if’ code block (i.e. channelCount was greater than zero). The Moving Light Assistant function PresetDocView:DispatchAction tells the Preset Documentation view to dispatch the action passed in the parameter. PresetDocView:DispatchAction takes a string as a parameter which is the action you wish to perform. Again on the Moving Light Assistant Wiki, you will find a list of the actions you can send. In the case of this line of code, you tell the Preset Documentation view to select the first channel.

channelIter = 1

while channelIter <= channelCount do

-- Get the channel number and add it to the channel list string.
channelInfo = PresetInfo:GetSelectedChannel()
channelNum = channelInfo.ChannelNumber

In much the same way we got the preset information earlier, we want to get the preset information for a channel. This time we call the PresetInfo:GetSelectedChannel Moving Light Assistant function which will assign the preset information to the channelInfo variable. Once we have the channels preset information, we can access the variable ChannelNumber from channelInfo to get the channel number and assign it to the variable channelNum.

-- Only add the channel if we are to photograph it.
if channelInfo.AutoPhotograph then

We then access the AutoPhotograph variable of the channelInfo structure to see if it is true. We use the if then statement to evaluate if it is true.

if firstChannelDone == 0 then
channelList = channelNum
firstChannelDone = 1
channelList = channelList .." + " ..channelNum

We are now inside the code that will be executed if the AutoPhotograph variable is true. We then look to see if the firstChannelDone variable is equal to 0. If the firstChannelDone variable is equal to 0 then we assign to the channelList variable the channel number. As we have handled the first channel, we then set the firstChannelDone variable to one to stop us passing through this code again when we loop again. If the firstChannelDone variable does not equal zero, then we will end up in the else block of code. We want to add the channel to the current value of the variable channelList.


This is the end of the if channelInfo.AutoPhotograph then statement.

-- Move to next channel in the list.
PresetDocView:DispatchAction("Select Next Channel")
channelIter = channelIter + 

These are the last actions in the ‘while do’ loop. We send an action to the Preset Documentation view to select the next channel. We increase the channellter variable so the ‘while do’ loop will eventually evaluate to false (the channelIter variable will be greater than the channelCount variable). We then have the end statement for the ‘while do’ loop.

At this point, channelList should contain a string of the channels in the preset that have their auto checkbox checked.

-- Prepare and take Preset photo
PreTakePresetPhoto(channelList, presetID) 

We now call the PreTakePresetPhoto function defined earlier with the channelList and PresetID variables as parameters. We then pause the script by calling the MLA function Wait. You might want to increase the wait time if you have lights that take a while to get into position.

PresetDocView:DispatchAction("Take Preset Photo")
io.write("Take Preset Photo", "\n")
PostTakePresetPhoto(channelList, presetID)

We now send an action to the Preset Documentation view telling it take a preset photo. The taken photo will be added to the currently selected preset. We will wait one second as the camera may not be instant to take a photo.

We than call the PostTakePresetPhoto function defined earlier passing the channelList and PresetID variables as parameters

-- Iterate through channels and take Channel photographs.
channelIter = 1
PresetDocView:DispatchAction("Select First Channel") 
while channelIter <= channelCount do
-- Get the channel number.
channelInfo = PresetInfo:GetSelectedChannel()
channelNum = channelInfo.ChannelNumber
-- Only take channel photo if the Auto flag is true.
if channelInfo.AutoPhotograph then
PresetDocView:DispatchAction("Take Channel Photo")
io.write("Take Preset Photo", "\n")
-- Move to next channel in the list.
PresetDocView:DispatchAction("Select Next Channel")
channelIter = channelIter + 1

Hopefully the code section above should look pretty familiar. It is similar to the code before that stepped through the channels to build the channelList variable. The difference being that we tell the Preset Documentation view to take a channel photograph, which will be added to the currently selected channel. Note the calling of the Pre and Post TakeChannelPhoto functions defined earlier.


This is the end of the if channelCount > 0 then statement.

-- We are done.

We have finished taking all the photos, so finally we call the PostPhotoSession function we defined earlier.

Was this helpful?

Yes No
You indicated this topic was not helpful to you ...
Could you please leave a comment telling us why? Thank you!
Thanks for your feedback.