Have node-red sit there and wait for a sequence

237 views
Skip to first unread message

Dan Hoover

unread,
Mar 4, 2017, 12:05:01 PM3/4/17
to Node-RED
Everyone has been really good about helping and not making fun as I've fumbled my way through node-red.  I've made a ton of progress, but I still have some gaps.  I'm trying to write a function where basically node red just sits there and waits for the right sequence of messages to pass through it.  In this case (for simplicity) 231.  Then I'd like it to fire off something, anything when it receives that order. I've toyed with a few things but my javascript is failing me.  

I basically have 3 buttons, passing in 1 2 or 3
var newMsg = { payload: msg.payload.length };
newMsg.payload = "1";
return newMsg;

Then I'm trying to parse that, but I don't really know how to get it to hang on to a sort of "buffer" if the data that's flown through my function.  

My feeble attempt at a function looks like this...
var gotIt = { payload: msg.payload.length };
//sequence is 231
sequence = {
 check : function(e){
  sequence.value += this.textContent;
   if (sequence.value == sequence.sequence)
     {
       gotIt.payload = "Got It";
       sequence.value = "";
     }else{
        gotIt.payload = ""; 
     }
   }, 
  value : "",
  sequence : "231"
}
return gotIt;

Again, I'm pretty sure I'm failing at not understanding how the whole buffer concept works.  Any point in the right direction would be really helpful.


[{"id":"d8fbd570.94b8b8","type":"function","z":"45e5bebc.e6cbd","name":"GLOBAL","func":"global.set(\"gotIt\",\"0\");  \nreturn msg;","outputs":1,"noerr":0,"x":361.2000274658203,"y":376.2000274658203,"wires":[["bd43250a.f109b8","64f5efd0.b54f4"]]},{"id":"a9c88b9f.757228","type":"inject","z":"45e5bebc.e6cbd","name":"Button 1","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":126.19999694824219,"y":456.20001220703125,"wires":[["5316cf1f.badc9"]]},{"id":"5316cf1f.badc9","type":"function","z":"45e5bebc.e6cbd","name":"Trigger 1","func":"var newMsg = { payload: msg.payload.length };\nnewMsg.payload = \"1\";\nreturn newMsg;\n\n\n","outputs":1,"noerr":0,"x":315.5,"y":456.8000030517578,"wires":[["bd43250a.f109b8"]]},{"id":"34a9a447.9d0ccc","type":"inject","z":"45e5bebc.e6cbd","name":"SetGlobal","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":128.5,"y":376.8000030517578,"wires":[["d8fbd570.94b8b8"]]},{"id":"64f5efd0.b54f4","type":"debug","z":"45e5bebc.e6cbd","name":"","active":true,"console":"false","complete":"false","x":900.4999542236328,"y":384.8000030517578,"wires":[]},{"id":"7cc7ff6a.99218","type":"inject","z":"45e5bebc.e6cbd","name":"Button 2","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":128.1999969482422,"y":534.2000122070312,"wires":[["a35a1e08.a2601"]]},{"id":"a35a1e08.a2601","type":"function","z":"45e5bebc.e6cbd","name":"Trigger 2","func":"var newMsg = { payload: msg.payload.length };\nnewMsg.payload = \"2\";\nreturn newMsg;\n\n\n","outputs":1,"noerr":0,"x":317.5,"y":534.8000030517578,"wires":[["bd43250a.f109b8"]]},{"id":"f49771e2.9fb79","type":"inject","z":"45e5bebc.e6cbd","name":"Button 3","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":128.1999969482422,"y":616.2000122070312,"wires":[["df2bcb25.817208"]]},{"id":"df2bcb25.817208","type":"function","z":"45e5bebc.e6cbd","name":"Trigger 3","func":"var newMsg = { payload: msg.payload.length };\nnewMsg.payload = \"3\";\nreturn newMsg;\n\n\n","outputs":1,"noerr":0,"x":317.5,"y":616.8000030517578,"wires":[["bd43250a.f109b8"]]},{"id":"bd43250a.f109b8","type":"function","z":"45e5bebc.e6cbd","name":"Sequencer","func":"var gotIt = { payload: msg.payload.length };\n//sequence is 231\n\nsequence = {\n  \n check : function(e){\n  sequence.value += this.textContent;\n \n   if (sequence.value == sequence.sequence)\n     {\n       gotIt.payload = \"Got It\";\n       sequence.value = \"\";\n     }else{\n        gotIt.payload = \"\"; \n     }\n   }, \n \n  value : \"\",\n  sequence : \"231\"\n\n}\n\n\n\n//end\nreturn gotIt;","outputs":1,"noerr":0,"x":598.4999847412109,"y":531.6000213623047,"wires":[["adb4b171.0727b"]]},{"id":"adb4b171.0727b","type":"debug","z":"45e5bebc.e6cbd","name":"","active":true,"console":"false","complete":"false","x":873.4999847412109,"y":527.8000335693359,"wires":[]}]

Zenofmud

unread,
Mar 4, 2017, 1:23:52 PM3/4/17
to node...@googlegroups.com
Here is how I would do it.

[{"id":"155083e8.f9d304","type":"function","z":"404c1bdf.8d2e94","name":"GLOBAL","func":"global.set(\"validseq\",\"231\"); \nglobal.set(\"inputseq\",\"999\"); \nreturn msg;","outputs":1,"noerr":0,"x":394,"y":245,"wires":[["f453eff9.9757c8"]]},{"id":"152736bc.e12ea1","type":"inject","z":"404c1bdf.8d2e94","name":"Button 1","topic":"","payload":"1","payloadType":"str","repeat":"","crontab":"","once":false,"x":120.99996948242188,"y":306,"wires":[["92262418.67933","be53cb93.e0e7e"]]},{"id":"95e1361b.708408","type":"inject","z":"404c1bdf.8d2e94","name":"SetGlobal","topic":"","payload":"312","payloadType":"num","repeat":"","crontab":"","once":false,"x":130.2999725341797,"y":242.5999755859375,"wires":[["155083e8.f9d304"]]},{"id":"f453eff9.9757c8","type":"debug","z":"404c1bdf.8d2e94","name":"","active":true,"console":"false","complete":"true","x":625.2999267578125,"y":246.5999755859375,"wires":[]},{"id":"4d41822d.f4c904","type":"inject","z":"404c1bdf.8d2e94","name":"Button 2","topic":"","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"x":118.99996948242188,"y":381,"wires":[["92262418.67933"]]},{"id":"219c330b.b6c0fc","type":"inject","z":"404c1bdf.8d2e94","name":"Button 3","topic":"","payload":"3","payloadType":"str","repeat":"","crontab":"","once":false,"x":118.99996948242188,"y":446,"wires":[["92262418.67933"]]},{"id":"92262418.67933","type":"function","z":"404c1bdf.8d2e94","name":"Sequencer","func":"var newMsg = { payload: msg.payload.length };\n\nvar validseq = global.get(\"validseq\"); \n\nvar inseq = global.get(\"inputseq\"); \nnode.warn(inseq);\n\n//sequence is 231\ninseq = inseq.concat(msg.payload);\nnode.warn(inseq);\nif (inseq.endsWith.validseq)\n {\n newMsg.payload = \"Got It\";\n } else {\n newMsg.payload = \"no match\"; \n }\nvar newseq = inseq.substring(1);\nnode.warn(newseq);\nglobal.set(\"inputseq\",newseq); \n\nreturn newMsg;","outputs":1,"noerr":0,"x":433.29998779296875,"y":388.3999938964844,"wires":[["6b88a8ae.c74a28"]]},{"id":"6b88a8ae.c74a28","type":"debug","z":"404c1bdf.8d2e94","name":"","active":true,"console":"false","complete":"true","x":624.2999877929688,"y":387.6000061035156,"wires":[]},{"id":"be53cb93.e0e7e","type":"debug","z":"404c1bdf.8d2e94","name":"","active":true,"console":"false","complete":"false","x":647,"y":320,"wires":[]}]
> On Mar 4, 2017, at 12:05 PM, Dan Hoover <mud...@gmail.com> wrote:
>

Dan Hoover

unread,
Mar 4, 2017, 1:31:51 PM3/4/17
to Node-RED
I think you're definitely on the right track.  I never would have thought of that approach. My only issue is that I can never get the "Got it" message to fire.  Is there something I'm missing?  I would assume you hit the global and then 231 and it should fire, right? I keep getting no match.

Dan Hoover

unread,
Mar 4, 2017, 1:35:18 PM3/4/17
to Node-RED

This is what I'm seeing.  

Zenofmud

unread,
Mar 4, 2017, 1:39:02 PM3/4/17
to node...@googlegroups.com
if you press the inputs in the sequence  2 3 1 it should give you the ‘gotit’. If you press 2,2,2,3,1,2,3,1 you will get the ‘got it when you hit the last 2,3,1 sequence. The code just keeps adding the last button pressed to the global string and saving the last three digits of it.

-- 
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
--- 
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/8cbeadd3-63e9-4fad-868c-c2cbf34c3c83%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Zenofmud

unread,
Mar 4, 2017, 1:42:11 PM3/4/17
to node...@googlegroups.com
Here is what I see:

Dan Hoover

unread,
Mar 4, 2017, 1:45:26 PM3/4/17
to Node-RED

That's so weird. This is why JavaScript and I don't get along. This is what I'm seeing.  I appreciate your time SOOO much. This logic is going to help me a ton.

Zenofmud

unread,
Mar 4, 2017, 1:47:09 PM3/4/17
to node...@googlegroups.com
OHH, now this is interesting. I did the original on my Mac and just tried it on a Pi and it doesn’t work!! Hmmmm, got to see what is different.

On Mar 4, 2017, at 1:42 PM, Zenofmud <zeno...@zenofmud.org> wrote:

Here is what I see:

<gottit.png>

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Dan Hoover

unread,
Mar 4, 2017, 1:50:05 PM3/4/17
to Node-RED
Wow. Hmm. That's interesting.  I need to run to a meeting, but I appreciate your help so much. I have about 10 uses for this logic at our camp and I was pulling my hair out with about 10 different angles at trying to make something like this work.

Zenofmud

unread,
Mar 4, 2017, 2:06:13 PM3/4/17
to node...@googlegroups.com
Replace the sequence logic with this which works on the pi

//——————————————————————
// setup newMsg
var newMsg = { payload: msg.payload.length };

// grab the globals
var validseq = global.get("validseq");  
var inseq    = global.get("inputseq");  

add msg.payload to end of inseq
inseq = inseq.concat(msg.payload);

// grab only the last 3 characters of inseq
newinseq = inseq.substr(1);

//compare the new sequence to the valid sequence
if (newinseq == validseq)
    {
        newMsg.payload = "Got It";
    } else {
        newMsg.payload = "no match"; 
    }

Store the current input sequence into the global
global.set("inputseq",newseq);  

return newMsg;
//——————————————————————

Zenofmud

unread,
Mar 4, 2017, 2:11:55 PM3/4/17
to node...@googlegroups.com
oops, I hate it when I try to pretty something up in a text editor and don’t check it for errors - the previous will toss an error (1) incorrect variable name and (2) comment lines missing a ‘//‘ at the beginning. Use this instead:

//——————————————————————
// setup newMsg
var newMsg = { payload: msg.payload.length };

// grab the globals
var validseq = global.get("validseq");  
var inseq    = global.get("inputseq");  

//add msg.payload to end of inseq
inseq = inseq.concat(msg.payload);

// grab only the last 3 characters of inseq
newinseq = inseq.substr(1);

//compare the new sequence to the valid sequence
if (newinseq == validseq)
    {
        newMsg.payload = "Got It";
    } else {
        newMsg.payload = "no match"; 
    }

//Store the current input sequence into the global
global.set("inputseq",newinseq);  

return newMsg;
//——————————————————————

Julian Knight

unread,
Mar 4, 2017, 2:35:53 PM3/4/17
to Node-RED
Still an error there I'm afraid, you haven't declared newinseq

Zenofmud

unread,
Mar 4, 2017, 2:49:59 PM3/4/17
to node...@googlegroups.com
Ok, here is the latest and this is working and shortened. The original problem was that the current line:
if (inseq.endsWith(global.get("validseq")))
was
if (inseq.endsWith.validseq)
but should have been
if (inseq.endsWith(validseq))
blasted computers and syntax !#$! (grin)

Here is the working function

//——————————————————————
// setup newMsg
var newMsg = { payload: msg.payload.length };

// grab the global
var inseq = global.get("inputseq");  

//add msg.payload to end of inseq
inseq = inseq.concat(msg.payload);

//compare the new sequence to the valid sequence
if (inseq.endsWith(global.get("validseq")))
    {
        newMsg.payload = "Got It";
    } else {
        newMsg.payload = "no match"; 
    }

//Store the last 3 chars of inseq into the global
global.set("inputseq",inseq.substring(1));  

return newMsg;
//——————————————————————

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Dan Hoover

unread,
Mar 4, 2017, 3:40:54 PM3/4/17
to Node-RED
Paul! I came back from my meeting and you solved all my problems! I cannot thank you enough. You are absolutely awesome.  

I'm a PHP dev but I do very little in js and my brain just  doesn't think that way. This is SO helpful to have this script to serve as a template. Thank you. Thank you. Thank you!

Dan Hoover

unread,
Mar 4, 2017, 4:17:21 PM3/4/17
to Node-RED
I'm still struggling with how to generate this string as a random number between 1 and 3. I don't feel like it should be this hard.  I need to be able to generate that 3 button sequence randomly and see what it is.  

//global.set("validseq","231");  
var a = Math.floor(Math.random() * 3) + 1;    
var b = Math.floor(Math.random() * 3) + 1;
var c = Math.floor(Math.random() * 3) + 1;
var seq = a+b+c;
global.set("validseq",seq);  
global.set("inputseq","999"); 
var newMsg = global.get("validseq"); 
return newMsg;

Dan Hoover

unread,
Mar 4, 2017, 4:23:01 PM3/4/17
to Node-RED
I'm getting it. I just need to figure out how to concatenate those variables without adding them :)

Dan Hoover

unread,
Mar 4, 2017, 4:27:41 PM3/4/17
to Node-RED
For those following. I got it.  JS concatenation is weird. 

var newMsg = { payload: msg.payload };
//global.set("validseq","231");  
var a = Math.floor(Math.random() * 3) + 1;    
var b = Math.floor(Math.random() * 3) + 1;
var c = Math.floor(Math.random() * 3) + 1;
var seq = a+ ""+ b+ ""+ c;
global.set("validseq",seq);  
global.set("inputseq","999"); 
newMsg.payload = seq;
return newMsg; 

Colin Law

unread,
Mar 4, 2017, 4:34:31 PM3/4/17
to node...@googlegroups.com
It is not really wierd. a b and c are numbers so not surprisingly if you say
1+2+3 you get 6. You would think it odd if adding up numbers gave you
anything else. By inserting a string you are forcing it to convert the
numbers to characters so the + operator becomes string concatenation.
It will also do what you want if you do
"" + a + b + c
as then you are starting with a (empty) string and concatenating the
digits to that.

Colin
> --
> http://nodered.org
>
> Join us on Slack to continue the conversation: http://nodered.org/slack
> ---
> You received this message because you are subscribed to the Google Groups
> "Node-RED" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to node-red+u...@googlegroups.com.
> To post to this group, send email to node...@googlegroups.com.
> Visit this group at https://groups.google.com/group/node-red.
> To view this discussion on the web, visit
> https://groups.google.com/d/msgid/node-red/217e8ccb-1f83-4463-9660-5debcadba12c%40googlegroups.com.

Dan Hoover

unread,
Mar 5, 2017, 9:14:19 AM3/5/17
to Node-RED
I guess it's not "weird" that a plus sign would add. It's weird to use a plus sign for concatenation.  Different languages have different rules and I'm just learning to think in Javascript. Thanks again so much for your help.  This really helps me with several things I'm working on. 

steve rickus

unread,
Mar 5, 2017, 6:59:47 PM3/5/17
to Node-RED
Another way to do this, and avoid using javascript altogether, is to install Dave's fine data-generator node. It's a core node that is not installed by default with the standard package. I use it all the time to generate data objects, and random (but within defined limits) numbers and strings.

The template you can use to generate a string of three integers (1-3) looks like this:
{{int 1 3}}{{int 1 3}}{{int 1 3}}

Set the output type to "string", inject any value, and you get a new random three-digit code...

Dan Hoover

unread,
Mar 9, 2017, 7:36:40 PM3/9/17
to Node-RED
That is fantastic! Thank you so much for that!
Reply all
Reply to author
Forward
0 new messages