2.15.23
This commit is contained in:
+120
-3
@@ -67,6 +67,7 @@ class NetworkManager:
|
||||
self._queue_lock = threading.Lock()
|
||||
self._send_event = threading.Event()
|
||||
self._uart4g_lock = threading.Lock()
|
||||
self._terminal_send_event = threading.Event()
|
||||
self._device_id = None
|
||||
self._password = None
|
||||
self._raw_line_data = []
|
||||
@@ -676,7 +677,7 @@ class NetworkManager:
|
||||
except OSError:
|
||||
pass
|
||||
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")
|
||||
if self.logger:
|
||||
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)
|
||||
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):
|
||||
"""
|
||||
连接到服务器(自动选择WiFi或4G)
|
||||
@@ -1114,8 +1138,12 @@ class NetworkManager:
|
||||
return False
|
||||
try:
|
||||
for _ in range(max_retries):
|
||||
if self._terminal_send_event.is_set():
|
||||
return False
|
||||
cmd = f'AT+MIPSEND={link_id},{len(data)}'
|
||||
if ">" not in hardware_manager.at_client.send(cmd, ">", 2000):
|
||||
if self._terminal_send_event.is_set():
|
||||
return False
|
||||
time.sleep_ms(50)
|
||||
continue
|
||||
|
||||
@@ -1130,14 +1158,73 @@ class NetworkManager:
|
||||
hardware_manager.uart4g.write(b"\x1A")
|
||||
with hardware_manager.at_client._q_lock:
|
||||
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):
|
||||
return True
|
||||
if self._terminal_send_event.is_set():
|
||||
return False
|
||||
time.sleep_ms(50)
|
||||
return False
|
||||
finally:
|
||||
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:
|
||||
"""按手册:MSSLCFG(auth) -> (可选) MSSLCERTWR -> MSSLCFG(cert) -> MIPCFG(ssl)"""
|
||||
ssl_id = getattr(config, "SSL_ID", 1)
|
||||
@@ -1874,12 +1961,25 @@ class NetworkManager:
|
||||
pending_cleared = False
|
||||
last_heartbeat_ack_time = time.ticks_ms()
|
||||
last_heartbeat_send_time = time.ticks_ms()
|
||||
last_wifi_sta_check_time = time.ticks_ms()
|
||||
|
||||
while True:
|
||||
# 如果底层连接已断开,尽快跳出内层循环触发重连/重选网络
|
||||
if not self._tcp_connected:
|
||||
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 活动
|
||||
try:
|
||||
from ota_manager import ota_manager
|
||||
@@ -2312,8 +2412,23 @@ class NetworkManager:
|
||||
if item:
|
||||
msg_type, data_dict = item[:2]
|
||||
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)
|
||||
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():
|
||||
if item_is_high:
|
||||
@@ -2329,6 +2444,8 @@ class NetworkManager:
|
||||
pass
|
||||
break
|
||||
if sent_event is not None:
|
||||
if terminal_result is not None:
|
||||
terminal_result["sent"] = True
|
||||
sent_event.set()
|
||||
|
||||
# 发送激光校准结果
|
||||
|
||||
Reference in New Issue
Block a user