液顯ID讀卡器UDP協(xié)議開發(fā)Python小程序。代碼如下:
# pip install netifaces import subprocess import struct import threading from PyQt5.QtGui import QFont import os import socket import re import datetime import netifaces from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt, QThread, pyqtSignal, QDateTime from PyQt5.QtWidgets import QApplication, QWidget, QDesktopWidget, QMessageBox, QCheckBox from SockUdpReaderPyqt5UI import Ui_Frame from WIFISetUp import Ui_wifiwin from NetParaSetup import Ui_NetParaWin from ISO15693RW import Ui_ISO15693RW import sys Bindip = "" Bindprot = 0 listen = 0 changip = 0 LastBuf = bytes(9) # 保存最后接收到的信息,用于比較是否重復接收的信息 CardNuff = bytearray() # 保存C3主動讀取IC卡扇區(qū)數(shù)據(jù) class MyDialog(QThread): # 對話框線程 sig = pyqtSignal(object) def run(self): self.sig.emit('') class SockListenThread(QThread): # Socket端口偵聽線程 Sock_data = pyqtSignal(int, str, bytes) # 創(chuàng)建一個信號,將接收到的數(shù)據(jù)交給槽函數(shù)處理 def run(self): global LastBuf global CardNuff while listen == 1: try: data, addr = s.recvfrom(1024) RemortIPort = '%s:%s' % addr self.Sock_data.emit(0, RemortIPort, data) except: self.Sock_data.emit(1, 'Socket端口偵聽線程正在重啟...', bytes(0)) # 讀寫15693標簽 # ======================================================================================================================= class ISO15693RW(QWidget, Ui_ISO15693RW): iso15693Signel = pyqtSignal(str, bytes) def __init__(self): super().__init__() self.setupUi(self) self.pushButton_setrwblock.clicked.connect(self.pushButton_setrwblock_clicked) self.pushButton_readcard.clicked.connect(self.pushButton_readcard_clicked) self.pushButton_writecard.clicked.connect(self.pushButton_writecard_clicked) mainWindow.rw15693Signel.connect(self.getrw15693inf) def open(self): self.show() def closeEvent(self, event): mainWindow.setEnabled(True) def getrw15693inf(self, code, remoiport,dispinf): #接收到主窗口更新顯示的信號 if (remoiport==self.lineEdit_RemoIPort.text().strip()): if (code == 1): self.lineEdit_RWCardno.setText(dispinf) elif (code == 2): self.plainTextEdit_Data.setPlainText(dispinf) elif (code == 3): self.lineEdit_disp.setText(dispinf) def pushButton_setrwblock_clicked(self): # 設置15693網(wǎng)絡讀寫器 主動讀卡塊號,未選擇塊號則讀取UID卡號上傳 self.lineEdit_disp.setText('') RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "遠程設備IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return afi = self.spinBox_AFI.value() masklen = self.spinBox_masklen.value() cardmask = self.lineEdit_Mask.text().strip() try: maskbuf = bytes.fromhex(cardmask) if (len(maskbuf) != 8): QMessageBox.critical(self, "警告", "掩碼必須是16位16進制數(shù)!", QMessageBox.Yes) self.lineEdit_Mask.setFocus() return except: QMessageBox.critical(self, "警告", "掩碼必須是16位16進制數(shù)!", QMessageBox.Yes) self.lineEdit_Mask.setFocus() return blocks = 255 # 塊數(shù)取255,表示每次更新所有參數(shù)區(qū) sendbuf = bytes([eval('0x47')]) # 1字節(jié)指令碼 sendbuf = sendbuf + bytes.fromhex('0000') # 2字節(jié)機號 0000表示任意機 sendbuf = sendbuf + bytes([masklen]) # 1字節(jié)掩碼長度 sendbuf = sendbuf + bytes.fromhex(cardmask) # 8字節(jié)掩碼 sendbuf = sendbuf + bytes([afi]) # 1字節(jié)AFI sendbuf = sendbuf + bytes([blocks % 256]) + bytes([blocks // 256]) # 2字節(jié)的塊數(shù) seleblock = '' j = 0 for i in range(64): self.chckbox = self.findChild(QCheckBox, "checkBox%d" % (i)) if self.chckbox.isChecked(): seleblock = '1' + seleblock else: seleblock = '0' + seleblock if (len(seleblock) == 8): sendbuf = sendbuf + bytes([int(seleblock, 2)]) seleblock = '' j = j + 1 for i in range(j, 32): sendbuf = sendbuf + bytes([0]) sendbuf = sendbuf + bytes.fromhex('55AA6699') self.iso15693Signel.emit(RemoIPort, sendbuf) def pushButton_readcard_clicked(self): #發(fā)指令驅動15693讀寫器讀指定塊號數(shù)據(jù) self.lineEdit_disp.setText('') self.plainTextEdit_Data.setPlainText('') RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "遠程設備IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return sendbuf = bytes([eval('0x30')]) # 1字節(jié)指令碼 sendbuf = sendbuf + bytes.fromhex('0000') # 2字節(jié)機號 0000表示任意機 if (self.radioButton_thiscard.isChecked()): # 讀寫指定卡號的卡片 RWCardNo = self.lineEdit_RWCardno.text().strip() try: rwcardbuf = bytes.fromhex(RWCardNo) if (len(rwcardbuf) != 8): QMessageBox.critical(self, "警告", "讀寫卡號必須是16位16進制數(shù)!", QMessageBox.Yes) self.lineEdit_RWCardno.setFocus() return else: sendbuf = sendbuf + bytes([64]) + rwcardbuf[::-1] # 注意傳入的卡號高位在前 except: QMessageBox.critical(self, "警告", "讀寫卡號必須是16位16進制數(shù)!", QMessageBox.Yes) self.lineEdit_RWCardno.setFocus() return else: # 讀寫感應區(qū)上任意卡 sendbuf = sendbuf + bytes([0]) + bytes.fromhex('0000000000000000') afi = self.spinBox_AFI.value() sendbuf = sendbuf + bytes([afi]) # 指定AFI seleblock = '' blockflaglen = 0 blockflag = bytes() for i in range(64): self.chckbox = self.findChild(QCheckBox, "checkBox%d" % (i)) if self.chckbox.isChecked(): seleblock = '1' + seleblock blockflaglen = i + 1 else: seleblock = '0' + seleblock if (len(seleblock) == 8): blockflag = blockflag + bytes([int(seleblock, 2)]) seleblock = '' sendbuf = sendbuf + bytes([blockflaglen % 256]) + bytes([blockflaglen // 256]) # 2字節(jié)的塊數(shù) j = (blockflaglen + 7) // 8 sendbuf = sendbuf + blockflag[0:j] sendbuf = sendbuf + bytes.fromhex('55AA6699') self.iso15693Signel.emit(RemoIPort, sendbuf) def pushButton_writecard_clicked(self): #發(fā)指令驅動15693讀寫器寫數(shù)據(jù)到指定塊內 self.lineEdit_disp.setText('') writestr=self.plainTextEdit_Data.toPlainText().strip() if (writestr==''): writestr='塊號:00 數(shù)據(jù):01020304n' writestr =writestr+ '塊號:01 數(shù)據(jù):05060708n' self.plainTextEdit_Data.setPlainText(writestr) QMessageBox.critical(self, "警告", "請按此格式輸入要寫入的數(shù)據(jù)!", QMessageBox.Yes) j=0 k=4 #一般NXP每塊都是 4 個字節(jié) datainfostr="" writearray = writestr.split('n') for i in range(0,len(writearray)): if (len(writearray[i])>0): blockinfostr=writearray[i].split(":") if (len(blockinfostr)>=2): block='%02X' % (int(blockinfostr[1][0:2])) writedata=blockinfostr[2].strip() if (i==0 and len(writedata)==16): k=8 #本次寫入的是每塊有 8 個字節(jié)的卡片,如富士通的MB89R118 if (len(writedata)==k*2): datainfostr=datainfostr+block+writedata j=j+1 else: QMessageBox.critical(self, "警告", "第 "+block+" 塊的數(shù)據(jù)不正確!", QMessageBox.Yes) return if (k==4 and j==20): QMessageBox.information(self, "警告", "每塊4字節(jié)的卡片,一次最多寫20塊,多于20塊請分次寫入!", QMessageBox.Yes) break if (k==8 and j==10): QMessageBox.information(self, "警告", "每塊8字節(jié)的卡片,一次最多寫10塊,多于10塊請分次寫入!", QMessageBox.Yes) break if (j==0): QMessageBox.critical(self, "警告", "請按樣本輸入正確的寫卡數(shù)據(jù)!", QMessageBox.Yes) return RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "遠程設備IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return sendbuf = bytes([eval('0x31')]) # 1字節(jié)指令碼 sendbuf = sendbuf + bytes.fromhex('0000') # 2字節(jié)機號 0000表示任意機 if (self.radioButton_thiscard.isChecked()): # 讀寫指定卡號的卡片 RWCardNo = self.lineEdit_RWCardno.text().strip() try: rwcardbuf = bytes.fromhex(RWCardNo) if (len(rwcardbuf) != 8): QMessageBox.critical(self, "警告", "讀寫卡號必須是16位16進制數(shù)!", QMessageBox.Yes) self.lineEdit_RWCardno.setFocus() return else: sendbuf = sendbuf + bytes([64]) + rwcardbuf[::-1] # 注意傳入的卡號高位在前 except: QMessageBox.critical(self, "警告", "讀寫卡號必須是16位16進制數(shù)!", QMessageBox.Yes) self.lineEdit_RWCardno.setFocus() return else: # 讀寫感應區(qū)上任意卡 sendbuf = sendbuf + bytes([0]) + bytes.fromhex('0000000000000000') afi = self.spinBox_AFI.value() sendbuf = sendbuf + bytes([afi]) # 指定AFI sendbuf = sendbuf + bytes([k]) # 每塊字節(jié)數(shù),15693卡每塊的字節(jié)數(shù),大多卡為每塊4個字節(jié),富士通15693卡有一些型號是8個字節(jié) sendbuf = sendbuf + bytes([j]) # 本次總計寫塊數(shù),如果每塊4字節(jié) 一次最多可寫20塊, 每塊8字節(jié)一次最多寫10塊 sendbuf = sendbuf + bytes.fromhex(datainfostr) # 本次寫入的每塊數(shù) sendbuf = sendbuf + bytes.fromhex('55AA6699') # 固定的后綴 self.iso15693Signel.emit(RemoIPort, sendbuf) # 設置讀卡器網(wǎng)絡參數(shù)========================================================================================================= class NetParaSetwindow(QWidget, Ui_NetParaWin): netparaSignel = pyqtSignal(str, bytes) def __init__(self): super().__init__() self.setupUi(self) self.pushButton_computerIP.clicked.connect(self.pushButton_computerIP_clicked) self.pushButton_broadcast.clicked.connect(self.pushButton_broadcast_clicked) self.pushButton_computerMAC.clicked.connect(self.pushButton_computerMAC_clicked) self.pushButton_gateway.clicked.connect(self.pushButton_gateway_clicked) self.pushButton_gatewayMAC.clicked.connect(self.pushButton_gatewayMAC_clicked) self.pushButton_SetupNew.clicked.connect(self.pushButton_SetupNew_clicked) self.pushButton_SetupOld.clicked.connect(self.pushButton_SetupOld_clicked) self.radioButton_RemoMACAuto.toggled.connect(self.radioButton_RemoMACAuto_changeEvent) self.radioButton_Gatwayauto.toggled.connect(self.radioButton_Gatwayauto_changeEvent) self.pushButton_SetTCP.clicked.connect(self.pushButton_SetTCP_clicked) self.pushButton_SetHttp.clicked.connect(self.pushButton_SetHttp_clicked) def open(self): self.show() def closeEvent(self, event): mainWindow.setEnabled(True) def pushButton_computerIP_clicked(self): self.lineEdit_RemoIP.setText(mainWindow.CBIP.currentText().strip()) self.lineEdit_RemoMAC.setText(get_mac_address(mainWindow.CBIP.currentText().strip())) def pushButton_broadcast_clicked(self): self.lineEdit_RemoIP.setText("255.255.255.255") self.lineEdit_RemoMAC.setText("FF-FF-FF-FF-FF-FF") self.radioButton_RemoMACAuto.setChecked(True) return def pushButton_computerMAC_clicked(self): self.lineEdit_RemoMAC.setText(get_mac_address(self.lineEdit_RemoIP.text())) def pushButton_gateway_clicked(self): self.lineEdit_Gatwag.setText(get_default_gateway()) self.lineEdit_GatwayMAC.setText(get_mac_address(self.lineEdit_Gatwag.text())) def pushButton_gatewayMAC_clicked(self): self.lineEdit_GatwayMAC.setText(get_mac_address(self.lineEdit_Gatwag.text())) def radioButton_RemoMACAuto_changeEvent(self): if (self.radioButton_RemoMACAuto.isChecked()): self.lineEdit_RemoMAC.setText("FF-FF-FF-FF-FF-FF") def radioButton_Gatwayauto_changeEvent(self): if (self.radioButton_Gatwayauto.isChecked()): self.lineEdit_GatwayMAC.setText("FF-FF-FF-FF-FF-FF") def pushButton_SetupOld_clicked(self): # 固件日期為2015年以前設備的網(wǎng)絡參數(shù)設置 self.plainTextEdit_Disp.setPlainText(" ") DevNo = int(self.lineEdit_ReaderNnm.text()) DEvIp = self.lineEdit_ReaderIP.text() DevMask = self.lineEdit_ReaderMask.text() ServeIp = self.lineEdit_RemoIP.text() SerialNum = self.lineEdit_Serial.text() sdata = bytes([eval('0xF0')]) # 1字節(jié)指令碼 try: FieldsList = DEvIp.split('.') HexStr = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備IP sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備IP地址輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderIP.setFocus() return try: FieldsList = DevMask.split('.') HexStr = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備子網(wǎng)掩碼 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備子網(wǎng)掩碼輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderMask.setFocus() return try: FieldsList = ServeIp.split('.') HexStr = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備遠程服務器IP sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備遠程服務器IP輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIP.setFocus() return try: HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備機號輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderNnm.setFocus() return try: FieldsList = SerialNum.split('-') HexStr = FieldsList[0] + FieldsList[1] + FieldsList[2] + FieldsList[3] # 4字節(jié)設備網(wǎng)出廠序號 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備出廠序號輸入錯誤!", QMessageBox.Yes) self.lineEdit_Serial.setFocus() return sdata = sdata + bytes([self.comboBox_beep.currentIndex()]) if (self.checkBox.isChecked()): RemoIPort = "255.255.255.255:39169" else: RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "遠程設備IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return self.netparaSignel.emit(RemoIPort, sdata) def pushButton_SetupNew_clicked(self): # 固件日期為2015年以后設備的網(wǎng)絡參數(shù)設置 self.plainTextEdit_Disp.setPlainText(" ") if (self.radioButton_RemoMACAuto.isChecked()): self.lineEdit_RemoMAC.setText("FF-FF-FF-FF-FF-FF") if (self.radioButton_Gatwayauto.isChecked()): self.lineEdit_GatwayMAC.setText("FF-FF-FF-FF-FF-FF") DevNo = int(self.lineEdit_ReaderNnm.text()) DEvIp = self.lineEdit_ReaderIP.text() DevMask = self.lineEdit_ReaderMask.text() DevPort = int(self.lineEdit_ReaderPort.text()) DevGetway = self.lineEdit_Gatwag.text() GetwayMac = self.lineEdit_GatwayMAC.text() ServeIp = self.lineEdit_RemoIP.text() ServerMac = self.lineEdit_RemoMAC.text() SerialNum = self.lineEdit_Serial.text() sdata = bytes([eval('0xF9')]) # 1字節(jié)指令碼 try: FieldsList = DEvIp.split('.') HexStr = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備IP sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備IP地址輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderIP.setFocus() return try: FieldsList = DevMask.split('.') HexStr = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備子網(wǎng)掩碼 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備子網(wǎng)掩碼輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderMask.setFocus() return try: FieldsList = ServeIp.split('.') HexStr = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備遠程服務器IP sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備遠程服務器IP輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIP.setFocus() return try: FieldsList = ServerMac.split('-') HexStr = FieldsList[0] + FieldsList[1] + FieldsList[2] + FieldsList[3] + FieldsList[4] + FieldsList[ 5] # 6字節(jié)設備遠程服務器MAC sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備遠程服務器MAC輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoMAC.setFocus() return try: FieldsList = DevGetway.split('.') HexStr = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備網(wǎng)關 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備網(wǎng)關IP輸入錯誤!", QMessageBox.Yes) self.lineEdit_Gatwag.setFocus() return try: FieldsList = GetwayMac.split('-') HexStr = FieldsList[0] + FieldsList[1] + FieldsList[2] + FieldsList[3] + FieldsList[4] + FieldsList[ 5] # 6字節(jié)設備網(wǎng)關MAC sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備網(wǎng)關MAC輸入錯誤!", QMessageBox.Yes) self.lineEdit_GatwayMAC.setFocus() return try: HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備機號輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderNnm.setFocus() return try: HexStr = '%02X%02X' % (DevPort % 256, DevPort // 256) # 2字節(jié)端口號 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderPort.setFocus() return try: FieldsList = SerialNum.split('-') HexStr = FieldsList[0] + FieldsList[1] + FieldsList[2] + FieldsList[3] # 4字節(jié)設備網(wǎng)出廠序號 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "設備出廠序號輸入錯誤!", QMessageBox.Yes) self.lineEdit_Serial.setFocus() return searchcode = self.comboBox_beep.currentIndex() if (self.radioButton_RemoMACAuto.isChecked()): searchcode = searchcode + 2 if (self.radioButton_Gatwayauto.isChecked()): searchcode = searchcode + 4 if (self.checkBox_DHCP.isChecked()): searchcode = searchcode + 8 if (self.comboBox_SendEn.currentIndex() == 1): searchcode = searchcode + 16 searchcode = searchcode + self.comboBox_Sendinterval.currentIndex() * 32 sdata = sdata + bytes([searchcode]) sdata = sdata + bytes.fromhex('55AA6699') if (self.checkBox.isChecked()): RemoIPort = "255.255.255.255:39169" else: RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "遠程設備IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return self.netparaSignel.emit(RemoIPort, sdata) def pushButton_SetTCP_clicked(self): # 設置TCP協(xié)議讀卡器 遠程服務器偵聽端口 self.plainTextEdit_Disp.setPlainText('') RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "遠程設備IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return sdata = bytes([eval('0x1D')]) # 1字節(jié)指令碼 sdata = sdata + bytes.fromhex("0000075C04") DevPort = int(self.lineEdit_ReaderPort.text()) try: HexStr = '%02X%02X' % (DevPort % 256, DevPort // 256) # 2字節(jié)端口號 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "讀卡器通訊端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderPort.setFocus() return DevPort = int(self.lineEdit_TCPRemoPort.text()) try: HexStr = '%02X%02X' % (DevPort % 256, DevPort // 256) # 2字節(jié)端口號 sdata = sdata + bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "服務器TCP通訊端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_TCPRemoPort.setFocus() return sdata = sdata + bytes([sdata[6] ^ sdata[7] ^ sdata[8] ^ sdata[9]]) sdata = sdata + bytes.fromhex("55AA6699") self.netparaSignel.emit(RemoIPort, sdata) def pushButton_SetHttp_clicked(self): # 設置HTTP協(xié)議讀卡器數(shù)據(jù)傳送方式、服務端偵聽端口 及 訪問文件 self.plainTextEdit_Disp.setPlainText('') RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "遠程設備IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return filename = self.lineEdit_filename.text().strip() filenamebuf = bytes(filename, encoding='gbk') filelen = len(filenamebuf) if (filelen == 0 or filelen > 252): QMessageBox.critical(self, "警告", "訪問文件不可以為空,文件長度也不可以>252!", QMessageBox.Yes) self.lineEdit_filename.setFocus() return if (filename[0:1] == '/'): QMessageBox.critical(self, "警告", "訪問文件首字符不可以為: /", QMessageBox.Yes) self.lineEdit_filename.setFocus() return if (filename[0:4] == 'http'): QMessageBox.critical(self, "警告", "訪問文件無需帶域名!", QMessageBox.Yes) self.lineEdit_filename.setFocus() return DevPort = int(self.lineEdit_HttpRemoPort.text()) try: HexStr = '%02X%02X' % (DevPort % 256, DevPort // 256) # 2字節(jié)端口號 PortBuf = bytes.fromhex(HexStr) except: QMessageBox.critical(self, "警告", "讀卡器通訊端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_ReaderPort.setFocus() return sdata = bytes([eval('0x1D')]) # 1字節(jié)指令碼 sdata = sdata + bytes.fromhex("0000") # 2字節(jié)機號 00表示任意機號 sdata = sdata + bytes([filelen + 7]) sdata = sdata + bytes([91]) # 設定HTTP協(xié)議的文件路徑、上傳方式 標識 sdata = sdata + bytes([filelen + 4]) sdata = sdata + bytes([self.comboBox_Sendmodel.currentIndex()]) # 提交方式 sdata = sdata + bytes([255]) sdata = sdata + PortBuf # 服務器偵聽端口 sdata = sdata + filenamebuf # 訪問文件 crc = sdata[6] ^ sdata[7] ^ sdata[8] ^ sdata[9] for num in range(0, len(filenamebuf)): crc = crc ^ filenamebuf[num] sdata = sdata + bytes([crc]) sdata = sdata + bytes.fromhex("55AA6699") self.netparaSignel.emit(RemoIPort, sdata) # 設置讀卡器WIFI熱點======================================================================================================== class WifiSetWindow(QWidget, Ui_wifiwin): WifiSignel = pyqtSignal(int, str, bytes) # 創(chuàng)建一個信號,向主窗口請求發(fā)送對應的指令 def __init__(self): super().__init__() self.setupUi(self) self.setWindowTitle("WIFI熱點參數(shù)設置") self.radioButton_DHCP.toggled.connect(self.radioButton_DHCP_changeEvent) self.pushButton_SetUp.clicked.connect(self.pushButton_SetUp_click) self.pushButton_Read.clicked.connect(self.pushButton_Read_click) def open(self): self.show() def closeEvent(self, event): mainWindow.setEnabled(True) def radioButton_DHCP_changeEvent(self): if (self.radioButton_DHCP.isChecked()): self.groupBox.setVisible(False) else: self.groupBox.setVisible(True) def pushButton_SetUp_click(self): # 設置WIFI熱點名稱、密碼、WIFIIP及數(shù)據(jù)傳送方式 self.plainTextEdit.setPlainText(" ") RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "設備有線IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return wifiname = bytes(self.lineEdit_SSID.text().strip(), encoding='utf8') namelen = len(wifiname) if (namelen > 60): self.plainTextEdit.setPlainText("熱點名稱長度不可以大于60字節(jié)!") return wifipass = bytes(self.lineEdit_Password.text().strip(), encoding='utf8') passlen = len(wifipass) if (passlen > 64): self.plainTextEdit.setPlainText("WIFI密鑰長度不可以大于64字節(jié)!") return comb = bytes([eval('0xF7')]) # F7是指令碼 comb = comb + bytes.fromhex('0000') # 2字節(jié)機號 comb = comb + bytes([namelen]) # 1字節(jié)熱點名稱長度 if self.checkBox.isChecked(): comb = comb + bytes([passlen]) # 1字節(jié)密碼長度 else: comb = comb + bytes([0]) # 1字節(jié)密碼長度 comb = comb + wifiname # 熱點名稱 for num in range(namelen, 60): # 熱點名稱長度不足60,占位符 comb = comb + bytes([0]) comb = comb + wifipass # WiFI密碼 for num in range(passlen, 64): # WiFI密碼長度不足64,占位符 comb = comb + bytes([0]) if (self.radioButton_DHCP.isChecked()): # wifi的IP是DHCP自動分配 comb = comb + bytes([0]) comb = comb + bytes.fromhex('000000000000000000000000') else: # wifi的IP是靜態(tài)綁定 wifiip = GetHexIPAdd(self.lineEdit_IP.text()) if (wifiip == '00000000'): self.plainTextEdit.setPlainText("WIFI的IP地址輸入錯誤!") self.lineEdit_IP.setFocus() return wifimask = GetHexIPAdd(self.lineEdit_mask.text()) if (wifiip == '00000000'): self.plainTextEdit.setPlainText("WIFI的掩碼地址輸入錯誤!") self.lineEdit_mask.setFocus() return wifigetway = GetHexIPAdd(self.lineEdit_gateway.text()) if (wifiip == '00000000'): self.plainTextEdit.setPlainText("WIFI的掩碼地址輸入錯誤!") self.lineEdit_gateway.setFocus() return comb = comb + bytes([1]) comb = comb + bytes.fromhex(wifiip) comb = comb + bytes.fromhex(wifimask) comb = comb + bytes.fromhex(wifigetway) comb = comb + bytes([self.comboBox_Sendmode.currentIndex()]) comb = comb + bytes.fromhex('55AA6699') # 指令結束碼,抗網(wǎng)絡上的干擾信號 self.WifiSignel.emit(1, RemoIPort, comb) # 發(fā)送信號,主窗口接收到信號后,觸發(fā)主窗口槽函數(shù)發(fā)送指令 def pushButton_Read_click(self): # 查詢WIFI連接狀態(tài) self.plainTextEdit.setPlainText(" ") RemoIPort = self.lineEdit_RemoIPort.text().strip() if (IsIport(RemoIPort) == False): QMessageBox.critical(self, "警告", "設備有線IP端口輸入錯誤!", QMessageBox.Yes) self.lineEdit_RemoIPort.setFocus() return comb = bytes.fromhex("A40000") global LastBuf LastBuf = bytes(9) self.WifiSignel.emit(1, RemoIPort, comb) # 發(fā)送信號,主窗口接收到信號后,觸發(fā)主窗口槽函數(shù)發(fā)送指令 # 主窗口,偵聽網(wǎng)絡端口獲取刷卡信息、向讀卡器發(fā)送顯示、響聲、語音===================================================================== class MainWindow(QtWidgets.QMainWindow, Ui_Frame): rw15693Signel = pyqtSignal(int, str,str) def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.PBSearch.clicked.connect(self.PBSearch_click) self.PBClear.clicked.connect(self.PBClear_click) self.CBIP.currentIndexChanged.connect(self.CBIP_selectionchange) self.PBSendDispBeep.clicked.connect(self.PBSendDispBeep_click) self.PBEditpara.clicked.connect(self.PBEditpara_click) self.tableWidget.doubleClicked.connect(self.table_doubleClick) self.PBSwitchOn.clicked.connect(self.PBSwitchOn_click) self.PBSwitchOff.clicked.connect(self.PBSwitchOff_click) self.PBSendDispSpk.clicked.connect(self.PBSendDispSpk_click) self.PBSendDispTTS.clicked.connect(self.PBSendDispTTS_click) self.PBReadCard.clicked.connect(self.PBReadCard_click) self.PBWriteCard.clicked.connect(self.PBWriteCard_click) self.PBChangeKey.clicked.connect(self.PBChangeKey_click) self.PBSetRW.clicked.connect(self.PBSetRW_click) self.PBWifiSet.clicked.connect(self.PBWifiSet_click) self.PBGetmodel.clicked.connect(self.PBGetmodel_click) self.PB15693RW.clicked.connect(self.PB15693RW_click) def Getiso15693Signal(self, remortiport, sdata): FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送設置WIFI參數(shù)的指令 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def GetWiFiWindoSignal(self, sigcode, remortiport, sdata): if (sigcode == 1): # 設置WIFI叁數(shù)的信號 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送設置WIFI參數(shù)的指令 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[ 0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def GetNetParaSetSignal(self, remortiport, sdata): FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送設置WIFI參數(shù)的指令 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def SockGetData(self, dispcode, RemortIPort, data): global LastBuf global CardNuff if (dispcode == 0): self.textEdit_7.setText(RemortIPort) DispStr = get_time() + 'FromIP:' + (RemortIPort + ' ')[0:22] + ' Data:' for num in range(0, len(data)): DispStr = DispStr + '%02X ' % (data[num]) self.ListAddItem(DispStr) if (len(data) > 8): if (data[0] == LastBuf[0] and data[1] == LastBuf[1] and data[2] == LastBuf[2] and data[3] == LastBuf[3] and data[4] == LastBuf[4] and data[5] == LastBuf[5] and data[6] == LastBuf[6] and data[7] == LastBuf[7] and data[8] == LastBuf[8]): # 比較是否是重發(fā)數(shù)據(jù) exit # 是設備重發(fā)的數(shù)據(jù),直接丟棄不做處理 else: LastBuf = data[0:9] # 將接收到的信息保存,用于下次接收數(shù)據(jù)時比對 if (data[0] == eval('0xF2')): # 接收到設備開機、搜索在線設備的返回信息,對信息解析 DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) DevMask = '%d.%d.%d.%d' % (data[5], data[6], data[7], data[8]) DevPort = '%d' % (data[9] + data[10] * 256) DevNo = '%05d' % (data[11] + data[12] * 256) DevGetway = '%d.%d.%d.%d' % (data[13], data[14], data[15], data[16]) GetwayMac = '' for num in range(17, 23): GetwayMac = GetwayMac + '%02X' % (data[num]) if (num < 22): GetwayMac = GetwayMac + '-' ServeIp = '%d.%d.%d.%d' % (data[23], data[24], data[25], data[26]) ServerMac = '' for num in range(27, 33): ServerMac = ServerMac + '%02X' % (data[num]) if (num < 32): ServerMac = ServerMac + '-' Search = '%02X' % (data[33]) Beep = ('00000000' + bin(data[34])[2:])[-8:] DevMac = '16-88-' for num in range(35, 39): DevMac = DevMac + '%02X' % (data[num]) if (num < 38): DevMac = DevMac + '-' SerialNum = '' HCMac = '' if (len(data) > 39): for num in range(39, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) if (num < 45): HCMac = '%02X' % (data[num]) + HCMac if (num < 44): HCMac = '-' + HCMac rowPosition = self.tableWidget.rowCount() self.tableWidget.insertRow(rowPosition) NewItem = QtWidgets.QTableWidgetItem(DevNo) self.tableWidget.setItem(rowPosition, 0, NewItem) NewItem = QtWidgets.QTableWidgetItem(DEvIp) self.tableWidget.setItem(rowPosition, 1, NewItem) NewItem = QtWidgets.QTableWidgetItem(DevMask) self.tableWidget.setItem(rowPosition, 2, NewItem) NewItem = QtWidgets.QTableWidgetItem(DevPort) self.tableWidget.setItem(rowPosition, 3, NewItem) NewItem = QtWidgets.QTableWidgetItem(DevGetway) self.tableWidget.setItem(rowPosition, 4, NewItem) NewItem = QtWidgets.QTableWidgetItem(GetwayMac) self.tableWidget.setItem(rowPosition, 5, NewItem) NewItem = QtWidgets.QTableWidgetItem(ServeIp) self.tableWidget.setItem(rowPosition, 6, NewItem) NewItem = QtWidgets.QTableWidgetItem(ServerMac) self.tableWidget.setItem(rowPosition, 7, NewItem) NewItem = QtWidgets.QTableWidgetItem(Search) self.tableWidget.setItem(rowPosition, 8, NewItem) NewItem = QtWidgets.QTableWidgetItem(Beep) self.tableWidget.setItem(rowPosition, 9, NewItem) NewItem = QtWidgets.QTableWidgetItem(DevMac[6:17]) self.tableWidget.setItem(rowPosition, 10, NewItem) NewItem = QtWidgets.QTableWidgetItem(DevMac) self.tableWidget.setItem(rowPosition, 11, NewItem) NewItem = QtWidgets.QTableWidgetItem(SerialNum) self.tableWidget.setItem(rowPosition, 12, NewItem) NewItem = QtWidgets.QTableWidgetItem(HCMac) self.tableWidget.setItem(rowPosition, 13, NewItem) NewItem = QtWidgets.QTableWidgetItem(' ') self.tableWidget.setItem(rowPosition, 14, NewItem) NewItem = QtWidgets.QTableWidgetItem(' ') self.tableWidget.setItem(rowPosition, 15, NewItem) self.tableWidget.resizeColumnsToContents() self.textEdit_8.setText(DevNo) dispinf = '數(shù)據(jù)解析:設備響應搜索指令、開機標識:F2,設備信息已在表格內顯示,如需修改設備網(wǎng)絡參數(shù),先在表格內點擊要修改的設備再點擊 "修改選定設備的網(wǎng)絡參數(shù)" 鍵!' self.textEdit_9.setText(dispinf) elif (data[0] == eval('0xF3')): # 接收到設備的心跳數(shù)據(jù)包,設備心跳間隔可根據(jù)協(xié)議自行設置 DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) elif (data[0] == eval('0xC1') or data[0] == eval('0xD1')): # 接收到讀取IC、ID卡信息的數(shù)據(jù)包,對信息解析 self.DisableSendAge(RemortIPort, data) FunCode = '%02X' % (data[0]) DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 設備IP DevNo = '%05d' % (data[5] + data[6] * 256) # 機號 FrameNo = '%d' % (data[7] + data[8] * 256) # 數(shù)據(jù)包序號 SerialNum = '' # 設備硬件序列號 for num in range(14, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) if (data[0] == eval('0xC1')): Card16H = '%02X%02X%02X%02X' % (data[10], data[11], data[12], data[13]) # 原始16進制卡號 Cardno = data[10] Cardno = Cardno + (data[11] * 256) Cardno = Cardno + (data[12] * 65536) Cardno = Cardno + (data[13] * 16777216) CardnoStr = '%010d' % Cardno # 轉10進制卡號 dispinf = '數(shù)據(jù)解析:讀IC卡號標識:' else: Card16H = '%02X%02X%02X%02X' % (data[9], data[10], data[11], data[12]) # 原始16進制卡號 Cardno = data[9] Cardno = Cardno + (data[10] * 256) Cardno = Cardno + (data[11] * 65536) Cardno = Cardno + (data[12] * 16777216) CardnoStr = '%010d' % Cardno # 轉10進制卡號 dispinf = '數(shù)據(jù)解析:讀ID卡號標識:' dispinf = dispinf + FunCode + ',設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H + " 轉10進制卡號:" + CardnoStr + ",硬件序列號:" + SerialNum self.textEdit_9.setText(dispinf) self.textEdit_8.setPlainText(DevNo) self.textEdit_3.setText(Card16H) self.PBSendDispBeep_click() elif (data[0] == eval('0xC3')): # 全扇區(qū)讀寫器收到讀卡扇區(qū)內的數(shù)據(jù)(刷卡時主動讀取并上傳) j = data[10] * 48 m = data[11] * 48 for num in range(0, m): # 將讀取到的扇區(qū)信息存入讀卡緩沖 CardNuff.append(data[16 + num]) if (data[11] + data[10] >= data[ 9]): # 已完全收到所有包數(shù)據(jù),一個數(shù)據(jù)包最多傳4個扇區(qū)的數(shù)據(jù),如果讀寫器設備讀寫扇區(qū)數(shù)大于4,數(shù)據(jù)要分2個包上傳,扇區(qū)數(shù)大于8要分3個包,大與12要分4個包上傳 FunCode = '%02X' % (data[0]) DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) DevNo = '%05d' % (data[5] + data[6] * 256) # 機號 FrameNo = '%d' % (data[7] + data[8] * 256) # 數(shù)據(jù)包序號 Card16H = '%02X%02X%02X%02X' % (data[12], data[13], data[14], data[15]) # 原始16進制卡號 dispinf = '數(shù)據(jù)解析:讀IC卡扇區(qū)標識:' + FunCode + ',設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H + ",讀卡信息已在扇區(qū)數(shù)據(jù)欄顯示!" self.textEdit_9.setText(dispinf) m = data[9] * 48 CardInfStr = '' for num in range(0, m): CardInfStr = CardInfStr + '%02X ' % (CardNuff[num]) self.textEdit_5.setPlainText(CardInfStr) CardNuff = bytearray() # 已接收完,清空接收緩沖 self.textEdit_3.setText(Card16H) elif (data[0] == eval('0xC5')): # 指定區(qū)號、密碼讀卡返回信息 FunCode = '%02X' % (data[0]) DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 設備IP DevNo = '%05d' % (data[5] + data[6] * 256) # 機號 SectNum = data[7] # 扇區(qū)總數(shù) Card16H = '%02X%02X%02X%02X' % (data[8], data[9], data[10], data[11]) Sectors = data[12] # 扇區(qū)號 dispinf = '數(shù)據(jù)解析:讀IC卡扇區(qū)標識:' + FunCode + ',設備IP:' + DEvIp + ',機號:' + DevNo + ",16進制卡號:" + Card16H if (data[13] == 0): CardInfStr = '' for num in range(0, 48): CardInfStr = CardInfStr + '%02X ' % (data[14 + num]) dispinf = dispinf + ",讀取 " + str(Sectors) + " 扇區(qū)數(shù)據(jù)成功!" self.textEdit_9.setText(dispinf) self.textEdit_8.setText(DevNo) self.textEdit_3.setText(Card16H) self.textEdit_5.setPlainText(CardInfStr) else: if (data[13] == 12): dispinf = dispinf + ",卡密碼認證失敗!本次讀卡失敗!" self.textEdit_9.setText(dispinf) else: dispinf = dispinf + ",讀卡失敗,錯誤代碼:%02X" % (data[13]) self.textEdit_9.setText(dispinf) elif (data[0] == eval('0xCD')): # 響應寫卡、更改卡密碼后的返回信息 FunCode = '%02X' % (data[0]) DEvIp = '%d.%d.%d.%d' % (data[2], data[3], data[4], data[5]) # 設備IP DevNo = '%05d' % (data[6] + data[7] * 256) # 機號 SectNum = data[8] # 扇區(qū)總數(shù) Card16H = '%02X%02X%02X%02X' % (data[9], data[10], data[11], data[12]) # 原始16進制卡號 Sectors = data[13] # 扇區(qū)號 dispinf = '數(shù)據(jù)解析:寫IC卡扇區(qū)標識:' + FunCode + ',設備IP:' + DEvIp + ',機號:' + DevNo + ",16進制卡號:" + Card16H if (data[1] == 0x3A): if (data[14] == 0x00): dispinf = dispinf + ',更改卡密碼成功!' elif (data[14] == 0x0C): dispinf = dispinf + ',卡密碼認證失敗,更改卡密碼失?。? else: dispinf = dispinf + ',更改卡密碼失敗,錯誤代碼:%02X' % (data[14]) else: if (data[1] == 0x3D): if (data[14] == 0x00): dispinf = dispinf + ',寫卡成功!' elif (data[14] == 0x0C): dispinf = dispinf + ',卡密碼認證失敗,寫卡失敗!' else: dispinf = dispinf + ',寫卡失敗,錯誤代碼:%02X' % (data[14]) self.textEdit_9.setText(dispinf) elif (data[0] == eval('0xCF') or data[0] == eval('0xDF')): # 接收到IC、ID卡離開讀卡器感應區(qū)的信息 # DisableSendAge(data, addr) FunCode = '%02X' % (data[0]) DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 設備IP DevNo = '%05d' % (data[5] + data[6] * 256) # 機號 FrameNo = ':%d' % (data[7] + data[8] * 256) # 數(shù)據(jù)包序號 Card16H = '%02X%02X%02X%02X' % (data[11], data[12], data[13], data[14]) # 原始16進制卡號 Cardno = data[11] Cardno = Cardno + (data[12] * 256) Cardno = Cardno + (data[13] * 65536) Cardno = Cardno + (data[14] * 16777216) CardnoStr = '%010d' % Cardno # 轉10進制卡號 SerialNum = '' # 設備硬件序列號 for num in range(15, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) if (data[0] == eval('0xCF')): dispinf = '數(shù)據(jù)解析:IC卡離開標識:' else: dispinf = '數(shù)據(jù)解析:ID卡離開標識:' dispinf = dispinf + FunCode + ',設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H + " 轉10進制卡號:" + CardnoStr + ",硬件序列號:" + SerialNum self.textEdit_9.setText(dispinf) self.textEdit_8.setText(DevNo) elif (data[0] == eval('0xA4')): # 返回WIFI連接狀態(tài) dispinf = 'WIFI的IP地址:%d.%d.%d.%d' % (data[7], data[8], data[9], data[10]) + "n" dispinf = dispinf + 'WIFI子網(wǎng)掩碼:%d.%d.%d.%d' % (data[11], data[12], data[13], data[14]) + "n" dispinf = dispinf + '本地 MAC地址:%02X-%02X-%02X-%02X-%02X-%02X' % ( data[15], data[16], data[17], data[18], data[19], data[20]) + "n" dispinf = dispinf + ' WIFI網(wǎng)關IP:%d.%d.%d.%d' % (data[21], data[22], data[23], data[24]) + "n" dispinf = dispinf + '網(wǎng)關 MAC地址:%02X-%02X-%02X-%02X-%02X-%02X' % ( data[25], data[26], data[27], data[28], data[29], data[30]) + "n" if (data[31] == 0): dispinf = dispinf + 'WIFI網(wǎng)絡狀態(tài):已連接wifi' + 'n' elif (data[31] == 1): dispinf = dispinf + 'WIFI網(wǎng)絡狀態(tài):連接失敗!' + 'n' elif (data[31] == 2): dispinf = dispinf + 'WIFI網(wǎng)絡狀態(tài):已初始化!' + 'n' else: dispinf = dispinf + 'WIFI網(wǎng)絡狀態(tài):未初始化!' + 'n' dispinf = dispinf + '讀卡器 名稱:' + data[34:(34 + data[32])].decode('utf-8') + 'n' dispinf = dispinf + 'WIFI熱點名稱:' + data[44:(44 + data[33])].decode('utf-8') + 'n' self.wifiset.plainTextEdit.setPlainText(dispinf) elif (data[0] == eval('0xF6')): # 返回設備版本型號、固件日期 DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 設備IP DevNo = '%05d' % (data[5] + data[6] * 256) # 機號 namelen = data[7] namebufbeg = 8 namebufend = namebufbeg + namelen namestr = data[namebufbeg:namebufend].decode('gbk') verlen = data[namebufend] verbufbeg = namebufend + 1 verbufend = verbufbeg + verlen verstr = '' + data[verbufbeg:verbufend].decode('gbk') + '' SerialNum = '' if (data[verbufend] == eval('0xFF')): for num in range(verbufend + 1, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) rows = self.tableWidget.rowCount() if (rows > 0): for num in range(0, rows): if (DEvIp == self.tableWidget.item(num, 1).text() and SerialNum == self.tableWidget.item( num, 12).text()): self.tableWidget.item(num, 14).setText(namestr) self.tableWidget.item(num, 15).setText(verstr) break elif (data[0] == eval('0x47')): # 設置15693讀寫器讀卡塊號成功 self.rw15693Signel.emit(3,RemortIPort, "設置15693讀寫器主動讀卡塊號成功!") elif (data[0] == eval('0xC7')): # 15693卡刷卡信息 self.DisableSendAge(RemortIPort, data) DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4]) # 設備IP DevNo = '%05d' % (data[5] + data[6] * 256) # 機號 FrameNo = '%d' % (data[7] + data[8] * 256) # 數(shù)據(jù)包序號 if (data[9] == eval('0x00')): self.rw15693Signel.emit(3, RemortIPort, "卡不在感應區(qū)!") else: Card16H = '%02X%02X%02X%02X%02X%02X%02X%02X' % ( data[19], data[18], data[17], data[16], data[15], data[14], data[13], data[12]) # 原始16進制卡號 self.rw15693Signel.emit(1,RemortIPort, Card16H) if (self.findChild(QWidget, "ISO15693標簽讀寫器測試")): self.ISO15693RW.lineEdit_RWCardno.setText(Card16H) if (data[9] == eval('0x01')): # 主動讀取15693卡號 SerialNum = '' # 設備硬件序列號 for num in range(20, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:主動讀取15693卡號,設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(3, RemortIPort, "主動讀取15693卡號成功!") elif (data[9] == eval('0x02')): # 主動讀取15693卡號、塊數(shù)據(jù) DSFID = '%02X' % (data[11]) blockdata = '' for j in range(1, data[21] + 1): blockdata = blockdata + '塊號:%02d' % (data[(j - 1) * (data[20] + 1) + 22]) + ' 數(shù)據(jù):' for i in range(1, data[20] + 1): blockdata = blockdata + '%02X' % (data[(j - 1) * (data[20] + 1) + 22 + i]) blockdata = blockdata + "n" SerialNum = '' # 設備硬件序列號 for num in range(len(data) - 8, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:主動讀取15693卡號及塊數(shù)據(jù),設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H + ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(2,RemortIPort, blockdata) self.rw15693Signel.emit(3, RemortIPort, "主動讀取15693卡號及塊數(shù)據(jù)成功!") elif (data[9] == eval('0x03')): # 電腦發(fā)指令讀卡成功,僅返回卡號 SerialNum = '' # 設備硬件序列號 for num in range(20, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:接收指令讀取15693卡號,設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(3, RemortIPort, "接收指令讀取15693卡號成功!") elif (data[9] == eval('0x04')): # 電腦發(fā)指令讀卡成功 DSFID = '%02X' % (data[11]) blockdata = '' for j in range(1, data[21] + 1): blockdata = blockdata + '塊號:%02d' % (data[(j - 1) * (data[20] + 1) + 22]) + ' 數(shù)據(jù):' for i in range(1, data[20] + 1): blockdata = blockdata + '%02X' % (data[(j - 1) * (data[20] + 1) + 22 + i]) blockdata = blockdata + "n" SerialNum = '' # 設備硬件序列號 for num in range(len(data) - 8, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:接收指令讀取15693卡號及塊數(shù)據(jù),設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H + ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(2,RemortIPort, blockdata) self.rw15693Signel.emit(3, RemortIPort, "接收指令讀取15693卡號及塊數(shù)據(jù)成功!") elif (data[9] == eval('0x05')): # 電腦發(fā)指令讀卡成功,僅返回卡號 DSFID = '%02X' % (data[11]) SerialNum = '' # 設備硬件序列號 for num in range(20, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:電腦發(fā)指令重新讀卡號成功,設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H+ ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(3, RemortIPort, "接收指令重新讀卡號成功成功!") elif (data[9] == eval('0x06')): # 電腦發(fā)指令寫卡成功 DSFID = '%02X' % (data[11]) SerialNum = '' # 設備硬件序列號 for num in range(20, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:電腦發(fā)指令寫卡成功,設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H+ ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(3, RemortIPort, "電腦發(fā)指令寫卡成功!") elif (data[9] == eval('0x07')): # 卡離開感應區(qū) DSFID = '%02X' % (data[11]) SerialNum = '' # 設備硬件序列號 for num in range(20, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:卡離開感應區(qū),設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H+ ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(3, RemortIPort, "卡離開感應區(qū)!") elif (data[9] == eval('0x6A')): # 電腦發(fā)指令寫卡失敗,返回卡號 DSFID = '%02X' % (data[11]) SerialNum = '' # 設備硬件序列號 for num in range(20, len(data)): SerialNum = SerialNum + '%02X' % (data[num]) dispinf = '數(shù)據(jù)解析:電腦發(fā)指令寫卡失敗,設備IP:' + DEvIp + ',機號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進制卡號:" + Card16H+ ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum self.rw15693Signel.emit(3, RemortIPort, "電腦發(fā)指令寫卡失敗!") self.textEdit_9.setText(dispinf) elif (len(data) > 0): if (data[0] == eval('0xF7')): if (len(data) == 8 and data[7] == 0): self.wifiset.plainTextEdit.setPlainText("設置設備WIFI熱點參數(shù)的指令已傳送到設備,30秒后可以獲取到設備WIFI連接狀態(tài)!") elif (data[0] == eval('0x1D')): if (RemortIPort == self.netparawin.lineEdit_RemoIPort.text()): self.netparawin.plainTextEdit_Disp.setPlainText('1D設置參數(shù)指令成功執(zhí)行!') elif (dispcode == 1): self.ListAddItem(RemortIPort) def table_doubleClick(self): currentrow = self.tableWidget.currentRow() # 獲取當前鼠標點擊了第幾行 if (currentrow >= 0): DevNo = self.tableWidget.item(currentrow, 0).text() DEvIp = self.tableWidget.item(currentrow, 1).text() DevPort = self.tableWidget.item(currentrow, 3).text() self.textEdit_7.setPlainText(DEvIp + ':' + DevPort) self.textEdit_8.setPlainText(DevNo) def PBEditpara_click(self): currentrow = self.tableWidget.currentRow() # 獲取當前鼠標點擊了第幾行 if (currentrow >= 0): self.netparawin = NetParaSetwindow() # 實例化 網(wǎng)絡參數(shù)設置窗口 screen = QDesktopWidget().screenGeometry() size = self.netparawin.geometry() newLeft = (screen.width() - size.width()) // 2 newTop = (screen.height() - size.height()) // 2 self.netparawin.move(newLeft, newTop) self.netparawin.setWindowFlags(QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowStaysOnTopHint) self.netparawin.lineEdit_ReaderNnm.setText(self.tableWidget.item(currentrow, 0).text()) self.netparawin.lineEdit_ReaderIP.setText(self.tableWidget.item(currentrow, 1).text()) self.netparawin.lineEdit_ReaderMask.setText(self.tableWidget.item(currentrow, 2).text()) self.netparawin.lineEdit_ReaderPort.setText(self.tableWidget.item(currentrow, 3).text()) self.netparawin.lineEdit_Gatwag.setText(self.tableWidget.item(currentrow, 4).text()) self.netparawin.lineEdit_GatwayMAC.setText(self.tableWidget.item(currentrow, 5).text()) self.netparawin.lineEdit_RemoIP.setText(self.tableWidget.item(currentrow, 6).text()) self.netparawin.lineEdit_RemoMAC.setText(self.tableWidget.item(currentrow, 7).text()) self.netparawin.lineEdit_Serial.setText(self.tableWidget.item(currentrow, 10).text()) Search = eval('0x' + self.tableWidget.item(currentrow, 8).text().strip()) if (Search == 0): self.netparawin.radioButton_gatwaybind.setChecked(True) self.netparawin.radioButton_RemoMACBind.setChecked(True) elif (Search == 1): self.netparawin.radioButton_gatwaybind.setChecked(True) self.netparawin.radioButton_RemoMACAuto.setChecked(True) elif (Search == 2): self.netparawin.radioButton_Gatwayauto.setChecked(True) self.netparawin.radioButton_RemoMACBind.setChecked(True) else: self.netparawin.radioButton_Gatwayauto.setChecked(True) self.netparawin.radioButton_RemoMACAuto.setChecked(True) paracod = self.tableWidget.item(currentrow, 9).text().strip() self.netparawin.comboBox_beep.setCurrentIndex(int(paracod[-1:8], 2)) if (paracod[-2:7] == '1'): self.netparawin.checkBox_DHCP.setChecked(True) else: self.netparawin.checkBox_DHCP.setChecked(False) self.netparawin.comboBox_SendEn.setCurrentIndex(int(paracod[-3:6], 2)) self.netparawin.comboBox_Sendinterval.setCurrentIndex(int(paracod[0:5], 2)) self.netparawin.label_19.setStyleSheet('color:red;') self.netparawin.label_20.setStyleSheet('color:red;') self.netparawin.lineEdit_RemoIPort.setStyleSheet('color:blue;') self.netparawin.plainTextEdit_Disp.setStyleSheet('color:blue;') self.netparawin.lineEdit_RemoIPort.setText(self.textEdit_7.toPlainText().strip()) self.netparawin.show() self.setEnabled(False) self.netparawin.netparaSignel.connect(self.GetNetParaSetSignal) # 將設置網(wǎng)絡參數(shù)窗口的 信號 綁定給 主窗口的 槽函數(shù) else: QMessageBox.critical(self, "警告", " 請選擇一臺在線設備!", QMessageBox.Yes) def ListAddItem(self, itemstr): if self.listWidget.count() > 10: self.listWidget.clear() self.listWidget.addItem(itemstr) self.listWidget.scrollToBottom() seleid = self.listWidget.count() - 1 self.listWidget.item(seleid).setSelected(True) def PBSearch_click(self): global LastBuf LastBuf = bytes(9) self.tableWidget.setRowCount(0) # 清空表格內現(xiàn)有記錄 self.textEdit_7.setPlainText('255.255.255.255:39169') sdata = bytes([eval('0xA6')]) # 搜索在線設備的指令碼 s.sendto(sdata, ('255.255.255.255', Bindprot)) # 發(fā)送搜索同網(wǎng)段內所有在線設備的廣播指令 self.ListAddItem( get_time() + 'SendTo:' + ("255.255.255.255:" + str(Bindprot) + " ")[0:22] + " Data:A6") sdata = bytes([eval('0xA8')]) # 查詢設備版本型號、固件更新日期 s.sendto(sdata, ('255.255.255.255', Bindprot)) # 發(fā)送搜索同網(wǎng)段內所有在線設備的廣播指令 self.ListAddItem( get_time() + 'SendTo:' + ("255.255.255.255:" + str(Bindprot) + " ")[0:22] + " Data:A8") def PBClear_click(self): self.listWidget.clear() self.textEdit_9.setText('') def CBIP_selectionchange(self): global listen global s if listen == 1: listen = 0 s.close() if changip == 1: try: Bindip = self.CBIP.currentText() Bindprot = int(self.TEPort.toPlainText()) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.bind((Bindip, Bindprot)) self.subSockListenThread = SockListenThread() self.subSockListenThread.Sock_data.connect(self.SockGetData) self.subSockListenThread.start() listen = 1 self.ListAddItem("Socket is bind to :" + Bindip + ":" + str(Bindprot)) except: listen = 0 self.ListAddItem("Socket is bind to :" + Bindip + ":" + str(Bindprot) + " failure!") def DisableSendAge(self, remortiport, data): # 接收到讀卡器上傳的數(shù)據(jù)包立即回應,否則讀卡器會繼續(xù)上傳三次 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) senddata = bytes( [105, data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]]) # 接收到的數(shù)包前9字節(jié),首字節(jié)改為 69H 來回應 s.sendto(senddata, (Remoip, Reprot)) SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(senddata)): SendInf = SendInf + '%02X ' % (senddata[num]) self.ListAddItem(SendInf) def PBGetmodel_click(self): remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) comb = bytes([eval('0xA8')]) # A8是指令碼 s.sendto(comb, (Remoip, Reprot)) # 發(fā)送A8指令查詢設備版本型號 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(comb)): SendInf = SendInf + '%02X ' % (comb[num]) self.ListAddItem(SendInf) def PBSendDispBeep_click(self): remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 dispinf = self.textEdit.toPlainText() + ' ' # 加空格是為了全屏顯示 DispStr = dispinf[0:34] disb = bytes(DispStr, encoding='gbk') # 將要顯示的文字轉bytes comb = bytes([eval('0x5A')]) # 5A是指令碼 comb = comb + bytes.fromhex(HexStr) # 2字節(jié)機號 comb = comb + bytes([self.CBbeep.currentIndex()]) # 1字節(jié)蜂鳴代碼 comb = comb + bytes([self.spinBox.value()]) # 1字節(jié)顯示時長 sdata = comb + disb # 34字節(jié)顯示文字 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送5A指令驅動讀卡器顯示文字+蜂鳴響聲 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBSwitchOff_click(self): remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 DelayTime = self.spinBox_2.value() DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256) # 2字節(jié)繼電器延時 switch = 'E%d' % (self.CBSwitch.currentIndex()) # 所選的繼電器 sdata = bytes([eval('0x78')]) # 78是指令碼 sdata = sdata + bytes.fromhex(HexStr) # 2字節(jié)機號 sdata = sdata + bytes.fromhex(switch) # 1字節(jié)繼電器代號 sdata = sdata + bytes.fromhex(DelHexStr) # 2字節(jié)延長時間 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送78指令驅動讀卡器關閉已開啟的繼電器 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBSwitchOn_click(self): remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 DelayTime = self.spinBox_2.value() DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256) # 2字節(jié)繼電器延時 switch = 'F%d' % (self.CBSwitch.currentIndex()) # 所選的繼電器 sdata = bytes([eval('0x78')]) # 78是指令碼 sdata = sdata + bytes.fromhex(HexStr) # 2字節(jié)機號 sdata = sdata + bytes.fromhex(switch) # 1字節(jié)繼電器代號 sdata = sdata + bytes.fromhex(DelHexStr) # 2字節(jié)延長時間 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送78指令驅動讀卡器開啟繼電器 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBSendDispTTS_click(self): remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 DelayTime = self.spinBox_2.value() DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256) # 2字節(jié)繼電器延時 voice = self.spinBox_3.value() # 語音大小,最大聲音值16 if (voice > 16): voice = 16 DispStr = self.textEdit.toPlainText() + ' ' # 加空格是為了全屏顯示 disb = bytes(DispStr, encoding='gbk') # 將要顯示的文字轉bytes SpkStr = '[v' + str( voice) + ']' + self.textEdit_2.toPlainText() # 要播報的TTS語音,[v10]表示音量,取值0-16,可放置字符串的任意地方,一次最多126個字節(jié) Spkb = bytes(SpkStr, encoding='gbk') # 將要播報的TTS語音轉bytes, Spkl = len(Spkb) # TTS語音長度 switch = 'F%d' % (self.CBSwitch.currentIndex()) # 所選的繼電器 sufb = bytes([eval('0x55'), eval('0xaa'), eval('0x66'), eval('0x99')]) # 固定的抗干擾后綴 comb = bytes([eval('0x5C')]) # 5C是指令碼 comb = comb + bytes.fromhex(HexStr) # 2字節(jié)機號 comb = comb + bytes([self.CBbeep.currentIndex()]) # 1字節(jié)蜂鳴代碼 comb = comb + bytes.fromhex(switch) # 1字節(jié)繼電器代碼 comb = comb + bytes.fromhex(DelHexStr) # 2字節(jié)繼電器延時 comb = comb + bytes([self.spinBox.value()]) # 1字節(jié)顯示時長 comb = comb + bytes([0, 34, Spkl]) # 1字節(jié)顯示起始位+1字節(jié)顯示長度+1語音長度 sdata = comb + disb[0:34] + Spkb + sufb s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送5C指令驅動讀卡器顯示文字+蜂鳴響聲+開關繼電器+播報TTS語音 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBSendDispSpk_click(self): remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 DelayTime = self.spinBox_2.value() DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256) # 2字節(jié)延時 DispStr = self.textEdit.toPlainText() + ' ' # 加空格是為了全屏顯示 disb = bytes(DispStr, encoding='gbk') # 將要顯示的文字轉bytes Spkb = bytes([55, 41, 53]) # 固定組合語音代碼,取值請查看通訊協(xié)議說明,一次最大取值21條 Spkl = len(Spkb) # 語音代碼條數(shù) switch = 'F%d' % (self.CBSwitch.currentIndex()) # 所選的繼電器 sufb = bytes([eval('0x55'), eval('0xaa'), eval('0x66'), eval('0x99')]) # 固定的抗干擾后綴 comb = bytes([eval('0x5B')]) # 5B是指令碼 comb = comb + bytes.fromhex(HexStr) # 2字節(jié)機號 comb = comb + bytes([self.CBbeep.currentIndex()]) # 1字節(jié)蜂鳴代碼 comb = comb + bytes.fromhex(switch) # 1字節(jié)繼電器代碼 comb = comb + bytes.fromhex(DelHexStr) # 2字節(jié)繼電器延時 comb = comb + bytes([self.spinBox.value()]) # 1字節(jié)顯示時長 comb = comb + bytes([0, 36, Spkl]) # 1字節(jié)顯示起始位+1字節(jié)顯示長度+1語音長度 sdata = comb + disb[0:36] + Spkb + sufb s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送5B指令驅動讀卡器顯示文字+蜂鳴響聲+開關繼電器+播報固定組合語音 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBReadCard_click(self): keystr = self.textEdit_4.toPlainText().strip() # 卡片認證密碼 if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6): self.ListAddItem("卡密碼輸入錯誤!") self.textEdit_4.setFocus() return cardstr = self.textEdit_3.toPlainText().strip() if (is_valid_hex(cardstr) == False or len(bytes.fromhex(cardstr)) != 4): # 16進制卡號 self.ListAddItem("卡號輸入錯誤!") self.textEdit_3.setFocus() return self.textEdit_5.setPlainText('') global LastBuf LastBuf = bytes(9) remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 sector = self.CBPage.currentIndex() # 讀寫扇區(qū)號 auth = self.CBauth.currentIndex() # 密碼認證方式 sdata = bytes([eval('0x3B')]) # 3B是指令碼 sdata = sdata + bytes.fromhex(HexStr) # 2字節(jié)機號 sdata = sdata + bytes([1]) # 1字節(jié)扇區(qū)個數(shù) sdata = sdata + bytes.fromhex(cardstr) # 4字節(jié)16進制卡號 00000000 表示可操作任意卡 sdata = sdata + bytes([sector]) # 1字節(jié)扇區(qū)號 sdata = sdata + bytes([auth]) # 1字節(jié)密碼認證方式 sdata = sdata + bytes.fromhex(keystr) # 6字節(jié)密碼 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送3B指令驅動讀寫器讀卡 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBWriteCard_click(self): keystr = self.textEdit_4.toPlainText().strip() # 卡片認證密碼 if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6): self.ListAddItem("卡密碼輸入錯誤!") self.textEdit_4.setFocus() return cardstr = self.textEdit_3.toPlainText().strip() if (is_valid_hex(cardstr) == False or len(bytes.fromhex(cardstr)) != 4): # 16進制卡號 self.ListAddItem("卡號輸入錯誤!") self.textEdit_3.setFocus() return Writestr = self.textEdit_5.toPlainText().strip() # 48字節(jié)寫卡數(shù)據(jù) if (is_valid_hex(Writestr) == False or len(bytes.fromhex(Writestr)) != 48): self.ListAddItem("寫卡數(shù)據(jù)輸入錯誤,請輸入48個16進制寫卡數(shù)據(jù)!") self.textEdit_5.setFocus() return remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 sector = self.CBPage.currentIndex() # 讀寫扇區(qū)號 auth = self.CBauth.currentIndex() # 密碼認證方式 sdata = bytes([eval('0x3D')]) # 3D是指令碼 sdata = sdata + bytes.fromhex(HexStr) # 2字節(jié)機號 sdata = sdata + bytes([1]) # 1字節(jié)扇區(qū)個數(shù) sdata = sdata + bytes.fromhex(cardstr) # 4字節(jié)16進制卡號 00000000 表示可操作任意卡 sdata = sdata + bytes([sector]) # 1字節(jié)扇區(qū)號 sdata = sdata + bytes([auth]) # 1字節(jié)密碼認證方式 sdata = sdata + bytes.fromhex(keystr) # 6字節(jié)卡密碼 sdata = sdata + bytes.fromhex(Writestr) # 48字節(jié)寫卡數(shù)據(jù) sdata = sdata + bytes.fromhex("55AA6699") # 4字節(jié)防錯 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送3D指令驅動讀寫器寫卡 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBChangeKey_click(self): self.Dialog = MyDialog() self.Dialog.sig.connect(self.Changekey) self.Dialog.start() def Changekey(self, obj): res = QMessageBox.question(None, "警告", " 您確定要繼續(xù)執(zhí)行修改卡密碼及控制位的操作嗎?如確定修改請務必記住卡的新密碼,否則卡片將報廢!", QMessageBox.Yes | QMessageBox.No) if (QMessageBox.Yes == res): global LastBuf LastBuf = bytes(9) newkey = self.textEdit_6.toPlainText().strip() # 16字節(jié)新卡密碼 if (is_valid_hex(newkey) == False or len(bytes.fromhex(newkey)) != 16): self.ListAddItem("卡新密鑰輸入錯誤!") self.textEdit_6.setFocus() return keystr = self.textEdit_4.toPlainText().strip() # 卡片認證密碼 if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6): self.ListAddItem("卡密碼輸入錯誤!") self.textEdit_4.setFocus() return cardstr = self.textEdit_3.toPlainText().strip() if (is_valid_hex(cardstr) == False or len(bytes.fromhex(cardstr)) != 4): # 16進制卡號 self.ListAddItem("卡號輸入錯誤!") self.textEdit_3.setFocus() return remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 sector = self.CBPage.currentIndex() # 讀寫扇區(qū)號 auth = self.CBauth.currentIndex() # 密碼認證方式 auth = auth + self.ChangeKey.currentIndex() * 2 # 密碼修改方式 sdata = bytes([eval('0x3A')]) # 3A是指令碼 sdata = sdata + bytes.fromhex(HexStr) # 2字節(jié)機號 sdata = sdata + bytes([1]) # 1字節(jié)扇區(qū)個數(shù) sdata = sdata + bytes.fromhex(cardstr) # 4字節(jié)16進制卡號 00000000 表示可操作任意卡 sdata = sdata + bytes([sector]) # 1字節(jié)扇區(qū)號 sdata = sdata + bytes([auth]) # 1字節(jié)密碼認證方式 sdata = sdata + bytes.fromhex(keystr) # 6字節(jié)卡密碼 sdata = sdata + bytes.fromhex(newkey) # 16字節(jié)新密碼 sdata = sdata + bytes.fromhex("55AA6699") # 4字節(jié)防錯 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送3A指令驅動讀寫器更改卡片密鑰 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[ 0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBSetRW_click(self): self.Dialog = MyDialog() self.Dialog.sig.connect(self.SetRW) self.Dialog.start() def SetRW(self, obj): remortiport = self.textEdit_7.toPlainText().strip() # 需要驅動設備的 IP、端口 FieldsList = remortiport.split(':') Remoip = FieldsList[0] Reprot = int(FieldsList[1]) DevNo = int(self.textEdit_8.toPlainText()) HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256) # 2字節(jié)機號 sector = self.CBPage.currentIndex() # 讀寫扇區(qū)號 auth = self.CBauth.currentIndex() # 密碼認證方式 res = QMessageBox.question(None, "提示", " 按 Yes 鍵把讀寫器設為主動讀取第 " + str( self.CBPage.currentIndex()) + " 扇區(qū)數(shù)據(jù),按 No 鍵將讀寫器設為只讀卡號不讀扇區(qū)數(shù)據(jù)。", QMessageBox.Yes | QMessageBox.No) if (QMessageBox.No == res): sdata = bytes([eval('0x4B')]) # 4B是指令碼 sdata = sdata + bytes.fromhex(HexStr) # 2字節(jié)機號 sdata = sdata + bytes([0]) # 讀0個扇區(qū)數(shù)據(jù) sdata = sdata + bytes.fromhex("55AA6699") # 4字節(jié)確認碼 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送4B指令將讀寫器設為只讀卡號 SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[ 0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) else: keystr = self.textEdit_4.toPlainText().strip() # 卡片認證密碼 if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6): self.ListAddItem("卡密碼輸入錯誤!") self.textEdit_4.setFocus() return sdata = bytes([eval('0x4B')]) # 4B是指令碼 sdata = sdata + bytes.fromhex("0000") # 2字節(jié)機號 sdata = sdata + bytes([1]) # 主動讀取的扇區(qū)數(shù),如果要開通幾個扇區(qū)這里就填幾 if (auth == 0): sector = sector + 128 sdata = sdata + bytes([sector]) + bytes.fromhex( keystr) # 1字節(jié)的扇區(qū)號及密碼認證類型 + 6字節(jié)卡認證密碼 ,如果讀多個扇區(qū)也按此結構加入,可以開通全部的16個扇區(qū) sdata = sdata + bytes.fromhex("55AA6699") # 4字節(jié)確認碼 s.sendto(sdata, (Remoip, Reprot)) # 發(fā)送4B指令將讀寫器設為主動讀取扇區(qū) SendInf = get_time() + 'SendTo:' + (remortiport + ' ')[ 0:22] + ' Data:' # 為方便開發(fā),打印出詳細的指令 for num in range(0, len(sdata)): SendInf = SendInf + '%02X ' % (sdata[num]) self.ListAddItem(SendInf) def PBWifiSet_click(self): self.wifiset = WifiSetWindow() # 實例化 wifi熱點參數(shù)設置窗口 screen = QDesktopWidget().screenGeometry() size = self.wifiset.geometry() # 獲得窗口相關坐標 newLeft = (screen.width() - size.width()) // 2 newTop = (screen.height() - size.height()) // 2 # 移動窗口使其居中 self.wifiset.move(newLeft, newTop) self.wifiset.setWindowFlags( # 使能最小化按鈕 .WindowMinimizeButtonHint QtCore.Qt.WindowCloseButtonHint | # 使能關閉按鈕 QtCore.Qt.WindowStaysOnTopHint) # 窗體總在最前端 self.wifiset.groupBox.setVisible(False) self.wifiset.comboBox_Sendmode.setCurrentIndex(1) self.wifiset.label_7.setStyleSheet('color: red;') self.wifiset.lineEdit_RemoIPort.setStyleSheet("color: red;") self.wifiset.show() self.setEnabled(False) self.wifiset.WifiSignel.connect(self.GetWiFiWindoSignal) # 將wifi熱點參數(shù)窗口的 信號 綁定給 主窗口的 槽函數(shù) self.wifiset.lineEdit_RemoIPort.setText(self.textEdit_7.toPlainText().strip()) def PB15693RW_click(self): self.ISO15693RW = ISO15693RW() screen = QDesktopWidget().screenGeometry() size = self.ISO15693RW.geometry() # 獲得窗口相關坐標 newLeft = (screen.width() - size.width()) // 2 newTop = (screen.height() - size.height()) // 2 # 移動窗口使其居中 self.ISO15693RW.move(newLeft, newTop) self.ISO15693RW.setWindowFlags( # 使能最小化按鈕 .WindowMinimizeButtonHint QtCore.Qt.WindowCloseButtonHint | # 使能關閉按鈕 QtCore.Qt.WindowStaysOnTopHint) # 窗體總在最前端 self.ISO15693RW.lineEdit_RemoIPort.setText(self.textEdit_7.toPlainText().strip()) self.ISO15693RW.lineEdit_Mask.setText('0000000000000000') self.ISO15693RW.label_19.setStyleSheet('color:red;') self.ISO15693RW.label_20.setStyleSheet('color:red;') self.ISO15693RW.lineEdit_RemoIPort.setStyleSheet('color:blue;') self.ISO15693RW.lineEdit_disp.setStyleSheet('color:blue;') self.ISO15693RW.show() self.setEnabled(False) self.ISO15693RW.iso15693Signel.connect(self.Getiso15693Signal) # ======================================================================================================================= def get_time(): current_time = datetime.datetime.now() current_time_str = current_time.strftime("%H:%M:%S.%f")[:-3] return current_time_str + ' ' def is_valid_hex(input_str): input_str = input_str.replace(" ", "") try: if (len(bytes.fromhex(input_str)) == len(input_str) / 2): return True else: return False except: return False def GetHexIPAdd(inputstr): try: FieldsList = inputstr.split('.') HexIPAdd = '%02X%02X%02X%02X' % ( int(FieldsList[0]), int(FieldsList[1]), int(FieldsList[2]), int(FieldsList[3])) # 4字節(jié)設備IP if (len(HexIPAdd) != 8): HexIPAdd = "00000000" except: HexIPAdd = "00000000" return HexIPAdd def IsIport(inputstr): try: remortiport = inputstr.strip() FieldsList = remortiport.split(':') Remoip = GetHexIPAdd(FieldsList[0]) Reprot = int(FieldsList[1]) if (Remoip == "00000000"): return False else: return True except: return False def get_mac_address(ip_address): # 不能返回本機MAC # 初始化 用正則表達式're'編譯出匹配MAC地址的正則表達式對象 patt_mac = re.compile('([a-f0-9]{2}[-:]){5}[a-f0-9]{2}', re.I) # ping os.popen('ping -n 1 -w 500 {} > nul'.format(ip_address)) # 然后使用'arp'命令獲取該IP地址對應的MAC地址 返回一個類文件對象 可以通過 read 方法獲取命令的輸出結果 arp_file = os.popen('arp -a {}'.format(ip_address)) # 使用正則表達式'self.patt_mac'在輸出結果中查找符合 MAC 地址格式的字符串 并返回找到的第一個匹配項 即 IP 對應的 MAC 地址 mac_addr = patt_mac.search(arp_file.read()) # 根據(jù)正則表達式對象匹配MAC地址 如果匹配到了就返回MAC地址 否則返回None if mac_addr: mac_addr = mac_addr.group() return mac_addr else: return 'FF-FF-FF-FF-FF-FF' def get_default_gateway(): gateways = netifaces.gateways() return gateways['default'][netifaces.AF_INET][0] # 獲取IPv4的默認網(wǎng)關 # ======================================================================================================================= if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) mainWindow = MainWindow() screen = QDesktopWidget().screenGeometry() size = mainWindow.geometry() # 獲得窗口相關坐標 newLeft = (screen.width() - size.width()) // 2 newTop = (screen.height() - size.height()) // 2 # 移動窗口使其居中 mainWindow.move(newLeft, newTop) mainWindow.setWindowTitle("RFID網(wǎng)絡讀卡器測試工具 Ver:2024.04.01") mainWindow.show() mainWindow.TEPort.setPlainText("39169") mainWindow.textEdit.setPlainText("歡迎您使用我們的網(wǎng)絡讀卡器!") mainWindow.textEdit_2.setPlainText("歡迎您使用我們的網(wǎng)絡讀卡器!") mainWindow.textEdit_3.setPlainText("00000000") mainWindow.textEdit_4.setPlainText("FFFFFFFFFFFF") mainWindow.textEdit_5.setPlainText( "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") mainWindow.textEdit_6.setPlainText("FF FF FF FF FF FF FF 07 80 69 FF FF FF FF FF FF") mainWindow.textEdit_7.setPlainText('255.255.255.255:39169') mainWindow.textEdit_8.setPlainText('00000') mainWindow.spinBox.setValue(20) mainWindow.spinBox_2.setValue(200) mainWindow.spinBox_3.setValue(10) mainWindow.CBauth.setCurrentIndex(0) mainWindow.listWidget.setStyleSheet("color: blue;") mainWindow.textEdit_9.setStyleSheet("color: blue;") mainWindow.label_19.setStyleSheet("color: red;") mainWindow.PBSearch.setStyleSheet("color: red;") if sys.platform == 'linux' or sys.platform == 'mac': # linux、mac系統(tǒng)獲取電腦所有網(wǎng)卡IP ips = [ip.split('/')[0] for ip in os.popen("ip addr | grep 'inet '|awk '{print $2}'").readlines()] for i in ips: mainWindow.CBIP.addItem(i) else: addrs = socket.getaddrinfo(socket.gethostname(), None) # Windows系統(tǒng)獲取電腦所有網(wǎng)卡IP for item in addrs: if ':' not in item[4][0]: mainWindow.CBIP.addItem(item[4][0]) if mainWindow.CBIP.count() > 0: Bindip = mainWindow.CBIP.currentText() Bindprot = int(mainWindow.TEPort.toPlainText()) try: listen = 1 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.bind((Bindip, Bindprot)) mainWindow.subSockListenThread = SockListenThread() mainWindow.subSockListenThread.Sock_data.connect(mainWindow.SockGetData) mainWindow.subSockListenThread.start() # t1=threading.Thread(target=run,args=("t1",)) # t1.setDaemon(True) #守護線程--也稱“服務線程”,在沒有用戶線程可服務時會自動離開,確保關閉窗口后關閉處理線程 # t1.start() mainWindow.ListAddItem("Socket is bind to :" + Bindip + ":" + str(Bindprot)) except: listen = 0 mainWindow.ListAddItem("Socket is bind to :" + Bindip + ":" + str(Bindprot) + " failure!") changip = 1 sys.exit(app.exec_())
UDP通信代碼如下:
#python通過縮進來表示代碼塊,不可以隨意更改每行前面的空白,否則程序會運行錯誤?。。∪绻s進不一致,就會報錯: IndentationError #!/usr/bin/env python # -*- coding: utf-8 -*- #python -m pdb xxx.py 調試程度 n命令單步執(zhí)行,s命令單步執(zhí)行 會進入函數(shù)內部 b xx ,c #import pdb pdb.set_trace() 設斷點 import sys import os import socket import time import pdb #接收到數(shù)據(jù)包后向設備發(fā)確認信息,否則設備會重發(fā)三次-------------------------------------------- def DisableSendAge(data,addr): #105是指令碼+接收到的信息前8個字節(jié) sdata=bytes([105,data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8]]) s.sendto(sdata,addr) message = 'SendData To %s:%s' % (addr, sdata) print(message+"n") #向讀卡器發(fā)送顯示及蜂鳴響聲---------------------------------------------------------------- def SendDispBeep(DispStr,addr): DispStr=DispStr[0:34] disb=bytes(DispStr, encoding='gbk') #將要顯示的文字轉bytes comb=bytes([eval('0x5A'),0,0,2,30]) #5A是指令碼+2字節(jié)機號+1字節(jié)蜂鳴代碼+1字節(jié)顯示時長 sdata=comb+disb s.sendto(sdata,addr) message = 'SendData To %s:%s' % (addr, sdata) print(message+"n") #向讀卡器發(fā)送顯示+繼電器+固定組合語音------------------------------------------------------- def SendDispSpk(DispStr,addr): DispStr=DispStr[0:34] disb=bytes(DispStr, encoding='gbk') #將要顯示的文字轉bytes Spkb=bytes([55,41,53]) #固定組合語音代碼,取值請查看通訊協(xié)議說明,一次最大取值21條 Spkl=len(Spkb) #語音代碼條數(shù) sufb=bytes([eval('0x55'),eval('0xaa'),eval('0x66'),eval('0x99')]) #固定的抗干擾后綴 comb=bytes([eval('0x5B'),0,0,2,eval('0xF0'),30,0,20,0,36,Spkl]) #5B是指令碼+2字節(jié)機號+1字節(jié)蜂鳴代碼+1字節(jié)繼電器代碼+2字節(jié)繼電器延時+1字節(jié)顯示時長+1字節(jié)顯示起始位+1字節(jié)顯示長度+1語音長度 sdata=comb+disb+Spkb+sufb s.sendto(sdata,addr) message = 'SendData To %s:%s' % (addr, sdata) print(message+"n") #向讀卡器發(fā)送顯示+繼電器+TTS語音------------------------------------------------------- def SendDispTTS(DispStr,addr): DispStr=DispStr[0:34] disb=bytes(DispStr, encoding='gbk') #將要顯示的文字轉bytes SpkStr='[v10]感謝您的使用,再見!' #要播報的TTS語音,[v10]表示音量,取值0-16,可放置字符串的任意地方,一次最多126個字節(jié) Spkb=bytes(SpkStr, encoding='gbk') #將要播報的TTS語音轉bytes, Spkl=len(Spkb) #TTS語音長度 sufb=bytes([eval('0x55'),eval('0xaa'),eval('0x66'),eval('0x99')]) #固定的抗干擾后綴 comb=bytes([eval('0x5C'),0,0,2,eval('0xF0'),20,0,20,0,36,Spkl]) #5C是指令碼+2字節(jié)機號+1字節(jié)蜂鳴代碼+1字節(jié)繼電器代碼+2字節(jié)繼電器延時+1字節(jié)顯示時長+1字節(jié)顯示起始位+1字節(jié)顯示長度+1語音長度 sdata=comb+disb+Spkb+sufb s.sendto(sdata,addr) message = 'SendData To %s:%s' % (addr, sdata) print(message+"n") #向讀寫器發(fā)送讀扇區(qū)內數(shù)據(jù)的指令--------------------------------------------------------- def ReadCardInf(data,addr): comb=bytes([eval('0x3B'),data[5],data[6],1,data[10],data[11],data[12],data[13],8,0,]) #指令碼3B+2字節(jié)機號(data[5],data[6]存有機號)+1字節(jié)扇區(qū)個數(shù)+4個字節(jié)卡號(data存有卡號)+1字節(jié)扇區(qū)號+1字節(jié)密碼認證方式 keys=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')]) #6個字節(jié)的卡認證密碼 sdata=comb+keys s.sendto(sdata,addr) message = 'SendData To %s:%s' % (addr, sdata) print(message+"n") #向讀寫器發(fā)送寫信息到指定扇區(qū)的指令--------------------------------------------------------- def WriteCard(data,addr): sdata=bytearray() sdata.append(eval('0x3D')) #寫卡指令碼 sdata.append(data[5]) #2個字節(jié)的機號,如都取0表示任意機號 sdata.append(data[6]) #data[56]保存了上傳時設備的機號 sdata.append(1) #操作扇區(qū)的個數(shù) sdata.append(data[8]) #4個字節(jié)的卡號,data[891011]保存了已讀取的卡號 sdata.append(data[9]) #如果這4個字節(jié)全部取0表示任意卡 sdata.append(data[10]) sdata.append(data[11]) sdata.append(8) #扇區(qū)號 sdata.append(0) #取值0表示以A密碼認證,取值1表示以B密碼認證 sdata.append(eval('0xFF')) #6個字節(jié)的卡片認證密碼 sdata.append(eval('0xFF')) sdata.append(eval('0xFF')) sdata.append(eval('0xFF')) sdata.append(eval('0xFF')) sdata.append(eval('0xFF')) for num in range(0,48): #48個字節(jié)的寫卡信息 sdata.append(data[14+num]) #data[14]保存了已讀取的卡扇區(qū)信息,這里表示將已讀取的數(shù)據(jù)再次寫入,如要寫新的數(shù)據(jù)將數(shù)據(jù)寫入這段緩沖 sdata.append(eval('0x55')) #4個字節(jié)固定的抗干擾后綴 sdata.append(eval('0xAA')) sdata.append(eval('0x66')) sdata.append(eval('0x99')) s.sendto(sdata,addr) message = 'SendData To %s:%s' % (addr, sdata) print(message+"n") #獲取電腦時鐘--------------------------------------------------------------------------- def get_time(): st = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) st=st[0:16] return st #主程序--------------------------------------------------------------------------------- IpList=[] if sys.platform == 'linux' or sys.platform=='mac': # linux、mac系統(tǒng)獲取電腦所有網(wǎng)卡IP ips = [ip.split('/')[0] for ip in os.popen("ip addr | grep 'inet '|awk '{print $2}'").readlines()] for i in ips: IpList.append(i) print('%d '%(len(IpList)) + i) else: addrs = socket.getaddrinfo(socket.gethostname(),None) #windows獲取電腦所有網(wǎng)卡IP for item in addrs: if ':' not in item[4][0]: IpList.append(item[4][0]) print('%d '%(len(IpList)) + item[4][0]) BUFSIZE = 1024 Bindip=IpList[1] #如有多張網(wǎng)卡,可選擇綁定不同的網(wǎng)卡 Bindprot=39169 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.bind((Bindip, Bindprot)) print('n系統(tǒng)綁定IP:'+Bindip+':%d'% (Bindprot)) CardNuff=bytearray() sdata=bytes([166]) #搜索在線設備的指令碼 s.sendto(sdata,('255.255.255.255',Bindprot)) #發(fā)送搜索同網(wǎng)段內所有在線設備的廣播指令 message = 'SendData To 255.255.255.255:39169 a6' print(message+"n") LastBuf=bytes([0,0,0,0,0,0,0,0,0]) #保存最后接收到的信息,用于比較是否重復接收的信息 while True: data, addr = s.recvfrom(BUFSIZE) message = 'Received from %s:%s' % (addr, data) print(message) if(len(data)>8): if(data[0]==LastBuf[0] and data[1]==LastBuf[1] and data[2]==LastBuf[2] and data[3]==LastBuf[3] and data[4]==LastBuf[4] and data[5]==LastBuf[5] and data[6]==LastBuf[6] and data[7]==LastBuf[7] and data[8]==LastBuf[8]): #比較是否是重發(fā)數(shù)據(jù) DisableSendAge(data, addr) #接收到重復上傳的信息,不用解析處理 print('n') else: LastBuf=data[0:9] #將接收到的信息保存,用于下次接收數(shù)據(jù)時比對 if(data[0]==eval('0xF2')): #接收到設備開機、搜索在線設備的返回信息,對信息解析 print('指令碼 :%02x 設備開機 或 響應服務器的搜索' % (data[0])) print('設備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4])) print('掩 碼 :%d.%d.%d.%d' % (data[5],data[6],data[7],data[8])) print('通訊端口:%d' % (data[9]+data[10]*256)) print('機 號 :%d' % (data[11]+data[12]*256)) print('網(wǎng) 關 :%d.%d.%d.%d' % (data[13],data[14],data[15],data[16])) MacStr='' for num in range(17,23): MacStr=MacStr+'%02x' % (data[num]) if(num22): MacStr=MacStr+'-' print('網(wǎng)關MAC:'+ MacStr) print('遠程服務器IP:%d.%d.%d.%d' % (data[23],data[24],data[25],data[26])) MacStr='' for num in range(27,33): MacStr=MacStr+'%02x' % (data[num]) if(num32): MacStr=MacStr+'-' print('服務器MAC:'+ MacStr) print('網(wǎng)絡標識:%02x' % (data[33])) print('響聲標識:%02x' % (data[34])) MacStr='16-88-' for num in range(35,39): MacStr=MacStr+'%02x' % (data[num]) if(num38): MacStr=MacStr+'-' print('讀卡器MAC:'+ MacStr) if(len(data)?>39): SerialNum='' for num in range(39,len(data)): SerialNum=SerialNum+'%02x' % (data[num]) print('設備唯一序號:'+ SerialNum) print('n') elif(data[0]==eval('0xF3')): #接收到設備的心跳數(shù)據(jù)包,設備心跳間隔可根據(jù)協(xié)議自行設置 print('指令碼 :%02x 設備心跳包' % (data[0])) print('設備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4])) print('機 號 :%d' % (data[5]+data[6]*256)) print('包序號 :%d' % (data[7]+data[8]*256)) print('心跳類型:%02x' % (data[9])) print('長度 :%02x' % (data[10])) print('繼電器狀態(tài):%02x' % (data[11])) print('外部輸入狀態(tài):%02x' % (data[12])) print('隨機動態(tài)碼:%02x%02x%02x%02x' % (data[13],data[14],data[15],data[16])) SerialNum='' for num in range(17,len(data)): SerialNum=SerialNum+'%02x' % (data[num]) print('設備序列號:'+ SerialNum+'n') elif(data[0]==eval('0xD1')): #接收到讀取ID卡信息的數(shù)據(jù)包,對信息解析 print('指令碼 :%02x 接收到ID卡刷卡' % (data[0])) print('設備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4])) print('機 號 :%d' % (data[5]+data[6]*256)) print('包序號 :%d' % (data[7]+data[8]*256)) print('16進制卡號:%02x%02x%02x%02x' % (data[9],data[10],data[11],data[12])) Cardno=data[9] Cardno=Cardno+(data[10]*256) Cardno=Cardno+(data[11]*65536) Cardno=Cardno+(data[12]*16777216) CardnoStr='%010d' % Cardno print('10進制卡號:'+CardnoStr) SerialNum='' for num in range(14,len(data)): SerialNum=SerialNum+'%02x' % (data[num]) print('設備序列號:'+ SerialNum+'n') DisableSendAge(data, addr) #向設備發(fā)送確認包,否則相同的信息設備會重復發(fā)送三次 #在這里加入業(yè)務對數(shù)據(jù)庫的查、增、刪、改操作 #將業(yè)務處理結果發(fā)送到設備 DispStr='卡號:'+CardnoStr+' '+get_time()+' '#滿屏顯示,補足后面空格 SendDispBeep(DispStr,addr) #向讀卡器發(fā)送顯示及蜂鳴響聲 #SendDispSpk(DispStr,addr) #向讀卡器發(fā)送顯示+繼電器+固定組合語音 #SendDispTTS(DispStr,addr) #向讀卡器發(fā)送顯示+繼電器+TTS語音 elif(data[0]==eval('0xC1')): #接收到讀取IC卡號的數(shù)據(jù)包,對信息解析 print('指令碼 :%02x 接收到IC卡刷卡' % (data[0])) print('設備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4])) print('機 號 :%d' % (data[5]+data[6]*256)) print('包序號 :%d' % (data[7]+data[8]*256)) print('16進制卡號:%02x%02x%02x%02x' % (data[10],data[11],data[12],data[13])) Cardno=data[10] Cardno=Cardno+(data[11]*256) Cardno=Cardno+(data[12]*65536) Cardno=Cardno+(data[13]*16777216) CardnoStr='%010d' % Cardno print('10進制卡號:'+CardnoStr) SerialNum='' for num in range(14,len(data)): SerialNum=SerialNum+'%02x' % (data[num]) print('設備序列號:'+ SerialNum+'n') DisableSendAge(data, addr) #向設備發(fā)送確認包,否則相同的信息設備會重復發(fā)送三次 #在這里加入業(yè)務對數(shù)據(jù)庫的查、增、刪、改操作 #將業(yè)務處理結果發(fā)送到設備 DispStr='卡號:'+CardnoStr+' '+get_time()+' '#滿屏顯示,補足后面空格 #SendDispBeep(DispStr,addr) #向讀卡器發(fā)送顯示及蜂鳴響聲 #SendDispSpk(DispStr,addr) #向讀卡器發(fā)送顯示+繼電器+固定組合語音 SendDispTTS(DispStr,addr) #向讀卡器發(fā)送顯示+繼電器+TTS語音 ReadCardInf(data,addr) #如果設備是讀寫器,可以繼續(xù) 發(fā)送讀取指定扇區(qū)信息的指令 elif(data[0]==eval('0xC3')): #全扇區(qū)讀寫器收到讀卡扇區(qū)內的數(shù)據(jù)(刷卡時主動讀取并上傳) j=data[10]*48 m=data[11]*48 for num in range(0,m): #將讀取到的扇區(qū)信息存入讀卡緩沖 CardNuff.append(data[16+num]) if(data[11]+data[10]>=data[9]): #已完全收到所有包數(shù)據(jù),一個數(shù)據(jù)包最多傳4個扇區(qū)的數(shù)據(jù),如果讀寫器設備讀寫扇區(qū)數(shù)大于4,數(shù)據(jù)要分2個包上傳,扇區(qū)數(shù)大于8要分3個包,大與12要分4個包上傳 print('接收到的信息為IC卡扇區(qū)內數(shù)據(jù)') print('指令碼 :%02x ' % (data[0])) print('設備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4])) print('機 號 :%d' % (data[5]+data[6]*256)) print('包序號 :%d' % (data[7]+data[8]*256)) print('16進制卡號:%02x%02x%02x%02x' % (data[12],data[13],data[14],data[15])) Cardno=data[12] Cardno=Cardno+(data[13]*256) Cardno=Cardno+(data[14]*65536) Cardno=Cardno+(data[15]*16777216) CardnoStr='%010d' % Cardno print('10進制卡號:'+CardnoStr) m=data[9]*48 CardInfStr='' for num in range(0,m): CardInfStr=CardInfStr+'%02x ' % (CardNuff[num]) print('卡片內數(shù)據(jù):'+ CardInfStr) #在這里加入業(yè)務對數(shù)據(jù)庫的查、增、刪、改操作 CardNuff=bytearray() #已接收完,清空接收緩沖 print('n') elif(data[0]==eval('0xC5')): #指定區(qū)號、密碼讀卡返回信息 print('接收到的信息為讀取IC卡扇區(qū)內數(shù)據(jù)') print('指令碼 :%02x ' % (data[0])) print('設備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4])) print('機 號 :%d' % (data[5]+data[6]*256)) print('16進制卡號:%02x%02x%02x%02x' % (data[8],data[9],data[10],data[11])) print('扇區(qū)數(shù) :%02x ' % (data[7])) print('扇區(qū)號 :%02x ' % (data[12])) if(data[13]==0): CardInfStr='' for num in range(0,48): CardInfStr=CardInfStr+'%02x ' % (data[14+num]) print('卡片內數(shù)據(jù):'+ CardInfStr+'n') WriteCard(data,addr) #如果寫卡,可以繼續(xù) 發(fā)送寫信息到指定扇區(qū)的指令 else: if(data[13]==12): print('卡密碼認證失敗n') else: print('讀卡失敗,錯誤代碼:%02x ' % (data[13])+'n') elif(data[0]==eval('0xCD')): #響應寫卡、更改卡密碼后的返回信息 print('指令碼 :%02x ' % (data[0])) print('設備IP :%d.%d.%d.%d' % (data[2],data[3],data[4],data[5])) print('機 號 :%d' % (data[6]+data[7]*256)) print('16進制卡號:%02x%02x%02x%02x' % (data[9],data[10],data[11],data[12])) print('扇區(qū)數(shù) :%02x ' % (data[8])) print('扇區(qū)號 :%02x ' % (data[13])) if(data[1]==0x3A): if(data[14]==0x00): print('更改卡密碼成功!') else: print('更改卡密碼失敗,錯誤代碼:%02x ' % (data[14])) else: if(data[1]==0x3D): if(data[14]==0x00): print('寫卡成功!') else: print('寫卡失敗,錯誤代碼:%02x ' % (data[14])) print('n') else: print('n')
審核編輯 黃宇
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。
舉報投訴
-
讀卡器
+關注
關注
2文章
438瀏覽量
40330 -
python
+關注
關注
56文章
4827瀏覽量
86796
發(fā)布評論請先 登錄
相關推薦
熱點推薦
硬核跨界!CAN轉EtherCAT:門禁讀卡器的“破壁者”來了
耐達訊通訊技術CAN轉EtherCAT網(wǎng)關這位“技術紅娘”,如何讓門禁讀卡器秒變“雙語達人”
傳統(tǒng)門禁讀卡器??緾AN協(xié)議穩(wěn)扎穩(wěn)打,但智能建筑要求實時性爆炸:刷卡開門必須毫秒級響應,還得聯(lián)動燈光、空調
發(fā)表于 07-16 14:24

DD3118 高集成度讀卡器控制芯片數(shù)據(jù)手冊
DD3118是一款采用40納米低功耗技術制造的高性能、高集成度讀卡器控制芯?片,專為讀卡器設計。作為讀卡器的核心功能模塊,DD3118支持USB?3.0、SD ?3.0和eMMC?4.5標準協(xié)議,能夠穩(wěn)定訪問存儲在內存卡中的數(shù)據(jù)
發(fā)表于 06-16 16:14
?2次下載
DD3118規(guī)格書|DD3118說明書|3.0讀卡器芯片規(guī)格書
DD3118是一款高性能、高度集成的讀卡器控制芯片,DD3118采用40nm低功耗技術制造,專為讀卡器或者讀卡方案設計的芯片。DD3118作為讀卡器的核心功能模塊,SD 3.0和eMM
發(fā)表于 06-12 17:40
?0次下載
抖膽DD3118高性價比USB3.0讀卡器芯片方案-替代創(chuàng)惟GL3213S
、封裝信息及訂購信息。
適合人群:硬件工程師、電子設計師以及對USB3.0讀卡器控制芯片有興趣的技術人員。
DD3118芯片框架:
DD3118芯片管腳分布及定義說明:
使用場景及目標:① 設計和開發(fā)
發(fā)表于 05-27 17:28
MAX14502高速USB至SD讀卡器,提供旁路控制技術手冊
MAX14502 USB轉SD? 卡讀卡器為支持全速USB通信(12Mbps)且?guī)в幸粋€或兩個SD卡插槽的便攜式設備,提供了將其升級為高速(480Mbps)USB卡讀卡器功能的途徑。MAX14502
MAXQ1741用于磁卡讀卡器的DeepCover安全微控制器技術手冊
讀卡器接口、I2C接口、兩個SPI接口和一個通用同步/異步收發(fā)器接口(USART)。安全功能包括AES加密引擎、硬件隨機數(shù)發(fā)生器、電壓攻擊檢測器和自毀輸入引腳。單周期16位RISC M

MAXQ1743 DeepCover安全磁卡讀卡器IC技術手冊
DeepCover 嵌入式安全方案采用多重先進的物理安全機制保護敏感數(shù)據(jù),提供最高等級的密鑰存儲安全保護。
DeepCover MAXQ1743是集成的三軌磁條讀卡器IC,在機器/磁卡接口上為POS終端或ATM讀卡器提供安全保障。磁卡數(shù)據(jù)可采用AES或DES/TDE

ID卡網(wǎng)絡讀卡器C#小程序開發(fā)
(85.6x54x0.80±0.04mm)、異型卡等不同類型。按照應用場景,它通常包含個人的身份信息,如姓名、照片、身份證號碼等,常見的包括身份證、員工工作證、學生證,以及用于考勤、門禁、一卡通等系統(tǒng)的卡片。 二、工作原理 ID卡的工作過程如下: ID卡閱讀

TRF7970A NFC讀卡器天線多路復用
電子發(fā)燒友網(wǎng)站提供《TRF7970A NFC讀卡器天線多路復用.pdf》資料免費下載
發(fā)表于 10-26 11:15
?4次下載

AGV讀卡器在AGV自動搬運小車上應用方案
AGV小車上的AGV讀卡器通過讀取地面軌道的RFID電子標簽信息,做出相應的動作(如改變速度、選擇軌道、定位和停車等)。在AGV小車經(jīng)過站點A處時,AGV讀卡器讀取A處的電子標簽ID號,AGV小車

評論