Inserting PLC values into a table with a Gateway Event Tag Change Script

Hi all,

I have created a Named Query that inserts two parameters (values) into a table. I would like to have a Gateway Tag Change Script that runs the Named Query when a PLC tag changes and provides the PLC values to the Named Query.

Here is my admittedly very ugly Gateway Tag Change Script:

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):	
	LiftRaised = system.tag.readBlocking(["[default]Station/ACell_15/Stations/Unload/PLC/Lift raised"])[0].value
	if previousValue.value != currentValue.value and initialChange == False and currentValue.value == 1 and LiftRaised == True:
		CycleTime = system.tag.readBlocking(['[default]Station/ACell_15/Stations/Unload/StationCycleTime'])[0].value - system.tag.readBlocking(['[default]Station/ACell_15/Stations/Unload/CycleCountdownTime'])[0].value
		Delta =system.tag.readBlocking(['[default]Station/ACell_15/Stations/Unload/StationCycleTime'])[0].value - CycleTime
		#system.tag.writeBlocking(["[.]../HistorianTags/CompletedCycleTime", "[.]../HistorianTags/CycleDelta"], [CycleTime, Delta])
		parameters = {'CompletedCycleTime':CycleTime, 'CycleDelta':CycleDelta}
		system.db.runNamedQuery(ACell_15_Data_Insert, parameters)

It does not have errors that I can find, but on the tag change nothing happens :frowning:

Am I going about this correctly? Can this even work? I have been stuck on this for a while and would really appreciate some help!

Thank you,
Luke M. Smith

edit: here is my named query script


INSERT INTO ACell15_Pacing
	(CompletedCycleTime, CycleDelta)
VALUES
	(:CompletedCycleTime, :CycleDelta)

Is this script exactly as you posted it, what you have in the script window of the Gateway Tag Change Script?

If so, then nothing is happening because you are defining a function, but then never calling it. so it never gets executed.

Instead what you should do is create a Library Script perhaps something like this:

def insertCycleData():
    tagPaths = ['[default]Station/ACell_15/Stations/Unload/StationCycleTime', '[default]Station/ACell_15/Stations/Unload/StationCycleTime']
    cycleTime, cycleDelta = [qv.value for qv in system.tag.readBlocking(tagPaths)]
    system.db.runNamedQuery('ACell_15_Data_Insert', {'CompletedCycleTime':cycleTime, 'CycleDelta': cycleDelta})

Then your Tag Change script could be simply:

LibraryName.insertCycleData()

Here is the User manual page on Gateway Tag Change Scripts, that will show how to do things like check against initial change.

1 Like

That's a tag value change script, not a gateway event.

Start by just logging things, to make sure they are actually what you think they are.

Actually, I suspect that it started as a Tag value change script, but is being refactored as a Gateway Tag Change event.

Based on previous context, that arguably you wouldn't have if you didn't know to go look.

1 Like

yup you are correct. I copy-pasted and left out the row starting with "def". But then I was getting errors and adding the "def" line in fixed it. Once this project is over im going back to the basics to learn from the ground up. Thanks for all your help,lrose.

It fixed the errors because it made the whole thing obsolete - the function doesn't run, so it can't produce errors.

I believe that's the code you want for a gateway event tag change script:

if not initialChange and newValue.value == 1:
	paths = [
		"[default]Station/ACell_15/Stations/Unload/PLC/Lift raised",
		"[default]Station/ACell_15/Stations/Unload/StationCycleTime",
		"[default]Station/ACell_15/Stations/Unload/CycleCountdownTime"
	]
	lift_raised, station_cycle_time, cycle_countdown_time = [qv.value for qv in system.tag.readBlocking(paths)]
	if lift_raised:
		cycle_time = station_cycle_time - cycle_countdown_time
		cycle_delta = station_cycle_time - cycle_time
		parameters = {
			'CompletedCycleTime': cycle_time,
			'CycleDelta': cycle_delta
		}
		system.db.runNamedQuery("ACell_15_Data_Insert", parameters)
1 Like

This works like a charm! thank you both.

@lrose I really like your idea of using the library object. I set up the def insertCycleData() script in the project library and then changed my Gateway Tag Change Script to LibraryName.insertCycleData(). It did not work, so I hardcoded values and simplified it as much as possible to learn how it works. I could not get it to work. Is there more setup I need with this method?

LibraryName is just a place holder. So, for instance say you added a new script to the project library that you named, myScript. You place your function definition inside of that script resource.

Then you would call that like this:

myScript.insertCycleData()

Since I don't know what you named your script resource (or if you placed it in a folder) then I cant tell you exactly what the call should be. So long as the script and event are defined inside the same project there is nothing else that needs to be done for this to work.

I actually should have included that part in my answer.
There are weird things happening in gateway event scripts and you should get the habit of not coding in them, but just calling scripts that are in your library.

I suspected that was the case. thank you again!

I moved my script into a library script per these recommendations. Now when I save my project, my table gets an overlay error until the process is ran and it updates. Is there a way to avoid this?

I haven't used it but have a look at the Table component's emptyMessage.noData documentation.

Perfect, Thank you Transistor