IF / AND / OR Logic added to Event Handlers?
-
Hey Guys, I'd really like the ability to handle switching MODBUS outputs using logic from inputs.
For example, my water scheme I'm using Mango on I have the following setup that needs to switch solenoid valves...Bore Pump ---> Solenoid Valve Position 1 ---> Top Tank Level Sensor
Position 2 ---> Driveway Tank Level SensorDam Pump ---> Solenoid Valve Position 1 ---> Driveway Tank Level Sensor
Position 2 ---> Main line feedHope you can understand what I'm trying to achieve here. When the tanks are full it needs to stop the pumps that are currently switched to feed that tank.
I know it can be done using scripts but just curious as to how much work would be needed to setup the GUI to handle such logic?
Cheers
Dan -
You could probably do all of this using Event Detectors and Point Links but I'm wondering why you would want to add the complexity when the script to do this is so simple and then you have a single place to maintain it and/or modify it. You can add notes into the script and just so many benefits over a GUI. That said, it's probably not too difficult to make a GUI to do some really basic logic functions but you will always have much more power within a script.
Would it help if we provided some more examples of basic scripts like this?
Joel.
-
Gidday Joel, thanks for the info. It would be very handy if you could give me a head start on the scripts.
I'm ok with PHP type programming but I can never get my head around javascript so lets hope its not all javascript based :-/Cheers
Dan -
Did you read the help file for the Scripting Data Source, it has pretty extensive explanations?
It's not clear from your earlier post what the exact logic is regarding the level sensors but here is a simple example:
You need to add you data points to the context using the drop down list and assig a variable name.
tank level sensor = x
Pump = yif (x.value == 0) // level sensor is 0 when full and 1 when calling for water
{
// This turns the pump off
y.set(0);
}
else if (x.value == 1) // level sensor is 0 when full and 1 when calling for water
{
// This turns the pump on
y.set(1);
}If you can provide a clear description of the logic with the various level sensors and pumps we can give you the exact script to use.
Thanks,
Joel.
-
Gidday Joel, I've had another look at the scripting system and I am still trying to work out the easiest way to achieve what I'm wanting to achieve.
Basicly I want to set a point depending on more than one input. I can't seem to do this with the event handlers, I can only set one point with one input status.
eg:
I have a tank that will tell me if it's low level, then start the pump, BUT, I only want this to happen if the Pump isn't already running, and the Pump isn't already doing another job.
Once the job is finished this should still be in alarm state active so it will check again and start the pump, it also needs to open a solenoid and ensure the other two on the three way setup are closed.I think of it as PLC logic where we can have interlocks using NC and NO contacts, which makes stuff happen depending on weather or not a few other things are in a certain position.
I will upload the latest diagram of my water telemetry setup with some logic stuff...
Cheers
Dan -
I've attached a diagram with the first part of logic / automation I'd like to achieve.
Basically the feature I'm after is the ability to switch a point on or off depending on multiple events rather than one.
Hopefully this might be a simple addition to the event handlers view? It would be great to be able to do this without having to write a script, unless I can get the hang of writing a script :-P
Cheers
DanAttachment: download link
-
I had a play with the scripting, you are right it does seem quite simple when you RTFM again...
should this work? I haven't put the high level stop stuff in yet...
// check if in manual mode at solar pump tank if(p31.value == 0) { // do fuck all } // check if in auto mode else if (p31.value == 1 && p7.value < 5000) { // check pump not running if(p11.value == 0) { // open north solenoid p24.set(1); // close southern solenoid p22.set(0); // close western solenoid p28.set(0); // start pump p11.set(1); } } // check if in manual mode at driveway tank if(p36.value == 0) { // do fuck all } // check if in auto mode at driveway tank else if (p36.value == 1 && p23.value < 5000) { // check pump not running if(p11.value == 0) { // open southern solenoid p22.set(1); // close northern solenoid p24.set(0); // close western solenoid p28.set(0); // start pump p11.set(1); } }
-
Dan,
I'm one of the developers here at Infinite Automation, Joel asked me to take a look at your script.
It looks ok to me. The only suggestion I would make is to be more explicit with the order of operations in the else if statements. I think they will work as is, but I always prefer to ensure that by enclosing things in parentheses.
I re-wrote your code to be a little simpler, but like I said it should work as is.
// check if in auto mode, level low and pump not running if ((p31.value == 1) && (p7.value < 5000) && (p11.value == 0)) { // open north solenoid p24.set(1); // close southern solenoid p22.set(0); // close western solenoid p28.set(0); // start pump p11.set(1); } // check if in auto mode at driveway tank , leve is low and pump not running if ((p36.value == 1) && (p23.value < 5000) && (p11.value == 0)) { // open southern solenoid p22.set(1); // close northern solenoid p24.set(0); // close western solenoid p28.set(0); // start pump p11.set(1); }
Terry
-
Gidday Terry, thanks for that.
I will give it a go and see if it works.
I do need the automatic stuff only to happen if my AUTO/MANUAL point is switched on. I put the whole lot inside another {} loop to achieve this.
There is a separate loop for each tank site.
So the values of '0' and '1' should work as opposed to 'true' and 'false' ?
Oh, and it would be awesome if the script editor allowed indenting in our code ;-P
Cheers
Dan -
You'll see in the script I have a low value and high value, is there any way to take that from a setpoint that the user can set within the graphical interface?
even just a couple of text entry boxes? -
Hi Dan,
Just replace the low values and high values with data points on the scripting data source. Then you can place those data points on a graphic view for users to adjust.
-
Thanks Joel, I've already managed to get the values in there on some virtual data points.
Is the only option to adjust by putting a clickable 'Simple Point' onto the Graphical View, is this correct? Or is there a text box I can use.Cheers
Dan -
No check out the server side script widget. This allows you to do all sorts of things.
Here are some example scripts. The ones with images probably wont work as the image path won't be right but they should be useful:
------------------------------------------------------------------------------ //Server Side Script //Drop Down List ------------------------------------------------------------------------------ var s=""; var idx = 0; s = "<select onchange='idx=this.options(this.selectedIndex).value; \ if (idx == 0) mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"0\"); \ if (idx == 14) mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"14\"); \ if (idx == 32) mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"32\"); \ if (idx == 3) mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"3\"); \ if (idx == 94) mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"94\"); \ if (idx == 55) mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"55\"); \ return value;'> \ <option value=0>Zero</option> \ <option value=14>Fourteen</option> \ <option value=32>ThirtyTwo</option> \ <option value=3>Three</option> \ <option value=94>Ninety Four</option> \ <option value=55>fIFTYFive</option> \ </select>"; return s; ------------------------------------------------------------------------------ //Server Side Script //increase value and image on click ------------------------------------------------------------------------------ var s = ""; if (value == 0) s += "<img style='cursor:pointer;' src='graphics/LDI/startcal-green.gif' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"1\");return 1;'/>"; else if (value == 1) s += "<img style='cursor:pointer;' src='graphics/LDI/startcal-blue.gif' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"2\");return 2;'/>"; else if (value == 2) s += "<img style='cursor:pointer;' src='graphics/LDI/startcal-yellow.gif' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"3\");return 3;'/>"; else if (value == 3) s += "<img style='cursor:pointer;' src='graphics/LDI/startcal-brown.gif' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"0\");return 0;'/>"; return s; ------------------------------------------------------------------------------ //Server Side Script //Decrease the value on click with image: ------------------------------------------------------------------------------ var result = ""; result += "<span onclick='mango.view.setPoint("+ point.id+", "+ pointComponent.id +", \""+ (value - 1) +"\")'>"; result += "<img src='/images/updownarrow/downBenchmark.png'/>"; return result; ------------------------------------------------------------------------------ //Server Side Script //Increase the value on Click with image: ------------------------------------------------------------------------------ var result = ""; result += "<span onclick='mango.view.setPoint("+ point.id+", "+ pointComponent.id +", \""+ (value + 1) +"\")'>"; result += "<img src='/images/updownarrow/upBenchmark.png'/>"; return result; ------------------------------------------------------------------------------ //Server Side Script for point display with decimal place control - change (0) for # of decimals ------------------------------------------------------------------------------ return '<span style="font-size:16px;">'+ value.toFixed(1) +'</span>'; return '<span style="font-size:16px;">Collector: '+ '<font color="blue">'+ value.toFixed(0) +' °F</span>'; ------------------------------------------------------------------------------ //Server Side Script //Toggle on image click ------------------------------------------------------------------------------ var s = ""; if (!value) s += "<img style='cursor:pointer;' src='graphics/Drinks/drink_empty.png' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"true\");return true;'/>"; else if (value) s += "<img style='cursor:pointer;' src='graphics/Drinks/drink.png' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"false\");return false;'/>"; return s; ------------------------------------------------------------------------------ //Server Side Script //Turn on with click but can't turn off ------------------------------------------------------------------------------ var s = ""; if (!value) s += "<img style='cursor:pointer;' src='graphics/LDI/StartPreset-Green.gif' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"true\");return true;'/>"; else if (value) var s = ""; if (value) s += "<img src='graphics/LDI/StartPreset-Yellow.gif'/>"; return s; ------------------------------------------------------------------------------ //Server Side Script //Toggle with text and Image: ------------------------------------------------------------------------------ var s = ""; s += "<a href='#' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \""+ !value +"\");return false;'>Toggle</a>"; s += " its state."; if (value) s += "<img style='cursor:pointer;' src='graphics/Drinks/drink.png' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"false\");return false;'/>"; else s += "<img src='graphics/Drinks/drink_empty.png'/>"; return s; ------------------------------------------------------------------------------ //Server Side Script //On / Off / Toggle text no image: ------------------------------------------------------------------------------ var s = ""; s += "Or, use these scripted controls to turn the light "; s += "<a href='#' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"false\");return false;'>"; s += value ? "Off" : "<b>Off</b>"; s += "</a>, "; s += "<a href='#' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \"true\");return false;'>"; s += value ? "<b>On</b>" : "On"; s += "</a>, or to "; s += "<a href='#' onclick='mango.view.setPoint("+ point.id +", \""+ pointComponent.id +"\", \""+ !value +"\");return false;'>Toggle</a>"; s += " its state."; return s; ------------------------------------------------------------------------------ //Server Side Script //Change from On to off with font format ------------------------------------------------------------------------------ if (!value) return "<span style="font-size:40px;"><font color="gray">Off</span>"; else if (value) return "<span style="font-size:40px;">'+ '<font color="blue">'+' On</span>"; if (!value) return "<span style="font-size:40px;">'+ '<font color="gray">'+ Off</span>"; else if (value) return "<span style="font-size:40px;">'+ '<font color="blue">'+ On</span>"; return s;