调整协议识别逻辑、调整时间读取逻辑
This commit is contained in:
@@ -47,13 +47,16 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
|
||||
// ---------- 充电状态 ----------
|
||||
bool _isCharging = false;
|
||||
String _chargeType = ''; // "EPP", "PPS", "SDP", "无线" 等
|
||||
String _chargeType = ''; // "EPP", "PPS", "SDP", "无线", "MZ_EPP" 等
|
||||
double _chargePower = 0.0;
|
||||
double _chargeVolt = 0.0;
|
||||
double _chargeCurr = 0.0;
|
||||
int? _wiredLevel;
|
||||
bool _isWireless = false;
|
||||
|
||||
// 🟢 1.3.0-dev.3: 充电开始时间(UTC),用于时间窗口判断
|
||||
DateTime? _chargingStartTime;
|
||||
|
||||
// 动画控制
|
||||
late AnimationController _chargeAnimationController;
|
||||
late Animation<double> _bottomSlide;
|
||||
@@ -195,15 +198,17 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- 1.3.0-dev.1: 使用 UTC 生成文件名 ----------
|
||||
String getTodayFileName() {
|
||||
DateTime now = DateTime.now();
|
||||
String year = now.year.toString();
|
||||
String month = now.month.toString().padLeft(2, '0');
|
||||
String day = now.day.toString().padLeft(2, '0');
|
||||
DateTime nowUtc = DateTime.now().toUtc();
|
||||
String year = nowUtc.year.toString();
|
||||
String month = nowUtc.month.toString().padLeft(2, '0');
|
||||
String day = nowUtc.day.toString().padLeft(2, '0');
|
||||
return 'mbattery_charger_log_${year}_${month}_$day';
|
||||
}
|
||||
|
||||
// ---------- 时间戳工具方法 ----------
|
||||
/// 解析日志行中的时间戳,强制解析为 UTC
|
||||
DateTime? _parseLogTimestamp(String line) {
|
||||
RegExp reg = RegExp(r'\[(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})\]');
|
||||
Match? match = reg.firstMatch(line);
|
||||
@@ -226,18 +231,24 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
}
|
||||
}
|
||||
|
||||
/// 🟢 1.3.0-dev.3: 时间窗口以插入时刻为基准,只向前看
|
||||
bool _isLogTimestampValid(DateTime? logTime) {
|
||||
if (logTime == null) return false;
|
||||
if (_chargingStartTime == null) {
|
||||
// 边缘情况:回退到当前时间 ±3 分钟
|
||||
DateTime nowUtc = DateTime.now().toUtc();
|
||||
Duration diff = nowUtc.difference(logTime);
|
||||
bool isValid = diff.abs().inMinutes <= 3;
|
||||
return isValid;
|
||||
return diff.abs().inMinutes <= 3;
|
||||
}
|
||||
// 日志时间必须在 [充电开始时间, 充电开始时间 + 3 分钟] 范围内
|
||||
DateTime endTime = _chargingStartTime!.add(const Duration(minutes: 3));
|
||||
return logTime.isAfter(_chargingStartTime!) && logTime.isBefore(endTime);
|
||||
}
|
||||
|
||||
// ---------- 🟢 核心:系统API只触发充电状态,不设类型 ----------
|
||||
// ---------- 核心:系统API定调 ----------
|
||||
void _applySystemChargeState(bool isCharging, String systemChargeType) {
|
||||
dev.log(
|
||||
'[_applySystemChargeState] isCharging: $isCharging, systemChargeType: $systemChargeType (忽略,只用来触发状态)',
|
||||
'[_applySystemChargeState] isCharging: $isCharging, systemChargeType: $systemChargeType',
|
||||
name: 'BatteryHealth',
|
||||
);
|
||||
|
||||
@@ -252,16 +263,48 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
_chargeVolt = 0.0;
|
||||
_chargeCurr = 0.0;
|
||||
_wiredLevel = null;
|
||||
_chargingStartTime = null; // 🟢 清空开始时间
|
||||
_updateChargeState();
|
||||
return;
|
||||
}
|
||||
|
||||
// 🟢 不再根据 systemChargeType 设定类型,统一显示"识别中..."
|
||||
// 类型完全由日志解析决定
|
||||
if (_chargeType.isEmpty) {
|
||||
_chargeType = ''; // 保持空,让日志解析来填充
|
||||
// 🟢 1.3.0-dev.3: 记录充电开始时刻(仅当从断开状态变为充电状态时)
|
||||
if (_chargingStartTime == null) {
|
||||
_chargingStartTime = DateTime.now().toUtc();
|
||||
dev.log(
|
||||
'[_applySystemChargeState] 充电开始时间: $_chargingStartTime',
|
||||
name: 'BatteryHealth',
|
||||
);
|
||||
}
|
||||
|
||||
if (systemChargeType == "WIRELESS") {
|
||||
dev.log('[_applySystemChargeState] 无线充电模式', name: 'BatteryHealth');
|
||||
_isWireless = true;
|
||||
_chargeType = "无线";
|
||||
_wiredLevel = null;
|
||||
} else if (systemChargeType == "AC") {
|
||||
dev.log(
|
||||
'[_applySystemChargeState] 有线快充模式 (AC/PPS)',
|
||||
name: 'BatteryHealth',
|
||||
);
|
||||
_isWireless = false;
|
||||
_chargeType = "PPS";
|
||||
} else if (systemChargeType == "USB") {
|
||||
dev.log(
|
||||
'[_applySystemChargeState] 有线慢充模式 (USB/SDP)',
|
||||
name: 'BatteryHealth',
|
||||
);
|
||||
_isWireless = false;
|
||||
_chargeType = "SDP";
|
||||
} else {
|
||||
// UNKNOWN 时清空旧类型,等待日志修正
|
||||
dev.log(
|
||||
'[_applySystemChargeState] ⚠️ 未知类型: $systemChargeType,清空类型等待日志',
|
||||
name: 'BatteryHealth',
|
||||
);
|
||||
_isWireless = false;
|
||||
_chargeType = '';
|
||||
}
|
||||
_isWireless = false; // 重置无线标志,等待日志确认
|
||||
|
||||
_chargePower = 0.0;
|
||||
_chargeVolt = 0.0;
|
||||
@@ -269,13 +312,12 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
_updateChargeState();
|
||||
});
|
||||
|
||||
// 🟢 插入充电器后立即读取日志
|
||||
if (_isCharging) {
|
||||
_fetchChargeDataFromLog();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- 🟢 日志解析:唯一的数据源 ----------
|
||||
// ---------- 日志解析 ----------
|
||||
void _parseChargeDataFromLog(List<String> lines) {
|
||||
dev.log(
|
||||
'[_parseChargeDataFromLog] 开始解析,共 ${lines.length} 行',
|
||||
@@ -367,15 +409,16 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
_chargeVolt = vbus / 1000000.0;
|
||||
_chargeCurr = ibus / 1000000.0;
|
||||
|
||||
// 有线模式
|
||||
_isWireless = false;
|
||||
|
||||
// 🟢 1.3.0-dev.2: real_type 优先级最高
|
||||
if (realType != null && realType == "PPS") {
|
||||
_chargeType = "PPS";
|
||||
} else if (level >= 3) {
|
||||
_chargeType = "PPS";
|
||||
} else if (realType != null && realType == "SDP") {
|
||||
} else if (realType != null &&
|
||||
(realType == "SDP" || realType == "FLOAT")) {
|
||||
_chargeType = "SDP";
|
||||
} else if (level >= 3 && _chargeType != "PPS") {
|
||||
_chargeType = "PPS";
|
||||
} else if (_chargeType.isEmpty) {
|
||||
_chargeType = "SDP";
|
||||
}
|
||||
@@ -385,8 +428,9 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
} else {
|
||||
_wiredLevel = null;
|
||||
}
|
||||
|
||||
dev.log(
|
||||
'[_parseChargeDataFromLog] 有线更新: $_chargeType, ${_chargePower.toStringAsFixed(2)}W',
|
||||
'[_parseChargeDataFromLog] 有线更新: $_chargeType, ${_chargePower.toStringAsFixed(2)}W, level: $level',
|
||||
name: 'BatteryHealth',
|
||||
);
|
||||
});
|
||||
@@ -394,11 +438,25 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
}
|
||||
}
|
||||
|
||||
// 🟢 1.3.0-dev.3: 增加超时保护
|
||||
Future<void> _fetchChargeDataFromLog() async {
|
||||
if (!_isCharging) {
|
||||
dev.log('[_fetchChargeDataFromLog] 未充电,跳过读取', name: 'BatteryHealth');
|
||||
return;
|
||||
}
|
||||
|
||||
// 超时检查:如果插入超过 5 分钟还没读到数据,不再频繁报错
|
||||
if (_chargingStartTime != null) {
|
||||
Duration elapsed = DateTime.now().toUtc().difference(_chargingStartTime!);
|
||||
if (elapsed.inMinutes > 5) {
|
||||
dev.log(
|
||||
'[_fetchChargeDataFromLog] 充电开始已超过 5 分钟,跳过本次轮询',
|
||||
name: 'BatteryHealth',
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String fullPath = _filePath + getTodayFileName();
|
||||
dev.log('[_fetchChargeDataFromLog] 尝试读取: $fullPath', name: 'BatteryHealth');
|
||||
|
||||
@@ -636,7 +694,6 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
_applySystemChargeState(isCharging, systemType);
|
||||
});
|
||||
|
||||
// 🟢 轮询间隔缩短为 15 秒
|
||||
_pollTimer = Timer.periodic(const Duration(seconds: 15), (timer) {
|
||||
if (_isCharging) {
|
||||
_fetchChargeDataFromLog();
|
||||
@@ -980,9 +1037,9 @@ class _BatteryHealthPageState extends State<BatteryHealthPage>
|
||||
double value = percents[index];
|
||||
Color barColor;
|
||||
if (value > 0) {
|
||||
if (value >= 80) {
|
||||
if (value >= 80)
|
||||
barColor = kHealthGreen;
|
||||
} else if (value >= 60)
|
||||
else if (value >= 60)
|
||||
barColor = kHealthYellow;
|
||||
else
|
||||
barColor = kHealthOrange;
|
||||
|
||||
@@ -11,14 +11,14 @@ class ChargeDetailPage extends StatelessWidget {
|
||||
final int? wiredLevel;
|
||||
|
||||
const ChargeDetailPage({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.chargeType,
|
||||
required this.isWireless,
|
||||
required this.power,
|
||||
required this.volt,
|
||||
required this.curr,
|
||||
this.wiredLevel,
|
||||
}) : super(key: key);
|
||||
});
|
||||
|
||||
String _getDisplayPower() {
|
||||
if (isWireless) {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.2.0
|
||||
version: 1.2.0-dev.3
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.2
|
||||
|
||||
Reference in New Issue
Block a user