Ejemplo n.º 1
0
class MainWin( wx.Frame ):
	def __init__( self, parent, id = wx.ID_ANY, title='', size=(200,200) ):
		wx.Frame.__init__(self, parent, id, title, size=size)

		self.config = wx.Config(appName="wxExample",
						vendorName="Edward Sitarski",
						style=wx.CONFIG_USE_LOCAL_FILE)
						
		self.SetBackgroundColour( wx.Colour(232,232,232) )
		
		font = self.GetFont()
		bigFont = wx.Font( font.GetPointSize() * 1.5, font.GetFamily(), font.GetStyle(), wx.FONTWEIGHT_BOLD )
		italicFont = wx.Font( bigFont.GetPointSize()*2.2, bigFont.GetFamily(), wx.FONTSTYLE_ITALIC, bigFont.GetWeight() )
		
		self.vbs = wx.BoxSizer( wx.VERTICAL )
		
		self.vbs.Add( setFont(italicFont,wx.StaticText(self, wx.ID_ANY, 'wxExample LLRP Reader Demo')), border = 8, flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL )
		
		self.reset = setFont( bigFont, wx.Button(self, wx.ID_ANY, 'Reset') )
		self.reset.Bind( wx.EVT_BUTTON, self.doReset )
		self.vbs.Add( self.reset, border = 8, flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL )
		
		#------------------------------------------------------------------------------------------------
		# Reader configuration ui.
		#
		gbs = wx.GridBagSizer( 4, 4 )
		self.vbs.Add( gbs, flag=wx.EXPAND|wx.ALL, border = 4 )
		
		iRow = 0
		gbs.Add( setFont(bigFont,wx.StaticText(self, wx.ID_ANY, 'Reader Configuration:')), pos=(iRow,0), span=(1,2), flag=wx.ALIGN_LEFT )
		
		iRow += 1
		self.useHostName = wx.RadioButton( self, wx.ID_ANY, 'Host Name:', style=wx.wx.RB_GROUP )
		gbs.Add( self.useHostName, pos=(iRow,0), span=(1,1), flag=wx.ALIGN_CENTER_VERTICAL )
		hb = wx.BoxSizer( wx.HORIZONTAL )
		hb.Add( wx.StaticText(self, wx.ID_ANY, ReaderHostNamePrefix), flag=wx.ALIGN_CENTER_VERTICAL )
		self.readerHostName = masked.TextCtrl( self, wx.ID_ANY,
							mask         = 'NN-NN-NN',
							defaultValue = '00-00-00',
							useFixedWidthFont = True,
							size=(80, -1),
						)
		hb.Add( self.readerHostName )
		hb.Add( wx.StaticText(self, wx.ID_ANY, ReaderHostNameSuffix), flag=wx.ALIGN_CENTER_VERTICAL )
		gbs.Add( hb, pos=(iRow,1), span=(1,1), flag=wx.ALIGN_LEFT )
		
		iRow += 1
		self.useStaticAddress = wx.RadioButton( self, wx.ID_ANY, 'IP:' )
		gbs.Add( self.useStaticAddress, pos=(iRow,0), span=(1,1), flag=wx.ALIGN_CENTER_VERTICAL )
		self.readerHost = masked.IpAddrCtrl( self, wx.ID_ANY, style = wx.TE_PROCESS_TAB )
		gbs.Add( self.readerHost, pos=(iRow,1), span=(1,1), flag=wx.ALIGN_LEFT )
		
		self.useHostName.SetValue( True )
		self.useStaticAddress.SetValue( False )
		
		#------------------------------------------------------------------------------------------------
		# Add messages
		#
		self.readerMessagesText = wx.TextCtrl( self, wx.ID_ANY, style=wx.TE_READONLY|wx.TE_MULTILINE|wx.HSCROLL, size=(-1,400) )
		self.vbs.Add( self.readerMessagesText, flag=wx.EXPAND, proportion=1 )
		self.readerMessages = MessageManager( self.readerMessagesText )
		
		#------------------------------------------------------------------------------------------------
		# Create a timer to check the message queue.
		#
		self.timer = wx.Timer()
		self.timer.Bind( wx.EVT_TIMER, self.updateMessages )
		self.timer.Start( 1000, False )
		
		self.Bind(wx.EVT_CLOSE, self.onCloseWindow)

		self.readOptions()
		self.SetSizer( self.vbs )
		self.start()
	
	def start( self ):
		self.dataQ = Queue()	# Queue to put messages from the reaader.
		
		rospecID = 123					# Arbitrary rospecID.
		inventoryParameterSpecID = 1234	# Arbitrary inventory parameter spec id.

		# Create a reader connection.
		self.conn = LLRPConnection()

		# Add a callback so we can print the tags.
		self.conn.addHandler( RO_ACCESS_REPORT_Message, self.accessReportHandler )

		# Add a default callback so we can see what else comes from the reader.
		self.conn.addHandler( 'default', self.defaultHandler )

		self.readerMessages.write( 'Connecting to the reader at %s...\n' % datetime.datetime.now() )
		try:
			response = self.conn.connect( self.getReaderHost() )
		except Exception as e:
			self.readerMessages.write( 'Connection to reader failed.\nException:\n%s\n\nCheck address and/or network connection and press Reset.' % e )
			return

		# Compute a correction between the reader's time and the computer's time.
		readerTime = response.getFirstParameterByClass(UTCTimestamp_Parameter).Microseconds
		readerTime = datetime.datetime.utcfromtimestamp( readerTime / 1000000.0 )
		self.timeCorrection = datetime.datetime.now() - readerTime

		self.readerMessages.write( 'Disabling all rospecs...' )
		response = self.conn.transact( DISABLE_ROSPEC_Message(ROSpecID = 0) )

		self.readerMessages.write( 'Delete our old rospec (if it exists).' )
		response = self.conn.transact( DELETE_ROSPEC_Message(ROSpecID = rospecID) )

		self.readerMessages.write( 'Create an rospec that reports every read as soon as it happens.' )
		response = self.conn.transact(
			ADD_ROSPEC_Message( Parameters = [
				ROSpec_Parameter(
					ROSpecID = rospecID,
					CurrentState = ROSpecState.Disabled,
					Parameters = [
						ROBoundarySpec_Parameter(		# Configure boundary spec (start and stop triggers for the reader).
							Parameters = [
								ROSpecStartTrigger_Parameter(ROSpecStartTriggerType = ROSpecStartTriggerType.Immediate),
								ROSpecStopTrigger_Parameter(ROSpecStopTriggerType = ROSpecStopTriggerType.Null),
							]
						), # end ROBoundarySpec
						AISpec_Parameter(				# Antenna Inventory Spec (specifies which antennas and protocol to use)
							AntennaIDs = [0],			# Use all antennas.
							Parameters = [
								AISpecStopTrigger_Parameter( AISpecStopTriggerType = AISpecStopTriggerType.Null ),
								InventoryParameterSpec_Parameter(
									InventoryParameterSpecID = inventoryParameterSpecID,
									ProtocolID = AirProtocols.EPCGlobalClass1Gen2,
								),
							]
						), # end AISpec
						ROReportSpec_Parameter(			# Report spec (specified how often and what to send from the reader)
							ROReportTrigger = ROReportTriggerType.Upon_N_Tags_Or_End_Of_ROSpec,
							N = 1,						# N = 1 --> update on each read.
							Parameters = [
								TagReportContentSelector_Parameter(
									EnableAntennaID = True,
									EnableFirstSeenTimestamp = True,
								),
							]
						), # end ROReportSpec
					]
				), # end ROSpec_Parameter
			])	# end ADD_ROSPEC_Message
		)
		if not response.success():
			self.readerMessages.write( 'ADD_ROSPEC failed.  response:\n%s' % response)
			return

		self.readerMessages.write( 'And enable it...' )
		response = self.conn.transact( ENABLE_ROSPEC_Message(ROSpecID = rospecID) )
		if not response.success():
			self.readerMessages.write( 'ENABLE_ROSPEC failed.  response:\n%s' % response)
			return

		self.readerMessages.write( 'Start thread to listen to the reader...' )
		self.readerMessages.write( 'Listening for reader events...')
		self.conn.startListener()
	
	def gracefulShutdown( self ):
		if self.conn:
			if self.conn.isListening():
				self.conn.stopListener()
			self.conn = None
		self.dataQ = None
	
	def updateMessages( self, event ):
		''' Write all the accumulated reader messages to the screen. '''
		while 1:
			try:
				d = self.dataQ.get( False )
			except Empty:
				break
			message = ' '.join( str(x) for x in d[1:] )
			if d[0] == 'Reader':
				self.readerMessages.write( message )

	def doReset( self, event ):
		self.writeOptions()
		self.gracefulShutdown()
		self.readerMessages.clear()
		wx.CallAfter( self.start )
	
	def onCloseWindow( self, event ):
		self.gracefulShutdown()
		wx.Exit()
		
	def getReaderHost( self ):
		if self.useHostName.GetValue():
			return ReaderHostNamePrefix + self.readerHostName.GetValue() + ReaderHostNameSuffix
		else:
			return self.readerHost.GetAddress()
	
	def writeOptions( self ):
		self.config.Write( 'UseHostName', 'True' if self.useHostName.GetValue() else 'False' )
		self.config.Write( 'ReaderHostName', ReaderHostNamePrefix + self.readerHostName.GetValue() + ReaderHostNameSuffix )
		self.config.Write( 'ReaderAddr', self.readerHost.GetAddress() )
		self.config.Write( 'ReaderPort', str(ReaderInboundPort) )
	
	def readOptions( self ):
		useHostName = (self.config.Read('UseHostName', 'True').upper()[:1] == 'T')
		self.useHostName.SetValue( useHostName )
		self.useStaticAddress.SetValue( not useHostName )
		self.readerHostName.SetValue( self.config.Read(
				'ReaderHostName',
				ReaderHostNamePrefix + '00-00-00' + ReaderHostNameSuffix)[len(ReaderHostNamePrefix):-len(ReaderHostNameSuffix)] )
		self.readerHost.SetValue( self.config.Read('ReaderAddr', '0.0.0.0') )
	
	def defaultHandler( self, message ):
		''' Write to a queue so we can process it later. '''
		self.dataQ.put( ('Reader', ('Unexpected message:\n', message) ) )
	
	def accessReportHandler( self, accessReport ):
		''' Write the access report to a queue so we can process it later. '''
		''' We also could send these directly as a custom event. '''
		for tag in accessReport.getTagData():
			tagID = HexFormatToInt( tag['EPC'] )
			discoveryTime = tag['Timestamp']		# In microseconds since Jan 1, 1970
			discoveryTime = datetime.datetime.utcfromtimestamp( discoveryTime / 1000000.0 ) + self.timeCorrection
			self.dataQ.put( ('Reader', (tagID, discoveryTime.strftime('%Y-%m-%d %H:%M:%S.%f'))) )
Ejemplo n.º 2
0
	def start( self ):
		self.dataQ = Queue()	# Queue to put messages from the reaader.
		
		rospecID = 123					# Arbitrary rospecID.
		inventoryParameterSpecID = 1234	# Arbitrary inventory parameter spec id.

		# Create a reader connection.
		self.conn = LLRPConnection()

		# Add a callback so we can print the tags.
		self.conn.addHandler( RO_ACCESS_REPORT_Message, self.accessReportHandler )

		# Add a default callback so we can see what else comes from the reader.
		self.conn.addHandler( 'default', self.defaultHandler )

		self.readerMessages.write( 'Connecting to the reader at %s...\n' % datetime.datetime.now() )
		try:
			response = self.conn.connect( self.getReaderHost() )
		except Exception as e:
			self.readerMessages.write( 'Connection to reader failed.\nException:\n%s\n\nCheck address and/or network connection and press Reset.' % e )
			return

		# Compute a correction between the reader's time and the computer's time.
		readerTime = response.getFirstParameterByClass(UTCTimestamp_Parameter).Microseconds
		readerTime = datetime.datetime.utcfromtimestamp( readerTime / 1000000.0 )
		self.timeCorrection = datetime.datetime.now() - readerTime

		self.readerMessages.write( 'Disabling all rospecs...' )
		response = self.conn.transact( DISABLE_ROSPEC_Message(ROSpecID = 0) )

		self.readerMessages.write( 'Delete our old rospec (if it exists).' )
		response = self.conn.transact( DELETE_ROSPEC_Message(ROSpecID = rospecID) )

		self.readerMessages.write( 'Create an rospec that reports every read as soon as it happens.' )
		response = self.conn.transact(
			ADD_ROSPEC_Message( Parameters = [
				ROSpec_Parameter(
					ROSpecID = rospecID,
					CurrentState = ROSpecState.Disabled,
					Parameters = [
						ROBoundarySpec_Parameter(		# Configure boundary spec (start and stop triggers for the reader).
							Parameters = [
								ROSpecStartTrigger_Parameter(ROSpecStartTriggerType = ROSpecStartTriggerType.Immediate),
								ROSpecStopTrigger_Parameter(ROSpecStopTriggerType = ROSpecStopTriggerType.Null),
							]
						), # end ROBoundarySpec
						AISpec_Parameter(				# Antenna Inventory Spec (specifies which antennas and protocol to use)
							AntennaIDs = [0],			# Use all antennas.
							Parameters = [
								AISpecStopTrigger_Parameter( AISpecStopTriggerType = AISpecStopTriggerType.Null ),
								InventoryParameterSpec_Parameter(
									InventoryParameterSpecID = inventoryParameterSpecID,
									ProtocolID = AirProtocols.EPCGlobalClass1Gen2,
								),
							]
						), # end AISpec
						ROReportSpec_Parameter(			# Report spec (specified how often and what to send from the reader)
							ROReportTrigger = ROReportTriggerType.Upon_N_Tags_Or_End_Of_ROSpec,
							N = 1,						# N = 1 --> update on each read.
							Parameters = [
								TagReportContentSelector_Parameter(
									EnableAntennaID = True,
									EnableFirstSeenTimestamp = True,
								),
							]
						), # end ROReportSpec
					]
				), # end ROSpec_Parameter
			])	# end ADD_ROSPEC_Message
		)
		if not response.success():
			self.readerMessages.write( 'ADD_ROSPEC failed.  response:\n%s' % response)
			return

		self.readerMessages.write( 'And enable it...' )
		response = self.conn.transact( ENABLE_ROSPEC_Message(ROSpecID = rospecID) )
		if not response.success():
			self.readerMessages.write( 'ENABLE_ROSPEC failed.  response:\n%s' % response)
			return

		self.readerMessages.write( 'Start thread to listen to the reader...' )
		self.readerMessages.write( 'Listening for reader events...')
		self.conn.startListener()