Writing to Database from a Tag Value Change Script

I am trying to add rows to the database every time a tag changes state. Specifically, every time a Boolean tag becomes true, I want to take the name of that tag and add it into a new row in the database table.

I have tried using value change scrips on the tag itself, and inside of the script calling a named query.

I have also tried using query tags, but that did not work either.

Anyone have any advice on a better way to do this?
Thanks

Are you trying to watch/log multiple tags? If so, use a Gateway Tag Change event in a project. Add the target tag(s) to the monitored tag list, and configure your script to check that the value transitioned from 0 to 1 and pull the name of the tag (event.tagPath.toStr()) and insert it into the db table.

This gives you more flexibility than a transaction group, as a Gateway Tag Change event can be set to monitor all tags in a folder by using wildcards.

Do you have a default gateway scoped project set up?


Named queries are scoped to a project, and if the project isn't identified here then the tag event script would be unable to use the resource.

To simplify, use a simple runPrepUpdate on the tag event script.

	if currentValue.value == 1: # rising
		system.db.runPrepUpdate(query, [], "DBConnName")

Do NOT interact with the DB in a Tag Value Change script. You have a limited amount of threads (3) to handle all tag events. Any blocking work will cause issues with other tags. Tag Value Change scripts need to execute in the single digit milliseconds to avoid impacting the tag system.

Use a Gateway Tag Change Event instead. Those spawn threads as needed. They are also much more visible to other engineers (there is a dedicated page on the gateway showing active Gateway Tag Change Event scripts).

2 Likes

In the same project as the Gateway Tag Change event, create a project library script with something along the lines of

def onTagChanged(initialChange, executionCount, newValue, previousValue, event):
	"""  """
	# If script just started or tag just initialized, don't do anything
	if initialChange or not previousValue:
		return

	# Catch Transition from 0 to 1 and log tag path to db
	if not previousValue.value and newValue.value:
		tagPath = str(event.tagPath)
		system.db.runNamedQuery("ThisProject", "InsertTagRecord", params={"tagPath": tagPath})

	return

and call that from the Gateway Tag Change event script, ie onTagChanged(initialChange, executionCount, newValue, previousValue, event)

I am just working on a demo project for now, so I'm only dealing with 3-5 tags I need to track. But I will definitely look into Gateway Tag Change Events, and thank you for linking the manual page, I was looking for that for a while.

I looked and I was missing that part entirely. After adding it back in, the script was able to execute. Thanks for the tip

I think you've marked a bad answer as the correct solution. This will be misleading for anyone asking the same question and finding yours.