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 import init_logging, get_logger, stop_logging
|
||||||
from logger_manager import logger_manager
|
from logger_manager import logger_manager
|
||||||
from time_sync import sync_system_time_from_4g
|
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 laser_manager import laser_manager
|
||||||
from vision import start_save_shot_worker
|
from vision import start_save_shot_worker
|
||||||
from network import network_manager
|
from network import network_manager
|
||||||
@@ -125,13 +125,6 @@ def cmd_str():
|
|||||||
logger_manager.init_logging(log_level=logging.WARNING)
|
logger_manager.init_logging(log_level=logging.WARNING)
|
||||||
logger = logger_manager.logger
|
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()
|
# laser_manager.turn_off_laser()
|
||||||
|
|
||||||
|
|||||||
+12
-2
@@ -18,7 +18,7 @@ import socket
|
|||||||
import config
|
import config
|
||||||
|
|
||||||
from hardware import hardware_manager
|
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 logger_manager import logger_manager
|
||||||
from wifi import wifi_manager
|
from wifi import wifi_manager
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -2256,7 +2256,17 @@ class NetworkManager:
|
|||||||
"netType": self.network_type,
|
"netType": self.network_type,
|
||||||
}
|
}
|
||||||
self.safe_enqueue(battery_data, 2)
|
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 升级
|
elif inner_cmd == 5: # OTA 升级
|
||||||
inner_data = data_obj.get("data", {}) if isinstance(data_obj, dict) else {}
|
inner_data = data_obj.get("data", {}) if isinstance(data_obj, dict) else {}
|
||||||
ssid = inner_data.get("ssid")
|
ssid = inner_data.get("ssid")
|
||||||
|
|||||||
@@ -142,138 +142,6 @@ def is_charging(threshold_ma=10.0):
|
|||||||
return False
|
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):
|
def voltage_to_percent(voltage):
|
||||||
"""
|
"""
|
||||||
根据电压估算电池百分比(高密度查表插值 + 滤波)。
|
根据电压估算电池百分比(高密度查表插值 + 滤波)。
|
||||||
|
|||||||
+1
-1
@@ -4,6 +4,6 @@
|
|||||||
应用版本号
|
应用版本号
|
||||||
每次 OTA 更新时,只需要更新这个文件中的版本号
|
每次 OTA 更新时,只需要更新这个文件中的版本号
|
||||||
"""
|
"""
|
||||||
VERSION = '2.15.33'
|
VERSION = '2.15.34'
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user