feat: 添加串口失败跟踪和冷却机制,优化串口重试逻辑
This commit is contained in:
parent
275ad1a720
commit
b0115059e5
@ -94,10 +94,11 @@
|
||||
"data_bits": 8,
|
||||
"parity": "N",
|
||||
"port": "9600",
|
||||
"ser": "COM2",
|
||||
"ser": "",
|
||||
"stable_threshold": 10,
|
||||
"stop_bits": 1,
|
||||
"timeout": 1
|
||||
"timeout": 1,
|
||||
"comment": "称重通过寄存器D11获取,无需串口"
|
||||
},
|
||||
"xj": {
|
||||
"bit": 10,
|
||||
|
||||
@ -51,6 +51,12 @@ class SerialManager:
|
||||
# 稳定性时间跟踪
|
||||
self.stability_start_time = 0 # 开始检测稳定性的时间
|
||||
|
||||
# 串口失败跟踪
|
||||
self.port_failure_count: Dict[str, int] = {} # 记录每个串口的连续失败次数
|
||||
self.port_last_failure_time: Dict[str, float] = {} # 记录每个串口的最后失败时间
|
||||
self.max_failures = 5 # 最大连续失败次数
|
||||
self.failure_cooldown = 300 # 失败冷却时间(秒),5分钟
|
||||
|
||||
# 数据存储
|
||||
self.data = {
|
||||
'mdz': 0,
|
||||
@ -996,20 +1002,26 @@ class SerialManager:
|
||||
port_name = self.cz_config['ser']
|
||||
baud_rate = self.cz_config.get('port', 9600)
|
||||
|
||||
if not self.is_port_open(port_name):
|
||||
# 检查串口是否在冷却期内
|
||||
if self._should_skip_port_attempt(port_name):
|
||||
logging.info(f"称重串口 {port_name} 在冷却期内,跳过重试(失败{self.port_failure_count.get(port_name, 0)}次)")
|
||||
elif not self.is_port_open(port_name):
|
||||
try:
|
||||
if self.open_port(port_name, 'cz', baud_rate):
|
||||
logging.info(f"自动打开称重串口 {port_name} 成功")
|
||||
self._reset_port_failure(port_name) # 成功后重置失败计数
|
||||
else:
|
||||
logging.error(f"自动打开称重串口 {port_name} 失败")
|
||||
self._record_port_failure(port_name)
|
||||
success = False
|
||||
except Exception as e:
|
||||
logging.error(f"自动打开称重串口 {port_name} 时发生异常: {e}")
|
||||
self._record_port_failure(port_name)
|
||||
success = False
|
||||
else:
|
||||
logging.info(f"称重串口 {port_name} 已经打开,无需重新打开")
|
||||
else:
|
||||
logging.warning("称重串口未配置或设置为不使用,跳过自动打开")
|
||||
logging.info("称重串口未配置或设置为不使用,跳过自动打开")
|
||||
|
||||
# 尝试打开线径串口
|
||||
if self.xj_config and 'ser' in self.xj_config and self.xj_config['ser'] and self.xj_config['ser'].strip():
|
||||
@ -1325,4 +1337,46 @@ class SerialManager:
|
||||
logging.error(f"线程监控主循环异常: {e}")
|
||||
# 尝试重新启动监控
|
||||
time.sleep(10)
|
||||
self._start_thread_monitor()
|
||||
self._start_thread_monitor()
|
||||
|
||||
def _should_skip_port_attempt(self, port_name: str) -> bool:
|
||||
"""检查是否应该跳过串口重试(基于失败次数和冷却时间)"""
|
||||
current_time = time.time()
|
||||
|
||||
# 如果没有失败记录,允许尝试
|
||||
if port_name not in self.port_failure_count:
|
||||
return False
|
||||
|
||||
failure_count = self.port_failure_count[port_name]
|
||||
last_failure_time = self.port_last_failure_time.get(port_name, 0)
|
||||
|
||||
# 如果失败次数超过最大值且在冷却期内,跳过
|
||||
if failure_count >= self.max_failures:
|
||||
time_since_failure = current_time - last_failure_time
|
||||
if time_since_failure < self.failure_cooldown:
|
||||
return True
|
||||
else:
|
||||
# 冷却期结束,重置失败计数给一次机会
|
||||
logging.info(f"串口 {port_name} 冷却期结束,重置失败计数")
|
||||
self._reset_port_failure(port_name)
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def _record_port_failure(self, port_name: str):
|
||||
"""记录串口打开失败"""
|
||||
current_time = time.time()
|
||||
self.port_failure_count[port_name] = self.port_failure_count.get(port_name, 0) + 1
|
||||
self.port_last_failure_time[port_name] = current_time
|
||||
|
||||
failure_count = self.port_failure_count[port_name]
|
||||
if failure_count >= self.max_failures:
|
||||
cooldown_minutes = self.failure_cooldown // 60
|
||||
logging.warning(f"串口 {port_name} 连续失败{failure_count}次,将在{cooldown_minutes}分钟内暂停重试")
|
||||
|
||||
def _reset_port_failure(self, port_name: str):
|
||||
"""重置串口失败计数"""
|
||||
if port_name in self.port_failure_count:
|
||||
del self.port_failure_count[port_name]
|
||||
if port_name in self.port_last_failure_time:
|
||||
del self.port_last_failure_time[port_name]
|
||||
Loading…
Reference in New Issue
Block a user