112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
import time
|
|
from serial import Serial
|
|
from function.tools.ByteConv import conv_int_to_array, trans_list_to_str
|
|
from function.frame import make_frame_modbus, check_frame_modbus, print_display
|
|
|
|
|
|
class DeviceSerial:
|
|
""" 串口通信设备原型
|
|
"""
|
|
def __init__(self, com_name="COM1", **kwargs):
|
|
""" 初始化设备 """
|
|
if com_name is not None:
|
|
com_config = {}
|
|
com_config['baudrate'] = kwargs['baudrate'] if 'baudrate' in kwargs.keys() else 115200
|
|
com_config['parity'] = kwargs['parity'] if 'parity' in kwargs.keys() else 'N'
|
|
com_config['bytesize'] = kwargs['bytesize'] if 'bytesize' in kwargs.keys() else 8
|
|
com_config['stopbits'] = kwargs['stopbits'] if 'stopbits' in kwargs.keys() else 1
|
|
self.__com = Serial(com_name, timeout=0, **com_config)
|
|
else:
|
|
self.__com = None
|
|
|
|
self.flag_print = kwargs['frame_print'] if 'frame_print' in kwargs.keys() else False
|
|
self.time_out = kwargs['time_out'] if 'time_out' in kwargs.keys() else 1
|
|
self.time_gap = kwargs['time_gap'] if 'time_gap' in kwargs.keys() else 0.01
|
|
self.retry = kwargs['retry'] if 'retry' in kwargs.keys() else 1
|
|
|
|
self.output = {
|
|
'result': False,
|
|
'code_func': 0x00,
|
|
}
|
|
self.log = {
|
|
'send': 0,
|
|
'read': 0,
|
|
'keep-fail': 0,
|
|
'record': {
|
|
'config': None,
|
|
'data': None,
|
|
},
|
|
}
|
|
|
|
def __read_frame(self) -> bool:
|
|
""" 使用帧字节超时策略读报文帧, 并进行解析数据, 打印异常 """
|
|
frame_recv = b''
|
|
time_start, time_current, flag_frame = time.time(), time.time(), False
|
|
while (time_current - time_start) < self.time_out:
|
|
time.sleep(self.time_gap)
|
|
bytes_read = self.__com.read_all()
|
|
time_current = time.time()
|
|
if flag_frame and len(bytes_read) == 0:
|
|
break
|
|
elif len(bytes_read):
|
|
flag_frame = True
|
|
frame_recv += bytes_read
|
|
try:
|
|
self.output = check_frame_modbus(frame_recv, self.block['data'])
|
|
if self.flag_print:
|
|
print("Read Frame: ", trans_list_to_str(frame_recv))
|
|
except Exception as ex:
|
|
print("Error Info: ", ex)
|
|
if self.flag_print and frame_recv:
|
|
print("Fail Data: " , trans_list_to_str(frame_recv))
|
|
self.output['result'] = False
|
|
|
|
return self.output['result']
|
|
def __transfer_data(self, frame: bytearray) -> bool:
|
|
""" 串口收发报文, 包含重试逻辑与数据打印 """
|
|
if self.__com is None:
|
|
print(trans_list_to_str(frame))
|
|
return False
|
|
|
|
fail_count = 0
|
|
while fail_count < self.retry:
|
|
frame_discard = self.__com.read_all()
|
|
self.__com.write(frame)
|
|
self.log['send'] += 1
|
|
|
|
if self.flag_print and frame_discard:
|
|
print("Discard Data: " , frame_discard)
|
|
if self.flag_print:
|
|
print("Send Frame: ", trans_list_to_str(frame))
|
|
|
|
time.sleep(10 * self.time_gap)
|
|
if self.__read_frame():
|
|
if (self.flag_print is not None) and 'Regs' in self.output.keys():
|
|
print_display(self.output['Regs'])
|
|
self.log['read'] += 1
|
|
break
|
|
else:
|
|
fail_count += 1
|
|
if fail_count >= self.log['keep-fail']:
|
|
self.log['keep-fail'] = fail_count
|
|
time.sleep(2*self.time_out)
|
|
|
|
return fail_count < self.retry
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|