How do I integrate an RFID scanner with HMI?

Hello all, we have already integrated password validation through our LDAP for accessing sensitive areas of our HMI, but we would only like to maintain that option of validation for supervisors when they are at a desktop. I have a handy dandy pcProx Plus I am experimenting with that would fit the bill for our manufacturing environment. It just plugs right into the thin client’s USB. I had scripts available that leverage the PyUSB library but when I attempted to integrate them into Ignition I found out that it is not part of standard Jython currently. If all else fails I will just write it in Java and introduce it that way. But before I do all that I just thought I would see if there was an option to import external Python libraries in Ignition7.7 (I already have the script). Or perhaps an even easier solution? Thanks

Yes, there is an option to import external Python libraries in Ignition 7.7.

See this forum post: inductiveautomation.com/for … 71&t=12803

See this article: perfectabstractions.com/blog … on-modules

Best,

Thanks Nick! This looks just like the info I needed. I got into something else right now so I’ll probably try the scanner again on Monday and I’ll post the results

Sounds great.

Placing the built PyUSB module in Ignitions pylib directory would work if Ignition’s Jython interpreter would let me use the ctypes module which is a PyUSB dependency. When I received an error because of an absence of the ctypes module I built it and placed it in the pylib directory. I then received errors whenever the ctype module tried to wrap the c libraries. Unless there is a way to get this module to work with Jython I guess I will have to go ahead with a java solution.

Yes, it looks like the support for ctypes is limited in Jython 2.5.

Hello all. For anyone interested my original intent was to communicate directly with these PcProx RF readers we have gotten from RFIDEAS. Their readers are configured to extract the information from the cards and send it to the thinclient as keystrokes. I wanted to speak directly to the device to negate the possibility of someone trying to bypass it with another input device. After scratching my head a little I had an A-Ha! moment. The PcProx readers can be configured to prepend or postpend characters to the card’s input. so I created a key to match my device input. It is now too easy. I create a password text box and hide it (still has to be visible to get focus) and create an event to give the text box focus to receive the reader’s input . I use a handy dandy Python slice to separate my key from the badge data then use a few conditionals to check first for illegal input devices(invalid key) and then for matching user with appropriate role in my authorization group. Simple yet effective enough for our needs for now. If anyone else has tried to use RFID scanners with their HMIs I would love to hear your solutions.

I know this is old, but happen to have the code you used?

Actually I do. It has evolved and is much better now. would you like it?

1 Like

I sure would. Just got my first RFID badge reader, and am looking to do the same thing.

Thanks in advance!

-Lenny

###########_THIS FUNCTION TAKES STRING FROM RFID READER CARD SCAN AND VERIFIES USER IN DATABASE BEFORE RETURNING THEIR ROLES
#Parameter= window: string name of current main window
#########################################################

	def verifyUser(self, window):
		key = '<we use a three character prefix>'
		tstamp = system.db.dateFormat(system.tag.read("[System]Client/System/CurrentDateTime").value, "yyyy-MM-dd HH:mm:ss")
		window = system.gui.getWindow(window)
		data = window.rootContainer.getComponent('txtRFIDinput')
		IdNoVldte = data.text[:3]
		IdNo = data.text[3:]
		if IdNoVldte==key:	##if the key doesn't match someone is attempting an intrusion	
			url = "http://000.00.00.00/v1/employee/creds.php" #insert your own URL
			params = {"k":"<privateAPIkeyyou can make your own>", "id":IdNo}	
			result = system.net.httpPost(url, params)
			if result.find('firstname') == -1:
				roles= [{'role': 'none'}]
				system.tag.write("[Client]IdNo", IdNo)
				data.text = ""
				return roles			
			else:
				personalData = system.util.jsonDecode(result)
				cmnname = personalData['firstname']+" "+personalData['lastname']
				roles = personalData['roles']
			#if len(roles)<=0:
				#system.gui.warningBox("Your access is denied! If you believe this is an error please see a supervisor")
				#system.db.runUpdateQuery("INSERT INTO rfidlogins (`datetime`, `rfidtag`, `action`, `cmnname`, `task`) VALUES ('"+tstamp+"', '"+IdNo+"', 'DENIED', 'unlisted user', 'none')")
				#data.text = ""
			#else:
			tags = ["[Client]tstamp", "[Client]IdNo", "[Client]cmnname"]
			vals = [tstamp, IdNo, cmnname]
			system.tag.writeAll(tags, vals)
			data.text = ""
			return roles
		else:
			data.text = ""
			
#--------------------end-verifyUser----------------------------------------------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

This is an example function you could use. We use this function in a project level script in all of our projects that have our RFID readers, which at this point is almost the entire factory. We even track when the employees go on break. So you will of course have to have a text input field on every open page requiring the use of the reader. Make sure the text field is visible make it as small as you can and move it to the very back layer so no one can mess with it. Then you have to activate it. On some projects I only need one page and I use a single timer on the page and I activate and deactivate the timer with navigation buttons, but I will show you the one I use for our Press lines.

lc = project.Line1_6.core()
x = system.tag.read("[Client]clientWindow").value
if len(system.gui.findWindow('MAIN1'))==1:
	window = system.gui.getWindow('MAIN1')
	data = window.rootContainer.getComponent('txtRFIDinput')
	data.requestFocusInWindow()
	entry = data.text
	if len(entry) >= 6:
		if x != "MAIN1":
			system.tag.write("[Client]clientWindow", "MAIN1")
			window = system.tag.read("[Client]clientWindow").value
		else:
			window = x
		roles = lc.verifyUser(window)
		lc.getRoles(roles)
	else:
		pass
elif len(system.gui.findWindow('HEAT1'))==1:
	window = system.gui.getWindow('HEAT1')
	data = window.rootContainer.getComponent('txtRFIDinput')
	data.requestFocusInWindow()
	entry = data.text
	if len(entry) >= 6:
		window = x
		roles = lc.verifyUser(window)
		lc.getRoles(roles)
	else:
		pass
elif len(system.gui.findWindow('DIAGNOSTICS'))==1:
	window = system.gui.getWindow('DIAGNOSTICS')
	data = window.rootContainer.getComponent('txtRFIDinput')
	data.requestFocusInWindow()
	entry = data.text
	if len(entry) >= 6:
		window = x
		roles = lc.verifyUser(window)
		lc.getRoles(roles)
	else:
		pass
else:
	pass

I’ll see if I can find the original which wrote to Ignitions user DB but I can’t promise anything. this way was better for us because we were able to send the data to our Domino server and allow the factory supervisors to control employee access so they weren’t bothering us every other day. So take a look at this and send me your questions if you have any. This can be done so many ways that it can almost make your head spin. Good luck I’m here if you need it, Erik

1 Like

sorry forgot to mention the second script is used as a client timer script.

How about that I just realized today that a snippet of the old code is still present in the commented out warning box section. We just stopped responding if the card had no credentials at some point and I commented it out just in case they wanted it added, but I never updated it’s data source. So that commented out section shows how to send it to an internal Ignition user DB. So all you have to do is set one up.

Thanks Eric, we have a request from a customer for RFID logins, haven’t got the job yet, but thanks for posting your solution. I’ll let you know how I go, if we get the go-ahead. Cheers!