2.15.23
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+37
-1
@@ -69,7 +69,7 @@ class ATClient:
|
|||||||
# 同上:避免在 _reader_loop 持锁期间二次 acquire
|
# 同上:避免在 _reader_loop 持锁期间二次 acquire
|
||||||
self._http_events.append(ev)
|
self._http_events.append(ev)
|
||||||
|
|
||||||
def send(self, cmd: str, expect: str = "OK", timeout_ms: int = 2000):
|
def send(self, cmd: str, expect: str = "OK", timeout_ms: int = 2000, abort_event=None):
|
||||||
"""
|
"""
|
||||||
发送 AT 命令并等待 expect(子串匹配)。
|
发送 AT 命令并等待 expect(子串匹配)。
|
||||||
注意:expect=">" 用于等待 prompt。
|
注意:expect=">" 用于等待 prompt。
|
||||||
@@ -90,6 +90,9 @@ class ATClient:
|
|||||||
|
|
||||||
t0 = time.ticks_ms()
|
t0 = time.ticks_ms()
|
||||||
while abs(time.ticks_diff(time.ticks_ms(), t0)) < timeout_ms:
|
while abs(time.ticks_diff(time.ticks_ms(), t0)) < timeout_ms:
|
||||||
|
if abort_event is not None and abort_event.is_set():
|
||||||
|
self._waiting = False
|
||||||
|
break
|
||||||
if (not self._waiting) or (self._expect in self._resp):
|
if (not self._waiting) or (self._expect in self._resp):
|
||||||
self._waiting = False
|
self._waiting = False
|
||||||
break
|
break
|
||||||
@@ -102,6 +105,39 @@ class ATClient:
|
|||||||
except:
|
except:
|
||||||
return str(self._resp)
|
return str(self._resp)
|
||||||
|
|
||||||
|
def send_raw_and_wait(self, data: bytes, expect: str = "OK", timeout_ms: int = 1000,
|
||||||
|
suffix: bytes = b""):
|
||||||
|
"""Register the response waiter before writing raw UART data."""
|
||||||
|
expect_b = expect.encode() if isinstance(expect, str) else expect
|
||||||
|
with self._cmd_lock:
|
||||||
|
with self._q_lock:
|
||||||
|
self._waiting = True
|
||||||
|
self._expect = expect_b
|
||||||
|
self._resp = b""
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
while total < len(data):
|
||||||
|
n = self.uart.write(data[total:])
|
||||||
|
if not n or n < 0:
|
||||||
|
time.sleep_ms(1)
|
||||||
|
continue
|
||||||
|
total += n
|
||||||
|
if suffix:
|
||||||
|
self.uart.write(suffix)
|
||||||
|
|
||||||
|
t0 = time.ticks_ms()
|
||||||
|
while abs(time.ticks_diff(time.ticks_ms(), t0)) < timeout_ms:
|
||||||
|
if (not self._waiting) or (self._expect in self._resp):
|
||||||
|
self._waiting = False
|
||||||
|
break
|
||||||
|
time.sleep_ms(5)
|
||||||
|
|
||||||
|
self._waiting = False
|
||||||
|
try:
|
||||||
|
return self._resp.decode(errors="ignore")
|
||||||
|
except:
|
||||||
|
return str(self._resp)
|
||||||
|
|
||||||
def _find_urc_tag(self, tag: bytes):
|
def _find_urc_tag(self, tag: bytes):
|
||||||
"""
|
"""
|
||||||
只在"真正的 URC 边界"查找 tag,避免误命中 HTTP payload 内容。
|
只在"真正的 URC 边界"查找 tag,避免误命中 HTTP payload 内容。
|
||||||
|
|||||||
@@ -346,10 +346,13 @@ AUTO_POWER_OFF_IN_SECONDS = 10 * 60 # 自动关机时间(秒),0表示不
|
|||||||
# 实机数据:正常放电约为正电流,插入充电线后约为负电流。
|
# 实机数据:正常放电约为正电流,插入充电线后约为负电流。
|
||||||
CHARGING_SHUTDOWN_ENABLED = True # True=充电时退出应用,False=关闭充电关机功能
|
CHARGING_SHUTDOWN_ENABLED = True # True=充电时退出应用,False=关闭充电关机功能
|
||||||
CHARGING_DIAGNOSTIC_LOG_ENABLED = False
|
CHARGING_DIAGNOSTIC_LOG_ENABLED = False
|
||||||
CHARGING_CHECK_INTERVAL_MS = 5000
|
CHARGING_CHECK_INTERVAL_MS = 3000
|
||||||
CHARGING_CURRENT_THRESHOLD_MA = 100.0
|
CHARGING_CURRENT_THRESHOLD_MA = 100.0
|
||||||
CHARGING_CONFIRM_COUNT = 2
|
CHARGING_CONFIRM_COUNT = 2
|
||||||
CHARGING_NOTIFY_TIMEOUT_MS = 30000
|
CHARGING_NOTIFY_TIMEOUT_MS = 30000
|
||||||
|
CHARGING_4G_UART_LOCK_TIMEOUT_SEC = 2.5
|
||||||
|
CHARGING_4G_PROMPT_TIMEOUT_MS = 1500
|
||||||
|
CHARGING_4G_CONFIRM_TIMEOUT_MS = 1000
|
||||||
CHARGING_EXIT_SCRIPT = APP_DIR + "/charging_exit.sh"
|
CHARGING_EXIT_SCRIPT = APP_DIR + "/charging_exit.sh"
|
||||||
|
|
||||||
BATTERY_SOC_LPF_ALPHA = 0.5
|
BATTERY_SOC_LPF_ALPHA = 0.5
|
||||||
|
|||||||
+120
-3
@@ -67,6 +67,7 @@ class NetworkManager:
|
|||||||
self._queue_lock = threading.Lock()
|
self._queue_lock = threading.Lock()
|
||||||
self._send_event = threading.Event()
|
self._send_event = threading.Event()
|
||||||
self._uart4g_lock = threading.Lock()
|
self._uart4g_lock = threading.Lock()
|
||||||
|
self._terminal_send_event = threading.Event()
|
||||||
self._device_id = None
|
self._device_id = None
|
||||||
self._password = None
|
self._password = None
|
||||||
self._raw_line_data = []
|
self._raw_line_data = []
|
||||||
@@ -676,7 +677,7 @@ class NetworkManager:
|
|||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
w = network.wifi.Wifi()
|
w = network.wifi.Wifi()
|
||||||
e = w.connect(ssid, password, wait=True, timeout=15)
|
e = w.connect(ssid, password, wait=True, timeout=10)
|
||||||
err.check_raise(e, "connect wifi failed")
|
err.check_raise(e, "connect wifi failed")
|
||||||
if self.logger:
|
if self.logger:
|
||||||
self.logger.info(f"[ota] Connect success, got ip{w.get_ip()}")
|
self.logger.info(f"[ota] Connect success, got ip{w.get_ip()}")
|
||||||
@@ -715,6 +716,29 @@ class NetworkManager:
|
|||||||
self._enqueue((msg_type, data_dict, sent_event), high)
|
self._enqueue((msg_type, data_dict, sent_event), high)
|
||||||
return bool(sent_event.wait(max(0, int(timeout_ms)) / 1000.0))
|
return bool(sent_event.wait(max(0, int(timeout_ms)) / 1000.0))
|
||||||
|
|
||||||
|
def safe_replace_queue_and_wait(self, data_dict, msg_type=2, timeout_ms=30000):
|
||||||
|
"""Drop queued messages, enqueue one terminal message, and wait for its TCP write."""
|
||||||
|
sent_event = threading.Event()
|
||||||
|
with self._queue_lock:
|
||||||
|
self._high_send_queue.clear()
|
||||||
|
self._normal_send_queue.clear()
|
||||||
|
self._high_send_queue.append((msg_type, data_dict, sent_event))
|
||||||
|
self._send_event.set()
|
||||||
|
return bool(sent_event.wait(max(0, int(timeout_ms)) / 1000.0))
|
||||||
|
|
||||||
|
def safe_terminal_send_and_wait(self, data_dict, msg_type=2, timeout_ms=30000):
|
||||||
|
"""Cancel ordinary 4G waits and replace queued work with one terminal message."""
|
||||||
|
sent_event = threading.Event()
|
||||||
|
result = {"sent": False}
|
||||||
|
self._terminal_send_event.set()
|
||||||
|
with self._queue_lock:
|
||||||
|
self._high_send_queue.clear()
|
||||||
|
self._normal_send_queue.clear()
|
||||||
|
self._high_send_queue.append((msg_type, data_dict, sent_event, "terminal", result))
|
||||||
|
self._send_event.set()
|
||||||
|
completed = sent_event.wait(max(0, int(timeout_ms)) / 1000.0)
|
||||||
|
return bool(completed and result["sent"])
|
||||||
|
|
||||||
def connect_server(self):
|
def connect_server(self):
|
||||||
"""
|
"""
|
||||||
连接到服务器(自动选择WiFi或4G)
|
连接到服务器(自动选择WiFi或4G)
|
||||||
@@ -1114,8 +1138,12 @@ class NetworkManager:
|
|||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
for _ in range(max_retries):
|
for _ in range(max_retries):
|
||||||
|
if self._terminal_send_event.is_set():
|
||||||
|
return False
|
||||||
cmd = f'AT+MIPSEND={link_id},{len(data)}'
|
cmd = f'AT+MIPSEND={link_id},{len(data)}'
|
||||||
if ">" not in hardware_manager.at_client.send(cmd, ">", 2000):
|
if ">" not in hardware_manager.at_client.send(cmd, ">", 2000):
|
||||||
|
if self._terminal_send_event.is_set():
|
||||||
|
return False
|
||||||
time.sleep_ms(50)
|
time.sleep_ms(50)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -1130,14 +1158,73 @@ class NetworkManager:
|
|||||||
hardware_manager.uart4g.write(b"\x1A")
|
hardware_manager.uart4g.write(b"\x1A")
|
||||||
with hardware_manager.at_client._q_lock:
|
with hardware_manager.at_client._q_lock:
|
||||||
hardware_manager.at_client._rx = b""
|
hardware_manager.at_client._rx = b""
|
||||||
r = hardware_manager.at_client.send("", "OK", 8000)
|
r = hardware_manager.at_client.send(
|
||||||
|
"", "OK", 8000, abort_event=self._terminal_send_event
|
||||||
|
)
|
||||||
if ("SEND OK" in r) or ("OK" in r) or ("+MIPSEND" in r):
|
if ("SEND OK" in r) or ("OK" in r) or ("+MIPSEND" in r):
|
||||||
return True
|
return True
|
||||||
|
if self._terminal_send_event.is_set():
|
||||||
|
return False
|
||||||
time.sleep_ms(50)
|
time.sleep_ms(50)
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
self._uart4g_lock.release()
|
self._uart4g_lock.release()
|
||||||
|
|
||||||
|
def _tcp_send_terminal_raw(self, data: bytes) -> bool:
|
||||||
|
if not self._tcp_connected:
|
||||||
|
return False
|
||||||
|
if self._network_type == "wifi":
|
||||||
|
return self._tcp_send_raw_via_wifi(data, max_retries=1)
|
||||||
|
if self._network_type != "4g":
|
||||||
|
return False
|
||||||
|
|
||||||
|
link_id = getattr(config, "TCP_LINK_ID", 0)
|
||||||
|
lock_timeout_sec = float(
|
||||||
|
getattr(config, "CHARGING_4G_UART_LOCK_TIMEOUT_SEC", 2.5)
|
||||||
|
)
|
||||||
|
prompt_timeout_ms = int(
|
||||||
|
getattr(config, "CHARGING_4G_PROMPT_TIMEOUT_MS", 1500)
|
||||||
|
)
|
||||||
|
confirm_timeout_ms = int(
|
||||||
|
getattr(config, "CHARGING_4G_CONFIRM_TIMEOUT_MS", 1000)
|
||||||
|
)
|
||||||
|
lock_start_ms = time.ticks_ms()
|
||||||
|
if not self._uart4g_lock.acquire(timeout=max(0.0, lock_timeout_sec)):
|
||||||
|
self.logger.warning(
|
||||||
|
f"[CHARGE-4G] uart_lock timeout timeout_sec={lock_timeout_sec}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
lock_elapsed_ms = abs(time.ticks_diff(time.ticks_ms(), lock_start_ms))
|
||||||
|
cmd = f'AT+MIPSEND={link_id},{len(data)}'
|
||||||
|
prompt_start_ms = time.ticks_ms()
|
||||||
|
if ">" not in hardware_manager.at_client.send(
|
||||||
|
cmd, ">", max(0, prompt_timeout_ms)):
|
||||||
|
prompt_elapsed_ms = abs(time.ticks_diff(time.ticks_ms(), prompt_start_ms))
|
||||||
|
self.logger.warning(
|
||||||
|
f"[CHARGE-4G] prompt failed lock_ms={lock_elapsed_ms} "
|
||||||
|
f"prompt_ms={prompt_elapsed_ms}"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
prompt_elapsed_ms = abs(time.ticks_diff(time.ticks_ms(), prompt_start_ms))
|
||||||
|
confirm_start_ms = time.ticks_ms()
|
||||||
|
r = hardware_manager.at_client.send_raw_and_wait(
|
||||||
|
data,
|
||||||
|
expect="OK",
|
||||||
|
timeout_ms=max(0, confirm_timeout_ms),
|
||||||
|
suffix=b"\x1A",
|
||||||
|
)
|
||||||
|
confirm_elapsed_ms = abs(time.ticks_diff(time.ticks_ms(), confirm_start_ms))
|
||||||
|
sent = ("SEND OK" in r) or ("OK" in r) or ("+MIPSEND" in r)
|
||||||
|
self.logger.warning(
|
||||||
|
f"[CHARGE-4G] send_done lock_ms={lock_elapsed_ms} "
|
||||||
|
f"prompt_ms={prompt_elapsed_ms} confirm_ms={confirm_elapsed_ms} "
|
||||||
|
f"sent={sent}"
|
||||||
|
)
|
||||||
|
return sent
|
||||||
|
finally:
|
||||||
|
self._uart4g_lock.release()
|
||||||
|
|
||||||
def _configure_ssl_before_connect(self, link_id: int) -> bool:
|
def _configure_ssl_before_connect(self, link_id: int) -> bool:
|
||||||
"""按手册:MSSLCFG(auth) -> (可选) MSSLCERTWR -> MSSLCFG(cert) -> MIPCFG(ssl)"""
|
"""按手册:MSSLCFG(auth) -> (可选) MSSLCERTWR -> MSSLCFG(cert) -> MIPCFG(ssl)"""
|
||||||
ssl_id = getattr(config, "SSL_ID", 1)
|
ssl_id = getattr(config, "SSL_ID", 1)
|
||||||
@@ -1874,12 +1961,25 @@ class NetworkManager:
|
|||||||
pending_cleared = False
|
pending_cleared = False
|
||||||
last_heartbeat_ack_time = time.ticks_ms()
|
last_heartbeat_ack_time = time.ticks_ms()
|
||||||
last_heartbeat_send_time = time.ticks_ms()
|
last_heartbeat_send_time = time.ticks_ms()
|
||||||
|
last_wifi_sta_check_time = time.ticks_ms()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
# 如果底层连接已断开,尽快跳出内层循环触发重连/重选网络
|
# 如果底层连接已断开,尽快跳出内层循环触发重连/重选网络
|
||||||
if not self._tcp_connected:
|
if not self._tcp_connected:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if self._network_type == "wifi":
|
||||||
|
now_ms = time.ticks_ms()
|
||||||
|
if abs(time.ticks_diff(now_ms, last_wifi_sta_check_time)) >= 1000:
|
||||||
|
last_wifi_sta_check_time = now_ms
|
||||||
|
if not wifi_manager.is_sta_associated():
|
||||||
|
self.logger.warning(
|
||||||
|
"[WIFI-TCP] STA disconnected; leave WiFi session and reselect network"
|
||||||
|
)
|
||||||
|
wifi_manager.disconnect_wifi()
|
||||||
|
self._tcp_connected = False
|
||||||
|
break
|
||||||
|
|
||||||
# OTA 期间暂停 TCP 活动
|
# OTA 期间暂停 TCP 活动
|
||||||
try:
|
try:
|
||||||
from ota_manager import ota_manager
|
from ota_manager import ota_manager
|
||||||
@@ -2312,8 +2412,23 @@ class NetworkManager:
|
|||||||
if item:
|
if item:
|
||||||
msg_type, data_dict = item[:2]
|
msg_type, data_dict = item[:2]
|
||||||
sent_event = item[2] if len(item) > 2 else None
|
sent_event = item[2] if len(item) > 2 else None
|
||||||
|
item_is_terminal = len(item) > 3 and item[3] == "terminal"
|
||||||
|
terminal_result = item[4] if item_is_terminal and len(item) > 4 else None
|
||||||
pkt = self._netcore.make_packet(msg_type, data_dict)
|
pkt = self._netcore.make_packet(msg_type, data_dict)
|
||||||
if not self.tcp_send_raw(pkt):
|
send_ok = (
|
||||||
|
self._tcp_send_terminal_raw(pkt)
|
||||||
|
if item_is_terminal
|
||||||
|
else self.tcp_send_raw(pkt)
|
||||||
|
)
|
||||||
|
if not send_ok:
|
||||||
|
if item_is_terminal:
|
||||||
|
if terminal_result is not None:
|
||||||
|
terminal_result["sent"] = False
|
||||||
|
if sent_event is not None:
|
||||||
|
sent_event.set()
|
||||||
|
break
|
||||||
|
if self._terminal_send_event.is_set():
|
||||||
|
continue
|
||||||
# 发送失败:将消息放回队首(队列满则丢弃)
|
# 发送失败:将消息放回队首(队列满则丢弃)
|
||||||
with self.get_queue_lock():
|
with self.get_queue_lock():
|
||||||
if item_is_high:
|
if item_is_high:
|
||||||
@@ -2329,6 +2444,8 @@ class NetworkManager:
|
|||||||
pass
|
pass
|
||||||
break
|
break
|
||||||
if sent_event is not None:
|
if sent_event is not None:
|
||||||
|
if terminal_result is not None:
|
||||||
|
terminal_result["sent"] = True
|
||||||
sent_event.set()
|
sent_event.set()
|
||||||
|
|
||||||
# 发送激光校准结果
|
# 发送激光校准结果
|
||||||
|
|||||||
@@ -179,6 +179,11 @@ def charging_shutdown_monitor():
|
|||||||
|
|
||||||
if current_ma < -abs(threshold_ma):
|
if current_ma < -abs(threshold_ma):
|
||||||
confirm_count += 1
|
confirm_count += 1
|
||||||
|
if logger:
|
||||||
|
logger.warning(
|
||||||
|
f"[CHARGE-TIMING] sample tick_ms={maix_time.ticks_ms()} "
|
||||||
|
f"current={current_ma:.1f}mA confirm={confirm_count}/{confirm_required}"
|
||||||
|
)
|
||||||
if logger:
|
if logger:
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[CHARGE] INA226 充电电流 {current_ma:.1f}mA "
|
f"[CHARGE] INA226 充电电流 {current_ma:.1f}mA "
|
||||||
@@ -209,12 +214,30 @@ def charging_shutdown_monitor():
|
|||||||
0,
|
0,
|
||||||
int(getattr(config, "CHARGING_NOTIFY_TIMEOUT_MS", 30000)),
|
int(getattr(config, "CHARGING_NOTIFY_TIMEOUT_MS", 30000)),
|
||||||
)
|
)
|
||||||
notification_sent = network_manager.safe_enqueue_and_wait(
|
notify_start_ms = maix_time.ticks_ms()
|
||||||
|
if logger:
|
||||||
|
logger.warning(
|
||||||
|
f"[CHARGE-TIMING] enqueue_start tick_ms={notify_start_ms} "
|
||||||
|
f"network={network_manager.network_type} "
|
||||||
|
f"tcp_connected={network_manager.tcp_connected} "
|
||||||
|
f"timeout_ms={notify_timeout_ms}"
|
||||||
|
)
|
||||||
|
notification_sent = network_manager.safe_terminal_send_and_wait(
|
||||||
{"poweroff": "充电中"},
|
{"poweroff": "充电中"},
|
||||||
2,
|
2,
|
||||||
high=True,
|
|
||||||
timeout_ms=notify_timeout_ms,
|
timeout_ms=notify_timeout_ms,
|
||||||
)
|
)
|
||||||
|
notify_end_ms = maix_time.ticks_ms()
|
||||||
|
notify_elapsed_ms = abs(
|
||||||
|
maix_time.ticks_diff(notify_end_ms, notify_start_ms)
|
||||||
|
)
|
||||||
|
if logger:
|
||||||
|
logger.warning(
|
||||||
|
f"[CHARGE-TIMING] enqueue_done tick_ms={notify_end_ms} "
|
||||||
|
f"elapsed_ms={notify_elapsed_ms} sent={bool(notification_sent)} "
|
||||||
|
f"network={network_manager.network_type} "
|
||||||
|
f"tcp_connected={network_manager.tcp_connected}"
|
||||||
|
)
|
||||||
if notification_sent:
|
if notification_sent:
|
||||||
if logger:
|
if logger:
|
||||||
logger.info("[CHARGE] 充电状态已发送到服务器")
|
logger.info("[CHARGE] 充电状态已发送到服务器")
|
||||||
|
|||||||
Binary file not shown.
@@ -36,3 +36,4 @@
|
|||||||
# 2.15.24 空改测试
|
# 2.15.24 空改测试
|
||||||
# 2.15.25 修复整合后关机失败和ota格式更新问题
|
# 2.15.25 修复整合后关机失败和ota格式更新问题
|
||||||
# 2.15.26
|
# 2.15.26
|
||||||
|
# 2.15.33 26-8-12 14:03 修改充4g电关机时间 修复切换网络卡住bug
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@
|
|||||||
应用版本号
|
应用版本号
|
||||||
每次 OTA 更新时,只需要更新这个文件中的版本号
|
每次 OTA 更新时,只需要更新这个文件中的版本号
|
||||||
"""
|
"""
|
||||||
VERSION = '2.15.31'
|
VERSION = '2.15.33'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -549,15 +549,20 @@ class WiFiManager:
|
|||||||
on_poor_quality_callback: WiFi质量差时的回调函数
|
on_poor_quality_callback: WiFi质量差时的回调函数
|
||||||
"""
|
"""
|
||||||
with self._wifi_quality_lock:
|
with self._wifi_quality_lock:
|
||||||
if self._wifi_quality_monitor_thread is not None and self._wifi_quality_monitor_thread.is_alive():
|
current_thread = self._wifi_quality_monitor_thread
|
||||||
|
current_stop_event = self._wifi_quality_stop_event
|
||||||
|
if (current_thread is not None and current_thread.is_alive()
|
||||||
|
and not current_stop_event.is_set()):
|
||||||
self.logger.warning("[WiFi Monitor] 监测线程已在运行")
|
self.logger.warning("[WiFi Monitor] 监测线程已在运行")
|
||||||
return
|
return
|
||||||
|
|
||||||
self._network_type_callback = network_type_callback
|
self._network_type_callback = network_type_callback
|
||||||
self._on_poor_quality_callback = on_poor_quality_callback
|
self._on_poor_quality_callback = on_poor_quality_callback
|
||||||
self._wifi_quality_stop_event.clear()
|
stop_event = threading.Event()
|
||||||
|
self._wifi_quality_stop_event = stop_event
|
||||||
self._wifi_quality_monitor_thread = threading.Thread(
|
self._wifi_quality_monitor_thread = threading.Thread(
|
||||||
target=self._quality_monitor_loop,
|
target=self._quality_monitor_loop,
|
||||||
|
args=(stop_event,),
|
||||||
daemon=True,
|
daemon=True,
|
||||||
name="wifi_quality_monitor"
|
name="wifi_quality_monitor"
|
||||||
)
|
)
|
||||||
@@ -568,13 +573,14 @@ class WiFiManager:
|
|||||||
"""停止 WiFi 质量监测线程"""
|
"""停止 WiFi 质量监测线程"""
|
||||||
with self._wifi_quality_lock:
|
with self._wifi_quality_lock:
|
||||||
t = self._wifi_quality_monitor_thread
|
t = self._wifi_quality_monitor_thread
|
||||||
|
stop_event = self._wifi_quality_stop_event
|
||||||
if t is None:
|
if t is None:
|
||||||
return
|
return
|
||||||
if not t.is_alive():
|
if not t.is_alive():
|
||||||
self._wifi_quality_monitor_thread = None
|
self._wifi_quality_monitor_thread = None
|
||||||
return
|
return
|
||||||
|
|
||||||
self._wifi_quality_stop_event.set()
|
stop_event.set()
|
||||||
try:
|
try:
|
||||||
t.join(timeout=2.0)
|
t.join(timeout=2.0)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -588,12 +594,12 @@ class WiFiManager:
|
|||||||
self._wifi_quality_monitor_thread = None
|
self._wifi_quality_monitor_thread = None
|
||||||
self.logger.info("[WiFi Monitor] 已停止后台监测线程")
|
self.logger.info("[WiFi Monitor] 已停止后台监测线程")
|
||||||
|
|
||||||
def _quality_monitor_loop(self):
|
def _quality_monitor_loop(self, stop_event):
|
||||||
"""
|
"""
|
||||||
WiFi 质量监测循环(后台线程)
|
WiFi 质量监测循环(后台线程)
|
||||||
每 5 秒检查 STA 关联状态和 RSSI,发现断链或质量差则触发切换
|
每 5 秒检查 STA 关联状态和 RSSI,发现断链或质量差则触发切换
|
||||||
"""
|
"""
|
||||||
while not self._wifi_quality_stop_event.is_set():
|
while not stop_event.is_set():
|
||||||
try:
|
try:
|
||||||
# 只在 WiFi 连接时才测量
|
# 只在 WiFi 连接时才测量
|
||||||
network_type = self._network_type_callback()
|
network_type = self._network_type_callback()
|
||||||
@@ -631,7 +637,8 @@ class WiFiManager:
|
|||||||
self.logger.warning("[WiFi Monitor] 质量差,切换前快速重试 2 次(每次间隔1秒)")
|
self.logger.warning("[WiFi Monitor] 质量差,切换前快速重试 2 次(每次间隔1秒)")
|
||||||
|
|
||||||
for retry_idx in range(2):
|
for retry_idx in range(2):
|
||||||
time.sleep_ms(1000)
|
if stop_event.wait(1.0):
|
||||||
|
return
|
||||||
reachable2 = self.is_sta_associated()
|
reachable2 = self.is_sta_associated()
|
||||||
rtt2 = None
|
rtt2 = None
|
||||||
rssi2 = self._get_wifi_rssi_dbm()
|
rssi2 = self._get_wifi_rssi_dbm()
|
||||||
@@ -660,7 +667,7 @@ class WiFiManager:
|
|||||||
self._on_poor_quality_callback()
|
self._on_poor_quality_callback()
|
||||||
|
|
||||||
# 休眠 5 秒
|
# 休眠 5 秒
|
||||||
time.sleep(5)
|
stop_event.wait(5.0)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"[WiFi Monitor] 监测异常:{e}")
|
self.logger.error(f"[WiFi Monitor] 监测异常:{e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user