Reset tag values to zero

Dear Team, Hope you are doing well. I am currently working on resetting all the tag values to zero irrespective of its data type. I am facing some difficulties can you help me with some logic please.

I would like to change all the tag path's value to zero at once during specific time, Requesting your support please

What is 0 for a string ? For a dataset ? For a boolean ? Even for a numeric type, actually: Is 0 really the default you need to reset to ?

What do you want/expect to happen with non-memory tags ?

But more importantly: Why ?

5 Likes

When you say

Do you really mean ALL of the tags inside a tag provider or ALL of the tags in a specific list of tags? I get the impression, based on your other post on another thread, that it's on a list of tags.
Also,

It helps us to know what exacly are you finding dificult, do you already have a code that isn't working and throwing some unexpected error? Or no code at all at the moment?
At least for me, this kind of operation makes more sense to be done by the PLC.
At last, you can try this out, it's not very elegant but might work if you adapt it to your scenario:

#Your initial list of tags. Remember that now we don't have 
#the .dataType added at the end, we're adding it later.
tagList = ["New Folder/New Tag",
		   "New Folder/New Tag 1",
		   "New Folder/New Tag 2",
		   "New Folder/New Tag 3",
		   "New Folder/New Tag 4",
		   "New Folder/New Tag 5",
		   "New Folder/New Tag 6"]

#now we create a list of tagpaths to be read but with 
#.dataType added at the end because that's all we need.
tagListRead = [tag + ".dataType" for tag in tagList]

#Another list that first reads the tags from tagListRead
#then from the qualified value we get only the .value part
#then convert to a string so we can compare them easily
tagValues = [str(tag.value) for tag in system.tag.readBlocking(tagListRead)]

#list of what we'll consider a numeric dataType
numeric = ("Int4",
		   "Float8",
		   "Float4",
		   "Int8")

#We initialize a list of values we're going to write back
#to the inital tags
values = []

#Now we populate the values list based on the datatype
for dataType in tagValues:
	if dataType in numeric:
		values.append(0)
		print 
	elif dataType == "String":
		values.append("")
	elif dataType == "Boolean":
		values.append(False)
	else:
		
		values.append(None)
		print "DataType: %s NOT FOUND"%(dataType)
system.tag.writeBlocking(tagList, values)
1 Like

Thanks a lot for your quick helping hands @leonardo.godoi, I really appreciate it. Let me give a try the script that you have shared

Thanks for your questions @pascal.fragnoud . Its a business requirement where all tag values reset should be incorporated due to shift timings,

Irrespective of tag types - all the numeric data type should be reset to 0 and string needs to be reset to "Null".

It's a business requirement where all tag values reset should be incorporated due to shift timings,

I suggest that this is the wrong approach. You will be much better off with never-resetting counters that allow you to quickly calculate total production between any two timestamps. Have the database record the count at the end of each shift and subtract that value from the current count if you want to know the shift count.

Irrespective of tag types - all the numeric data type should be reset to 0 and string needs to be reset to "Null".

That should read, "Respective of tag types, ...".

I would like to change all the tag path's value to zero ...

It seems that you meant a list of tags, not all tags. You should add clarification to your original post but leave it so that anyone reading it can understand the answers already given.

4 Likes

You will most likely eventually pay the price for this. What happens when your system has a couple hundred thousand tags, are you going to lockout all operations until the reset can occur?

It is quite simple to do this, but as the system grows it will take more and more time to process.

As @Transistor said, I would strongly encourage whomever can make this decision to reconsider this policy.

All of that being said the best way to handle this is (if you actually meant all tags) in a scheduled gateway event script (do not run this on any GUI thread).

You did not provide a "zero" value for Boolean, Dates, Datasets, Documents, or Any of the Arrays. So, I haven't handled them. Adding another type other than Boolean to the dataTypes to be zeroed will break the script.

results = system.tag.browse("[Provider]RootFolder", {"tagType":"AtomicTag","recursive":True}).results
dataTypes = ('Int1','Int2','Int4','Int8','Float4','Float8','String')
tagResets = [(result['fullPath'],'Null' if str(result['dataType']) == 'String' else 0) for result in results if str(result['dataType']) in dataTypes]
tagPaths,tagValues = zip(*tagResets)
system.tag.writeAsync(tagPaths,tagValues)
3 Likes

@leonardo.godoi great thanks :pray: I tried the script and it works great, I have a small request

Instead of manually adding the tag paths in the tag list, I would like to dynamically add tag paths associated with the respective tag folder (Ex:[default]Test)

So I can avoid manually adding the tag paths

See my script.

2 Likes

The easiest way I found to do this is setup up a gateway timer script. Below is one I have been using for awhile.

#get current date and time
now = system.date.now()
dayOfMonth = system.date.getDayOfMonth(now)
hour = system.date.getHour24(now)
minute = system.date.getMinute(now)
second = system.date.getSecond(now)
#equipment list
equipment = [1734,1747,1752,1756,1770,1786,1787,1795,1799,
         	1803,1806,1809,1813,1814,1815,1816,1818,1821,1822,1823,1824,1825,1826,1827,1828,1829,
         	1830,1831,1832,1833,1834,1845,1852,1854,1856,1857,1861,1862,1863,1867,1873,
         	1875,1877,1878,1879,1881,1883,1884,1885,1887,1888,1891,1892,1893,1894,1895,1896,
         	10838,10851,10852,10859,10861,10894,10899,10900,10901]

#moves downtime hours, downtime timer, and state(if state is 1 then it moves it to 0 and the writes a 1 back at the start of the new month)
if dayOfMonth == 1 and hour == 0 and minute == 0 and second == 0:
         
        for x in equipment:
			if system.tag.read("[default]Moblie/Downtime" + str(x) + "State").value == 1:
				system.tag.write("[default]Moblie/Downtime" + str(x) + "State", 0)
				system.tag.write("[default]Moblie/Downtime" + str(x), 0)
				system.tag.write("[default]Moblie/Downtime" + str(x) + "Timer", 0)
				system.tag.write("[default]Moblie/Downtime" + str(x) + "State", 1)
			else:
				system.tag.write("[default]Moblie/Downtime" + str(x), 0)
				system.tag.write("[default]Moblie/Downtime" + str(x) + "Timer", 0)


I know you didn't ask for it, but..

  • put the reset logic in a library script WITHOUT the date thing
  • call that script in a scheduled event (not a timer script) configured to run at midnight on the first day of the month
  • set up a list of tags and read/write them all at the same time with system.tag.readBlocking and system.tag.writeBlocking instead of individually

If you have difficulties writing it let us know, we'll give you a hand.
Hint: I like itertools.product to build lists of tags

1 Like