Switch node with loops until 1 of 2 conditions is met

Sorry for the lack of clarity. My intent with the original flowchart at the start of this thread was to show the whole thing, but like you pointed out, thinking about the scheme in a Node-RED way changes it up a bit.

The process starts with a large mass of material on a vibratory scale. The goal is to dispense w kg in n seconds (e.g. 4 kg in 10 seconds). If we dispense 4 kg in 3 seconds, the vibrator stops and the next 10-second round will start in 7 seconds. At the start of each cycle, we need to know the initial weight on the scale. If we precisely dispensed 4 kg in each cycle, and started with 20 kg, then the second cycle would start with an initial weight of 16 kg, the third cylce would start with 12 kg, etc.

In reality, we have over- or under-feeding, but that is allowable. For example, we start at 20 kg and in 10 seconds, we dispense 5 kg (it vibrated off 1 kg more than the msg.payload.dispense value of 4). In that case, the next cycle would have an initial value of 15 kg.

An under-feeding example would be if we start at 20 kg and in 10 seconds, only 1 kg was dispensed. In that case, the next cycle would have an intial value of 19 kg.

If the vibrating took 9.9 seconds, then you're right, the next one starts immediately with virtually no gap. This is also to be expected.

The process ends when all the mass of material on the scale is 0.

To stop when the weight is zero you could feed the weight into a Switch node set to send the message to output 1 when the value is less than 1 (or 0.5 or whatever is appropriate) I would not check for exactly zero as I suspect the sensor may not go exactly to zero sometimes, and to output 2 otherwise. Then feed those into into Change nodes set to change msg.payload to strings close and open respectively, and to set the topic to control, then feed those into a node-red-contrib-simple-gate. Put the gate between the 10 second Inject node and next node and the result will be that the inject messages will get blocked when scales are empty.

Is anything else not working?

That's a smart approach to address whenever the scale is near empty. I will implement it and report back.

Meanwhile, what about having these two items appear on a dashboard?

  1. an n-second countdown timer that coincides with n seconds in the Trigger node
  2. the weight dispensed (ideally updated once per second), i.e. initial - msg.payload.dispense? Do I need to assign a variable name to this? I have tried creating a variable with this value and sending to a chart, but no success.

The simple-gate node works nicely and stops the inject when the weight is <= 5.

Thank you Colin!

[{"id":"94e859bdf0b2c10e","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"1600c410e9ef7425","type":"inject","z":"94e859bdf0b2c10e","name":"Start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"10.01","crontab":"","once":true,"onceDelay":0.1,"topic":"Start","payload":"true","payloadType":"bool","x":110,"y":280,"wires":[["39e67a0686b0b5f2"]]},{"id":"ca7388684c1ed2b7","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"16","payloadType":"num","x":130,"y":660,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"31e3f6d570e61a23","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"14","payloadType":"num","x":130,"y":700,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"da6bf3ebe50437fc","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"13","payloadType":"num","x":130,"y":740,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"627ef94e971e9a87","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"12","payloadType":"num","x":130,"y":780,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"d11829039b7b76f6","type":"change","z":"94e859bdf0b2c10e","name":"topic: weight","rules":[{"t":"set","p":"topic","pt":"msg","to":"weight","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1130,"y":560,"wires":[["94dc8259f3faa4f3"]]},{"id":"9377b8a60d5d56b2","type":"trigger","z":"94e859bdf0b2c10e","name":"","op1":"5.5","op2":"0","op1type":"num","op2type":"num","duration":"10","extend":false,"overrideDelay":false,"units":"s","reset":"0","bytopic":"all","topic":"topic","outputs":1,"x":1030,"y":280,"wires":[["5f352a142459f3bb","7b1d0270c339ebb1"]]},{"id":"7b1d0270c339ebb1","type":"debug","z":"94e859bdf0b2c10e","name":"Vibrator","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1540,"y":280,"wires":[]},{"id":"783c58f6ad3c2c18","type":"inject","z":"94e859bdf0b2c10e","name":"Amount to dispense","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dispense","payload":"4","payloadType":"num","x":150,"y":460,"wires":[["94dc8259f3faa4f3"]]},{"id":"94dc8259f3faa4f3","type":"join","z":"94e859bdf0b2c10e","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1290,"y":460,"wires":[["ac0e1c7a83d98968","27a01dc09a72f0ec"]]},{"id":"5f352a142459f3bb","type":"change","z":"94e859bdf0b2c10e","name":"topic: state","rules":[{"t":"set","p":"topic","pt":"msg","to":"state","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1230,"y":340,"wires":[["94dc8259f3faa4f3"]]},{"id":"ac0e1c7a83d98968","type":"function","z":"94e859bdf0b2c10e","name":"Done?","func":"/* Determines whether vibration is complete and sends \"Off\" when it is\n * msg.payload.state contains vibration state \"On\" or \"Off\"\n * msg.payload.weight contains current weight measurement\n * msg.payload.dispense contains amount to dispense\n * \n*/\nlet initial = context.get(\"initial\") || msg.payload.weight  // pick up starting weight from saved value\n// if not running just keep track of current weight\nif (msg.payload.state === 0) {\n    initial = msg.payload.weight\n    msg = null      // so nothing will be sent at the end\n} else if (msg.payload.weight > initial - msg.payload.dispense) {\n    msg = null      // don't send anything as it is already on, or has been turned off by the Trigger node\n} else \n{\n    msg.payload = 0\n}\n\ncontext.set(\"initial\", initial)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1430,"y":420,"wires":[["9542e62b072701a9","7b1d0270c339ebb1"]]},{"id":"9542e62b072701a9","type":"link out","z":"94e859bdf0b2c10e","name":"Reset trigger","links":["04cacefa8a368a73"],"x":1495,"y":480,"wires":[]},{"id":"04cacefa8a368a73","type":"link in","z":"94e859bdf0b2c10e","name":"reset","links":["9542e62b072701a9"],"x":935,"y":220,"wires":[["9377b8a60d5d56b2","5f352a142459f3bb"]]},{"id":"a497014f24d79d22","type":"comment","z":"94e859bdf0b2c10e","name":"Reset trigger","info":"","x":1050,"y":180,"wires":[]},{"id":"8cdfac5c617f1fe0","type":"comment","z":"94e859bdf0b2c10e","name":"Values from sensor","info":"","x":130,"y":560,"wires":[]},{"id":"a9f4b546eeee6b88","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":130,"y":820,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"5e2ece19ca3c21dc","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"7","payloadType":"num","x":129.00867462158203,"y":857.001708984375,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"27a01dc09a72f0ec","type":"debug","z":"94e859bdf0b2c10e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1450,"y":540,"wires":[]},{"id":"961271629a3f1223","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"18","payloadType":"num","x":130,"y":620,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"39b6434c45181ece","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"6","payloadType":"num","x":130,"y":900,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"6b13cfaaf1721c2e","type":"switch","z":"94e859bdf0b2c10e","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"5","vt":"num"},{"t":"gt","v":"5","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":630,"y":520,"wires":[["a2d705b40ad504ae"],["6c51240f01154e25"]]},{"id":"89f5f19ba03f873a","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"5","payloadType":"num","x":130,"y":940,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"88777b5517db9cb5","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"4","payloadType":"num","x":130,"y":980,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"39e67a0686b0b5f2","type":"gate","z":"94e859bdf0b2c10e","name":"","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","statusCmd":"status","persist":false,"storeName":"memory","x":850,"y":280,"wires":[["9377b8a60d5d56b2"]]},{"id":"a2d705b40ad504ae","type":"change","z":"94e859bdf0b2c10e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"close","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":600,"y":340,"wires":[["39e67a0686b0b5f2"]]},{"id":"6c51240f01154e25","type":"change","z":"94e859bdf0b2c10e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"open","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":420,"wires":[["39e67a0686b0b5f2"]]}]

Set the Function node to have two outputs (in the Setup tab if you are on node-red v2.x). Output 2 will be the amount dispensed. At the start of the Done function add
msg2 = {payload: 0}
Change the lines

} else if (initial - msg.payload.dispense < msg.payload.weight) {
    msg = null      // don't send anything as it is already on, or has been turned off by the Trigger node
} else {
    msg.payload = "Off"
}

to

} else {
    msg2 = {payload: initial - msg.payload.weight}
    if (initial - msg.payload.dispense < msg.payload.weight) {
        msg = null      // don't send anything as it is already on, or has been turned off by the Trigger node
    } else {
        msg.payload = "Off"
    }
}

and change the return at the end to send the messages to the outputs
return [msg,msg2]

Then you can connect output2 direct to the gauge or whatever you want to show the amount dispensed.

Thanks again Colin. The modifications to the Function node indeed allow me to store / plot / do calculations with the amount dispensed.

What do you want to happen after the hopper has run out? As it is, I suspect it will start dispensing again as soon as you start refilling it, before the weight has stabilized.

So the original non-Node-RED system has a secondary vibrator that turns on when the scale reaches 0.5 or something near 0 (empty). For that, I was going to employ a similar approach, i.e. a Join node with state (of vibrator2) + msg.payload.weight + msg.payload.dispense (to specify the upper limit of where to stop).

So in the example of 20 kg dispensing 4 kg every 10 sec, the scale would go down to 16 kg in the first 10s, then 12kg in the next 10s, then 8kg, then 4kg, then to 0kg. When it reaches 0.5kg, it would stop (as it does now), the Simple Gate would close for the Trrigger node to stop the main vibrator, and then I was going to start the "refill the scale" flow using the technique described above.

In real world terms, the cycle time here is not 10s, but 150 seconds. And typically it takes 30 or 45 seconds to dispense the required amount from vibrator 1, and only about 10 sec to do the refill. Delays (as Paul suggested) are also employed at various points to allow settling.

OK, if I understand correctly then that should work provided the refill is complete before the next dispense cycle starts. An alternative would be to close the gate when the hopper is empty (as you already have) but don't open it as soon as the weight goes back above 0.5, but open it later on another signal that indicates the refill is complete.

OK, so I have this working nearly perfect, but I need some help. I put a second Gate node (node-red-contrib-simple-gate) and have it opening when the other Gate node is closed. This allows the flow for the Refill Vibrator to receive its value (7 volts). When the scale weight is <= 5, the Refill signal (7) starts OK, but then is halted by the Gate node once we reach a value higher than 5 (e.g. 6). What I need is for the Gate node to stay open until the msg.payload.weight >= msg.payload.max_wt, as I wrote in the Function node, which in my example is 18.

I think the solution might be to address both Gate nodes with a more comprehensive approach, such as:

  • if the scale weight is <= 5, then close Gate 1 (and thus halt the flow for the Main Vibrator) and open Gate 2.
  • when the scale weight goes above 5, then keep Gate 1 closed until msg.payload.weight >= msg.payload.max_wt. Then close Gate 2 and open Gate 1.

Maybe a more elaborate Function node would be more suitable.

[{"id":"94e859bdf0b2c10e","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"1600c410e9ef7425","type":"inject","z":"94e859bdf0b2c10e","name":"Start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"30.01","crontab":"","once":true,"onceDelay":0.1,"topic":"Start","payload":"true","payloadType":"bool","x":130,"y":260,"wires":[["39e67a0686b0b5f2"]]},{"id":"ca7388684c1ed2b7","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"16","payloadType":"num","x":150,"y":640,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"31e3f6d570e61a23","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"14","payloadType":"num","x":150,"y":680,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"da6bf3ebe50437fc","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"13","payloadType":"num","x":150,"y":720,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"627ef94e971e9a87","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"12","payloadType":"num","x":150,"y":760,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"d11829039b7b76f6","type":"change","z":"94e859bdf0b2c10e","name":"topic: weight","rules":[{"t":"set","p":"topic","pt":"msg","to":"weight","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":870,"y":740,"wires":[["94dc8259f3faa4f3","88b7622453495ab2"]]},{"id":"9377b8a60d5d56b2","type":"trigger","z":"94e859bdf0b2c10e","name":"","op1":"5.5","op2":"0","op1type":"num","op2type":"num","duration":"30","extend":false,"overrideDelay":false,"units":"s","reset":"0","bytopic":"all","topic":"topic","outputs":1,"x":1050,"y":260,"wires":[["5f352a142459f3bb","7b1d0270c339ebb1","186f3b343c07b370","3b687d67bb1b056a"]]},{"id":"7b1d0270c339ebb1","type":"debug","z":"94e859bdf0b2c10e","name":"Main Vibrator","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1610,"y":220,"wires":[]},{"id":"783c58f6ad3c2c18","type":"inject","z":"94e859bdf0b2c10e","name":"Amount to dispense","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dispense","payload":"4","payloadType":"num","x":170,"y":440,"wires":[["94dc8259f3faa4f3"]]},{"id":"94dc8259f3faa4f3","type":"join","z":"94e859bdf0b2c10e","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1310,"y":440,"wires":[["ac0e1c7a83d98968"]]},{"id":"5f352a142459f3bb","type":"change","z":"94e859bdf0b2c10e","name":"topic: state","rules":[{"t":"set","p":"topic","pt":"msg","to":"state","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1270,"y":160,"wires":[["94dc8259f3faa4f3"]]},{"id":"ac0e1c7a83d98968","type":"function","z":"94e859bdf0b2c10e","name":"Done?","func":"/* Determines whether vibration is complete and sends \"Off\" when it is\n * msg.payload.state contains vibration state \"On\" or \"Off\"\n * msg.payload.weight contains current weight measurement\n * msg.payload.dispense contains amount to dispense\n * \n*/\nmsg2 = {payload: 0}\nlet initial = context.get(\"initial\") || msg.payload.weight  // pick up starting weight from saved value\n// if not running just keep track of current weight\nif (msg.payload.state === 0) {\n    initial = msg.payload.weight\n    msg = null      // so nothing will be sent at the end\n} else {\n    msg2 = {payload: initial - msg.payload.weight}\n    if (initial - msg.payload.dispense < msg.payload.weight) {\n        msg = null      // don't send anything as it is already on, or has been turned off by the Trigger node\n    } else {\n        msg.payload = 0\n    }\n}\n\ncontext.set(\"initial\", initial)\nreturn [msg,msg2];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1450,"y":340,"wires":[["9542e62b072701a9","7b1d0270c339ebb1"],["aceff88681a6926c"]]},{"id":"9542e62b072701a9","type":"link out","z":"94e859bdf0b2c10e","name":"Reset trigger","links":["04cacefa8a368a73"],"x":1495,"y":420,"wires":[]},{"id":"04cacefa8a368a73","type":"link in","z":"94e859bdf0b2c10e","name":"reset","links":["9542e62b072701a9"],"x":955,"y":200,"wires":[["9377b8a60d5d56b2","5f352a142459f3bb"]]},{"id":"a497014f24d79d22","type":"comment","z":"94e859bdf0b2c10e","name":"Reset trigger","info":"","x":1010,"y":160,"wires":[]},{"id":"8cdfac5c617f1fe0","type":"comment","z":"94e859bdf0b2c10e","name":"Values from scale","info":"","x":140,"y":540,"wires":[]},{"id":"a9f4b546eeee6b88","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":150,"y":800,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"5e2ece19ca3c21dc","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"7","payloadType":"num","x":149.00867462158203,"y":837.001708984375,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"961271629a3f1223","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"18","payloadType":"num","x":150,"y":600,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"39b6434c45181ece","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"6","payloadType":"num","x":150,"y":880,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"6b13cfaaf1721c2e","type":"switch","z":"94e859bdf0b2c10e","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"5","vt":"num"},{"t":"gt","v":"5","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":520,"wires":[["a2d705b40ad504ae","3ce465305c7f70fe"],["6c51240f01154e25","4854b991964157a2"]]},{"id":"89f5f19ba03f873a","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"5","payloadType":"num","x":150,"y":920,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"88777b5517db9cb5","type":"inject","z":"94e859bdf0b2c10e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"4","payloadType":"num","x":150,"y":960,"wires":[["d11829039b7b76f6","6b13cfaaf1721c2e"]]},{"id":"39e67a0686b0b5f2","type":"gate","z":"94e859bdf0b2c10e","name":"","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","statusCmd":"status","persist":false,"storeName":"memory","x":870,"y":260,"wires":[["9377b8a60d5d56b2"]]},{"id":"a2d705b40ad504ae","type":"change","z":"94e859bdf0b2c10e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"close","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":620,"y":320,"wires":[["39e67a0686b0b5f2"]]},{"id":"6c51240f01154e25","type":"change","z":"94e859bdf0b2c10e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"open","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":380,"wires":[["39e67a0686b0b5f2"]]},{"id":"aceff88681a6926c","type":"ui_chart","z":"94e859bdf0b2c10e","name":"","group":"db172adca8234e63","order":0,"width":0,"height":0,"label":"chart","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":1630,"y":380,"wires":[[]]},{"id":"4a0dd8ea1f863671","type":"inject","z":"94e859bdf0b2c10e","name":"Max weight for scale","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"max_wt","payload":"18","payloadType":"num","x":170,"y":1040,"wires":[["88b7622453495ab2"]]},{"id":"88b7622453495ab2","type":"join","z":"94e859bdf0b2c10e","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1210,"y":840,"wires":[["ce7eb1010a5de738"]]},{"id":"186f3b343c07b370","type":"change","z":"94e859bdf0b2c10e","name":"topic: state","rules":[{"t":"set","p":"topic","pt":"msg","to":"state","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1210,"y":720,"wires":[["88b7622453495ab2"]]},{"id":"3b687d67bb1b056a","type":"debug","z":"94e859bdf0b2c10e","name":"Refill Vibrator","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1720,"y":580,"wires":[]},{"id":"ce7eb1010a5de738","type":"function","z":"94e859bdf0b2c10e","name":"Done?","func":"/* Determines whether vibration is complete and sends \"Off\" when it is\n * msg.payload.state contains vibration state \"On\" or \"Off\"\n * msg.payload.weight contains current weight measurement\n * msg.payload.dispense contains amount to dispense\n * \n*/\nif (msg.payload.weight >= msg.payload.max_wt) {\n    msg.payload = 0\n    // stop refill vibratory unit since max weight has been met\n}\n else {\n        msg.payload = 7\n    }\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1410,"y":840,"wires":[["9c5b2de5115f3004"]]},{"id":"9c5b2de5115f3004","type":"gate","z":"94e859bdf0b2c10e","name":"","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","statusCmd":"status","persist":false,"storeName":"memory","x":1510,"y":680,"wires":[["3b687d67bb1b056a"]]},{"id":"4854b991964157a2","type":"change","z":"94e859bdf0b2c10e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"close","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":820,"y":580,"wires":[["9c5b2de5115f3004"]]},{"id":"3ce465305c7f70fe","type":"change","z":"94e859bdf0b2c10e","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"open","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":760,"y":640,"wires":[["9c5b2de5115f3004"]]},{"id":"db172adca8234e63","type":"ui_group","name":"Default","tab":"19a149e811eb9626","order":1,"disp":true,"width":"10","collapse":false,"className":""},{"id":"19a149e811eb9626","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

Took me a while to work through many "almost" iterations, but I finally got a working two-stage vibratory feeder flow. The refill feeder dispenses material to a scale (up the the payload.max_wt amount). Once that amount is there (> 18 in my example), then the Gate node closes off the refill flow and the weigh vibratory flow dispenses the prescribed amount in 30 seconds using the Trigger node. In my flow, 7 (on the refill vibratory flow) represents 7 volts and 5.5 (on the weigh vibratory flow) represents 5.5 volts, and 4 is the weight amount to be dispensed in 30 seconds. If 4 kg is dispensed in 3 seconds, then the weigh vibratory unit goes from 5.5 to 0 for the next 27 seconds. Once the scale gets down below 5 kg, then the Gate node closes and the refill vibratory flow takes over.

Thanks again to Colin for his help.

[{"id":"b6e79918d2e48f56","type":"tab","label":"Flow 2","disabled":false,"info":""},{"id":"06bfbb799d34dbd3","type":"inject","z":"b6e79918d2e48f56","name":"Start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"30.01","crontab":"","once":true,"onceDelay":0.1,"topic":"Start","payload":"true","payloadType":"bool","x":610,"y":1020,"wires":[["3b3818b1eadfc1ed"]]},{"id":"c60bfd15732cbd6b","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"16","payloadType":"num","x":110,"y":920,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"2d7caab6fe7644ea","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"14","payloadType":"num","x":110,"y":960,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"480f5d9350c6e318","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"13","payloadType":"num","x":110,"y":1000,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"837899fb20024765","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"12","payloadType":"num","x":110,"y":1040,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"f5286e4882762fc6","type":"change","z":"b6e79918d2e48f56","name":"topic: weight","rules":[{"t":"set","p":"topic","pt":"msg","to":"weight","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":970,"y":1460,"wires":[["b0a90f1aaf77c6cb"]]},{"id":"6b4aaae2df611ed3","type":"trigger","z":"b6e79918d2e48f56","name":"","op1":"5.5","op2":"0","op1type":"num","op2type":"num","duration":"30","extend":false,"overrideDelay":false,"units":"s","reset":"0","bytopic":"all","topic":"topic","outputs":1,"x":1150,"y":1020,"wires":[["e586b26490e05add","fada2203c738703d"]]},{"id":"fada2203c738703d","type":"debug","z":"b6e79918d2e48f56","name":"Weigh Vibrator","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1620,"y":1020,"wires":[]},{"id":"2202f10719fa5dcf","type":"inject","z":"b6e79918d2e48f56","name":"Amount to dispense","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"dispense","payload":"4","payloadType":"num","x":1070,"y":1200,"wires":[["b0a90f1aaf77c6cb"]]},{"id":"b0a90f1aaf77c6cb","type":"join","z":"b6e79918d2e48f56","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":true,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":1330,"y":1200,"wires":[["2782c4ddfd62418f","2102e201a7f9ac45"]]},{"id":"e586b26490e05add","type":"change","z":"b6e79918d2e48f56","name":"topic: state","rules":[{"t":"set","p":"topic","pt":"msg","to":"state","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1290,"y":1080,"wires":[["b0a90f1aaf77c6cb"]]},{"id":"2782c4ddfd62418f","type":"function","z":"b6e79918d2e48f56","name":"Done?","func":"/* Determines whether vibration is complete and sends \"Off\" when it is\n * msg.payload.state contains vibration state \"On\" or \"Off\"\n * msg.payload.weight contains current weight measurement\n * msg.payload.dispense contains amount to dispense\n * \n*/\nlet initial = context.get(\"initial\") || msg.payload.weight  // pick up starting weight from saved value\n// if not running just keep track of current weight\nif (msg.payload.state === 0) {\n    initial = msg.payload.weight\n    msg = null      // so nothing will be sent at the end\n} else if (initial - msg.payload.dispense < msg.payload.weight) {\n    msg = null      // don't send anything as it is already on, or has been turned off by the Trigger node\n} else \n{\n    msg.payload = 0\n}\n\ncontext.set(\"initial\", initial)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1470,"y":1160,"wires":[["72c41203ce0ad505","fada2203c738703d"]]},{"id":"72c41203ce0ad505","type":"link out","z":"b6e79918d2e48f56","name":"Reset trigger","links":["bedf876359d48735"],"x":1535,"y":1220,"wires":[]},{"id":"bedf876359d48735","type":"link in","z":"b6e79918d2e48f56","name":"reset","links":["72c41203ce0ad505"],"x":1035,"y":920,"wires":[["6b4aaae2df611ed3","e586b26490e05add"]]},{"id":"9c83c621999b95eb","type":"comment","z":"b6e79918d2e48f56","name":"Reset trigger","info":"","x":1070,"y":880,"wires":[]},{"id":"5331e978845b9b76","type":"comment","z":"b6e79918d2e48f56","name":"Values from scale","info":"","x":120,"y":760,"wires":[]},{"id":"f3b51c51b8c47cff","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"10","payloadType":"num","x":110,"y":1080,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"b2e75279177be22d","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"7","payloadType":"num","x":109.00867462158203,"y":1117.001708984375,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"5640c15684dd97d1","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"18","payloadType":"num","x":110,"y":880,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"97876c426ceaabb8","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"6","payloadType":"num","x":110,"y":1160,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"edbd3f19d04c407c","type":"switch","z":"b6e79918d2e48f56","name":"","property":"payload","propertyType":"msg","rules":[{"t":"lte","v":"5","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":650,"y":1160,"wires":[["943cfced7d427d18"]]},{"id":"33cae89e2e55ce7d","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"5","payloadType":"num","x":110,"y":1200,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"f1d58095f636e15d","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"4","payloadType":"num","x":110,"y":1240,"wires":[["f5286e4882762fc6","edbd3f19d04c407c","dddaed5467c4abe5"]]},{"id":"3b3818b1eadfc1ed","type":"gate","z":"b6e79918d2e48f56","name":"WeighFeederGate","controlTopic":"control","defaultState":"open","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"default","statusCmd":"status","persist":false,"storeName":"memory","x":930,"y":1020,"wires":[["6b4aaae2df611ed3"]]},{"id":"943cfced7d427d18","type":"change","z":"b6e79918d2e48f56","name":"Close Gate","rules":[{"t":"set","p":"payload","pt":"msg","to":"close","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":630,"y":1080,"wires":[["3b3818b1eadfc1ed"]]},{"id":"0fd22328387781be","type":"change","z":"b6e79918d2e48f56","name":"Open Gate","rules":[{"t":"set","p":"payload","pt":"msg","to":"open","tot":"str"},{"t":"set","p":"topic","pt":"msg","to":"control","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":750,"y":960,"wires":[["3b3818b1eadfc1ed"]]},{"id":"f60e30563b3534b9","type":"link in","z":"b6e79918d2e48f56","name":"","links":["2c2f2a6ec379f3d4","28e86387fbfb684a"],"x":655,"y":860,"wires":[["0fd22328387781be"]]},{"id":"44fbb9d7068cb291","type":"inject","z":"b6e79918d2e48f56","name":"Max weight for scale","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"max_wt","payload":"18","payloadType":"num","x":510,"y":540,"wires":[["75a63341a8fbf2c7"]]},{"id":"dddaed5467c4abe5","type":"change","z":"b6e79918d2e48f56","name":"topic: weight","rules":[{"t":"set","p":"topic","pt":"msg","to":"weight","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":600,"wires":[["75a63341a8fbf2c7"]]},{"id":"d25723b3f289dac8","type":"debug","z":"b6e79918d2e48f56","name":"Refill Vibrator","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1480,"y":480,"wires":[]},{"id":"7b6bfdd9d096799c","type":"switch","z":"b6e79918d2e48f56","name":"","property":"payload.weight","propertyType":"msg","rules":[{"t":"lte","v":"payload.max_wt","vt":"msg"},{"t":"gt","v":"payload.max_wt","vt":"msg"}],"checkall":"true","repair":false,"outputs":2,"x":1110,"y":520,"wires":[["2337d05af81d7251"],["fe1fadd118b151c7"]]},{"id":"2337d05af81d7251","type":"change","z":"b6e79918d2e48f56","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"7","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1280,"y":480,"wires":[["d25723b3f289dac8"]]},{"id":"fe1fadd118b151c7","type":"change","z":"b6e79918d2e48f56","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":1280,"y":560,"wires":[["2d8fc5e4c97a25d7","28e86387fbfb684a"]]},{"id":"2d8fc5e4c97a25d7","type":"debug","z":"b6e79918d2e48f56","name":"Refill Vibrator","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1480,"y":560,"wires":[]},{"id":"28e86387fbfb684a","type":"link out","z":"b6e79918d2e48f56","name":"","links":["f60e30563b3534b9"],"x":1415,"y":620,"wires":[]},{"id":"75a63341a8fbf2c7","type":"join","z":"b6e79918d2e48f56","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"2","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":710,"y":560,"wires":[["776c453bee3cbbc3"]]},{"id":"ee6109c11c5db6a1","type":"comment","z":"b6e79918d2e48f56","name":"Weigh Vibratory Feeder","info":"","x":520,"y":900,"wires":[]},{"id":"fb62f965ccae7417","type":"comment","z":"b6e79918d2e48f56","name":"Refill Vibratory Feeder","info":"","x":560,"y":400,"wires":[]},{"id":"725a54b4f3677aa7","type":"inject","z":"b6e79918d2e48f56","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"19","payloadType":"num","x":110,"y":840,"wires":[["edbd3f19d04c407c","f5286e4882762fc6","dddaed5467c4abe5"]]},{"id":"7a53348ba2265f65","type":"status","z":"b6e79918d2e48f56","name":"","scope":["3b3818b1eadfc1ed"],"x":520,"y":480,"wires":[["4299365811c6c21c"]]},{"id":"776c453bee3cbbc3","type":"gate","z":"b6e79918d2e48f56","name":"RefillFeederGate","controlTopic":"control","defaultState":"closed","openCmd":"open","closeCmd":"close","toggleCmd":"toggle","defaultCmd":"close","statusCmd":"status","persist":false,"storeName":"memory","x":930,"y":520,"wires":[["7b6bfdd9d096799c"]]},{"id":"4299365811c6c21c","type":"function","z":"b6e79918d2e48f56","name":"","func":"var status_fill= msg.status.fill;\nmsg.topic=\"control\";\nif(status_fill==\"green\")\n{\n    msg.payload=\"close\";\n}\nelse\n{\n    msg.payload=\"open\";\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":480,"wires":[["776c453bee3cbbc3"]]},{"id":"2102e201a7f9ac45","type":"debug","z":"b6e79918d2e48f56","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1440,"y":1280,"wires":[]}]
1 Like

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