How to keep flow running after one of the triggers is false?

I'm sorry the title is not to clear, but I wasn't sure how else to say it.

I am new to Node-Red so please let me know if I don't give all the information you need.

We have an application on an industrial device where we are monitoring the status of a piece of machinery. We are loading all the values into a database. But we only want to write to the database when the machinery is running. We are monitoring pressure and solenoid valves.

Everything is working beautiful except for the control to start and stop the flow.

When the pressure is > 0 and a digital input turns on, we know the machine has started and we must start the flow. The tricky part for me though, is that the digital input could turn on or off multiple times during runtime but as long as the pressure is up we need to keep the flow running.

So, in short, if the conditions are met in 2 variables, we need to consider the machine running, but after the machine is running, we can only monitor the pressure variable and not the manifold.

I was attempting to use the switch node, but it did not seem to be able to do what I need it to.

I look forward to your advice. Thanks!!!

you could store the values in context (flow or global) then use a function node to compute the state.

e.g.

  • pressure --> change node (store value in flow as "pressure")
  • digital input --> change node (store value in flow as "runSignal")

in a function node (somewhere suitable - perhaps before the SQL node)...

var pressure = flow.get("pressure") || 0; //get pressure value from flow context store
var runSignal = flow.get("runSignal") || false;  //get runSignal value from flow context store

//if runSignal is not false OR pressure is > 0, let the msg be sent onwards
if(runSignal || pressure > 0) {
    return msg; //pas the msg to next node 
}
return null; //halt the flow (dont send msg)

EDIT:

Being new to node-red, it would help you a lot if you spend 30 mins watching these easy to digest videos from one of the creators - some excellent tips in there to make you very proficient.

A clean way to do it would be using one of the state machine nodes (such as node-red-contrib-dsm) but it isn't a trivial learning exercise to use one of those. Maybe better to stick with a more basic approach initially, then at some point you can decide to refactor it if the mood takes you.

Thanks for your responses.

Steve.
your method makes sense, but it is similar to what I had been doing that doesn't quite work and it doesn't answer the tricky part that I was running into.

If pressure is > 0 and runSignal is true then we must begin running the flow and then the flow must continue running until the pressure = 0 even if the runSignal turns off.

I am more of a plc programmer and in ladder logic we would use a Set & Reset.............

Also thanks for the link to those videos. I will watch them when I get a chance.

I too am a PLC programmer - however - a flow in node-red doesnt "continue running" like a PLC scan.

everything is event driven so whatever makes your database insert - you need to allow or disallow it. Thats why i suggested that.

The logic I posted caters for runSignal being off if(runSignal || pressure > 0) << the || means "OR"

In english: if runSignal is on OR pressure > 0 then you may pass

Whatever triggers your flow now - keep that & insert a function node between it and the database - it will run if the conditions are met.

EDIT: there is a good chance I am missing some context so my response is based on the info you provided. If so, then paste a screen shot with comments on it & export your flow for me to look at

Thanks. I will work at it a little more. And show you my flow later. OK?

1 Like

So I just need a little help on the syntax here. I am using a function node as you described. Here is my work in this function node.

This would do the job just fine, except there is one caveat (that I forgot to mention, thus why your solution wouldn't quite work for me. My apologies!)

Heres how it works....this machine will start a cycle. When a manifold valve is opened and we have pressure, we indicate we are starting a cycle. The cycle will be considered complete when the pressure goes to 0. During the cycle, the manifolds may turn on and off at random.
So far your logic would work fine...

But the issue is sometimes they use this pump for other things and at times we will see pressure but no manifolds. So that is where (unless I misunderstand?) your OR logic would break down.

so to make sure I'm not missing something....
If a manifold turns on all by itself, we cannot start writing.
If the pressure turns on all by itself, we cannot start writing.
Once both pressure and a manifold have turned on, we need to start writing continuously until the pressure goes off, regardless of the state of the manifold.

Does that make any more sense? I am struggling with the correct syntax to that in a function node.
I am only monitoring this machine and not controlling it, so I have to work with this.

flows(5).json (9.7 KB)

Here is my flow export

Show me the contents of your globals. (right hand side bar context data)

I will do that once I am back online with the machine

This is at the current moment

Could you also copy your function code (as text) between three backticks like this...

```
code here
```

var manifold2=global.get('manifold2') || 0;
var manifold3=global.get('manifold3') || 0;
var manifold4=global.get('manifold4') || 0;
var manifold5=global.get('manifold5') || 0;
var manifold6=global.get('manifold6') || 0;
var flow=global.get('flow') || 0;
var pressure=global.get('pressure') || 0; 
var cycle;
var manifoldON;
global.set('cycle', cycle);
global.set('manifoldON',manifoldON);

if (manifold1 || manifold2 || manifold3 || manifold4 || manifold5 || manifold6) {
 manifoldON = true;   
} else {
 manifoldON = false;
}




msg.payload = cycle;

return msg;

This is what it currently is. I have tried a lot of different things because I was sure hoping to be able to figure it out myself. But I can't get the right syntax. So I deleted all my tries that weren't working.

The problem for me is I need the flow to start when both the pressure is up and a manifold is on, and I need it to keep running until the pressure goes off, even if a manifold turns off. But I don't want it to start if just a manifold or just the pressure turns on. And so everything I have come up with, the flow will start correctly when a manifold is up and the pressure is up, but I haven't been able to figure out how to keep it running when the manifold turns off mid cycle.

 //  cycle = 2; 
//} else if ((cycle!=2) && manifoldON && (pressure > 0)){
//   cycle = 1;
//} else (cycle = 0)
if ((cycle == 1) && (pressure > 0)) {
    cycle = 2;
}

if ((cycle !=2) && manifoldON && (pressure > 0)) {
}  cycle = 1;

This is some of more former tries, but I think I am getting hung up over how a plc scans. It seems it starts the scan of the function node with 'cycle' as 'undefined'. Does it not save the value that it set 'cycle' to the last time I fired the flow??

EDIT: neither of these are complete tries, but it shows you where my mind was running to.

some initial thoughts...

i will post something to help in a minute

Thanks for your tips. They are helpful, but everything you mentioned is working okay. I need help in the machine_running? node. Thanks!

So you dont want my help?

There is nothing wrong with the machine_running node - its your design as a whole - joinng strings, mis-use of the delay node etc etc.

As we touched on before - node-red is event based and you are running it like a PLC - polling everything.

You are setting the global values cycle and manifoldON before you have calculated them. I imagine you meant the manifoldON global set to be after the if/else code.
Then you return cycle in msg.payload but have not set cycle to anything at all.

IMO there is much wrong (and while it may work, you should correct it).

Mostly, you are working like a PLC.

  1. I would change al the nodes from "GET" style to "INPUT" style and be 100% event based.
  2. lose the pointless delay
  3. change those SET_ and Compile_ functions to one function that build a proper object
  4. lose the JSON node

NOTE: It will STILL ouptut the exact same value as before, just that the data will be consistent and correct