Function node - Connect output to input

I'm implementing a valve check for my irrigation system. Basically I'm switching valves on and off in a certain sequence and timing, and I'm monitoring the water consumption in between, using mqtt in and out messages. Implementation is a function node with a state machine that is receiving two type of messages, mqtt water messages and event state transition messages, and is emitting two type of messages as well, mqtt valve switch messages and event state transition messages. The event state transition messages are emitted by node.send() within a setTimeout callback to one of the outputs and are routed back to the node itself.

My issue is that node-red does not like me to create the path from the output back to the input of the same node.

How would you go about this? Route it via a no-op function node?

Kind regards, Sebastian

For good reason - you can very easily end up with a loop that crashes node-red.

A state machine in a function node is not really the ideal node-red way - you hide the visual flow aspect inside a function node.

Is your logic so complex you couldn't avoid a state machine and do this in flow logic?

yes - or indeed use a delay node as that timeout.

Not sure what to say here. I guess with flow logic it would be possible ...

// 7:50 Überprüfe Hauptventilfunktion

var t5 = {
    mainoff: {topic:"t5/set/10",payload:{valve:"OFF"}},
    mainon: {topic:"t5/set/10",payload:{valve:"ON"}},
    valve2s: {topic:"t5/set/6",payload:{"valve,1":2}},
    alert: {topic:"t5/alert",payload:"Valve check error, "},
}
var st = context.get("st")
var mqtt = [];

function after(ms,sn) {
    st.hl = 0;
    st.sn = 1;
    setTimeout(function(){node.send([{event:sn},null]);},ms);
}

function t5error(error) {
    if (error) {
        mqtt = [t5.mainoff,{topic:t5.alert.topic,payload:t5.alert.payload+error+" "+(st.hl/2.0).toFixed(1)+"l"}];
        flow.set("valvecheckerror",true);
    } else {
        flow.set("valvecheckerror",false);
    }
    st.sn = 0;
}

if (st===undefined) {
    st = {sn:0};
    context.set("st",st); // Changes to st below will be reflected in the context store
}

if (st.sn==1 && msg.event>1) {
    st.sn = msg.event;
}

switch (st.sn) {
case 0: // Switch main valve on, ignore flow the first five seconds, then check for one minute that no water flows
    if (msg.event=="start") {
        mqtt = [t5.mainon];
        after(5000,2);
    }
    break;
case 1: // Count the half liters being consumed
    if (msg.payload.topic=="hl") {
        st.hl++;
    }
    break;
case 2: // Check for one minute that no water is in use
    after(60000,3);
    break;
case 3:
    if (st.hl) { // We detected water running when preparing the test. Flag error.
        t5error("in use");
    } else { // Open pond valve for 2 seconds and check for 5 seconds that the water consumption is as expected between 1.5 and 2.5 liters
        mqtt = [t5.valve2s];
        after(5000,4);
    }
    break;
case 4:
    if (st.hl<3 || st.hl>5) { // Our opening of the valve2s has resulted in unexpected water use
        t5error("strange");
    } else { // Close main valve and wait one second, then open pond valve again
        mqtt = [t5.mainoff];
        after(1000,5);
    }
    break;
case 5: // Open pond valve for two seconds and check for 5 seconds that no water is consumed with the main valve closed
    mqtt = [t5.valve2s];
    after(5000,6);
    break;
case 6:
    if (st.hl) { // We detected water running despite the main valve closed. Flag error.
        t5error("not off");
    } else { // Open main valve again and clear error. Note: Opening main valve will repressurise the system resulting in a slight flow
        mqtt = [t5.mainon];
        t5error();
    }
    break;
}
return [null,mqtt];

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.