Files
MEIZU-Battery-Healthy/lib/logic/charge_parser.dart
T
2026-07-07 23:37:29 +08:00

141 lines
3.9 KiB
Dart

import 'dart:developer' as dev;
import '../utils/time_utils.dart';
/// 充电日志解析器
class ChargeParser {
/// 解析充电数据,返回解析结果
static ParseResult parse(List<String> lines, DateTime? chargingStartTime) {
dev.log('[ChargeParser] 开始解析,共 ${lines.length} 行', name: 'BatteryHealth');
final validLines = _collectValidLines(lines, chargingStartTime);
if (validLines.isEmpty) {
dev.log('[ChargeParser] 无有效时间窗口内的数据行', name: 'BatteryHealth');
return ParseResult.empty();
}
// 按时间戳从新到旧排序
validLines.sort((a, b) => b['timestamp'].compareTo(a['timestamp']));
final latest = validLines.first;
final latestLine = latest['line'] as String;
final latestType = latest['type'] as String;
dev.log(
'[ChargeParser] 最新有效数据: $latestType, 时间: ${latest['timestamp']}',
name: 'BatteryHealth',
);
if (latestType == 'wls') {
return _parseWireless(latestLine);
} else {
return _parseWired(latestLine);
}
}
static List<Map<String, dynamic>> _collectValidLines(
List<String> lines,
DateTime? chargingStartTime,
) {
final result = <Map<String, dynamic>>[];
for (String line in lines) {
final timestamp = TimeUtils.parseLogTimestamp(line);
if (!TimeUtils.isLogTimestampValid(timestamp, chargingStartTime)) {
continue;
}
final isUsb =
line.contains('chg_usb') &&
(line.contains('ibus=') || line.contains('real_type='));
final isWls = line.contains('chg_wls') && line.contains('wls_online=1');
if (isUsb || isWls) {
result.add({
'line': line,
'timestamp': timestamp,
'type': isWls ? 'wls' : 'usb',
});
}
}
return result;
}
static ParseResult _parseWireless(String line) {
final typeReg = RegExp(r'wls_type=(\w+)');
final voltReg = RegExp(r'wls_volt=(\d+)');
final currReg = RegExp(r'wls_curr=(\d+)');
final wlsType = typeReg.firstMatch(line)?.group(1);
final volt = int.parse(voltReg.firstMatch(line)?.group(1) ?? '0');
final curr = int.parse(currReg.firstMatch(line)?.group(1) ?? '0');
return ParseResult(
isWireless: true,
chargeType: wlsType ?? '无线',
power: (volt * curr) / 1000000.0,
volt: volt / 1000.0,
curr: curr / 1000.0,
wiredLevel: null,
);
}
static ParseResult _parseWired(String line) {
final ibusReg = RegExp(r'ibus=(\d+)');
final vbusReg = RegExp(r'vbus=(\d+)');
final levelReg = RegExp(r'wired_level=(\d+)');
final typeReg = RegExp(r'real_type=(\w+)');
final ibus = int.parse(ibusReg.firstMatch(line)?.group(1) ?? '0');
final vbus = int.parse(vbusReg.firstMatch(line)?.group(1) ?? '0');
final realType = typeReg.firstMatch(line)?.group(1);
final level = int.parse(levelReg.firstMatch(line)?.group(1) ?? '0');
String chargeType;
if (realType == 'PPS') {
chargeType = 'PPS';
} else if (realType == 'SDP' || realType == 'FLOAT') {
chargeType = 'SDP';
} else if (level >= 3) {
chargeType = 'PPS';
} else {
chargeType = 'SDP';
}
return ParseResult(
isWireless: false,
chargeType: chargeType,
power: (vbus * ibus) / 1000000000.0,
volt: vbus / 1000000.0,
curr: ibus / 1000000.0,
wiredLevel: chargeType == 'PPS' ? level : null,
);
}
}
class ParseResult {
final bool isWireless;
final String chargeType;
final double power;
final double volt;
final double curr;
final int? wiredLevel;
ParseResult({
required this.isWireless,
required this.chargeType,
required this.power,
required this.volt,
required this.curr,
this.wiredLevel,
});
factory ParseResult.empty() {
return ParseResult(
isWireless: false,
chargeType: '',
power: 0.0,
volt: 0.0,
curr: 0.0,
wiredLevel: null,
);
}
}