#连接库初步完成

This commit is contained in:
CC
2026-01-27 18:44:49 +08:00
parent 8c39f0daf8
commit 949743972c
82 changed files with 1187 additions and 650 deletions

View File

@@ -1,30 +0,0 @@
import 'dart:typed_data';
import '../../../../core/protocol/machine_protocol_codec.dart';
class LawnMoverProtocolModel {
final int left;
final int right;
final int lift;
final int mower;
final int ignition;
final int emergency;
LawnMoverProtocolModel({
required this.left,
required this.right,
this.lift = 0,
this.mower = 0,
this.ignition = 0,
this.emergency = 0,
});
Uint8List toBytes() => MachineProtocolCodec.encodeRemoteControlPayload(
left: left,
right: right,
lift: lift,
mower: mower,
ignition: ignition,
emergency: emergency,
);
}

View File

@@ -0,0 +1,89 @@
import 'dart:typed_data';
import 'package:maibu_satabot_v2/core/data/base_model.dart';
import 'package:maibu_satabot_v2/features/remote_control/domain/entities/machine_control_entity.dart';
class MachineControlModel extends MachineControlEntity implements BaseModel<MachineControlEntity>{
MachineControlModel({
required super.leftSpeed,
required super.rightSpeed,
required super.chassisLift,
required super.mowerSpeed,
required super.ignitionStatus,
required super.isEmergency,
});
factory MachineControlModel.fromEntity(MachineControlEntity entity) {
return MachineControlModel(
leftSpeed: entity.leftSpeed,
rightSpeed: entity.rightSpeed,
chassisLift: entity.chassisLift,
mowerSpeed: entity.mowerSpeed,
ignitionStatus: entity.ignitionStatus,
isEmergency: entity.isEmergency,
);
}
/// 需要传入计算好的左右轮速度
Uint8List toRawPacket(Map<String, int> speeds) {
// 1. 调用 Codec:生成协议定义的 8 字节 Payload
final payload = encodeRemoteControlPayload(
left: speeds['left'] ?? 0,
right: speeds['right'] ?? 0,
lift: chassisLift,
mower: mowerSpeed,
ignition: ignitionStatus,
emergency: isEmergency ? 1 : 0,
);
// 2. 调用 Builder:封装帧头、指令、CRC、帧尾
return payload;
}
@override
MachineControlEntity toEntity() {
return MachineControlEntity(
leftSpeed: leftSpeed,
rightSpeed: rightSpeed,
chassisLift: chassisLift,
mowerSpeed: mowerSpeed,
ignitionStatus: ignitionStatus,
isEmergency: isEmergency,
);
}
@override
Map<String, dynamic> toJson() {
return {
'leftSpeed': leftSpeed,
'rightSpeed': rightSpeed,
'chassisLift': chassisLift,
'mowerSpeed': mowerSpeed,
'ignitionStatus': ignitionStatus,
'isEmergency': isEmergency,
};
}
Uint8List encodeRemoteControlPayload({
required int left,
required int right,
int lift = 0,
int mower = 0,
int ignition = 0,
int emergency = 0,
}) {
final bd = ByteData(8); // 只分配 8 字节
int pos = 0;
bd.setInt16(pos, left, Endian.little);
pos += 2;
bd.setInt16(pos, right, Endian.little);
pos += 2;
bd.setUint8(pos++, lift);
bd.setUint8(pos++, mower);
bd.setUint8(pos++, ignition);
bd.setUint8(pos++, emergency);
return bd.buffer.asUint8List();
}
}

View File

@@ -1,103 +1,132 @@
class RunningStatusModel {
final String voltage;
final String leftTargetSpeed;
final String rightTargetSpeed;
final String leftMeasureSpeed;
final String rightMeasureSpeed;
final String leftCurrent;
final String rightCurrent;
final String leftMotorTemp;
final String rightMotorTemp;
final String chipTemp;
final String yaw;
final String pitch;
final String roll;
final String satelliteCnt;
final String qual;
final String headingStatus;
final String latitude;
final String longitude;
final String time;
final String knifeCuttingSpeed;
final String controlMode;
final String workingArea;
final String battery;
import 'dart:convert';
import 'dart:typed_data';
import 'package:maibu_satabot_v2/core/data/base_model.dart';
import 'package:maibu_satabot_v2/features/remote_control/domain/entities/running_status_entity.dart';
import '../../../../core/network/enums/control_mode.dart';
class RunningStatusModel extends RunningStatusEntity
implements BaseModel<RunningStatusEntity> {
RunningStatusModel({
this.voltage = '',
this.leftTargetSpeed = '',
this.rightTargetSpeed = '',
this.leftMeasureSpeed = '',
this.rightMeasureSpeed = '',
this.leftCurrent = '',
this.rightCurrent = '',
this.leftMotorTemp = '',
this.rightMotorTemp = '',
this.chipTemp = '',
this.yaw = '',
this.pitch = '',
this.roll = '',
this.satelliteCnt = '',
this.qual = '',
this.headingStatus = '',
this.latitude = '',
this.longitude = '',
this.time = '',
this.knifeCuttingSpeed = '',
this.controlMode = '',
this.workingArea = '',
this.battery = '',
required super.voltage,
required super.leftTargetSpeed,
required super.rightTargetSpeed,
required super.leftMeasureSpeed,
required super.rightMeasureSpeed,
required super.leftCurrent,
required super.rightCurrent,
required super.leftMotorTemp,
required super.rightMotorTemp,
required super.chipTemp,
required super.yaw,
required super.pitch,
required super.roll,
required super.satelliteCnt,
required super.qual,
required super.headingStatus,
required super.latitude,
required super.longitude,
required super.time,
required super.knifeCuttingSpeed,
required super.controlMode,
required super.workingArea,
required super.battery,
required super.obstacleFlag,
});
RunningStatusModel copyWith({
String? voltage,
String? leftTargetSpeed,
String? rightTargetSpeed,
String? leftMeasureSpeed,
String? rightMeasureSpeed,
String? leftCurrent,
String? rightCurrent,
String? leftMotorTemp,
String? rightMotorTemp,
String? chipTemp,
String? yaw,
String? pitch,
String? roll,
String? satelliteCnt,
String? qual,
String? headingStatus,
String? latitude,
String? longitude,
String? time,
String? knifeCuttingSpeed,
String? controlMode,
String? workingArea,
String? battery,
}) {
@override
RunningStatusEntity toEntity() => this;
@override
Map<String, dynamic> toJson() {
return {
'voltage': voltage,
'leftTargetSpeed': leftTargetSpeed,
'rightTargetSpeed': rightTargetSpeed,
'leftMeasureSpeed': leftMeasureSpeed,
'rightMeasureSpeed': rightMeasureSpeed,
'leftCurrent': leftCurrent,
'rightCurrent': rightCurrent,
'leftMotorTemp': leftMotorTemp,
'rightMotorTemp': rightMotorTemp,
'chipTemp': chipTemp,
'yaw': yaw,
'pitch': pitch,
'roll': roll,
'satelliteCnt': satelliteCnt,
'qual': qual,
'headingStatus': headingStatus,
'latitude': latitude,
'longitude': longitude,
'time': time,
'knifeCuttingSpeed': knifeCuttingSpeed,
'controlMode': controlMode,
'workingArea': workingArea,
'battery': battery,
'obstacleFlag': obstacleFlag,
};
}
factory RunningStatusModel.fromBytes(Uint8List payload) {
// 将 Uint8List 转换为字符串 (通常是 utf8 或 ascii)
final rawString = utf8.decode(payload);
// 按逗号分割成数组
final parts = rawString.split(',');
// 辅助函数:安全转换数字,防止硬件发空字符串导致崩溃
double parseD(int index) =>
(index < parts.length && parts[index].isNotEmpty)
? double.tryParse(parts[index]) ?? 0.0
: 0.0;
int parseI(int index) => (index < parts.length && parts[index].isNotEmpty)
? int.tryParse(parts[index]) ?? 0
: 0;
String parseS(int index) => (index < parts.length) ? parts[index] : "";
ControlMode mapMode(int val) {
switch (val) {
case 1:
return ControlMode.LOCAL;
case 2:
return ControlMode.BLE;
case 3:
return ControlMode.TCP;
case 4:
return ControlMode.OTHER;
default:
return ControlMode.NONE; // 0 或其他异常值
}
}
return RunningStatusModel(
voltage: voltage ?? this.voltage,
leftTargetSpeed: leftTargetSpeed ?? this.leftTargetSpeed,
rightTargetSpeed: rightTargetSpeed ?? this.rightTargetSpeed,
leftMeasureSpeed: leftMeasureSpeed ?? this.leftMeasureSpeed,
rightMeasureSpeed: rightMeasureSpeed ?? this.rightMeasureSpeed,
leftCurrent: leftCurrent ?? this.leftCurrent,
rightCurrent: rightCurrent ?? this.rightCurrent,
leftMotorTemp: leftMotorTemp ?? this.leftMotorTemp,
rightMotorTemp: rightMotorTemp ?? this.rightMotorTemp,
chipTemp: chipTemp ?? this.chipTemp,
yaw: yaw ?? this.yaw,
pitch: pitch ?? this.pitch,
roll: roll ?? this.roll,
satelliteCnt: satelliteCnt ?? this.satelliteCnt,
qual: qual ?? this.qual,
headingStatus: headingStatus ?? this.headingStatus,
latitude: latitude ?? this.latitude,
longitude: longitude ?? this.longitude,
time: time ?? this.time,
knifeCuttingSpeed: knifeCuttingSpeed ?? this.knifeCuttingSpeed,
controlMode: controlMode ?? this.controlMode,
workingArea: workingArea ?? this.workingArea,
battery: battery ?? this.battery,
voltage: parseD(0), // 电压
leftTargetSpeed: parseI(1), // 左轮目标速度
rightTargetSpeed: parseI(2), // 右轮目标速度
leftMeasureSpeed: parseI(3), // 左轮测量速度
rightMeasureSpeed: parseI(4), // 右轮测量速度
leftCurrent: parseD(5), // 左轮电流
rightCurrent: parseD(6), // 右轮电流
leftMotorTemp: parseD(7), // 左轮温度
rightMotorTemp: parseD(8), // 右轮温度
chipTemp: parseD(9), // 芯片温度
yaw: parseD(10), // 偏航角
pitch: parseD(11), // 仰俯角
roll: parseD(12), // 翻滚角
satelliteCnt: parseI(13), // 卫星数
qual: parseI(14), // 定位质量 (0-7)
headingStatus: parseI(15), // 航向角状态
latitude: parseD(16), // 纬度
longitude: parseD(17), // 经度
time: parseS(18), // 时间字符串
knifeCuttingSpeed: parseI(19), // 割刀速度
controlMode: mapMode(20), // 控制模式 (0-4)
battery: parseD(21), // 电池电量 (0-100)
workingArea: parseD(22), // 作业面积
obstacleFlag: parseI(23), // 障碍物标志 (0/1)
);
}
}