Set StreamDeck Image by Algorithm?

The Stream_Deck_Set_Image action is fantastic. Is it possible to use a variable (efficiently) to specify which icon is used? I saw an @Web option…can anyone clear up what that method would be, and how time-efficient it is?

Thank you, all.

I don't have that device, so I'm not speaking with authority, but may I ask, are you asking if KM can automatically change the Stream Deck Icon whenever you change the variable? If so, no, there are no triggers to take actions when variables change. You have to use macros to cause things to happen.

1 Like

Hmm.. I don't even see the @Web option. The only thing I can think of is using a switch/case chain to set various pre-defined images based on the value of a variable.

1 Like

Thank you, @Sleepy - based on everyone's collective advice, I'm writing an Action. Wish me luck! :joy:

You're right, @devoy, I was mistaken.

I use a Stream Deck daily and have written a LOT of macros that interface with it. Could you be a little more specific what you’re trying to do? I might be able to help if you haven't figured it out already.


Hi @cdthomer,

Below is more information. I sincerely appreciate any help from anyone on this. (Details are under the triangle widget.)

Based on a set of changing variables, set the icons for StreamDeck Buttons. This is a real-time operation.

Based on incoming MIDI CC Packets, the value of each packet, and the state of a global KM variables for each StreamDeck button—pass an icon from KM to set a specific StreamDeck button icon. This happens for every StreamDeck button, in real-time.

Project Status
I wrote a bunch of macros. Everything works. The buttons are updated quickly enough.

My problem
Too much code.


Note: I've highlighted references to my variables for clarity. (Hopefully.)


  • Two StreamDecks totalling 47 buttons.
  • Each button has three possible states.
  • Each button state has 14 possible values.
  • Every button is updated in real-time.
  • The frame-rate is approximately 15 frames/second.


  • We don't need (or expect) all the incoming data.
  • The frame-rate of individual buttons can dip.

Current Implementation
The incoming MIDI CC Number determines which button is updated. The global state value of that button determines what type of icon is used. The value of the incoming MIDI CC Number determines the colour (value) of the icon.

Every icon has a dedicated Macro. These Macros have no content; they simply have a unique icon assigned to them in KeyboardMaestro. (84 Macros; "Icon Macros")

The Macro for a specific MIDI CC number is Triggered. There are 47 incoming possible =MIDI CC numbers, corresponding to the 47 StreamDeck buttons. (Code Bloat: 47 Macros; "Trigger Macros")
Perform a Calculation to determine the button row and column.
Build the Token representing the String containing the button ID (e.g. "R1C3").
Determine which icon should be assigned, based on every possible combination of button State and MIDI CC value. (Code Bloat: 84 conditional statements in each Trigger Macro.)
Call KeyboardMaestro's StreamDeckSetImage action, specifying which icon to use by specifying which IconMacro to reference.

My Solutions that Don't Work

Too Many Trigger Macros
Have just one Trigger Macro that is called whenever a new MIDI Control Number packet enters the KeyboardMaestro Engine.

Problem: In my testing, the execution time is much faster using separate Macros.

Too Many Conditionals
Don't use them. Instead, add the SetIcon action to each of the IconMacros. Then, in the TriggerMacro, use a function pointer reference (or equivalent) to the appropriate TriggerIcon.

An example implementation would be constructing the IconMacro name based on the MIDI CC value and Button State.

Another possible implementation is to create a list of all 84 IconMacros in AppleScript, and then reference the correct one based onMIDI CC value and Button State.

Problem: Using raw AppleScript within a KeyboardMaestro requires sending to, and receiving information from, the KeyboardMaestro Engine. (E.g. "tell application "KeyboardMaestro"). This is too slow. (There's too much overhead—neither AppleScript nor Keyboard Maestro is designed for real-time operations like this.)

Another Idea: Write a KeyboardMaestro Action. This is AppleScript, of course, but it's potentially more efficient for this to be compiled a reusable component. And because we're already inside the KeyboardMaestro Engine, we don't need to call KeyboardMaestro as an external application (e.g. "tell KeyBoard Maestro"). The internal action can simply reference the variables and Macros from my TriggerMacro, directly. Because we're in AppleScript for the Action, we an use AppleScript's ability to dynamically call functions (i.e. handler).

Thank you, Kindly, for anyone who's read this far. :sob: :sob: :sob:

Sincerely, Bill