feat: 1.json换为pb 2.wifi、ota 优化
This commit is contained in:
@@ -13,7 +13,9 @@ from maix import camera, display, image, app, time, uart, pinmap, i2c
|
||||
from maix.peripheral import adc
|
||||
import _thread
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import shutil
|
||||
import time as wall_time
|
||||
|
||||
# 导入新模块
|
||||
@@ -126,7 +128,7 @@ def cmd_str():
|
||||
|
||||
# 1. 初始化日志系统(WARNING级别,不打印/写入INFO和DEBUG日志,提高执行流畅度)
|
||||
import logging
|
||||
logger_manager.init_logging(log_level=logging.WARNING)
|
||||
logger_manager.init_logging(log_level=logging.DEBUG)
|
||||
logger = logger_manager.logger
|
||||
|
||||
# 补充:因为初始化的时候,激光会亮,先关了它
|
||||
@@ -254,6 +256,55 @@ def cmd_str():
|
||||
# 4. 初始化设备ID(network_manager 内部会自动设置 device_id 和 password)
|
||||
network_manager.read_device_id()
|
||||
|
||||
# 4.1 检查是否有 OTA 待更新文件(从临时目录移动到实际目录)
|
||||
staging_dir = f"{config.APP_DIR}/ota_staging"
|
||||
if os.path.exists(staging_dir):
|
||||
try:
|
||||
moved_count = 0
|
||||
for root, dirs, files in os.walk(staging_dir):
|
||||
for f in files:
|
||||
src = os.path.join(root, f)
|
||||
rel = os.path.relpath(src, staging_dir)
|
||||
dest = os.path.join(config.APP_DIR, rel)
|
||||
dest_dir = os.path.dirname(dest)
|
||||
if dest_dir:
|
||||
try:
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
shutil.copy2(src, dest)
|
||||
moved_count += 1
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[OTA] 移动文件失败 {rel}: {e}")
|
||||
# 删除临时目录
|
||||
try:
|
||||
shutil.rmtree(staging_dir, ignore_errors=True)
|
||||
except:
|
||||
pass
|
||||
if logger:
|
||||
logger.info(f"[OTA] 已从临时目录更新 {moved_count} 个文件,重启应用...")
|
||||
# 清理硬件资源,然后重启应用
|
||||
try:
|
||||
laser_manager.turn_off_laser()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
camera_manager.release()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
os.sync()
|
||||
except:
|
||||
pass
|
||||
import sys
|
||||
os.execv(sys.executable, [sys.executable, os.path.join(config.APP_DIR, "main.py")])
|
||||
return
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[OTA] 处理临时目录失败: {e}")
|
||||
|
||||
# 5. 创建照片存储目录(如果启用图像保存或检测失败时强制保存)
|
||||
if config.SAVE_IMAGE_ENABLED or getattr(config, "SAVE_IMAGE_ON_FAILURE", False):
|
||||
photo_dir = config.PHOTO_DIR
|
||||
@@ -290,6 +341,7 @@ def cmd_str():
|
||||
trigger_adc_val = 0 # 触发时的气压值,气压需降回此值以下才能再次触发
|
||||
# 读取一次ADC初始值,防止开机时传感器已有压力导致误触发
|
||||
enable_check = True
|
||||
_should_reboot = False
|
||||
try:
|
||||
last_adc_val = hardware_manager.adc_obj.read()
|
||||
except Exception:
|
||||
@@ -345,6 +397,14 @@ def cmd_str():
|
||||
time.sleep_ms(250)
|
||||
continue
|
||||
|
||||
# OTA 完成后需要重启,从主循环退出(由启动时 staging 检测处理重启)
|
||||
if network_manager.ota_restart_pending:
|
||||
network_manager.ota_restart_pending = False
|
||||
_should_reboot = True
|
||||
if logger:
|
||||
logger.info("[MAIN] OTA重启标志已设置,退出主循环...")
|
||||
break
|
||||
|
||||
# 不在 OTA 状态下,检测是否空闲足够长,自动关机
|
||||
# print(f"[MAIN] 空闲时间: {hardware_manager.get_idle_time_in_sec() }秒")
|
||||
# print(f"配置关机时间:{config.AUTO_POWER_OFF_IN_SECONDS} 秒")
|
||||
@@ -430,10 +490,62 @@ def cmd_str():
|
||||
_flush_pressure_buf("exception")
|
||||
except:
|
||||
pass
|
||||
time.sleep_ms(1000) # 等待1秒后继续
|
||||
|
||||
|
||||
time.sleep_ms(1000) # 等待1秒后 continue
|
||||
|
||||
# 主循环退出后,如果是由 OTA 触发的,移动 staging 文件并重启应用
|
||||
if _should_reboot:
|
||||
staging_dir = f"{config.APP_DIR}/ota_staging"
|
||||
if os.path.exists(staging_dir):
|
||||
try:
|
||||
moved_count = 0
|
||||
for root, dirs, files in os.walk(staging_dir):
|
||||
for f in files:
|
||||
src = os.path.join(root, f)
|
||||
rel = os.path.relpath(src, staging_dir)
|
||||
dest = os.path.join(config.APP_DIR, rel)
|
||||
dest_dir = os.path.dirname(dest)
|
||||
if dest_dir:
|
||||
try:
|
||||
os.makedirs(dest_dir, exist_ok=True)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
shutil.copy2(src, dest)
|
||||
moved_count += 1
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[OTA] 移动文件失败 {rel}: {e}")
|
||||
try:
|
||||
shutil.rmtree(staging_dir, ignore_errors=True)
|
||||
except:
|
||||
pass
|
||||
if logger:
|
||||
logger.info(f"[MAIN] OTA 更新完成,已应用 {moved_count} 个文件,重启应用...")
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[OTA] 处理 staging 目录失败: {e}")
|
||||
else:
|
||||
if logger:
|
||||
logger.info("[MAIN] OTA 更新完成,重启应用...")
|
||||
# 清理硬件资源,然后重启应用(不重启设备)
|
||||
try:
|
||||
laser_manager.turn_off_laser()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
camera_manager.release()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
hardware_manager.stop_idle_timer()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
os.sync()
|
||||
except:
|
||||
pass
|
||||
import sys
|
||||
os.execv(sys.executable, [sys.executable, os.path.join(config.APP_DIR, "main.py")])
|
||||
|
||||
|
||||
# 主程序入口
|
||||
|
||||
Reference in New Issue
Block a user