Posts by hepi



    I am trying to write a plugin for controlling the encoders with MIDI.

    The console does not support Relative MIDI messages,
    for example one of the relative standards specifies that midi value 65 means +1, and midi value 63 means -1.

    I wish I could get the raw MIDI value straight to my Plugin, any way of doing that?

    I thought to try using the MIDI remotes to add a line for each value , that will call a different macro.
    So one line for the value 63, and another for the value 65 of the same MIDI channel & index.

    It seems impossible.

    The In & Out ranges are only for mapping range values to a fader.
    The Trigger On/Off is not suitable since if I put Trigger ON at 63 it catch both 63 and 65.

    Any ideas?

    Other Solutions

    1) I could use an external MIDI adapter app to change the MIDI controller's messages to they use different MIDI index. Or even convert them to different OSC messages.

    2) I can think of a devilish HACK, using Trigger ON, and assuming that ALL matching macro lines are called before the next MIDI massage is handled. But I'd rather have a proper solution.


    1) I didn't know aboutReloadUI, thanks.
    2)I guess If I add a hook to the ShowData object, I could get notified when a show is loaded. I didn't try it. I wish there was an explicit API for a load-show event. (And I wish there was a StartMacro, or some event when the system starts (or a show is loaded)
    3) Do you work for MA Lighting? How do you know all this stuff?

    Danger Zone !

    I try to avoid (or minimise) my use of globals, they are dangerous.

    For example (and I think it's an MA bug),
    when you load another show, your global objects remain !! This is bad !!

    At least if you do use globals, then a single table variable is a good idea,

    and you should give it a very unique name.
    Be sure to include:
    - plugin author

    - plugin name
    - plugin version (be careful with that)

    - maybe even the ShowFile name, to workaround the MA bug mentioned before)

    I use this property name for global variable ids:

    Development Drawback

    When using Globals objects, usually a Singleton (A single object), then you check if your global exists and if not then you create it.
    This means that during development, when you run ReloadPlugins, it also does NOT reset your globals,

    and you in some case need to restart MA3, or use another plugin to delete you globals intentionally.

    That will be nice to see.
    My plugin infrastructure library is a beast. it's big, and complicated.
    Thus not ready for sharing yet, since it needs to mature more with time.
    But I've been inspired to share parts of it, reference at least.

    Will do it soon.

    TypeScript Types

    I wanted to figure out :

    How many people here develop MA3 plugins with TypeScript?

    I am developing in TypeScript, and I am maintaining this grandMA3-types library (a fork of LightYourWay).

    If you are interested in collaborating in maintaining this library,
    please write me here.
    If there are enough developers actively developing in TypeScript (at least 3-4) ,
    then I suggest we collaborate maintain and share a single library for this.

    So if you are one of those,
    write it here.


    Unfortunately I also couldn't find a way.
    You could use Set attribute command with relative values (e.g. +1,-1),
    it works.
    But it's not the same as emulating the encoder rotation,
    since you need to know exactly what attribute you want to change.

    I am guessing it's possible to do it with the Mouse() function,

    if the encoder toolbar is visible.
    You can use GraphicsRoot to find the coordinates of the encoder,

    and use Mouse function to "press", "move" "release".

    I didn't try it yet.
    Let us know if it works for you.

    Hack to Call your plugin with an object address as argument

    Clintos About your original question, of interacting with the CommandLine.
    I can't beat Andreas answer, but I found a little hack that might be useful in some cases.

    If you define a Macro with this command:

    Plugin 1 "

    Notice that the opening quote is not closed !

    And set the Macro settings:
    - AddToCmdLine = Yes

    - Execute = No

    When after you run the macro, you could click on any object/executor etc...
    And your Plugin will receive the object's address as an argument.

    This is handy if you want to call your plugin with an object address that is selected by the user via the GUI (and not with a popup dialog).

    Hope it helps.

    Hi Hoss,

    I used your Wiki at the beginning, thanks you for that.
    But stopped after a while.
    Most of what I was looking for was missing (Object-API specifically)

    I started documenting the Object-API in the form of TypeScript types
    (Since I am developing plugins in TypeScript)

    You can find it here (It's a fork):

    I also wrote some general documentation about using and developing Plugins.
    I can share that with you.

    You are welcome to contact me at: hepi [AT] ma3-pro-plugins [dot] com
    And we might collaborate on this.

    I think hooks work only for changes in the data model.

    And an executor's fader value is not in the model.
    You get the fader value by calling a function on the executor:


    You I think you can't hook it. (But I didn't try it yet)

    1) You can have a macro that when you run it, it will update the Temp fader's value according to the current speed master's value.
    3) You can poll the SpeedMaster value, every second (using the Timer() function), and update the Temp fader's value.
    2) You can use some external OSC app, that listens for speedster changes, and sends back a Command that sets the Temp fader's value.

    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)