Interval time calculation

i got the following flow:"

[{"id":"79ce684e.6b6da8","type":"function","z":"1f216cc0.281a93","name":"INSERT statement","func":"msg.topic = \"INSERT INTO `IOT_DATA` ( `DATA_BRON`,`DATA_SOORT`,`DATA_WAARDE`) VALUES ('77','uit',\" + msg.payload + \")\";\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":360,"wires":[["933216aa.2dc248","a4481e1e.3b5b9"]]},{"id":"933216aa.2dc248","type":"debug","z":"1f216cc0.281a93","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1170,"y":360,"wires":[]},{"id":"9eb082e8.fa622","type":"mqtt in","z":"1f216cc0.281a93","name":"","topic":"pers77_status","qos":"2","broker":"d0e4f151.5ec18","x":70,"y":400,"wires":[["5cbedf1f.672cc","54c828cf.882268","4dac3b4d.140274"]]},{"id":"a4481e1e.3b5b9","type":"mysql","z":"1f216cc0.281a93","mydb":"23c1ad96.82d712","name":"","x":1170,"y":400,"wires":[[]]},{"id":"54c828cf.882268","type":"function","z":"1f216cc0.281a93","name":"Color","func":"if (msg.payload == 1) {\n    msg.payload = true;\n} else {\n    msg.payload = false;\n}\nreturn msg;","outputs":1,"noerr":0,"x":250,"y":500,"wires":[["4484dea2.81af1","aca98c67.3cfae"]]},{"id":"3c3ee011.f1b88","type":"function","z":"1f216cc0.281a93","name":"Generate spike","func":"var interval = setInterval(function() {\n    clearInterval(interval);\n\tnode.send({payload: 0});\n}, msg.payload); \n\nreturn null;","outputs":1,"noerr":0,"x":440,"y":380,"wires":[["20746ea6.68e8e2"]]},{"id":"20746ea6.68e8e2","type":"interval-length","z":"1f216cc0.281a93","format":"mills","bytopic":false,"minimum":"","maximum":"","window":"","timeout":false,"msgTimeout":"","minimumunit":"secs","maximumunit":"msecs","windowunit":"secs","reset":false,"startup":true,"msgField":"payload","timestampField":"timestamp","repeatTimeout":false,"name":"","x":640,"y":380,"wires":[["79ce684e.6b6da8","2a1fad18.a78762"],[]]},{"id":"2a1fad18.a78762","type":"debug","z":"1f216cc0.281a93","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":930,"y":400,"wires":[]},{"id":"5cbedf1f.672cc","type":"switch","z":"1f216cc0.281a93","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"0","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":250,"y":400,"wires":[["3c3ee011.f1b88"],["e8683c0e.f97bb"]]},{"id":"c448d0c8.e005e","type":"function","z":"1f216cc0.281a93","name":"INSERT statement","func":" msg.topic = \"INSERT INTO `IOT_DATA` ( `DATA_BRON`,`DATA_SOORT`,`DATA_WAARDE`) VALUES ('77','aan',\" + msg.payload + \")\";\nreturn msg;","outputs":1,"noerr":0,"x":950,"y":460,"wires":[["5a14a007.53421","b50c1a56.eb3f28"]]},{"id":"5a14a007.53421","type":"debug","z":"1f216cc0.281a93","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1170,"y":460,"wires":[]},{"id":"b50c1a56.eb3f28","type":"mysql","z":"1f216cc0.281a93","mydb":"23c1ad96.82d712","name":"","x":1170,"y":500,"wires":[[]]},{"id":"e8683c0e.f97bb","type":"function","z":"1f216cc0.281a93","name":"Generate spike","func":"var interval = setInterval(function() {\n    clearInterval(interval);\n\tnode.send({payload: 0});\n}, msg.payload); \n\nreturn null;","outputs":1,"noerr":0,"x":440,"y":420,"wires":[["d1a16f19.b92e2"]]},{"id":"d1a16f19.b92e2","type":"interval-length","z":"1f216cc0.281a93","format":"mills","bytopic":false,"minimum":"","maximum":"","window":"","timeout":false,"msgTimeout":"","minimumunit":"secs","maximumunit":"msecs","windowunit":"secs","reset":false,"startup":true,"msgField":"payload","timestampField":"timestamp","repeatTimeout":false,"name":"","x":640,"y":420,"wires":[["c448d0c8.e005e","c41f05fb.e87568"],[]]},{"id":"c41f05fb.e87568","type":"debug","z":"1f216cc0.281a93","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":930,"y":500,"wires":[]},{"id":"4dac3b4d.140274","type":"debug","z":"1f216cc0.281a93","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":250,"y":580,"wires":[]},{"id":"4484dea2.81af1","type":"ui_led","z":"1f216cc0.281a93","group":"ef52ec43.10754","order":1,"width":"3","height":"2","label":"Aan/uit","labelPlacement":"right","labelAlignment":"left","colorForValue":[{"color":"red","value":"false","valueType":"bool"},{"color":"green","value":"true","valueType":"bool"}],"name":"Aan/uit","x":420,"y":500,"wires":[]},{"id":"aca98c67.3cfae","type":"ui_led","z":"1f216cc0.281a93","group":"ef52ec43.10754","order":2,"width":"4","height":"2","label":"Slag","labelPlacement":"right","labelAlignment":"left","colorForValue":[{"color":"red","value":"false","valueType":"bool"},{"color":"green","value":"true","valueType":"bool"}],"name":"Slag","x":410,"y":540,"wires":[]},{"id":"d0e4f151.5ec18","type":"mqtt-broker","z":"","name":"MQTT_Broker","broker":"192.168.16.76","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"23c1ad96.82d712","type":"MySQLdatabase","z":"","host":"127.0.0.1","port":"3306","db":"VEKO_IOT","tz":""},{"id":"ef52ec43.10754","type":"ui_group","z":"","name":"Pers 77","tab":"6b96da3f.ce1c04","order":1,"disp":true,"width":"24","collapse":false},{"id":"6b96da3f.ce1c04","type":"ui_tab","z":"","name":"Machine data","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

The problem i just noticed is that the time on is calculating the time between 1 and 1 and the time off is calculated between 0 and 0. So it's not the time on (1 to 0) or off (o to 1) but between on and on or off and off.

Can anyone help me to get the time on and off?

Hi, I cant (wont) try your code as it has several nodes I'm not going to install.

If you could specify exactly what you want, I'll give it a try.

At a guess, you want to know the time (in seconds? in milliseconds?) between a msg.payload changing from 1 to 0 or from 0 to 1?

Yes, exactly. I get a signal 1 (on) or 0 (off) from a MQTT client. Now i want to know what time that the machine is on (1 to 0) and the time that the machine is off (0 to 1) in milliseconds.

Slightly different to what you had but achieves your requirement...

[{"id":"3235ba39.f39db6","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"b9f0215b.aa8f6","type":"function","z":"3235ba39.f39db6","name":"INSERT statement","func":"msg.topic = \"INSERT INTO `IOT_DATA` ( `DATA_BRON`,`DATA_SOORT`,`DATA_WAARDE`) VALUES ('77','uit',\" + msg.payload + \")\";\nreturn msg;","outputs":1,"noerr":0,"x":410,"y":180,"wires":[["979687b.7485778"]]},{"id":"979687b.7485778","type":"debug","z":"3235ba39.f39db6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":650,"y":180,"wires":[]},{"id":"2452252a.92166a","type":"mqtt in","z":"3235ba39.f39db6","name":"","topic":"pers77_status","qos":"2","broker":"3a71034c.ba914c","x":110,"y":40,"wires":[["c5efd5cc.ab5d08"]]},{"id":"4e44da17.34e7c4","type":"inject","z":"3235ba39.f39db6","name":"","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":100,"wires":[["c5efd5cc.ab5d08"]]},{"id":"e3185552.d13128","type":"inject","z":"3235ba39.f39db6","name":"","topic":"","payload":"off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":140,"wires":[["c5efd5cc.ab5d08"]]},{"id":"c5efd5cc.ab5d08","type":"function","z":"3235ba39.f39db6","name":"state change time measure","func":"let now = Date.now();\nlet state = (msg.payload == true || msg.payload == \"1\" || msg.payload == \"on\");//state will be true if payload is 1 or \"on\"  otherwise it will be false\nlet stateMem = context.get(\"stateMem\");\ncontext.set(\"stateMem\",state);//store this state\n\nif(stateMem !== true && stateMem !== false){\n    //this is likely first time here.  Store time and exit\n    context.set(\"nowMem\",now)\n    return null;//halt flow  \n} \n\n//if both are equal (e.g. both are on or both are off), return null\nif(state === stateMem){\n    return null;//halt flow\n}\n\n//if we reach here, state has changed, calc difference in ms\n\n//get last time memory\nlet nowMem = context.get(\"nowMem\") || Date.now();\n\n//update time memory for next time\ncontext.set(\"nowMem\",now);\n\nlet diff = now - nowMem;//calc diff\n\nmsg.state = state;\nmsg.payload = diff;\nreturn msg;\n","outputs":1,"noerr":0,"x":380,"y":120,"wires":[["b9f0215b.aa8f6","e258cc3d.8ca4a"]]},{"id":"4ca4b6c0.425e08","type":"inject","z":"3235ba39.f39db6","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":200,"wires":[["c5efd5cc.ab5d08"]]},{"id":"e52655eb.861638","type":"inject","z":"3235ba39.f39db6","name":"","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":240,"wires":[["c5efd5cc.ab5d08"]]},{"id":"e258cc3d.8ca4a","type":"debug","z":"3235ba39.f39db6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":630,"y":120,"wires":[]},{"id":"3a71034c.ba914c","type":"mqtt-broker","z":"","name":"MQTT_Broker","broker":"192.168.16.76","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
2 Likes

So, state indicates with true or false if the machine is on or off?

Yes.
If you need access to state, you can get it in the next node.

Also, If you want the original value sent in by MQTT, add this as first line in the function block...
msd.originalPayload = msg.payload;

Ok, i got it working only now i need to insert the value if state false and true. How can i get those out of the message?

20-6-2019 14:32:18node: e0377b88.bc8098
msg : Object
object
_msgid: "bb3ea1b.9490e6"
topic: ""
payload: 1581672
state: false

not certain what you mean?

As it was inserted into msg like this msg.state = something you get it in the next node that recieves this msg will be able to access msg.state.

Perhaps you should read "working with messages" to help you help yourself? It has useful tips about finding values and copying the path.

NOTE...

  • In some nodes you have to specify just the property name e.g. state
  • In others nodes like the function node you access it via its full path e.g. msg.state.

It something you get used to & understand after a while. If you are unsure, try both until it works.

I got one more question about this code. When the machine is turned off for the weekend it counts the time off for monday over the last three days. Now i tried the following but it's not working. I want to change the diff to 0 when diff is more then 8 hours.

let now = Date.now();
let state = (msg.payload == true || msg.payload == "1" || msg.payload == "on"|| msg.payload == 1);//state will be true if payload is 1 or "on"  otherwise it will be false
let stateMem = context.get("stateMem");
context.set("stateMem",state);//store this state

if(stateMem !== true && stateMem !== false){
    //this is likely first time here.  Store time and exit
    context.set("nowMem",now)
    return null;//halt flow  
} 

//if both are equal (e.g. both are on or both are off), return null
if(state === stateMem){
    return null;//halt flow
}

//if we reach here, state has changed, calc difference in ms

//get last time memory
let nowMem = context.get("nowMem") || Date.now();

//update time memory for next time
context.set("nowMem",now);

let diff = now - nowMem;//calc diff

if (diff >= 28800000) {
insdiff = 0;
} else {
	insdiff = diff
}

msg.state = state;
msg.payload = insdiff;

return msg;

Have you tried adding some debug functions, such as node.warn in your code, so you can see why it's failing. Especially just before this, to see diff.

if (diff >= 28800000) {
insdiff = 0;
} 

https://nodered.org/docs/user-guide/writing-functions

So two problems I see.

  1. You don't declare this new variable. Try this...
msg.diff = now - nowMem;//calc diff
msg.payload = msg.diff;
if (msg.diff >= 28800000) {
  msg.payload = 0;
}
msg.state = state;
return msg
  1. Context is not retentive. I.e. it's lost after a power cycle. For that functionality you will need to use persistent storage. There are contrib nodes that can do this or you can setup persistent context. Search the Web and this forum. If you get stuck, ask or create new thread.