本示例使用的设备:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.1d292c1bk8Qc9r&ft=t&id=17021194999
一、服务端绑定IP开启UDP端口接收消费机提交的请求
import sys
import os
import socket
import time
import datetime
IpList=[]
if sys.platform == 'linux' or sys.platform=='mac': # linux、mac系统获取电脑所有网卡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获取电脑所有网卡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[0] #如果电脑有多个网卡IP,可以选择绑定不同的IP
Bindprot=39192
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s.bind((Bindip, Bindprot))
print('\n系统绑定IP:'+Bindip+':%d'% (Bindprot)+'\n')
while True:
data, addr = s.recvfrom(BUFSIZE)
message = 'Received from %s:%s \n' % (addr, data)
print(message)
GetInf = str(data, encoding="gbk")
FieldsList = GetInf.split(',') #分割接收到的数据后解析、处理、返回指令 */
二、接收到消费机上传的刷卡数据
if(FieldsList[0]=='102'): #接收到消费机的刷卡信息
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferCardidStr = FieldsList[5] #卡号
if(len(FieldsList)>6): #2018年以后的设备有唯一硬件序号
DevBufferSerialNumStr=FieldsList[6]
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
#可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
#用009指令 将业务处理结果发送到设备
#设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制
SendInfStr="009,"+ DevBufferMachinStr + ",卡号:" + DevBufferCardidStr + "\\nn姓名:张三丰\\n余额:888.88\\n状态:卡可正常使用\\n,20,1,0"
SendInfToIp(SendInfStr,addr)
三、接收到消费机上传的现金支付请求
if(FieldsList[0]=='103'): #接收到 输入消费金额后刷卡、消费机定额消费、消费机计次消费 的上传信息
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferCardidStr = FieldsList[5] #卡号
DevBufferUseMoneryStr= FieldsList[6] #消费金额
DevBufferUseTimeStr= FieldsList[7] #消费时间
if(len(FieldsList)>8): #2018年以后的设备有唯一硬件序号
DevBufferSerialNumStr=FieldsList[8]
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
#可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
#用006指令返回本次消费失败
#用008指令返回本次消费成功
#设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制
#SendInfStr="006," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + "姓名:张三丰 \\n余额:168.88 \\n状态:此卡已挂失 \\n ,20,0,6"
SendInfStr="008," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + DevBufferUseMoneryStr + "," + "姓名:张三丰 {123.45}\\n,20,0,1"
SendInfToIp(SendInfStr,addr)
四、接收到消费机上传的计次消费请求
if(FieldsList[0]=='104'): #接收到 计次消费模式下,终端刷卡后设备向电脑发送此信息
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferCardidStr = FieldsList[5] #卡号
DevBufferUseTimeStr= FieldsList[6] #消费时间
if(len(FieldsList)>7): #2018年以后的设备有唯一硬件序号
DevBufferSerialNumStr=FieldsList[7]
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
#可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
#用006指令返回本次消费失败
#用008指令返回本次消费成功
#设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制
SendInfStr="006," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + "姓名:张三丰 \\n余额:168.88 \\n状态:此卡已挂失\\n ,20,0,6"
#SendInfStr="008," + DevBufferMachinStr + "," + DevBufferCardidStr + ",0.00," + "姓名:张三丰 {123.45}\\n,20,0,1"
SendInfToIp(SendInfStr,addr)
五、接收到消费机上传的记账消费记录
if(FieldsList[0]=='105'): #接收到脱网时 白名单卡 记账消费记录
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferCardidStr = FieldsList[5] #卡号
DevBufferUseMoneryStr= FieldsList[6] #消费金额
DevBufferUseTimeStr= FieldsList[7] #消费时间
DevBufferStaryStr= FieldsList[8] #消费方式 0扣费 1计次
DevBufferRecordAddStr= FieldsList[9] #记录地址标识
DevBufferAllNoStr= FieldsList[10] #总计录数
if(len(FieldsList)>11): #2018年以后的设备有唯一硬件序号
DevBufferSerialNumStr=FieldsList[11]
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
if(isVaildDate(DevBufferUseTimeStr)==0): #判断消费时间是否正确
DevBufferUseTimeStr="9999-99-99 99:99:99" #如果消费时间不正确,需更为 9999-99-99 99:99:99 才能将此条非法记录删除
#时间正确说明是条有效记录,可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
#清除设备内当前这条已上传的记录,驱动设备继续上传剩下的记录
SendInfStr="011," + DevBufferMachinStr + "," + DevBufferCardidStr + "," + DevBufferUseMoneryStr + "," + DevBufferUseTimeStr + "," + DevBufferRecordAddStr
SendInfToIp(SendInfStr,addr)
六、接收到消费机上传的按键信息
if(FieldsList[0]=='106'): #接收到设备的按键信息
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferUseTimeStr= FieldsList[5] #按键信息
if(len(FieldsList)>6): #2018年以后的设备有唯一硬件序号
DevBufferSerialNumStr=FieldsList[6]
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
#可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
七、接收到消费机上传的扫码支付请求
if(FieldsList[0]=='128'): #接收到消费金额、扫码信息
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferCommandStr = FieldsList[5] #指令号
DevBufferUseMoneryStr= FieldsList[6] #消费金额
DevBufferUseTimeStr= FieldsList[7] #消费时间
DevBufferQrcodeInfStr=""
if(len(FieldsList)>9): #防止二维码信息中有分隔符,
for num in range(9,len(FieldsList)-1):
DevBufferQrcodeInfStr=DevBufferQrcodeInfStr+FieldsList[num]
DevBufferSerialNumStr=FieldsList[len(FieldsList)-1] #2018年以后的设备有唯一硬件序号
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
#可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
#用006指令返回本次消费失败
#用008指令返回本次消费成功
#设备如接收到了本次发送的信息,会以109指令回复,在正式项目中要根据此特性做重发机制
#SendInfStr="006," + DevBufferMachinStr + "," + DevBufferCommandStr + "," + "姓名:张三丰 \\n余额:168.88 \\n状态:此卡已挂失 \\n ,20,0,6"
SendInfStr="008," + DevBufferMachinStr + "," + DevBufferCommandStr + "," + DevBufferUseMoneryStr + ",正在进行扫码支付..{请不要按动键盘! \\n},5,0,1"
SendInfToIp(SendInfStr,addr)
八、接收到消费机开机信号
if(FieldsList[0]=='101'): #接收到设备的开机信号
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferDatetimeStr = FieldsList[5] #设备日期时间
if(len(FieldsList)>6): #2018年以后的设备有唯一硬件序号
DevBufferSerialNumStr=FieldsList[6]
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
GetDT=DevBufferDatetimeStr[0:16]
SysDT= get_time()
if (GetDT!=SysDT): #设备时钟与系统不符,更新设备时间
SendInfStr="003," + DevBufferMachinStr +"," + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
SendInfToIp(SendInfStr,addr)
门禁控制板介绍:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.52de2c1bIqEgQP&ft=t&id=599136536796
九、接收到门禁控制板提交的刷卡开门请求
if(FieldsList[0]=='150'): #接收到实时考勤门禁机的刷卡信息
DevRecFramesStr = FieldsList[1] #包序列号
DevBufferIpAddrStr = FieldsList[2] #终端IP
DevBufferRemoteAddrStr = FieldsList[3] #远程电脑指机IP
DevBufferMachinStr = FieldsList[4] #机号
DevBufferCardidStr = FieldsList[5] #卡号
DevBufferReaderStr= FieldsList[6] #读头号
DevBufferDoorNoStr= FieldsList[7] #门或继电器号
DevBufferDelayStr= FieldsList[8] #门磁未关秒数,0表示已关
DevBufferPasswPropStr= FieldsList[9] #密码属性(0密码无效,1刷卡后按密码,2补签密码,3开门密码,4防迫胁密码)
DevBufferPassWStr= FieldsList[10] #密码(最多8位数字)
DevBufferUseTimeStr= FieldsList[11] #刷卡时间
if(len(FieldsList)>12): #2018年以后的设备有唯一硬件序号
DevBufferSerialNumStr=FieldsList[12]
SendInfStr="001,"+DevRecFramesStr #确定接收到信息,否则设备会连续发送三次
SendInfToIp(SendInfStr,addr)
#可以在这里加上业务对数据库的查、增、删操作,要分析是否重复接收的信息
#用050指令返回开门成功
#用051指令返回开门失败,正式系统开发时要有重发机制
#SendInfStr="051," + DevBufferMachinStr + "," + DevBufferCardidStr + ",卡号:" + DevBufferCardidStr + "\\n姓名:张三丰 \\n状态:无效卡\\n,20,1,3"
SendInfStr="050," + DevBufferMachinStr + "," + DevBufferCardidStr + ",卡号:" + DevBufferCardidStr + "\\n姓名:张三丰 \\n状态:欢迎关临\\n,20,1,0," + DevBufferReaderStr + "," + DevBufferDoorNoStr + ",5,20"
SendInfToIp(SendInfStr,addr)
十、服务端回应消费机的指令
def SendInfToIp(SendInfStr,addr):
sdata=bytes(SendInfStr, encoding='gbk') #将要发送的信息转为bytes
s.sendto(sdata,addr)
message = 'SendData To %s:%s' % (addr, sdata)
print(message+"\n")