整合python目录的代码

This commit is contained in:
ranchuan
2023-09-15 10:53:44 +08:00
parent 58b751d519
commit 8a14e74500
25 changed files with 4746 additions and 9 deletions

5
.gitignore vendored
View File

@@ -3,4 +3,7 @@ dist/
file/
__pycache__/
*.pid
*.spec
*.spec
download/
*.csv
quest_info.txt

View File

@@ -35,4 +35,9 @@
2023.7.28
添加升级方案按钮
.axf 结尾的为主板m4程序
改为20通道
改为20通道
2023.9.12
升级软件添加从服务器下载程序文件的功能
升级文件名不能有空格
2023.9.15
整合python目录的代码

42
coder/coder_check.py Normal file
View File

@@ -0,0 +1,42 @@
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import coder_params as cpars
class check_dlog(QObject):
def __init__(self,father:QDialog,slave_num:int,txt:str) -> None:
QObject.__init__(self)
self.slave_num=slave_num
self.x_size=100*self.slave_num
if(self.x_size>1500):
self.x_size=1500
self.w=QDialog(father)
self.w.resize(self.x_size+100,200)
self.w.setWindowTitle(txt)
self.w.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self.code_list=QTableWidget(self.w)
self.code_list.setObjectName(u"code_list")
self.code_list.setGeometry(QRect(50, 50, self.x_size, 100))
self.code_list.setColumnCount(self.slave_num)
self.code_list.insertRow(0)
channel_list=[]
for i in range(self.slave_num):
channel_list.append("通道{d}".format(d=i+1))
self.code_list.setHorizontalHeaderLabels(channel_list)
self.code_list.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
def ack_list_init(self,ack_list:list):
length=len(ack_list)
for i in range(length):
self.code_list.setItem(0,i,QTableWidgetItem(cpars.code_errinfo(int(ack_list[i]))))
if(ack_list[i]!="0"):
self.code_list.item(0,i).setBackground(Qt.GlobalColor.red)
def show(self):
self.w.show()
def close(self):
self.w.destroy(True,True)

471
coder/coder_main.py Normal file
View File

@@ -0,0 +1,471 @@
import os
import sys
import datetime
from datetime import datetime, timedelta
import prottcp as prot
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import threading
import time
import serial
import serial.tools.list_ports
import coder_params as cpars
import coder_check as chk
# 批检仪赋码上位机
STR_RED="\033[1;31m"
STR_BLUE="\033[1;34m"
STR_END="\033[0m"
# 获取北京时间
def get_date():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y%m%d")
return utc_time
# 获取北京时间
def get_time():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y-%m-%d %H:%M:%S")
return utc_time
class coder(QObject):
def __init__(self) -> None:
QObject.__init__(self)
self.app = QApplication(sys.argv)
self.code_id=0
self.run_times=0
self.slave_num=10
self.code_list_lock=[]
self.save_file="code_list.csv"
self.ser_is_open = False
self.ser=prot.protu()
self.widget = QWidget()
self.widget.resize(1500, 800)
self.widget.setWindowTitle("批检仪赋码工具")
self.com_but_init()
self.combsp_init()
self.com_init()
self.code_list_init()
self.dot_fat_init()
self.channel_init()
self.sig_list_init()
self.moterup_init()
self.infotext_init()
self.widget.destroyed.connect(self.quit)
def quit(self):
self.close_serial()
print("app exit.")
# 程序退出
sys.exit(1)
# 初始化
def init(self,detonator_fat:bytearray,chip_fat:bytearray,signature_code:bytearray,slave_num:int):
self.set_params(detonator_fat,chip_fat,signature_code,slave_num)
date=get_date().encode('utf-8')
self.date=date[-5:]
self.year=date[:4]
self.save_file=date.decode("utf-8")+".csv"
if(os.path.exists(self.save_file)):
with open(self.save_file) as f:
lines=f.readlines()
length=len(lines)
self.code_id=length
for i in lines:
self.code_list_add(i)
print("code id start as:",self.code_id)
self.code_list_to_bottom()
# 设置雷管厂,芯片厂,特征码
def set_params(self,detonator_fat:bytearray,chip_fat:bytearray,signature_code:bytearray,slave_num:int):
self.detonator_fat=detonator_fat
self.chip_fat=chip_fat
self.slave_num=slave_num
self.signature_code=signature_code
info="已更换编码参数,现在的编码参数为:"+"雷管厂:"+detonator_fat.decode("utf-8")+",芯片厂:"+chip_fat.decode("utf-8")
info+=",特征码:"+signature_code.decode("utf-8")+",通道数:"+str(slave_num)
self.set_infotext(info)
# 选择波特率
def combsp_init(self):
self.combsp = QComboBox(self.widget)
self.combsp.setObjectName(u"combsp")
self.combsp.setGeometry(QRect(465, 10, 85, 25))
self.combsp.setEditable(True)
self.combsp.currentIndexChanged.connect(self.com_changed)
for i in cpars.uartbsp_list():
self.combsp.addItem(i)
self.combsp_label = QLabel(self.widget)
self.combsp_label.setObjectName(u"label")
self.combsp_label.setGeometry(QRect(405, 16, 72, 15))
self.combsp_label.setText("波特率:")
# 选择雷管厂家
def dot_fat_init(self):
self.dot_fat = QComboBox(self.widget)
self.dot_fat.setObjectName(u"dot_fat")
self.dot_fat.setGeometry(QRect(645, 10, 400, 25))
self.dot_fat.setEditable(False)
self.dot_fat.currentIndexChanged.connect(self.params_changed)
for i in cpars.dot_fat_list():
self.dot_fat.addItem(i)
self.dot_fat_label = QLabel(self.widget)
self.dot_fat_label.setObjectName(u"label")
self.dot_fat_label.setGeometry(QRect(570, 16, 72, 15))
self.dot_fat_label.setText("雷管厂家:")
# com口
def com_init(self):
self.com = QComboBox(self.widget)
self.com.setObjectName(u"com")
self.com.setGeometry(QRect(95, 10, 300, 25))
self.com.setEditable(True)
self.com.currentIndexChanged.connect(self.com_changed)
# self.com.addItem("utcp:7777")
ports_list = list(serial.tools.list_ports.comports())
for comport in ports_list:
# print(comport.name,comport.description)
self.com.addItem(comport.name+":"+comport.description)
self.com_label = QLabel(self.widget)
self.com_label.setObjectName(u"label")
self.com_label.setGeometry(QRect(30, 16, 72, 15))
self.com_label.setText("COM口:")
# 特征码
def sig_list_init(self):
self.sig_list = QComboBox(self.widget)
self.sig_list.setObjectName(u"sig_list")
self.sig_list.setGeometry(QRect(1285, 10, 85, 25))
self.sig_list.setEditable(False)
self.sig_list.currentIndexChanged.connect(self.params_changed)
for i in cpars.code_signature_code_list():
self.sig_list.addItem(i)
self.sig_list_label = QLabel(self.widget)
self.sig_list_label.setObjectName(u"label")
self.sig_list_label.setGeometry(QRect(1220, 16, 72, 15))
self.sig_list_label.setText("特征码:")
# 通道数
def channel_init(self):
self.channel = QComboBox(self.widget)
self.channel.setObjectName(u"channel")
self.channel.setGeometry(QRect(1125, 10, 85, 25))
self.channel.setEditable(True)
self.channel.currentIndexChanged.connect(self.params_changed)
for i in cpars.code_channel_list():
self.channel.addItem(i)
self.channel_label = QLabel(self.widget)
self.channel_label.setObjectName(u"label")
self.channel_label.setGeometry(QRect(1055, 16, 72, 15))
self.channel_label.setText("通道数:")
# 提示信息
def infotext_init(self):
self.infotext=QLabel(self.widget)
self.infotext.setGeometry(QRect(30, 765, 1200, 15))
self.infotext.setText("请打开串口以开始赋码")
def set_infotext(self,text:str):
try:
self.infotext.setText(text)
except Exception as e:
pass
# 初始化打开端口按钮
def com_but_init(self):
self.com_but = QPushButton(self.widget)
self.com_but.setObjectName(u"com_but")
self.com_but.setGeometry(QRect(1250, 50, 93, 28))
self.com_but.setText("打开端口")
self.com_but.clicked.connect(self.com_but_clicked)
# 电机上升
def moterup_init(self):
self.moterup=QPushButton(self.widget)
self.moterup.setObjectName(u"moteerup")
self.moterup.setGeometry(QRect(1250, 90, 93, 28))
self.moterup.setText("电机上升")
self.moterup.clicked.connect(self.cmd_moter_up)
# 注码结果列表
def code_list_init(self):
self.code_list=QTableWidget(self.widget)
self.code_list.setObjectName(u"code_list")
self.code_list.setGeometry(QRect(30, 50, 1200, 700))
self.code_list.setColumnCount(6)
self.code_list.setHorizontalHeaderLabels(list(["创建时间","通道号","注码结果","管壳码","UID","密码"]))
self.code_list.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
# 添加数据
def code_list_add(self,code_line:str):
code_strs=code_line.split(",")
errcode=int(code_strs[2])
code_strs[2]=cpars.code_errinfo(errcode)
RowCont=self.code_list.rowCount()
self.code_list.insertRow(RowCont)
for i in range(6):
self.code_list.setItem(RowCont,i,QTableWidgetItem(code_strs[i]))
if(errcode!=0):
self.code_list.item(RowCont,i).setBackground(Qt.GlobalColor.red)
# 滚动到底部
def code_list_to_bottom(self):
self.code_list.scrollToBottom()
def com_but_clicked(self):
print("com but clicked")
if(self.ser_is_open==False):
item=self.com.itemText(self.com.currentIndex())
bsp=self.combsp.itemText(self.combsp.currentIndex())
com=item.split(":")[0]
if(com!="utcp"):
item=com+":"+bsp
self.open_serial(item)
else:
self.close_serial()
def set_port_state(self,state:bool):
self.ser_is_open=state
if(state==True):
self.com_but.setText("关闭端口")
else:
self.com_but.setText("打开端口")
# 无效化编码参数设置项
def params_active(self,power:bool):
self.dot_fat.setEnabled(power)
self.sig_list.setEnabled(power)
self.channel.setEnabled(power)
# 更换管壳码生成参数
def params_changed(self,index:int):
try:
dot_fat=self.dot_fat.itemText(self.dot_fat.currentIndex()).split(":")[0].encode("utf-8")
chip_fat=b"AD"
sig_code=self.sig_list.itemText(self.sig_list.currentIndex()).encode("utf-8")
slave_num=self.channel.itemText(self.channel.currentIndex())
self.set_params(dot_fat,chip_fat,sig_code,int(slave_num))
except Exception as e:
pass
# 更换端口时关闭之前的
def com_changed(self,index:int):
print("com changed")
self.set_infotext("串口参数有变动,将自动关闭打开的串口")
self.close_serial()
# 打开通信接口
def open_serial(self,com:str):
if(self.ser.init(com)==True):
self.ser.recv_signal.connect(self.recv_slot)
self.ser.start_recv()
self.set_port_state(True)
print("open serial.")
self.set_infotext("打开串口成功,开始监听请求赋码指令")
else:
self.set_infotext("打开串口失败,是否有其他程序占用了串口?")
print("open serial failed.")
def close_serial(self):
try:
self.ser.recv_signal.disconnect(self.recv_slot)
except Exception as a:
pass
self.ser.close()
self.set_infotext("串口已关闭")
self.set_port_state(False)
def recv_slot(self,cmd:int,data:bytearray,err:str):
print("recv:","cmd:",hex(cmd),"data:",data.hex(' '))
if(self.run_times<=0):
print("run times end.")
self.set_infotext("运行次数已结束,不再响应检测赋码指令")
return
self.run_times-=1
ack=False
if(cmd==0x81):
self.set_infotext("已接收检测结果")
ack=self.decode_check(data)
if(ack==True):
self.cmd_code(self.slave_num)
else:
print("check failed.")
self.set_infotext("检测出现异常,未进行赋码,请排查异常后重试")
self.cmd_moter_up()
self.params_active(True)
elif(cmd==0x82):
self.set_infotext("已接收赋码结果")
ack=self.decode_code(data)
if(ack!=True):
print("code failed.")
self.set_infotext("赋码出现异常,本次赋码结果被丢弃,请排查异常后重试")
self.cmd_moter_up()
self.params_active(True)
elif(cmd==0x37):
print("key press.")
self.params_active(False)
self.set_infotext("已接收请求检测命令")
self.cmd_moter_down()
time.sleep(2)
self.cmd_check(self.slave_num)
def run(self,times:int):
self.run_times=times*4
self.widget.show()
ret=self.app.exec()
self.close_serial()
sys.exit(ret)
# 生成管壳码
def calc_shell_code(self,id:int):
shell=bytearray()
shell+=self.detonator_fat
shell+=self.date
shell+=self.signature_code
shell+="{d:05d}".format(d=id).encode("utf-8")
return shell
# 生成n通道的注码数据
def creat_code_data(self,id:int,num:int):
d=bytearray()
d.append(num&0xff)
d+=self.year
for i in range(num):
d.append(i&0xff)
d+=self.calc_shell_code(id+i)
return d
# 发送检测命令
def cmd_check(self,num:int):
d=bytearray()
d.append(num&0xff)
d.append(0)
self.ser.send(1,d)
print("check start.")
# 电机上升
def cmd_moter_up(self):
d=bytearray()
d.append(0x02)
try:
self.ser.send(0x40,d)
except Exception as e:
self.set_infotext("发送命令失败,是否没有打开串口?")
print("moter up.")
# 电机下降
def cmd_moter_down(self):
d=bytearray()
d.append(0x03)
self.ser.send(0x40,d)
print("moter down.")
# 发送赋码指令
def cmd_code(self,num:int):
self.ser.send(2,self.creat_code_data(self.code_id,num))
print("code start.")
# 解析检测结果
def decode_check(self,data:bytearray):
num=data[0]
ack=True
acks_list=[]
for i in range(num):
ack_i=data[6*i+3]
str_start=""
if(ack_i!=0):
ack=False
str_start=STR_RED
print(str_start+"addr:",int(data[6*i+2]),"ack:",ack_i,STR_END)
acks_list.append(str(ack_i))
try:
self.ch_dlog.close()
self.co_dlog.close()
except Exception as e:
pass
if(ack!=True):
self.ch_dlog=chk.check_dlog(self.widget,self.slave_num)
self.ch_dlog.ack_list_init(acks_list)
self.ch_dlog.show()
return ack
# 解析注码结果
def decode_code(self,data:bytearray):
num=data[0]
ack=True
code_list=[]
# 生成注码结果数据
for i in range(num):
ack_i=data[39*i+2]
str_start=""
d=data[39*i+3:39*i+3+38]
shell_code=d[:13].decode("utf-8")
uid_code=d[13:13+16].decode("utf-8")
psw_code=d[13+16:13+16+8].decode("utf-8")
code_list.append(((i+1),ack_i,shell_code,uid_code,psw_code))
# 统计错误信息
length=len(code_list)
if(len(self.code_list_lock)==0):
# 第一次失败,保存失败数据
self.code_list_lock=code_list
else:
# 不是第一次失败,比对失败数据,把成功过的统计出来
if (len(self.code_list_lock)>length):
self.code_list_lock=self.code_list_lock[:length]
for i in range(length):
# 长度不足的地方填充为本次的结果
if(i>=len(self.code_list_lock)):
self.code_list_lock.append(code_list[i])
if(self.code_list_lock[i][0]==code_list[i][0]):
if(code_list[i][1]==0):
self.code_list_lock[i]=code_list[i]
# 校验注码结果
acks_list=[]
for i in self.code_list_lock:
str_start=""
ack_i=i[1]
if(ack_i!=0):
ack=False
str_start=STR_RED
print(str_start+"addr:",i[0],"ack:",ack_i,STR_END)
print("\t","shell_code:",i[2])
print("\t","uid_code:",i[3])
print("\t","psw_code:",i[4])
acks_list.append(str(ack_i))
if(ack==True):
s=""
time=get_time()
for i in self.code_list_lock:
s=time+","+str(i[0])+','+str(i[1])+','+i[2]+','+i[3]+','+i[4]
self.code_list_add(s)
with open(self.save_file,"+a") as f:
f.write(s+'\n')
self.code_list_to_bottom()
print("save to file:",self.save_file)
# 全部成功,清除错误记录
self.code_list_lock.clear()
self.code_id+=self.slave_num
try:
self.co_dlog.close()
except Exception as e:
pass
if(ack!=True):
self.co_dlog=chk.check_dlog(self.widget,self.slave_num,"注码结果查看")
self.co_dlog.ack_list_init(acks_list)
self.co_dlog.show()
return ack
if __name__ == "__main__":
c=coder()
c.init(b'00',b'AD',b'A',10)
c.run(5000)

121
coder/coder_params.py Normal file
View File

@@ -0,0 +1,121 @@
# 雷管厂家列表
detonator_fat_list="""00 测试用工厂代号
01 北京京煤化工有限公司
04 河北卫星化工股份有限公司
07 山西焦煤集团化工有限责任公司汾矿分公司
08 山西金恒化工集团股份有限公司
09 山西壶化集团股份有限公司
10 内蒙古生力资源集团红旗化工有限公司
12 新时代民爆(辽宁)股份有限公司
14 葫芦岛凌河化工集团有限责任公司
15 辽宁华丰民用化工发展有限公司
18 长春吉阳工业有限公司
19 黑龙江青化民爆器材有限公司
20 黑龙江盛安民用爆破器材有限责任公司鹤岗分公司
21 徐州雷鸣民爆器材有限公司
22 南京理工科技化工有限责任公司
24 浙江物产光华民爆器材有限公司
29 福建海峡科化股份有限公司烽林分公司
30 福建省民爆化工股份有限公司永春分公司
34 江西新余国泰特种化工有限责任公司
36 山东圣世达化工有限责任公司
37 山东泰山民爆器材有限公司
38 前进民爆股份有限公司
44 湖北卫东化工股份有限公司
48 湖南神斧集团向红机械化工有限责任公司
49 湘南爆破器材有限责任公司
52 广东宏大韶化民爆有限公司
53 广西金建华民用爆破器材有限公司
56 四川省宜宾威力化工有限责任公司
57 雅化集团绵阳实业有限公司
58 重庆顺安天力达爆破器材有限公司
59 贵州盘江民爆有限公司
60 贵州久联民爆器材发展股份有限公司九八四四生产分公司
61 云南燃一有限责任公司
64 西安庆华民用爆破器材股份有限公司
65 甘肃久联民爆器材有限公司白银雪松分公司
68 新疆雪峰民用爆破器材有限责任公司"""
def dot_fat_list():
str_lines=detonator_fat_list.split("\n")
fat_list=[]
for line in str_lines:
s=line.split("\t")
fat_list.append(s[0]+":"+s[1])
return fat_list
# 波特率列表
def uartbsp_list():
ulist=["115200","57600","9600"]
return ulist
# 根据注码异常代码获取描述
code_errinfo_list=[
"0:成功",
"1:检测器异常",
"2:电容异常",
"3:接触异常",
"4:桥丝异常",
"5:芯片异常",
"6:未找到相关任务",
"7:过流",
"8:短路",
"193:电压设置失败",
"194:三码验证失败",
"195:UID写入失败",
"196:密码写入失败",
"197:获取UID失败",
"198:UID比对失败",
"199:锁存失败",
"200:等待接入超时",
"201:已存在其他数据"
]
def code_errinfo(errcode:int):
for i in code_errinfo_list:
s=i.split(":")
if(int(s[0])==errcode):
return s[1]
return "未定义的错误码"
# 通道数
def code_channel_list():
ulist=["10","20"]
return ulist
# 特征号
def code_signature_code_list():
code_str="ACDEFGHIJKLMNOPQRSTUVWXYZabdefghijklmnpqrty0123456789"
sig_list=[]
for i in code_str:
sig_list.append(i)
return sig_list
if __name__ == "__main__":
fats=dot_fat_list()
for line in fats:
print(line)

126
coder/coder_test.py Normal file
View File

@@ -0,0 +1,126 @@
import serial
import serial.tools.list_ports
import threading
import time
import socket
# 把tcp封装为串口
class utcp:
is_open=False
def __init__(self,port:int)->None:
self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ser.bind(("",port))
self.ser.settimeout(10)
self.ser.listen(128)
print("wait for mcu connect.")
self.client,self.client_addr=self.ser.accept()
print("client:",self.client_addr)
self.is_open=True
def read(self,len:int):
return self.client.recv(len)
def write(self,data:bytearray):
return self.client.send(data)
def close(self):
self.client.close()
self.ser.close()
self.is_open=False
class port:
def __init__(self) -> None:
pass
def open(self,name:str,bsp:int):
if(name!="utcp"):
self.ser = serial.Serial(port=name, baudrate=bsp,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,timeout=None)
else:
self.ser=utcp(9527)
def start_recv(self):
self.thread_ = threading.Thread(target=self.recv, args=())
self.thread_.start()
def recv(self,num:int):
d=bytearray()
try:
while(num>len(d)):
d+=self.ser.read(num-len(d))
except Exception as a:
print("port closed")
return 0
print("recv code:",d.hex(" "))
def send(self,data:bytearray):
self.ser.write(data)
# 测试上位机
def ecode_test(self,times:int):
print("检测赋码系统耗时测试:")
tick=0
while(tick<times):
tick+=1
print("当前={d1},总共={d2}".format(d1=tick,d2=times))
# 等待数据库写入
time.sleep(3)
start = time.perf_counter()
# 开始检测
self.send(bytearray([0xB0, 0x00, 0x02, 0x00, 0x60]))
# 接收指令应答
self.recv(5)
# 接收检测结果
self.recv(24)
end = time.perf_counter()
print("检测耗时:",end-start)
start2=time.perf_counter()
# 开始注码
self.send(bytearray([0xF0, 0x00, 0x02, 0xE0, 0x41, 0xB1, 0x00, 0x02, 0x00, 0xFB]))
# 接收指令应答
self.recv(5)
# 接收注码 结果
self.recv(305)
end = time.perf_counter()
print("注码耗时:",end-start2)
# 打标结束,保存数据库
self.send(bytearray([0xF0, 0x00, 0x02, 0xE2, 0x23, 0xB2, 0x00, 0x02, 0x00, 0x67]))
# 接收指令应答
self.recv(5)
end = time.perf_counter()
print("总耗时:",end-start)
# 测试注码仪
def coder_test(self,times:int):
print("赋码仪耗时测试:")
tick=0
while(tick<times):
tick+=1
start = time.perf_counter()
print("当前={d1},总共={d2}".format(d1=tick,d2=times))
# 开始检测
self.send(bytearray([0x59, 0x6D, 0x05, 0x00, 0x01, 0x66, 0x04, 0x05, 0x00, 0x2F, 0xD9]))
# 接收指令应答
self.recv(13)
# 接收检测结果
self.recv(72)
end = time.perf_counter()
print("检测耗时:",end-start)
start2=time.perf_counter()
# 开始注码
self.send(bytearray([0x59,0x6D,0x94,0x00,0x02,0xBE,0x01,0x0A,0x32,0x30,0x32,0x33,0x00,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x39,0x01,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x38,0x02,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x37,0x03,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x36,0x04,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x35,0x05,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x34,0x06,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x33,0x07,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x32,0x08,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x31,0x09,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x30,0x44,0xC1]))
# 接收指令应答
self.recv(12)
# 接收注码 结果
self.recv(401)
end = time.perf_counter()
print("注码耗时:",end-start2)
end = time.perf_counter()
print("总耗时:",end-start)
if __name__ == "__main__":
p=port()
# 检测赋码仪系统测试
# p.open("com8",115200)
# p.ecode_test(50000)
# 赋码仪设备串口测试
p.open("com5",115200)
p.coder_test(5)
# p.open("com16",115200)
# p.coder_test(1000)
# 赋码仪设备网口测试
# p.open("utcp",0)
# p.coder_test(5)

519
coder/prottcp.py Normal file
View File

@@ -0,0 +1,519 @@
import serial
import serial.tools.list_ports
import threading
import time
import json
import socket
from PyQt5.QtCore import *
def crc16(data:bytearray,offset:int,len:int):
if(len>0):
crc=0xffff
for i in range(len-offset):
crc=(crc^data[i+offset])&0xffff
for j in range(8):
if(crc&1)!=0:
crc=((crc>>1)^0xa001)&0xffff
else:
crc=(crc>>1)&0xffff
return crc&0xff,(crc>>8)&0xff
return 0,0
def crc32(data:bytearray):
temp=0
crc=0xffffffff
i=0
if(len(data)%4!=0):
return 0
while(i<len(data)):
temp=data[i]|(data[i+1]<<8)|(data[i+2]<<16)|(data[i+3]<<24)
i+=4
for j in range(32):
if((crc^temp)&0x80000000)!=0:
crc=0x04c11db7^(crc<<1)
else:
crc<<=1
temp<<=1
crc&=0xffffffff
return crc
# 把tcp封装为串口
class utcp:
is_open=False
def __init__(self,port:int)->None:
self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ser.bind(("",port))
self.ser.settimeout(10)
self.ser.listen(128)
print("wait for mcu connect.")
self.client,self.client_addr=self.ser.accept()
print("client:",self.client_addr)
self.is_open=True
def read(self,len:int):
# return self.ser.recv(len)
return self.client.recv(len)
def write(self,data:bytearray):
# return self.ser.send(data)
return self.client.send(data)
def close(self):
self.client.close()
self.ser.close()
self.is_open=False
# 生成一个任务的参数
def scheme_task_to_byte(j:json):
data=bytearray()
data.append(j["TaskID"])
data.append(j["TaskIndex"])
data.append(j["RetryCount"])
data.append(j["ErrJumpTo"])
data.append((j["ParamCount"]&0x0f)|(j["ReturnCount"]<<4))
for i in j["ParamVal"]:
data.append(i&0xff)
data.append(i>>8)
return data
# 生成任务参数序列
def scheme_tasks_to_byte(j:json):
data=bytearray()
for i in j["TaskArray"]:
data+=scheme_task_to_byte(i)
length=len(data)
if(length<(0x700-4)):
for i in range(0x700-4-length):
data.append(0xff)
return data
# 生成任务id序列
def scheme_taskids_to_byte(j:json):
t=bytearray()
t.append(j["PlanID"]&0xff)
t.append((j["PlanID"]>>8)&0xff)
t.append((j["PlanID"]>>16)&0xff)
t.append((j["PlanID"]>>24)&0xff)
for i in j["TaskArray"]:
t.append(i["TaskID"])
length=len(t)
if(length<(0x100)):
for i in range(0x100-length):
t.append(0xff)
return t
# 根据方案生成小板用的字节数据
def scheme_to_byte(j:json):
t=bytearray()
t+=scheme_taskids_to_byte(j)
t+=scheme_tasks_to_byte(j)
crc=crc32(t)
t.append(crc&0xff)
t.append((crc>>8)&0xff)
t.append((crc>>16)&0xff)
t.append((crc>>24)&0xff)
return t
# int转数组
def arr_from_int(num:int):
return bytearray([num&0xff,(num>>8)&0xff,(num>>16)&0xff,(num>>24)&0xff])
# 提取方案中的范围数据, 先max后min
def scheme_get_task_range(j:json):
t=bytearray()
t+=arr_from_int(j["TaskID"])
t+=arr_from_int(j["TaskIndex"])
t+=arr_from_int(j["ReturnCount"])
t+=arr_from_int(j["ExecuteErrCode"])
index=0
for i in j["TestStandard"]:
t+=arr_from_int(i["Max"])
t+=arr_from_int(i["Min"])
if (index<len(j["ResultErrCode"])):
t+=arr_from_int(j["ResultErrCode"][index])
else:
t+=arr_from_int(0)
index+=1
# 不足16的部分填充为16
n=16-len(j["TestStandard"])
for i in range(n):
t+=arr_from_int(65535)
t+=arr_from_int(0)
t+=arr_from_int(0)
return t
# 根据方案生成主板用的字节数据
def scheme_to_host(j:json):
t=bytearray()
t+=arr_from_int(j["PlanID"])
t+=arr_from_int(j["TimeOutM"])
t+=arr_from_int(len(j["TaskArray"]))
for i in j["TaskArray"]:
t+=scheme_get_task_range(i)
return t
# 发送文件类
class handle:
stat=0
name=""
def __init__(self) -> None:
pass
def get_rate(self):
return self.packet_now*100//self.packet_all
def get_data(self):
if(self.stat==0):
length=len(self.data)
# 1是写0是读
t=bytearray([1,length&0xff,(length>>8)&0xff,(length>>16)&0xff,(length>>24)&0xff])
t+=self.name.encode()
self.stat=1
return t
elif(self.stat==1):
packet_bytes=200
if(len(self.data)<self.sent_bytes):
packet_bytes=len(self.data)-self.sent_bytes
if(packet_bytes>0):
self.packet_now+=1
t=bytearray()
t.append(2)
t.append(self.packet_now&0xff)
t.append((self.packet_now>>8)&0xff)
t.append(self.packet_all&0xff)
t.append((self.packet_all>>8)&0xff)
t+=self.data[self.sent_bytes:self.sent_bytes+packet_bytes]
self.sent_bytes+=packet_bytes
return t
else:
print("send done.")
return bytearray()
# 设置要发送的文件
def set_file(self,name:str):
self.data=bytearray()
with open(name,"rb") as f:
self.data=f.read()
self.name=f.name.split('/')[-1]
self.stat=0
self.packet_all=(len(self.data)+199)//200
self.sent_bytes=0
self.packet_now=0
self.packet_bytes=200
# 设置要发送的方案
def set_json(self,name:str):
self.data=bytearray()
with open(name,"rb") as f:
json_obj=json.loads(f.read())
d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
d+=scheme_to_host(json_obj)
# print("len=",len(d),d.hex(","))
self.data=d
self.name=f.name.split('/')[-1]
self.stat=0
self.packet_all=(len(self.data)+199)//200
self.sent_bytes=0
self.packet_now=0
self.packet_bytes=200
class protu(QObject):
# 进度信号ip1~100
rate_signal =pyqtSignal([int])
# 结束信号ip成败描述
end_signal = pyqtSignal([bool,str])
# 接收到数据信号
recv_signal =pyqtSignal([int,bytearray,str])
hand=handle()
def __init__(self) -> None:
QObject.__init__(self)
self.cmd=0
self.cmd_no=0
self.str_err=""
self.is_big_data=False
self.num_to_recv=0
self.recv_data=bytearray()
def init(self,com:str):
s=com.split(":")
try:
if(s[0]=="utcp"):
self.ser = utcp(int(s[1]))
else:
bsp=int(s[1])
self.ser = serial.Serial(port=s[0], baudrate=bsp,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,timeout=None)
except Exception as e:
print(str(e))
return False
return True
def encode(self,data:bytearray):
t=bytearray()
length=len(data)+3
t.append(0x59)
t.append(0x6d)
t.append(length&0xff)
t.append(length>>8)
t.append(self.cmd)
t.append(self.cmd_no&0xff)
t.append(self.cmd_no>>8)
t+=data
a,b=crc16(t,2,length+4)
t.append(a)
t.append(b)
# print("encode:",t.hex(","))
return t
def decode(self,data:bytearray):
self.str_err="ok"
if(len(data)<10):
print("recv data len too less.")
self.str_err="recv data len too less."
return bytearray()
if(data[0]!=0x59 or data[1]!=0x6d or data[2]!=0x43):
# print("frame head not 0x59 0x6d.")
self.str_err="frame head not 0x59 0x6d."
return bytearray()
length=data[3]|(data[4]<<8)
if(length==65535):
# 重新设置数据长度
length=data[7]|(data[8]<<8)|(data[9]<<16)|(data[10]<<24);
self.is_big_data=True
else:
self.is_big_data=False
if(length+7!=len(data)):
print("recv data have lossed")
self.str_err="recv data have lossed"
return bytearray()
a,b=crc16(data,3,length+5)
if(a!=data[-2] or b!=data[-1]):
print("recv data check error.h_crc=%02x %02x,crc=%02x %02x",a,b,data[-2],data[-1])
self.str_err="recv data check error."
self.cmd_no=data[6]|(data[7]<<8)
self.cmd=data[5]
if(self.is_big_data==False):
return bytearray(data[8:-2])
else:
return bytearray(data[12:-2])
# 不带校验的接收函数
def recv_(self):
while(self.ser.is_open):
try:
data=self.ser.read(500)
except Exception as a:
# print("err:",str(a))
print("port closed")
return
if(len(data)>0):
t=self.decode(data)
if(self.str_err=="ok"):
self.recv_data+=t
# print("recv",t.hex(","))
# print(type(self.cmd),type(t),type(self.str_err))
self.recv_signal.emit(self.cmd,t,self.str_err)
# self.send_file_next(self.cmd,t,self.str_err)
# print("sent signal---")
else:
print(data.decode("utf-8"))
# 带帧校验的接收函数
def recv(self):
# self.recv_signal.connect(self.send_file_next)
data=bytearray()
while(self.ser.is_open):
d=bytes()
try:
d=self.ser.read(1)
except Exception as a:
# print("err:",str(a))
print("port closed")
return
data+=d
if(len(data)==3):
if(data[0]==0x59 and data[1]==0x6d and data[2]==0x43):
self.num_to_recv=5
else:
data=data[1:]
self.num_to_recv=0
elif(len(data)==5):
length=data[3]|(data[4]<<8)
if(length<65535):
self.num_to_recv+=length+2
self.is_big_data=False
else:
self.num_to_recv=12
self.is_big_data=True
elif(len(data)==12):
if(self.is_big_data==True):
length=data[8]|(data[9]<<8)|(data[10]<<16)|(data[11]<<24)
self.num_to_recv=5+length+2
if(self.num_to_recv>0 and self.num_to_recv==len(data)):
t=self.decode(data)
self.recv_data+=t
# print("recv",t.hex(","))
self.recv_signal.emit(self.cmd,t,self.str_err)
# self.send_file_next(self.cmd,t,self.str_err)
# print("sent signal---")
data.clear()
# else:
# print("len(data)={d1},num_ro_recv={d2}".format(d1=len(data),d2=self.num_to_recv))
def send(self,cmd:int,data:bytearray):
self.cmd=cmd
self.cmd_no+=1
self.ser.write(self.encode(data))
def send_str(self,txt:str):
self.ser.write(txt.encode("utf-8"))
def start_recv(self):
self.thread_ = threading.Thread(target=self.recv, args=())
self.thread_.start()
def wait(self):
self.thread_.join()
def close(self):
try:
if(self.ser.is_open):
self.ser.close()
except Exception as e:
print(str(e))
def send_file_next(self,cmd:int,data:bytearray,err:str):
print("send_file_next")
data=self.hand.get_data()
if(len(data)>0):
self.send(cmd,data)
else:
self.close()
def send_file(self,cmd:int,name:str):
self.start_recv()
self.hand.set_file(name)
# self.send_file_next(cmd,bytearray([0]),"ok")
self.recv_signal.emit(cmd,bytearray([0]),"ok")
self.wait()
# 0x30 开始检测
# 0x31 检测上报
# 0x32 读写方案
# 0x33 连接维护
# 0x34 自检数据
# 0x35 自检上报
# 0x36 升级脚本
# 0xed 主板升级
# 0xee 小板升级
# 0x40 电机矫正
# 0x41 小板电阻矫正
# 0x42 小板电阻测量
# 0x43 小板硬件版本
# with open("file/judge.lua","rb") as f:
# send_file("COM5",0x36,f.name.split('/')[-1],f.read())
# with open("file/JQ_JCXB_V54.bin","rb") as f:
# send_file("COM5",0xee,f.name.split('/')[-1],f.read())
# with open("file/checker_ye_cfg.json","rb") as f:
# json_obj=json.loads(f.read())
# d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
# d=scheme_to_host(json_obj)
# print("len=",len(d),d.hex(","))
# send_file("COM5",0x32,f.name.split('/')[-1],f.read())
def int2str(num:int):
s=str(num//100)
s=s+str(num%100//10)
s=s+str(num%10)
return s
if __name__ == "__main__":
u=protu()
# u.init("utcp:7777")
# u.send_file(0xee,"file/JQ_JCXB_V54.bin")
# u.send_file(0xed,"../Objects/checker_gen1_app_20230602.bin")
# 设置电阻 矫正值
u.cmd=0x41
data=bytearray([1,0,0x00,2,0,0x00,3,0,0x00,4,0,0x00,5,0,0x00,6,0,0x00,7,0,0x00,8,0,0x00,9,0,0x00,10,0,0x00,11,0,0x00,12,0,0x00,13,0,0x00,14,0,0x00,15,0,0x00,16,0,0x00,17,0,0x00,18,0,0x00,19,0,0x00,20,0,0x00])
# 测量电阻
# u.cmd=0x42
# data=bytearray([0])
# 设置硬件版本号
# u.cmd=0x43
# data=bytearray([1,50,0x00,2,51,0x00,3,52,0x00,4,53,0x00,5,54,0x00,6,55,0x00,7,56,0x00,8,57,0x00,9,58,0x00,10,59,0x00,11,60,0x00,12,61,0x00,13,62,0x00,14,63,0x00,15,64,0x00,16,65,0x00,17,66,0x00,18,67,0x00,19,68,0x00,20,69,0x00])
# 设置电机校正值
# u.cmd=0x40
# data=bytearray([0x01,100,0])
# data=bytearray([0x02]) # 上升
# data=bytearray([0x03]) # 下降
print(u.encode(data).hex(' '))
# with open("file/EX_Coder_Test_2023-07-6.json","rb") as f:
# json_obj=json.loads(f.read())
# d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
# d+=scheme_to_host(json_obj)
# print(int2str(20))
# s="{d:03d}".format(d=2)
# print(s)
# with open("file/7-15.json","rb") as f:
# u.cmd=0x22
# p=u.encode(f.read())
# print(p.hex(' '))
# 开始检测
# 59 6d 03 00 30 00 00 60 0f
# 结束应答
# 59 6D 03 00 31 00 00 31 CF

42
coder_2ch/coder_check.py Normal file
View File

@@ -0,0 +1,42 @@
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import coder_params as cpars
class check_dlog(QObject):
def __init__(self,father:QDialog,slave_num:int,txt:str) -> None:
QObject.__init__(self)
self.slave_num=slave_num
self.x_size=100*self.slave_num
if(self.x_size>1500):
self.x_size=1500
self.w=QDialog(father)
self.w.resize(self.x_size+100,200)
self.w.setWindowTitle(txt)
self.w.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self.code_list=QTableWidget(self.w)
self.code_list.setObjectName(u"code_list")
self.code_list.setGeometry(QRect(50, 50, self.x_size, 100))
self.code_list.setColumnCount(self.slave_num)
self.code_list.insertRow(0)
channel_list=[]
for i in range(self.slave_num):
channel_list.append("通道{d}".format(d=i+1))
self.code_list.setHorizontalHeaderLabels(channel_list)
self.code_list.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
def ack_list_init(self,ack_list:list):
length=len(ack_list)
for i in range(length):
self.code_list.setItem(0,i,QTableWidgetItem(cpars.code_errinfo(int(ack_list[i]))))
if(ack_list[i]!="0"):
self.code_list.item(0,i).setBackground(Qt.GlobalColor.red)
def show(self):
self.w.show()
def close(self):
self.w.destroy(True,True)

665
coder_2ch/coder_main.py Normal file
View File

@@ -0,0 +1,665 @@
import os
import sys
import datetime
from datetime import datetime, timedelta
import prottcp as prot
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import threading
import time
import serial
import serial.tools.list_ports
import coder_params as cpars
import coder_check as chk
# 批检仪赋码上位机
STR_RED="\033[1;31m"
STR_BLUE="\033[1;34m"
STR_END="\033[0m"
# 获取北京时间
def get_date():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y%m%d")
return utc_time
# 获取北京时间
def get_time():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y-%m-%d %H:%M:%S")
return utc_time
class coder(QObject):
def __init__(self) -> None:
QObject.__init__(self)
self.app = QApplication(sys.argv)
self.code_id=0
self.run_times=0
self.slave_num=10
self.code_list_lock=[]
self.save_file="code_list.csv"
self.ser_is_open = False
self.recv_handler=None
self.autoinc_id=False
self.autotest_is_open=0
self.ser=prot.protu()
self.widget = QWidget()
self.widget.resize(1500, 800)
self.widget.setWindowTitle("批检仪赋码工具")
self.com_but_init()
self.combsp_init()
self.com_init()
self.code_list_init()
self.dot_fat_init()
self.channel_init()
self.sig_list_init()
self.moterup_init()
self.infotext_init()
self.recv_handler_table_init()
self.device_type_init()
self.autoinc_init()
self.check_but_init()
self.posend_but_init()
self.autotest_but_init()
self.stop_but_init()
self.widget.destroyed.connect(self.quit)
def quit(self):
self.close_serial()
print("app exit.")
# 程序退出
sys.exit(1)
# 初始化
def init(self,detonator_fat:bytearray,chip_fat:bytearray,signature_code:bytearray,slave_num:int):
self.set_params(detonator_fat,chip_fat,signature_code,slave_num)
date=get_date().encode('utf-8')
self.date=date[-5:]
self.year=date[:4]
self.save_file=date.decode("utf-8")+".csv"
if(os.path.exists(self.save_file)):
with open(self.save_file) as f:
lines=f.readlines()
length=len(lines)
self.code_id=length
for i in lines:
self.code_list_add(i)
print("code id start as:",self.code_id)
self.code_list_to_bottom()
# 设置雷管厂,芯片厂,特征码
def set_params(self,detonator_fat:bytearray,chip_fat:bytearray,signature_code:bytearray,slave_num:int):
self.detonator_fat=detonator_fat
self.chip_fat=chip_fat
self.slave_num=slave_num
self.signature_code=signature_code
info="已更换编码参数,现在的编码参数为:"+"雷管厂:"+detonator_fat.decode("utf-8")+",芯片厂:"+chip_fat.decode("utf-8")
info+=",特征码:"+signature_code.decode("utf-8")+",通道数:"+str(slave_num)
self.set_infotext(info)
# 选择波特率
def combsp_init(self):
self.combsp = QComboBox(self.widget)
self.combsp.setObjectName(u"combsp")
self.combsp.setGeometry(QRect(465, 10, 85, 25))
self.combsp.setEditable(True)
self.combsp.currentIndexChanged.connect(self.com_changed)
for i in cpars.uartbsp_list():
self.combsp.addItem(i)
self.combsp_label = QLabel(self.widget)
self.combsp_label.setObjectName(u"label")
self.combsp_label.setGeometry(QRect(405, 16, 72, 15))
self.combsp_label.setText("波特率:")
# 选择雷管厂家
def dot_fat_init(self):
self.dot_fat = QComboBox(self.widget)
self.dot_fat.setObjectName(u"dot_fat")
self.dot_fat.setGeometry(QRect(645, 10, 400, 25))
self.dot_fat.setEditable(False)
self.dot_fat.currentIndexChanged.connect(self.params_changed)
for i in cpars.dot_fat_list():
self.dot_fat.addItem(i)
self.dot_fat_label = QLabel(self.widget)
self.dot_fat_label.setObjectName(u"label")
self.dot_fat_label.setGeometry(QRect(570, 16, 72, 15))
self.dot_fat_label.setText("雷管厂家:")
# com口
def com_init(self):
self.com = QComboBox(self.widget)
self.com.setObjectName(u"com")
self.com.setGeometry(QRect(95, 10, 300, 25))
self.com.setEditable(True)
self.com.currentIndexChanged.connect(self.com_changed)
# self.com.addItem("utcp:7777")
ports_list = list(serial.tools.list_ports.comports())
for comport in ports_list:
# print(comport.name,comport.description)
self.com.addItem(comport.name+":"+comport.description)
self.com_label = QLabel(self.widget)
self.com_label.setObjectName(u"label")
self.com_label.setGeometry(QRect(30, 16, 72, 15))
self.com_label.setText("COM口:")
# 特征码
def sig_list_init(self):
self.sig_list = QComboBox(self.widget)
self.sig_list.setObjectName(u"sig_list")
self.sig_list.setGeometry(QRect(1285, 10, 85, 25))
self.sig_list.setEditable(False)
self.sig_list.currentIndexChanged.connect(self.params_changed)
for i in cpars.code_signature_code_list():
self.sig_list.addItem(i)
self.sig_list_label = QLabel(self.widget)
self.sig_list_label.setObjectName(u"label")
self.sig_list_label.setGeometry(QRect(1220, 16, 72, 15))
self.sig_list_label.setText("特征码:")
# 通道数
def channel_init(self):
self.channel = QComboBox(self.widget)
self.channel.setObjectName(u"channel")
self.channel.setGeometry(QRect(1125, 10, 85, 25))
self.channel.setEditable(True)
self.channel.currentIndexChanged.connect(self.params_changed)
for i in cpars.code_channel_list():
self.channel.addItem(i)
self.channel_label = QLabel(self.widget)
self.channel_label.setObjectName(u"label")
self.channel_label.setGeometry(QRect(1055, 16, 72, 15))
self.channel_label.setText("通道数:")
# 提示信息
def infotext_init(self):
self.infotext=QLabel(self.widget)
self.infotext.setGeometry(QRect(30, 765, 1200, 15))
self.infotext.setText("请打开串口以开始赋码")
def set_infotext(self,text:str):
try:
self.infotext.setText(text)
except Exception as e:
pass
# 初始化打开端口按钮
def com_but_init(self):
self.com_but = QPushButton(self.widget)
self.com_but.setObjectName(u"com_but")
self.com_but.setGeometry(QRect(1250, 50, 93, 28))
self.com_but.setText("打开端口")
self.com_but.clicked.connect(self.com_but_clicked)
# 电机上升
def moterup_init(self):
self.moterup=QPushButton(self.widget)
self.moterup.setObjectName(u"moteerup")
self.moterup.setGeometry(QRect(1250, 90, 93, 28))
self.moterup.setText("电机上升")
self.moterup.clicked.connect(self.cmd_moter_up)
# 自动增加id号
def autoinc_init(self):
self.autoinc=QPushButton(self.widget)
self.autoinc.setObjectName(u"autoinc")
self.autoinc.setGeometry(QRect(1250, 130, 93, 28))
self.autoinc.clicked.connect(self.autoinc_clicked)
self.autoinc_clicked()
# 开始检测
def check_but_init(self):
self.check_but=QPushButton(self.widget)
self.check_but.setObjectName(u"check_but")
self.check_but.setGeometry(QRect(1250, 170, 93, 28))
self.check_but.clicked.connect(self.check_but_clicked)
self.check_but.setText("开始检测")
# 到位感应
def posend_but_init(self):
self.posend_but=QPushButton(self.widget)
self.posend_but.setObjectName(u"posend_but")
self.posend_but.setGeometry(QRect(1250, 210, 93, 28))
self.posend_but.clicked.connect(self.posend_but_clicked)
self.posend_but.setText("到位感应")
# 自动测试
def autotest_but_init(self):
self.autotest_but=QPushButton(self.widget)
self.autotest_but.setObjectName(u"autotest_but")
self.autotest_but.setGeometry(QRect(1250, 250, 93, 28))
self.autotest_but.clicked.connect(self.autotest_but_clicked)
self.autotest_but.setText("开自动测试")
# 自动测试
def stop_but_init(self):
self.stop_but=QPushButton(self.widget)
self.stop_but.setObjectName(u"stop_but")
self.stop_but.setGeometry(QRect(1250, 290, 93, 28))
self.stop_but.clicked.connect(self.stop_but_clicked)
self.stop_state=True
self.stop_but_clicked()
# 初始化设备类型选择框
def device_type_init(self):
self.device_type_list = QComboBox(self.widget)
self.device_type_list.setObjectName(u"device_type_list")
self.device_type_list.setGeometry(QRect(1370, 50, 93, 28))
self.device_type_list.setEditable(False)
self.device_type_list.currentIndexChanged.connect(self.device_type_changed)
for i in self.recv_handler_table.items():
self.device_type_list.addItem(i[0])
# self.device_type_list_label = QLabel(self.widget)
# self.device_type_list_label.setObjectName(u"label")
# self.device_type_list_label.setGeometry(QRect(1220, 16, 72, 15))
# self.device_type_list_label.setText("特征码:")
self.device_type_changed(0)
# 注码结果列表
def code_list_init(self):
self.code_list=QTableWidget(self.widget)
self.code_list.setObjectName(u"code_list")
self.code_list.setGeometry(QRect(30, 50, 1200, 700))
self.code_list.setColumnCount(6)
self.code_list.setHorizontalHeaderLabels(list(["创建时间","通道号","注码结果","管壳码","UID","密码"]))
self.code_list.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
# 添加数据
def code_list_add(self,code_line:str):
code_strs=code_line.split(",")
errcode=int(code_strs[2])
code_strs[2]=cpars.code_errinfo(errcode)
RowCont=self.code_list.rowCount()
self.code_list.insertRow(RowCont)
for i in range(6):
self.code_list.setItem(RowCont,i,QTableWidgetItem(code_strs[i]))
if(errcode!=0):
self.code_list.item(RowCont,i).setBackground(Qt.GlobalColor.red)
# 滚动到底部
def code_list_to_bottom(self):
self.code_list.scrollToBottom()
def com_but_clicked(self):
print("com but clicked")
if(self.ser_is_open==False):
item=self.com.itemText(self.com.currentIndex())
bsp=self.combsp.itemText(self.combsp.currentIndex())
com=item.split(":")[0]
if(com!="utcp"):
item=com+":"+bsp
self.open_serial(item)
else:
self.close_serial()
def set_port_state(self,state:bool):
self.ser_is_open=state
if(state==True):
self.com_but.setText("关闭端口")
else:
self.com_but.setText("打开端口")
# 修改id自增状态
def autoinc_clicked(self):
if(self.autoinc_id==True):
self.autoinc_id=False
self.autoinc.setText("打开ID自增")
self.set_infotext("已关闭ID自增")
else:
self.autoinc_id=True
self.autoinc.setText("关闭ID自增")
self.set_infotext("已打开ID自增")
def check_but_clicked(self):
print("send start check cmd.")
self.cmd_user(0x90,bytearray([2]))
def posend_but_clicked(self):
print("send in place cmd.")
self.cmd_user(0x90,bytearray([3]))
def stop_but_clicked(self):
print("send stop cmd.")
if(self.stop_state==False):
# 发送急停命令
self.cmd_user(0x90,bytearray([0]))
self.stop_but.setText("运行")
self.stop_state=True
else:
# 发送启动命令
self.cmd_user(0x90,bytearray([1]))
self.stop_but.setText("急停")
self.stop_state=False
def autotest_but_clicked(self):
if(self.autotest_is_open==0):
self.autotest_but.setText("启动中...")
self.autotest_is_open=2
self.autotest_but.setEnabled(False)
self.start_autotest()
elif(self.autotest_is_open==1):
self.autotest_but.setText("关闭中...")
self.autotest_is_open=3
self.autotest_but.setEnabled(False)
# 无效化编码参数设置项
def params_active(self,power:bool):
self.dot_fat.setEnabled(power)
self.sig_list.setEnabled(power)
self.channel.setEnabled(power)
self.device_type_list.setEnabled(power)
# 更换管壳码生成参数
def params_changed(self,index:int):
try:
dot_fat=self.dot_fat.itemText(self.dot_fat.currentIndex()).split(":")[0].encode("utf-8")
chip_fat=b"AD"
sig_code=self.sig_list.itemText(self.sig_list.currentIndex()).encode("utf-8")
slave_num=self.channel.itemText(self.channel.currentIndex())
self.set_params(dot_fat,chip_fat,sig_code,int(slave_num))
except Exception as e:
pass
# 设备类型发生了改变
def device_type_changed(self,index:int):
device_type=self.device_type_list.itemText(index)
self.recv_handler=self.recv_handler_table[device_type]
self.set_infotext("设备已切换为:"+device_type)
# 更换端口时关闭之前的
def com_changed(self,index:int):
print("com changed")
self.set_infotext("串口参数有变动,将自动关闭打开的串口")
self.close_serial()
# 打开通信接口
def open_serial(self,com:str):
if(self.ser.init(com)==True):
self.ser.recv_signal.connect(self.recv_slot)
self.ser.start_recv()
self.set_port_state(True)
print("open serial.")
self.set_infotext("打开串口成功,开始监听请求赋码指令")
else:
self.set_infotext("打开串口失败,是否有其他程序占用了串口?")
print("open serial failed.")
def close_serial(self):
try:
self.ser.recv_signal.disconnect(self.recv_slot)
except Exception as a:
pass
self.ser.close()
self.set_infotext("串口已关闭")
self.set_port_state(False)
def recv_slot(self,cmd:int,data:bytearray,err:str):
# print("recv:","cmd:",hex(cmd),"data:",data.hex(' '))
if(self.run_times<=0):
print("run times end.")
self.set_infotext("运行次数已结束,不再响应检测赋码指令")
return
self.run_times-=1
if (self.recv_handler!=None):
self.recv_handler(cmd,data,err)
# 2通道赋码设备的处理函数
def recv_deal_coder2ch(self,cmd:int,data:bytearray,err:str):
ack=False
if(cmd==0x8b):
self.params_active(False)
self.set_infotext("已接收请求赋码命令")
self.cmd_code(self.slave_num)
elif(cmd==0x82):
self.set_infotext("已接收赋码结果")
ack=self.decode_code(data)
if(ack!=True):
print("code failed.")
self.set_infotext("赋码出现异常,本次赋码结果被丢弃,请排查异常后重试")
self.params_active(True)
elif(cmd==0x8c):
s="设备信息:{d1},{d2}".format(d1=int(data[0]),d2=data[1:].decode("utf-8"))
print(s)
self.set_infotext(s)
elif(cmd==0x8a):
self.cmd_user(0x8a,bytearray([0]))
elif(cmd==0x91):
# 输入通道状态
print("input:channel({d1})={d2}".format(d1=int(data[0]),d2=int(data[1])))
elif(cmd==0x92):
# 输出通道状态
print("output:channel({d1})={d2}".format(d1=int(data[0]),d2=int(data[1])))
# 批检仪的处理函数
def recv_deal_checker(self,cmd:int,data:bytearray,err:str):
ack=False
if(cmd==0x81):
self.set_infotext("已接收检测结果")
ack=self.decode_check(data)
if(ack==True):
self.cmd_code(self.slave_num)
else:
print("check failed.")
self.set_infotext("检测出现异常,未进行赋码,请排查异常后重试")
self.cmd_moter_up()
self.params_active(True)
elif(cmd==0x82):
self.set_infotext("已接收赋码结果")
ack=self.decode_code(data)
if(ack!=True):
print("code failed.")
self.set_infotext("赋码出现异常,本次赋码结果被丢弃,请排查异常后重试")
self.cmd_moter_up()
self.params_active(True)
elif(cmd==0x37):
print("key press.")
self.params_active(False)
self.set_infotext("已接收请求检测命令")
self.cmd_moter_down()
time.sleep(2)
self.cmd_check(self.slave_num)
# 初始化处理函数列表
def recv_handler_table_init(self):
self.recv_handler_table={"批检仪":self.recv_deal_checker,
"赋码控制器":self.recv_deal_coder2ch}
def run(self,times:int):
self.run_times=times*4
self.widget.show()
ret=self.app.exec()
self.close_serial()
sys.exit(ret)
# 生成管壳码
def calc_shell_code(self,id:int):
shell=bytearray()
shell+=self.detonator_fat
shell+=self.date
shell+=self.signature_code
shell+="{d:05d}".format(d=id).encode("utf-8")
return shell
# 生成n通道的注码数据
def creat_code_data(self,id:int,num:int):
d=bytearray()
d.append(num&0xff)
d+=self.year
for i in range(num):
d.append(i&0xff)
d+=self.calc_shell_code(id+i)
return d
# 发送检测命令
def cmd_check(self,num:int):
d=bytearray()
d.append(num&0xff)
d.append(0)
self.ser.send(1,d)
print("check start.")
# 电机上升
def cmd_moter_up(self):
d=bytearray()
d.append(0x02)
try:
self.ser.send(0x40,d)
except Exception as e:
self.set_infotext("发送命令失败,是否没有打开串口?")
print("moter up.")
# 电机下降
def cmd_moter_down(self):
d=bytearray()
d.append(0x03)
self.ser.send(0x40,d)
print("moter down.")
# 发送赋码指令
def cmd_code(self,num:int):
self.ser.send(2,self.creat_code_data(self.code_id,num))
print("code start.")
# 发送任意命令
def cmd_user(self,cmd:int,data:bytearray):
try:
self.ser.send(cmd,data)
except Exception as e:
self.set_infotext("发送命令失败,是否没有打开串口?")
# 解析检测结果
def decode_check(self,data:bytearray):
num=data[0]
ack=True
acks_list=[]
for i in range(num):
ack_i=data[6*i+3]
str_start=""
if(ack_i!=0):
ack=False
str_start=STR_RED
print(str_start+"addr:",int(data[6*i+2]),"ack:",ack_i,STR_END)
acks_list.append(str(ack_i))
try:
self.ch_dlog.close()
self.co_dlog.close()
except Exception as e:
pass
if(ack!=True):
self.ch_dlog=chk.check_dlog(self.widget,self.slave_num)
self.ch_dlog.ack_list_init(acks_list)
self.ch_dlog.show()
return ack
# 解析注码结果
def decode_code(self,data:bytearray):
num=data[0]
ack=True
code_list=[]
# 生成注码结果数据
for i in range(num):
ack_i=data[39*i+2]
str_start=""
d=data[39*i+3:39*i+3+38]
shell_code=d[:13].decode("utf-8")
uid_code=d[13:13+16].decode("utf-8")
psw_code=d[13+16:13+16+8].decode("utf-8")
code_list.append(((i+1),ack_i,shell_code,uid_code,psw_code))
# 统计错误信息
length=len(code_list)
if(len(self.code_list_lock)==0):
# 第一次失败,保存失败数据
self.code_list_lock=code_list
else:
# 不是第一次失败,比对失败数据,把成功过的统计出来
if (len(self.code_list_lock)>length):
self.code_list_lock=self.code_list_lock[:length]
for i in range(length):
# 长度不足的地方填充为本次的结果
if(i>=len(self.code_list_lock)):
self.code_list_lock.append(code_list[i])
if(self.code_list_lock[i][0]==code_list[i][0]):
if(code_list[i][1]==0):
self.code_list_lock[i]=code_list[i]
else:
if(self.code_list_lock[i][1]!=0):
self.code_list_lock[i]=code_list[i]
# 校验注码结果
acks_list=[]
for i in self.code_list_lock:
str_start=""
ack_i=i[1]
if(ack_i!=0):
ack=False
str_start=STR_RED
print(str_start+"addr:",i[0],"ack:",ack_i,STR_END)
print("\t","shell_code:",i[2])
print("\t","uid_code:",i[3])
print("\t","psw_code:",i[4])
acks_list.append(str(ack_i))
if(ack==True):
s=""
time=get_time()
for i in self.code_list_lock:
s=time+","+str(i[0])+','+str(i[1])+','+i[2]+','+i[3]+','+i[4]
self.code_list_add(s)
with open(self.save_file,"+a") as f:
f.write(s+'\n')
self.code_list_to_bottom()
print("save to file:",self.save_file)
# 全部成功,清除错误记录
self.code_list_lock.clear()
if(self.autoinc_id==True):
self.code_id+=self.slave_num
try:
self.co_dlog.close()
except Exception as e:
pass
if(ack!=True):
self.co_dlog=chk.check_dlog(self.widget,self.slave_num,"注码结果查看")
self.co_dlog.ack_list_init(acks_list)
self.co_dlog.show()
return ack
def start_autotest(self):
self.thread_ = threading.Thread(target=self.autotest, args=())
self.thread_.start()
def autotest(self):
self.autotest_but.setText("关自动测试")
self.autotest_is_open=1
self.autotest_but.setEnabled(True)
while(self.autotest_is_open==1):
if(self.ser_is_open!=True):
print("ser was closed,stop autotest.")
break
self.check_but_clicked()
time.sleep(3)
self.posend_but_clicked()
time.sleep(13)
self.autotest_but.setText("开自动测试")
self.autotest_is_open=0
self.autotest_but.setEnabled(True)
if __name__ == "__main__":
c=coder()
c.init(b'00',b'AD',b'A',int(cpars.code_channel_list()[0]))
c.run(10000)

121
coder_2ch/coder_params.py Normal file
View File

@@ -0,0 +1,121 @@
# 雷管厂家列表
detonator_fat_list="""00 测试用工厂代号
01 北京京煤化工有限公司
04 河北卫星化工股份有限公司
07 山西焦煤集团化工有限责任公司汾矿分公司
08 山西金恒化工集团股份有限公司
09 山西壶化集团股份有限公司
10 内蒙古生力资源集团红旗化工有限公司
12 新时代民爆(辽宁)股份有限公司
14 葫芦岛凌河化工集团有限责任公司
15 辽宁华丰民用化工发展有限公司
18 长春吉阳工业有限公司
19 黑龙江青化民爆器材有限公司
20 黑龙江盛安民用爆破器材有限责任公司鹤岗分公司
21 徐州雷鸣民爆器材有限公司
22 南京理工科技化工有限责任公司
24 浙江物产光华民爆器材有限公司
29 福建海峡科化股份有限公司烽林分公司
30 福建省民爆化工股份有限公司永春分公司
34 江西新余国泰特种化工有限责任公司
36 山东圣世达化工有限责任公司
37 山东泰山民爆器材有限公司
38 前进民爆股份有限公司
44 湖北卫东化工股份有限公司
48 湖南神斧集团向红机械化工有限责任公司
49 湘南爆破器材有限责任公司
52 广东宏大韶化民爆有限公司
53 广西金建华民用爆破器材有限公司
56 四川省宜宾威力化工有限责任公司
57 雅化集团绵阳实业有限公司
58 重庆顺安天力达爆破器材有限公司
59 贵州盘江民爆有限公司
60 贵州久联民爆器材发展股份有限公司九八四四生产分公司
61 云南燃一有限责任公司
64 西安庆华民用爆破器材股份有限公司
65 甘肃久联民爆器材有限公司白银雪松分公司
68 新疆雪峰民用爆破器材有限责任公司"""
def dot_fat_list():
str_lines=detonator_fat_list.split("\n")
fat_list=[]
for line in str_lines:
s=line.split("\t")
fat_list.append(s[0]+":"+s[1])
return fat_list
# 波特率列表
def uartbsp_list():
ulist=["115200","57600","9600"]
return ulist
# 根据注码异常代码获取描述
code_errinfo_list=[
"0:成功",
"1:检测器异常",
"2:电容异常",
"3:接触异常",
"4:桥丝异常",
"5:芯片异常",
"6:未找到相关任务",
"7:过流",
"8:短路",
"193:电压设置失败",
"194:三码验证失败",
"195:UID写入失败",
"196:密码写入失败",
"197:获取UID失败",
"198:UID比对失败",
"199:锁存失败",
"200:等待接入超时",
"201:已存在其他数据"
]
def code_errinfo(errcode:int):
for i in code_errinfo_list:
s=i.split(":")
if(int(s[0])==errcode):
return s[1]
return "未定义的错误码"
# 通道数
def code_channel_list():
ulist=["1","10","20"]
return ulist
# 特征号
def code_signature_code_list():
code_str="ACDEFGHIJKLMNOPQRSTUVWXYZabdefghijklmnpqrty0123456789"
sig_list=[]
for i in code_str:
sig_list.append(i)
return sig_list
if __name__ == "__main__":
fats=dot_fat_list()
for line in fats:
print(line)

126
coder_2ch/coder_test.py Normal file
View File

@@ -0,0 +1,126 @@
import serial
import serial.tools.list_ports
import threading
import time
import socket
# 把tcp封装为串口
class utcp:
is_open=False
def __init__(self,port:int)->None:
self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ser.bind(("",port))
self.ser.settimeout(10)
self.ser.listen(128)
print("wait for mcu connect.")
self.client,self.client_addr=self.ser.accept()
print("client:",self.client_addr)
self.is_open=True
def read(self,len:int):
return self.client.recv(len)
def write(self,data:bytearray):
return self.client.send(data)
def close(self):
self.client.close()
self.ser.close()
self.is_open=False
class port:
def __init__(self) -> None:
pass
def open(self,name:str,bsp:int):
if(name!="utcp"):
self.ser = serial.Serial(port=name, baudrate=bsp,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,timeout=None)
else:
self.ser=utcp(9527)
def start_recv(self):
self.thread_ = threading.Thread(target=self.recv, args=())
self.thread_.start()
def recv(self,num:int):
d=bytearray()
try:
while(num>len(d)):
d+=self.ser.read(num-len(d))
except Exception as a:
print("port closed")
return 0
print("recv code:",d.hex(" "))
def send(self,data:bytearray):
self.ser.write(data)
# 测试上位机
def ecode_test(self,times:int):
print("检测赋码系统耗时测试:")
tick=0
while(tick<times):
tick+=1
print("当前={d1},总共={d2}".format(d1=tick,d2=times))
# 等待数据库写入
time.sleep(3)
start = time.perf_counter()
# 开始检测
self.send(bytearray([0xB0, 0x00, 0x02, 0x00, 0x60]))
# 接收指令应答
self.recv(5)
# 接收检测结果
self.recv(24)
end = time.perf_counter()
print("检测耗时:",end-start)
start2=time.perf_counter()
# 开始注码
self.send(bytearray([0xF0, 0x00, 0x02, 0xE0, 0x41, 0xB1, 0x00, 0x02, 0x00, 0xFB]))
# 接收指令应答
self.recv(5)
# 接收注码 结果
self.recv(305)
end = time.perf_counter()
print("注码耗时:",end-start2)
# 打标结束,保存数据库
self.send(bytearray([0xF0, 0x00, 0x02, 0xE2, 0x23, 0xB2, 0x00, 0x02, 0x00, 0x67]))
# 接收指令应答
self.recv(5)
end = time.perf_counter()
print("总耗时:",end-start)
# 测试注码仪
def coder_test(self,times:int):
print("赋码仪耗时测试:")
tick=0
while(tick<times):
tick+=1
start = time.perf_counter()
print("当前={d1},总共={d2}".format(d1=tick,d2=times))
# 开始检测
self.send(bytearray([0x59, 0x6D, 0x05, 0x00, 0x01, 0x66, 0x04, 0x05, 0x00, 0x2F, 0xD9]))
# 接收指令应答
self.recv(13)
# 接收检测结果
self.recv(72)
end = time.perf_counter()
print("检测耗时:",end-start)
start2=time.perf_counter()
# 开始注码
self.send(bytearray([0x59,0x6D,0x94,0x00,0x02,0xBE,0x01,0x0A,0x32,0x30,0x32,0x33,0x00,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x39,0x01,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x38,0x02,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x37,0x03,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x36,0x04,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x35,0x05,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x34,0x06,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x33,0x07,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x32,0x08,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x31,0x09,0x35,0x38,0x33,0x30,0x36,0x31,0x39,0x41,0x30,0x34,0x30,0x30,0x30,0x44,0xC1]))
# 接收指令应答
self.recv(12)
# 接收注码 结果
self.recv(401)
end = time.perf_counter()
print("注码耗时:",end-start2)
end = time.perf_counter()
print("总耗时:",end-start)
if __name__ == "__main__":
p=port()
# 检测赋码仪系统测试
# p.open("com8",115200)
# p.ecode_test(50000)
# 赋码仪设备串口测试
p.open("com5",115200)
p.coder_test(5)
# p.open("com16",115200)
# p.coder_test(1000)
# 赋码仪设备网口测试
# p.open("utcp",0)
# p.coder_test(5)

519
coder_2ch/prottcp.py Normal file
View File

@@ -0,0 +1,519 @@
import serial
import serial.tools.list_ports
import threading
import time
import json
import socket
from PyQt5.QtCore import *
def crc16(data:bytearray,offset:int,len:int):
if(len>0):
crc=0xffff
for i in range(len-offset):
crc=(crc^data[i+offset])&0xffff
for j in range(8):
if(crc&1)!=0:
crc=((crc>>1)^0xa001)&0xffff
else:
crc=(crc>>1)&0xffff
return crc&0xff,(crc>>8)&0xff
return 0,0
def crc32(data:bytearray):
temp=0
crc=0xffffffff
i=0
if(len(data)%4!=0):
return 0
while(i<len(data)):
temp=data[i]|(data[i+1]<<8)|(data[i+2]<<16)|(data[i+3]<<24)
i+=4
for j in range(32):
if((crc^temp)&0x80000000)!=0:
crc=0x04c11db7^(crc<<1)
else:
crc<<=1
temp<<=1
crc&=0xffffffff
return crc
# 把tcp封装为串口
class utcp:
is_open=False
def __init__(self,port:int)->None:
self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ser.bind(("",port))
self.ser.settimeout(10)
self.ser.listen(128)
print("wait for mcu connect.")
self.client,self.client_addr=self.ser.accept()
print("client:",self.client_addr)
self.is_open=True
def read(self,len:int):
# return self.ser.recv(len)
return self.client.recv(len)
def write(self,data:bytearray):
# return self.ser.send(data)
return self.client.send(data)
def close(self):
self.client.close()
self.ser.close()
self.is_open=False
# 生成一个任务的参数
def scheme_task_to_byte(j:json):
data=bytearray()
data.append(j["TaskID"])
data.append(j["TaskIndex"])
data.append(j["RetryCount"])
data.append(j["ErrJumpTo"])
data.append((j["ParamCount"]&0x0f)|(j["ReturnCount"]<<4))
for i in j["ParamVal"]:
data.append(i&0xff)
data.append(i>>8)
return data
# 生成任务参数序列
def scheme_tasks_to_byte(j:json):
data=bytearray()
for i in j["TaskArray"]:
data+=scheme_task_to_byte(i)
length=len(data)
if(length<(0x700-4)):
for i in range(0x700-4-length):
data.append(0xff)
return data
# 生成任务id序列
def scheme_taskids_to_byte(j:json):
t=bytearray()
t.append(j["PlanID"]&0xff)
t.append((j["PlanID"]>>8)&0xff)
t.append((j["PlanID"]>>16)&0xff)
t.append((j["PlanID"]>>24)&0xff)
for i in j["TaskArray"]:
t.append(i["TaskID"])
length=len(t)
if(length<(0x100)):
for i in range(0x100-length):
t.append(0xff)
return t
# 根据方案生成小板用的字节数据
def scheme_to_byte(j:json):
t=bytearray()
t+=scheme_taskids_to_byte(j)
t+=scheme_tasks_to_byte(j)
crc=crc32(t)
t.append(crc&0xff)
t.append((crc>>8)&0xff)
t.append((crc>>16)&0xff)
t.append((crc>>24)&0xff)
return t
# int转数组
def arr_from_int(num:int):
return bytearray([num&0xff,(num>>8)&0xff,(num>>16)&0xff,(num>>24)&0xff])
# 提取方案中的范围数据, 先max后min
def scheme_get_task_range(j:json):
t=bytearray()
t+=arr_from_int(j["TaskID"])
t+=arr_from_int(j["TaskIndex"])
t+=arr_from_int(j["ReturnCount"])
t+=arr_from_int(j["ExecuteErrCode"])
index=0
for i in j["TestStandard"]:
t+=arr_from_int(i["Max"])
t+=arr_from_int(i["Min"])
if (index<len(j["ResultErrCode"])):
t+=arr_from_int(j["ResultErrCode"][index])
else:
t+=arr_from_int(0)
index+=1
# 不足16的部分填充为16
n=16-len(j["TestStandard"])
for i in range(n):
t+=arr_from_int(65535)
t+=arr_from_int(0)
t+=arr_from_int(0)
return t
# 根据方案生成主板用的字节数据
def scheme_to_host(j:json):
t=bytearray()
t+=arr_from_int(j["PlanID"])
t+=arr_from_int(j["TimeOutM"])
t+=arr_from_int(len(j["TaskArray"]))
for i in j["TaskArray"]:
t+=scheme_get_task_range(i)
return t
# 发送文件类
class handle:
stat=0
name=""
def __init__(self) -> None:
pass
def get_rate(self):
return self.packet_now*100//self.packet_all
def get_data(self):
if(self.stat==0):
length=len(self.data)
# 1是写0是读
t=bytearray([1,length&0xff,(length>>8)&0xff,(length>>16)&0xff,(length>>24)&0xff])
t+=self.name.encode()
self.stat=1
return t
elif(self.stat==1):
packet_bytes=200
if(len(self.data)<self.sent_bytes):
packet_bytes=len(self.data)-self.sent_bytes
if(packet_bytes>0):
self.packet_now+=1
t=bytearray()
t.append(2)
t.append(self.packet_now&0xff)
t.append((self.packet_now>>8)&0xff)
t.append(self.packet_all&0xff)
t.append((self.packet_all>>8)&0xff)
t+=self.data[self.sent_bytes:self.sent_bytes+packet_bytes]
self.sent_bytes+=packet_bytes
return t
else:
print("send done.")
return bytearray()
# 设置要发送的文件
def set_file(self,name:str):
self.data=bytearray()
with open(name,"rb") as f:
self.data=f.read()
self.name=f.name.split('/')[-1]
self.stat=0
self.packet_all=(len(self.data)+199)//200
self.sent_bytes=0
self.packet_now=0
self.packet_bytes=200
# 设置要发送的方案
def set_json(self,name:str):
self.data=bytearray()
with open(name,"rb") as f:
json_obj=json.loads(f.read())
d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
d+=scheme_to_host(json_obj)
# print("len=",len(d),d.hex(","))
self.data=d
self.name=f.name.split('/')[-1]
self.stat=0
self.packet_all=(len(self.data)+199)//200
self.sent_bytes=0
self.packet_now=0
self.packet_bytes=200
class protu(QObject):
# 进度信号ip1~100
rate_signal =pyqtSignal([int])
# 结束信号ip成败描述
end_signal = pyqtSignal([bool,str])
# 接收到数据信号
recv_signal =pyqtSignal([int,bytearray,str])
hand=handle()
def __init__(self) -> None:
QObject.__init__(self)
self.cmd=0
self.cmd_no=0
self.str_err=""
self.is_big_data=False
self.num_to_recv=0
self.recv_data=bytearray()
def init(self,com:str):
s=com.split(":")
try:
if(s[0]=="utcp"):
self.ser = utcp(int(s[1]))
else:
bsp=int(s[1])
self.ser = serial.Serial(port=s[0], baudrate=bsp,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,timeout=None)
except Exception as e:
print(str(e))
return False
return True
def encode(self,data:bytearray):
t=bytearray()
length=len(data)+3
t.append(0x59)
t.append(0x6d)
t.append(length&0xff)
t.append(length>>8)
t.append(self.cmd)
t.append(self.cmd_no&0xff)
t.append(self.cmd_no>>8)
t+=data
a,b=crc16(t,2,length+4)
t.append(a)
t.append(b)
# print("encode:",t.hex(","))
return t
def decode(self,data:bytearray):
self.str_err="ok"
if(len(data)<10):
print("recv data len too less.")
self.str_err="recv data len too less."
return bytearray()
if(data[0]!=0x59 or data[1]!=0x6d or data[2]!=0x43):
# print("frame head not 0x59 0x6d.")
self.str_err="frame head not 0x59 0x6d."
return bytearray()
length=data[3]|(data[4]<<8)
if(length==65535):
# 重新设置数据长度
length=data[7]|(data[8]<<8)|(data[9]<<16)|(data[10]<<24);
self.is_big_data=True
else:
self.is_big_data=False
if(length+7!=len(data)):
print("recv data have lossed")
self.str_err="recv data have lossed"
return bytearray()
a,b=crc16(data,3,length+5)
if(a!=data[-2] or b!=data[-1]):
print("recv data check error.h_crc=%02x %02x,crc=%02x %02x",a,b,data[-2],data[-1])
self.str_err="recv data check error."
self.cmd_no=data[6]|(data[7]<<8)
self.cmd=data[5]
if(self.is_big_data==False):
return bytearray(data[8:-2])
else:
return bytearray(data[12:-2])
# 不带校验的接收函数
def recv_(self):
while(self.ser.is_open):
try:
data=self.ser.read(500)
except Exception as a:
# print("err:",str(a))
print("port closed")
return
if(len(data)>0):
t=self.decode(data)
if(self.str_err=="ok"):
self.recv_data+=t
# print("recv",t.hex(","))
# print(type(self.cmd),type(t),type(self.str_err))
self.recv_signal.emit(self.cmd,t,self.str_err)
# self.send_file_next(self.cmd,t,self.str_err)
# print("sent signal---")
else:
print(data.decode("utf-8"))
# 带帧校验的接收函数
def recv(self):
# self.recv_signal.connect(self.send_file_next)
data=bytearray()
while(self.ser.is_open):
d=bytes()
try:
d=self.ser.read(1)
except Exception as a:
# print("err:",str(a))
print("port closed")
return
data+=d
if(len(data)==3):
if(data[0]==0x59 and data[1]==0x6d and data[2]==0x43):
self.num_to_recv=5
else:
data=data[1:]
self.num_to_recv=0
elif(len(data)==5):
length=data[3]|(data[4]<<8)
if(length<65535):
self.num_to_recv+=length+2
self.is_big_data=False
else:
self.num_to_recv=12
self.is_big_data=True
elif(len(data)==12):
if(self.is_big_data==True):
length=data[8]|(data[9]<<8)|(data[10]<<16)|(data[11]<<24)
self.num_to_recv=5+length+2
if(self.num_to_recv>0 and self.num_to_recv==len(data)):
t=self.decode(data)
self.recv_data+=t
# print("recv",t.hex(","))
self.recv_signal.emit(self.cmd,t,self.str_err)
# self.send_file_next(self.cmd,t,self.str_err)
# print("sent signal---")
data.clear()
# else:
# print("len(data)={d1},num_ro_recv={d2}".format(d1=len(data),d2=self.num_to_recv))
def send(self,cmd:int,data:bytearray):
self.cmd=cmd
self.cmd_no+=1
self.ser.write(self.encode(data))
def send_str(self,txt:str):
self.ser.write(txt.encode("utf-8"))
def start_recv(self):
self.thread_ = threading.Thread(target=self.recv, args=())
self.thread_.start()
def wait(self):
self.thread_.join()
def close(self):
try:
if(self.ser.is_open):
self.ser.close()
except Exception as e:
print(str(e))
def send_file_next(self,cmd:int,data:bytearray,err:str):
print("send_file_next")
data=self.hand.get_data()
if(len(data)>0):
self.send(cmd,data)
else:
self.close()
def send_file(self,cmd:int,name:str):
self.start_recv()
self.hand.set_file(name)
# self.send_file_next(cmd,bytearray([0]),"ok")
self.recv_signal.emit(cmd,bytearray([0]),"ok")
self.wait()
# 0x30 开始检测
# 0x31 检测上报
# 0x32 读写方案
# 0x33 连接维护
# 0x34 自检数据
# 0x35 自检上报
# 0x36 升级脚本
# 0xed 主板升级
# 0xee 小板升级
# 0x40 电机矫正
# 0x41 小板电阻矫正
# 0x42 小板电阻测量
# 0x43 小板硬件版本
# with open("file/judge.lua","rb") as f:
# send_file("COM5",0x36,f.name.split('/')[-1],f.read())
# with open("file/JQ_JCXB_V54.bin","rb") as f:
# send_file("COM5",0xee,f.name.split('/')[-1],f.read())
# with open("file/checker_ye_cfg.json","rb") as f:
# json_obj=json.loads(f.read())
# d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
# d=scheme_to_host(json_obj)
# print("len=",len(d),d.hex(","))
# send_file("COM5",0x32,f.name.split('/')[-1],f.read())
def int2str(num:int):
s=str(num//100)
s=s+str(num%100//10)
s=s+str(num%10)
return s
if __name__ == "__main__":
u=protu()
# u.init("utcp:7777")
# u.send_file(0xee,"file/JQ_JCXB_V54.bin")
# u.send_file(0xed,"../Objects/checker_gen1_app_20230602.bin")
# 设置电阻 矫正值
u.cmd=0x41
data=bytearray([1,0,0x00,2,0,0x00,3,0,0x00,4,0,0x00,5,0,0x00,6,0,0x00,7,0,0x00,8,0,0x00,9,0,0x00,10,0,0x00,11,0,0x00,12,0,0x00,13,0,0x00,14,0,0x00,15,0,0x00,16,0,0x00,17,0,0x00,18,0,0x00,19,0,0x00,20,0,0x00])
# 测量电阻
# u.cmd=0x42
# data=bytearray([0])
# 设置硬件版本号
# u.cmd=0x43
# data=bytearray([1,50,0x00,2,51,0x00,3,52,0x00,4,53,0x00,5,54,0x00,6,55,0x00,7,56,0x00,8,57,0x00,9,58,0x00,10,59,0x00,11,60,0x00,12,61,0x00,13,62,0x00,14,63,0x00,15,64,0x00,16,65,0x00,17,66,0x00,18,67,0x00,19,68,0x00,20,69,0x00])
# 设置电机校正值
# u.cmd=0x40
# data=bytearray([0x01,100,0])
# data=bytearray([0x02]) # 上升
# data=bytearray([0x03]) # 下降
print(u.encode(data).hex(' '))
# with open("file/EX_Coder_Test_2023-07-6.json","rb") as f:
# json_obj=json.loads(f.read())
# d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
# d+=scheme_to_host(json_obj)
# print(int2str(20))
# s="{d:03d}".format(d=2)
# print(s)
# with open("file/7-15.json","rb") as f:
# u.cmd=0x22
# p=u.encode(f.read())
# print(p.hex(' '))
# 开始检测
# 59 6d 03 00 30 00 00 60 0f
# 结束应答
# 59 6D 03 00 31 00 00 31 CF

306
coder_dly/coder_pc.py Normal file
View File

@@ -0,0 +1,306 @@
import serial
import serial.tools.list_ports
import threading
import time
import socket
def crc8(data:bytearray,seed:int=0xff):
poly=0x0135
crc=seed
length=len(data)
for i in range(length):
d=data[i]
for j in range(8):
bit=(crc^d)&0x01
crc>>= 1
if(bit>0):
crc^=poly
crc=crc&0xff
d>>=1
return crc
# 把tcp封装为串口
class utcp:
is_open=False
def __init__(self,port:int)->None:
self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ser.bind(("",port))
self.ser.settimeout(10)
self.ser.listen(128)
print("wait for mcu connect.")
self.client,self.client_addr=self.ser.accept()
print("client:",self.client_addr)
self.is_open=True
def read(self,len:int):
return self.client.recv(len)
def write(self,data:bytearray):
return self.client.send(data)
def close(self):
self.client.close()
self.ser.close()
self.is_open=False
class port:
def __init__(self) -> None:
pass
def open(self,name:str,bsp:int):
if(name!="utcp"):
self.ser = serial.Serial(port=name, baudrate=bsp,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,timeout=None)
else:
self.ser=utcp(9527)
def start_recv(self):
self.thread_ = threading.Thread(target=self.recv, args=())
self.thread_.start()
def recv(self):
d=bytearray()
while(True):
try:
d+=self.ser.read(1)
except Exception as a:
# print("err:",str(a))
print("port closed")
return 0,bytearray()
if(d[0]!=0x23):
d=d[1:]
if((len(d)>=4) and (len(d)>=((d[2]<<8)|d[3]))):
print("recv code:",d.hex(" "))
return self.decode(d)
def send(self,type:int,data:bytearray):
print("send:",self.encode(type,data).hex(" "))
self.ser.write(self.encode(type,data))
def encode(self,type:int,data:bytearray):
table=b"0123456789"
d=bytearray()
d.append(0x23)
d.append(table[type])
length=len(data)+7
d.append((length>>8)&0xff)
d.append(length&0xff)
d+=data
d.append(crc8(d))
d.append(0x0d)
d.append(0x0a)
return d
# 解码 返回指令类型,内容
def decode(self,data:bytearray):
d=data[0:-3]
if(crc8(d)==data[-3]):
return d[1]-0x30,d[4:]
else:
print("crc failed.")
return 0,bytearray()
def calc_shell_code(self,id:int):
shell=bytearray()
# shell+=b"58"
shell+=b"61"
shell+=b"30815A"
shell+="{d:05d}".format(d=id).encode("utf-8")
return shell
# 打包pc到密码终端注码指令
def pack_code_cmd(self,id_start:int,data_other:bytearray=bytearray()):
d=bytearray()
# d+=b"AD"
d+=b"A0"
d.append(0)
d.append(10)
for i in range(10):
d.append(0)
d.append(i+1)
d.append(0)
d.append(13)
leng=len(data_other)
d.append((leng>>8)&0xff)
d.append((leng&0xff))
shell_code=self.calc_shell_code(id_start+i)
print("shell_code:",shell_code.decode("utf-8"))
d+=shell_code
d+=data_other
return d
# 打包pc到密码终端注码指令,生成uid
def pack_code2_cmd(self,id_start:int,data_other:bytearray=bytearray()):
d=bytearray()
fact_chip=b"A0"
year=b"23"
d+=fact_chip
d.append(0)
d.append(10)
for i in range(10):
d.append(0)
d.append(i+1)
d.append(0)
d.append(13)
shell_code=self.calc_shell_code(id_start+i)
uid_code=fact_chip+year+shell_code[0:2]+shell_code[3:]
leng=len(uid_code)
d.append((leng>>8)&0xff)
d.append((leng&0xff))
leng=len(data_other)
d.append((leng>>8)&0xff)
d.append((leng&0xff))
d+=shell_code
d+=uid_code
d+=data_other
return d
# 根据管壳码生成uid和密码
def pack_psw_cmd(self,data:bytearray,year:bytearray=b"23"):
d=bytearray()
fact_chip=data[0:2]
num=(data[2]<<8)|data[3]
data=data[4:]
d+=fact_chip
d.append((num>>8)&0xff)
d.append(num&0xff)
for i in range(num):
index=(data[0]<<8)|data[1]
shell_len=(data[2]<<8)|data[3]
other_len=(data[4]<<8)|data[5]
shell_code=data[6:6+shell_len]
other=data[6+shell_len:6+shell_len+other_len]
# print("shell code:",shell_code.decode("utf-8"))
# print("other:",other.decode("utf-8"))
# 一位年份扩展为两位年份,需考虑计划年份与生产时年份不同的情况
# uid为16位包含芯片厂家代码和两位年份
uid_code=fact_chip+year+shell_code[0:2]+shell_code[3:]
uid_len=len(uid_code)
# 默认生成的密码
psw_code=b"12345678"
psw_len=len(psw_code)
d.append((index>>8)&0xff)
d.append(index&0xff)
d.append((shell_len>>8)&0xff)
d.append(shell_len&0xff)
d.append((uid_len>>8)&0xff)
d.append(uid_len&0xff)
d.append((psw_len>>8)&0xff)
d.append(psw_len&0xff)
d.append((other_len>>8)&0xff)
d.append(other_len&0xff)
d+=shell_code
d+=uid_code
d+=psw_code
d+=other
data=data[6+shell_len+other_len:]
return d
# 根据管壳码密码注码,生成注码结果
def code_write(self,data:bytearray):
d=bytearray()
fact_chip=data[0:2]
num=(data[2]<<8)|data[3]
data=data[4:]
d+=fact_chip
d.append((num>>8)&0xff)
d.append(num&0xff)
for i in range(num):
index=(data[0]<<8)|data[1]
shell_len=(data[2]<<8)|data[3]
uid_len=(data[4]<<8)|data[5]
psw_len=(data[6]<<8)|data[7]
other_len=(data[8]<<8)|data[9]
shell_code=data[10:10+shell_len]
uid_code=data[10+shell_len:10+shell_len+uid_len]
psw_code=data[10+shell_len+uid_len:10+shell_len+uid_len+psw_len]
other=data[10+shell_len+uid_len+psw_len:10+shell_len+uid_len+psw_len+other_len]
ack=bytearray([0])
ack_len=len(ack)
print("shell_code:",shell_code.decode("utf-8"))
print("uid_code:",uid_code.decode("utf-8"))
print("psw_code:",psw_code.decode("utf-8"))
print("other:",other.decode("utf-8"))
d.append((index>>8)&0xff)
d.append(index&0xff)
d.append((shell_len>>8)&0xff)
d.append(shell_len&0xff)
d.append((uid_len>>8)&0xff)
d.append(uid_len&0xff)
d.append((other_len>>8)&0xff)
d.append(other_len&0xff)
# d.append((ack_len>>8)&0xff)
d.append(ack_len&0xff)
d+=shell_code
d+=uid_code
d+=other
d+=ack
data=data[10+shell_len+uid_len+psw_len+other_len:]
return d
# 解析注码结果
def code_wirte_end(self,data:bytearray):
fact_chip=data[0:2]
num=(data[2]<<8)|data[3]
data=data[4:]
print("fact_chip:",fact_chip)
print("num:",num)
for i in range(num):
index=(data[0]<<8)|data[1]
shell_len=(data[2]<<8)|data[3]
uid_len=(data[4]<<8)|data[5]
other_len=(data[6]<<8)|data[7]
ack_len=(data[8]<<8)|data[9]
shell_code=data[10:10+shell_len]
uid_code=data[10+shell_len:10+shell_len+uid_len]
other=data[10+shell_len+uid_len:10+shell_len+uid_len+other_len]
ack=data[10+shell_len+uid_len+other_len:10+shell_len+uid_len+other_len+ack_len]
if __name__ == "__main__":
p=port()
# p.open("com11",115200)
# print("生成透传任意指令")
# d_send=p.encode(5,b"123456789aaaddddggd")
# print(d_send.hex(" "))
d_send=p.encode(6,b"987654321ssddffghhf")
print(d_send.hex(" "))
# print("解析透传任意指令")
# typ,d_recv=p.decode(d_send)
# print(typ,d_recv.hex(" "))
print("生成管壳码注码命令")
d_send=p.encode(1,p.pack_code_cmd(987,b"asdfgk"))
print(d_send.hex(" "))
# print("生成管壳码UID注码命令")
# d_send=p.encode(7,p.pack_code2_cmd(0,b"asdfgk"))
# print(d_send.hex(" "))
# print("解析管壳码注码命令生成UID密码注码命令")
# typ,d_recv=p.decode(d_send)
# d_send=p.encode(2,p.pack_psw_cmd(d_recv))
# print(d_send.hex(" "))
# while (True):
# typ,d_recv=p.recv()
# start = time.perf_counter()
# print("解析uid密码注码命令生成注码结果")
# # d_send=p.encode(3,p.code_write(d_recv))
# # print(d_send.hex(" "))
# # time.sleep(0.1)
# if(typ==2):
# print("返回透传数据")
# p.send(6,b"sssss")
# print("发送注码成功")
# p.send(3,p.code_write(d_recv))
# end = time.perf_counter()
# print("赋码耗时:",end-start)
# elif(typ==5):
# print("返回透传数据")
# p.send(6,b"hello world.")
# end = time.perf_counter()
# print("透传耗时:",end-start)

184
mysql/mysql.py Normal file
View File

@@ -0,0 +1,184 @@
import pymysql as mysql
import datetime
from datetime import datetime, timedelta
import hashlib
import os
import sys
import quest
def connect():
try:
db=mysql.connect(host='124.70.178.159',user='admin',passwd='Rc5345750.',port=3306)
print("connect mysql success.")
return db
except Exception as e:
print("can not connect service.")
return None
# 获取北京时间
def get_date():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y%m%d")
return utc_time
# 获取北京时间
def get_time():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y-%m-%d %H:%M:%S")
return utc_time
# 获取数据md5
def md5(data:bytearray):
m=hashlib.md5(data).hexdigest()
# print(m)
return m
# 获得主板sn号
def get_computer_sn():
sn = os.popen("wmic bios get serialnumber").readlines()
return sn[2].strip()
class sql:
def __init__(self) -> None:
self.download_path="download/"
# 初始化返回True成功
def init(self,table_name:str):
self.db=connect()
self.table_name=table_name
if(self.db!=None):
self.cur=self.db.cursor()
self.cur.execute("use andy_data")
self.cur.execute("select version()")
a=self.cur.fetchone()
print(a)
self.create_table(self.table_name)
return True
return False
# 创建表
def create_table(self,table_name:str):
cmd="""CREATE TABLE IF NOT EXISTS `{d1}`(
`id` INT UNSIGNED AUTO_INCREMENT,
`time` VARCHAR(30) NOT NULL,
`name` VARCHAR(256) NOT NULL,
`md5` VARCHAR(33) NOT NULL,
`data` MEDIUMBLOB NOT NULL,
`info` VARCHAR(512),
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;""".format(d1=table_name)
self.cur.execute(cmd)
# 插入数据
def insert(self,file_name:str,info:str=""):
s=file_name.split('.')
if(len(s)<2):
print("file name without type suffix,will not insert.")
return
with open(file_name,"rb") as f:
d=f.read()
md=md5(d)
lis=self.show()
if(len(lis)>0):
if(lis[-1][3]==md):
print("the same file was saved,will not insert.")
return
try:
cmd="INSERT INTO {d1} (time,name,md5,data,info) VALUES (%s,%s,%s,%s,%s);".format(d1=self.table_name)
self.db.begin()
self.cur.execute(cmd,([get_time(),file_name,md,d,info]))
self.db.commit()
print("insert file success.")
except Exception as e:
self.db.rollback()
print(str(e))
# 查看数据
def show(self):
cmd= "select id,time,name,md5,info from {d1};".format(d1=self.table_name)
self.cur.execute(cmd)
a=self.cur.fetchall()
# for i in a:
# print(i[0],i[1],i[2],i[3])
return a
def show_tables(self):
cmd= "show tables"
self.cur.execute(cmd)
a=self.cur.fetchall()
for i in a:
print(i)
return a
# 下载指定文件,返回文件路径
def download(self,id:int):
if not os.path.exists(self.download_path):
os.makedirs(self.download_path)
ack,name=self.exists(id)
if(ack==True):
print("the same file is exists,will not download.")
return name
cmd="select name,data from {d1} WHERE id={d2};".format(d1=self.table_name,d2=id)
self.cur.execute(cmd)
a=self.cur.fetchall()
for i in a:
ss=i[0].replace('\\','/')
ss=ss.split('/')[-1].split('.')
name=self.download_path+ss[0]+' -'+str(id)+'.'+ss[1]
with open(name,'+bw') as f:
f.write(i[1])
return name
print("can not find the file with id:",id)
return ""
# 获取md5
def get_md5(self,id:int):
cmd="select md5 from {d1} WHERE id={d2};".format(d1=self.table_name,d2=id)
self.cur.execute(cmd)
a=self.cur.fetchall()[0]
return a[0]
# 扫描文件
def scan_files(self):
path = self.download_path
if not os.path.exists(path):
os.makedirs(path)
list=os.listdir(path)
return list
# 判断文件是否存在
def exists(self,id:int):
for i in self.scan_files():
s=i.split('.')[-2].split('-')[-1]
if(int(s)==id):
with open(self.download_path+i,"rb") as f:
md=md5(f.read())
if(md==self.get_md5(id)):
return True,i
return False,""
if __name__ == "__main__":
if(len(sys.argv)>=3):
sql_path=sys.argv[1]
sql_file=sys.argv[2]
s=sql()
if(s.init(sql_path)==True):
q=quest.quest_text("请输入本次提交的描述信息")
ack,text=q.show()
if(ack==True):
s.insert(sql_file,text)
else:
print("user cancelled.")

97
mysql/quest.py Normal file
View File

@@ -0,0 +1,97 @@
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import os
# 定义询问字符文件
QUEST_FILE = "quest_info.txt"
def load_info():
if os.path.exists(QUEST_FILE):
with open(QUEST_FILE,"r") as f:
return f.read()
return ""
def save_info(text:str):
with open(QUEST_FILE,'+w') as f:
print("save:",text)
f.write(text)
class quest_text(QObject):
def __init__(self,title:str):
QObject.__init__(self)
self.app = QApplication(sys.argv)
self.w=QDialog()
self.w.resize(800,400)
self.w.setWindowTitle(title)
self.w.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self.w.setWindowModality(Qt.WindowModality.ApplicationModal)
self.text=load_info()
self.text_edit = QTextEdit(self.w)
self.text_edit.setObjectName(u"text")
self.text_edit.setGeometry(QRect(20, 20, 760, 320))
self.text_edit.setFrameShape(QFrame.Shape.Box)
self.text_edit.setMidLineWidth(1)
self.text_edit.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.text_edit.setPlainText(self.text)
self.text_edit.moveCursor(QTextCursor.MoveOperation.End, QTextCursor.MoveMode.MoveAnchor)
self.ok_but_init()
self.cancel_but_init()
def ok_but_init(self):
self.ok_but=QPushButton(self.w)
self.ok_but.setObjectName(u"ok_but")
self.ok_but.setGeometry(QRect(700, 350, 93, 28))
self.ok_but.clicked.connect(self.ok_but_clicked)
self.ok_but.setText("确认")
self.ok_but.setCheckable(True)
self.ok_but.setChecked(True)
self.ok_state=False
def cancel_but_init(self):
self.cancel_but=QPushButton(self.w)
self.cancel_but.setObjectName(u"cancel_but")
self.cancel_but.setGeometry(QRect(600, 350, 93, 28))
self.cancel_but.clicked.connect(self.cancel_but_clicked)
self.cancel_but.setText("取消")
self.ok_but.setCheckable(True)
self.ok_state=False
def ok_but_clicked(self):
self.text=self.text_edit.toPlainText()
self.ok_state=True
self.w.done(QDialog.DialogCode.Accepted)
self.w.close()
def cancel_but_clicked(self):
self.text=self.text_edit.toPlainText()
self.ok_state=False
self.w.done(QDialog.DialogCode.Accepted)
self.w.close()
def item_clicked(self,item:QListWidgetItem ):
self.select_item=item.text()
self.w.done(QDialog.DialogCode.Accepted)
self.w.close()
def show(self):
# if(self.w.exec()==QDialog.DialogCode.Accepted):
# return self.ok_state,self.text
self.w.show()
a=self.app.exec()
# sys.exit()
save_info(self.text)
return self.ok_state,self.text
if __name__=="__main__":
q=quest_text("输入本次提交的描述")
ack,text=q.show()
print("ack=",ack,"text=",text)

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

179
updata/mysql.py Normal file
View File

@@ -0,0 +1,179 @@
import pymysql as mysql
import datetime
from datetime import datetime, timedelta
import hashlib
import os
def connect():
try:
db=mysql.connect(host='124.70.178.159',user='admin',passwd='Rc5345750.',port=3306)
print("connect mysql success.")
return db
except Exception as e:
print("can not connect service.")
return None
# 获取北京时间
def get_date():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y%m%d")
return utc_time
# 获取北京时间
def get_time():
now_time = datetime.utcnow()
utc_time = now_time + timedelta(hours=8) # UTC只是比北京时间提前了8个小时
utc_time = utc_time.strftime("%Y-%m-%d %H:%M:%S")
return utc_time
# 获取数据md5
def md5(data:bytearray):
m=hashlib.md5(data).hexdigest()
# print(m)
return m
# 获得主板sn号
def get_computer_sn():
sn = os.popen("wmic bios get serialnumber").readlines()
return sn[2].strip()
class sql:
def __init__(self) -> None:
self.download_path="download/"
if not os.path.exists(self.download_path):
os.makedirs(self.download_path)
# 初始化返回True成功
def init(self,table_name:str):
self.db=connect()
self.table_name=table_name
if(self.db!=None):
self.cur=self.db.cursor()
self.cur.execute("use andy_data")
self.cur.execute("select version()")
a=self.cur.fetchone()
print(a)
# self.create_table(self.table_name)
return True
return False
# 创建表
def create_table(self,table_name:str):
cmd="""CREATE TABLE IF NOT EXISTS `{d1}`(
`id` INT UNSIGNED AUTO_INCREMENT,
`time` VARCHAR(30) NOT NULL,
`name` VARCHAR(256) NOT NULL,
`md5` VARCHAR(33) NOT NULL,
`data` MEDIUMBLOB NOT NULL,
`info` VARCHAR(512),
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;""".format(d1=table_name)
self.cur.execute(cmd)
# 插入数据
def insert(self,file_name:str):
s=file_name.split('.')
if(len(s)<2):
print("file name without type suffix,will not insert.")
return
with open(file_name,"rb") as f:
d=f.read()
md=md5(d)
lis=self.show()
if(len(lis)>0):
if(lis[-1][3]==md):
print("the same file was saved,will not insert.")
return
try:
cmd="INSERT INTO {d1} (time,name,md5,data) VALUES (%s,%s,%s,%s);".format(d1=self.table_name)
self.db.begin()
self.cur.execute(cmd,([get_time(),file_name,md,d]))
self.db.commit()
print("insert file success.")
except Exception as e:
self.db.rollback()
print(str(e))
# 查看数据
def items(self):
cmd= "select id,time,name,md5,info from {d1};".format(d1=self.table_name)
self.cur.execute(cmd)
a=self.cur.fetchall()
# for i in a:
# print(i[0],i[1],i[2],i[3])
return a
def show_tables(self):
cmd= "show tables"
self.cur.execute(cmd)
a=self.cur.fetchall()
# for i in a:
# print(i)
return a
# 下载指定文件,返回文件路径
def download(self,id:int):
ack,name=self.exists(id)
if(ack==True):
print("the same file is exists,will not download.")
return name
cmd="select name,data from {d1} WHERE id={d2};".format(d1=self.table_name,d2=id)
self.cur.execute(cmd)
a=self.cur.fetchall()
for i in a:
ss=i[0].replace('\\','/')
ss=ss.split('/')[-1].split('.')
name_prefix='.'.join(ss[:-1])
name=self.download_path+name_prefix+'--'+str(id)+'.'+ss[-1]
with open(name,'+bw') as f:
f.write(i[1])
return name
print("can not find the file with id:",id)
return ""
# 获取md5
def get_md5(self,id:int):
cmd="select md5 from {d1} WHERE id={d2};".format(d1=self.table_name,d2=id)
self.cur.execute(cmd)
a=self.cur.fetchall()[0]
return a[0]
# 扫描文件
def scan_files(self):
path = self.download_path
if not os.path.exists(path):
os.makedirs(path)
list=os.listdir(path)
return list
# 判断文件是否存在
def exists(self,id:int):
for i in self.scan_files():
s=i.split('.')[-2].split('-')[-1]
if(int(s)==id):
name=self.download_path+i
with open(name,"rb") as f:
md=md5(f.read())
if(md==self.get_md5(id)):
return True,name
return False,""
if __name__ == "__main__":
s=sql()
if(s.init("test_data")==True):
# s.insert("file\\check_result.csv")
# s.show()
# file=s.download(1)
# print("save file:",file)
s.show_tables()

536
updata/prottcp.py Normal file
View File

@@ -0,0 +1,536 @@
import serial
import serial.tools.list_ports
import threading
import time
import json
import socket
from PyQt5.QtCore import *
def crc16(data:bytearray,offset:int,len:int):
if(len>0):
crc=0xffff
for i in range(len-offset):
crc=(crc^data[i+offset])&0xffff
for j in range(8):
if(crc&1)!=0:
crc=((crc>>1)^0xa001)&0xffff
else:
crc=(crc>>1)&0xffff
return crc&0xff,(crc>>8)&0xff
return 0,0
def crc32(data:bytearray):
temp=0
crc=0xffffffff
i=0
if(len(data)%4!=0):
return 0
while(i<len(data)):
temp=data[i]|(data[i+1]<<8)|(data[i+2]<<16)|(data[i+3]<<24)
i+=4
for j in range(32):
if((crc^temp)&0x80000000)!=0:
crc=0x04c11db7^(crc<<1)
else:
crc<<=1
temp<<=1
crc&=0xffffffff
return crc
# 把tcp封装为串口
class utcp:
is_open=False
def __init__(self,port:int)->None:
self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ser.bind(("",port))
self.ser.settimeout(10)
self.ser.listen(128)
print("wait for mcu connect.")
self.client,self.client_addr=self.ser.accept()
print("client:",self.client_addr)
self.is_open=True
def read(self,len:int):
# return self.ser.recv(len)
return self.client.recv(len)
def write(self,data:bytearray):
# return self.ser.send(data)
return self.client.send(data)
def close(self):
self.client.close()
self.ser.close()
self.is_open=False
# 生成一个任务的参数
def scheme_task_to_byte(j:json):
data=bytearray()
data.append(j["TaskID"])
data.append(j["TaskIndex"])
data.append(j["RetryCount"])
data.append(j["ErrJumpTo"])
data.append((j["ParamCount"]&0x0f)|(j["ReturnCount"]<<4))
for i in j["ParamVal"]:
data.append(i&0xff)
data.append(i>>8)
return data
# 生成任务参数序列
def scheme_tasks_to_byte(j:json):
data=bytearray()
for i in j["TaskArray"]:
data+=scheme_task_to_byte(i)
length=len(data)
if(length<(0x700-4)):
for i in range(0x700-4-length):
data.append(0xff)
return data
# 生成任务id序列
def scheme_taskids_to_byte(j:json):
t=bytearray()
t.append(j["PlanID"]&0xff)
t.append((j["PlanID"]>>8)&0xff)
t.append((j["PlanID"]>>16)&0xff)
t.append((j["PlanID"]>>24)&0xff)
for i in j["TaskArray"]:
t.append(i["TaskID"])
length=len(t)
if(length<(0x100)):
for i in range(0x100-length):
t.append(0xff)
return t
# 根据方案生成小板用的字节数据
def scheme_to_byte(j:json):
t=bytearray()
t+=scheme_taskids_to_byte(j)
t+=scheme_tasks_to_byte(j)
crc=crc32(t)
t.append(crc&0xff)
t.append((crc>>8)&0xff)
t.append((crc>>16)&0xff)
t.append((crc>>24)&0xff)
return t
# int转数组
def arr_from_int(num:int):
return bytearray([num&0xff,(num>>8)&0xff,(num>>16)&0xff,(num>>24)&0xff])
# 提取方案中的范围数据, 先max后min
def scheme_get_task_range(j:json):
t=bytearray()
t+=arr_from_int(j["TaskID"])
t+=arr_from_int(j["TaskIndex"])
t+=arr_from_int(j["ReturnCount"])
t+=arr_from_int(j["ExecuteErrCode"])
index=0
for i in j["TestStandard"]:
t+=arr_from_int(i["Max"])
t+=arr_from_int(i["Min"])
if (index<len(j["ResultErrCode"])):
t+=arr_from_int(j["ResultErrCode"][index])
else:
t+=arr_from_int(0)
index+=1
# 不足16的部分填充为16
n=16-len(j["TestStandard"])
for i in range(n):
t+=arr_from_int(65535)
t+=arr_from_int(0)
t+=arr_from_int(0)
return t
# 根据方案生成主板用的字节数据
def scheme_to_host(j:json):
t=bytearray()
t+=arr_from_int(j["PlanID"])
t+=arr_from_int(j["TimeOutM"])
t+=arr_from_int(len(j["TaskArray"]))
for i in j["TaskArray"]:
t+=scheme_get_task_range(i)
return t
# 发送文件类
class handle:
stat=0
name=""
def __init__(self) -> None:
pass
def get_rate(self):
return self.packet_now*100//self.packet_all
def get_data(self):
if(self.stat==0):
length=len(self.data)
# 1是写0是读
t=bytearray([1,length&0xff,(length>>8)&0xff,(length>>16)&0xff,(length>>24)&0xff])
t+=self.name.encode()
self.stat=1
return t
elif(self.stat==1):
packet_bytes=200
if(len(self.data)<self.sent_bytes):
packet_bytes=len(self.data)-self.sent_bytes
if(packet_bytes>0):
self.packet_now+=1
t=bytearray()
t.append(2)
t.append(self.packet_now&0xff)
t.append((self.packet_now>>8)&0xff)
t.append(self.packet_all&0xff)
t.append((self.packet_all>>8)&0xff)
t+=self.data[self.sent_bytes:self.sent_bytes+packet_bytes]
self.sent_bytes+=packet_bytes
return t
else:
print("send done.")
return bytearray()
# 设置要发送的文件
def set_file(self,name:str):
self.data=bytearray()
with open(name,"rb") as f:
self.data=f.read()
self.name=f.name.split('/')[-1]
self.stat=0
self.packet_all=(len(self.data)+199)//200
self.sent_bytes=0
self.packet_now=0
self.packet_bytes=200
# 设置要发送的方案
def set_json(self,name:str):
self.data=bytearray()
with open(name,"rb") as f:
json_obj=json.loads(f.read())
d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
d+=scheme_to_host(json_obj)
# print("len=",len(d),d.hex(","))
self.data=d
self.name=f.name.split('/')[-1]
self.stat=0
self.packet_all=(len(self.data)+199)//200
self.sent_bytes=0
self.packet_now=0
self.packet_bytes=200
class protu(QObject):
# 进度信号ip1~100
rate_signal =pyqtSignal([int])
# 结束信号ip成败描述
end_signal = pyqtSignal([bool,str])
# 接收到数据信号
recv_signal =pyqtSignal([int,bytearray,str])
# 接收到字符串信号
recv_str_signal =pyqtSignal([int,str,str])
hand=handle()
def __init__(self) -> None:
QObject.__init__(self)
self.cmd=0
self.cmd_no=0
self.str_err=""
self.is_big_data=False
self.num_to_recv=0
self.recv_data=bytearray()
def init(self,com:str):
s=com.split(":")
try:
if(s[0]=="utcp"):
self.ser = utcp(int(s[1]))
else:
bsp=int(s[1])
self.ser = serial.Serial(port=s[0], baudrate=bsp,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,timeout=None)
except Exception as e:
print(str(e))
return False
return True
def encode(self,data:bytearray):
t=bytearray()
length=len(data)+3
t.append(0x59)
t.append(0x6d)
t.append(length&0xff)
t.append(length>>8)
t.append(self.cmd)
t.append(self.cmd_no&0xff)
t.append(self.cmd_no>>8)
t+=data
a,b=crc16(t,2,length+4)
t.append(a)
t.append(b)
# print("encode:",t.hex(","))
return t
def decode(self,data:bytearray):
self.str_err="ok"
if(len(data)<10):
print("recv data len too less.")
self.str_err="recv data len too less."
return bytearray()
if(data[0]!=0x59 or data[1]!=0x6d or data[2]!=0x43):
# print("frame head not 0x59 0x6d.")
self.str_err="frame head not 0x59 0x6d."
return bytearray()
length=data[3]|(data[4]<<8)
if(length==65535):
# 重新设置数据长度
length=data[7]|(data[8]<<8)|(data[9]<<16)|(data[10]<<24);
self.is_big_data=True
else:
self.is_big_data=False
if(length+7!=len(data)):
print("recv data have lossed")
self.str_err="recv data have lossed"
return bytearray()
a,b=crc16(data,3,length+5)
if(a!=data[-2] or b!=data[-1]):
print("recv data check error.h_crc=%02x %02x,crc=%02x %02x",a,b,data[-2],data[-1])
self.str_err="recv data check error."
self.cmd_no=data[6]|(data[7]<<8)
self.cmd=data[5]
if(self.is_big_data==False):
return bytearray(data[8:-2])
else:
return bytearray(data[12:-2])
# 不带校验的接收函数
def recv_(self):
while(self.ser.is_open):
try:
data=self.ser.read(500)
except Exception as a:
# print("err:",str(a))
print("port closed")
return
if(len(data)>0):
t=self.decode(data)
if(self.str_err=="ok"):
self.recv_data+=t
# print("recv",t.hex(","))
# print(type(self.cmd),type(t),type(self.str_err))
self.recv_signal.emit(self.cmd,t,self.str_err)
# self.send_file_next(self.cmd,t,self.str_err)
# print("sent signal---")
else:
print(data.decode("utf-8"))
# 带帧校验的接收函数
def recv(self):
# self.recv_signal.connect(self.send_file_next)
data=bytearray()
data_str=bytearray()
while(self.ser.is_open):
d=bytes()
try:
d=self.ser.read(1)
except Exception as a:
# print("err:",str(a))
print("port closed")
return
data+=d
data_str+=d
if(len(data)==3):
if(data[0]==0x59 and data[1]==0x6d and data[2]==0x43):
self.num_to_recv=5
else:
data=data[1:]
self.num_to_recv=0
elif(len(data)==5):
length=data[3]|(data[4]<<8)
if(length<65535):
self.num_to_recv+=length+2
self.is_big_data=False
else:
self.num_to_recv=12
self.is_big_data=True
elif(len(data)==12):
if(self.is_big_data==True):
length=data[8]|(data[9]<<8)|(data[10]<<16)|(data[11]<<24)
self.num_to_recv=5+length+2
if(self.num_to_recv>0 and self.num_to_recv==len(data)):
t=self.decode(data)
self.recv_data+=t
# print("recv",t.hex(","))
self.recv_signal.emit(self.cmd,t,self.str_err)
# self.send_file_next(self.cmd,t,self.str_err)
# print("sent signal---")
data.clear()
data_str.clear()
elif(len(data_str)>=2):
if((data_str[-2]==0x0d) and (data_str[-1]==0x0a)):
data_str=data_str[:-2]
recv_str=""
try:
recv_str=data_str.decode("utf-8")
self.recv_str_signal.emit(0,recv_str,"ok")
data_str.clear()
except Exception as e:
print(str(e))
# print(recv_str)
# else:
# print("len(data)={d1},num_ro_recv={d2}".format(d1=len(data),d2=self.num_to_recv))
def send(self,cmd:int,data:bytearray):
self.cmd=cmd
self.cmd_no+=1
# print("send:",data.hex(","))
self.ser.write(self.encode(data))
def send_str(self,txt:str):
self.ser.write(txt.encode("utf-8"))
def start_recv(self):
self.thread_ = threading.Thread(target=self.recv, args=())
self.thread_.start()
def wait(self):
self.thread_.join()
def close(self):
try:
if(self.ser.is_open):
self.ser.close()
except Exception as e:
print(str(e))
def send_file_next(self,cmd:int,data:bytearray,err:str):
print("send_file_next")
data=self.hand.get_data()
if(len(data)>0):
self.send(cmd,data)
else:
self.close()
def send_file(self,cmd:int,name:str):
self.start_recv()
self.hand.set_file(name)
# self.send_file_next(cmd,bytearray([0]),"ok")
self.recv_signal.emit(cmd,bytearray([0]),"ok")
self.wait()
# 0x30 开始检测
# 0x31 检测上报
# 0x32 读写方案
# 0x33 连接维护
# 0x34 自检数据
# 0x35 自检上报
# 0x36 升级脚本
# 0xed 主板升级
# 0xee 小板升级
# 0x40 电机矫正
# 0x41 小板电阻矫正
# 0x42 小板电阻测量
# 0x43 小板硬件版本
# with open("file/judge.lua","rb") as f:
# send_file("COM5",0x36,f.name.split('/')[-1],f.read())
# with open("file/JQ_JCXB_V54.bin","rb") as f:
# send_file("COM5",0xee,f.name.split('/')[-1],f.read())
# with open("file/checker_ye_cfg.json","rb") as f:
# json_obj=json.loads(f.read())
# d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
# d=scheme_to_host(json_obj)
# print("len=",len(d),d.hex(","))
# send_file("COM5",0x32,f.name.split('/')[-1],f.read())
def int2str(num:int):
s=str(num//100)
s=s+str(num%100//10)
s=s+str(num%10)
return s
if __name__ == "__main__":
u=protu()
# u.init("utcp:7777")
# u.send_file(0xee,"file/JQ_JCXB_V54.bin")
# u.send_file(0xed,"../Objects/checker_gen1_app_20230602.bin")
# 设置电阻 矫正值
u.cmd=0x41
data=bytearray([1,0,0x00,2,0,0x00,3,0,0x00,4,0,0x00,5,0,0x00,6,0,0x00,7,0,0x00,8,0,0x00,9,0,0x00,10,0,0x00,11,0,0x00,12,0,0x00,13,0,0x00,14,0,0x00,15,0,0x00,16,0,0x00,17,0,0x00,18,0,0x00,19,0,0x00,20,0,0x00])
# 测量电阻
# u.cmd=0x42
# data=bytearray([0])
# 设置硬件版本号
# u.cmd=0x43
# data=bytearray([1,50,0x00,2,51,0x00,3,52,0x00,4,53,0x00,5,54,0x00,6,55,0x00,7,56,0x00,8,57,0x00,9,58,0x00,10,59,0x00,11,60,0x00,12,61,0x00,13,62,0x00,14,63,0x00,15,64,0x00,16,65,0x00,17,66,0x00,18,67,0x00,19,68,0x00,20,69,0x00])
# 设置电机校正值
# u.cmd=0x40
# data=bytearray([0x01,100,0])
# data=bytearray([0x02]) # 上升
# data=bytearray([0x03]) # 下降
print(u.encode(data).hex(' '))
# with open("file/EX_Coder_Test_2023-07-6.json","rb") as f:
# json_obj=json.loads(f.read())
# d=scheme_to_byte(json_obj)
# print("len=",len(d),d.hex(","))
# d+=scheme_to_host(json_obj)
# print(int2str(20))
# s="{d:03d}".format(d=2)
# print(s)
# with open("file/7-15.json","rb") as f:
# u.cmd=0x22
# p=u.encode(f.read())
# print(p.hex(' '))
# 开始检测
# 59 6d 03 00 30 00 00 60 0f
# 结束应答
# 59 6D 03 00 31 00 00 31 CF

52
updata/select_list.py Normal file
View File

@@ -0,0 +1,52 @@
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class select_list(QObject):
def __init__(self,father:QDialog,title:str,str_list:list):
QObject.__init__(self)
self.w=QDialog(father)
self.w.resize(800,400)
self.w.setWindowTitle(title)
self.w.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self.w.setWindowModality(Qt.WindowModality.ApplicationModal)
self.file_list = QListWidget(self.w)
self.file_list.setObjectName(u"str_list")
self.file_list.setGeometry(QRect(20, 20, 760, 360))
self.file_list.setFrameShape(QFrame.Shape.Box)
self.file_list.setMidLineWidth(1)
self.file_list.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.file_list.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
self.file_list.itemDoubleClicked.connect(self.item_clicked)
self.item_append(str_list)
def item_append(self,items:list):
for i in items:
# print("add item",i[0])
self.file_list.addItem(i[0])
def item_clicked(self,item:QListWidgetItem ):
self.select_item=item.text()
self.w.done(QDialog.DialogCode.Accepted)
self.w.close()
def show(self):
# self.w.show()
if(self.w.exec()==QDialog.DialogCode.Accepted):
# print(self.select_item)
return self.select_item
return ""

View File

@@ -14,6 +14,8 @@ import encodings.idna
import base64
import memory_pic
import ctypes
import mysql
import select_list
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid")
STR_RED="\033[1;31m"
@@ -90,8 +92,6 @@ class data_box(QObject):
class updata_dlg(QObject):
# 进度信号ip1~100
rate_signal =pyqtSignal([str,int])
@@ -106,6 +106,7 @@ class updata_dlg(QObject):
self.widget.resize(703, 409)
self.widget.setWindowTitle("批检仪程序升级")
self.widget.setWindowFlags(Qt.WindowType.WindowStaysOnTopHint)
self.addrs=""
self.but_y=60
self.but_y_step=40
self.file_list_init()
@@ -117,8 +118,10 @@ class updata_dlg(QObject):
self.hand_but_init()
self.addfile_but_init()
self.scheme_but_init()
self.download_but_init()
self.ip_prefix_init()
self.ip_hand_init()
self.channel_init()
self.widget.destroyed.connect(self.quit)
self.scan_file()
self.scan_slave()
@@ -246,11 +249,20 @@ class updata_dlg(QObject):
self.scheme_but.setToolTip("请先将要升级的方案文件发送到主板中然后点击此按钮开始升级方案到MCU。")
# self.addfile_but.setToolTipDuration(1)
# 初始化下载文件按钮
def download_but_init(self):
self.download_but = QPushButton(self.widget)
self.download_but.setObjectName(u"download_but")
self.download_but.setGeometry(QRect(590, self.but_y, 93, 28))
self.but_y+=self.but_y_step
self.download_but.setText("下载文件")
self.download_but.clicked.connect(self.download_but_clicked)
# ip前缀
def ip_prefix_init(self):
self.ip_prefix = QLineEdit(self.widget)
self.ip_prefix.setObjectName(u"ip_prefix")
self.ip_prefix.setGeometry(QRect(130, 10, 113, 21))
self.ip_prefix.setGeometry(QRect(110, 10, 113, 21))
self.ip_prefix.setText("192.168.80")
self.ip_prefix_label = QLabel(self.widget)
self.ip_prefix_label.setObjectName(u"label")
@@ -265,18 +277,33 @@ class updata_dlg(QObject):
def ip_hand_init(self):
self.ip_hand = QLineEdit(self.widget)
self.ip_hand.setObjectName(u"ip_hand")
self.ip_hand.setGeometry(QRect(430, 10, 120, 21))
self.ip_hand.setGeometry(QRect(360, 10, 120, 21))
ip=self.ip_prefix.text()
self.ip_hand.setText(ip+".81")
self.ip_hand_label = QLabel(self.widget)
self.ip_hand_label.setObjectName(u"ip_hand_label")
self.ip_hand_label.setGeometry(QRect(300, 10, 120, 21))
self.ip_hand_label.setGeometry(QRect(230, 10, 120, 21))
self.ip_hand_label.setText("手动添加IP地址")
self.ip_hand_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.ip_hand_label.setToolTip("如果扫描不到设备可以尝试手动添加设备的IP地址然后升级。")
self.ip_hand.setToolTip("如果扫描不到设备可以尝试手动添加设备的IP地址然后升级。")
# self.ip_hand_label.setToolTipDuration(1)
# 选择通道数
def channel_init(self):
self.channel = QComboBox(self.widget)
self.channel.setObjectName(u"channel")
self.channel.setGeometry(QRect(560, 10, 100, 25))
self.channel.setEditable(True)
self.channel.addItem("10通道")
self.channel.addItem("20通道")
self.channel.currentIndexChanged.connect(self.channel_changed)
self.channel_changed(0)
# self.channel_label = QLabel(self.widget)
# self.channel_label.setObjectName(u"label")
# self.channel_label.setGeometry(QRect(410, 16, 72, 15))
# self.channel_label.setText("波特率:")
# 显示消息框
def show_msg(self,msg:str):
m=QMessageBox(self.widget)
@@ -366,6 +393,14 @@ class updata_dlg(QObject):
ip=self.ip_hand.text()
self.slave_list.addItem(ip+",local_id_0")
def channel_changed(self,index:int):
s=self.channel.itemText(index)
print("channel_changed,str=",s)
if(s=="10通道"):
self.addrs="1,2,3,4,5,6,7,8,9,10 "
elif(s=="20通道"):
self.addrs="1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 "
print("addrs:",self.addrs)
# 发送文件按钮按下
def save_but_clicked(self):
print("save_but_clicked.")
@@ -456,6 +491,39 @@ class updata_dlg(QObject):
shutil.copy(i,path+i.split("/")[-1])
self.scan_file()
def download_but_clicked(self):
sql=mysql.sql()
if(sql.init("")):
str_list=sql.show_tables()
sel=select_list.select_list(self.widget,"选择文件目录",str_list)
path=sel.show()
# print("path:",path)
if(len(path)<=0):
print("not select any item,break.")
return
sql.table_name=path
items=sql.items()
str_list=[]
for i in items:
item_name=i[2].replace("\\","/")
item_name=item_name.split("/")[-1]
if(i[4]!=None):
s=str(i[0])+"|"+i[1]+"|"+item_name+"|"+i[4]
else:
s=str(i[0])+"|"+i[1]+"|"+item_name
# print(s)
str_list.append((s,))
sel=select_list.select_list(self.widget,"选择文件",str_list)
item=sel.show()
# print("item:",item)
if(len(item)<=0):
print("not select any item,break.")
return
item=item.split("|")
file_name=sql.download(int(item[0]))
dst="file/"+file_name.split("/")[-1]
shutil.copy(file_name,dst)
self.scan_file()
# 开始运行
def run(self):
@@ -523,7 +591,8 @@ class updata_dlg(QObject):
u.dst_ip_list=ip_list
u.rate_signal.connect(self.rate_slot)
u.end_signal.connect(self.end_slot)
updata_cmd="mcu updata 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 "
print("addrs:",self.addrs)
updata_cmd="mcu updata "+self.addrs+' '
updata_cmd+="/home/root/config/"+file
cmd_list=[]
cmd_list.append((updata_cmd,1,900))
@@ -536,7 +605,7 @@ class updata_dlg(QObject):
u.dst_ip_list=ip_list
u.rate_signal.connect(self.rate_slot)
u.end_signal.connect(self.end_slot)
updata_cmd="mcu scheme 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 "
updata_cmd="mcu scheme "+self.addrs+' '
cmd_list=[]
cmd_list.append((updata_cmd,1,9))
t = threading.Thread(target=u.bordcast, args=(cmd_list,))

554
updata/updata_uart.py Normal file
View File

@@ -0,0 +1,554 @@
import sys
import os
import shutil
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import threading
import time
import portalocker
import serial
import serial.tools.list_ports
import prottcp
import mysql
import select_list
STR_RED="\033[1;31m"
STR_BLUE="\033[1;34m"
STR_END="\033[0m"
class progress_box(QObject):
def __init__(self) -> None:
QObject.__init__(self)
def init(self,father:QDialog,text:str,x:int):
# print("text=",text)
self.lable = QLabel(father)
self.lable.setObjectName(u"label")
self.lable.setGeometry(QRect(40, x, 120, 15))
self.lable.setText(text)
self.p=QProgressBar(father)
self.p.setValue(0)
self.p.setGeometry(QRect(40,x+20,450,20))
def set_rate(self,rate:int):
# print(text)
self.p.setValue(rate)
class data_box(QObject):
def __init__(self) -> None:
QObject.__init__(self)
self.select_item=""
def init(self,father:QDialog,title:str,text:str,x:int):
# print("text=",text)
self.lable = QLabel(father)
self.lable.setObjectName(u"label")
self.lable.setGeometry(QRect(40, x, 120, 20))
self.lable.setText(title)
self.text = QLabel(father)
self.text.setObjectName(u"text")
self.text.setGeometry(QRect(40,x+20,450,30))
self.text.setText(text)
class updata_dlg(QObject):
# 进度信号ip1~100
rate_signal =pyqtSignal([int])
# 结束信号ip成败描述
end_signal = pyqtSignal([bool,str])
failed_signal = pyqtSignal()
def __init__(self):
QObject.__init__(self)
self.app = QApplication(sys.argv)
self.widget = QWidget()
self.widget.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self.widget.resize(703, 409)
self.widget.setWindowTitle("赋码仪程序升级")
self.file_list_init()
self.com_but_init()
self.save_but_init()
self.updatas_but_init()
# self.cmd_but_init()
self.sstate_but_init()
self.scheme_but_init()
self.com_init()
self.combsp_init()
self.download_but_init()
self.widget.destroyed.connect(self.quit)
self.failed_signal.connect(self.updata_failed)
self.cmd=0
self.port_is_open=False
def quit(self):
self.close_port()
# 程序退出
qApp.exit(1)
# 初始化文件列表
def file_list_init(self):
self.file_list = QListWidget(self.widget)
self.file_list.setObjectName(u"file_list")
self.file_list.setGeometry(QRect(25, 60, 531, 310))
self.file_list.setFrameShape(QFrame.Shape.Box)
self.file_list.setMidLineWidth(1)
self.file_list.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
self.file_list.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
self.file_list.itemDoubleClicked.connect(self.item_clicked)
# 初始化打开端口按钮
def com_but_init(self):
self.com_but = QPushButton(self.widget)
self.com_but.setObjectName(u"com_but")
self.com_but.setGeometry(QRect(590, 10, 93, 28))
self.com_but.setText("打开端口")
self.com_but.clicked.connect(self.com_but_clicked)
# 初始化发送文件按钮
def save_but_init(self):
self.save_but = QPushButton(self.widget)
self.save_but.setObjectName(u"save_but")
self.save_but.setGeometry(QRect(590, 60, 93, 28))
self.save_but.setText("发送文件")
self.save_but.clicked.connect(self.save_but_clicked)
# 初始化发送命令按钮
def cmd_but_init(self):
self.cmd_but = QPushButton(self.widget)
self.cmd_but.setObjectName(u"save_but")
self.cmd_but.setGeometry(QRect(590, 100, 93, 28))
self.cmd_but.setText("升级MCU")
self.cmd_but.clicked.connect(self.cmd_but_clicked)
# 初始化升级小板按钮
def updatas_but_init(self):
self.updatas_but = QPushButton(self.widget)
self.updatas_but.setObjectName(u"updatas_but")
self.updatas_but.setGeometry(QRect(590, 100, 93, 28))
self.updatas_but.setText("升级小板")
self.updatas_but.clicked.connect(self.updatas_but_clicked)
# 初始化在线状态按钮
def sstate_but_init(self):
self.sstate_but = QPushButton(self.widget)
self.sstate_but.setObjectName(u"sstate_but")
self.sstate_but.setGeometry(QRect(590, 140, 93, 28))
self.sstate_but.setText("主板参数")
self.sstate_but.clicked.connect(self.sstate_but_clicked)
# 初始化方案状态按钮
def scheme_but_init(self):
self.scheme_but = QPushButton(self.widget)
self.scheme_but.setObjectName(u"scheme_but")
self.scheme_but.setGeometry(QRect(590, 180, 93, 28))
self.scheme_but.setText("方案参数")
self.scheme_but.clicked.connect(self.scheme_but_clicked)
# 初始化下载文件按钮
def download_but_init(self):
self.download_but = QPushButton(self.widget)
self.download_but.setObjectName(u"download_but")
self.download_but.setGeometry(QRect(590, 220, 93, 28))
self.download_but.setText("下载文件")
self.download_but.clicked.connect(self.download_but_clicked)
# com口
def com_init(self):
self.com = QComboBox(self.widget)
self.com.setObjectName(u"com")
self.com.setGeometry(QRect(85, 10, 300, 25))
self.com.setEditable(True)
self.com.currentIndexChanged.connect(self.com_changed)
self.com.addItem("utcp:7777")
ports_list = list(serial.tools.list_ports.comports())
for comport in ports_list:
# print(comport.name,comport.description)
self.com.addItem(comport.name+":"+comport.description)
self.com_label = QLabel(self.widget)
self.com_label.setObjectName(u"label")
self.com_label.setGeometry(QRect(30, 16, 72, 15))
self.com_label.setText("COM口:")
# 选择波特率
def combsp_init(self):
self.combsp = QComboBox(self.widget)
self.combsp.setObjectName(u"combsp")
self.combsp.setGeometry(QRect(470, 10, 80, 25))
self.combsp.setEditable(True)
self.combsp.addItem("115200")
self.combsp.addItem("57600")
self.combsp.addItem("38400")
self.combsp.addItem("9600")
self.combsp_label = QLabel(self.widget)
self.combsp_label.setObjectName(u"label")
self.combsp_label.setGeometry(QRect(410, 16, 72, 15))
self.combsp_label.setText("波特率:")
# 显示消息框
def show_msg(self,msg:str):
m=QMessageBox(self.widget)
m.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
m.setText(msg)
m.setWindowTitle("提示")
m.show()
# 找到已选择的文件
def get_selected_file_by_type(self,type:str):
file_list=[]
items=self.file_list.selectedItems()
for i in items:
if(i.text()[-len(type):]==type):
file_list.append(i.text())
if(len(file_list)!=1):
self.show_msg("请选择一个并且只选择一个 "+type+" 文件")
return ""
return file_list[0]
# 获取已选择的文件列表
def get_selected_fils(self):
file_list=[]
items=self.file_list.selectedItems()
if(len(items)==0):
self.show_msg("请选择至少一个文件")
return []
have_elf=False
have_bin=False
have_lua=False
for i in items:
if(i.text()[-4:]==".elf"):
if(have_elf==True):
self.show_msg("只可选择一个 .elf 文件")
return []
have_elf=True
if(i.text()[-4:]==".bin"):
if(have_bin==True):
self.show_msg("只可选择一个 .bin 文件")
return []
have_bin=True
if(i.text()[-4:]==".lua"):
if(have_lua==True):
self.show_msg("只可选择一个 .lua 文件")
return []
have_lua=True
file_list.append(i.text())
return file_list
def item_clicked(self,item:QListWidgetItem ):
print("item clicked.")
print("slected item is",item.text())
def com_but_clicked(self):
print("com but clicked")
if(self.port_is_open==False):
self.open_port()
else:
self.close_port()
def com_changed(self,index:int):
print("com changed")
self.close_port()
def get_cmd(self,file:str):
l=[(".bin",0xee),(".pkt",0xed),(".json",0x32)]
for i in l:
if(file.endswith(i[0])):
return i[1]
return 0
# 发送文件按钮按下
def save_but_clicked(self):
print("save_but_clicked.")
path = self.getpath()+"file\\"
file_list=self.get_selected_fils()
if(len(file_list)==0):
return
self.cmd=self.get_cmd(file_list[0])
print("cmd=",self.cmd)
w=QDialog(self.widget)
w.resize(703-150, 1*40+20)
w.setWindowTitle("上传文件")
w.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self.handle_=prottcp.handle()
if(file_list[0].endswith(".json")):
self.handle_.set_json("file/"+file_list[0])
else:
self.handle_.set_file("file/"+file_list[0])
d=self.handle_.get_data()
try:
self.port.send(self.cmd,d)
except Exception as e:
print("com not open")
self.show_msg("端口未打开")
del self.handle_
w.close()
return
self.creat_progress(w)
w.show()
# self.failed_signal.connect(w.close)
# w.destroyed.connect(self.close_port)
def updata_failed(self):
self.show_msg("打开端口失败")
# 创建进度条
def creat_progress(self,father:QDialog):
self.probar_list=[]
for i in range(1):
p=progress_box()
p.init(father,"发送文件",+i*40)
self.rate_signal.connect(p.set_rate)
self.probar_list.append(p)
# 发送命令按钮按下
def cmd_but_clicked(self):
print("cmd_but clicked.")
file=self.get_selected_file_by_type(".bin")
if(len(file)==0):
return
print("file:",file)
w=QDialog(self.widget)
w.resize(703-150, 1*40+20)
w.setWindowTitle("升级mcu")
self.updata_mcu(file)
self.creat_progress(w)
w.show()
def sstate_but_clicked(self):
print("sstate_but clicked.")
try:
self.port.send_str("sysinfo")
except Exception as e:
print("com not open")
print(str(e))
def scheme_but_clicked(self):
print("scheme_but clicked.")
try:
self.port.send_str("scheme")
except Exception as e:
print("com not open")
print(str(e))
def updatas_but_clicked(self):
print("updatas_but clicked.")
try:
self.port.send_str("updatas 1,2,3,4,5,6,7,8,9,10")
self.show_msg("已发送升级指令,请留意小板升级情况")
except Exception as e:
self.show_msg("命令发送失败")
print("com not open")
print(str(e))
def download_but_clicked(self):
sql=mysql.sql()
if(sql.init("")):
str_list=sql.show_tables()
sel=select_list.select_list(self.widget,"选择文件目录",str_list)
path=sel.show()
# print("path:",path)
if(len(path)<=0):
print("not select any item,break.")
return
sql.table_name=path
items=sql.items()
str_list=[]
for i in items:
item_name=i[2].replace("\\","/")
item_name=item_name.split("/")[-1]
if(i[4]!=None):
s=str(i[0])+"|"+i[1]+"|"+item_name+"|"+i[4]
else:
s=str(i[0])+"|"+i[1]+"|"+item_name
# print(s)
str_list.append((s,))
sel=select_list.select_list(self.widget,"选择文件",str_list)
item=sel.show()
# print("item:",item)
if(len(item)<=0):
print("not select any item,break.")
return
item=item.split("|")
file_name=sql.download(int(item[0]))
dst="file/"+file_name.split("/")[-1]
shutil.copy(file_name,dst)
self.scan_file()
# 开始运行
def run(self):
self.widget.show()
sys.exit(self.app.exec())
def set_port_state(self,state:bool):
self.port_is_open=state
if(state==True):
self.com_but.setText("关闭端口")
else:
self.com_but.setText("打开端口")
# 扫描文件
def scan_file(self):
self.file_list.clear()
self.file_list.addItems(self.find_type([".bin",".json",".pkt"]))
# 扫描指定类型的文件
def find_type(self,types:list):
path = self.getpath()+"file\\"
if not os.path.exists(path):
os.makedirs(path)
list=os.listdir(path)
file_list=[]
for t in types:
for i in list:
if(len(t)>0):
if(i[-len(t):]==t):
file_list.append(i)
else:
file_list.append(i)
return file_list
# 获得文件绝对路径
def getpath(self):
path=os.path.abspath(sys.argv[0])
list_str=path.split("\\")
return path.replace(list_str[-1],"")
# 调用此函数打开通信
def open_port(self):
t = threading.Thread(target=self.com_thread, args=())
t.start()
def com_thread(self):
self.port=prottcp.protu()
item=self.com.itemText(self.com.currentIndex())
bsp=self.combsp.itemText(self.combsp.currentIndex())
com=item.split(":")[0]
if(com!="utcp"):
item=com+":"+bsp
print("item text:",item)
if(self.port.init(item)==False):
print("init port failed.")
self.failed_signal.emit()
self.set_port_state(False)
return
else:
print("init port success.")
self.set_port_state(True)
self.port.recv_signal.connect(self.recv_slot)
self.port.recv_str_signal.connect(self.recv_str_slot)
self.port.start_recv()
self.port.wait()
def close_port(self):
print("close port")
self.set_port_state(False)
try:
self.port.close()
self.port.recv_signal.disconnect(self.recv_slot)
self.port.recv_str_signal.disconnect(self.recv_str_slot)
except Exception as e:
pass
def recv_str_slot(self,cmd:int,txt:str,err:str):
print("|-|",txt)
def recv_slot(self,cmd:int,data:bytearray,err:str):
# print("recv:",cmd,data)
if(self.cmd!=cmd):
return
try:
data=self.handle_.get_data()
if(len(data)>0):
self.port.send(cmd,data)
rate=self.handle_.get_rate()
self.rate_signal.emit(rate)
else:
del self.handle_
except Exception as e:
print(str(e))
# 开始升级mcu
def updata_mcu(self,file):
pass
# 小板通信测试
def comm_test(self):
pass
def end_slot(self,ip,ack,err):
# print(ip,ack,err)
if(ack==False):
self.show_msg(ip+":"+err)
def rate_slot(self,rate):
# print("rate signal:",ip,rate)
self.rate_signal.emit(rate)
def data_slot(self,ip,text):
pass
# 创建数据显示
def creat_databoxs(self,father:QDialog,data_list:list):
self.datab_list=[]
for i in range(len(data_list)):
p=data_box()
p.init(father,data_list[i][0],data_list[i][1],+i*50)
self.datab_list.append(p)
class locker():
def _get_lock(self):
file_name = os.path.basename(__file__)
# linux等平台依然使用标准的/var/run其他nt等平台使用当前目录
if os.name == "posix":
lock_file_name = f"/var/run/{file_name}.pid"
else:
lock_file_name = f"{file_name}.pid"
self.fd = open(lock_file_name, "w")
try:
portalocker.lock(self.fd, portalocker.LOCK_EX | portalocker.LOCK_NB)
# 将当前进程号写入文件
# 如果获取不到锁上一步就已经异常了,所以不用担心覆盖
self.fd.writelines(str(os.getpid()))
# 写入的数据太少,默认会先被放在缓冲区,我们强制同步写入到文件
self.fd.flush()
except:
print(f"{file_name} have another instance running.")
exit(1)
def __init__(self):
self._get_lock()
# 和fcntl有点区别portalocker释放锁直接有unlock()方法
# 还是一样,其实并不需要在最后自己主动释放锁
def __del__(self):
portalocker.unlock(self.fd)
if __name__ == "__main__":
lock=locker()
dlg=updata_dlg()
dlg.scan_file()
dlg.run()