91 lines
3.7 KiB
Dart
91 lines
3.7 KiB
Dart
|
||
import 'dart:convert';
|
||
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/entities/running_status_entity.dart';
|
||
import 'package:maibu_satabot_v2/features/devices/domain/entities/gps_entity.dart';
|
||
import 'package:maibu_satabot_v2/core/network/protocol_decoder.dart'; // 确保能访问 RawPacket
|
||
|
||
import '../../../../core/network/net_message_dispatcher.dart';
|
||
import 'device_status_event.dart';
|
||
import 'device_status_state.dart';
|
||
|
||
class DeviceStatusBloc extends Bloc<DeviceStatusEvent, DeviceStatusState> {
|
||
final NetMessageDispatcher _dispatcher;
|
||
|
||
DeviceStatusBloc(this._dispatcher) : super(DeviceStatusInitial()) {
|
||
// 直接订阅 0x02 指令的字符串流
|
||
_dispatcher.onStringMessage().listen((jsonString) {
|
||
add(DeviceStatusLoaded(jsonString));
|
||
});
|
||
|
||
// 订阅 0x12 的 JSON 流()
|
||
_dispatcher.onJsonMessage(0x12).listen((jsonData) {
|
||
add(PushMessageReceived(jsonData));
|
||
});
|
||
}
|
||
|
||
@override
|
||
Stream<DeviceStatusState> mapEventToState(DeviceStatusEvent event) async* {
|
||
if (event is DeviceStatusLoaded) {
|
||
yield* _mapDeviceStatusLoaded(event);
|
||
} else if (event is PushMessageReceived) {
|
||
yield* _mapPushMessageReceived(event);
|
||
}
|
||
}
|
||
|
||
Stream<DeviceStatusState> _mapDeviceStatusLoaded(DeviceStatusLoaded event) async* {
|
||
try {
|
||
final fields = event.jsonString.trim().split(' ');
|
||
if (fields.length < 18) {
|
||
yield DeviceStatusError('字段不足,期望 ≥18,实际: ${fields.length}');
|
||
return;
|
||
}
|
||
///解析设备状态
|
||
final status = RunningStatusEntity().copyWith(
|
||
voltage: double.tryParse(fields[0]) ?? 0.0,
|
||
leftTargetSpeed: double.tryParse(fields[1]) ?? 0.0,
|
||
rightTargetSpeed: double.tryParse(fields[2]) ?? 0.0,
|
||
leftMeasureSpeed: double.tryParse(fields[3]) ?? 0.0,
|
||
rightMeasureSpeed: double.tryParse(fields[4]) ?? 0.0,
|
||
leftCurrent: double.tryParse(fields[5]) ?? 0.0,
|
||
rightCurrent: double.tryParse(fields[6]) ?? 0.0,
|
||
leftMotorTemp: double.tryParse(fields[7]) ?? 0.0,
|
||
rightMotorTemp: double.tryParse(fields[8]) ?? 0.0,
|
||
chipTemp: double.tryParse(fields[9]) ?? 0.0,
|
||
yaw: double.tryParse(fields[10]) ?? 0.0,
|
||
pitch: double.tryParse(fields[11]) ?? 0.0,
|
||
roll: double.tryParse(fields[12]) ?? 0.0,
|
||
satelliteCnt: int.tryParse(fields[13]) ?? 0,
|
||
qual: int.tryParse(fields[14]) ?? 0,
|
||
headingStatus: int.tryParse(fields[15]) ?? 0,
|
||
latitude: double.tryParse(fields[16]) ?? 0.0,
|
||
longitude: double.tryParse(fields[17]) ?? 0.0,
|
||
knifeCuttingSpeed: fields.length > 19 && fields[19].isNotEmpty ? fields[19] : "0",
|
||
controlMode: fields.length > 20 && fields[20].isNotEmpty ? fields[20] : "0",
|
||
battery: fields.length > 21 && fields[21].isNotEmpty ? fields[21] : "0",
|
||
workingArea: fields.length > 22 && fields[22].isNotEmpty ? fields[22] : "0",
|
||
obstacleFlag: fields.length > 23 && fields[23].isNotEmpty ? fields[23] : "0",
|
||
);
|
||
///解析GPS
|
||
final gps = GPSEntity(status.latitude, status.longitude);
|
||
yield DeviceStatusUpdated(status, gps);
|
||
} catch (e) {
|
||
yield DeviceStatusError('解析设备状态失败: $e');
|
||
}
|
||
}
|
||
/// 解析 推送消息
|
||
Stream<DeviceStatusState> _mapPushMessageReceived(PushMessageReceived event) async* {
|
||
try {
|
||
final eventStr = event.jsonData['event'] ?? '';
|
||
final deviceId = event.jsonData['deviceId'] ?? '未知';
|
||
debugPrint('收到推送事件: $eventStr, 设备: $deviceId');
|
||
|
||
// 可扩展:yield PushMessageState(event.jsonData)
|
||
} catch (e) {
|
||
yield DeviceStatusError('解析推送消息失败: $e');
|
||
}
|
||
}
|
||
|
||
}
|