diff --git a/lib/logic/capacity_extractor.dart b/lib/logic/capacity_extractor.dart index 971b322..2588c2e 100644 --- a/lib/logic/capacity_extractor.dart +++ b/lib/logic/capacity_extractor.dart @@ -1,31 +1,36 @@ /// 容量提取工具 /// 支持两种日志格式: /// 1. learned_cap(21 系列):单位 µAh,除以 1000 得到 mAh -/// 2. remaining_cap(20 系列):单位 mAh,直接使用(但 21 系列的 remaining_cap 也是 µAh,需判断) -/// -/// 🟢 1.4.5 优化:仅从 status=Full 的行中提取容量(充满状态下 BMS 最准确) +/// 🟢 优先级最高,不受 status 限制(BMS 可能在任意状态行更新此值) +/// 2. remaining_cap(20 系列):仅从 status=Full 行提取,单位智能识别(µAh/mAh) class CapacityExtractor { static int? extractCapacity(List lines) { - // 🟢 只保留包含 tbat= 且 status=Full 的行 - final fullLines = lines.where((line) { - return line.contains('tbat=') && line.contains('status=Full'); - }).toList(); + final validLines = lines.where((line) => line.contains('tbat=')).toList(); + if (validLines.isEmpty) return null; - if (fullLines.isEmpty) { - // 今天没有充满电的记录,返回 null 表示无有效数据 - return null; - } - - // 模式一:learned_cap(21 系列) + // ============================================================ + // 🟢 第一优先级:learned_cap(21 系列专属) + // 不限制 status,在所有有效行中搜索,取最新的一条 + // ============================================================ final learnedReg = RegExp(r'learned_cap=(\d+)'); - for (String line in fullLines.reversed) { + for (String line in validLines.reversed) { final match = learnedReg.firstMatch(line); if (match != null) { - return int.parse(match.group(1)!) ~/ 1000; + final value = int.parse(match.group(1)!); + // learned_cap 单位固定为 µAh,直接除以 1000 转 mAh + return value ~/ 1000; } } - // 模式二:remaining_cap 最大值(20 系列,或 21 系列回退) + // ============================================================ + // 🟢 第二优先级: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) { @@ -39,7 +44,7 @@ class CapacityExtractor { } if (maxRemaining == null) return null; - // 🟢 判断单位:如果数值大于 100000(约 100 mAh),则认为是 µAh,需除以 1000 + // 🟢 智能单位识别:如果数值大于 100000(约 100 mAh),视为 µAh 需除以 1000 if (maxRemaining > 100000) { return maxRemaining ~/ 1000; } else { diff --git a/lib/utils/charge_utils.dart b/lib/utils/charge_utils.dart index b7271b2..bf05217 100644 --- a/lib/utils/charge_utils.dart +++ b/lib/utils/charge_utils.dart @@ -71,7 +71,7 @@ class ChargeUtils { if (wiredLevel != null && ChargeMaps.wiredPower.containsKey(wiredLevel)) { final requested = ChargeMaps.wiredPower[wiredLevel]!.round(); - return "≈${requested}w/L-${wiredLevel}"; + return "≈${requested}w/L-$wiredLevel"; } return "≈${power.round()}w"; diff --git a/lib/widgets/charge_detail_page.dart b/lib/widgets/charge_detail_page.dart index 5d09a56..7420535 100644 --- a/lib/widgets/charge_detail_page.dart +++ b/lib/widgets/charge_detail_page.dart @@ -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 _getProtocolDisplay() { if (isWireless) return '无线充电($chargeType)'; diff --git a/pubspec.yaml b/pubspec.yaml index bba64fe..617dc48 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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.5.0-dev.1 +version: 1.5.0-dev.3 environment: sdk: ^3.9.2