Perspective barcode scanner

Hi,

I have scanner ScanSKU. This scanner has build in scanner and button to trigger scanner.
I just wonder if I can use this to scan barcode and write in to tag.
So I was able to use button event and scan barcode with camera - but this is not what I want.
I was able to use Input text and build in scanner and button and write it to tag. However, it means somebody need to always keep text field in focus.

So ideal scenario is to scan barcode with build in scanner and button and write in to tag.

Regards
Pawel

Hi Pawel,

Try using a session event script.

https://docs.inductiveautomation.com/display/DOC80/Perspective+Session+Event+Scripts

Hi Jordan

So this is what I have added in to Barcode Scanner. But nothing is happened.


This is working when I have button in the app and use scanner camera as per the instruction in article.
But, when I use build in scanner and build in button nothing has changed.
I is working when I create input text field and use build in scanner and button but when text field lost focus then nothing is scanned.
Based on this I know that app received data just want pass this to the tag.

Regards
Pawel

Sound like it’s working as a keyboard wedge. Are there settings for the scanner portion for output modes?

If I am understanding you correctly, it sounds like what you are looking for is the Barcode Scanner Input component. This component doesn’t require focus and can be configured to accept a keyboard wedge scanner as long as the scanner can be configured to send it’s data with the appropriate prefix/suffix or regex.
If you get the component accepting the scanner data, you can either have a button in the app or create a property change script on the component’s data property to write to the tag.

1 Like

Hi osolorzano
Thanks for replay.
Yes, I am trying to make Barcode Scanner Input to work.
Not sure what do you mean by appropriate prefix/suffix. I thought I need this only if I like to modify barcodes by adding prefix or suffix. In my example barcodes or 2D matrix does not have prefix or suffix just string characters such us “GLW1234567”. So when I used input text field built in scanner and button working find, however it required continuous focus and I think it acting as standard keyboard.

When I used Barcode Scanner Input and app button it opens camera and scan barcodes with no problem.
What I want, is to be able to scan using build in scanner and button. Not sure however how to check if scanner is sending data to app. It does when I used input text field.
The scanner I am using is ScanSKU Android scanner.

Regards
Pawel

The way the input works is if you configure the prefix/suffix property with a character, it will listen and record characters between them. For example, if you set prefix to ! and the suffix property to @. Then start preview mode and type !asdf@, asdf will get recorded.
Your ScanSKU app should have a setting to add prefixes and suffixes. If you set the prefix and suffix for the scanner to be the same as the Barcode Scanner Input, it should then start working because your scanner will send a string of characters like !GLW1234567@ instead of just GLW1234567.

2 Likes

Hi osolorzano

Thanks for your help it is working now. I can see string go through this property,
However, I can’t make Session Event Barcode Scanned to write in to the tag as suggested on Perspective manual.
system.tag.writeAsync(['[default]EVAP/Station_7/Scanner_Input'], [data.text])

Unfortunately this is not working.
So, I tried to set up Barcode scanner input and it works partially as I have scanned only GLW7227932. But it updates Tag with this string
[[GLW7227932, Good, Thu Jan 01 01:00...

So I added custom property to format this in to GLW7227932
Then I have script to add this number in to sql as part of “change script”.

	import datetime
	SerialNO = self.custom.key
	id_Component = 32
	Status = 1
	t_stamp = datetime.datetime.utcnow()


	query = "INSERT INTO Production_Progress (Serial_Number, id_Component, Status, t_stamp ) VALUES (?,?,?,?)"
	args = [SerialNO, id_Component, Status, t_stamp ]
	system.db.runPrepUpdate(query, args)

The problem I have is that even if I scan once system will run this qry 2-3 times.
So I am getting double entries.

My question is:

  1. Why Session Event Barcode Scanned is not working
  2. How to qry once the barcode is scanned.

Regards
Pawel

Sorry for the late reply, the reason the Session Event doesn’t work is because that is specifically for the Scan Barcode Action. That session event is really just meant for mobile devices that have cameras attached to be used like a barcode scanner. An actual barcode scanner like the one you have would use the Barcode Scanner Input and change scripts like you have tried.
That said, I have been unable to reproduce the issue you are seeing of the query being run multiple times. Would you able able to provide a copy of the view you are working with so I can take a look?

Thanks for getting back to me as I stuck with this project.
So here is how I set this up.

  1. I have barcode scanner input. Which is linked to a String Tag.
    However, when I scan any barcode it also fetches, quality, timestamp information.
    image
    I will expect only GLW1232797

So I have created Custom property to give me only barcode string.

  1. On this Custom property I have setup change script to add value in to SQL DB.
  2. All working fine except script below is runned few times, usually about 3 times every time I scan new barcode.
    Script:
def valueChanged(self, previousValue, currentValue, origin):
	"""
	This function will be called when the value of the property changes.

	Arguments:
		self: A reference to the component that is invoking this function.
		previousValue: The previous value, as a qualified value object.
		currentValue: The new value, as a qualified value object.
		origin: The origin of the property value. Possible origin values include
		        Browser, Binding, BindingWriteback, Script, Delegate, Session
	"""
	import datetime
	from time import sleep
	GLW_Current = self.custom.CurrentGLW
	GLW_Last = self.custom.LastGLW
	
	if GLW_Current != GLW_Last:
	
		sleep (2)
		SerialNO = GLW_Current
		id_Component = 32
		Status = 1
		t_stamp = datetime.datetime.utcnow()

		query = "INSERT INTO Production_Progress (Serial_Number, id_Component, Status, t_stamp ) VALUES (?,?,?,?)"
		args = [SerialNO, id_Component, Status, t_stamp ]
		system.db.runPrepUpdate(query, args)
		table = self.getSibling("Table")
		table.refreshBinding("props.data")
		self.custom.LastGLW = GLW_Current
		
	else:
		Status = 0

So I would like to address 2 things.

  1. Why when I scan barcode it also puts info in to tag about quality and timestamp?
  2. Why script is run more than once. Even if the previous value and current is the same?
    These are the results in SQL DB:
    image

Regards
Pawel

Almost every value you interact with within Ignition is actually a Qualified Value of some sort. Qualified Value is an important concept because this is how quality and timing are conveyed throughout the project. If you look at the docstring of valueChanged in the code you provided above, you’ll see that it clearly defines that you will receive a Qualified Value. If you ONLY want your string, try looking at currentValue.value, which will give you the value attribute of the Qualified Value.

THIS is because the QUALIFIED VALUE is NOT the same. See the time stamps in your Database? What happened is you received three entries which were all not equal to one another. The first entry has a Serial_Number of one of our Object classes, the second had a different Serial_Number, and the third had a different t_stamp.

You can probably boil your script down to something simpler, like:

if currentValue.value != previousValue.value:
    # do some stuff

This would only perform the logic if the new value scanned was not equal to the last value scanned.

1 Like

One thing I want to point out with how this is all set up. The binding to the string tag you have is taking what it scanned and turning that qualified value into the value of the tag, which itself will have a qualified value with the value being a stringified qualified value. While not really the source of your issues considering the queries are done from the custom property, I think this can be simplified a bit.

What you can do is put the change script directly onto the props.data property and do a script like:

	import datetime
	
	# Ignore the change script when setting the value to an empty list
	if(len(currentValue.value)>0):
		# Get the currently scanned option and set that to SerialNo
		SerialNo = currentValue.value[0].value
		GLW_Last = self.custom.LastGLW
		if(GLW_Last != SerialNo):
			# Set the other variables
			id_Component = 32
			Status = 1
			t_stamp = datetime.datetime.utcnow()
			
			# Do your sql query here and table refresh
			
			# Set LastGLW
			self.custom.LastGLW = SerialNo
		else:
			Status = 0
			
		# Clear the props.data since it seems like you are
		# just using the most recently completed barcode scan
		self.props.data = []

I tried your script but I am getting this error.

line 5, in valueChanged AttributeError: ‘unicode’ object has no attribute ‘value’

import datetime
if(len(currentValue.value)>0):
		# Get the currently scanned option and set that to SerialNo
		SerialNo = currentValue.value[0].value
		GLW_Last = self.custom.LastGLW.value
		if(GLW_Last != SerialNo):
			# Set the other variables
			id_Component = 32
			Status = 1
			t_stamp = datetime.datetime.utcnow()
			
			query = "INSERT INTO Production_Progress (Serial_Number, id_Component, Status, t_stamp ) VALUES (?,?,?,?)"
			args = [SerialNo, id_Component, Status, t_stamp ]
			system.db.runPrepUpdate(query, args)
			table = self.getSibling("Table")
			table.refreshBinding("props.data")
			
			# Set LastGLW
			self.custom.LastGLW = SerialNo
		else:
			Status = 0
			
		# Clear the props.data since it seems like you are
		# just using the most recently completed barcode scan
		self.props.data = []

Simple answer: GLW_Last = self.custom.LastGLW.value is attempting to reference something which is a str and then get the value attribute. When I mentioned that

What I should have said is “Usually, when you’re referencing something which is not a visible property”. What I mean by that is this: if you can see the property in a property editor, then you can (99%) of the time reference it as a straight value (str, int, float, list), but if you’re looking at currentValue, previousValue, or anything returned from a system.tag scripting call, you’re probably dealing with a QualifiedValue object.

TLDR; change GLW_Last = self.custom.LastGLW.value to GLW_Last = self.custom.LastGLW. When we provide scripts, please always take our suggestion with a grain of salt - we don’t have the same setup and data you have, so there’s almost no chance we’ve actually run the script ourselves, and it is only meant as an example or suggestion.

1 Like