Datachange script executing everytime for memory tag dataset

Dear All
I would like to ask about tag change scripts for memory dataset tag

I have tag with tag event script

if currentValue.value == 1:
	    system.db.runNamedQuery("XXXX","XXXX",params)
	    headers = ["Article", "Size"]
	    data = []
	    data.append([str(int_articleNumberValue[0].value), str(int_sizeNumberValue[0].value)])
	    int_injectedValues = system.dataset.toDataSet(headers, data)    
	    #write to the tag
	    system.tag.write("[default]XXX/XXX/plc_Station"+ str(int_stationNumberValue[0].value) +"Size", int_injectedValues)

this script is writing readed tags and storying values to the 30 memory dataset tag regarding the station number value.

On these memory tags i have another one tag event script, which is sending email when there is a change.

But this script is executing everytime when the coping is done even the values are same.

Is there some possibility to run tag event value change script for memory dataset values only when values in dataset are changed?

Thank you

Dataset “change” is based on object equivalence, and for datasets that is true only for a comparison against itself. You are producing a new dataset, so that will always be a change. Your script will have to do the comparison you wish (row by row) and avoid writing to the memory tag when the contents are equal.

I vaguely recall there being a helper in the SDK API that will do a deep equals check on datasets, but a brief scan of the API didn’t jog my memory. ):

1 Like

This is a little hacky and I hope doesn’t bring down the righteous wrath of @pturmel on my, but you might consider making a second tag that’s is a boolean/bit, maybe call it “dataset_locked”. Then you can write your tag event script like

if currentValue.value == 1 and not system.tag.read("dataset_locked").value:
    system.tag.write("dataset_locked") = True
    system.db.runNamedQuery(“XXXX”,“XXXX”,params)
    headers = [“Article”, “Size”]
    data = []
    data.append([str(int_articleNumberValue[0].value), str(int_sizeNumberValue[0].value)])
    int_injectedValues = system.dataset.toDataSet(headers, data)
    #write to the tag
    system.tag.write("[default]XXX/XXX/plc_Station"+ str(int_stationNumberValue[0].value) +“Size”, int_injectedValues)
    system.tag.write("dataset_locked") = False

Basically the idea is to track when your first change fires off and use that to exclude all other events from happening until your first run through is done, at which point the tag value script is available again. Though with this methodology you might want to use a try/except/finally clause so that you can always finally write that system.tag.write("dataset_locked") = False and make sure a scripting error doesn’t accidentally leave things in a locked state.

The issue is that there's a change on every query, even though the results have the same contents as the prior dataset. Your algorithm doesn't help that.

Oh I misunderstood the issue, I see now. Honestly this seems like a redesign is a little bit in order. Take away the tag change script off the dataset tag that fires too much, and at the end of the script you wrote use a sendMessage that triggers sending a script that sends off emails.

Either that, or use a database table to record what emails you sent already, and use that information in your current tag change script event to prevent sending duplicate emails. Though I don’t have the same set up, my application does have a table of emails sent out to help prevent sending of duplicates. It’s also just nice to keep a record in case you need to go back.

Nah. The original script just needs to deep compare the new dataset against the current dataset, and skip the tag write if the contents match.

Oh now I see. I really should avoid coming here before coffee.

2 Likes

Ok thank you i added

	int_stationArticle = "[default]XXX/XXX/plc_Station"+str(int_stationNumberValue[0].value)+"Size[0,0]"
	int_stationArticleValue = system.tag.readBlocking([int_stationArticle])
	int_stationSize = "[default]XXX/XXX/plc_Station"+str(int_stationNumberValue[0].value)+"Size[0,1]"
	int_stationSizeValue = system.tag.readBlocking([int_stationSize])      	

	if ((str(int_articleNumberValue[0].value) != str(int_stationArticleValue[0].value) or str(int_sizeNumberValue[0].value) != str(int_stationSizeValue[0].value)) and currentValue.value == 1):
		headers = ["Article", "Size"]
		data = []
		data.append([str(int_articleNumberValue[0].value), str(int_sizeNumberValue[0].value)])
		int_injectedValues = system.dataset.toDataSet(headers, data)    
		system.tag.write("[default]XXX/XXX/plc_Station"+ str(int_stationNumberValue[0].value) +"Size", int_injectedValues)

and now it is working correctly thanks