55 lines
2.1 KiB
Dart
55 lines
2.1 KiB
Dart
/// 容量提取工具
|
||
/// 支持两种日志格式:
|
||
/// 1. learned_cap(21 系列):单位 µAh,除以 1000 得到 mAh
|
||
/// 🟢 优先级最高,不受 status 限制(BMS 可能在任意状态行更新此值)
|
||
/// 2. remaining_cap(20 系列):仅从 status=Full 行提取,单位智能识别(µAh/mAh)
|
||
class CapacityExtractor {
|
||
static int? extractCapacity(List<String> lines) {
|
||
final validLines = lines.where((line) => line.contains('tbat=')).toList();
|
||
if (validLines.isEmpty) return null;
|
||
|
||
// ============================================================
|
||
// 🟢 第一优先级:learned_cap(21 系列专属)
|
||
// 不限制 status,在所有有效行中搜索,取最新的一条
|
||
// ============================================================
|
||
final learnedReg = RegExp(r'learned_cap=(\d+)');
|
||
for (String line in validLines.reversed) {
|
||
final match = learnedReg.firstMatch(line);
|
||
if (match != null) {
|
||
final value = int.parse(match.group(1)!);
|
||
// learned_cap 单位固定为 µAh,直接除以 1000 转 mAh
|
||
return value ~/ 1000;
|
||
}
|
||
}
|
||
|
||
// ============================================================
|
||
// 🟢 第二优先级:remaining_cap(20 系列回退方案)
|
||
// 仅从 status=Full 行提取(充满状态下 BMS 最准确)
|
||
// ============================================================
|
||
final fullLines = validLines
|
||
.where((line) => line.contains('status=Full'))
|
||
.toList();
|
||
if (fullLines.isEmpty) return null;
|
||
|
||
final remainingReg = RegExp(r'remaining_cap=(\d+)');
|
||
int? maxRemaining;
|
||
for (String line in fullLines) {
|
||
final match = remainingReg.firstMatch(line);
|
||
if (match != null) {
|
||
final value = int.parse(match.group(1)!);
|
||
if (maxRemaining == null || value > maxRemaining) {
|
||
maxRemaining = value;
|
||
}
|
||
}
|
||
}
|
||
if (maxRemaining == null) return null;
|
||
|
||
// 🟢 智能单位识别:如果数值大于 100000(约 100 mAh),视为 µAh 需除以 1000
|
||
if (maxRemaining > 100000) {
|
||
return maxRemaining ~/ 1000;
|
||
} else {
|
||
return maxRemaining;
|
||
}
|
||
}
|
||
}
|