Commit 6d1704c6 authored by akari's avatar akari
parents 47ea47f1 0c5d8ff9
......@@ -10,6 +10,9 @@ class BluetoothReadModel extends Equatable {
final int? oxygenConcentration;
final int? co2Measurement;
final DateTime? updatedAt;
final int? totalTime;
final double? ambientTemperature;
final int? o2SupplyTime;
const BluetoothReadModel({
this.sn,
......@@ -18,6 +21,9 @@ class BluetoothReadModel extends Equatable {
this.oxygenConcentration,
this.co2Measurement,
this.updatedAt,
this.totalTime,
this.ambientTemperature,
this.o2SupplyTime,
});
factory BluetoothReadModel.fromMcuReport(McuReport report) {
......@@ -30,6 +36,10 @@ class BluetoothReadModel extends Equatable {
report.oxygenConcentration < 0 ? null : report.oxygenConcentration,
co2Measurement: report.co2Measurement < 0 ? null : report.co2Measurement,
updatedAt: DateTime.now(),
totalTime: report.totalTime < 0 ? null : report.totalTime,
ambientTemperature:
report.ambientTemperature.isNaN ? null : report.ambientTemperature,
o2SupplyTime: report.o2SupplyTime < 0 ? null : report.o2SupplyTime,
);
}
......@@ -42,6 +52,9 @@ class BluetoothReadModel extends Equatable {
int? oxygenConcentration,
int? co2Measurement,
DateTime? updatedAt,
int? totalTime,
double? ambientTemperature,
int? o2SupplyTime,
bool clearSn = false,
}) {
return BluetoothReadModel(
......@@ -51,6 +64,9 @@ class BluetoothReadModel extends Equatable {
oxygenConcentration: oxygenConcentration ?? this.oxygenConcentration,
co2Measurement: co2Measurement ?? this.co2Measurement,
updatedAt: updatedAt ?? this.updatedAt,
totalTime: totalTime ?? this.totalTime,
ambientTemperature: ambientTemperature ?? this.ambientTemperature,
o2SupplyTime: o2SupplyTime ?? this.o2SupplyTime,
);
}
......@@ -62,5 +78,8 @@ class BluetoothReadModel extends Equatable {
oxygenConcentration,
co2Measurement,
updatedAt,
totalTime,
ambientTemperature,
o2SupplyTime,
];
}
......@@ -6,6 +6,9 @@ class MonitoringMetricBO extends Equatable {
/// 指标数值
final String value;
/// 设定值(温度/湿度/氧气为设定值,CO₂为告警阈值)
final String setValue;
/// 指标单位
final String unit;
......@@ -22,6 +25,7 @@ class MonitoringMetricBO extends Equatable {
required this.value,
required this.unit,
required this.label,
this.setValue = '--',
this.borderColorValue = 0xFF999999,
this.backgroundColorValue = 0x1A999999,
});
......@@ -29,6 +33,7 @@ class MonitoringMetricBO extends Equatable {
factory MonitoringMetricBO.fromJson(Map<String, dynamic> json) {
return MonitoringMetricBO(
value: json['value'] as String? ?? '',
setValue: json['setValue'] as String? ?? '--',
unit: json['unit'] as String? ?? '',
label: json['label'] as String? ?? '',
borderColorValue: json['borderColorValue'] as int? ?? 0xFF999999,
......@@ -39,6 +44,7 @@ class MonitoringMetricBO extends Equatable {
@override
List<Object?> get props => [
value,
setValue,
unit,
label,
borderColorValue,
......
......@@ -18,10 +18,35 @@ class MonitoringTopStatusBar extends StatelessWidget {
),
),
padding: EdgeInsets.only(left: 32.w, bottom: 22.h),
child: Row(
child: BlocBuilder<BluetoothReadBloc, BluetoothReadState>(
builder: (context, state) {
final info = state.info;
String totalTimeText;
if (info.totalTime != null) {
totalTimeText = '${info.totalTime}h';
} else {
totalTimeText = '--';
}
String ambientTempText;
if (info.ambientTemperature != null) {
ambientTempText = info.ambientTemperature!.toStringAsFixed(2);
} else {
ambientTempText = '--';
}
String o2SupplyTimeText;
if (info.o2SupplyTime != null) {
o2SupplyTimeText = '${info.o2SupplyTime}h';
} else {
o2SupplyTimeText = '--';
}
return Row(
children: [
Text(
'总运行时长:9999h',
'总运行时长:$totalTimeText',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
......@@ -29,7 +54,7 @@ class MonitoringTopStatusBar extends StatelessWidget {
),
SizedBox(width: 32.w),
Text(
'环境温度:30.68',
'环境温度:$ambientTempText',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
......@@ -37,27 +62,23 @@ class MonitoringTopStatusBar extends StatelessWidget {
),
SizedBox(width: 32.w),
Text(
'总制氧时长:500h',
'制氧时长:$o2SupplyTimeText',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
),
SizedBox(width: 32.w),
BlocBuilder<BluetoothReadBloc, BluetoothReadState>(
builder: (context, state) {
final sn = state.info.sn;
return Text(
'sn:${sn ?? ''}',
Text(
'sn:${info.sn ?? ''}',
style: TextStyle(
color: Colors.white,
fontSize: 25.sp,
),
);
},
),
],
);
},
),
);
}
......
......@@ -54,9 +54,6 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
bool _isMqttConnecting = false;
String? _mqttDeviceSn;
/// 已收到的摄像头告警 eventId 集合,用于去重
final Set<String> _seenAlarmEventIds = {};
/// 记录已请求过舱详情的 SN,避免每个 BLE 数据帧都重复请求接口
String? _lastFetchedCabinSn;
bool _isFetchingCabinDetail = false;
......@@ -703,7 +700,6 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
latestBluetoothRawHex: '',
cameraAlerts: const [],
));
_seenAlarmEventIds.clear();
_isManualUnbindingBluetooth = false;
}
......@@ -904,10 +900,6 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
final alarm = CameraAlarmBO.fromJson(json);
// 按 eventId 去重
if (_seenAlarmEventIds.contains(alarm.eventId)) return;
_seenAlarmEventIds.add(alarm.eventId);
final timeStr = _formatTimestamp(alarm.timestamp);
final behaviorTitle = alarm.titleByBehaviorCode;
final petName = alarm.petName;
......@@ -923,10 +915,20 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
alarmId: alarm.alarmId,
);
// 按告警标题去重:相同标题 → 原地覆盖;不同标题 → 插入头部
final existingIndex = state.cameraAlerts.indexWhere((a) => a.title == title);
if (existingIndex >= 0) {
// 已存在相同标题 → 原地替换
final updatedAlerts = List<AlertInfoBO>.from(state.cameraAlerts);
updatedAlerts[existingIndex] = alert;
emit(state.copyWith(cameraAlerts: updatedAlerts));
} else {
// 不存在 → 插入头部
emit(state.copyWith(
cameraAlerts: [alert, ...state.cameraAlerts],
));
}
}
/// 处理 MQTT pet/bind 宠物绑定消息
///
......@@ -1045,24 +1047,28 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
'舱内温度',
_formatReportTemperatureOrKeep(report.mainTemperature, '舱内温度'),
fallbackUnit: '℃',
setValue: _formatSetTemperature(report.temperatureSetting),
baseMetrics: metrics,
),
'舱内湿度': _replaceMetricValue(
'舱内湿度',
_formatReportIntOrKeep(report.humidity, '舱内湿度'),
fallbackUnit: 'RH',
setValue: _formatSetInt(report.humiditySetting),
baseMetrics: metrics,
),
'氧气浓度': _replaceMetricValue(
'氧气浓度',
_formatReportIntOrKeep(report.oxygenConcentration, '氧气浓度'),
fallbackUnit: '%',
setValue: _formatSetInt(report.oxygenSetting),
baseMetrics: metrics,
),
'二氧化碳': _replaceMetricValue(
'二氧化碳',
_formatReportIntOrKeep(report.co2Measurement, '二氧化碳'),
fallbackUnit: 'ppm',
setValue: _formatSetInt(report.co2Setting),
baseMetrics: metrics,
),
};
......@@ -1134,6 +1140,7 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
String label,
String value, {
required String fallbackUnit,
String? setValue,
List<MonitoringMetricBO>? baseMetrics,
}) {
final metrics = baseMetrics ?? state.metrics;
......@@ -1147,12 +1154,14 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
if (existing == null) {
return MonitoringMetricBO(
value: value,
setValue: setValue ?? '--',
unit: fallbackUnit,
label: label,
);
}
return MonitoringMetricBO(
value: value,
setValue: setValue ?? existing.setValue,
unit: existing.unit.isEmpty ? fallbackUnit : existing.unit,
label: existing.label,
borderColorValue: existing.borderColorValue,
......@@ -1171,6 +1180,16 @@ class MonitoringIndexCubit extends HydratedCubit<MonitoringIndexState> {
return _existingMetricValue(label) ?? '--';
}
String _formatSetTemperature(double value) {
if (value.isNaN) return '--';
final fixed = value.toStringAsFixed(1);
return fixed.endsWith('.0') ? fixed.substring(0, fixed.length - 2) : fixed;
}
String _formatSetInt(int value) {
return value < 0 ? '--' : '$value';
}
String _formatReportIntOrKeep(int value, String label) {
if (value >= 0) return '$value';
return _existingMetricValue(label) ?? '--';
......
......@@ -148,7 +148,7 @@ class MonitoringMetricCard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'设定24${metric.unit}',
'设定${metric.setValue}${metric.unit}',
style: TextStyle(
color: Colors.white,
fontSize: 24.sp,
......
......@@ -173,7 +173,7 @@ class MonitoringPetInfoCard extends StatelessWidget {
SizedBox(height: 30.h),
_buildCareLevelBlock(info),
SizedBox(height: 25.h),
_buildExitButton(),
// _buildExitButton(),
],
);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment