Keyboard Shortcuts
ctrl + shift + ? :
Show all keyboard shortcuts
ctrl + g :
Navigate to a group
ctrl + shift + f :
Find
ctrl + / :
Quick actions
esc to dismiss
Likes
- Nodered-Hamradio
- Messages
Search
Re: Modifying a Stream Deck Button
Ken
?
I have attache a demo flow you can use to follow along below.
?
First, for sending images to the buttons, you must send the following object.
?
{"event":"setImage","device":"3B4A178B0FA8D7408582138E1F192969", "context":"b92505aa7b38be8abe13cb04ee0c242e", ?
"payload":{"image":"data:image/svg+xml;charset=utf8,<svg viewBox = \"0 0 72 72\" width = \"72\" height = \"72\" ><rect width=\"72\" height=\"72\" style=\"stroke: rgb(0, 0, 0); fill: red; fill-opacity: 1;\"></rect><text style=\"fill: white; font-family: Arial, sans-serif; font-size: 25px; white-space: pre; text-anchor: middle;\" x=\"36\" y=\"30\" bx:origin=\"0.5 0.479796\">Red </text><text style=\"fill: blue; font-family: Arial, sans-serif; font-size: 15px; white-space: pre; text-anchor: middle;\" x=\"36\" y=\"50\" bx:origin=\"0.5 0.479796\">On </text></svg>"}}
?
event is the action you want to command to the button, in this case, "set image". ? See the StreamDeck developer document for all the available actions.
?
context is the button identification, not to be confused with the "id" you assigned the button in the config panel. ?This number is sent when you first push the button, so that future commands from Node-Red can use this id to oommand the button. ? ?Because your button graphics are not updating, I suspect you are not using the correct context number.
?
In this case, the payload is a SVG image to build a red background and some test of various size, position, and color.
?
?
Attache is my version of the SD Flow. ?It uses the same concepts that Warren showed you, but different coding.
?
The function, ""Process Stream Deck Input" will, for each unique button id (the name you gave the button) but into Node-Red flow context the context (button) and the device numbers. ?Below is the example for the button we pushed, above. ? The "device' number can be included in the command object, if you have multiple Stream Deck devices.
?
?
{"context":"b92505aa7b38be8abe13cb04ee0c242e",
"device":"3B4A178B0FA8D7408582138E1F192969",
"id":"toggle","
server":"ws://192.168.70.38:1880/streamdeck"}
?
?
Ok, Now we have everything in flow context to use the button id to search for the correspoiding context (button) and device numbers.
?
Lets look at this flow that build a gauge. ? In this gauge, we have multiple SVC components, that can be modified to your situation:
?
?
The "Build Streamdeck Button", has pre build SVG elements, background, gauge, text one, text two, switch icon, mic icon, speaker icon, and image.
?
?
At the bottom of this function, you build the button with the SVG elements you desire, in the case of the above gauge button, the line is:
?
msg.payload = "data:image/svg+xml;charset=utf8,<svg " + view_box + defs + background + text_one + text_two + gauge + speaker_icon + "</svg>"
"data:image/svg+xml;charset=utf8,<svg " + view_box + defs + background ?>>> is boiler plant that Stream deck needs to build the SVG image.
?
"</svg>" is the end of the SVG line.
?
The desired SVG elements are added between, derived from the element variable names above. In this case, we are using text_one, text_two, gauge, and speaker_icon.
?
Now, how to add the variables to change the SVG file to make the button dynamic. See the "Button Config" function. You can hardcode any of the gauge button parameters or you can input a dynamic value from other pass of your floe
?
In this example, the msg.gauge_pixels, is derived from the msg.payload input.....note, full scale on the gauge is 72 pixels.
?
You can also control the "tick" mark on the gauge.
?
Here is the full configuration for the gauge:
// gauge full scale = 72 pixels
msg.gauge_pixels = msg.payload
msg.tick_pixels = msg.tick
msg.icon_color = "white"
msg.icon_opacity = "0.35"
msg.tick_color = "red"
msg.background_opacity = "0.5"
msg.background_color = "black"
msg.gauge_text_low = "-90"
msg.gauge_text_hi = "-10"
msg.gauge_color_low = "white"
msg.gauge_color_hi = "red"
msg.gauge_x = "10"
msg.one_text = msg.payload
msg.two_text = "Mic Level"
msg.text_one_color = "white"
msg.text_two_color = "red"
msg.font_one_size = "20px"
msg.font_two_size = "15px"
msg.text_one_anchor = "middle"
msg.text_two_anchor = "middle"
//Note: possible anchors are: start, middle, end
msg.one_x = "36"
msg.two_x = "36"
msg.one_y = "56"
msg.two_y = "68"
msg.id = "meter"
return msg;
?
OK, now we must build the object to command Stream Deck to build the button with the SVG image.
?
It is the same object we did for the simple red background image above, but it now contains the SVG elements to build the gauge button:
?
{"event":"setImage","device":"3B4A178B0FA8D7408582138E1F192969",
"context":"b1dd149bf270a96f2b25544c204dd46f",
"payload":{"image":"data:image/svg+xml;charset=utf8,<svg viewBox = \"0 0 72 72\" width = \"72\" height = \"72\" ><defs><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"linear\" x1=\"0px\" y1=\"0px\" x2=\"72px\" y2=\"8px\" gradientTransform=\"matrix(1, 0, 0, 1, 0, 0)\"><stop offset=\"0\" stop-color=\"green\"></stop><stop offset=\"0.3\" stop-color=\"#ff0\"></stop><stop offset=\"0.8\" stop-color=\"#f00\"></stop></linearGradient></defs><rect width=\"72\" height=\"72\" style=\"stroke: rgb(0, 0, 0); fill: black; fill-opacity: 0.5;\"></rect><text style=\"fill: white; font-family: Arial, sans-serif; font-size: 20px; white-space: pre; text-anchor: middle;\" x=\"36\" y=\"56\" bx:origin=\"0.5 0.479796\">25 </text><text style=\"fill: red; font-family: Arial, sans-serif; font-size: 15px; white-space: pre; text-anchor: middle;\" x=\"36\" y=\"68\" bx:origin=\"0.5 0.479796\">Mic Level </text><g transform=\"matrix(1, 0, 0, 0.995671, -0, 10)\"><title>Gauge</title><rect x=\"4\" y=\"8\" fill=\"#29ABE2\" width=\"64\" height=\"2\"></rect><rect x=\"4\" y=\"20\" fill=\"#29ABE2\" width=\"42\" heig..."}}
?
Here is the magic, You enter the "id" of the button. In our case, we entered the id as "gauge" in the StreamDeck config
?
?
?
And, on our node-red flow, for the gauge demonstration, we enter the same id name.
?
Using the button id name, the "ContextR1" uses the button name to find the corresponding button context in flow context.
?
The "Set Image" function then builds the command object to send to StreamDeck via the WS Proxy socket.
?
?
? |
Re: Modifying a Stream Deck Button
Hi All.? Warren, I got your flow to work.? The problem I was having is that I assigned a graphic to the SD buttons at design time.? I guess this does not get overridden by the output of the NR flow.? So the buttons are now what your flow output:? A solid color with the appropriate text.? Is there a way to include an image as well, say a png?? Also, I'm really confused about the "context" carried by the message.? I see that in your flow, it is pointing to the Global context variables but what information is it carrying and how is it used?? Is it just an indication of how to address a specific button?? Thanks again for you help as well as Alan's and Dave's. |
Re: Modifying a Stream Deck Button
¿ªÔÆÌåÓýAlan and I were discussing this on the phone earlier. If the equipment you are controlling (example - Antenna Genius) sends status updates or can be queried for status, then that should determine what to send to the button. ?A multistate button may not be ideal but rather send static images to the buttons based on the device¡¯s status.? The DLI Web Switch flow does just that but if you restart Node Red, you must push all eight buttons to get the button ID into context data so Node Red knows how to send websocket payload to correct button. I¡¯m going to look at how to set this context data without need to press the button.? 73 Dave wo2x Sent from my waxed string and tin cans.? On Mar 8, 2025, at 3:45?PM, Ken Kayser via groups.io <kxkayser@...> wrote:
|
Re: Modifying a Stream Deck Button
Hi Warren.? Thanks so much for taking the time to respond to my query and creating the example flow.? I have attempted to get it working in my environment but have not been successful.? I can follow most of the flow until you get into the svg nodes when I get somewhat lost.? Below is the output of the last node in the flow before the WebSocket out node.
?
This is after pressing the ant1 button.? Expanding the first object, I get:
?
However, it doesn't change the buttons on the Stream Deck.? Does this output give you an indication of what might be wrong?? What more can I supply for debugging?? Thanks again for your help.
|
Re: Modifying a Stream Deck Button
Ken,
?
How about a combination of Alan's options 2 and 3 above?
2- send images for the desired button via node-red.? This is the method Dave, WO2X demonstrated
3- send SVG formatted?commands - ?Most advanced and my preferred method.
?
Here's how I do it using Dave's concept of building an SVG graphics for a button having two lines of text
and configurable background color.? No physical SVG graphics files are needed. That's the real benefit here
as creating and modifying individual graphic files can get tedious for an antenna setup with 12 selections
and two states each.? It is easily extendable and allows quick alteration of the text and colors down the road.
?
Here is a partial flow with the meat of the logic.? It assumes you have 4 antenna buttons that need to be
ganged so when one is pressed, the all four buttons change background color to indicate active or inactive state.
?
The idea is when a button is pressed, create a function that sends out four messages to the StreamDeck, altering
the button background colors.? The button SVG (text) is instantiated in a basic form, then modified
to show the appropriate background color based on it being active or inactive.
?
When a button is pressed, you capture the buttonId (and likely filter for "keyDown" only)
?
This is the logic that sends out four messages that define the four button cap states
based on which button was just pressed. One message in, four messages out.
?
?
Here is what the "4-Button ganging logic here" function spit out if "ant1" is passed in.?
?
?
The Create Basic Button function defines the button?in a generic way
(thanks to Dave, W2OX for this concept)
A new object is created with all of the desired properties for the button.
and the input payload and topic are just tacked back on.
?
?
The next function uses the buttonId in a Case statement to override the basic properties?
to suit the button being passed in and the states we want to show a particular button as.
?
Remember, this function gets called FOUR times (one for each case) when you press a single button.
?
Here is the first of four cases in that function.? They are almost all the same except for background color.
You can alter the font size and location of the two lines of text here.
?
?
The next function (again, stolen from Dave) just builds a giant string that represents an SVG graphic.
I use another function to strip out the SVG properties, as we don't need them anymore and don't need
to pass them along.?
?
I use my own stripped down version of the SD "out" node.? You can use the SD out if you choose to.
?
The result is passed back to the StreamDeck via the WebSocket Out node.
?
?
The attached flow is not a complete working example.? You will need to wire it into your existing WebSocket nodes to communicate with the StreamDeck.
Use it as an outline to create simple button caps with two lines of text.? You could of course, extend the SVG text to have more complicated graphic elements.
I lifted this from a working solution for W4AX to control four relays on a Pi Hat.? Forgive me if I left out something important while summarizing into an example.
?
Warren, KD4Z
?
?
?
|
Re: Modifying a Stream Deck Button
On Fri, Mar 7, 2025 at 05:29 PM, Ken Kayser wrote:
Do you think this is the best way to achieve my goal or would I be better off sending the actual graphics as in Dave's solution? Ken
?
From your description, I would agree, using Dave's approach to send the image of the button from Node-Red, based on the antenna logic, would be best.
?
Using the WSProxy MultiState process is best suited for toggle situations.
?
You can use any png format image. ?I did include a folder of all my button images in the previous message. ?Those will work in Daves flow also.
?
Alan |
Re: Modifying a Stream Deck Button
Hi Alan.? Thanks for your thorough response and examples.? I've been able to use the WSMultiState button as you suggested.? I need to go a little further as I need to change the state of say all buttons on a row at one time.? My use case is a have a row of buttons that selects an active antenna from a group of 4.? I'd like to have the selected antenna show green.? When I select a different antenna, it should turn green and the previously selected antenna should be reset to it's original color.? I suppose I could accomplish this by sending all the non-selected buttons a 0 state and have the selected button assume a 1 state.? Your example shows how to change the state with node-red.? Do you think this is the best way to achieve my goal or would I be better off sending the actual graphics as in Dave's solution?? Thanks again. |
Re: Modifying a Stream Deck Button
Attached is a more advanced "WSProxy Multistate" button flow to demonstrate?configuring button graphics and to command the button?state from Node-Red. First, build your button icon using your favorite graphics program.? I have attached a zip file of all the icons I have built. ? On StreamDeck, select the multistate button.? Note there are two "states".? On the right, click on the () to "decouple" the graphics for each state.? The button below the graphic shows the state of the button?shown.? Click on the down carrot to build the button graphics. Select one of the options.? In this case, select the "Set from File" option. Build an image, png format, or select one from the attached zip file of icons I have built. Now, configure the button id and Web socket path, using the ip address of your device running node red. ? Here, I have used the id of "button_one" assuming you may have many buttyons, and the WS path can be anything?unique, I used "multistate". OK, now on the Node Red side. ? I have attached a demostration?flow that will receive the button state from StreamDeck and will command the button state to change, from Node Red. I do not use the StreamDeck node red node.? I built custom functions to do the same and found they are more reliable for commanding the MultiState web socket. Under the covers, here is the object that needs to be built to command the button state.? The context number was provided from StreamDeck to provide a link to the button you pushed.? My functions take care of all this.? Just info how the command works. {"event":"setState","context":"dff469b0fa0da24434dcf5967117c0fc","payload":{"state":"1"}} Now, back to using the demonstration?flow. We want node-red to command something when the button changes state.? The demo set up two states, a switch?icon, green and red: First, configure the id of the button in the "id" switch.? Wire in the desired KeyUp, or KeyDown switch. ? Last, wire the "Do Something" into your flow as desired to fire off a downstream node. Now, to command the WSMultiState button to change states from your Node Red flow.? Again, modify the "id" node to the id you gave to the button.? I have provided inject nodes to demo the ability to command StreamDeck to change the state of the button.? You can wire in your flow to command the button states to change by sending?a "1", or a "0". Enjoy. Alan. WA9WUD On Thu, Mar 6, 2025 at 6:26?PM Alan Blind <a.alan.blind@...> wrote:
|
Re: Modifying a Stream Deck Button
Ken There are three ways to do dynamic buttons, easy to more advanced, in order: 1- use the WSProxy MultiState StreamDeck Custom Plugin - easy and more below. 2- send images for the desired button via node-red.? This is the method Dave, WO2X demonstrated 3- send SVG formatted?commands - ?Most advanced and my preferred method. I will let Dave chime in on #2 So, about the easiest?method?#1. You said you have already used the WSProxy plug-in. ? Its companion is the WSProxy Multistate plugin. Note on the button config within the StreamDeck config page, there are two dots below the button.? Each time you push the button, it will toggle between the two button configurations. ? So, configure?each button to the desired configuration?using all the button configuration tools within SteamDeck. ? This will give you the "dynamic" effect for each push of the button, background?color, text, images. Now in Node-Red, look at the JSON for the button id. ?"msg.payload.payload.state" will toggle with each button push between "0" and "1".? This will correspond to the button configured for each state. Now in your Node-Red flow, filter ?"msg.payload.payload.state" for "0" or "1" and tie that into the desired thing you want to happen in your flow. Alan.? WA9WUD On Thu, Mar 6, 2025 at 5:34?PM Ken Kayser via <kxkayser=[email protected]> wrote:
|
Modifying a Stream Deck Button
Since the Zoom meeting hosted by Ron a few weeks ago, I've purchased a Stream Deck and had fun modifying several of my flows to use it with both the WS proxy and FRStack plugins.? So far, I have created all my buttons statically.? I'd like to take the next step and dynamically change the buttons based on my flow.? Dave gave a quick lesson on this during the Zoom but I didn't have the background to follow it then.? Can someone point me in the right direction?? Thanks in advance.? |
Re: Flex Radio Nodes
Walter, K5WH told me that Flex had indicated to him new firmware that would allow addressing multiple radios by IP address rather than just UDP broadcasts. Don't know much other than that, but sure would make life easier than now for those of us who have more than one Flexradio.?
?
Charlie KB8CR |
Re: Little Azimuth Map project
¿ªÔÆÌåÓýHelloIs there some place where you share/save projects?? Or only randomly?? Best Regards, Stein-Roar?Zamora Brobakken post@... LB3RE K3RAG LC0X Skype: lb3re.rag 3. mars 2025 kl.?23:20 skrev Ken Kayser via groups.io <kxkayser@...>:
|
Re: Little Azimuth Map project
Hi again Alan.? I wanted to thank you again for your guidance on this project.? I have successfully generated several maps using? NS6T's site and incorporating them into my multiple map rotor flow.? Interesting to see that's it's not actually the svg file that's incorporated into the svg node but rather the base64 representation.? I'm assuming that it's the svg node that allows for the clickable responses and several other properties I'm enjoying although it's still a little obscure for me.? Thanks again. |
Re: Little Azimuth Map project
I'm all set now. I downloaded Great Circle Mapper and built a new World map that I absolutely love. Now I just wish I could figure out how to make a USA grid map that has the rotor headings, but is centered on the US and not my location. That's the downfall of living way up in one of the corners. An azimuthal map doesn't really work well for this. That's a project for another day. Thanks for your help Alan.?
?
|
Re: Little Azimuth Map project
Patrick and others who what "dynamic" SVG maps.
?
In the demo, "build your own rotor map" flow, there is a section for dynamic maps. ?For your maps, you need to modify the function(s) below for each of your desired maps.
?
?
First, after you have your map image file, it needs to be converted to base 64. ?Here is a link to a web site that will do the conversion:
?
?
?
Then, you need to build the SVG string to paste into the function node. ?The string will all be within "" and will start with?
msg.payload = "data:image/png;base64,
?
then paste in the base 64 image text, no space following the comma.
?
Be sure there is a closing ", at the end of the large string.
?
Alan. WA9WUD
?
?
|
to navigate to use esc to dismiss