Having trouble with tag scripting and data types (apparently)

Hey Everyone,

I'm working with some tag scripting and a named query for the first time. The tag is part of a UDT (probably not important but you never know)

Idea is this: An operator selects a program to run in a furnace. If that value has changed, the value changed script kicks off

The point of the script is to run a named query which will grab the total run time of the program they just picked, the last time it was run in this particular furnace, and then store that time in a memory tag so that we can display on the HMI. The query works fine on it's own when tested.

In the DB, the program number is an integer, the furnace number is an integer, and the run time is set as "numeric" (PostgreSQL) but it's basically a float as it's in minutes (so 35.25 for example represents 35 minutes 15 seconds)

The Program tag is a float (just because that's how the PLC sends it even though its an integer), the Furnace tag is an integer, and the LastRunTime tag is a float.

When I run the script I get" Error trying to coerce '[.]../Furnace' to a number". Here's my script:

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

if currentValue.value != previousValue.value and initialChange == False:

	projectName = "Test_IgnitionSystem"
	namedQuery = "QryLastRunTime"
	
	programNo = "[.]Program"
	furnaceNo = "[.]../Furnace"
			
	parameters = {"Furnace_No":furnaceNo, "Program_No":programNo}
	 
	lastRunTimeVal = (system.db.runNamedQuery(projectName, namedQuery, parameters))
	
	tagPath = "[.]LastRunTime"
	system.tag.writeBlocking(tagPath, lastRunTimeVal)

I feel like I'm not understanding some key piece of information here. Anyone got any ideas?

Thanks much!

Strings containing tag paths do not magically turn into the values of those tags. You need to use system.tag.readBlocking() to do that part.

1 Like

Its always you Phil!

Thank you so much. Big DOH by me. So I've gotten past that now and rewrote the script but Im still not getting the value written to the tag. Am I using the correct syntax for receiving the result of the named query? Here's the updated script. If I add the logger info part I get an error about a number being required so I don't think I'm getting the correct result from the query.

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

if currentValue.value != previousValue.value and initialChange == False:

	logger = system.util.getLogger("myLogger")

	projectName = "Test_IgnitionSystem"
	namedQuery = "QryLastRunTime"
	
	paramPaths = ["[.]Program","[.]../Furnace"]
	param = system.tag.readBlocking(paramPaths)
						
	parameters = {"Program_No":param[0].value, "Furnace_No":param[1].value}
				 
	lastRunTime = (system.db.runNamedQuery(projectName, namedQuery, parameters))
			
	logger.info("last run time = %d"% lastRunTime)
	
	tagPath = "[.]LastRunTime"
	system.tag.writeBlocking(tagPath, lastRunTime)

Not sure. That would be fine for a scalar query. Otherwise you get a dataset, from which you have to extract values at row,column coordinates.

You should always check initialChange before accessing previousValue (order matters with python's and operator) in order to avoid null pointer errors. Avoid "something == False"... Use "not something" instead.

1 Like

Phil you are the best thank you! In retrospect it all makes sense now! Even though I was running a query I knew would only give me one result, it was still coming over as a dataset. Changing that made everything AOK.

Funny too with your second comment about checking initialChange first - I took that line of code directly from the IU video directly! But what you said makes sense to me.

In the hopes it helps someone else, here's my final code:

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

# Make sure the script is firing because of a change to data only and not a change in quality
if not initialChange and currentValue.value != previousValue.value:

	# Set up my project name and named query variables for when I call it
	projectName = "test_IgnitionSystem"
	namedQuery = "QryLastRunTime"
	
	# Set the paths for the two parameters I need to pass the query and read them from the tags
	paramPaths = ["[.]Program","[.]../Furnace"]
	param = system.tag.readBlocking(paramPaths)

	# Set up my parameters for the query based on the tags I just read												
	parameters = {"Program_No":param[0].value, "Furnace_No":param[1].value}

	# Run my named query and put the result in lastRunTime - make sure query is set to scaler			 					 
	lastRunTime = (system.db.runNamedQuery(projectName, namedQuery, parameters))

	# Set my tag path for the location I want to write the result of the query to and write it					
	tagPath = "[.]LastRunTime"
	system.tag.writeBlocking(tagPath, lastRunTime)

Thanks Again Phil!

1 Like