准备更新temp_avg相关字段能力

This commit is contained in:
2026-09-16 20:47:19 +08:00
parent 68e7be98ed
commit 75e9e85848
54 changed files with 106 additions and 1217 deletions
+18
View File
@@ -45,6 +45,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
String _deviceModel = "魅族21 Pro (默认)";
double _maxTemp = 0;
double _minTemp = 0;
double _batteryTempAvg = 0;
double _maxVolt = 0;
double _minVolt = 0;
bool _hasData = false;
@@ -359,6 +360,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
final volt = _extractVolt(lastLine);
final (maxTemp, minTemp) = _extractTempExtremes(validLines);
final (maxVolt, minVolt) = _extractVoltExtremes(validLines);
final tempAvg = _extractTempAvg(validLines);
dev.log(
'🔵 字段提取: cycle=$cycle, temp=$temp, volt=$volt',
@@ -390,6 +392,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
_currentCap = (validatedCap ?? _currentCap).toDouble();
_cycleCount = cycle;
_batteryTemp = temp;
_batteryTempAvg = tempAvg;
_batteryVolt = volt;
_maxTemp = maxTemp;
_minTemp = minTemp;
@@ -494,6 +497,20 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
return (maxTemp ?? 0, minTemp ?? 0);
}
double _extractTempAvg(List<String> lines) {
final reg = RegExp(r'tbat=(\d+)');
double sum = 0;
int count = 0;
for (String line in lines) {
final match = reg.firstMatch(line);
if (match != null) {
sum += double.parse(match.group(1)!);
count++;
}
}
return count > 0 ? sum / count : 0;
}
(double, double) _extractVoltExtremes(List<String> lines) {
final reg = RegExp(r'vbat=(\d+)');
double? maxVolt, minVolt;
@@ -773,6 +790,7 @@ class _BatteryHealthPageState extends State<BatteryHealthPage> {
child: BatteryInfoPanel(
batteryVolt: _batteryVolt,
batteryTemp: _batteryTemp,
tempAvg: _batteryTempAvg,
maxVolt: _maxVolt,
minVolt: _minVolt,
maxTemp: _maxTemp,
+18 -4
View File
@@ -87,25 +87,39 @@ class BatteryDataService {
continue;
}
// 提取电压极值
// 提取电压极值与平均温度
final voltReg = RegExp(r'vbat=(\d+)');
final tempReg = RegExp(r'tbat=(\d+)');
double? maxVolt, minVolt;
double tempSum = 0;
int tempCount = 0;
for (String line in lines) {
if (!line.contains('tbat=')) continue;
final match = voltReg.firstMatch(line);
if (match != null) {
final v = int.parse(match.group(1)!) / 1000000;
final vMatch = voltReg.firstMatch(line);
if (vMatch != null) {
final v = int.parse(vMatch.group(1)!) / 1000000;
if (maxVolt == null || v > maxVolt) maxVolt = v;
if (minVolt == null || v < minVolt) minVolt = v;
}
final tMatch = tempReg.firstMatch(line);
if (tMatch != null) {
tempSum += double.parse(tMatch.group(1)!);
tempCount++;
}
}
if (maxVolt == null || minVolt == null) continue;
final tempAvg = tempCount > 0 ? tempSum / tempCount : 0.0;
await _dbService.insertOrUpdate(
dateStr,
validatedCap,
maxVolt,
minVolt,
tempAvg: tempAvg, // 🆕
);
dev.log(
'🔵 插入数据库: $dateStr, cap=$validatedCap',
+20 -6
View File
@@ -6,22 +6,21 @@ import 'package:path/path.dart';
class DatabaseService {
static Database? _database;
static const String _tableName = 'battery_data';
static const int _dbVersion = 2; // 🆕 1.7.1 加入 temp_avg
/// 获取数据库实例(单例)
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
/// 初始化数据库
Future<Database> _initDatabase() async {
final dbPath = await getDatabasesPath();
final path = join(dbPath, 'battery_health.db');
return await openDatabase(
path,
version: 1,
version: _dbVersion,
onCreate: (db, version) async {
await db.execute('''
CREATE TABLE $_tableName (
@@ -29,6 +28,7 @@ class DatabaseService {
capacity INTEGER NOT NULL,
volt_max REAL NOT NULL,
volt_min REAL NOT NULL,
temp_avg REAL NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL
)
''');
@@ -37,6 +37,15 @@ class DatabaseService {
''');
dev.log('✅ 数据库表创建成功', name: 'DatabaseService');
},
onUpgrade: (db, oldVersion, newVersion) async {
// 🆕 1.7.1 v1 -> v2:添加 temp_avg 字段
if (oldVersion < 2) {
await db.execute(
'ALTER TABLE $_tableName ADD COLUMN temp_avg REAL NOT NULL DEFAULT 0',
);
dev.log('✅ 数据库升级 v1->v2:已添加 temp_avg 字段', name: 'DatabaseService');
}
},
);
}
@@ -45,8 +54,9 @@ class DatabaseService {
String date,
int capacity,
double voltMax,
double voltMin,
) async {
double voltMin, {
double tempAvg = 0, // 🆕
}) async {
final db = await database;
final now = DateTime.now().toIso8601String();
@@ -55,9 +65,13 @@ class DatabaseService {
'capacity': capacity,
'volt_max': voltMax,
'volt_min': voltMin,
'temp_avg': tempAvg,
'updated_at': now,
}, conflictAlgorithm: ConflictAlgorithm.replace);
dev.log('📝 数据已保存: $date, cap=$capacity', name: 'DatabaseService');
dev.log(
'📝 数据已保存: $date, cap=$capacity, tempAvg=${tempAvg.toStringAsFixed(1)}',
name: 'DatabaseService',
);
}
/// 查询最近 N 条数据(按日期倒序)
+34 -11
View File
@@ -11,6 +11,8 @@ class BatteryInfoPanel extends StatelessWidget {
final double minTemp;
final DataAbnormalType abnormalType;
final double tempAvg;
const BatteryInfoPanel({
super.key,
required this.batteryVolt,
@@ -19,6 +21,7 @@ class BatteryInfoPanel extends StatelessWidget {
required this.minVolt,
required this.maxTemp,
required this.minTemp,
this.tempAvg = 0,
this.abnormalType = DataAbnormalType.none,
});
@@ -110,13 +113,14 @@ class BatteryInfoPanel extends StatelessWidget {
'${batteryTemp.toStringAsFixed(0)}℃',
),
const SizedBox(height: 8),
// 🆕 一行显示:↑ max ↓ min [avg] avg
Row(
children: [
RichText(
text: TextSpan(
style: const TextStyle(
fontFamily: 'Flyme',
fontSize: 14,
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.red,
),
@@ -128,16 +132,16 @@ class BatteryInfoPanel extends StatelessWidget {
color: Colors.red,
),
),
TextSpan(text: '${maxTemp.toStringAsFixed(0)}℃'),
TextSpan(text: '${maxTemp.toStringAsFixed(1)}℃'),
],
),
),
const SizedBox(width: 12),
const SizedBox(width: 6),
RichText(
text: TextSpan(
style: const TextStyle(
fontFamily: 'Flyme',
fontSize: 14,
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blue,
),
@@ -149,10 +153,22 @@ class BatteryInfoPanel extends StatelessWidget {
color: Colors.blue,
),
),
TextSpan(text: '${minTemp.toStringAsFixed(0)}℃'),
TextSpan(text: '${minTemp.toStringAsFixed(1)}℃'),
],
),
),
const SizedBox(width: 6),
_buildIcon('avg', size: 14),
const SizedBox(width: 2),
Text(
'${tempAvg.toStringAsFixed(1)}℃',
style: const TextStyle(
fontFamily: 'Flyme',
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.grey,
),
),
],
),
],
@@ -162,24 +178,31 @@ class BatteryInfoPanel extends StatelessWidget {
);
}
Widget _buildIcon(String type) {
Widget _buildIcon(String type, {double size = 18}) {
switch (type) {
case 'voltage':
return SvgPicture.asset(
'assets/icons/si--lightning-fill.svg',
width: 18,
height: 18,
width: size,
height: size,
colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn),
);
case 'temperature':
return SvgPicture.asset(
'assets/icons/mdi--temperature.svg',
width: 18,
height: 18,
width: size,
height: size,
colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn),
);
case 'avg': // 🆕
return SvgPicture.asset(
'assets/icons/avg.svg',
width: size,
height: size,
colorFilter: const ColorFilter.mode(Colors.grey, BlendMode.srcIn),
);
default:
return const Icon(Icons.help_outline, size: 18, color: Colors.grey);
return Icon(Icons.help_outline, size: size, color: Colors.grey);
}
}