Multiple condition Expression - Nested If Statement?

I am trying to make a comparison between 2 tags in an expression tag to show if my symbol is running, faulted, or stopped

what I am going for is

if Tag 1 and Tag 2 are both true = we are in a “running” state
if nothing is true = we are in a “stopped” state

if only tag 1 is true = “faulted”
if only tag 2 is true = “faulted”

I tried using the example from the user manual but I kept having it so if both tags were true it was giving me the “Tag 2 is positive” result instead of the “both tags are positive result” , So I don’t get it because I assumed that spot is for 1st condition false 2nd condition true ,but its the result I get for both conditions being true?

if ({tag1} > 0 , if ({tag2} > 0 , "Both Tags are positive." , "Tag 1 is positive." ), if ({tag2} > 0 , "Tag 2 is positive." , "Neither Tag is positive." ))

1 Like

You say your tags can be true, so are they booleans ?
If so, I’d suggest something like this:

if (tag1 && tag2, "both are true",
    if (tag1 || tag2, "only one is true",
        "both are false"
    )
)

if they’re not, as your code suggest, simply replace tag1 and tag2 with a boolean expression:

if (tag1 > 0 && tag2 > 0, "both are above 0",
    if (tag1 > 0 || tag2 > 0, "only one is above 0",
        "both are 0"
    )
)

Technically, || isn’t an xor operator, but if you reach that point then the check for both are true has already been made, which means if a || b returns true then only one can be true.
The fallback then handles the both are false case.

one is a boolean and one is me checking if something is greater than 0 , would that still work?

Yes, just mix and match. Use the boolean value of the boolean tag directly, and use your comparison for the other one.

if (tag1 && tag2 > 0, "both conditions are true",
    if (tag1 || tag2 > 0, "only one is true",
        "both are false"
    )
)

If it makes it clearer, you can think of it like this:

if (tag1 = true && tag2 > 0, "both conditions are true",
    if (tag1 = true || tag2 > 0, "only one is true",
        "both are false"
    )
)

Except you don’t need to explicitly check for truth if your tag is already a boolean.

1 Like

ah I see, because a true is a 1 right? so its just checking 1 >0

nice, thanks for the help , I didn’t even know you could use && and ||

ill let you know if it works after it runs again

Well, I guess you could technically think about true as 1, but that’s not why I write it like this.
It’s about readability. It doesn’t make much sense with names like tag1 and tag2, but with real names (if you’re following a logical naming convention) it makes things clear and simple.
Let’s say your boolean tag is named something like engine_started, and your value tag is named gear.
To know if you can get your car moving by stepping on the pedal, this is quite clear:

if (engine_started && gear > 0, "car moves",
    if (engine_started || gear > 0, "you're missing one step",
        "you need to turn on the engine and switch on first gear if you want to move"
    )
)

Now, technically, you don’t HAVE to compare gear’s value to 0. If it’s 0, using it in a boolean expression will return false, because it’s 0. You could write

if (engine_started && gear, "car moves",
    if (engine_started || gear, "you're missing one step",
        "you need to turn on the engine and switch on first gear if you want to move"
    )
)

if gear is above 0, then it will be considered true. It will work. But I find gear > 0 brings more meaning to the code. It’s more explicit.

1 Like

its looking like its working!! , thanks again

from the looks of it, it flickers a fault for a second during the transition

so it looks like I need to add a third condition checking that only 1 tag is on for longer then a certain period of time

any idea how I would go about that?

at least that is telling me all 3 of the current conditions are active when they should be

maybe a delay before that or check , does expression have delays?

I’m not sure I understand the issue…
What flickers, and what is the transition you’re talking about ? Can I see the actual thing you’re using ?

the issue is Tag 1 goes true and it takes about half a second before Tag 2 updates over 0

so it will show faulted during that half a second

the if statement you have is working as intended , I just didn’t think of that tiny time in between

You should use binEnc to combine your two tags into a single binary encoded integer. Then use case and test for 0, 1, 2, 4. Using ifs for this is overly complicated

1 Like

Can you show me how you’re using that expression ? It shouldn’t flicker or anything, there’s no reason any amount of time between activations would lead to a fault…

I don’t find 2 simple ifs to be more complicated than abinEnc and a case :X

Ok so tag 1 is a solenoid and tag 2 is the output value that goes up when that solenoid is activated

if solenoid = true and output is greater than 0 then its running as intended

but i wanted to check if for some reason the solenoid comes on by itself, or there is only an output, then i have a problem I can go investigate on the machine

the flicker only happens on the way back down, the output is at 5 , so once the solenoid shuts off it takes a second for the output to go back to 0 , which is the time i get the fault

I don’t see how that would cause a fault (which I understand as ‘makes the expression error out’).
Show us (like, a screenshot or a gif) how you’re using it.

Expression

This expression creates a status based on the 2 tags

status

which is just bound to a pump symbol’s state in perspective , so i can visually see if running stopped or faulted

the output value goes between -.03 and 5 whenever the solenoid comes on so I just used 0 as the check since its default value when its not on is below 0

the output is quick to go from -.03 above 0 because its next to it, but once its up at 5 , it takes time on the way back down

so if the solenoid turns Off the 5 is tripping the Fault check until it gets back down to 0 because it takes 1 second for it to go from 5 - 0

OOOh okay I get it, when you say you get a fault, you mean it’s the status faulted returned by the expression !
I thought you were getting an error while the value was coming back down to 0…

Well, I guess you could throw in timestamp checks on {SolenoidON}… but that gets messy real quick.

is there any way to delay in expressions? if it did the or check 2 seconds after the both check it wouldnt hurt anything

I don’t think it’s a good idea to add a delay to the evaluation itself. But I guess using an intermediate custom property on your pump symbol, and doing some timestamp comparisons to determine if the evaluation should be run, you could manage to effectively delay it…

I can’t do that now (I have my own job to attend to ;p) but if I find some time I’ll see if I can figure something out - though someone else might just come in and give you the answer in the meantime.

1 Like

I am trying to use this if condition in expression binding in ignition perspective. Where it has to return true if the tag values are in limits else false but even though the tag values are out of limits it is returning only true.

 if( ((tag1 > limit_l1) && (tag1 < limit_h1))||
     ((tag2 > limit_l2) && (tag2 < limit_h2))||
     ((tag3 > limit_l3) && (tag3 < limit_h3)) , True, False)