fix: 检测充电关机
This commit is contained in:
@@ -22,7 +22,7 @@ from version import VERSION
|
||||
# from logger import init_logging, get_logger, stop_logging
|
||||
from logger_manager import logger_manager
|
||||
from time_sync import sync_system_time_from_4g
|
||||
from power import charging_shutdown_monitor, init_ina226
|
||||
from power import init_ina226
|
||||
from laser_manager import laser_manager
|
||||
from vision import start_save_shot_worker
|
||||
from network import network_manager
|
||||
@@ -125,13 +125,6 @@ def cmd_str():
|
||||
logger_manager.init_logging(log_level=logging.WARNING)
|
||||
logger = logger_manager.logger
|
||||
|
||||
# 充电关机独立读取 INA226,不依赖 TCP 连接或心跳流程。
|
||||
try:
|
||||
_thread.start_new_thread(charging_shutdown_monitor, ())
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[CHARGE] 启动独立监测线程失败: {e}")
|
||||
|
||||
# 补充:因为初始化的时候,激光会亮,先关了它
|
||||
# laser_manager.turn_off_laser()
|
||||
|
||||
|
||||
+12
-2
@@ -18,7 +18,7 @@ import socket
|
||||
import config
|
||||
|
||||
from hardware import hardware_manager
|
||||
from power import get_bus_voltage, voltage_to_percent
|
||||
from power import get_bus_voltage, voltage_to_percent, is_charging
|
||||
from logger_manager import logger_manager
|
||||
from wifi import wifi_manager
|
||||
import subprocess
|
||||
@@ -2256,7 +2256,17 @@ class NetworkManager:
|
||||
"netType": self.network_type,
|
||||
}
|
||||
self.safe_enqueue(battery_data, 2)
|
||||
self.logger.info(f"电量上报: {battery_percent}%")
|
||||
self.logger.info(f"电量上报: {battery_percent}% 充电: {is_charging()}")
|
||||
if is_charging():
|
||||
self.safe_enqueue(
|
||||
{
|
||||
"cmd": 700,
|
||||
},
|
||||
2,
|
||||
)
|
||||
elif inner_cmd == 700:
|
||||
self.logger.warning("服务器下发关机!!!")
|
||||
exit(-1)
|
||||
elif inner_cmd == 5: # OTA 升级
|
||||
inner_data = data_obj.get("data", {}) if isinstance(data_obj, dict) else {}
|
||||
ssid = inner_data.get("ssid")
|
||||
|
||||
@@ -142,138 +142,6 @@ def is_charging(threshold_ma=10.0):
|
||||
return False
|
||||
|
||||
|
||||
def charging_shutdown_monitor():
|
||||
"""独立监测 INA226;连续确认充电后通知服务器并退出应用。"""
|
||||
logger = logger_manager.logger
|
||||
shutdown_enabled = bool(getattr(config, "CHARGING_SHUTDOWN_ENABLED", False))
|
||||
diagnostic_enabled = bool(getattr(config, "CHARGING_DIAGNOSTIC_LOG_ENABLED", False))
|
||||
if not shutdown_enabled and not diagnostic_enabled:
|
||||
if logger:
|
||||
logger.info("[CHARGE] 充电退出监测已禁用")
|
||||
return
|
||||
|
||||
interval_ms = max(100, int(getattr(config, "CHARGING_CHECK_INTERVAL_MS", 5000)))
|
||||
threshold_ma = float(getattr(config, "CHARGING_CURRENT_THRESHOLD_MA", 10.0))
|
||||
confirm_required = max(1, int(getattr(config, "CHARGING_CONFIRM_COUNT", 2)))
|
||||
confirm_count = 0
|
||||
|
||||
if logger:
|
||||
logger.info(
|
||||
f"[CHARGE] 独立监测线程启动: interval={interval_ms}ms, "
|
||||
f"threshold={threshold_ma:.1f}mA, confirm={confirm_required}, "
|
||||
f"shutdown={'on' if shutdown_enabled else 'off'}"
|
||||
)
|
||||
|
||||
while True:
|
||||
current_ma = get_current()
|
||||
if diagnostic_enabled and logger:
|
||||
voltage = get_bus_voltage()
|
||||
logger.info(
|
||||
f"[CHARGE-DIAG] INA226 voltage={voltage:.3f}V, "
|
||||
f"current={current_ma:.1f}mA"
|
||||
)
|
||||
|
||||
if not shutdown_enabled:
|
||||
maix_time.sleep_ms(interval_ms)
|
||||
continue
|
||||
|
||||
if current_ma < -abs(threshold_ma):
|
||||
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:
|
||||
logger.info(
|
||||
f"[CHARGE] INA226 充电电流 {current_ma:.1f}mA "
|
||||
f"({confirm_count}/{confirm_required})"
|
||||
)
|
||||
else:
|
||||
confirm_count = 0
|
||||
|
||||
if confirm_count >= confirm_required:
|
||||
script_path = getattr(
|
||||
config,
|
||||
"CHARGING_EXIT_SCRIPT",
|
||||
config.APP_DIR + "/charging_exit.sh",
|
||||
)
|
||||
if not os.path.isfile(script_path):
|
||||
if logger:
|
||||
logger.error(f"[CHARGE] 退出脚本不存在: {script_path}")
|
||||
confirm_count = 0
|
||||
else:
|
||||
if logger:
|
||||
logger.warning(
|
||||
f"[CHARGE] 已连续确认充电,通知服务器后退出应用: current={current_ma:.1f}mA"
|
||||
)
|
||||
try:
|
||||
from network import network_manager
|
||||
|
||||
notify_timeout_ms = max(
|
||||
0,
|
||||
int(getattr(config, "CHARGING_NOTIFY_TIMEOUT_MS", 30000)),
|
||||
)
|
||||
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": "充电中"},
|
||||
2,
|
||||
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 logger:
|
||||
logger.info("[CHARGE] 充电状态已发送到服务器")
|
||||
elif logger:
|
||||
logger.warning(
|
||||
f"[CHARGE] 等待服务器发送超时({notify_timeout_ms}ms),继续执行退出"
|
||||
)
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[CHARGE] 充电状态上报失败,继续执行退出: {e}")
|
||||
try:
|
||||
from laser_manager import laser_manager
|
||||
|
||||
laser_manager.turn_off_laser()
|
||||
if logger:
|
||||
logger.info("[CHARGE] 激光关闭命令已发送")
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[CHARGE] Python 关闭激光失败,交由退出脚本兜底: {e}")
|
||||
try:
|
||||
subprocess.Popen([
|
||||
"/bin/sh",
|
||||
script_path,
|
||||
str(os.getpid()),
|
||||
str(getattr(config, "DISTANCE_SERIAL_DEVICE", "/dev/ttyS1")),
|
||||
str(getattr(config, "DISTANCE_SERIAL_BAUDRATE", 9600)),
|
||||
])
|
||||
return
|
||||
except Exception as e:
|
||||
if logger:
|
||||
logger.error(f"[CHARGE] 调用退出脚本失败: {e}")
|
||||
confirm_count = 0
|
||||
|
||||
maix_time.sleep_ms(interval_ms)
|
||||
|
||||
|
||||
def voltage_to_percent(voltage):
|
||||
"""
|
||||
根据电压估算电池百分比(高密度查表插值 + 滤波)。
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@
|
||||
应用版本号
|
||||
每次 OTA 更新时,只需要更新这个文件中的版本号
|
||||
"""
|
||||
VERSION = '2.15.33'
|
||||
VERSION = '2.15.34'
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user