Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sd-output node sends "setState" instead of "setImage" #7

Open
oskapt opened this issue Jan 10, 2021 · 5 comments
Open

sd-output node sends "setState" instead of "setImage" #7

oskapt opened this issue Jan 10, 2021 · 5 comments

Comments

@oskapt
Copy link

oskapt commented Jan 10, 2021

Hello again!

I'm trying to work through the example in the README, but using the sd-input/output nodes instead. It appears that sd-output sends setState for anything with an image, but the example uses setImage. The output node doesn't work unless I use a change node afterward and convert the event field back to setImage. Bug? Something I'm missing?

@ybizeul
Copy link
Owner

ybizeul commented Jan 11, 2021

Thanks for your report.

The way it has been implemented is if Title and Image of the node configuration is empty, then it's assumed to be a state change.

The 3 lines are actually a "or" option, but I didn't figure out how to present it in a more obvious way.

Here is a sample flow to illustrate it, let me know if you think there is a bug :

[
   {
      "id":"32d6f437.d2213c",
      "type":"sd-output",
      "z":"d9237648.984d6",
      "name":"Stream Deck",
      "streamdeckID":"",
      "title":"",
      "title-type":"str",
      "image":"image",
      "image-type":"msg",
      "state":"",
      "state-type":"msg",
      "x":910,
      "y":500,
      "wires":[
         [
            "20e1dda7.2282ba"
         ]
      ]
   },
   {
      "id":"fdcc663c.76bfb",
      "type":"sd-input",
      "z":"d9237648.984d6",
      "name":"Stream Deck In",
      "x":420,
      "y":500,
      "wires":[
         [
            "cbb05c5e.2c791",
            "b204211c.10455"
         ]
      ]
   },
   {
      "id":"2bb3dfb8.02822",
      "type":"jimp-image",
      "z":"d9237648.984d6",
      "name":"",
      "data":"https://picsum.photos/144",
      "dataType":"str",
      "ret":"b64",
      "parameter1":"",
      "parameter1Type":"msg",
      "parameter2":"",
      "parameter2Type":"msg",
      "parameter3":"",
      "parameter3Type":"msg",
      "parameter4":"",
      "parameter4Type":"msg",
      "parameter5":"",
      "parameter5Type":"msg",
      "parameter6":"",
      "parameter6Type":"msg",
      "parameter7":"",
      "parameter7Type":"msg",
      "parameter8":"",
      "parameter8Type":"msg",
      "sendProperty":"image",
      "sendPropertyType":"msg",
      "parameterCount":0,
      "jimpFunction":"none",
      "selectedJimpFunction":{
         "name":"none",
         "fn":"none",
         "description":"Just loads the image.",
         "parameters":[
            
         ]
      },
      "x":770,
      "y":500,
      "wires":[
         [
            "32d6f437.d2213c"
         ]
      ]
   },
   {
      "id":"b00524f.17e97d8",
      "type":"websocket in",
      "z":"d9237648.984d6",
      "name":"",
      "server":"181cef6a.c12fc1",
      "client":"",
      "x":240,
      "y":500,
      "wires":[
         [
            "fdcc663c.76bfb"
         ]
      ]
   },
   {
      "id":"20e1dda7.2282ba",
      "type":"websocket out",
      "z":"d9237648.984d6",
      "name":"",
      "server":"181cef6a.c12fc1",
      "client":"",
      "x":1080,
      "y":500,
      "wires":[
         
      ]
   },
   {
      "id":"cbb05c5e.2c791",
      "type":"switch",
      "z":"d9237648.984d6",
      "name":"Key Up",
      "property":"payload.event",
      "propertyType":"msg",
      "rules":[
         {
            "t":"eq",
            "v":"keyUp",
            "vt":"str"
         }
      ],
      "checkall":"true",
      "repair":false,
      "outputs":1,
      "x":600,
      "y":500,
      "wires":[
         [
            "2bb3dfb8.02822"
         ]
      ]
   },
   {
      "id":"b204211c.10455",
      "type":"switch",
      "z":"d9237648.984d6",
      "name":"willAppear",
      "property":"payload.event",
      "propertyType":"msg",
      "rules":[
         {
            "t":"eq",
            "v":"willAppear",
            "vt":"str"
         }
      ],
      "checkall":"true",
      "repair":false,
      "outputs":1,
      "x":610,
      "y":540,
      "wires":[
         [
            "2bb3dfb8.02822"
         ]
      ]
   },
   {
      "id":"181cef6a.c12fc1",
      "type":"websocket-listener",
      "path":"/sd-demo1",
      "wholemsg":"false"
   }
]

@oskapt
Copy link
Author

oskapt commented Jan 12, 2021

As currently written, I can set the event type to setState and also provide a title, and it's ignored without telling me why. Is it ignored because there can only be one event type and you're limited by the Stream Deck? If so, perhaps instead of having "state" and "title" and "image" as fields, there can simply be "event" and "payload" where the payload is of the type expected by the event. That removes the confusion of having 2/3 of the available fields be ignored and should also simplify your control loop.

If you're not limited by the Stream Deck, the best case scenario is to process it on the Deck - if there's an image, set it. If there's a title, set it. If there's a state that is different than the current state set it (or just set it regardless, because it's idempotent).

Even if you are limited, perhaps you can hide that. If there are multiple fields, have the sd-output node send multiple messages. Then it truly becomes a convenience node.

@ybizeul
Copy link
Owner

ybizeul commented Jan 12, 2021

It's a good idea I think. As far as I know, a message can only carry one type of event, but I guess I could make so that multiple messages are sent if multiple fields are set.

I agree the current implementation leads to a lot of confusion and needs to be fixed :

  • Follow your suggestion, and let people set 3 parameters and set up to 3 message for each sd-output
  • Change the 3 text fields for one selection box and a text field to force the use to choose the type of event

@oskapt
Copy link
Author

oskapt commented Jan 14, 2021

As long as you clearly document what it does, either option is fine. Personally, I favor the "send multiple messages for me" option because it's less work for the user. In my live streams, for example, I have a multi-state button for muting audio. I want to change the state and also change the title to say, "MUTED." I would like to do this with a single node and a single, combined payload. If I need to update the state based on the successful completion of an action (e.g. only change to the muted image if the source is actually muted), then I would update the title and image and use a single-state button.

Any time I interact with a button, I'm going to make at least one change. If I need multiple interactions in one action, I would still like to do the same amount of work with Node-RED (e.g. configure one payload), and have the "send multiple messages" part occur transparently.

There's no direct benefit to me having to code multiple messages, other than understanding that multiple messages are being sent. A node that does that for me is my friend.

Still loving the project, btw. Last night I set it up to show and update QR codes for URLs during the stream, updating the image on the button to be the actual QR code being shown. It's accurate enough that my phone recognizes the QR code within the button and will open the URL. Out of the 27 buttons that I have configured on my Stream Deck XL for the show, 20 of them are using your project to control Streamlabs OBS via Node-RED. Thank you again for building this.

@ybizeul
Copy link
Owner

ybizeul commented Jan 14, 2021

That is great feedback !

I just had a revelation, something that I probably thought about while doing this, but forgot.

The actual behaviour is that if you have just the state specified, it'll trigger a state change event for the button.
If you have both the state and title or image it will change the image or title for that state but will not change the state of the button, the reasoning is that we're just updating informations but we want the use to be displayed that information when they push the button.

That is necessary so people can choose to update the status of the states without actually changing the state that is displayed, or, they can trigger a state change by just changing the state without setting a value.

To do what you're doing, I sometimes take a different approach, and try to configure anything that is static directly in Stream Deck, like the title or an icon that represents a state. I set both states in Stream Deck, and then handle the keyup event and if flip the state in the answer, leaving to Stream Deck to change icon and test.

The documentation is actually clear about this, as long as you understand Stream Deck SDK, which I shouldn't assume users do

If the configuration specifies only State, then a SetState event is sent.

If State is configured as well as Title or Image then the configured State will be set in payload.state in the event

Not a silver bullet, but just some thoughts to consider when redesigning this, which I will !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants