Trouble updating boolean tag in change script

I have 2 tags High Force 1 and OffsetForce 1. I have another tag (Time passed) that's keeping track of minutes since a button click. After 3 mins, I check whether HF 1 is within +-5% of OF 1. If it's not within that range I want to change the value of a boolean tag to true.

So in Time passed, I wrote this change script but my boolean tag never changes to true even though HF 1 is outside the range:

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):

    highF = system.tag.readBlocking('[Ignition_Bond_Press]Press 1/High Force 1')[0]
    offsetF = system.tag.readBlocking('[Ignition_Bond_Press]Press 1/OffsetForce 1')[0]
    if currentValue.value >= 3.00:
	   if highF < (offsetF * 0.95): 
		   if highF > (offsetF * 1.05):
			   system.tag.writeBlocking("[Ignition_Bond_Press]Press 1/Alert", True)
		   else:
			   system.tag.writeBlocking("[Ignition_Bond_Press]Press 1/Alert", False)
    else:
	    system.tag.writeBlocking("[Ignition_Bond_Press]Press 1/Alert", False)``

The logic is flawed here.
If highF is Below the range, it will write false to the tag.

I assumed you made sure the timer tag is actually incrementing.

edit: made the script a bit easier to read
edit2: and what @lrose said.

edit3: @lrose script makes more sense, use this instead.

You're not checking the actual value of the tags for highF or offsetF. Plus you should really read and write all of the tags at the same time.

readBlocking() returns a list of QualifiedValues, you are just referenceing the first QV, but not the actual value of that tag, so if-else clause is not evaluated the way you think that it should be.

Try code similar to this:


if currentValue.value >= 3.00:
    highF, offestF = system.tag.readBlocking(['[Ignition_Bond_Press]Press 1/High Force 1','[Ignition_Bond_Press]Press 1/OffsetForce 1'])
    lowLimit = offsetF.value * 0.95
    highLimit = offsetF.value * 1.05
    system.tag.writeBlocking(['[Ignition_Bond_Press]Press 1/Alert'],[ not (lowLimit < highF.value < highLimit)])

Edit for explanation:

Because this is in a Tag Value Changed Script, we want the script to execute a quickly as possible, so if the current value isn't within range don't do anything. Which is why I put everything within the first check.

1 Like

how is the last line changing the boolean tag?

You want the script to write False if the highF is not within the limits.

That expression is short hand for the following:

lowLimit < highF.value and highF.value < highLimit

This will evaluate True if highF is within the limits, so we invert it with a not , however, we need to insure that we evaluate the expression prior to inversion so we enclose it in parenthesis.

not (lowLimit < highF.value < highLimit)

Python will evalueate the expression and return true or false prior to the call to writeBlocking()

4 Likes

Consider, for the sake of you and everyone who comes after you, separating boolean expressions like that into standalone variables to make their logic and purpose more clear:

if currentValue.value >= 3.00:
    highF, offestF = system.tag.readBlocking(['[Ignition_Bond_Press]Press 1/High Force 1','[Ignition_Bond_Press]Press 1/OffsetForce 1'])
    lowLimit = offsetF.value * 0.95
    highLimit = offsetF.value * 1.05
    isInRange = lowLimit < highF.value < highLimit
    system.tag.writeBlocking(['[Ignition_Bond_Press]Press 1/Alert'],[not isInRange])
3 Likes

So how would it change Alert back to false if highF does change into within range?

In exactly the same way it changes it to true if it is out of range.

The expression evaluates to either True or False on each execution, that is then written to the tag.

I thought so, but then I did some test runs and I noticed that once Alert becomes true it doesn't change to false even when I change highF to within the range

I'm really not sure, the only thing that I can suggest is to put some logging into the script to verify the code is executing the way you think it is. Assuming that the code executes, if the highF value is within the range, then False should be written to the tag.

I forgot to take into account that I was testing with negative numbers. Once I used abs(), it worked

2 Likes