How to make a "real time button"?

Is it possible?

What I am wanting to do is have a button which if I click, sends a signal. But if I hold it, sends repeated signals (at a given frequency).

Can it be done?

My basic idea I was going to do was have an inject node creating the pulse train and it is switched (enabled?) through a gate to the desired nodes.

There is a button and if I press the button the gate allows the pulses to pass. When I release the button the gate stops passing the stream.

But it won't/can't work like that.

The best can think of is to press the button once to start the flow and a second time to stop the flow. Not really life like for a press button.

Interested in feedback on how to do it.

I'm suspicious that it needs some CSS (or HTML) stuff done and when the button is pressed it sends one signal and when it is released it sends another.

But that is beyond my knowledge / skill set.

The Trigger node can be configured to send a message repeatedly until it is reset by receiving another message. That would be my starting point for this.

Having an Inject node always firing would be quite wasteful.

Yes, but the trick for me is to get the two messages sent:
one when the button is pressed and the second when it is released.

I think it is worth to try Angular directives. Something like:

<button ng-mousedown="send({payload: 'down'})" ng-mouseup="send({payload: 'up'})">button1</button>
2 Likes

Thanks so much.

Now I shall have to work out where to put that code.

In a template node? (That is 100% a guess)

Yep ! You guessed it right.

1 Like

(Gotta get lucky sometimes)

Thanks very much again.

1 Like

Nice to have in the library, maybe useful, who knows when

[{"id":"5ea18678.975138","type":"trigger","z":"d01d2553.fd9838","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"-1","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":800,"y":2290,"wires":[["61d84db7.6342f4"]]},{"id":"5c39bd09.702d84","type":"ui_template","z":"d01d2553.fd9838","group":"16fdc5e1.9ee0fa","name":"","order":7,"width":0,"height":0,"format":"<button ng-mousedown=\"send({payload: 'down'})\" ng-mouseup=\"send({payload: 'up'})\">button1</button>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":330,"y":2360,"wires":[["e6fdaafd.8f97d8","dcfb5cce.0431a"]]},{"id":"e6fdaafd.8f97d8","type":"debug","z":"d01d2553.fd9838","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":560,"y":2500,"wires":[]},{"id":"dcfb5cce.0431a","type":"switch","z":"d01d2553.fd9838","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"down","vt":"str"},{"t":"eq","v":"up","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":540,"y":2360,"wires":[["5ea18678.975138"],["8cdd0a6b.40bcd8"]]},{"id":"61d84db7.6342f4","type":"debug","z":"d01d2553.fd9838","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1050,"y":2360,"wires":[]},{"id":"8cdd0a6b.40bcd8","type":"change","z":"d01d2553.fd9838","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":710,"y":2420,"wires":[["5ea18678.975138"]]},{"id":"16fdc5e1.9ee0fa","type":"ui_group","z":"","name":"Buttons","tab":"8f57f520.e87078","order":2,"disp":false,"width":"6","collapse":false},{"id":"8f57f520.e87078","type":"ui_tab","z":"","name":"Some stuff","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

1 Like

Thanks so much for the code.

Alas, in the mean time, I worked out this:

[{"id":"8d09f358.cc5c4","type":"ui_template","z":"1d85b106.5dfcd7","group":"2452ebe2.f30164","name":"Up","order":5,"width":"2","height":"1","format":"<button ng-mousedown=\"send({payload: 'down'})\" ng-mouseup=\"send({payload: 'up'})\"><i class=\"material-icons\"> volume_up </i></button>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":140,"y":180,"wires":[["26653ac7.751afe"]]},{"id":"26653ac7.751afe","type":"trigger","z":"1d85b106.5dfcd7","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"-250","extend":false,"units":"ms","reset":"up","bytopic":"all","name":"Repeate","x":320,"y":180,"wires":[["2ccb538f.012b7c"]]},{"id":"2452ebe2.f30164","type":"ui_group","z":"","name":"Audio","tab":"39b306a2.96619a","order":1,"disp":true,"width":"5","collapse":false},{"id":"39b306a2.96619a","type":"ui_tab","z":"","name":"TV remote control","icon":"dashboard","order":45,"disabled":false,"hidden":false}]

The template node to create a button and that goes into a trigger node.
The trigger node is set so:

So when the button is pressed it gets a down payload. That starts the trigger node to spit out the message 1 and continues until I release the button and a up message is received.
The 1 is nominal. Could be anything, as the node it goes into doesn't parse the payload value.

This way negates the need for the two other nodes you show.
But thanks all the same.

It is good to see there are multiple ways of doing it, and that people are thinking of the solution/s.

1 Like

Adding some CSS to the button would make it nicer.

[{"id":"860c90c5.d5f4e","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"1a094cd1.b6b9e3","type":"ui_template","z":"860c90c5.d5f4e","group":"10cf6690.edce69","name":"Up","order":5,"width":"2","height":"1","format":"\n<style>\n.button {\n  background-color: #097479;\n  border: none;\n  color: white;\n  padding: 15px 32px;\n  text-align: center;\n  text-decoration: none;\n  display: inline-block;\n  font-size: 16px;\n  margin: 4px 2px;\n  cursor: pointer;\n  \n  box-shadow: none !important;\n  width: 100% !important;\n  height: 100% !important;\n  margin: 0px !important;\n  min-width: 0px !important;\n  min-height: 0px !important;\n  white-space: nowrap;\n  text-transform: uppercase;\n  font-weight: 500;\n  font-size: 14px;\n  \n  transition: background-color 0.1s;\n\n}\n\nbutton:hover {\n  background-color: #0b8f95;\n}\n\nbutton:active {\n  background-color: #ff0000;\n}\n\n</style>\n<button ng-mousedown=\"send({payload: 'down'})\" ng-mouseup=\"send({payload: 'up'})\"><i class=\"material-icons\"> volume_up </i></button>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":330,"y":220,"wires":[["f02c1ed8.62ed7"]]},{"id":"f02c1ed8.62ed7","type":"trigger","z":"860c90c5.d5f4e","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"-1","extend":false,"units":"s","reset":"up","bytopic":"all","name":"Repeate","x":480,"y":220,"wires":[["a59de3c1.529e1"]]},{"id":"a59de3c1.529e1","type":"debug","z":"860c90c5.d5f4e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":630,"y":220,"wires":[]},{"id":"10cf6690.edce69","type":"ui_group","z":"","name":"Audio","tab":"f46d849e.3755b8","order":1,"disp":true,"width":"5","collapse":false},{"id":"f46d849e.3755b8","type":"ui_tab","z":"","name":"TV remote control","icon":"dashboard","order":45,"disabled":false,"hidden":false}]

ANIMATED-GIF

3 Likes

That is nice. But I wasn't smart enough to do it that way.

This is how I did it:

[{"id":"197104a5.3d7463","type":"ui_button","z":"1d85b106.5dfcd7","name":"MUTE","group":"2452ebe2.f30164","order":3,"width":1,"height":1,"passthru":false,"label":"{{msg.txt}}","tooltip":"","color":"{{msg.fontclr}}","bgcolor":"{{msg.colour}}","icon":"","payload":"X","payloadType":"str","topic":"","x":310,"y":340,"wires":[["ed304bba.7c574"]]},{"id":"ed304bba.7c574","type":"function","z":"1d85b106.5dfcd7","name":"Push Button","func":"var state = context.get(\"STATE\")||0;\n\n//  Look for a !X message to get values.\nif (msg.payload != \"X\")     //Do this if the message is NOT \"X\"\n{\n    //\n    //node.warn(\"Setting up\");\n    //  Background colours first.\n    //\n    context.set(\"ABGC\", msg.colourA);\n    context.set(\"BBGC\", msg.colourB);\n    //\n    //  Now do text.\n    //\n    context.set(\"Atxt\", msg.txtA);\n    context.set(\"Btxt\", msg.txtB);\n    //\n    //  Font colours.\n    //\n    context.set(\"AFC\",msg.txtclrA);\n    context.set(\"BFC\",msg.txtclrB);\n    //\n    //  Payloads.\n    //\n    context.set(\"PayloadA\", msg.payloadA);\n    context.set(\"PayloadB\", msg.payloadB);\n    //\n    //  Topic.\n    //\n    if (msg.topicSET !== null)\n    {\n        context.set(\"Topic\",msg.topicSET);\n    } else\n    {\n        context.set(\"Topic\",\"~\");\n    }\n    msg.colour = msg.colourA;\n    msg.fontclr = msg.txtclrA;\n    msg.txt = msg.txtA;\n    return msg;\n}\n//      Now on to the real stuff.\nif (msg.payload == \"X\")\n{\n    state = (state + 1)% 2;\n    //node.warn(state);\n    context.set(\"STATE\",state);\n}\nif (state === 0)\n{\n    //  Condition A\n    msg.payload = context.get(\"PayloadA\");\n    msg.colour = context.get(\"ABGC\");\n    msg.txt = context.get(\"Atxt\");\n    msg.fontclr = context.get(\"AFC\");\n} else\n{\n    //  Condition B\n    msg.payload = context.get(\"PayloadB\");\n    msg.colour = context.get(\"BBGC\");\n    msg.txt = context.get(\"Btxt\");\n    msg.fontclr = context.get(\"BFC\");\n}\nif (context.get(\"Topic\") == \"~\")\n{\n    msg.topic = \"\";\n} else\n{\n    msg.topic = context.get(\"Topic\");\n}\nreturn msg;\n","outputs":1,"noerr":0,"x":330,"y":390,"wires":[["197104a5.3d7463","c6440709.9f329"]]},{"id":"867dfa6b.064688","type":"function","z":"1d85b106.5dfcd7","name":"Setup","func":"msg = {\n    \"colourB\": \"red\",\n    \"colourA\": \"green\",\n    \"txtB\": '<i class=\"material-icons\">volume_off</i>',\n    \"txtA\": '<i class=\"material-icons\">volume_up</i>',\n    \"txtclrA\": \"black\",\n    \"txtclrB\": \"black\",\n    \"payloadA\": 0,\n    \"payloadB\": 1,\n    \"topicSET\": \"CONTROL\"\n}\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":300,"wires":[["ed304bba.7c574"]]},{"id":"f9834de.12c233","type":"inject","z":"1d85b106.5dfcd7","name":"Setup","topic":"","payload":"foo","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"1","x":160,"y":300,"wires":[["867dfa6b.064688"]]},{"id":"2452ebe2.f30164","type":"ui_group","z":"","name":"Audio","tab":"39b306a2.96619a","order":1,"disp":true,"width":"5","collapse":false},{"id":"39b306a2.96619a","type":"ui_tab","z":"","name":"TV remote control","icon":"dashboard","order":45,"disabled":false,"hidden":false}]

(Dumb question - but that's usual for me)

SORRY!

That is the volume ADJUST button.

ARGH!

Sincerely: I'm sorry.
(Original reply left for honesty)

I'll look at it a bit more. Had a bad night's sleep and things going on.

So what is the "difference" to the code:

[{"id":"8d09f358.cc5c4","type":"ui_template","z":"1d85b106.5dfcd7","group":"2452ebe2.f30164","name":"Up","order":5,"width":"2","height":"1","format":"<button ng-mousedown=\"send({payload: 'down'})\" ng-mouseup=\"send({payload: 'up'})\"><i class=\"material-icons\"> volume_up </i></button>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":140,"y":180,"wires":[["26653ac7.751afe"]]},{"id":"2452ebe2.f30164","type":"ui_group","z":"","name":"Audio","tab":"39b306a2.96619a","order":1,"disp":true,"width":"5","collapse":false},{"id":"39b306a2.96619a","type":"ui_tab","z":"","name":"TV remote control","icon":"dashboard","order":45,"disabled":false,"hidden":false}]
Ok, it is nice. I've loaded the code. But the button doesn't *hold the colour* when muted. Nor does the icon change. So it doesn't reflect the state. I'll mess around with the code (or more likely make a mess of it) and see if I can work it out.

My rationale is that you button has a special behaviour (behavior) while pressed, so it would be a good thing to display a different background colour (color) while it is pressed. Note that I tried to simulate in the template node the style of a standard ui_button. For that purpose I copied the css properties from the standard one (except the animation part).

Ok, I get that.

But the original template code you posted seems to do that. Reply #4.

Sorry. You lost me. As I said: the first post seemed to do that.

Oh, ok. (I need glasses) Ok. The button is a bit bigger / different "size/shape".
That is because of the new lines - obviously.

I think this post is a bit redundant. But again just so we are both on the same page I'll leave it as is.

I actually don't think there is a question in here now.

Ok, this may be something "of interest":

I mentioned button size/shape just then.

This is a screen refresh with nothing done yet:
The first block has the original code you posted. The second has your newer code.
Note sizes.

Screenshot from 2020-03-03 08-14-03

Pressing a button I get this:

Screenshot from 2020-03-03 08-14-08

Note the changed size.

Now the other two buttons - same:

Screenshot from 2020-03-03 08-14-15

Screenshot from 2020-03-03 08-14-17

(Argh! Just tested with Chrome. Different happenings.)

Firefox seems to not like that and changes the button sizes.
Ok, this too was a kind of waste of time - for you.
Sorry.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.