Sequential tag writing script

I am trying to simplify a brute force code to make it cleaner and more scalable.

I have x amount of tags that I want a barcode scanner to load.
The plan is scan 1 is serial 1, scan 2 is part number for serial 1, scan 3 is serial 2 (which must not match serial 1), scan 4 is part number for serial 2(matching part numbers is fine) and so on.

current code is

if len(sn1) <= 1:
system.tag.write(sn_tag1, Text)
elif len(sn1) > 1 and len(sn2) <= 1 and len(pn1) > 1 and sn1 != text:
system.tag.write(sn_tag2, Text)
elif len(sn2) > 1 and len(sn3) <= 1 and len(pn2) > 1 and sn2 != text:
system.tag.write(sn_tag3, Text) AND SO ON

I'm not sure I totally understand the requirements.
Do you have sample data or something you could share to show what the expected inputs and outputs would be in various scenarios?

You might be able to use the next builtin: 2. Built-in Functions — Python 2.7.18 documentation
It would help you return the first value that meets some condition.
I'm not sure where your sn variables are coming from.

#When barcode data recieved, populate correct fields

oven = event.source.parent.Oven
Text = event.source.text
TextMinusLeft = Text.lstrip('T')
p1 = system.tag.read(oven +"/Part Number/Part Number_1").value
p2 = system.tag.read(oven +"/Part Number/Part Number_2").value
p3 = system.tag.read(oven +"/Part Number/Part Number_3").value
p4 = system.tag.read(oven +"/Part Number/Part Number_4").value
p5 = system.tag.read(oven +"/Part Number/Part Number_5").value
p6 = system.tag.read(oven +"/Part Number/Part Number_6").value
p7 = system.tag.read(oven +"/Part Number/Part Number_7").value
p8 = system.tag.read(oven +"/Part Number/Part Number_8").value
p9 = system.tag.read(oven +"/Part Number/Part Number_9").value
p10 = system.tag.read(oven +"/Part Number/Part Number_10").value
p11 = system.tag.read(oven +"/Part Number/Part Number_11").value
p12 = system.tag.read(oven +"/Part Number/Part Number_12").value
p13 = system.tag.read(oven +"/Part Number/Part Number_13").value
p14 = system.tag.read(oven +"/Part Number/Part Number_14").value

j1 = system.tag.read(oven +"/Job Number/Job Number_1").value
j2 = system.tag.read(oven +"/Job Number/Job Number_2").value
j3 = system.tag.read(oven +"/Job Number/Job Number_3").value
j4 = system.tag.read(oven +"/Job Number/Job Number_4").value
j5 = system.tag.read(oven +"/Job Number/Job Number_5").value
j6 = system.tag.read(oven +"/Job Number/Job Number_6").value
j7 = system.tag.read(oven +"/Job Number/Job Number_7").value
j8 = system.tag.read(oven +"/Job Number/Job Number_8").value
j9 = system.tag.read(oven +"/Job Number/Job Number_9").value
j10 = system.tag.read(oven +"/Job Number/Job Number_10").value
j11 = system.tag.read(oven +"/Job Number/Job Number_11").value
j12 = system.tag.read(oven +"/Job Number/Job Number_12").value
j13 = system.tag.read(oven +"/Job Number/Job Number_13").value
j14 = system.tag.read(oven +"/Job Number/Job Number_14").value

Part ID
if Text.startswith("F") and len(Text) >= 6 and len(Text) < 14:
	print Text
	print TextMinusLeft
	if len(p1) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_1", Text)	
	elif len(p1) > 1 and len(p2) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_2", Text)
	elif len(p1) > 1 and len(p2) > 1 and len(p3) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_3", Text)	
	elif len(p1) > 1 and len(p2) > 1 and len(p3) > 1 and  len(p4) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_4", Text)	
	elif len(p1) > 1 and len(p2) > 1 and len(p3) > 1 and  len(p4) > 1 and  len(p5) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_5", Text)
	elif len(p1) > 1 and len(p2) > 1 and len(p3) > 1 and  len(p4) > 1 and  len(p5) > 1 and  len(p5) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_6", Text)	
	elif len(p7) > 1 and  len(p6) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_7", Text)
	elif len(p8) > 1 and  len(p7) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_8", Text)	
	elif len(p9) > 1 and  len(p8) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_9", Text)	
	elif len(p10) > 1 and  len(p9) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_10", Text)	
	elif len(p11) > 1 and  len(p10) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_11", Text)		
	elif len(p12) > 1 and  len(p11) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_12", Text)	
	elif len(p13) > 1 and  len(p12) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_13", Text)	
	elif len(p14) > 1 and  len(p13) <= 1:
		system.tag.write(oven +"/Part Number/Part Number_14", Text)				
Operator ID
elif (Text.isdecimal() and len(Text) >= 3 and len(Text) <= 4) or (Text.startswith("-") and len(Text) == 10):
	system.tag.write(oven +"/Operator", Text)	
 S/N
elif Text.isdecimal() and len(Text) >= 5 and len(Text) <= 7 and Text not in list:
		if len(j1) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_1", Text)	
		elif len(j1) > 1 and len(j2) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_2", Text)
		elif len(j1) > 1 and len(j2) > 1 and len(j3) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_3", Text)	
		elif len(j1) > 1 and len(j2) > 1 and len(j3) > 1 and  len(j4) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_4", Text)	
		elif len(j1) > 1 and len(j2) > 1 and len(j3) > 1 and  len(j4) > 1 and  len(j5) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_5", Text)
		elif len(j5) > 1 and  len(j6) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_6", Text)
		elif len(j6) > 1 and  len(j7) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_7", Text)
		elif len(j7) > 1 and  len(j8) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_8", Text)
		elif len(j8) > 1 and  len(j9) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_9", Text)
		elif len(j9) > 1 and  len(j10) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_10", Text)
		elif len(j10) > 1 and  len(j11) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_11", Text)
		elif len(j11) > 1 and  len(j12) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_12", Text)
		elif len(j12) > 1 and  len(j13) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_13", Text)
		elif len(j13) > 1 and  len(j14) <= 1:
			system.tag.write(oven +"/Job Number/Job Number_14", Text)
Clear text when done	
event.source.text =" 	

It would be helpful to supply some sample barcode scans, like what is Text = event.source.text

SN would just be a 7 digit number
PN would be like 5468M95X01--003 and will follow that format just different numbers in number spot and letters in letter spot length is always the same and dashes are in the same spot also.

Your script is extremely inefficient with all the tag reads.

First,
On each scan, use a regular expression to determine the type of the scan, whether it is a serial or part so bad scans don't get processed That would look something like

import re
# 7 digits = serial number
serialRegex = '\d{7}' 
# This looks for a pattern like 5468M95X01--003, which means it is a part number
partRegex = '\d{4}[A-Z]{1}\d{2}[A-Z]{1}\d{2}--\d{3}' 

scan = event.source.text
isSerial = bool(re.match(serialRegex,scan))
isPart = bool(re.match(partRegex,scan))

if isSerial:
	do something
elif isPart:
	do something else
else:	
	system.gui.errorBox('Unrecognized barcode')
1 Like

Sorry for this one it would be a part number that starts with an F

Does a part number always start with F?

Is there a reason for holding 14 serial/part numbers at a time instead of just the current serial and part? Are they processed in batches of 14?

What I am trying to accomplish with the read is to verify the currently scanned SN is not in the list of SN already scanned into the oven.

So on one oven they can have up to 14 parts with unique sn's and I have another with 51 openings. And I want them to never be able to scan a sn that is already scanned.

I have a similar process where I work. What I do, is I insert a scan into a database where serial numbers must be unique and the database enforces it. That prevents double scans and keeps track of all process history.

insert ignore oven_history (serial, part_number, ...)
values (<serial>, <part>, ...)

The insert ignore part means that if the record already exists, it just skips the insert

If the insert is successful, the query result is 1, otherwise 0.

I could change it so it is looking at the property in the window rather than a tag as I am guessing that would be more efficient.

This is code that has scaled up from one part to now 51 on one oven and possibly more in the future. And I am trying to make it scalable.

I was going to try the Python zip() function but I 1 am not very familiar with it and 2 I couldn't think of a way to increment it so scan 1 just drops in as there is nothing to check against then scan 2 checks sn 1 scan 3 checks sn 1 and sn 2 scan 4 checks sn 1,sn 2, and sn 3 for duplicates and so on based on a variable upper limit.

Have you tried this with a dataset tag?

What I currently do is the scans drop the part into a tag and at the end of the oven cure I push all of the serial number, part numbers, start and stop into a database.

I like your way of doing it I would just have to wrap my head around it a little more for my process.

The tag reads are inefficient because you are reading them one at a time instead of all at once.

tagPaths = ["/Part Number/Part Number_%s" % x for x in xrange(1,15)]
tags = system.tag.readAll(tagPaths)
for tag in tags:
   print tag.value

I recommend inserting the serial/part number pairs one at a time with a batch number that groups the associated serial numbers together (14, 51...). Log the start time at insert, then update the stop time on completion.

How do you handle rows that would need to be cleared?

Example. scan a serial number for part number and then you find that that part can not run for whatever reason.

Do you have a clear button that deletes rows?

You can either have a removal button that simply deletes the serial from the database, or handle the batch scans with a table/dataset tag then insert all at once (more scripting involved). You could also have a field, like defective, in the database where you could simply flag the serial as defective without deleting the scan record.