Concatenate numbers since digits from keyboard

Hello,
I am a nubee and I would use Node-red to automate some actions and to do this I would need to reconstruct in node-red an entry made on my numeric keyboard: When I enter "1", then "3" less than a second later, then "7" less than a second later, the payload should be "137".
If the delay of one second is exceeded, it restarts from the last entry.
The result can contain one, two or three digits.

I searched the forums, searched on google, tested a large number of nodes but I can't. Since I don't know how to code at all, I can't create the function that would perform this task.
Can anyone help me ?

So if you enter "1" and wait for > 1 second - should "1" be sent on?

Yes that's right.
If I enter "1" and wait more than a second I receive "1" and ... if I enter "1" then "2" less than a second later, I would like to receive "12".
Thank you for your interest in my subject!

You'll need to install node-red-contrib-queue-gate but this should do the job

[{"id":"3b401585.8c5b9a","type":"inject","z":"74793280.1ddf9c","name":"","topic":"","payload":"1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":100,"wires":[["499c2aa3.fe6fd4"]]},{"id":"b28cf793.7e3ce8","type":"inject","z":"74793280.1ddf9c","name":"","topic":"","payload":"7","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":220,"wires":[["499c2aa3.fe6fd4"]]},{"id":"d4834b6c.269188","type":"inject","z":"74793280.1ddf9c","name":"","topic":"","payload":"3","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":160,"wires":[["499c2aa3.fe6fd4"]]},{"id":"499c2aa3.fe6fd4","type":"function","z":"74793280.1ddf9c","name":"","func":"\nreturn msg;","outputs":1,"noerr":0,"x":315,"y":160,"wires":[["cd7ff538.6026a8","f061d3c4.fe3ce"]],"l":false},{"id":"cd7ff538.6026a8","type":"q-gate","z":"74793280.1ddf9c","name":"","controlTopic":"control","defaultState":"queueing","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","queueCmd":"queue","defaultCmd":"default","triggerCmd":"trigger","flushCmd":"flush","resetCmd":"reset","peekCmd":"peek","dropCmd":"drop","statusCmd":"status","maxQueueLength":"100","keepNewest":false,"qToggle":false,"persist":false,"x":770,"y":160,"wires":[["53e74633.197a78"]]},{"id":"f061d3c4.fe3ce","type":"trigger","z":"74793280.1ddf9c","op1":"","op2":"true","op1type":"nul","op2type":"bool","duration":"1","extend":true,"units":"s","reset":"","bytopic":"all","name":"","x":440,"y":80,"wires":[["75be446a.12192c"]]},{"id":"75be446a.12192c","type":"change","z":"74793280.1ddf9c","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"},{"t":"set","p":"payload","pt":"msg","to":"flush","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":80,"wires":[["cd7ff538.6026a8"]]},{"id":"a5d2db4c.e1f3b8","type":"debug","z":"74793280.1ddf9c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1070,"y":160,"wires":[]},{"id":"53e74633.197a78","type":"join","z":"74793280.1ddf9c","name":"","mode":"custom","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"","joinerType":"str","accumulate":false,"timeout":"0.5","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":890,"y":160,"wires":[["a5d2db4c.e1f3b8"]]}]

Wahoo !

Bravo and thank you! I'll try it immediately and give you news.

I imported the q-gate node which I did not have.
Then I added the PiKeyboard node (plus a Calculation node to filter the double message from this node) and it works perfectly! Thank you for your help !

I now have to solve the problem of displaying numbers because what goes back from the keyboard is a key code (ex: 79 for 1, 80 for 2, 81 for 3 ...; this gives "798081" for " 123 ")
Perhaps it is necessary to create a correspondence table?
Thanks again !

Hey Laurent,
there is an other easy way w/o any additional nodes to do this:

maybe you want to give this one a try aw:

which is pretty efficient and where function node simply does:

input = msg.payload;
input = String(input);                          //just in case
storage = context.get("storage")||[];           //recall last inputs, if not existent yet initialize a new empty array

if (input == "shoot!") {                        //the "topic you define in the trigger node"
    output = storage.join()                     //put all array indices together in one string
    output = output.replace(/,/gi,"");          // get rid of the commas e.g. replace them by an empty string
    msg = {payload:output};                     
    node.send(msg);
    context.set("storage",[]);                 //after sending empty the array in the storage
}else if (input != "shoot!") {                  // if there are other inputs to come:
    storage.push(input);                        // append them to the end of your storage array
    context.set("storage",storage);             // set your new array back to storage
}
return null;

BTW:
doing

storage = context.get("storage")||[];

works in most cases but is not very elegant,
in some cases better replace this by:

if (storage === undefined){
    storage = [];
}

FLOW:

[{"id":"e2031b15.1328f8","type":"debug","z":"8cd1075.a5184f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":1100,"wires":[]},{"id":"c897f150.27b29","type":"inject","z":"8cd1075.a5184f8","name":"","topic":"","payload":"1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1060,"wires":[["b2b497d1.b453f8","bc5714ff.6371d8"]]},{"id":"cd55936e.50beb","type":"inject","z":"8cd1075.a5184f8","name":"","topic":"","payload":"3","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1100,"wires":[["b2b497d1.b453f8","bc5714ff.6371d8"]]},{"id":"8870c11b.dcd31","type":"inject","z":"8cd1075.a5184f8","name":"","topic":"","payload":"7","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":1140,"wires":[["b2b497d1.b453f8","bc5714ff.6371d8"]]},{"id":"bc5714ff.6371d8","type":"function","z":"8cd1075.a5184f8","name":"","func":"//now = Date.now()\n//then = context.get(\"then\")||0;\n//context.set(\"then\",now);\n\ninput = msg.payload;\ninput = String(input);\nstorage = context.get(\"storage\")||[];\n//timedif = now-then;\n\nif (input == \"shoot!\") {\n    output = storage.join()\n    output = output.replace(/,/gi,\"\");\n    msg = {payload:output};\n    node.send(msg);\n    context.set(\"storage\",[]);\n}else if (input != \"shoot!\") {\n    storage.push(input);\n    context.set(\"storage\",storage);\n}\nreturn null;","outputs":1,"noerr":0,"x":530,"y":1100,"wires":[["e2031b15.1328f8"]]},{"id":"b2b497d1.b453f8","type":"trigger","z":"8cd1075.a5184f8","op1":"","op2":"shoot!","op1type":"nul","op2type":"str","duration":"1","extend":true,"units":"s","reset":"","bytopic":"all","name":"","x":330,"y":1020,"wires":[["bc5714ff.6371d8"]]}]
1 Like

Can you tell us what kind those "key codes" are of?
are those UTF-8 or utf-16, or generic?
thats what the solution depends on.

in your particular case, when a corresponance table from zero to 9 is enough you could:

init your table every start of NR

corrtable = [];
startindex = 78;
for (i=0;i<10;i++){
    corrtable[i] = String(startindex);
    startindex++;
}
flow.set("corrtable",corrtable);
return null;

/*
else if 0 is 88

corrtable = [];
corrtable[0] = 88;
startindex = 79;

for (i=1;i<10;i++){
    corrtable[i] = String(startindex);
    startindex++;
}

flow.set("corrtable",corrtable);
return null;
*/

and replace the keypad value before passing it to your flow

input = msg.payload;
corrtable = flow.get("corrtable");
msg.payload = corrtable.indexOf(input);
return msg;

FLOW:

[{"id":"4d1531f6.97713","type":"inject","z":"8cd1075.a5184f8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"1","x":130,"y":1280,"wires":[["195752c1.e76c8d"]]},{"id":"195752c1.e76c8d","type":"function","z":"8cd1075.a5184f8","name":"set your correspondence table to flow","func":"corrtable = [];\nstartindex = 78;\nfor (i=0;i<10;i++){\n    corrtable[i] = String(startindex);\n    startindex++;\n}\nflow.set(\"corrtable\",corrtable);\nreturn null;\n\n/*\nelse if 0 is 88\n\ncorrtable = [];\ncorrtable[0] = 88;\nstartindex = 79;\n\nfor (i=1;i<10;i++){\n    corrtable[i] = String(startindex);\n    startindex++;\n}\n\nflow.set(\"corrtable\",corrtable);\nreturn null;\n*/","outputs":0,"noerr":0,"x":380,"y":1280,"wires":[]},{"id":"28ba315f.c8799e","type":"debug","z":"8cd1075.a5184f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":730,"y":1420,"wires":[]},{"id":"f995441d.d92ad8","type":"inject","z":"8cd1075.a5184f8","name":"","topic":"","payload":"79","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1360,"wires":[["52c49bf.7e4c264"]]},{"id":"c3627624.d77518","type":"inject","z":"8cd1075.a5184f8","name":"","topic":"","payload":"80","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1400,"wires":[["52c49bf.7e4c264"]]},{"id":"4e0536ea.962df8","type":"inject","z":"8cd1075.a5184f8","name":"","topic":"","payload":"81","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1440,"wires":[["52c49bf.7e4c264"]]},{"id":"500c09bb.861398","type":"function","z":"8cd1075.a5184f8","name":"","func":"input = msg.payload;\ninput = String(input);                          //just in case\nstorage = context.get(\"storage\");\nif (storage === undefined){\n    storage = [];\n}\n\nif (input == \"shoot!\") {                        //the \"topic you define in the trigger node\"\n    output = storage.join()                     //put all array indices together in one string\n    output = output.replace(/,/gi,\"\");          // get rid of the commas e.g. replace them by an empty string\n    msg = {payload:output};                     \n    node.send(msg);\n    context.set(\"storage\",[]);\n}else if (input != \"shoot!\") {                  // if there are other inputs to come:\n    storage.push(input);                        // append them to the end of your storage array\n    context.set(\"storage\",storage);             // set your new array back to storage\n}\nreturn null;","outputs":1,"noerr":0,"x":550,"y":1420,"wires":[["28ba315f.c8799e"]]},{"id":"f775f7d3.021928","type":"trigger","z":"8cd1075.a5184f8","op1":"","op2":"shoot!","op1type":"nul","op2type":"str","duration":"1","extend":true,"units":"s","reset":"","bytopic":"all","name":"Trigger 1 sec","x":390,"y":1360,"wires":[["500c09bb.861398"]]},{"id":"52c49bf.7e4c264","type":"function","z":"8cd1075.a5184f8","name":"","func":"input = msg.payload;\ncorrtable = flow.get(\"corrtable\");\nmsg.payload = corrtable.indexOf(input);\nreturn msg;","outputs":1,"noerr":0,"x":250,"y":1400,"wires":[["f775f7d3.021928","500c09bb.861398"]]}]

Thanks a lot !!

It seems to be a number associated to each keyboard key.
Examples :
1 is 79
2 is 80
3 is 81
Esc is 1
F2 is 60
...
I use rasbian buster on pi3+so i think the second answer is UTF-8.

I'm very sorry to cannot give more precision. Nubee is my second name on computer code planet !!

thanks again for your help.

when it is utf and you need a complete conversion for every key, i would probably use some cummunitiy node like

node-red-contrib-iconv

if the numbers are enough for you, you could do it the way above, slim and easy.

Yes, numbers are enough. So it will be slim and easy, thank you.

But I always have to link each one to its own data (I have 250 lines linking each of the numbers to an argument that I need to retrieve in payload).
I tried Mysql, but too complicated for my weak knowledge.
Currently I am working on this path. Do you think I'm moving in the right direction?
Thank you for helping the Nubee to progress !!!

[{"id":"dc9d6f39.f253","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"af8a2ca.0844ed","type":"inject","z":"dc9d6f39.f253","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":240,"wires":[["d2664289.f0e4b"]]},{"id":"9c7f0e58.f74f3","type":"change","z":"dc9d6f39.f253","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"","fromt":"str","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":240,"wires":[["110d0ca7.df5c03"]]},{"id":"d2664289.f0e4b","type":"trigger","z":"dc9d6f39.f253","op1":"{"192.168.25.203":{"ipaddress":"192.168.25.203","location":"Living Room"},"192.168.1.11":{"ipaddress":"192.168.1.11","location":"Kitchen"}}","op2":"0","op1type":"json","op2type":"str","duration":"0","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":340,"y":240,"wires":[["9c7f0e58.f74f3","90135bbc.844d48"]]},{"id":"90135bbc.844d48","type":"debug","z":"dc9d6f39.f253","name":"a","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":530,"y":160,"wires":},{"id":"110d0ca7.df5c03","type":"debug","z":"dc9d6f39.f253","name":"b","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":790,"y":160,"wires":},{"id":"6989d787.2508b8","type":"function","z":"dc9d6f39.f253","name":"EPC Edge Analytics V1.1","func":"flow.rfid = flow.rfid || ;\nflow.activeReadSecs = flow.activeReadSecs || 3;\nflow.newTagReadSecs = flow.newTagReadSecs || 5;\n\nwbRSSIdB = Math.round(msg.wbRSSIdB || 0);\nnbRSSIdB = Math.round(msg.nbRSSIdB || 0);\nip = msg.ip || "no reader";\n\nif (msg.payload === "clear") {\n flow.rfid = ;\n msg.payload = "interval";\n}\n \nvar incoming = msg.epc || "No Tag";\n//var location = msg.ip || "Unknown";\ncurrentTime = msg.time || new Date();\n\nvar found = false;\nvar timeUpdate = true;\n\nif (msg.payload === "interval"){\n timeUpdate = false;\n} \n\nmsg.timeUpdate = timeUpdate;\n\nvar i;\nvar newTagRead = false;\n\nfor (i = 0; i < flow.rfid.length; i++){\n flow.rfid[i].timeElapsed = (currentTime - flow.rfid[i].time)/1000;\n \n if (flow.rfid[i].timeElapsed < (flow.activeReadSecs)){\n flow.rfid[i].activeRead = true;\n }\n else flow.rfid[i].activeRead = false;\n \n if (flow.rfid[i].epc === incoming){\n found = true;\n flow.rfid[i].wbRSSIdB = wbRSSIdB;\n flow.rfid[i].nbRSSIdB = nbRSSIdB;\n flow.rfid[i].ip = ip;\n if(timeUpdate){\n flow.rfid[i].time = currentTime;\n if (flow.rfid[i].timeElapsed > (flow.newTagReadSecs)){\n flow.rfid[i].count++;\n newTagRead = {"payload":{"epc":flow.rfid[i].epc,"time":currentTime,"ip":flow.rfid[i].ip}};\n }\n }\n }\n flow.rfid[i].timeElapsed = Math.round(flow.rfid[i].timeElapsed);\n}\n\nif (!found){\n var newRFID = JSON.parse('{"epc":"'+incoming+'","time":0}');\n newRFID.time = currentTime;\n flow.rfid[i] = newRFID;\n flow.rfid[i].count = 1;\n flow.rfid[i].timeElapsed = 0;\n flow.rfid[i].activeRead = true;\n flow.rfid[i].wbRSSIdB = wbRSSIdB;\n flow.rfid[i].nbRSSIdB = nbRSSIdB;\n \n newTagRead = {"payload":{"epc":flow.rfid[i].epc,"time":currentTime, "ip":flow.rfid[i].ip}};\n}\n\n\nmsg.payload = flow.rfid;\nif (newTagRead && newTagRead.payload.epc !== ""){\n return [msg,newTagRead];\n}\nelse return [msg,null];\n\n","outputs":"2","noerr":0,"x":770,"y":480,"wires":[,]},{"id":"76597ae0.bacae4","type":"change","z":"dc9d6f39.f253","name":"activeReadSecs & newTagReadSecs","rules":[{"t":"set","p":"activeReadSecs","pt":"flow","to":"payload.activeReadSecs","tot":"msg"},{"t":"set","p":"newTagReadSecs","pt":"flow","to":"payload.newTagReadSecs","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":460,"wires":[["6989d787.2508b8"]]},{"id":"2bf5b269.1e2c3e","type":"inject","z":"dc9d6f39.f253","name":"","topic":"","payload":"interval","payloadType":"str","repeat":"1","crontab":"","once":false,"onceDelay":"","x":540,"y":520,"wires":[["6989d787.2508b8"]]},{"id":"13bf0a7b.36f386","type":"change","z":"dc9d6f39.f253","name":"","rules":[{"t":"set","p":"myLookupTable","pt":"global","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":600,"wires":[]},{"id":"4aa54676.80d608","type":"inject","z":"dc9d6f39.f253","name":"","topic":"","payload":"{"192.168.25.203":{"ipaddress":"192.168.25.203","location":"Living Room"},"192.168.1.11":{"ipaddress":"192.168.1.11","location":"Kitchen"}}","payloadType":"json","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":550,"y":600,"wires":[["13bf0a7b.36f386"]]},{"id":"a651fa5e.a97c88","type":"inject","z":"dc9d6f39.f253","name":"Inject","topic":"tv","payload":"80","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":290,"y":880,"wires":[["e33d090b.16d848"]]},{"id":"fcc1c725.a73468","type":"csv","z":"dc9d6f39.f253","name":"","sep":",","hdrin":true,"hdrout":false,"multi":"mult","ret":"\n","temp":"a,b,c","skip":"0","strings":false,"x":750,"y":880,"wires":[["9a81f780.894d18"]]},{"id":"9a81f780.894d18","type":"debug","z":"dc9d6f39.f253","name":"t","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":950,"y":880,"wires":},{"id":"e33d090b.16d848","type":"template","z":"dc9d6f39.f253","name":"CSV data","field":"payload","fieldType":"msg","format":"text","syntax":"mustache","template":"a,b,c\n80,18,2\n52,36,10\n91,18,61\n32,47,65","output":"str","x":500,"y":880,"wires":[["fcc1c725.a73468"]]}]

okay, first of all, my wife got dinner prepared earlier, so I run out of time,
here is a flow with function in a function and timeout, so you wont neet the trigger node:

[{"id":"111fcd49.d367c3","type":"inject","z":"4f1996ea.42af68","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"1","x":130,"y":360,"wires":[["56d5e454.b82b5c"]]},{"id":"56d5e454.b82b5c","type":"function","z":"4f1996ea.42af68","name":"set your correspondence table to flow","func":"corrtable = [];\nstartindex = 78;\nfor (i=0;i<10;i++){\n    corrtable[i] = String(startindex);\n    startindex++;\n}\nflow.set(\"corrtable\",corrtable);\nreturn null;\n\n/*\nelse if 0 is 88\n\ncorrtable = [];\ncorrtable[0] = 88;\nstartindex = 79;\n\nfor (i=1;i<10;i++){\n    corrtable[i] = String(startindex);\n    startindex++;\n}\n\nflow.set(\"corrtable\",corrtable);\nreturn null;\n*/","outputs":0,"noerr":0,"x":380,"y":360,"wires":[]},{"id":"4bd94e18.dab09","type":"debug","z":"4f1996ea.42af68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":710,"y":480,"wires":[]},{"id":"a8213f6a.b3162","type":"inject","z":"4f1996ea.42af68","name":"","topic":"","payload":"79","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":440,"wires":[["12563e53.28c5a2"]]},{"id":"6a86d113.931c9","type":"inject","z":"4f1996ea.42af68","name":"","topic":"","payload":"80","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":480,"wires":[["12563e53.28c5a2"]]},{"id":"71505368.7e684c","type":"inject","z":"4f1996ea.42af68","name":"","topic":"","payload":"81","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":520,"wires":[["12563e53.28c5a2"]]},{"id":"5cc2e88e.cc0b28","type":"function","z":"4f1996ea.42af68","name":"","func":"input = msg.payload;\ninput = String(input);                          //just in case\nstorage = context.get(\"storage\");               // recall your storage\ntimer = context.get(\"timer\")||null;             // recall last timer if exists\nclearTimeout(timer);                            // clear the last timer\ncontext.set(\"timer\",timer);                     // set it to be emtpty\nif (storage === undefined){\n    storage = [];\n}\n\n\n//________________________________________________________________this is only called when sending the code\nrun = function mytimer(){                             //define a function that does all the stuff when you want to send the code\n\n    output = storage.join()                     //put all array indices together in one string\n    output = output.replace(/,/gi,\"\")          // get rid of the commas e.g. replace them by an empty string\n    msg = {payload:output}                   \n    node.send(msg)\n    context.set(\"storage\",[]);\n    return null;\n}\n\n//________________________________________________________________\n\n\ntimer = setTimeout(run,1000);               // set your new timer (1sec is 1000 milliseconds)\nstorage.push(input);                        // append them to the end of your storage array\ncontext.set(\"storage\",storage);             // set your new array back to storage\ncontext.set(\"timer\",timer);                 // store your new timer\nreturn null;","outputs":1,"noerr":0,"x":490,"y":480,"wires":[["4bd94e18.dab09"]]},{"id":"12563e53.28c5a2","type":"function","z":"4f1996ea.42af68","name":"","func":"input = msg.payload;\ncorrtable = flow.get(\"corrtable\");\nmsg.payload = corrtable.indexOf(input);\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":480,"wires":[["5cc2e88e.cc0b28"]]}]

with the function now doing following:

input = msg.payload;
input = String(input);                          //just in case
storage = context.get("storage");               // recall your storage
timer = context.get("timer")||null;             // recall last timer if exists
clearTimeout(timer);                            // clear the last timer
context.set("timer",timer);                     // set it to be emtpty
if (storage === undefined){
    storage = [];
}


//________________________________________________________________this is only called when sending the code
run = function mytimer(){                             //define a function that does all the stuff when you want to send the code

    output = storage.join()                     //put all array indices together in one string
    output = output.replace(/,/gi,"")          // get rid of the commas e.g. replace them by an empty string
    msg = {payload:output}                   
    node.send(msg)
    context.set("storage",[]);
    return null;
}

//________________________________________________________________


timer = setTimeout(run,1000);               // set your new timer (1sec is 1000 milliseconds)
storage.push(input);                        // append them to the end of your storage array
context.set("storage",storage);             // set your new array back to storage
context.set("timer",timer);                 // store your new timer
return null;

unfortunately your code is not to be imported,
there are characters missing.
please put the flow in code wrappers ( </> )

Thank you for everything.
I will continue to try to progress thanks to these elements.
Sorry for the truncated code, je vous le joins cette fois-ci in code wrappers
Enjoy your meal !

[{"id":"dc9d6f39.f253","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"af8a2ca.0844ed","type":"inject","z":"dc9d6f39.f253","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":true,"onceDelay":0.1,"x":130,"y":240,"wires":[["d2664289.f0e4b"]]},{"id":"9c7f0e58.f74f3","type":"change","z":"dc9d6f39.f253","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"","fromt":"str","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":240,"wires":[["110d0ca7.df5c03"]]},{"id":"d2664289.f0e4b","type":"trigger","z":"dc9d6f39.f253","op1":"{\"192.168.25.203\":{\"ipaddress\":\"192.168.25.203\",\"location\":\"Living Room\"},\"192.168.1.11\":{\"ipaddress\":\"192.168.1.11\",\"location\":\"Kitchen\"}}","op2":"0","op1type":"json","op2type":"str","duration":"0","extend":false,"units":"ms","reset":"","bytopic":"all","name":"","x":340,"y":240,"wires":[["9c7f0e58.f74f3","90135bbc.844d48"]]},{"id":"90135bbc.844d48","type":"debug","z":"dc9d6f39.f253","name":"a","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":530,"y":160,"wires":[]},{"id":"110d0ca7.df5c03","type":"debug","z":"dc9d6f39.f253","name":"b","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":790,"y":160,"wires":[]},{"id":"a651fa5e.a97c88","type":"inject","z":"dc9d6f39.f253","name":"Inject","topic":"tv","payload":"80","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":290,"y":880,"wires":[["e33d090b.16d848"]]},{"id":"fcc1c725.a73468","type":"csv","z":"dc9d6f39.f253","name":"","sep":",","hdrin":true,"hdrout":false,"multi":"mult","ret":"\\n","temp":"a,b,c","skip":"0","strings":false,"x":750,"y":880,"wires":[["9a81f780.894d18"]]},{"id":"9a81f780.894d18","type":"debug","z":"dc9d6f39.f253","name":"t","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":950,"y":880,"wires":[]},{"id":"e33d090b.16d848","type":"template","z":"dc9d6f39.f253","name":"CSV data","field":"payload","fieldType":"msg","format":"text","syntax":"mustache","template":"a,b,c\n80,18,2\n52,36,10\n91,18,61\n32,47,65","output":"str","x":500,"y":880,"wires":[["fcc1c725.a73468"]]}]

Okay,
the trigger block at the moment does nothing.
can you be more precise in what you want to look for and replace with?

e.g. are you looking for living room and want to return the ip address?

Sorry for the truncated code, je vous le joins cette fois-ci in code wrappers

Pas de probleme, je suis allmande. Peut-etre ma PC est devenu une victime de la barrière linguistique. Maintenant ca marche super. :wink:

Hello Deutshland, the language barrier is more in my head than in your PC!

Thanks again for your help and here are some details on the process I want to automate:
I enter a 3-digit number on my keyboard which corresponds to a url that I have in a csv database (2 columns: numbers; url).
Following the entry, the corresponding url must come out of a query node for example to enter as payload in an exec node.
The exec node will launch chromium and display the url.

If possible, I would like this database to be a csv file hosted on the Raspberry, but I can also imagine that this database is directly included in the node.
Yours,

okay, lets say you have a excel.csv,
excel

should it do like so?


FLOW:

[{"id":"4bd94e18.dab09","type":"debug","z":"4f1996ea.42af68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1430,"y":1360,"wires":[]},{"id":"a8213f6a.b3162","type":"inject","z":"4f1996ea.42af68","name":"","topic":"","payload":"79","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1160,"wires":[["12563e53.28c5a2"]]},{"id":"6a86d113.931c9","type":"inject","z":"4f1996ea.42af68","name":"","topic":"","payload":"85","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1240,"wires":[["12563e53.28c5a2"]]},{"id":"71505368.7e684c","type":"inject","z":"4f1996ea.42af68","name":"","topic":"","payload":"81","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":1200,"wires":[["12563e53.28c5a2"]]},{"id":"5cc2e88e.cc0b28","type":"function","z":"4f1996ea.42af68","name":"send the number string with 1sec timeout","func":"input = msg.payload;\ninput = String(input);                          //just in case\nstorage = context.get(\"storage\");               // recall your storage\ntimer = context.get(\"timer\")||null;             // recall last timer if exists\nclearTimeout(timer);                            // clear the last timer\ncontext.set(\"timer\",timer);                     // set it to be emtpty\nif (storage === undefined){\n    storage = [];\n}\n\n\n//________________________________________________________________this is only called when sending the code\nrun = function mytimer(){                             //define a function that does all the stuff when you want to send the code\n\n    output = storage.join()                     //put all array indices together in one string\n    output = output.replace(/,/gi,\"\")          // get rid of the commas e.g. replace them by an empty string\n    msg = {lookup:output}                       // important, in this case, this ist to be sent as msg.lookup, not msg.payload, otherwise the lookup function wont work \n    node.send(msg)\n    context.set(\"storage\",[]);\n    return null;\n}\n\n//________________________________________________________________\n\n\ntimer = setTimeout(run,1000);               // set your new timer (1sec is 1000 milliseconds)\nstorage.push(input);                        // append them to the end of your storage array\ncontext.set(\"storage\",storage);             // set your new array back to storage\ncontext.set(\"timer\",timer);                 // store your new timer\nreturn null;","outputs":1,"noerr":0,"x":700,"y":1200,"wires":[["41e4d04e.7a09d","c80db9e9.6e0f18"]]},{"id":"12563e53.28c5a2","type":"function","z":"4f1996ea.42af68","name":"replace keyboard input with numbers","func":"input = msg.payload;\ncorrtable = flow.get(\"corrtable\");\nmsg.payload = corrtable.indexOf(input);\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":1200,"wires":[["5cc2e88e.cc0b28"]]},{"id":"c80db9e9.6e0f18","type":"file in","z":"4f1996ea.42af68","name":"","filename":"/config/node-red/JsonDB/http/exampleURLlookup.csv","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":980,"y":1260,"wires":[["2a921965.0443c6"]]},{"id":"2a921965.0443c6","type":"csv","z":"4f1996ea.42af68","name":"","sep":";","hdrin":false,"hdrout":"","multi":"mult","ret":"\\n","temp":"","skip":"0","strings":false,"x":1170,"y":1300,"wires":[["722471e5.6a629","a4a7b9a8.9dfa08"]]},{"id":"722471e5.6a629","type":"function","z":"4f1996ea.42af68","name":"your lookup func","func":"lookup = msg.lookup;\nvar output;\ndata = msg.payload;\n\nfor (i=0;i<data.length;i++){\n    if (data[i].col1 == lookup){\n        output = data[i].col2;\n        context.set(\"lookup\",null);\n        msg = {payload:output};\n        node.send(msg);\n    }\n}\n\nreturn null;","outputs":1,"noerr":0,"x":1240,"y":1360,"wires":[["4bd94e18.dab09"]]},{"id":"41e4d04e.7a09d","type":"debug","z":"4f1996ea.42af68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"lookup","targetType":"msg","x":970,"y":1140,"wires":[]},{"id":"a4a7b9a8.9dfa08","type":"debug","z":"4f1996ea.42af68","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1430,"y":1300,"wires":[]},{"id":"e0f7cc84.c7c5b","type":"comment","z":"4f1996ea.42af68","name":"","info":"the seperator has to be semikolon (;)\nwhenn using miltiple columns, not commas\nthats an excel-thing","x":870,"y":1300,"wires":[]}]

Thank you again for your help.
I created the csv file from excel and adapted the name and the path in the corresponding node.
I connected your first node to my "calculation" node which I use to remove duplicates from the PiKeyboard node.
Finally I connected the output of the last node to an Exec node.

I can't get the stream to work and I get the following error message:
=> 14/04/2020 at 16: 28: 38 node: replace the keyboard entry with numbers
function: (error)
"TypeError: unable to read property 'indexOf' of undefined"
I have looked inside the code but I am unable to understand where the error is coming from.

[{"id":"9efbf573.b596b8","type":"tab","label":"Flow 5","disabled":false,"info":""},{"id":"d6528e62.3c079","type":"rpi-keyboard","z":"9efbf573.b596b8","name":"","x":150,"y":340,"wires":[["3d3b36eb.e797fa"]]},{"id":"3d3b36eb.e797fa","type":"calculate","z":"9efbf573.b596b8","name":"","pauseType":"rate","calculation":"max","timeout":"500","timeoutUnits":"milliseconds","rate":"1","x":150,"y":400,"wires":[["b6aa3c0.fb733c","99da5d5f.7dcc5"]]},{"id":"b6aa3c0.fb733c","type":"debug","z":"9efbf573.b596b8","name":"a","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":330,"y":400,"wires":[]},{"id":"99da5d5f.7dcc5","type":"function","z":"9efbf573.b596b8","name":"replace keyboard input with numbers","func":"input = msg.payload;\ncorrtable = flow.get(\"corrtable\");\nmsg.payload = corrtable.indexOf(input);\nreturn msg;","outputs":1,"noerr":0,"x":190,"y":480,"wires":[["460479aa.239818"]]},{"id":"460479aa.239818","type":"function","z":"9efbf573.b596b8","name":"send the number string with 1sec timeout","func":"input = msg.payload;\ninput = String(input);                          //just in case\nstorage = context.get(\"storage\");               // recall your storage\ntimer = context.get(\"timer\")||null;             // recall last timer if exists\nclearTimeout(timer);                            // clear the last timer\ncontext.set(\"timer\",timer);                     // set it to be emtpty\nif (storage === undefined){\n    storage = [];\n}\n\n\n//________________________________________________________________this is only called when sending the code\nrun = function mytimer(){                             //define a function that does all the stuff when you want to send the code\n\n    output = storage.join()                     //put all array indices together in one string\n    output = output.replace(/,/gi,\"\")          // get rid of the commas e.g. replace them by an empty string\n    msg = {lookup:output}                       // important, in this case, this ist to be sent as msg.lookup, not msg.payload, otherwise the lookup function wont work \n    node.send(msg)\n    context.set(\"storage\",[]);\n    return null;\n}\n\n//________________________________________________________________\n\n\ntimer = setTimeout(run,1000);               // set your new timer (1sec is 1000 milliseconds)\nstorage.push(input);                        // append them to the end of your storage array\ncontext.set(\"storage\",storage);             // set your new array back to storage\ncontext.set(\"timer\",timer);                 // store your new timer\nreturn null;","outputs":1,"noerr":0,"x":520,"y":480,"wires":[["514f5b1d.d0d0c4"]]},{"id":"514f5b1d.d0d0c4","type":"file in","z":"9efbf573.b596b8","name":"","filename":"/home/pi/Desktop/collecteweb.csv","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":740,"y":540,"wires":[["bb14dd59.04d3d"]]},{"id":"bb14dd59.04d3d","type":"csv","z":"9efbf573.b596b8","name":"","sep":";","hdrin":false,"hdrout":"","multi":"mult","ret":"\\n","temp":"","skip":"0","strings":false,"x":870,"y":600,"wires":[["beb8192.79141e8","6ccedd0d.bd8db4"]]},{"id":"6ccedd0d.bd8db4","type":"debug","z":"9efbf573.b596b8","name":"2","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1130,"y":600,"wires":[]},{"id":"afe742f0.ca6b6","type":"debug","z":"9efbf573.b596b8","name":"3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1130,"y":660,"wires":[]},{"id":"beb8192.79141e8","type":"function","z":"9efbf573.b596b8","name":"your lookup func","func":"lookup = msg.lookup;\nvar output;\ndata = msg.payload;\n\nfor (i=0;i<data.length;i++){\n    if (data[i].col1 == lookup){\n        output = data[i].col2;\n        context.set(\"lookup\",null);\n        msg = {payload:output};\n        node.send(msg);\n    }\n}\n\nreturn null;","outputs":1,"noerr":0,"x":940,"y":660,"wires":[["afe742f0.ca6b6","e630ae84.924f1"]]},{"id":"e630ae84.924f1","type":"exec","z":"9efbf573.b596b8","command":"DISPLAY=:0 chromium-browser --disable-infobars --no-default-browser-check --test-type --ignore-certificate-errors --no-first-run --disable-session-crashed-bubble;","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"display web","x":1150,"y":780,"wires":[[],[],[]]},{"id":"c788fc54.dfc22","type":"comment","z":"9efbf573.b596b8","name":"","info":"the seperator has to be semikolon (;)\nwhenn using miltiple columns, not commas\nthats an excel-thing","x":660,"y":580,"wires":[]}]

okay, what i actually did was setting up a correspondance table with strings of code, attached to en array index, that was the fastest way because you only wanted numbers as output.
so if you look up "80" by indexOf() you'll be returned the index which ist 2.

if you look up 80 (which is a number, not a string) you'll get this error.
i dont know the reason for, you use the calculation node. but i am shure it returns a number not a string.

please try following:
in the replace.... function node
add

input = String(input);

like this

input = msg.payload;
input = String(input);
corrtable = flow.get("corrtable");
msg.payload = corrtable.indexOf(input);
return msg;

by the way you can do this at once as well

input = String(msg.payload);

Good night and thank you.

My file coming from free office, I had to change the ";" with "," csv.
I just did the test and indeed it works very well! Thank you !

I always have a problem to display my url: I put a neoud exec which opens Chromium well but it does not embed in argument the url which is provided to it by your flow.
I tried to add "before and after the url in the database but it doesn't change anything.
An idea ?

PS: should I keep the node "set your correspondence table"?

[{"id":"8de410a.ae48df","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"f4c3f0a5.a5b5b","type":"debug","z":"8de410a.ae48df","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1390,"y":380,"wires":[]},{"id":"ed279091.31805","type":"inject","z":"8de410a.ae48df","name":"","topic":"","payload":"79","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":70,"y":340,"wires":[["8eb4aad3.2a3068"]]},{"id":"42c20eb7.0a028","type":"inject","z":"8de410a.ae48df","name":"","topic":"","payload":"85","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":70,"y":420,"wires":[["8eb4aad3.2a3068"]]},{"id":"d88cc8ee.f97588","type":"inject","z":"8de410a.ae48df","name":"","topic":"","payload":"81","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":70,"y":380,"wires":[["8eb4aad3.2a3068"]]},{"id":"3f64634b.166b9c","type":"function","z":"8de410a.ae48df","name":"send the number string with 1sec timeout","func":"input = msg.payload;\ninput = String(input);                          //just in case\nstorage = context.get(\"storage\");               // recall your storage\ntimer = context.get(\"timer\")||null;             // recall last timer if exists\nclearTimeout(timer);                            // clear the last timer\ncontext.set(\"timer\",timer);                     // set it to be emtpty\nif (storage === undefined){\n    storage = [];\n}\n\n\n//________________________________________________________________this is only called when sending the code\nrun = function mytimer(){                             //define a function that does all the stuff when you want to send the code\n\n    output = storage.join()                     //put all array indices together in one string\n    output = output.replace(/,/gi,\"\")          // get rid of the commas e.g. replace them by an empty string\n    msg = {lookup:output}                       // important, in this case, this ist to be sent as msg.lookup, not msg.payload, otherwise the lookup function wont work \n    node.send(msg)\n    context.set(\"storage\",[]);\n    return null;\n}\n\n//________________________________________________________________\n\n\ntimer = setTimeout(run,1000);               // set your new timer (1sec is 1000 milliseconds)\nstorage.push(input);                        // append them to the end of your storage array\ncontext.set(\"storage\",storage);             // set your new array back to storage\ncontext.set(\"timer\",timer);                 // store your new timer\nreturn null;","outputs":1,"noerr":0,"x":640,"y":400,"wires":[["6eaa0569.f52ccc","51ff4855.0025c8"]]},{"id":"8eb4aad3.2a3068","type":"function","z":"8de410a.ae48df","name":"replace keyboard input with numbers","func":"input = msg.payload;\ninput = String(input);\ncorrtable = flow.get(\"corrtable\");\nmsg.payload = corrtable.indexOf(input);\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":380,"wires":[["3f64634b.166b9c"]]},{"id":"51ff4855.0025c8","type":"file in","z":"8de410a.ae48df","name":"","filename":"/home/pi/Desktop/collecteweb.csv","format":"utf8","chunk":false,"sendError":false,"encoding":"none","x":860,"y":460,"wires":[["5d429e3b.0fc89"]]},{"id":"5d429e3b.0fc89","type":"csv","z":"8de410a.ae48df","name":"","sep":",","hdrin":false,"hdrout":"","multi":"mult","ret":"\\n","temp":"","skip":"0","strings":false,"x":1110,"y":500,"wires":[["87591d18.42414","4bba6d45.464944","9402a22f.0c72a"]]},{"id":"87591d18.42414","type":"function","z":"8de410a.ae48df","name":"your lookup func","func":"lookup = msg.lookup;\nvar output;\ndata = msg.payload;\n\nfor (i=0;i<data.length;i++){\n    if (data[i].col1 == lookup){\n        output = data[i].col2;\n        context.set(\"lookup\",null);\n        msg = {payload:output};\n        node.send(msg);\n    }\n}\n\nreturn null;","outputs":1,"noerr":0,"x":1200,"y":380,"wires":[["f4c3f0a5.a5b5b"]]},{"id":"6eaa0569.f52ccc","type":"debug","z":"8de410a.ae48df","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"lookup","targetType":"msg","x":910,"y":340,"wires":[]},{"id":"4bba6d45.464944","type":"debug","z":"8de410a.ae48df","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1370,"y":500,"wires":[]},{"id":"16ebb068.e0a9f","type":"comment","z":"8de410a.ae48df","name":"","info":"the seperator has to be semikolon (;)\nwhenn using miltiple columns, not commas\nthats an excel-thing","x":810,"y":500,"wires":[]},{"id":"9662cf7d.fdb7d","type":"function","z":"8de410a.ae48df","d":true,"name":"set your correspondence table to flow","func":"corrtable = [];\nstartindex = 78;\nfor (i=0;i<10;i++){\n    corrtable[i] = String(startindex);\n    startindex++;\n}\nflow.set(\"corrtable\",corrtable);\nreturn null;\n\n/*\nelse if 0 is 88\n\ncorrtable = [];\ncorrtable[0] = 88;\nstartindex = 79;\n\nfor (i=1;i<10;i++){\n    corrtable[i] = String(startindex);\n    startindex++;\n}\n\nflow.set(\"corrtable\",corrtable);\nreturn null;\n*/","outputs":0,"noerr":0,"x":390,"y":560,"wires":[]},{"id":"6a5d14ee.4b5c9c","type":"inject","z":"8de410a.ae48df","d":true,"name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"1","x":120,"y":560,"wires":[["9662cf7d.fdb7d"]]},{"id":"9402a22f.0c72a","type":"exec","z":"8de410a.ae48df","command":"DISPLAY=:0 chromium-browser","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":1380,"y":620,"wires":[[],[],[]]},{"id":"351125a7.78b12a","type":"rpi-keyboard","z":"8de410a.ae48df","name":"","x":70,"y":120,"wires":[["aa19dd12.1ef8b"]]},{"id":"aa19dd12.1ef8b","type":"calculate","z":"8de410a.ae48df","name":"","pauseType":"rate","calculation":"max","timeout":"500","timeoutUnits":"milliseconds","rate":"1","x":70,"y":180,"wires":[["8eb4aad3.2a3068"]]},{"id":"e5e2d079.a5e15","type":"inject","z":"8de410a.ae48df","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":480,"y":160,"wires":[["b3674e9.c1476b"]]},{"id":"b3674e9.c1476b","type":"exec","z":"8de410a.ae48df","command":"DISPLAY=:0 chromium-browser","addpay":true,"append":"https://www.symbio-system.com","useSpawn":"false","timer":"","oldrc":false,"name":"","x":740,"y":160,"wires":[[],[],[]]}]