0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

ID讀卡器Python小程序開發(fā)

鄒振豪 ? 來源:jf_51178285 ? 作者:jf_51178285 ? 2025-01-10 16:05 ? 次閱讀

液顯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)  # 保存最后接收到的信息,用于比較是否重復(fù)接收的信息
CardNuff = bytearray()  # 保存C3主動(dòng)讀取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)建一個(gè)信號,將接收到的數(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標(biāo)簽
# =======================================================================================================================
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):  # 設(shè)置15693網(wǎng)絡(luò)讀寫器 主動(dòng)讀卡塊號,未選擇塊號則讀取UID卡號上傳
        self.lineEdit_disp.setText('')
        RemoIPort = self.lineEdit_RemoIPort.text().strip()
        if (IsIport(RemoIPort) == False):
            QMessageBox.critical(self, "警告", "遠(yuǎn)程設(shè)備IP端口輸入錯(cuò)誤!", 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進(jìn)制數(shù)!", QMessageBox.Yes)
                self.lineEdit_Mask.setFocus()
                return
        except:
            QMessageBox.critical(self, "警告", "掩碼必須是16位16進(jìn)制數(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é)機(jī)號 0000表示任意機(jī)
        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ā)指令驅(qū)動(dòng)15693讀寫器讀指定塊號數(shù)據(jù)
        self.lineEdit_disp.setText('')
        self.plainTextEdit_Data.setPlainText('')
 
        RemoIPort = self.lineEdit_RemoIPort.text().strip()
        if (IsIport(RemoIPort) == False):
            QMessageBox.critical(self, "警告", "遠(yuǎn)程設(shè)備IP端口輸入錯(cuò)誤!", QMessageBox.Yes)
            self.lineEdit_RemoIPort.setFocus()
            return
 
        sendbuf = bytes([eval('0x30')])  # 1字節(jié)指令碼
        sendbuf = sendbuf + bytes.fromhex('0000')  # 2字節(jié)機(jī)號 0000表示任意機(jī)
 
        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進(jìn)制數(shù)!", QMessageBox.Yes)
                    self.lineEdit_RWCardno.setFocus()
                    return
                else:
                    sendbuf = sendbuf + bytes([64]) + rwcardbuf[::-1]  # 注意傳入的卡號高位在前
            except:
                QMessageBox.critical(self, "警告", "讀寫卡號必須是16位16進(jìn)制數(shù)!", QMessageBox.Yes)
                self.lineEdit_RWCardno.setFocus()
                return
        else:  # 讀寫感應(yīng)區(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ā)指令驅(qū)動(dòng)15693讀寫器寫數(shù)據(jù)到指定塊內(nèi)
        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 個(gè)字節(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 個(gè)字節(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, "警告", "遠(yuǎn)程設(shè)備IP端口輸入錯(cuò)誤!", QMessageBox.Yes)
            self.lineEdit_RemoIPort.setFocus()
            return
 
        sendbuf = bytes([eval('0x31')])  # 1字節(jié)指令碼
        sendbuf = sendbuf + bytes.fromhex('0000')  # 2字節(jié)機(jī)號 0000表示任意機(jī)
 
        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進(jìn)制數(shù)!", QMessageBox.Yes)
                    self.lineEdit_RWCardno.setFocus()
                    return
                else:
                    sendbuf = sendbuf + bytes([64]) + rwcardbuf[::-1]  # 注意傳入的卡號高位在前
            except:
                QMessageBox.critical(self, "警告", "讀寫卡號必須是16位16進(jìn)制數(shù)!", QMessageBox.Yes)
                self.lineEdit_RWCardno.setFocus()
                return
        else:  # 讀寫感應(yīng)區(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個(gè)字節(jié),富士通15693卡有一些型號是8個(gè)字節(jié)
        sendbuf = sendbuf + bytes([j])    # 本次總計(jì)寫塊數(shù),如果每塊4字節(jié) 一次最多可寫20塊, 每塊8字節(jié)一次最多寫10塊
        sendbuf = sendbuf + bytes.fromhex(datainfostr)  # 本次寫入的每塊數(shù)
        sendbuf = sendbuf + bytes.fromhex('55AA6699')   #  固定的后綴
        self.iso15693Signel.emit(RemoIPort, sendbuf)
 
# 設(shè)置讀卡器網(wǎng)絡(luò)參數(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年以前設(shè)備的網(wǎng)絡(luò)參數(shù)設(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é)設(shè)備IP
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備IP地址輸入錯(cuò)誤!", 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é)設(shè)備子網(wǎng)掩碼
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備子網(wǎng)掩碼輸入錯(cuò)誤!", 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é)設(shè)備遠(yuǎn)程服務(wù)器IP
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備遠(yuǎn)程服務(wù)器IP輸入錯(cuò)誤!", QMessageBox.Yes)
            self.lineEdit_RemoIP.setFocus()
            return
 
        try:
            HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256)  # 2字節(jié)機(jī)號
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備機(jī)號輸入錯(cuò)誤!", QMessageBox.Yes)
            self.lineEdit_ReaderNnm.setFocus()
            return
 
        try:
            FieldsList = SerialNum.split('-')
            HexStr = FieldsList[0] + FieldsList[1] + FieldsList[2] + FieldsList[3]  # 4字節(jié)設(shè)備網(wǎng)出廠序號
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備出廠序號輸入錯(cuò)誤!", 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, "警告", "遠(yuǎn)程設(shè)備IP端口輸入錯(cuò)誤!", QMessageBox.Yes)
                self.lineEdit_RemoIPort.setFocus()
                return
        self.netparaSignel.emit(RemoIPort, sdata)
 
    def pushButton_SetupNew_clicked(self):  # 固件日期為2015年以后設(shè)備的網(wǎng)絡(luò)參數(shù)設(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é)設(shè)備IP
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備IP地址輸入錯(cuò)誤!", 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é)設(shè)備子網(wǎng)掩碼
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備子網(wǎng)掩碼輸入錯(cuò)誤!", 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é)設(shè)備遠(yuǎn)程服務(wù)器IP
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備遠(yuǎn)程服務(wù)器IP輸入錯(cuò)誤!", 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é)設(shè)備遠(yuǎn)程服務(wù)器MAC
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備遠(yuǎn)程服務(wù)器MAC輸入錯(cuò)誤!", 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é)設(shè)備網(wǎng)關(guān)
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備網(wǎng)關(guān)IP輸入錯(cuò)誤!", 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é)設(shè)備網(wǎng)關(guān)MAC
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備網(wǎng)關(guān)MAC輸入錯(cuò)誤!", QMessageBox.Yes)
            self.lineEdit_GatwayMAC.setFocus()
            return
 
        try:
            HexStr = '%02X%02X' % (DevNo % 256, DevNo // 256)  # 2字節(jié)機(jī)號
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備機(jī)號輸入錯(cuò)誤!", 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, "警告", "設(shè)備端口輸入錯(cuò)誤!", QMessageBox.Yes)
            self.lineEdit_ReaderPort.setFocus()
            return
 
        try:
            FieldsList = SerialNum.split('-')
            HexStr = FieldsList[0] + FieldsList[1] + FieldsList[2] + FieldsList[3]  # 4字節(jié)設(shè)備網(wǎng)出廠序號
            sdata = sdata + bytes.fromhex(HexStr)
        except:
            QMessageBox.critical(self, "警告", "設(shè)備出廠序號輸入錯(cuò)誤!", 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, "警告", "遠(yuǎn)程設(shè)備IP端口輸入錯(cuò)誤!", QMessageBox.Yes)
                self.lineEdit_RemoIPort.setFocus()
                return
        self.netparaSignel.emit(RemoIPort, sdata)
 
    def pushButton_SetTCP_clicked(self):  # 設(shè)置TCP協(xié)議讀卡器 遠(yuǎn)程服務(wù)器偵聽端口
        self.plainTextEdit_Disp.setPlainText('')
 
        RemoIPort = self.lineEdit_RemoIPort.text().strip()
        if (IsIport(RemoIPort) == False):
            QMessageBox.critical(self, "警告", "遠(yuǎn)程設(shè)備IP端口輸入錯(cuò)誤!", 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, "警告", "讀卡器通訊端口輸入錯(cuò)誤!", 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, "警告", "服務(wù)器TCP通訊端口輸入錯(cuò)誤!", 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):  # 設(shè)置HTTP協(xié)議讀卡器數(shù)據(jù)傳送方式、服務(wù)端偵聽端口 及 訪問文件
        self.plainTextEdit_Disp.setPlainText('')
 
        RemoIPort = self.lineEdit_RemoIPort.text().strip()
        if (IsIport(RemoIPort) == False):
            QMessageBox.critical(self, "警告", "遠(yuǎn)程設(shè)備IP端口輸入錯(cuò)誤!", 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, "警告", "讀卡器通訊端口輸入錯(cuò)誤!", QMessageBox.Yes)
            self.lineEdit_ReaderPort.setFocus()
            return
 
        sdata = bytes([eval('0x1D')])  # 1字節(jié)指令碼
        sdata = sdata + bytes.fromhex("0000")  # 2字節(jié)機(jī)號 00表示任意機(jī)號
        sdata = sdata + bytes([filelen + 7])
        sdata = sdata + bytes([91])  # 設(shè)定HTTP協(xié)議的文件路徑、上傳方式  標(biāo)識
        sdata = sdata + bytes([filelen + 4])
        sdata = sdata + bytes([self.comboBox_Sendmodel.currentIndex()])  # 提交方式
        sdata = sdata + bytes([255])
        sdata = sdata + PortBuf  # 服務(wù)器偵聽端口
        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)
 
 
# 設(shè)置讀卡器WIFI熱點(diǎn)========================================================================================================
class WifiSetWindow(QWidget, Ui_wifiwin):
    WifiSignel = pyqtSignal(int, str, bytes)  # 創(chuàng)建一個(gè)信號,向主窗口請求發(fā)送對應(yīng)的指令
 
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle("WIFI熱點(diǎn)參數(shù)設(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):  # 設(shè)置WIFI熱點(diǎn)名稱、密碼、WIFIIP及數(shù)據(jù)傳送方式
        self.plainTextEdit.setPlainText(" ")
        RemoIPort = self.lineEdit_RemoIPort.text().strip()
        if (IsIport(RemoIPort) == False):
            QMessageBox.critical(self, "警告", "設(shè)備有線IP端口輸入錯(cuò)誤!", 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("熱點(diǎn)名稱長度不可以大于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é)機(jī)號
        comb = comb + bytes([namelen])  # 1字節(jié)熱點(diǎn)名稱長度
        if self.checkBox.isChecked():
            comb = comb + bytes([passlen])  # 1字節(jié)密碼長度
        else:
            comb = comb + bytes([0])  # 1字節(jié)密碼長度
        comb = comb + wifiname  # 熱點(diǎn)名稱
        for num in range(namelen, 60):  # 熱點(diǎn)名稱長度不足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自動(dòng)分配
            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地址輸入錯(cuò)誤!")
                self.lineEdit_IP.setFocus()
                return
 
            wifimask = GetHexIPAdd(self.lineEdit_mask.text())
            if (wifiip == '00000000'):
                self.plainTextEdit.setPlainText("WIFI的掩碼地址輸入錯(cuò)誤!")
                self.lineEdit_mask.setFocus()
                return
 
            wifigetway = GetHexIPAdd(self.lineEdit_gateway.text())
            if (wifiip == '00000000'):
                self.plainTextEdit.setPlainText("WIFI的掩碼地址輸入錯(cuò)誤!")
                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')  # 指令結(jié)束碼,抗網(wǎng)絡(luò)上的干擾信號
 
        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, "警告", "設(shè)備有線IP端口輸入錯(cuò)誤!", 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)絡(luò)端口獲取刷卡信息、向讀卡器發(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ā)送設(shè)置WIFI參數(shù)的指令
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        for num in range(0, len(sdata)):
            SendInf = SendInf + '%02X ' % (sdata[num])
        self.ListAddItem(SendInf)
 
    def GetWiFiWindoSignal(self, sigcode, remortiport, sdata):
        if (sigcode == 1):  # 設(shè)置WIFI叁數(shù)的信號
            FieldsList = remortiport.split(':')
            Remoip = FieldsList[0]
            Reprot = int(FieldsList[1])
 
            s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送設(shè)置WIFI參數(shù)的指令
 
            SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[
                                               0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
            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ā)送設(shè)置WIFI參數(shù)的指令
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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  # 是設(shè)備重發(fā)的數(shù)據(jù),直接丟棄不做處理
            else:
                LastBuf = data[0:9]  # 將接收到的信息保存,用于下次接收數(shù)據(jù)時(shí)比對
 
                if (data[0] == eval('0xF2')):  # 接收到設(shè)備開機(jī)、搜索在線設(shè)備的返回信息,對信息解析
                    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ù)解析:設(shè)備響應(yīng)搜索指令、開機(jī)標(biāo)識:F2,設(shè)備信息已在表格內(nèi)顯示,如需修改設(shè)備網(wǎng)絡(luò)參數(shù),先在表格內(nèi)點(diǎn)擊要修改的設(shè)備再點(diǎn)擊 "修改選定設(shè)備的網(wǎng)絡(luò)參數(shù)" 鍵!'
                    self.textEdit_9.setText(dispinf)
 
                elif (data[0] == eval('0xF3')):  # 接收到設(shè)備的心跳數(shù)據(jù)包,設(shè)備心跳間隔可根據(jù)協(xié)議自行設(shè)置
                    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])  # 設(shè)備IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 機(jī)號
                    FrameNo = '%d' % (data[7] + data[8] * 256)  # 數(shù)據(jù)包序號
                    SerialNum = ''  # 設(shè)備硬件序列號
                    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進(jìn)制卡號
                        Cardno = data[10]
                        Cardno = Cardno + (data[11] * 256)
                        Cardno = Cardno + (data[12] * 65536)
                        Cardno = Cardno + (data[13] * 16777216)
                        CardnoStr = '%010d' % Cardno  # 轉(zhuǎn)10進(jìn)制卡號
                        dispinf = '數(shù)據(jù)解析:讀IC卡號標(biāo)識:'
                    else:
                        Card16H = '%02X%02X%02X%02X' % (data[9], data[10], data[11], data[12])  # 原始16進(jìn)制卡號
                        Cardno = data[9]
                        Cardno = Cardno + (data[10] * 256)
                        Cardno = Cardno + (data[11] * 65536)
                        Cardno = Cardno + (data[12] * 16777216)
                        CardnoStr = '%010d' % Cardno  # 轉(zhuǎn)10進(jìn)制卡號
                        dispinf = '數(shù)據(jù)解析:讀ID卡號標(biāo)識:'
 
                    dispinf = dispinf + FunCode + ',設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + Card16H + " 轉(zhuǎn)10進(jìn)制卡號:" + 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ū)內(nèi)的數(shù)據(jù)(刷卡時(shí)主動(dòng)讀取并上傳)
                    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ù),一個(gè)數(shù)據(jù)包最多傳4個(gè)扇區(qū)的數(shù)據(jù),如果讀寫器設(shè)備讀寫扇區(qū)數(shù)大于4,數(shù)據(jù)要分2個(gè)包上傳,扇區(qū)數(shù)大于8要分3個(gè)包,大與12要分4個(gè)包上傳
                        FunCode = '%02X' % (data[0])
                        DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4])
                        DevNo = '%05d' % (data[5] + data[6] * 256)  # 機(jī)號
                        FrameNo = '%d' % (data[7] + data[8] * 256)  # 數(shù)據(jù)包序號
                        Card16H = '%02X%02X%02X%02X' % (data[12], data[13], data[14], data[15])  # 原始16進(jìn)制卡號
                        dispinf = '數(shù)據(jù)解析:讀IC卡扇區(qū)標(biāo)識:' + FunCode + ',設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + 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])  # 設(shè)備IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 機(jī)號
                    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ū)標(biāo)識:' + FunCode + ',設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",16進(jìn)制卡號:" + 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 + ",卡密碼認(rèn)證失??!本次讀卡失?。?
                            self.textEdit_9.setText(dispinf)
                        else:
                            dispinf = dispinf + ",讀卡失敗,錯(cuò)誤代碼:%02X" % (data[13])
                            self.textEdit_9.setText(dispinf)
 
                elif (data[0] == eval('0xCD')):  # 響應(yīng)寫卡、更改卡密碼后的返回信息
                    FunCode = '%02X' % (data[0])
                    DEvIp = '%d.%d.%d.%d' % (data[2], data[3], data[4], data[5])  # 設(shè)備IP
                    DevNo = '%05d' % (data[6] + data[7] * 256)  # 機(jī)號
                    SectNum = data[8]  # 扇區(qū)總數(shù)
                    Card16H = '%02X%02X%02X%02X' % (data[9], data[10], data[11], data[12])  # 原始16進(jìn)制卡號
                    Sectors = data[13]  # 扇區(qū)號
                    dispinf = '數(shù)據(jù)解析:寫IC卡扇區(qū)標(biāo)識:' + FunCode + ',設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",16進(jìn)制卡號:" + Card16H
                    if (data[1] == 0x3A):
                        if (data[14] == 0x00):
                            dispinf = dispinf + ',更改卡密碼成功!'
                        elif (data[14] == 0x0C):
                            dispinf = dispinf + ',卡密碼認(rèn)證失敗,更改卡密碼失?。?
                        else:
                            dispinf = dispinf + ',更改卡密碼失敗,錯(cuò)誤代碼:%02X' % (data[14])
                    else:
                        if (data[1] == 0x3D):
                            if (data[14] == 0x00):
                                dispinf = dispinf + ',寫卡成功!'
                            elif (data[14] == 0x0C):
                                dispinf = dispinf + ',卡密碼認(rèn)證失敗,寫卡失敗!'
                            else:
                                dispinf = dispinf + ',寫卡失敗,錯(cuò)誤代碼:%02X' % (data[14])
                    self.textEdit_9.setText(dispinf)
 
                elif (data[0] == eval('0xCF') or data[0] == eval('0xDF')):  # 接收到IC、ID卡離開讀卡器感應(yīng)區(qū)的信息
                    # DisableSendAge(data, addr)
                    FunCode = '%02X' % (data[0])
                    DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4])  # 設(shè)備IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 機(jī)號
                    FrameNo = ':%d' % (data[7] + data[8] * 256)  # 數(shù)據(jù)包序號
                    Card16H = '%02X%02X%02X%02X' % (data[11], data[12], data[13], data[14])  # 原始16進(jìn)制卡號
                    Cardno = data[11]
                    Cardno = Cardno + (data[12] * 256)
                    Cardno = Cardno + (data[13] * 65536)
                    Cardno = Cardno + (data[14] * 16777216)
                    CardnoStr = '%010d' % Cardno  # 轉(zhuǎn)10進(jìn)制卡號
                    SerialNum = ''  # 設(shè)備硬件序列號
                    for num in range(15, len(data)):
                        SerialNum = SerialNum + '%02X' % (data[num])
                    if (data[0] == eval('0xCF')):
                        dispinf = '數(shù)據(jù)解析:IC卡離開標(biāo)識:'
                    else:
                        dispinf = '數(shù)據(jù)解析:ID卡離開標(biāo)識:'
                    dispinf = dispinf + FunCode + ',設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + Card16H + " 轉(zhuǎn)10進(jìn)制卡號:" + 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)關(guān)IP:%d.%d.%d.%d' % (data[21], data[22], data[23], data[24]) + "n"
                    dispinf = dispinf + '網(wǎng)關(guān) 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)絡(luò)狀態(tài):已連接wifi' + 'n'
                    elif (data[31] == 1):
                        dispinf = dispinf + 'WIFI網(wǎng)絡(luò)狀態(tài):連接失?。? + 'n'
                    elif (data[31] == 2):
                        dispinf = dispinf + 'WIFI網(wǎng)絡(luò)狀態(tài):已初始化!' + 'n'
                    else:
                        dispinf = dispinf + 'WIFI網(wǎng)絡(luò)狀態(tài):未初始化!' + 'n'
                    dispinf = dispinf + '讀卡器  名稱:' + data[34:(34 + data[32])].decode('utf-8') + 'n'
                    dispinf = dispinf + 'WIFI熱點(diǎn)名稱:' + data[44:(44 + data[33])].decode('utf-8') + 'n'
 
                    self.wifiset.plainTextEdit.setPlainText(dispinf)
 
                elif (data[0] == eval('0xF6')):  # 返回設(shè)備版本型號、固件日期
                    DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4])  # 設(shè)備IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 機(jī)號
                    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')):  # 設(shè)置15693讀寫器讀卡塊號成功
                    self.rw15693Signel.emit(3,RemortIPort, "設(shè)置15693讀寫器主動(dòng)讀卡塊號成功!")
 
                elif (data[0] == eval('0xC7')):  # 15693卡刷卡信息
                    self.DisableSendAge(RemortIPort, data)
 
                    DEvIp = '%d.%d.%d.%d' % (data[1], data[2], data[3], data[4])  # 設(shè)備IP
                    DevNo = '%05d' % (data[5] + data[6] * 256)  # 機(jī)號
                    FrameNo = '%d' % (data[7] + data[8] * 256)  # 數(shù)據(jù)包序號
                    if (data[9] == eval('0x00')):
                        self.rw15693Signel.emit(3, RemortIPort, "卡不在感應(yīng)區(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進(jìn)制卡號
                        self.rw15693Signel.emit(1,RemortIPort, Card16H)
                        if (self.findChild(QWidget, "ISO15693標(biāo)簽讀寫器測試")):
                            self.ISO15693RW.lineEdit_RWCardno.setText(Card16H)
                        if (data[9] == eval('0x01')):  # 主動(dòng)讀取15693卡號
                            SerialNum = ''  # 設(shè)備硬件序列號
                            for num in range(20, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:主動(dòng)讀取15693卡號,設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + Card16H + ",硬件序列號:" + SerialNum
                            self.rw15693Signel.emit(3, RemortIPort, "主動(dòng)讀取15693卡號成功!")
                        elif (data[9] == eval('0x02')):  # 主動(dòng)讀取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 = ''  # 設(shè)備硬件序列號
                            for num in range(len(data) - 8, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:主動(dòng)讀取15693卡號及塊數(shù)據(jù),設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + Card16H + ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum
                            self.rw15693Signel.emit(2,RemortIPort, blockdata)
                            self.rw15693Signel.emit(3, RemortIPort, "主動(dòng)讀取15693卡號及塊數(shù)據(jù)成功!")
                        elif (data[9] == eval('0x03')):  # 電腦發(fā)指令讀卡成功,僅返回卡號
                            SerialNum = ''  # 設(shè)備硬件序列號
                            for num in range(20, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:接收指令讀取15693卡號,設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + 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 = ''  # 設(shè)備硬件序列號
                            for num in range(len(data) - 8, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:接收指令讀取15693卡號及塊數(shù)據(jù),設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + 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 = ''  # 設(shè)備硬件序列號
                            for num in range(20, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:電腦發(fā)指令重新讀卡號成功,設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + Card16H+ ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum
                            self.rw15693Signel.emit(3, RemortIPort, "接收指令重新讀卡號成功成功!")
                        elif (data[9] == eval('0x06')):  # 電腦發(fā)指令寫卡成功
                            DSFID = '%02X' % (data[11])
                            SerialNum = ''  # 設(shè)備硬件序列號
                            for num in range(20, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:電腦發(fā)指令寫卡成功,設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + Card16H+ ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum
                            self.rw15693Signel.emit(3, RemortIPort, "電腦發(fā)指令寫卡成功!")
                        elif (data[9] == eval('0x07')):  # 卡離開感應(yīng)區(qū)
                            DSFID = '%02X' % (data[11])
                            SerialNum = ''  # 設(shè)備硬件序列號
                            for num in range(20, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:卡離開感應(yīng)區(qū),設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + Card16H+ ',DSFID:' + DSFID + ",硬件序列號:" + SerialNum
                            self.rw15693Signel.emit(3, RemortIPort, "卡離開感應(yīng)區(qū)!")
                        elif (data[9] == eval('0x6A')):  # 電腦發(fā)指令寫卡失敗,返回卡號
                            DSFID = '%02X' % (data[11])
                            SerialNum = ''  # 設(shè)備硬件序列號
                            for num in range(20, len(data)):
                                SerialNum = SerialNum + '%02X' % (data[num])
                            dispinf = '數(shù)據(jù)解析:電腦發(fā)指令寫卡失敗,設(shè)備IP:' + DEvIp + ',機(jī)號:' + DevNo + ",數(shù)據(jù)包號:" + FrameNo + ",16進(jìn)制卡號:" + 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("設(shè)置設(shè)備WIFI熱點(diǎn)參數(shù)的指令已傳送到設(shè)備,30秒后可以獲取到設(shè)備WIFI連接狀態(tài)!")
 
            elif (data[0] == eval('0x1D')):
                if (RemortIPort == self.netparawin.lineEdit_RemoIPort.text()):
                    self.netparawin.plainTextEdit_Disp.setPlainText('1D設(shè)置參數(shù)指令成功執(zhí)行!')
 
        elif (dispcode == 1):
            self.ListAddItem(RemortIPort)
 
    def table_doubleClick(self):
        currentrow = self.tableWidget.currentRow()  # 獲取當(dāng)前鼠標(biāo)點(diǎn)擊了第幾行
        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()  # 獲取當(dāng)前鼠標(biāo)點(diǎn)擊了第幾行
        if (currentrow >= 0):
            self.netparawin = NetParaSetwindow()  # 實(shí)例化 網(wǎng)絡(luò)參數(shù)設(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)  # 將設(shè)置網(wǎng)絡(luò)參數(shù)窗口的 信號 綁定給 主窗口的 槽函數(shù)
        else:
            QMessageBox.critical(self, "警告", "     請選擇一臺在線設(shè)備!", 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)  # 清空表格內(nèi)現(xiàn)有記錄
        self.textEdit_7.setPlainText('255.255.255.255:39169')
        sdata = bytes([eval('0xA6')])  # 搜索在線設(shè)備的指令碼
        s.sendto(sdata, ('255.255.255.255', Bindprot))  # 發(fā)送搜索同網(wǎng)段內(nèi)所有在線設(shè)備的廣播指令
        self.ListAddItem(
            get_time() + 'SendTo:' + ("255.255.255.255:" + str(Bindprot) + "            ")[0:22] + " Data:A6")
 
        sdata = bytes([eval('0xA8')])  # 查詢設(shè)備版本型號、固件更新日期
        s.sendto(sdata, ('255.255.255.255', Bindprot))  # 發(fā)送搜索同網(wǎng)段內(nèi)所有在線設(shè)備的廣播指令
        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ù)包立即回應(yīng),否則讀卡器會(huì)繼續(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 來回應(yīng)
        s.sendto(senddata, (Remoip, Reprot))
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 需要驅(qū)動(dòng)設(shè)備的 IP、端口
        FieldsList = remortiport.split(':')
        Remoip = FieldsList[0]
        Reprot = int(FieldsList[1])
        comb = bytes([eval('0xA8')])  # A8是指令碼
        s.sendto(comb, (Remoip, Reprot))  # 發(fā)送A8指令查詢設(shè)備版本型號
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
 
        dispinf = self.textEdit.toPlainText() + '                                    '  # 加空格是為了全屏顯示
        DispStr = dispinf[0:34]
        disb = bytes(DispStr, encoding='gbk')  # 將要顯示的文字轉(zhuǎn)bytes
 
        comb = bytes([eval('0x5A')])  # 5A是指令碼
        comb = comb + bytes.fromhex(HexStr)  # 2字節(jié)機(jī)號
        comb = comb + bytes([self.CBbeep.currentIndex()])  # 1字節(jié)蜂鳴代碼
        comb = comb + bytes([self.spinBox.value()])  # 1字節(jié)顯示時(shí)長
        sdata = comb + disb  # 34字節(jié)顯示文字
 
        s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送5A指令驅(qū)動(dòng)讀卡器顯示文字+蜂鳴響聲
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
        DelayTime = self.spinBox_2.value()
        DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256)  # 2字節(jié)繼電器延時(shí)
        switch = 'E%d' % (self.CBSwitch.currentIndex())  # 所選的繼電器
 
        sdata = bytes([eval('0x78')])  # 78是指令碼
        sdata = sdata + bytes.fromhex(HexStr)  # 2字節(jié)機(jī)號
        sdata = sdata + bytes.fromhex(switch)  # 1字節(jié)繼電器代號
        sdata = sdata + bytes.fromhex(DelHexStr)  # 2字節(jié)延長時(shí)間
        s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送78指令驅(qū)動(dòng)讀卡器關(guān)閉已開啟的繼電器
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
        DelayTime = self.spinBox_2.value()
        DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256)  # 2字節(jié)繼電器延時(shí)
        switch = 'F%d' % (self.CBSwitch.currentIndex())  # 所選的繼電器
 
        sdata = bytes([eval('0x78')])  # 78是指令碼
        sdata = sdata + bytes.fromhex(HexStr)  # 2字節(jié)機(jī)號
        sdata = sdata + bytes.fromhex(switch)  # 1字節(jié)繼電器代號
        sdata = sdata + bytes.fromhex(DelHexStr)  # 2字節(jié)延長時(shí)間
        s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送78指令驅(qū)動(dòng)讀卡器開啟繼電器
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
 
        DelayTime = self.spinBox_2.value()
        DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256)  # 2字節(jié)繼電器延時(shí)
 
        voice = self.spinBox_3.value()  # 語音大小,最大聲音值16
        if (voice > 16):
            voice = 16
 
        DispStr = self.textEdit.toPlainText() + '                                    '  # 加空格是為了全屏顯示
        disb = bytes(DispStr, encoding='gbk')  # 將要顯示的文字轉(zhuǎn)bytes
 
        SpkStr = '[v' + str(
            voice) + ']' + self.textEdit_2.toPlainText()  # 要播報(bào)的TTS語音,[v10]表示音量,取值0-16,可放置字符串的任意地方,一次最多126個(gè)字節(jié)
        Spkb = bytes(SpkStr, encoding='gbk')  # 將要播報(bào)的TTS語音轉(zhuǎn)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é)機(jī)號
        comb = comb + bytes([self.CBbeep.currentIndex()])  # 1字節(jié)蜂鳴代碼
        comb = comb + bytes.fromhex(switch)  # 1字節(jié)繼電器代碼
        comb = comb + bytes.fromhex(DelHexStr)  # 2字節(jié)繼電器延時(shí)
        comb = comb + bytes([self.spinBox.value()])  # 1字節(jié)顯示時(shí)長
        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指令驅(qū)動(dòng)讀卡器顯示文字+蜂鳴響聲+開關(guān)繼電器+播報(bào)TTS語音
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
 
        DelayTime = self.spinBox_2.value()
        DelHexStr = '%02X%02X' % (DelayTime % 256, DelayTime // 256)  # 2字節(jié)延時(shí)
 
        DispStr = self.textEdit.toPlainText() + '                                    '  # 加空格是為了全屏顯示
        disb = bytes(DispStr, encoding='gbk')  # 將要顯示的文字轉(zhuǎn)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é)機(jī)號
        comb = comb + bytes([self.CBbeep.currentIndex()])  # 1字節(jié)蜂鳴代碼
        comb = comb + bytes.fromhex(switch)  # 1字節(jié)繼電器代碼
        comb = comb + bytes.fromhex(DelHexStr)  # 2字節(jié)繼電器延時(shí)
        comb = comb + bytes([self.spinBox.value()])  # 1字節(jié)顯示時(shí)長
        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指令驅(qū)動(dòng)讀卡器顯示文字+蜂鳴響聲+開關(guān)繼電器+播報(bào)固定組合語音
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 卡片認(rèn)證密碼
        if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6):
            self.ListAddItem("卡密碼輸入錯(cuò)誤!")
            self.textEdit_4.setFocus()
            return
 
        cardstr = self.textEdit_3.toPlainText().strip()
        if (is_valid_hex(cardstr) == False or len(bytes.fromhex(cardstr)) != 4):  # 16進(jìn)制卡號
            self.ListAddItem("卡號輸入錯(cuò)誤!")
            self.textEdit_3.setFocus()
            return
 
        self.textEdit_5.setPlainText('')
        global LastBuf
        LastBuf = bytes(9)
 
        remortiport = self.textEdit_7.toPlainText().strip()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
        sector = self.CBPage.currentIndex()  # 讀寫扇區(qū)號
        auth = self.CBauth.currentIndex()  # 密碼認(rèn)證方式
 
        sdata = bytes([eval('0x3B')])  # 3B是指令碼
        sdata = sdata + bytes.fromhex(HexStr)  # 2字節(jié)機(jī)號
        sdata = sdata + bytes([1])  # 1字節(jié)扇區(qū)個(gè)數(shù)
        sdata = sdata + bytes.fromhex(cardstr)  # 4字節(jié)16進(jìn)制卡號 00000000 表示可操作任意卡
        sdata = sdata + bytes([sector])  # 1字節(jié)扇區(qū)號
        sdata = sdata + bytes([auth])  # 1字節(jié)密碼認(rèn)證方式
        sdata = sdata + bytes.fromhex(keystr)  # 6字節(jié)密碼
 
        s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送3B指令驅(qū)動(dòng)讀寫器讀卡
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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()  # 卡片認(rèn)證密碼
        if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6):
            self.ListAddItem("卡密碼輸入錯(cuò)誤!")
            self.textEdit_4.setFocus()
            return
 
        cardstr = self.textEdit_3.toPlainText().strip()
        if (is_valid_hex(cardstr) == False or len(bytes.fromhex(cardstr)) != 4):  # 16進(jìn)制卡號
            self.ListAddItem("卡號輸入錯(cuò)誤!")
            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ù)輸入錯(cuò)誤,請輸入48個(gè)16進(jìn)制寫卡數(shù)據(jù)!")
            self.textEdit_5.setFocus()
            return
 
        remortiport = self.textEdit_7.toPlainText().strip()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
        sector = self.CBPage.currentIndex()  # 讀寫扇區(qū)號
        auth = self.CBauth.currentIndex()  # 密碼認(rèn)證方式
 
        sdata = bytes([eval('0x3D')])  # 3D是指令碼
        sdata = sdata + bytes.fromhex(HexStr)  # 2字節(jié)機(jī)號
        sdata = sdata + bytes([1])  # 1字節(jié)扇區(qū)個(gè)數(shù)
        sdata = sdata + bytes.fromhex(cardstr)  # 4字節(jié)16進(jìn)制卡號 00000000 表示可操作任意卡
        sdata = sdata + bytes([sector])  # 1字節(jié)扇區(qū)號
        sdata = sdata + bytes([auth])  # 1字節(jié)密碼認(rèn)證方式
        sdata = sdata + bytes.fromhex(keystr)  # 6字節(jié)卡密碼
        sdata = sdata + bytes.fromhex(Writestr)  # 48字節(jié)寫卡數(shù)據(jù)
        sdata = sdata + bytes.fromhex("55AA6699")  # 4字節(jié)防錯(cuò)
 
        s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送3D指令驅(qū)動(dòng)讀寫器寫卡
 
        SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
        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í)行修改卡密碼及控制位的操作嗎?如確定修改請務(wù)必記住卡的新密碼,否則卡片將報(bào)廢!",
                                   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("卡新密鑰輸入錯(cuò)誤!")
                self.textEdit_6.setFocus()
                return
 
            keystr = self.textEdit_4.toPlainText().strip()  # 卡片認(rèn)證密碼
            if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6):
                self.ListAddItem("卡密碼輸入錯(cuò)誤!")
                self.textEdit_4.setFocus()
                return
 
            cardstr = self.textEdit_3.toPlainText().strip()
            if (is_valid_hex(cardstr) == False or len(bytes.fromhex(cardstr)) != 4):  # 16進(jìn)制卡號
                self.ListAddItem("卡號輸入錯(cuò)誤!")
                self.textEdit_3.setFocus()
                return
 
            remortiport = self.textEdit_7.toPlainText().strip()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
            sector = self.CBPage.currentIndex()  # 讀寫扇區(qū)號
            auth = self.CBauth.currentIndex()  # 密碼認(rèn)證方式
            auth = auth + self.ChangeKey.currentIndex() * 2  # 密碼修改方式
 
            sdata = bytes([eval('0x3A')])  # 3A是指令碼
            sdata = sdata + bytes.fromhex(HexStr)  # 2字節(jié)機(jī)號
            sdata = sdata + bytes([1])  # 1字節(jié)扇區(qū)個(gè)數(shù)
            sdata = sdata + bytes.fromhex(cardstr)  # 4字節(jié)16進(jìn)制卡號 00000000 表示可操作任意卡
            sdata = sdata + bytes([sector])  # 1字節(jié)扇區(qū)號
            sdata = sdata + bytes([auth])  # 1字節(jié)密碼認(rèn)證方式
            sdata = sdata + bytes.fromhex(keystr)  # 6字節(jié)卡密碼
            sdata = sdata + bytes.fromhex(newkey)  # 16字節(jié)新密碼
            sdata = sdata + bytes.fromhex("55AA6699")  # 4字節(jié)防錯(cuò)
 
            s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送3A指令驅(qū)動(dòng)讀寫器更改卡片密鑰
            SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[
                                               0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
            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()  # 需要驅(qū)動(dòng)設(shè)備的 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é)機(jī)號
        sector = self.CBPage.currentIndex()  # 讀寫扇區(qū)號
        auth = self.CBauth.currentIndex()  # 密碼認(rèn)證方式
 
        res = QMessageBox.question(None, "提示", "     按 Yes 鍵把讀寫器設(shè)為主動(dòng)讀取第 " + str(
            self.CBPage.currentIndex()) + " 扇區(qū)數(shù)據(jù),按 No 鍵將讀寫器設(shè)為只讀卡號不讀扇區(qū)數(shù)據(jù)。", QMessageBox.Yes | QMessageBox.No)
        if (QMessageBox.No == res):
            sdata = bytes([eval('0x4B')])  # 4B是指令碼
            sdata = sdata + bytes.fromhex(HexStr)  # 2字節(jié)機(jī)號
            sdata = sdata + bytes([0])  # 讀0個(gè)扇區(qū)數(shù)據(jù)
            sdata = sdata + bytes.fromhex("55AA6699")  # 4字節(jié)確認(rèn)碼
            s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送4B指令將讀寫器設(shè)為只讀卡號
            SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[
                                               0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
            for num in range(0, len(sdata)):
                SendInf = SendInf + '%02X ' % (sdata[num])
            self.ListAddItem(SendInf)
        else:
            keystr = self.textEdit_4.toPlainText().strip()  # 卡片認(rèn)證密碼
            if (is_valid_hex(keystr) == False or len(bytes.fromhex(keystr)) != 6):
                self.ListAddItem("卡密碼輸入錯(cuò)誤!")
                self.textEdit_4.setFocus()
                return
 
            sdata = bytes([eval('0x4B')])  # 4B是指令碼
            sdata = sdata + bytes.fromhex("0000")  # 2字節(jié)機(jī)號
            sdata = sdata + bytes([1])  # 主動(dòng)讀取的扇區(qū)數(shù),如果要開通幾個(gè)扇區(qū)這里就填幾
            if (auth == 0):
                sector = sector + 128
            sdata = sdata + bytes([sector]) + bytes.fromhex(
                keystr)  # 1字節(jié)的扇區(qū)號及密碼認(rèn)證類型 + 6字節(jié)卡認(rèn)證密碼 ,如果讀多個(gè)扇區(qū)也按此結(jié)構(gòu)加入,可以開通全部的16個(gè)扇區(qū)
            sdata = sdata + bytes.fromhex("55AA6699")  # 4字節(jié)確認(rèn)碼
            s.sendto(sdata, (Remoip, Reprot))  # 發(fā)送4B指令將讀寫器設(shè)為主動(dòng)讀取扇區(qū)
            SendInf = get_time() + 'SendTo:' + (remortiport + '                      ')[
                                               0:22] + ' Data:'  # 為方便開發(fā),打印出詳細(xì)的指令
            for num in range(0, len(sdata)):
                SendInf = SendInf + '%02X ' % (sdata[num])
            self.ListAddItem(SendInf)
 
    def PBWifiSet_click(self):
        self.wifiset = WifiSetWindow()  # 實(shí)例化 wifi熱點(diǎn)參數(shù)設(shè)置窗口
 
        screen = QDesktopWidget().screenGeometry()
        size = self.wifiset.geometry()
        # 獲得窗口相關(guān)坐標(biāo)
        newLeft = (screen.width() - size.width()) // 2
        newTop = (screen.height() - size.height()) // 2
        # 移動(dòng)窗口使其居中
        self.wifiset.move(newLeft, newTop)
 
        self.wifiset.setWindowFlags(  # 使能最小化按鈕 .WindowMinimizeButtonHint
            QtCore.Qt.WindowCloseButtonHint |  # 使能關(guān)閉按鈕
            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熱點(diǎn)參數(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()
        # 獲得窗口相關(guān)坐標(biāo)
        newLeft = (screen.width() - size.width()) // 2
        newTop = (screen.height() - size.height()) // 2
        # 移動(dòng)窗口使其居中
        self.ISO15693RW.move(newLeft, newTop)
 
        self.ISO15693RW.setWindowFlags(  # 使能最小化按鈕 .WindowMinimizeButtonHint
            QtCore.Qt.WindowCloseButtonHint |  # 使能關(guān)閉按鈕
            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é)設(shè)備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):  # 不能返回本機(jī)MAC
    # 初始化 用正則表達(dá)式're'編譯出匹配MAC地址的正則表達(dá)式對象
    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地址對應(yīng)的MAC地址 返回一個(gè)類文件對象 可以通過 read 方法獲取命令的輸出結(jié)果
    arp_file = os.popen('arp -a {}'.format(ip_address))
    # 使用正則表達(dá)式'self.patt_mac'在輸出結(jié)果中查找符合 MAC 地址格式的字符串 并返回找到的第一個(gè)匹配項(xiàng) 即 IP 對應(yīng)的 MAC 地址
    mac_addr = patt_mac.search(arp_file.read())
 
    # 根據(jù)正則表達(dá)式對象匹配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的默認(rèn)網(wǎng)關(guān)
 
 
# =======================================================================================================================
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()
 
    screen = QDesktopWidget().screenGeometry()
    size = mainWindow.geometry()
    # 獲得窗口相關(guān)坐標(biāo)
    newLeft = (screen.width() - size.width()) // 2
    newTop = (screen.height() - size.height()) // 2
    # 移動(dòng)窗口使其居中
    mainWindow.move(newLeft, newTop)
 
    mainWindow.setWindowTitle("RFID網(wǎng)絡(luò)讀卡器測試工具 Ver:2024.04.01")
    mainWindow.show()
 
    mainWindow.TEPort.setPlainText("39169")
 
    mainWindow.textEdit.setPlainText("歡迎您使用我們的網(wǎng)絡(luò)讀卡器!")
    mainWindow.textEdit_2.setPlainText("歡迎您使用我們的網(wǎng)絡(luò)讀卡器!")
    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)      #守護(hù)線程--也稱“服務(wù)線程”,在沒有用戶線程可服務(wù)時(shí)會(huì)自動(dòng)離開,確保關(guān)閉窗口后關(guān)閉處理線程
            # 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通過縮進(jìn)來表示代碼塊,不可以隨意更改每行前面的空白,否則程序會(huì)運(yùn)行錯(cuò)誤!??!如果縮進(jìn)不一致,就會(huì)報(bào)錯(cuò): IndentationError
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#python -m pdb xxx.py 調(diào)試程度 n命令單步執(zhí)行,s命令單步執(zhí)行 會(huì)進(jìn)入函數(shù)內(nèi)部  b xx ,c
#import pdb    pdb.set_trace() 設(shè)斷點(diǎn)
 
import sys
import os
import socket
import time
import pdb
 
#接收到數(shù)據(jù)包后向設(shè)備發(fā)確認(rèn)信息,否則設(shè)備會(huì)重發(fā)三次--------------------------------------------
def DisableSendAge(data,addr):
   #105是指令碼+接收到的信息前8個(gè)字節(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')  #將要顯示的文字轉(zhuǎn)bytes
   
   comb=bytes([eval('0x5A'),0,0,2,30])    #5A是指令碼+2字節(jié)機(jī)號+1字節(jié)蜂鳴代碼+1字節(jié)顯示時(shí)長
   
   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')  #將要顯示的文字轉(zhuǎn)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é)機(jī)號+1字節(jié)蜂鳴代碼+1字節(jié)繼電器代碼+2字節(jié)繼電器延時(shí)+1字節(jié)顯示時(shí)長+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')  #將要顯示的文字轉(zhuǎn)bytes
   
   SpkStr='[v10]感謝您的使用,再見!'       #要播報(bào)的TTS語音,[v10]表示音量,取值0-16,可放置字符串的任意地方,一次最多126個(gè)字節(jié)
   Spkb=bytes(SpkStr, encoding='gbk')   #將要播報(bào)的TTS語音轉(zhuǎn)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é)機(jī)號+1字節(jié)蜂鳴代碼+1字節(jié)繼電器代碼+2字節(jié)繼電器延時(shí)+1字節(jié)顯示時(shí)長+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ū)內(nèi)數(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é)機(jī)號(data[5],data[6]存有機(jī)號)+1字節(jié)扇區(qū)個(gè)數(shù)+4個(gè)字節(jié)卡號(data存有卡號)+1字節(jié)扇區(qū)號+1字節(jié)密碼認(rèn)證方式    
   
   keys=bytes([eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF'),eval('0xFF')])        #6個(gè)字節(jié)的卡認(rèn)證密碼
   
   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個(gè)字節(jié)的機(jī)號,如都取0表示任意機(jī)號
   sdata.append(data[6])           #data[56]保存了上傳時(shí)設(shè)備的機(jī)號
   
   sdata.append(1)                 #操作扇區(qū)的個(gè)數(shù)
   
   sdata.append(data[8])           #4個(gè)字節(jié)的卡號,data[891011]保存了已讀取的卡號
   sdata.append(data[9])           #如果這4個(gè)字節(jié)全部取0表示任意卡
   sdata.append(data[10])
   sdata.append(data[11])
   
   sdata.append(8)                 #扇區(qū)號
   sdata.append(0)                 #取值0表示以A密碼認(rèn)證,取值1表示以B密碼認(rèn)證
   
   sdata.append(eval('0xFF'))      #6個(gè)字節(jié)的卡片認(rèn)證密碼
   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個(gè)字節(jié)的寫卡信息
       sdata.append(data[14+num])  #data[14]保存了已讀取的卡扇區(qū)信息,這里表示將已讀取的數(shù)據(jù)再次寫入,如要寫新的數(shù)據(jù)將數(shù)據(jù)寫入這段緩沖
   
   sdata.append(eval('0x55'))      #4個(gè)字節(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")
   
#獲取電腦時(shí)鐘---------------------------------------------------------------------------
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])             #搜索在線設(shè)備的指令碼
s.sendto(sdata,('255.255.255.255',Bindprot))   #發(fā)送搜索同網(wǎng)段內(nèi)所有在線設(shè)備的廣播指令
message = 'SendData To 255.255.255.255:39169  a6'
print(message+"n")
 
LastBuf=bytes([0,0,0,0,0,0,0,0,0])             #保存最后接收到的信息,用于比較是否重復(fù)接收的信息
 
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)    #接收到重復(fù)上傳的信息,不用解析處理
            print('n')
        else:
            LastBuf=data[0:9]             #將接收到的信息保存,用于下次接收數(shù)據(jù)時(shí)比對
            
            if(data[0]==eval('0xF2')):    #接收到設(shè)備開機(jī)、搜索在線設(shè)備的返回信息,對信息解析
                print('指令碼 :%02x  設(shè)備開機(jī) 或 響應(yīng)服務(wù)器的搜索' % (data[0]))           
                print('設(shè)備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('機(jī)  號 :%d' % (data[11]+data[12]*256))
                print('網(wǎng)  關(guān) :%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(num39):
                    SerialNum=''
                    for num in range(39,len(data)):
                        SerialNum=SerialNum+'%02x' % (data[num])  
                    print('設(shè)備唯一序號:'+ SerialNum)   
                                           
                print('n') 
                
            elif(data[0]==eval('0xF3')):  #接收到設(shè)備的心跳數(shù)據(jù)包,設(shè)備心跳間隔可根據(jù)協(xié)議自行設(shè)置
                print('指令碼 :%02x 設(shè)備心跳包' % (data[0]))
                print('設(shè)備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4]))             
                print('機(jī)  號 :%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('隨機(jī)動(dòng)態(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('設(shè)備序列號:'+ SerialNum+'n')       
                
            elif(data[0]==eval('0xD1')):  #接收到讀取ID卡信息的數(shù)據(jù)包,對信息解析
                print('指令碼 :%02x 接收到ID卡刷卡' % (data[0]))           
                print('設(shè)備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4]))             
                print('機(jī)  號 :%d' % (data[5]+data[6]*256))
                print('包序號 :%d' % (data[7]+data[8]*256))
                print('16進(jìn)制卡號:%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進(jìn)制卡號:'+CardnoStr)
                SerialNum=''
                for num in range(14,len(data)):
                    SerialNum=SerialNum+'%02x' % (data[num])
                print('設(shè)備序列號:'+ SerialNum+'n')
                
                DisableSendAge(data, addr)    #向設(shè)備發(fā)送確認(rèn)包,否則相同的信息設(shè)備會(huì)重復(fù)發(fā)送三次
                
                #在這里加入業(yè)務(wù)對數(shù)據(jù)庫的查、增、刪、改操作
                #將業(yè)務(wù)處理結(jié)果發(fā)送到設(shè)備
                
                DispStr='卡號:'+CardnoStr+'  '+get_time()+'                              '#滿屏顯示,補(bǔ)足后面空格
                
                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('設(shè)備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4]))             
                print('機(jī)  號 :%d' % (data[5]+data[6]*256))
                print('包序號 :%d' % (data[7]+data[8]*256))
                print('16進(jìn)制卡號:%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進(jìn)制卡號:'+CardnoStr)
                SerialNum=''
                for num in range(14,len(data)):
                    SerialNum=SerialNum+'%02x' % (data[num])
                print('設(shè)備序列號:'+ SerialNum+'n')
                
                DisableSendAge(data, addr)             #向設(shè)備發(fā)送確認(rèn)包,否則相同的信息設(shè)備會(huì)重復(fù)發(fā)送三次
                
                #在這里加入業(yè)務(wù)對數(shù)據(jù)庫的查、增、刪、改操作
                #將業(yè)務(wù)處理結(jié)果發(fā)送到設(shè)備
                
                DispStr='卡號:'+CardnoStr+'  '+get_time()+'                              '#滿屏顯示,補(bǔ)足后面空格
                
                #SendDispBeep(DispStr,addr)            #向讀卡器發(fā)送顯示及蜂鳴響聲  
                #SendDispSpk(DispStr,addr)             #向讀卡器發(fā)送顯示+繼電器+固定組合語音       
                SendDispTTS(DispStr,addr)              #向讀卡器發(fā)送顯示+繼電器+TTS語音
                
                ReadCardInf(data,addr)                 #如果設(shè)備是讀寫器,可以繼續(xù) 發(fā)送讀取指定扇區(qū)信息的指令
 
            elif(data[0]==eval('0xC3')):               #全扇區(qū)讀寫器收到讀卡扇區(qū)內(nèi)的數(shù)據(jù)(刷卡時(shí)主動(dòng)讀取并上傳)
                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ù),一個(gè)數(shù)據(jù)包最多傳4個(gè)扇區(qū)的數(shù)據(jù),如果讀寫器設(shè)備讀寫扇區(qū)數(shù)大于4,數(shù)據(jù)要分2個(gè)包上傳,扇區(qū)數(shù)大于8要分3個(gè)包,大與12要分4個(gè)包上傳
                    print('接收到的信息為IC卡扇區(qū)內(nèi)數(shù)據(jù)')
                    print('指令碼 :%02x ' % (data[0]))
                    print('設(shè)備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4]))
                    print('機(jī)  號 :%d' % (data[5]+data[6]*256))
                    print('包序號 :%d' % (data[7]+data[8]*256))
                    print('16進(jìn)制卡號:%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進(jìn)制卡號:'+CardnoStr)
                                        
                    m=data[9]*48
                    CardInfStr=''
                    for num in range(0,m):
                        CardInfStr=CardInfStr+'%02x ' % (CardNuff[num])                                       
                    print('卡片內(nèi)數(shù)據(jù):'+ CardInfStr)
                    
                    #在這里加入業(yè)務(wù)對數(shù)據(jù)庫的查、增、刪、改操作
                    
                    CardNuff=bytearray()                #已接收完,清空接收緩沖
                    
                print('n')    
 
            elif(data[0]==eval('0xC5')):               #指定區(qū)號、密碼讀卡返回信息
                print('接收到的信息為讀取IC卡扇區(qū)內(nèi)數(shù)據(jù)')
                print('指令碼 :%02x ' % (data[0]))
                print('設(shè)備IP :%d.%d.%d.%d' % (data[1],data[2],data[3],data[4]))
                print('機(jī)  號 :%d' % (data[5]+data[6]*256))
                print('16進(jìn)制卡號:%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('卡片內(nèi)數(shù)據(jù):'+ CardInfStr+'n')
                    
                    WriteCard(data,addr)                 #如果寫卡,可以繼續(xù) 發(fā)送寫信息到指定扇區(qū)的指令
                else:
                    if(data[13]==12):
                        print('卡密碼認(rèn)證失敗n')
                    else:
                        print('讀卡失敗,錯(cuò)誤代碼:%02x ' % (data[13])+'n')
                        
            elif(data[0]==eval('0xCD')):               #響應(yīng)寫卡、更改卡密碼后的返回信息
                print('指令碼 :%02x ' % (data[0]))
                print('設(shè)備IP :%d.%d.%d.%d' % (data[2],data[3],data[4],data[5]))
                print('機(jī)  號 :%d' % (data[6]+data[7]*256))
                print('16進(jìn)制卡號:%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('更改卡密碼失敗,錯(cuò)誤代碼:%02x ' % (data[14]))
                else:
                    if(data[1]==0x3D):
                        if(data[14]==0x00):
                            print('寫卡成功!')
                        else:
                            print('寫卡失敗,錯(cuò)誤代碼:%02x ' % (data[14]))
                            
                print('n')
                
    else:
        print('n')

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 讀卡器
    +關(guān)注

    關(guān)注

    2

    文章

    420

    瀏覽量

    39672
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4813

    瀏覽量

    85311
收藏 人收藏

    評論

    相關(guān)推薦

    液顯ID讀卡器C#小程序開發(fā)

    液顯WIFI無線讀卡器ID-10F用C#語音開發(fā)HTTP協(xié)議讀卡程序。讀卡器圖片如下:?
    的頭像 發(fā)表于 01-10 15:31 ?151次閱讀
    液顯<b class='flag-5'>ID</b><b class='flag-5'>讀卡器</b>C#小<b class='flag-5'>程序</b><b class='flag-5'>開發(fā)</b>

    ID卡網(wǎng)絡(luò)讀卡器C#小程序開發(fā)

    (85.6x54x0.80±0.04mm)、異型卡等不同類型。按照應(yīng)用場景,它通常包含個(gè)人的身份信息,如姓名、照片、身份證號碼等,常見的包括身份證、員工工作證、學(xué)生證,以及用于考勤、門禁、一卡通等系統(tǒng)的卡片。 二、工作原理 ID卡的工作過程如下: ID卡閱讀
    的頭像 發(fā)表于 12-31 11:30 ?201次閱讀
    <b class='flag-5'>ID</b>卡網(wǎng)絡(luò)<b class='flag-5'>讀卡器</b>C#小<b class='flag-5'>程序</b><b class='flag-5'>開發(fā)</b>

    ID讀卡器TCP協(xié)議QT小程序開發(fā)

    ID卡網(wǎng)絡(luò)讀卡器TCP協(xié)議QT小程序開發(fā)。 TCP(傳輸控制協(xié)議,Transmission Control Protocol)是互聯(lián)網(wǎng)中最核心、最基本的協(xié)議之一。以下是對TCP協(xié)議的詳
    的頭像 發(fā)表于 12-31 10:19 ?254次閱讀
    <b class='flag-5'>ID</b><b class='flag-5'>讀卡器</b>TCP協(xié)議QT小<b class='flag-5'>程序</b><b class='flag-5'>開發(fā)</b>

    開疆智能Modbus轉(zhuǎn)Profinet網(wǎng)關(guān)連接Modbus讀卡器YW-630MA配置案例

    簡介: Modbus讀卡器YW-630MA是基于RS485總線,遵循Modbus RTU協(xié)議的一款I(lǐng)C卡讀卡器.。這款讀卡器使為PLC而設(shè)計(jì)和研發(fā)的新一代讀寫,可以直接連接PLC,但
    的頭像 發(fā)表于 12-23 09:41 ?219次閱讀
    開疆智能Modbus轉(zhuǎn)Profinet網(wǎng)關(guān)連接Modbus<b class='flag-5'>讀卡器</b>YW-630MA配置案例

    充電樁非接觸式讀卡器 FSV-MD5422-01

    1、簡介 FSV-MD5422-01?產(chǎn)品是一款基于?13.56MHZ?頻率射頻技術(shù)上開發(fā)出來的非接觸式讀卡器模塊,?產(chǎn)品基于?TTL、RS232?串口兩種設(shè)計(jì)接口,通信協(xié)議簡單實(shí)用,方便產(chǎn)品
    的頭像 發(fā)表于 10-29 10:27 ?341次閱讀
    充電樁非接觸式<b class='flag-5'>讀卡器</b> FSV-MD5422-01

    TRF7970A NFC讀卡器天線多路復(fù)用

    電子發(fā)燒友網(wǎng)站提供《TRF7970A NFC讀卡器天線多路復(fù)用.pdf》資料免費(fèi)下載
    發(fā)表于 10-26 11:15 ?1次下載
    TRF7970A NFC<b class='flag-5'>讀卡器</b>天線多路復(fù)用

    AGV讀卡器在AGV自動(dòng)搬運(yùn)小車上應(yīng)用方案

    AGV小車上的AGV讀卡器通過讀取地面軌道的RFID電子標(biāo)簽信息,做出相應(yīng)的動(dòng)作(如改變速度、選擇軌道、定位和停車等)。在AGV小車經(jīng)過站點(diǎn)A處時(shí),AGV讀卡器讀取A處的電子標(biāo)簽ID號,AGV小車
    的頭像 發(fā)表于 10-12 17:33 ?363次閱讀
    AGV<b class='flag-5'>讀卡器</b>在AGV自動(dòng)搬運(yùn)小車上應(yīng)用方案

    二代身份證識別儀身份證閱讀讀卡器

    掃描儀 工地實(shí)名制讀卡器 二代證閱讀 ID/IC讀卡器 NFC讀卡模塊 多合一身份證讀卡模塊
    發(fā)表于 09-07 15:09

    讀卡板內(nèi)置設(shè)備中的應(yīng)用場景

    讀卡器
    jf_08279201
    發(fā)布于 :2024年09月03日 16:08:19

    X-CUBE-NFC4能否用于其他品牌的NFC讀卡器?

    X-CUBE-NFC4能否用于其他品牌的NFC讀卡器,或者通過移植來驅(qū)動(dòng)其他品牌的NFC讀卡器
    發(fā)表于 05-22 06:27

    網(wǎng)絡(luò)讀卡器_產(chǎn)品手冊

    電子發(fā)燒友網(wǎng)站提供《網(wǎng)絡(luò)讀卡器_產(chǎn)品手冊.pdf》資料免費(fèi)下載
    發(fā)表于 05-19 09:33 ?0次下載

    IO-Link RFID讀卡器系統(tǒng)方案設(shè)計(jì)與挑戰(zhàn)

    如圖2這個(gè)IO-Link RFID傳感的方案,使用了L6364和STM32G0通用電路來支持IO-Link的協(xié)議轉(zhuǎn)換,使用ST25R3916來作為NFC的讀卡器芯片。
    發(fā)表于 04-02 10:56 ?766次閱讀
    IO-Link RFID<b class='flag-5'>讀卡器</b>系統(tǒng)方案設(shè)計(jì)與挑戰(zhàn)

    請問使用ST25R3916方案的NFC讀卡器能否通過EMVCo 3.0 L1認(rèn)證測試?

    1.目前使用st25r3916方案的讀卡器是否能順利通過EMV3.0 L1測試? 2.有沒有可以通過認(rèn)證測試的套件并提供技術(shù)支持,或者提供樣品定制開發(fā)驗(yàn)證服務(wù)? 3.其他型號推薦?
    發(fā)表于 03-21 07:08