refind logger
This commit is contained in:
275
network.py
275
network.py
@@ -55,11 +55,15 @@ class NetworkManager:
|
||||
self._wifi_socket_lock = threading.Lock()
|
||||
self._prefer_wifi = True # 是否优先使用WiFi
|
||||
self._wifi_recv_buffer = b"" # WiFi接收缓冲区
|
||||
|
||||
self._initialized = True
|
||||
|
||||
# ==================== 状态访问(只读属性)====================
|
||||
|
||||
@property
|
||||
def logger(self):
|
||||
"""获取 logger 对象"""
|
||||
return logger_manager.logger
|
||||
|
||||
@property
|
||||
def tcp_connected(self):
|
||||
"""TCP连接状态"""
|
||||
@@ -162,17 +166,13 @@ class NetworkManager:
|
||||
with open("/device_key", "r") as f:
|
||||
device_id = f.read().strip()
|
||||
if device_id:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.debug(f"[INFO] 从 /device_key 读取到 DEVICE_ID: {device_id}")
|
||||
self.logger.debug(f"[INFO] 从 /device_key 读取到 DEVICE_ID: {device_id}")
|
||||
# 设置内部状态
|
||||
self._device_id = device_id
|
||||
self._password = device_id + "."
|
||||
return device_id
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[ERROR] 无法读取 /device_key: {e}")
|
||||
self.logger.error(f"[ERROR] 无法读取 /device_key: {e}")
|
||||
|
||||
# 使用默认值
|
||||
default_id = "DEFAULT_DEVICE_ID"
|
||||
@@ -246,18 +246,14 @@ class NetworkManager:
|
||||
if ip:
|
||||
self._wifi_connected = True
|
||||
self._wifi_ip = ip
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.info(f"[WIFI] 已连接,IP: {ip}")
|
||||
self.logger.info(f"[WIFI] 已连接,IP: {ip}")
|
||||
return ip, None
|
||||
std_time.sleep(1)
|
||||
|
||||
return None, "Timeout: No IP obtained"
|
||||
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[WIFI] 连接失败: {e}")
|
||||
self.logger.error(f"[WIFI] 连接失败: {e}")
|
||||
return None, f"Exception: {str(e)}"
|
||||
|
||||
def is_server_reachable(self, host, port=80, timeout=5):
|
||||
@@ -270,9 +266,7 @@ class NetworkManager:
|
||||
s.close()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.warning(f"[NET] 无法连接 {host}:{port} - {e}")
|
||||
self.logger.warning(f"[NET] 无法连接 {host}:{port} - {e}")
|
||||
return False
|
||||
|
||||
# ==================== 网络选择策略 ====================
|
||||
@@ -290,31 +284,25 @@ class NetworkManager:
|
||||
if prefer_wifi is None:
|
||||
prefer_wifi = self._prefer_wifi
|
||||
|
||||
logger = logger_manager.logger
|
||||
|
||||
# 策略1:如果指定优先WiFi,且WiFi可用,使用WiFi
|
||||
if prefer_wifi and self.is_wifi_connected():
|
||||
# 检查WiFi是否能连接到服务器
|
||||
if self.is_server_reachable(config.SERVER_IP, config.SERVER_PORT, timeout=3):
|
||||
self._network_type = "wifi"
|
||||
if logger:
|
||||
logger.info(f"[NET] 选择WiFi网络,IP: {self._wifi_ip}")
|
||||
self.logger.info(f"[NET] 选择WiFi网络,IP: {self._wifi_ip}")
|
||||
return "wifi"
|
||||
else:
|
||||
if logger:
|
||||
logger.warning("[NET] WiFi已连接但无法访问服务器,尝试4G")
|
||||
self.logger.warning("[NET] WiFi已连接但无法访问服务器,尝试4G")
|
||||
|
||||
# 策略2:如果WiFi可用,使用WiFi
|
||||
if self.is_wifi_connected():
|
||||
if self.is_server_reachable(config.SERVER_IP, config.SERVER_PORT, timeout=3):
|
||||
self._network_type = "wifi"
|
||||
if logger:
|
||||
logger.info(f"[NET] 选择WiFi网络,IP: {self._wifi_ip}")
|
||||
self.logger.info(f"[NET] 选择WiFi网络,IP: {self._wifi_ip}")
|
||||
return "wifi"
|
||||
|
||||
# 策略3:回退到4G
|
||||
if logger:
|
||||
logger.info("[NET] WiFi不可用或无法连接服务器,使用4G网络")
|
||||
self.logger.info("[NET] WiFi不可用或无法连接服务器,使用4G网络")
|
||||
self._network_type = "4g"
|
||||
return "4g"
|
||||
|
||||
@@ -362,9 +350,7 @@ class NetworkManager:
|
||||
if not network_type:
|
||||
return False
|
||||
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.info(f"连接到服务器(使用{network_type.upper()})...")
|
||||
self.logger.info(f"连接到服务器,使用{network_type.upper()}...")
|
||||
|
||||
# 根据网络类型建立TCP连接
|
||||
if network_type == "wifi":
|
||||
@@ -389,15 +375,11 @@ class NetworkManager:
|
||||
self._wifi_socket.setblocking(False)
|
||||
|
||||
self._tcp_connected = True
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.info("[WIFI-TCP] TCP连接已建立")
|
||||
self.logger.info("[WIFI-TCP] TCP连接已建立")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[WIFI-TCP] 连接失败: {e}")
|
||||
self.logger.error(f"[WIFI-TCP] 连接失败: {e}")
|
||||
|
||||
if self._wifi_socket:
|
||||
try:
|
||||
@@ -409,16 +391,30 @@ class NetworkManager:
|
||||
return False
|
||||
|
||||
def _connect_tcp_via_4g(self):
|
||||
"""通过4G模块建立TCP连接"""
|
||||
"""通过4G模块建立TCP连接(支持按手册绑定 SSL)"""
|
||||
link_id = getattr(config, "TCP_LINK_ID", 0)
|
||||
use_ssl = getattr(config, "USE_TCP_SSL", False)
|
||||
|
||||
host = config.SERVER_IP
|
||||
port = getattr(config, "TCP_SSL_PORT", 443) if use_ssl else config.SERVER_PORT
|
||||
tail = getattr(config, "MIPOPEN_TAIL", "")
|
||||
with self.get_uart_lock():
|
||||
hardware_manager.at_client.send("AT+MIPCLOSE=0", "OK", 1000)
|
||||
res = hardware_manager.at_client.send(f'AT+MIPOPEN=0,"TCP","{config.SERVER_IP}",{config.SERVER_PORT}', "+MIPOPEN", 8000)
|
||||
if "+MIPOPEN: 0,0" in res:
|
||||
resp = hardware_manager.at_client.send(f"AT+MIPCLOSE={link_id}", "OK", 1000)
|
||||
self.logger.info(f"[4G-TCP] AT+MIPCLOSE={link_id} response: {resp}")
|
||||
|
||||
if use_ssl:
|
||||
ok = self._configure_ssl_before_connect(link_id)
|
||||
if not ok:
|
||||
return False
|
||||
|
||||
# 按手册:AT+MIPOPEN=1,"TCP","host",443,,0
|
||||
# cmd = f'AT+MIPOPEN={link_id},"TCP","{host}",{port}{tail}'
|
||||
cmd = f'AT+MIPOPEN={link_id},"TCP","{host}",{port}'
|
||||
res = hardware_manager.at_client.send(cmd, "+MIPOPEN", 8000)
|
||||
self.logger.info(f"[4G-TCP] {cmd} response: {res}")
|
||||
if f"+MIPOPEN: {link_id},0" in res:
|
||||
self._tcp_connected = True
|
||||
return True
|
||||
else:
|
||||
logger = logger_manager.logger
|
||||
logger.error(f"[4G-TCP] 连接失败: {res}")
|
||||
return False
|
||||
|
||||
def _check_wifi_connection(self):
|
||||
@@ -442,9 +438,7 @@ class NetworkManager:
|
||||
def disconnect_server(self):
|
||||
"""断开TCP连接"""
|
||||
if self._tcp_connected:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.info("与服务器断开链接")
|
||||
self.logger.info("与服务器断开链接")
|
||||
|
||||
if self._network_type == "wifi":
|
||||
self._disconnect_tcp_via_wifi()
|
||||
@@ -465,9 +459,10 @@ class NetworkManager:
|
||||
self._wifi_socket = None
|
||||
|
||||
def _disconnect_tcp_via_4g(self):
|
||||
"""断开4G TCP连接"""
|
||||
link_id = getattr(config, "TCP_LINK_ID", 0)
|
||||
with self.get_uart_lock():
|
||||
hardware_manager.at_client.send("AT+MIPCLOSE=0", "OK", 1000)
|
||||
hardware_manager.at_client.send(f"AT+MIPCLOSE={link_id}", "OK", 1000)
|
||||
|
||||
|
||||
def tcp_send_raw(self, data: bytes, max_retries=2) -> bool:
|
||||
"""
|
||||
@@ -489,9 +484,7 @@ class NetworkManager:
|
||||
elif self._network_type == "4g":
|
||||
return self._tcp_send_raw_via_4g(data, max_retries)
|
||||
else:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error("[NET] 未选择网络类型,无法发送数据")
|
||||
self.logger.error("[NET] 未选择网络类型,无法发送数据")
|
||||
return False
|
||||
|
||||
def _tcp_send_raw_via_wifi(self, data: bytes, max_retries=2) -> bool:
|
||||
@@ -508,9 +501,7 @@ class NetworkManager:
|
||||
sent = self._wifi_socket.send(data[total_sent:])
|
||||
if sent == 0:
|
||||
# socket连接已断开
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.warning(f"[WIFI-TCP] 发送失败,socket已断开(尝试 {attempt+1}/{max_retries})")
|
||||
self.logger.warning(f"[WIFI-TCP] 发送失败,socket已断开(尝试 {attempt+1}/{max_retries})")
|
||||
break
|
||||
total_sent += sent
|
||||
|
||||
@@ -521,23 +512,19 @@ class NetworkManager:
|
||||
time.sleep_ms(50)
|
||||
|
||||
except OSError as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[WIFI-TCP] 发送异常: {e}(尝试 {attempt+1}/{max_retries})")
|
||||
self.logger.error(f"[WIFI-TCP] 发送异常: {e}(尝试 {attempt+1}/{max_retries})")
|
||||
time.sleep_ms(50)
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[WIFI-TCP] 未知错误: {e}(尝试 {attempt+1}/{max_retries})")
|
||||
self.logger.error(f"[WIFI-TCP] 未知错误: {e}(尝试 {attempt+1}/{max_retries})")
|
||||
time.sleep_ms(50)
|
||||
|
||||
return False
|
||||
|
||||
def _tcp_send_raw_via_4g(self, data: bytes, max_retries=2) -> bool:
|
||||
"""通过4G模块发送TCP数据"""
|
||||
link_id = getattr(config, "TCP_LINK_ID", 0)
|
||||
with self.get_uart_lock():
|
||||
for _ in range(max_retries):
|
||||
cmd = f'AT+MIPSEND=0,{len(data)}'
|
||||
cmd = f'AT+MIPSEND={link_id},{len(data)}'
|
||||
if ">" not in hardware_manager.at_client.send(cmd, ">", 2000):
|
||||
time.sleep_ms(50)
|
||||
continue
|
||||
@@ -551,15 +538,62 @@ class NetworkManager:
|
||||
total += n
|
||||
|
||||
hardware_manager.uart4g.write(b"\x1A")
|
||||
|
||||
r = hardware_manager.at_client.send("", "OK", 8000)
|
||||
if ("SEND OK" in r) or ("OK" in r) or ("+MIPSEND" in r):
|
||||
return True
|
||||
|
||||
time.sleep_ms(50)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def _configure_ssl_before_connect(self, link_id: int) -> bool:
|
||||
"""按手册:MSSLCFG(auth) -> (可选) MSSLCERTWR -> MSSLCFG(cert) -> MIPCFG(ssl)"""
|
||||
ssl_id = getattr(config, "SSL_ID", 1)
|
||||
auth_mode = getattr(config, "SSL_AUTH_MODE", 1)
|
||||
verify_mode = getattr(config, "SSL_VERIFY_MODE", 0)
|
||||
|
||||
# 1) 配置认证方式
|
||||
# r = hardware_manager.at_client.send(f'AT+MSSLCFG="auth",{ssl_id},{auth_mode}', "OK", 3000)
|
||||
r = hardware_manager.at_client.send(f'AT+MSSLCFG="auth",{ssl_id},0', "OK", 3000)
|
||||
self.logger.info(f"[4G-TCP] AT+MSSLCFG=\"auth\",{ssl_id},0 response: {r}")
|
||||
if "OK" not in r:
|
||||
return False
|
||||
|
||||
# 2) 写入根证书(只有 verify_mode=1 才需要)
|
||||
# if verify_mode == 1:
|
||||
if False:
|
||||
cert_filename = getattr(config, "SSL_CERT_FILENAME", None)
|
||||
cert_path = getattr(config, "SSL_CERT_PATH", None)
|
||||
if not cert_filename or not cert_path:
|
||||
return False
|
||||
|
||||
# 读取证书文件(设备侧路径)
|
||||
with open(cert_path, "rb") as f:
|
||||
cert_data = f.read()
|
||||
|
||||
# 按手册:AT+MSSLCERTWR="file",0,size -> 等待 ">" -> 写入证书内容 -> 等 OK
|
||||
r = hardware_manager.at_client.send(f'AT+MSSLCERTWR="{cert_filename}",0,{len(cert_data)}', ">", 5000)
|
||||
if ">" not in r:
|
||||
return False
|
||||
|
||||
# 直接写原始字节,不要额外拼 \r\n
|
||||
hardware_manager.uart4g.write(cert_data)
|
||||
|
||||
r = hardware_manager.at_client.send("", "OK", 8000)
|
||||
if "OK" not in r:
|
||||
return False
|
||||
|
||||
# 3) 引用根证书
|
||||
r = hardware_manager.at_client.send(f'AT+MSSLCFG="cert",{ssl_id},"{cert_filename}"', "OK", 3000)
|
||||
if "OK" not in r:
|
||||
return False
|
||||
|
||||
# 4) 绑定 TCP 通道到 ssl_id,并启用
|
||||
r = hardware_manager.at_client.send(f'AT+MIPCFG="ssl",{link_id},{ssl_id},1', "OK", 3000)
|
||||
self.logger.info(f"[4G-TCP] AT+MIPCFG=\"ssl\",{link_id},{ssl_id},1 response: {r}")
|
||||
if "OK" not in r:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def receive_tcp_data_via_wifi(self, timeout_ms=100):
|
||||
"""
|
||||
通过WiFi接收TCP数据
|
||||
@@ -586,9 +620,7 @@ class NetworkManager:
|
||||
return b""
|
||||
except OSError as e:
|
||||
# socket错误(连接断开等)
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.warning(f"[WIFI-TCP] 接收数据失败: {e}")
|
||||
self.logger.warning(f"[WIFI-TCP] 接收数据失败: {e}")
|
||||
|
||||
# 关闭socket
|
||||
try:
|
||||
@@ -600,9 +632,7 @@ class NetworkManager:
|
||||
|
||||
return b""
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[WIFI-TCP] 接收数据异常: {e}")
|
||||
self.logger.error(f"[WIFI-TCP] 接收数据异常: {e}")
|
||||
return b""
|
||||
|
||||
|
||||
@@ -615,9 +645,7 @@ class NetworkManager:
|
||||
|
||||
def send_http_cmd(self, cmd_str, timeout_ms=3000):
|
||||
"""发送 HTTP 相关 AT 指令(调试用)"""
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.debug(f"[HTTP AT] => {cmd_str}")
|
||||
self.logger.debug(f"[HTTP AT] => {cmd_str}")
|
||||
return hardware_manager.at_client.send(cmd_str, "OK", timeout_ms)
|
||||
|
||||
|
||||
@@ -644,9 +672,7 @@ class NetworkManager:
|
||||
import _thread
|
||||
from maix import camera
|
||||
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.info("[NET] TCP主线程启动")
|
||||
self.logger.info("[NET] TCP主线程启动")
|
||||
|
||||
send_hartbeat_fail_count = 0
|
||||
last_charging_check = 0
|
||||
@@ -666,9 +692,7 @@ class NetworkManager:
|
||||
time.sleep_ms(200)
|
||||
continue
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[NET] OTA检查异常: {e}")
|
||||
self.logger.error(f"[NET] OTA检查异常: {e}")
|
||||
time.sleep_ms(200)
|
||||
continue
|
||||
|
||||
@@ -690,8 +714,7 @@ class NetworkManager:
|
||||
time.sleep_ms(2000)
|
||||
continue
|
||||
|
||||
if logger:
|
||||
logger.info("➡️ 登录包已发送,等待确认...")
|
||||
self.logger.info("➡️ 登录包已发送,等待确认...")
|
||||
logged_in = False
|
||||
pending_cleared = False
|
||||
last_heartbeat_ack_time = time.ticks_ms()
|
||||
@@ -705,9 +728,7 @@ class NetworkManager:
|
||||
time.sleep_ms(200)
|
||||
continue
|
||||
except Exception as e:
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[NET] OTA检查异常: {e}")
|
||||
self.logger.error(f"[NET] OTA检查异常: {e}")
|
||||
time.sleep_ms(200)
|
||||
continue
|
||||
|
||||
@@ -752,8 +773,7 @@ class NetworkManager:
|
||||
|
||||
if not logged_in:
|
||||
try:
|
||||
if logger:
|
||||
logger.debug(f"[TCP] rx link={link_id} len={len(payload)} head={payload[:12].hex()}")
|
||||
self.logger.debug(f"[TCP] rx link={link_id} len={len(payload)} head={payload[:12].hex()}")
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -764,8 +784,7 @@ class NetworkManager:
|
||||
if body and body.get("cmd") == 1 and body.get("data") == "登录成功":
|
||||
logged_in = True
|
||||
last_heartbeat_ack_time = time.ticks_ms()
|
||||
if logger:
|
||||
logger.info("登录成功")
|
||||
self.logger.info("登录成功")
|
||||
|
||||
# 检查 ota_pending.json
|
||||
try:
|
||||
@@ -777,19 +796,16 @@ class NetworkManager:
|
||||
except:
|
||||
pending_obj = {}
|
||||
self.safe_enqueue({"result": "ota_ok", "url": pending_obj.get("url", "")}, 2)
|
||||
if logger:
|
||||
logger.info("[OTA] 已上报 ota_ok,等待心跳确认后删除 pending")
|
||||
self.logger.info("[OTA] 已上报 ota_ok,等待心跳确认后删除 pending")
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[OTA] ota_ok 上报失败: {e}")
|
||||
self.logger.error(f"[OTA] ota_ok 上报失败: {e}")
|
||||
else:
|
||||
break
|
||||
|
||||
# 处理心跳 ACK
|
||||
elif logged_in and msg_type == 4:
|
||||
last_heartbeat_ack_time = time.ticks_ms()
|
||||
if logger:
|
||||
logger.debug("✅ 收到心跳确认")
|
||||
self.logger.debug("✅ 收到心跳确认")
|
||||
|
||||
# 处理命令40(分片下载)
|
||||
elif logged_in and msg_type == 40:
|
||||
@@ -806,8 +822,7 @@ class NetworkManager:
|
||||
self._raw_line_data.clear()
|
||||
self._raw_line_data.append(body)
|
||||
if len(self._raw_line_data) >= int(t):
|
||||
if logger:
|
||||
logger.info(f"下载完成")
|
||||
self.logger.info(f"下载完成")
|
||||
from ota_manager import ota_manager
|
||||
stock_array = list(map(lambda x: x.get('d'), self._raw_line_data))
|
||||
local_filename = config.LOCAL_FILENAME
|
||||
@@ -816,8 +831,7 @@ class NetworkManager:
|
||||
ota_manager.apply_ota_and_reboot(None, local_filename)
|
||||
else:
|
||||
self.safe_enqueue({'data':{'l': len(self._raw_line_data), 'v': v}, 'cmd': 41})
|
||||
if logger:
|
||||
logger.info(f"已下载{len(self._raw_line_data)} 全部:{t} 版本:{v}")
|
||||
self.logger.info(f"已下载{len(self._raw_line_data)} 全部:{t} 版本:{v}")
|
||||
|
||||
# 处理业务指令
|
||||
elif logged_in and isinstance(body, dict):
|
||||
@@ -843,8 +857,7 @@ class NetworkManager:
|
||||
battery_percent = voltage_to_percent(voltage)
|
||||
battery_data = {"battery": battery_percent, "voltage": round(voltage, 3)}
|
||||
self.safe_enqueue(battery_data, 2)
|
||||
if logger:
|
||||
logger.info(f"电量上报: {battery_percent}%")
|
||||
self.logger.info(f"电量上报: {battery_percent}%")
|
||||
elif inner_cmd == 5: # OTA 升级
|
||||
inner_data = data_obj.get("data", {}) if isinstance(data_obj, dict) else {}
|
||||
ssid = inner_data.get("ssid")
|
||||
@@ -853,8 +866,7 @@ class NetworkManager:
|
||||
mode = (inner_data.get("mode") or "").strip().lower()
|
||||
|
||||
if not ota_url:
|
||||
if logger:
|
||||
logger.error("ota missing_url")
|
||||
self.logger.error("ota missing_url")
|
||||
self.safe_enqueue({"result": "missing_url"}, 2)
|
||||
continue
|
||||
|
||||
@@ -865,17 +877,14 @@ class NetworkManager:
|
||||
|
||||
# 自动判断模式:如果没有明确指定,根据WiFi连接状态和凭证决定
|
||||
if mode not in ("4g", "wifi"):
|
||||
if logger:
|
||||
logger.info("ota missing mode, auto-detecting...")
|
||||
self.logger.info("ota missing mode, auto-detecting...")
|
||||
# 只有同时满足:WiFi已连接 且 提供了WiFi凭证,才使用WiFi
|
||||
if self.is_wifi_connected() and ssid and password:
|
||||
mode = "wifi"
|
||||
if logger:
|
||||
logger.info("ota auto-selected: wifi (WiFi connected and credentials provided)")
|
||||
self.logger.info("ota auto-selected: wifi (WiFi connected and credentials provided)")
|
||||
else:
|
||||
mode = "4g"
|
||||
if logger:
|
||||
logger.info("ota auto-selected: 4g (WiFi not available or no credentials)")
|
||||
self.logger.info("ota auto-selected: 4g (WiFi not available or no credentials)")
|
||||
|
||||
if mode == "4g":
|
||||
ota_manager._set_ota_url(ota_url) # 记录 OTA URL,供命令7使用
|
||||
@@ -883,8 +892,7 @@ class NetworkManager:
|
||||
_thread.start_new_thread(ota_manager.direct_ota_download_via_4g, (ota_url,))
|
||||
else: # mode == "wifi"
|
||||
if not ssid or not password:
|
||||
if logger:
|
||||
logger.error("ota wifi mode requires ssid and password")
|
||||
self.logger.error("ota wifi mode requires ssid and password")
|
||||
self.safe_enqueue({"result": "missing_ssid_or_password"}, 2)
|
||||
else:
|
||||
ota_manager._start_update_thread()
|
||||
@@ -914,20 +922,17 @@ class NetworkManager:
|
||||
# 如果 ota_manager.ota_url 为 None,需要从其他地方获取
|
||||
ota_url_to_use = ota_manager.ota_url
|
||||
if not ota_url_to_use:
|
||||
if logger:
|
||||
logger.error("[OTA] cmd=7 但 OTA_URL 未设置")
|
||||
self.logger.error("[OTA] cmd=7 但 OTA_URL 未设置")
|
||||
self.safe_enqueue({"result": "ota_failed", "reason": "ota_url_not_set"}, 2)
|
||||
else:
|
||||
ota_manager._start_update_thread()
|
||||
_thread.start_new_thread(ota_manager.direct_ota_download, (ota_url_to_use,))
|
||||
elif inner_cmd == 41:
|
||||
if logger:
|
||||
logger.info("[TEST] 收到TCP射箭触发命令")
|
||||
self.logger.info("[TEST] 收到TCP射箭触发命令")
|
||||
self._manual_trigger_flag = True
|
||||
self.safe_enqueue({"result": "trigger_ack"}, 2)
|
||||
elif inner_cmd == 42: # 关机命令
|
||||
if logger:
|
||||
logger.info("[SHUTDOWN] 收到TCP关机命令,准备关机...")
|
||||
self.logger.info("[SHUTDOWN] 收到TCP关机命令,准备关机...")
|
||||
self.safe_enqueue({"result": "shutdown_ack"}, 2)
|
||||
time.sleep_ms(1000)
|
||||
self.disconnect_server()
|
||||
@@ -975,22 +980,19 @@ class NetworkManager:
|
||||
if logged_in and current_time - last_heartbeat_send_time > config.HEARTBEAT_INTERVAL * 1000:
|
||||
vol_val = get_bus_voltage()
|
||||
if not self.tcp_send_raw(self.make_packet(4, {"vol": vol_val, "vol_per": voltage_to_percent(vol_val)})):
|
||||
if logger:
|
||||
logger.error("心跳发送失败")
|
||||
self.logger.error("心跳发送失败")
|
||||
time.sleep_ms(3000)
|
||||
send_hartbeat_fail_count += 1
|
||||
if send_hartbeat_fail_count >= 3:
|
||||
send_hartbeat_fail_count = 0
|
||||
if logger:
|
||||
logger.error("连续3次发送心跳失败,重连")
|
||||
self.logger.error("连续3次发送心跳失败,重连")
|
||||
break
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
send_hartbeat_fail_count = 0
|
||||
last_heartbeat_send_time = current_time
|
||||
if logger:
|
||||
logger.debug("心跳已发送")
|
||||
self.logger.debug("心跳已发送")
|
||||
|
||||
# 删除 pending 文件(心跳发送成功后)
|
||||
if not pending_cleared:
|
||||
@@ -1000,39 +1002,28 @@ class NetworkManager:
|
||||
try:
|
||||
os.remove(pending_path)
|
||||
pending_cleared = True
|
||||
if logger:
|
||||
logger.info("[OTA] 心跳发送成功,已删除 ota_pending.json")
|
||||
self.logger.info("[OTA] 心跳发送成功,已删除 ota_pending.json")
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[OTA] 删除 pending 文件失败: {e}")
|
||||
self.logger.error(f"[OTA] 删除 pending 文件失败: {e}")
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[OTA] 检查 pending 文件时出错: {e}")
|
||||
self.logger.error(f"[OTA] 检查 pending 文件时出错: {e}")
|
||||
|
||||
# 心跳超时重连
|
||||
if logged_in and current_time - last_heartbeat_ack_time > 1000*60*10:
|
||||
if logger:
|
||||
logger.error("十分钟无心跳ACK,重连")
|
||||
self.logger.error("十分钟无心跳ACK,重连")
|
||||
break
|
||||
|
||||
time.sleep_ms(50)
|
||||
|
||||
self._tcp_connected = False
|
||||
if logger:
|
||||
logger.error("连接异常,2秒后重连...")
|
||||
self.logger.error("连接异常,2秒后重连...")
|
||||
time.sleep_ms(2000)
|
||||
|
||||
except Exception as e:
|
||||
# TCP主循环的顶层异常捕获,防止线程静默退出
|
||||
logger = logger_manager.logger
|
||||
if logger:
|
||||
logger.error(f"[NET] TCP主循环异常: {e}")
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
else:
|
||||
print(f"[NET] TCP主循环异常: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
self.logger.error(f"[NET] TCP主循环异常: {e}")
|
||||
import traceback
|
||||
self.logger.error(traceback.format_exc())
|
||||
self._tcp_connected = False
|
||||
time.sleep_ms(5000) # 等待5秒后重试连接
|
||||
|
||||
|
||||
Reference in New Issue
Block a user