MemoryTag - valueChange does not trigger

I have a counter that increments the tag "Counter" one by one, and a valueChange function associated to the same tag that performs a series of actions (although they do not come to the case, I will mention them anyway). The problem is that, while the counter increments, the valueChange script is not executed at any time.

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
	limit_counter = system.tag.readBlocking("[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Max_Counter")[0].value
	print limit_counter
	if currentValue.value >= limit_counter:
		print "first condition"
	 	Old_controlValue = system.tag.readBlocking("[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Old_controlValue")[0].value
	 	New_controlValue = system.tag.readBlocking("[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/New_controlValue")[0].value
	 	controlValue_path = str(system.tag.readBlocking("[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/controlValue_path")[0].value)
		if Old_controlValue != New_controlValue:
			print "second condition"
			system.tag.writeBlocking(controlValue_path, Old_controlValue)   
			system.tag.writeBlocking("[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Counter_Start", False)
			system.tag.writeBlocking("[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Fail", True)
		
			if Old_controlValue == 2:
				print Old_controlValue
				system.tag.writeBlocking("[BALEN]System/TEST/TagTest_RTU/word/tag_test", 2)
			elif Old_controlValue == 1:
				print Old_controlValue 
				system.tag.writeBlocking("[BALEN]System/TEST/TagTest_RTU/word/tag_test", 1)

What am I doing wrong? or what is the correct way for the valueChange to be executed as the counter increments?

many regards.

Prints are never going to be viewable. Use system.util.getLogger | Ignition User Manual , log your statements. I would also log your limitcount and currentValue.value just to be sure you are getting what you expected. Check your gateway logs after trying it again to see what logs come through.

Not that you can't do this on a tag's valueChange event either but there is a lot of info on the forum why it is preferential to create a Gateway Tag Change vent and then monitor the appropriate tag(s), instead of making the valueChanged on the tag directly. Though I don't see this being your issue right now.

1 Like

They're viewable you just have to know where to look.

This point can not be overstated here. This script, particularly with the number of blocking calls, is inappropriate as a tag valueChanged event script.

All of that being said, I see nothing syntactically incorrect about this script, which leads me to what information leads you to believe the script isn't executing?

3 Likes

Oh interesting, I still would say logger is best practice as you can label the logger and define priority levels. But good to know!

Also, read/writeBlocking functions expect lists of tags and values so they should be in [ ].

Technically, readBlocking() is now documented as accepting either a single string or a list of strings.

Write blocking on the other hand, isn't documented, but I believe it will accept it.

2 Likes

What I am trying to do is that after certain seconds, if the value of controlValue has not changed, then I assign the value of oldValue. However, this is not happening, so I am placing the print every time a condition is met to debug the code.

You are expecting a valueChanged() event when the value hasn't changed? Why would you think that would happen?

If you want to monitor for stale/old/unchanged values, you need a separate event, typically a timer event.

hi Phil

If in this case I have a gateway timer event that is triggered when I click on the button, it is then when I activate the counter with a limit of 110 seconds. What I try to do is the following: if, after 110 seconds, the current value (currentValue.value) is greater or equal to the limit of the counter (limit_counter) and the value of the control (controlValue) is different from the value of the indicator (indicatorValue), then I write the previous value (oldValue) in the tag that communicates with the RTU. Previously, I already get both the oldValue and the newValue in the button.

Is that what you mean by separating the events?

Not sure that this is something that should be handled with Ignition. Sounds like PLC work.

That said, seems like a project library script with system.util.invokeLater() to delay the execution would be what you want to use.

Also note that reads and writes should be combined. Just do all of your reads right away at the beginning.

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
    limit_counter, Old_controlValue, New_controlValue, controlValue_path = [tag.value for tag in system.tag.readBlocking("[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Max_Counter","[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Old_controlValue","[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/New_controlValue","[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/controlValue_path")]
	print limit_counter
	if currentValue.value >= limit_counter:
        writePaths = []
        writeVals = []
		print "first condition"
		if Old_controlValue != New_controlValue:
			print "second condition"
            writePaths += [str(controlValue_path), "[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Counter_Start", "[BALEN]System/Button_Saved_States/PCS_Comms_Enable_Disable/Rack_level/rack_prueba/Fail"]
            writeVals += [Old_controlValue, False, True]
		
			if Old_controlValue == 2:
				print Old_controlValue
                writePaths += ["[BALEN]System/TEST/TagTest_RTU/word/tag_test"]
                writeVals += [2]
			elif Old_controlValue == 1:
				print Old_controlValue 
                writePaths += ["[BALEN]System/TEST/TagTest_RTU/word/tag_test"]
                writeVals += [1]
                
            system.tag.writeBlocking(writePaths,writeVals)

This makes no sense. Gateway timer events trigger themselves on a set pace. How are you trying to get a 110 second time?

image

the Counter tag increments by 1, when it is greater than the Max_limit , then it will execute the valueChange logic

What is the real problem you are trying to solve? There is probably a much better way of doing it.

what I am looking for, is that if within 110 seconds, the required value (1 or 2) does not arrive, then we send again the value in which it was before, for example. 1 enable 2 disable, if I want to disable it and in the course of 110 seconds, I do not receive a response from the RTU/PLC then I return to the previous state which is the 1.

I still don't understand what this control system is trying to do.

Instead of creating Max_Counter,

  • Create a memory tag of type DateTime. Call it timeoutStart or similar. Update this at the start of the timeout period.
  • Create an expression tag timeout of type Boolean. Set the expression to
    now() - {[timeoutStart]} > 110000
    Use the tag change event to call a gateway script when this changes. The first line should check if it has turned false and return. Otherwise do what has to be done.
1 Like

I have realized that I was sending a string to an integrer tag and that is why the change was not being made....

I still thank everyone for their comments and suggestions that I have learned in this post.

many regards