重构设备类定义, 使用继承简化代码;
This commit is contained in:
@@ -1,30 +1,33 @@
|
||||
import time
|
||||
from serial import Serial
|
||||
from serial.tools import list_ports
|
||||
|
||||
from . import tools
|
||||
from . import function
|
||||
from .tools import ByteConv
|
||||
from .function import protocols
|
||||
|
||||
class DeviceSerial:
|
||||
""" 串口通信设备原型
|
||||
Note: 串口资源释放与重复开启
|
||||
"""
|
||||
def __init__(self, com_name="COM1", **kwargs):
|
||||
def __init__(self, com_name, callbacks, **kwargs):
|
||||
""" 初始化设备 """
|
||||
self.__com = None
|
||||
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.open_connection(com_name, **kwargs)
|
||||
|
||||
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
|
||||
|
||||
match callbacks:
|
||||
case (maker, parser):
|
||||
self.frame_maker = maker if maker is not None else lambda self: ''
|
||||
self.frame_parser = parser if parser is not None else lambda self, frame: ''
|
||||
case _:
|
||||
self.farme_maker = lambda self: ''
|
||||
self.frame_parser = lambda self, frame: ''
|
||||
|
||||
self.output = {
|
||||
'result': False,
|
||||
'code_func': 0x00,
|
||||
@@ -45,28 +48,33 @@ class DeviceSerial:
|
||||
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()
|
||||
bytes_read = self.__com.read_all()
|
||||
if flag_frame and len(bytes_read) == 0:
|
||||
break
|
||||
elif len(bytes_read):
|
||||
flag_frame = True
|
||||
frame_recv += bytes_read
|
||||
try:
|
||||
self.output = function.frame.check_frame_modbus(frame_recv, self.block['data'])
|
||||
self.output = self.frame_parser(frame_recv)
|
||||
if self.flag_print:
|
||||
print("Read Frame: ", tools.ByteConv.trans_list_to_str(frame_recv))
|
||||
print("Read Frame: ", ByteConv.trans_list_to_str(frame_recv))
|
||||
except Exception as ex:
|
||||
print("Error Info: ", ex)
|
||||
if self.flag_print and frame_recv:
|
||||
print("Fail Data: " , tools.ByteConv.trans_list_to_str(frame_recv))
|
||||
print("Fail Data: " , ByteConv.trans_list_to_str(frame_recv))
|
||||
self.output['result'] = False
|
||||
|
||||
return self.output['result']
|
||||
def __transfer_data(self, frame: bytearray) -> bool:
|
||||
|
||||
def _transfer_data(self) -> bool:
|
||||
""" 串口收发报文, 包含重试逻辑与数据打印 """
|
||||
# 生成发送帧
|
||||
frame: bytearray = self.frame_maker()
|
||||
|
||||
if self.__com is None:
|
||||
print(tools.ByteConv.trans_list_to_str(frame))
|
||||
""" 无效通信接口, 打印报文后返回 """
|
||||
print(ByteConv.trans_list_to_str(frame))
|
||||
return False
|
||||
|
||||
fail_count = 0
|
||||
@@ -78,22 +86,82 @@ class DeviceSerial:
|
||||
if self.flag_print and frame_discard:
|
||||
print("Discard Data: " , frame_discard)
|
||||
if self.flag_print:
|
||||
print("Send Frame: ", tools.ByteConv.trans_list_to_str(frame))
|
||||
print("Send Frame: ", ByteConv.trans_list_to_str(frame))
|
||||
|
||||
time.sleep(10 * self.time_gap)
|
||||
time.sleep(2 * self.time_gap)
|
||||
if self.__read_frame():
|
||||
if (self.flag_print is not None) and 'Regs' in self.output.keys():
|
||||
function.frame.print_display(self.output['Regs'])
|
||||
protocols.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)
|
||||
|
||||
fail_count += 1
|
||||
self.log['keep-fail'] = fail_count if fail_count >= self.log['keep-fail'] else self.log['keep-fail']
|
||||
time.sleep(2 * self.time_out)
|
||||
|
||||
return fail_count < self.retry
|
||||
|
||||
def close_connection(self) -> bool:
|
||||
""" 关闭连接, 释放通信资源
|
||||
|
||||
"""
|
||||
if self.__com is not None:
|
||||
self.__com.close()
|
||||
return self.__com is None or (not self.__com.is_open)
|
||||
|
||||
def open_connection(self, port=None, **kwargs) -> bool:
|
||||
""" 打开连接, 更新或重新配置通信资源
|
||||
|
||||
"""
|
||||
com_config = {
|
||||
'baudrate': 115200,
|
||||
'parity': 'N',
|
||||
'bytesize': 8,
|
||||
'stopbits': 1,
|
||||
}
|
||||
|
||||
serial_close = lambda com: com.close() if com.isOpen() else None
|
||||
serial_port_check = lambda port: port.upper() in (com.name for com in list_ports.comports())
|
||||
|
||||
match (self.__com, port, kwargs):
|
||||
case (None, str() as port, None):
|
||||
""" 使用默认参数打开串口 """
|
||||
self.__com = Serial(port, timeout=0, **com_config)
|
||||
case (None, str() as port, dict() as kwargs):
|
||||
""" 使用指定参数打开串口 """
|
||||
com_config['baudrate'] = kwargs['baudrate'] if 'baudrate' in kwargs.keys() else com_config['baudrate']
|
||||
com_config['parity'] = kwargs['parity'] if 'parity' in kwargs.keys() else com_config['parity']
|
||||
com_config['bytesize'] = kwargs['bytesize'] if 'bytesize' in kwargs.keys() else com_config['bytesize']
|
||||
com_config['stopbits'] = kwargs['stopbits'] if 'stopbits' in kwargs.keys() else com_config['stopbits']
|
||||
self.__com = Serial(port, timeout=0, **com_config)
|
||||
case (Serial() as com, None, None):
|
||||
""" 无参数重开串口 """
|
||||
serial_close(self.__com)
|
||||
com.open()
|
||||
case (Serial() as com, port, None):
|
||||
""" 重新指定端口号并打开串口 """
|
||||
serial_close(self.__com)
|
||||
if serial_port_check(port):
|
||||
raise ValueError("无效串口端口: %s" % port)
|
||||
com.port = port
|
||||
com.open()
|
||||
case (None, str() as port, dict() as kwargs):
|
||||
""" 重新指定端口号与配置并打开串口 """
|
||||
serial_close(self.__com)
|
||||
if serial_port_check(port):
|
||||
raise ValueError("无效串口端口: %s" % port)
|
||||
com.port = port
|
||||
com.baudrate = kwargs['baudrate'] if 'baudrate' in kwargs.keys() else com_config['baudrate']
|
||||
com.parity = kwargs['parity'] if 'parity' in kwargs.keys() else com_config['parity']
|
||||
com.bytesize = kwargs['bytesize'] if 'bytesize' in kwargs.keys() else com_config['bytesize']
|
||||
com.stopbits = kwargs['stopbits'] if 'stopbits' in kwargs.keys() else com_config['stopbits']
|
||||
com.open()
|
||||
case _:
|
||||
""" 匹配失败, 报错 """
|
||||
raise ValueError("Invalid config.")
|
||||
|
||||
return self.__com.is_open
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user