88 lines
2.7 KiB
Python
88 lines
2.7 KiB
Python
|
|
import time
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
recvData = bytearray() #接收的数据存放此数组
|
|||
|
|
startTime = time.time()
|
|||
|
|
|
|||
|
|
# 将bytearray以字为单位转换成16进制字符串,方便显示
|
|||
|
|
def wordData2HexStr(data):
|
|||
|
|
ret = ' '.join(data[i:i+2].hex() for i in range(0, len(data), 2))
|
|||
|
|
return ret.upper()
|
|||
|
|
|
|||
|
|
# 获取当前时间字符串
|
|||
|
|
def nowStr():
|
|||
|
|
now = datetime.now()
|
|||
|
|
ret = now.strftime('%H:%M:%S.') + f"{now.microsecond // 1000:03d}"
|
|||
|
|
return ret
|
|||
|
|
|
|||
|
|
def checkValue(data: bytes) -> int:
|
|||
|
|
# 初始化crc为0xFFFF
|
|||
|
|
crc = 0xFFFF
|
|||
|
|
|
|||
|
|
length = len(data)
|
|||
|
|
if length % 2 != 0:
|
|||
|
|
return 0
|
|||
|
|
|
|||
|
|
for i in range(0, length, 2):
|
|||
|
|
val = data[i] * 256 + data[i + 1]
|
|||
|
|
crc = crc ^ val
|
|||
|
|
|
|||
|
|
# 返回最终的crc值
|
|||
|
|
return crc
|
|||
|
|
|
|||
|
|
# 启动函数,命令开始会调用此函数
|
|||
|
|
def start():
|
|||
|
|
|
|||
|
|
log_i('----------------- ' + cmdInfo['name'] + ' ----------------')
|
|||
|
|
#log(f"[{devInfo['name']}]{cmdInfo['name']}")
|
|||
|
|
|
|||
|
|
startTime = time.time() #记录启动时间
|
|||
|
|
|
|||
|
|
recvData = bytearray() #清空接收数组
|
|||
|
|
|
|||
|
|
attr = cmdInfo['attr']
|
|||
|
|
cmdStr = attr['cmd'] + attr['data'] #组合要发送的报文,十六进制字符串
|
|||
|
|
|
|||
|
|
data = bytearray().fromhex(cmdStr) #将十六进制字符串转成字节数据发送
|
|||
|
|
|
|||
|
|
if attr['req_is_check'] == True:
|
|||
|
|
crc = checkValue(data)
|
|||
|
|
data = data + bytearray(crc.to_bytes(2, 'big'))
|
|||
|
|
send(data)
|
|||
|
|
|
|||
|
|
log_d(f"[{nowStr()}] Sent:{wordData2HexStr(data)}")
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
# 接收数据处理函数,当收到数据会调用此函数
|
|||
|
|
def recvDataHandler(data):
|
|||
|
|
global recvData
|
|||
|
|
recvData = recvData + data
|
|||
|
|
attr = cmdInfo['attr']
|
|||
|
|
rsp_len = int(attr['rsp_len']) * 2
|
|||
|
|
if len(recvData) >= rsp_len: #TBUS指令rsp_len以字为单位
|
|||
|
|
log_d(f"[{nowStr()}] Echo:{wordData2HexStr(recvData)}")
|
|||
|
|
if attr['rsp_is_check'] == True:
|
|||
|
|
# 校验数据正确性
|
|||
|
|
crc = int.from_bytes(recvData[rsp_len - 2:rsp_len], byteorder='big')
|
|||
|
|
calc_value = checkValue(recvData[0:rsp_len - 2])
|
|||
|
|
if crc != calc_value:
|
|||
|
|
log_w("CRC error:" +
|
|||
|
|
"should be " + '{:04X}'.format(calc_value) +
|
|||
|
|
",got " + '{:04X}'.format(crc))
|
|||
|
|
finish()
|
|||
|
|
return
|
|||
|
|
log_i("success")
|
|||
|
|
finish()
|
|||
|
|
|
|||
|
|
# 此函数会被重复调用,间隔10毫秒,直到finish()
|
|||
|
|
def loop():
|
|||
|
|
global recvData
|
|||
|
|
if time.time() > startTime + int(cmdInfo['attr']['rsp_timeout']) / 1000.0:
|
|||
|
|
if len(recvData) > 0:
|
|||
|
|
log_w(f"[{nowStr()}]RX timeout:{wordData2HexStr(recvData)}")
|
|||
|
|
else:
|
|||
|
|
log_w(f"[{nowStr()}]RX timeout")
|
|||
|
|
log_e(f"[{devInfo['name']}]{cmdInfo['name']} fail.")
|
|||
|
|
finish()
|