Store Temporary Data

Hi everyone, It is posible I dont want using any database to store the data?

Now I tried to use the getter and setter to store the temporary data. I dont know why the node red cannot get the previous data. If current minute is 20 I would like to get also 15,10 and 5.

`[{"id":"e8ee6740.9d5ce8","type":"inject","z":"8debfc1f.64b44","name":"","topic":"","payload":"","payloadType":"date","repeat":"30","crontab":"","once":false,"onceDelay":0.1,"x":270,"y":1980,"wires":[["1afb4e8a.2cab81","a0637ea5.4bf94","43fdadf3.8783c4","24721b90.b4ffe4"]]},{"id":"1afb4e8a.2cab81","type":"function","z":"8debfc1f.64b44","name":"get data 15,35,55 (payload4)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){\nif(minute === 15 || minute === 35 || minute === 55){\ncontext.get('minutes15',minute)\nif(minute != 'minutes15'){\ncontext.set('minutes15',minute)\nmsg={payload4:{minute:minute}}\n}else{\ncontext.set('minutes15',minute)\nmsg={payload4:{minute}}\n}\n}\n}else return null\n\n/*context.set('hour',hour)\ncontext.set('minute',minute)\ncontext.set('second',second)\ncontext.set('year',year)\ncontext.set('month',month)\ncontext.set('day',day)\n\n\n\nif(minute === 15 || minute === 35 || minute ===55){\n    msg={payload4:{\n        hour:hour,\n        minute:minute,\n        second:second,\n        year:year,\n        month:month,\n        day:day,\n\n        \n        /*'hours':context.set(hour),\n        'minutes':context.set(minute),\n        'seconds':context.set(second),\n        'years':context.set(year),\n        'months':context.set(month),\n        'days':context.set(day),\n\n        \n    }}\n}else{\n    msg={payload4:{\n        hour:context.get('hour'),\n        minute:context.get('minute'),\n        second:context.get('second'),\n        year:context.get('year'),\n        month:context.get('month'),\n        day:context.get('day'),\n\n    }}\n}\n*/\n\n\nreturn msg;","outputs":1,"noerr":0,"x":540,"y":1940,"wires":[["a18e938c.609de"]]},{"id":"a0637ea5.4bf94","type":"function","z":"8debfc1f.64b44","name":"get data 20,40,0 (payload1)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){\nif(minute === 20 || minute === 40 || minute === 0){\ncontext.get('minutes15',minute)\nif(minute != 'minutes15'){\ncontext.set('minutes15',minute)\nmsg={payload1:{minute:minute}}\n}else{\ncontext.set('minutes15',minute)\nmsg={payload1:{minute}}\n}\n}\n}else return null\n\n/*context.set('hour',hour)\ncontext.set('minute',minute)\ncontext.set('second',second)\ncontext.set('year',year)\ncontext.set('month',month)\ncontext.set('day',day)\n\n\n\nif(minute === 15 || minute === 35 || minute ===55){\n    msg={payload4:{\n        hour:hour,\n        minute:minute,\n        second:second,\n        year:year,\n        month:month,\n\n        \n        /*'hours':context.set(hour),\n        'minutes':context.set(minute),\n        'seconds':context.set(second),\n        'years':context.set(year),\n        'months':context.set(month),\n        'days':context.set(day),\n\n        \n    }}\n}else{\n    msg={payload4:{\n        hour:context.get('hour'),\n        minute:context.get('minute'),\n        second:context.get('second'),\n        year:context.get('year'),\n        month:context.get('month'),\n        day:context.get('day'),\n\n    }}\n}\n*/\n\n\n\nreturn msg;","outputs":1,"noerr":0,"x":540,"y":1980,"wires":[["a18e938c.609de"]]},{"id":"43fdadf3.8783c4","type":"function","z":"8debfc1f.64b44","name":"get data 25,45,5 (payload2)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){\nif(minute === 25 || minute === 45 || minute === 5){\ncontext.get('minutes15',minute)\nif(minute != 'minutes15'){\ncontext.set('minutes15',minute)\nmsg={payload2:{minute:minute}}\n}else{\ncontext.set('minutes15',minute)\nmsg={payload2:{minute}}\n}\n}\n}else return null\n\n/*context.set('hour',hour)\ncontext.set('minute',minute)\ncontext.set('second',second)\ncontext.set('year',year)\ncontext.set('month',month)\ncontext.set('day',day)\n\n\n\nif(minute === 15 || minute === 35 || minute ===55){\n    msg={payload4:{\n        hour:hour,\n        minute:minute,\n        second:second,\n        year:year,\n        month:month,\n        day:day,\n\n        \n        /*'hours':context.set(hour),\n        'minutes':context.set(minute),\n        'seconds':context.set(second),\n        'years':context.set(year),\n        'months':context.set(month),\n        'days':context.set(day),\n\n        \n    }}\n}else{\n    msg={payload4:{\n        hour:context.get('hour'),\n        minute:context.get('minute'),\n        second:context.get('second'),\n        year:context.get('year'),\n        month:context.get('month'),\n        day:context.get('day'),\n\n    }}\n}\n*/\n\n\n\nreturn msg;","outputs":1,"noerr":0,"x":540,"y":2020,"wires":[["a18e938c.609de"]]},{"id":"24721b90.b4ffe4","type":"function","z":"8debfc1f.64b44","name":"get data 30,50,10 (payload3)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){\nif(minute === 30 || minute === 50 || minute === 10){\ncontext.get('minutes15',minute)\nif(minute != 'minutes15'){\ncontext.set('minutes15',minute)\nmsg={payload3:{minute:minute}}\n}else{\ncontext.set('minutes15',minute)\nmsg={payload3:{minute}}\n}\n}\n}else return null\n\n/*context.set('hour',hour)\ncontext.set('minute',minute)\ncontext.set('second',second)\ncontext.set('year',year)\ncontext.set('month',month)\ncontext.set('day',day)\n\n\n\nif(minute === 15 || minute === 35 || minute ===55){\n    msg={payload4:{\n        hour:hour,\n        minute:minute,\n        second:second,\n        year:year,\n        month:month,\n        day:day,\n\n        \n        /*'hours':context.set(hour),\n        'minutes':context.set(minute),\n        'seconds':context.set(second),\n        'years':context.set(year),\n        'months':context.set(month),\n        'days':context.set(day),\n\n        \n    }}\n}else{\n    msg={payload4:{\n        hour:context.get('hour'),\n        minute:context.get('minute'),\n        second:context.get('second'),\n        year:context.get('year'),\n        month:context.get('month'),\n        day:context.get('day'),\n\n    }}\n}\n*/\n\n\n\nreturn msg;","outputs":1,"noerr":0,"x":540,"y":2060,"wires":[["a18e938c.609de"]]},{"id":"a18e938c.609de","type":"debug","z":"8debfc1f.64b44","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":810,"y":2020,"wires":[]}]`

This is my code.

Thanks.

Hi @jason_tien

you will need to provide some more explanation for what your flow is doing (or what you think it is doing) and which parts you want us to look at. There is a lot of code in there with no comments.

1 Like

hi @knolleary

`[{"id":"e8ee6740.9d5ce8","type":"inject","z":"8debfc1f.64b44","name":"","topic":"","payload":"","payloadType":"date","repeat":"30","crontab":"","once":false,"onceDelay":0.1,"x":90,"y":1960,"wires":[["1afb4e8a.2cab81","a0637ea5.4bf94","43fdadf3.8783c4","24721b90.b4ffe4"]]},{"id":"1afb4e8a.2cab81","type":"function","z":"8debfc1f.64b44","name":"get data 15,35,55 (payload4)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){\nif(minute === 15 || minute === 35 || minute === 55){\ncontext.get('minutes15',minute)\nif(minute != 'minutes15'){\ncontext.set('minutes15',minute)\nmsg={payload4:{minute:minute}}\n}else{\ncontext.set('minutes15',minute)\nmsg={payload4:{minute}}\n}\n}else{\ncontext.set('minutes15',minute)\nmsg={payload4:{minute}}\n}\n}else return null\n\n\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":1920,"wires":[["a18e938c.609de"]]},{"id":"a0637ea5.4bf94","type":"function","z":"8debfc1f.64b44","name":"get data 20,40,0 (payload1)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){\nif(minute === 20 || minute === 40 || minute === 0){\ncontext.get('minutes20',minute)\nif(minute != 'minutes20'){\ncontext.set('minutes20',minute)\nmsg={payload1:{minute:minute}}\n}else{\ncontext.set('minutes20',minute)\nmsg={payload1:{minute}}\n}\n}else{\ncontext.set('minutes20',minute)\nmsg={payload1:{minute}}\n}\n}else return null\n\n\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":1960,"wires":[["a18e938c.609de"]]},{"id":"43fdadf3.8783c4","type":"function","z":"8debfc1f.64b44","name":"get data 25,45,5 (payload2)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){\nif(minute === 25 || minute === 45 || minute === 5){\ncontext.get('minutes25',minute)\nif(minute != 'minutes25'){\ncontext.set('minutes25',minute)\nmsg={payload2:{minute:minute}}\n}else{\ncontext.set('minutes25',minute)\nmsg={payload2:{minute}}\n}\n}else{\ncontext.set('minutes25',minute)\nmsg={payload2:{minute}}\n}\n}else return null\n\n\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":2000,"wires":[["a18e938c.609de"]]},{"id":"24721b90.b4ffe4","type":"function","z":"8debfc1f.64b44","name":"get data 30,50,10 (payload3)","func":"d = new Date();\nminute = d.getMinutes();\n\nif(minute%5 === 0){ //get the 5,10,15 min\nif(minute === 30 || minute === 50 || minute === 10){\ncontext.get('minutes30',minute)\nif(minute != 'minutes30'){\ncontext.set('minutes30',minute) \nmsg={payload3:{minute:minute}} //send the current minute (ex:30)\n}else{                         //if it is not 30/50/10\ncontext.set('minutes30',minute)\nmsg={payload3:{minute}}    //send the(30 again)\n}\n}else{                         //if it is not 30/50/10\ncontext.set('minutes30',minute)\nmsg={payload3:{minute}}     //send the(30 again)\n}\n}else return null\n\n\nreturn msg;","outputs":1,"noerr":0,"x":360,"y":2040,"wires":[["a18e938c.609de"]]},{"id":"a18e938c.609de","type":"debug","z":"8debfc1f.64b44","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":630,"y":2000,"wires":[]}]`

Example current minute is 30 I want the output is minute 30,25,20 and 15.
I use getter and setter tried to store the 25,20 and 15 but it cannot work.

Thanks.

Define Temporary please ? Do you not care about the data between restarts of node-red and/or the box it is running on - or do you need to keep it ?

You can use the local filesystem on whatever device you are running to store data by including something like this in your settings.js file

contextStorage: {
default: {
module: "localfilesystem"
},
memoryOnly: {
module: "memory"
}
}

You can then use the change node to read and write variables into that storage space - or you can use function nodes with the same result.

Here is a good simple explanation and some examples

http://www.steves-internet-guide.com/node-red-variables/

Craig

1 Like

You are using context.set('xxx',nnn) - if you read the documentation you will see

In the Function node there are three predefined variables that can be used to access context:

  • context - the node’s local context
  • flow - the flow scope context
  • global - the global scope context

So any context variables you use are avaliable only in that node. So if node 'A' stores a variable using context, it will only be avaliable to node 'A'. Node 'B' will not have access to it.

You might want to try using flow variables.

2 Likes

Hello @zenofmud
I'm trying something similar. I want to set a trigger with a number from the GUI. This delay shuld be stored in a context variable named "delay". Now I got a output from my condition (should I turn the pump on or not) this would be a 1 or a 0. Now the my function should send a message to the trigger node with contains the payload and the last choosen delay time. Do you understand what I would like to achiev?

Here is my flow

[{"id":"e774e762.c2829","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"9c28a5be.46e498","type":"ui_numeric","z":"e774e762.c2829","name":"","label":"Timer delay","tooltip":"","group":"fe7501d.fa0bf8","order":9,"width":0,"height":0,"wrap":false,"passthru":true,"topic":"delay","topicType":"flow","format":"{{value}}","min":"0","max":"10","step":"1","x":830,"y":300,"wires":[["a0c62a0.69dc358"]]},{"id":"8b0df7cc.c1b078","type":"change","z":"e774e762.c2829","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"delay","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":850,"y":400,"wires":[["1145e7eb.c6b4b"]]},{"id":"1145e7eb.c6b4b","type":"function","z":"e774e762.c2829","name":"","func":"var delay = Number(flow.get('delay') || 0); \n\nif (isNaN(delay) === false) { \n    flow.set('delay',delay);\n    msg.delay = delay;\n}\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1100,"y":400,"wires":[["93404203.480d98","cbe23a92.4300f8"]]},{"id":"93404203.480d98","type":"debug","z":"e774e762.c2829","name":"Output Function","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1340,"y":400,"wires":[]},{"id":"a0c62a0.69dc358","type":"function","z":"e774e762.c2829","name":"","func":"var delay = Number(msg.payload); \nflow.set('delay',delay);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1080,"y":300,"wires":[[]]},{"id":"6e0004b1.354e1c","type":"inject","z":"e774e762.c2829","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":880,"y":500,"wires":[["1145e7eb.c6b4b"]]},{"id":"cbe23a92.4300f8","type":"trigger","z":"e774e762.c2829","name":"","op1":"1","op2":"0","op1type":"num","op2type":"num","duration":"10","extend":false,"overrideDelay":true,"units":"s","reset":"","bytopic":"all","topic":"delay","outputs":1,"x":1310,"y":520,"wires":[["dd409277.0b0bc8"]]},{"id":"dd409277.0b0bc8","type":"debug","z":"e774e762.c2829","name":"Trigger","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1500,"y":520,"wires":[]},{"id":"fe7501d.fa0bf8","type":"ui_group","name":"Sensor 3","tab":"e7c46d5e.a1283","order":3,"disp":true,"width":"6","collapse":false},{"id":"e7c46d5e.a1283","type":"ui_tab","name":"Dashboard","icon":"casino","order":1,"disabled":false,"hidden":false}]

Code inside the Function

var delay = Number(flow.get('delay') || 0); 

if (isNaN(delay) === false) { 
    flow.set('delay',delay);
    msg.delay = delay;
}


return msg;



Thanks for oure help

You have only exported the function node, so we can't see where you are saving the delay value. However, I see you are fetching from the node context using context.get(). If you have saved it to flow context then you should be using flow.get()

Hi @Colin thanks for the fast answere

I used context because I need the varible "delay" only in this function node.
I updatet my flow code, sorry for the wrong one :slight_smile:

You may only be reading it in the function node, but you are (I assume) setting it in another node, so you have to use flow or global so you can access it in both places. node context is only accessible in the function node itself.

Hi @Colin

Now I set the scope to "flow"
Each time I injectet a "1" in the function node my delay ist set to "NaN".

Here ho I understand my code :slight_smile: please teach me

var delay = flow.get('delay') || 0; // I fill the var delay with last which is stored in the flow scope under delay
var GPIO = msg.payload; // my Injected "1" is stored in GPIO

if (msg.delay != "NaN") { // If there is no delay message because I didn't change the delay I can't update the variable
    delay = Number(msg.delay);
    flow.set('delay',delay);
   msg.delay = delay;
}


msg.payload = GPIO;

return msg;

var delay = Number(flow.get('delay') || 0); 

//var GPIO = msg.payload; // this is pointless as you re-assign it back to msg.payload

if (isNaN(delay) === false) { 
    flow.set('delay',delay);
    msg.delay = delay;
}

//msg.payload = GPIO;  // this is pointless, payload is already value of GPIO!

return msg;

But somewhere I need to assigne the output from the UI to the variable delay in the flow scope.
I made now for this a function. Is there a more elegant way?

Thanks for your help. I updated the flow and the code in my origina post.

It can be as simple as 2 separate flows.

Flow 1...

UI Input --> CHANGE node (set flow.delay to msg.payload)

Flow 2...

inject --> function --> GPIO


NOTE: i guess at some point you actually want a delay node in the flow, so probably this is more accurate...

Flow 2...

inject --> function --> delay node --> GPIO

You are rigth. Thats how I did it now.
Inject --> function --> trigger --> GPIO
Now if the Soil dry the pump turn for a defined time on.
I think it would be more easy if it was possible to set the delay variable by the trigger node from the flow.delay variable. Do you now what i mean? :slight_smile:

Sorry for buthering you again.
But no I added the trigger node. But it looks like that it ignored the msg.delay...
Ist there something wrong in the configuration?
I updated the flow in the original post

Add a debug node set to show Complete Message, showing what is going into the trigger node and show us what it says.

Solved. The delay has to be in milisecond not in seconds. It is alwasy good to read the help text :slight_smile:

1 Like