Can someone explain why this trans.trigger does not work?

Ignition V7.7.5

(({[~]Nordon/NLSTP02_CastNumber} != {[~]pNLSTP02_CastNumber}) && ({[~]Nordon/NLSTP02_L_Phase}={txD/LOAD_START}))
||
((({[~]Nordon/NLSTP02_L_Phase}={txD/LOAD_END}) || ({[~]Nordon/NLSTP02_L_Phase}={txD/TRANSFER_START}) || ({[~]Nordon/NLSTP02_L_Phase}={txD/TRANSFER_END})) && hasChanged({[~]Nordon/NLSTP02_L_Phase},false))

The first part of the OR statmen works if the condition is met.
The second part never fires even though the ‘Phase’ value does change.
Does this have something to do with the hasChanged event?

Thanks,
Tim

OK, first post was written under pressure last night :frowning:

I’ll try and clarify the issue I’m having below:
I’ve a transaction that is triggered by the state of a PHASE tag.
PHASE=101 => NewBatch
PHASE=102 => Batch Complete
PHASE=103 => Start Transfer
PHASE=104 => Transfer Complete

The PHASE of 101 also needs to ensure that a new BATCHNumber has been received by ignition.
I’m using a PreviousBATCHNumber to compare.
This PreviousBATCHNumber is updated to the new BATCHNumber when the transaction is triggered.

The group trigger is as follows:
1:((PHASE=101) && (BATCHNumber != PreviousBATCHNumber))
2:¦¦
3:(((PHASE=102) OR (PHASE=103) OR (PHASE=104)) && hasChanged(PHASE))

If PHASE goes to 101 and the BatchNumber test is true, the Group will trigger. (Line 1)
If the PHASE now goes to 102/103/104, the Group will no longer trigger.

I’ve come to the conclusion that ‘hasChanged’ operates in an asynchronous manner?
i.e. If PHASE=101 and later changes to 102, the following occurs:
Line 1: PHASE is evaluated; the (PHASE=101) code is evaluated as false; it’s PreviousValue is updated to 102 and hasChanged is TRUE.
Line 3: PHASE is evaluated; the (PHASE=102) code is evaluated as true; however, it’s PreviousValue is now 102 therefore hasChanged is FALSE.

I’ve been assuming that hasChanged would hold its first evaluation state until the expression is fully evaluated.

I’ve re-arranged the Group Trigger expression as follows:

1:(hasChanged(PHASE) && ((PHASE=102) OR (PHASE=103) OR (PHASE=104)))
2:¦¦
3:((PHASE=101) && (BATCHNumber != PreviousBATCHNumber))

This now seems to work correctly.

Can someone please confirm my understanding of this and whether my last expression is correct?
Thanks for any help,
Tim

Hi TimOSullivan,

Your logic is:

condition = A or B

where:

A = a1 and a2

and

B = b1 and hasChanged(b2)

b1 = b1_1 or b1_2 or b1_3

So, to evaluate B, when b1 is false, hasChanged(b2) need not to be executed. For b1 false necessarily implies B false. Thus, the program may not run the hasChanged(b2) at all.

If you want to ensure hasChanged(b2) to be executed, you can put hasChanged(b2) first.

By first, I mean it is really the first:

something like this:

condition = B or A

where,

B = hasChanged(b2) and b1
b1 = b1_1 or b1_2 or b1_3
A = a1 and a2

(Note that the B is put earlier than A)

Suppose only the logic for B is flipped:

condition = A or B

where,

A = a1 and a2
B = hasChanged(b2) and b1
b1 = b1_1 or b1_2 or b1_3

then, if a1 and a2 are both true, B need not to be evaluated -> thus, hasChanged(b2) and and b1 are both skipped.

Hi Ian,
Thanks for the response.

I've actually modified the expression to the one you've outlined by putting the hasChanged first.
This works perfectly.

However, I still think there is an issue with the hasChanged where I used it in the first expression:

The issues is when b1 is True: hasChanged(b2) doesn't trigger.

I suspect that it's because the 'PHASE' tag is used in both b1 and b2.

Thanks again for your help
Tim

Hi TimOSulivan,

[quote=“TimOSullivan”]The issues is when b1 is True: hasChanged(b2) doesn’t trigger.

I suspect that it’s because the ‘PHASE’ tag is used in both b1 and b2.[/quote]

I see… I cannot be sure about the case by looking at your expression alone since I also never encounter such case in Ignition. And since it is a trans.trigger, it is harder to debug what’s going on too since you cannot print debugging message…

[quote=“TimOSullivan”]I’ve come to the conclusion that ‘hasChanged’ operates in an asynchronous manner?
i.e. If PHASE=101 and later changes to 102, the following occurs:
Line 1: PHASE is evaluated; the (PHASE=101) code is evaluated as false; it’s PreviousValue is updated to 102 and hasChanged is TRUE.
Line 3: PHASE is evaluated; the (PHASE=102) code is evaluated as true; however, it’s PreviousValue is now 102 therefore hasChanged is FALSE.[/quote]

This is possible. If b1 is true but hasChanged(b2) doesn’t trigger because it is Async (I assume all these are put in the run-always expression items) and we want to test it. We can check by putting:

condition = B or A

B = b1 and hasChanged(b2)
b1 = b1_1 or b1_2 or b1_3
A = a1 and a2

To make the hasChanged is evaluated the second after b1 and see if it doesn’t work.

Or, we can even check with simpler case:

condition = b1 or hasChanged(b2)

which should always return false.

Thanks Ian,
That last one is clever!

I’ll try it when I get back to site next week.

Keep you updated.
Tim