Posts by hepi


    I wrote support and here is what they answered:

    unfortunately, the whole grandMA3 Lua API is not very well documented (officially) at the moment. I will ask our TechDoc department about their future plans on this.

    In the meantime, you can get a full overview of all available functions for the current software version if you run HelpLua in the command line. This will output a text file "grandMA3_lua_functions" to your gma3_library folder. Of course, this does not replace a proper documentation, but it gives you a list of all functions with arguments, return values and data types.


    I noticed that ToAddr and FromAddr functions are not symmetrical.

    Form example, when running this plugin:

    return function()
        local app = Root()["ShowData"]["Appearances"]["Fixture"]
        local addr = ToAddr(app)
        Printf("ToAddr = " .. addr)
        local fromAddr = FromAddr(addr)
        Printf(" " ..

    I get an error:

    Anyone knows the correct syntax that FromAddr() is expecting?


    I tried setting the Layout Element's "AssignType" and "ID" properties but It seems they can't be change this way( think they are READ-ONLY.)

    (TypeScript Snippet that doesn't work)

    const elm: Element = layout.Append("Element")
    elm.AssignType = Enums.AssignType.Macro = 1


    Is there a LUA Object-API function that does what the "Assign" command does?
    I am trying to assign a macro to a layout (create a layout element)

    I specifically DO NOT want to use the command-line syntax (using Cmd("Assign ....")),
    because I don't want it to be included in the undo stack.

    Is there a way to issue CommandLine commands but have them excluded from the undo stack (Meaning that pressing "Oops" doesn't undo them)


    Hi ALL !

    Can we ask for documentation please for the Object API.

    Does anyone have direct contact with MA Lighting?
    What are they saying about this lack of documentation ??

    Here is a list of all the known functions (not documented), in TypeScript definition

    This simple plugin (which uses an undo block) causes a crash when it is "Oops"-ed

    return function()
      local undo = CreateUndo("MyAction")
      Cmd("Delete Layout 1000.1", undo)
      Cmd("Assign Macro 1000 At Layout 1000", undo)

    How to reproducing the crash

    (MA3 1.8.8, 1.8.1)

    1. Define a plugin with the above code

    2. Run these commands:

    Store Layout 1000
    Store Macro 1000
    Assign Macro 1000 At Layout 1000

    3. Run the plugin once

    4. Hit the "oops" button

    5. Run the plugin again


    Enjoy :)


    My plugin has internal state, which is stored in a PluginVariable.
    The "SetVar" Lua function has no "undo" argument. (AFIK)
    And when the user presses "Oops" , these variable value is not changed back.

    Suggested Solution:

    I think the there should be a way to listen for "Oops" events on specific undo handles.
    Something like this:

    function onUndo(undoName)
       Echo(undoName .. " was reverted"
    local undo = CreateUndo("MyAction 1")
    Cmd("Store something", undo)


    Since I don't believe this already exists, we need to submit a feature request for it.
    In the meantime, I can think of a workaround (didn't try it yet)

    I can create a dummy Sequence, and for each undo block that I create I can add a cue to that sequence, and I register a hook on this sequence.
    Then when the user Oops's, the cue would be deleted, and my hook would get called.

    Does that sound like a decent workaround?


    My plugin generates many appearances for it's UI layouts.
    These appearance are of no interest to the user.

    I am trying to avoid them from being seen in the "Select Appearance" dialog:

    I thought about putting them in a different DataPool, but it seems that Appearances are NOT part of the DataPool.
    They are also not part of the User Profile.
    So I guess they are global (right?)

    Any ideas on how to achieve this?


    I am trying to figure out if it is possible to modify system menus, and add features.
    For example, I want to add a custom selection value to the "Group Pool Setting" window.

    I was able to add the UI SwipeButton element, but modifying this file:
    /Users/[your user]/MALightingTechnology/gma3_1.8.1/shared/resource/lib_menus/ui/window_context/context_group_pool.uixml

    But I can't define the values for this SwipeButton,
    and I can find how to listen for changes in it's values.

    Does anyone have any idea about this subject.
    It's not really plugin development, I guess it's kind of a hack...


    I don't know when the "Execute" function is being run.
    I put a "Printf" in it but I never see it being printed. (Only the Main and Cleanup are called)

    How do you make the Execute function to be called?

    Now, I was digging into MA3 lua code which can be found, for example, here:
    /Users/[your user]/MALightingTechnology/gma3_1.8.1/shared/resource/lib_menus/ui/window_add/add_window.lua

    And I see the signalTable being used as an event listener.
    I was able to add a "Printf" in this function:
    (line 15 of add_window.lua)

    signalTable.AddWindowLoaded = function(caller, status, creator)

    I restarted MA3,
    and when I click on an empty screen space, and the "Add Window" dialog appeared, I saw my debug line begin printed.

    I am not sure this is relevant for Plugin development though.
    I hope there might be an event like, "OnPluginLoaded" or something that will replace the need for a StartupMacro.
    But there is no documentation about that.
    And dumping the signalTable, yields nothing.

    local pluginName = select(1,...);
    local componentName = select(2,...);
    local signalTable = select(3,...);
    local my_handle = select(4,...);


    - pluginName: is the plugin name which is the plugin's object name int the Plugins pool. Note that it can be change by the user, and your LUA code will NOT be aware of it !

    - componentName: is the plugin's component's name. A plan may have several component, each having an index and name. When you click a plugin object in the plugins pool, it always runs the first component. You can run other components directly using the "Plugin" command, e.g. "Plugin 3.1" runs component 3 of plugin with index 1.

    - signalTable: I don't know yet, but I guess it is some kind of object that you can put event listeners on, and listen to system events. I see it in use in the built in menus.

    - my_handle: This is the plugin's object handle (UserData). you need this when you register hooks.

    There is an execute_example.lua file under:

    This plugin returns:

    return Main,Cleanup,Execute

    I am curious about the Execute function.

    It is defined as such:

    -- ****************************************************************
    -- plugin execute entry point
    -- ****************************************************************

    local function Execute(Type,...)
    E("Execute-Example: Execute called")
    local func=signalTable[Type];
    if(func) then
    local debug_text=string.format("Execute %s not supported",Type);

    function signalTable:Key(Status,Source,Profile,Token)
    local debug_text=F("Execute Key (%s) %s UserProfile %d : %s",Status,Source,Profile,Token);

    function signalTable:Fader(Status,Source,Profile,Token,Value)
    local debug_text=F("Execute Fader (%s) %s UserProfile %d : %s %f",Status,Source,Profile,Token,Value);

    I don't really understand it yet.
    I don't understand what the signalTable is.
    But the interesting part is the "signalTable:Fader",
    could there be a way to listen to fader movement?

    Any information about this signalTable would be appreciated 🙏