APP远程遥控推出页面释放权限集成-待测试
This commit is contained in:
@@ -70,4 +70,47 @@ class RemoteHttpDatasource {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///app退出远程控制后释放权限
|
||||
Future<bool> releaseRemoteControlViaHttp( String platform) async {
|
||||
_logger.logWithLevel("app退出远程控制后释放权限 开始");
|
||||
final user = await _userStorage.getUser();
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
final token = user.token;
|
||||
final response = await _dio.post(
|
||||
'/forward/device/releaseControl',
|
||||
options: Options(
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ${token}',
|
||||
},
|
||||
),
|
||||
data: {'platform': "app"});
|
||||
try {
|
||||
final responseData = response.data as Map<String, dynamic>;
|
||||
//debugPrint("📊 [HTTP 响应] 完整数据:$responseData");
|
||||
_logger.log("releaseRemoteControlViaHttp 响应] 完整数据:$responseData");
|
||||
// 🔥 关键:先获取响应的 data 字段,再获取 remoteControl
|
||||
final dataField = responseData['data'] as Map<String, dynamic>?;
|
||||
if (dataField != null) {
|
||||
final bool hasRemoteControl = dataField['remoteControl'] as bool? ?? false;
|
||||
//debugPrint("✅ [HTTP 响应] remoteControl=$hasRemoteControl");
|
||||
_logger.log("releaseRemoteControlViaHttp响应] remoteControl=$hasRemoteControl");
|
||||
// 🔥 直接返回 remoteControl 的布尔值
|
||||
return hasRemoteControl;
|
||||
} else {
|
||||
//debugPrint("❌ [HTTP 响应] 缺少 data 字段");
|
||||
_logger.log("❌ [HTTP 响应] 缺少 data 字段");
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
// debugPrint('❌ [RemoteHttp] 解析响应失败:$e');
|
||||
_logger.log('❌ [RemoteHttp] 解析响应失败:$e');
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@ class RemoteControlRepositoryImpl implements RemoteControlRepository {
|
||||
void sendControlMachineCmd(MachineControlStatusEntity status) {
|
||||
// 1. 调用算法:将摇杆坐标 (x, y) 转换为左右轮电机转速
|
||||
final speeds = _diffSteer.calculate(status.originX, status.originY);
|
||||
|
||||
|
||||
//debugPrint('🎮 [摇杆数据] originX: ${status.originX}, originY: ${status.originY}');
|
||||
_logger.logWithLevel('⚙️ [电机速度] left: ${speeds['left']}, right: ${speeds['right']}');
|
||||
|
||||
@@ -54,15 +52,18 @@ class RemoteControlRepositoryImpl implements RemoteControlRepository {
|
||||
ignition: status.ignitionStatus,
|
||||
emergency: status.isEmergency ? 1 : 0,
|
||||
);
|
||||
debugPrint('📦 [发送数据] payload: ${payload}');
|
||||
debugPrint('📦 [发送数据] emergency 字节值:${payload[7]}');
|
||||
//debugPrint('📦 [发送数据] payload: ${payload}');
|
||||
_logger.logWithLevel('📦 [发送数据] payload: ${payload}');
|
||||
//debugPrint('📦 [发送数据] emergency 字节值:${payload[7]}');
|
||||
_logger.logWithLevel('📦 [发送数据] emergency 字节值:${payload[7]}');
|
||||
// 3. 调用 TcpClient:发送指令。
|
||||
// TcpClient.sendRaw 会自动帮你加上 [0xAB, 0xAA] 头和 [0xAA, 0xAB] 尾
|
||||
_tcpClient.sendRaw(
|
||||
MachineProtocolConstants.cmdRemoteControl, // 这里通常是 0x00
|
||||
payload,
|
||||
);
|
||||
debugPrint('✅ [TCP] 指令已发送');
|
||||
//debugPrint('✅ [TCP] 指令已发送');
|
||||
_logger.logWithLevel('✅ [TCP] 指令已发送');
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -91,4 +92,9 @@ class RemoteControlRepositoryImpl implements RemoteControlRepository {
|
||||
_remoteTcp.sendSwitchControlResponse(false, deviceId);
|
||||
}
|
||||
}
|
||||
///app退出远程控制后释放权限
|
||||
@override
|
||||
Future<bool> releasePermission(String platform) async {
|
||||
return await _remoteHttp.releaseRemoteControlViaHttp(platform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,4 +20,7 @@ abstract class RemoteControlRepository {
|
||||
|
||||
/// 新增:响应控制权限 同意和拒绝(发送 0x05 指令)
|
||||
void respondPermission(bool bool, String deviceId);
|
||||
|
||||
///APP 推出远程控制页面后释放权限
|
||||
Future<bool> releasePermission(String platform);
|
||||
}
|
||||
|
||||
@@ -229,7 +229,15 @@ class RemoteControlCubit extends Cubit<RemoteControlState> {
|
||||
void startControlLoop() {
|
||||
_timer?.cancel();
|
||||
_timer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
|
||||
// 核心调用:直接把 state 里的实体丢给 repository
|
||||
// 🔥 安全检查:无权限或急停时不发送
|
||||
if (!state.hasPermission || state.isEmergency) {
|
||||
debugPrint('⚠️ [定时器] 跳过发送 - hasPermission=${state.hasPermission}, isEmergency=${state.isEmergency}');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
debugPrint('⏰ [定时器] 发送控制指令 - originX=${state.controlEntity.originX}, originY=${state.controlEntity.originY}');
|
||||
_logger.logWithLevel('真实的发送的实体 - originX: ${state.controlEntity.originX}, originY: ${state.controlEntity.originY}');
|
||||
_repository.sendControlMachineCmd(state.controlEntity);
|
||||
});
|
||||
emit(state.copyWith(status: RemoteControlStatus.controlling));
|
||||
@@ -264,16 +272,36 @@ class RemoteControlCubit extends Cubit<RemoteControlState> {
|
||||
}
|
||||
|
||||
void updateOriginY(int y) {
|
||||
debugPrint('📥 [updateOriginY] 收到参数 y=$y');
|
||||
final updatedEntity = state.controlEntity.copyWith(
|
||||
y: y,
|
||||
);
|
||||
debugPrint('📤 [updateOriginY] 创建 updatedEntity.y=${updatedEntity.originY}');
|
||||
emit(state.copyWith(controlEntity: updatedEntity));
|
||||
debugPrint('✅ [updateOriginY] emit 完成,当前 state.controlEntity.originY=${state.controlEntity.originY}');
|
||||
|
||||
// 🔥 关键修复:如果归零,立即发送停止指令,使用更新后的实体
|
||||
if (y == 0) {
|
||||
_logger.logWithLevel('🛑 [updateOriginY] 检测到归零,立即发送停止指令');
|
||||
debugPrint('🛑 [updateOriginY] 发送 updatedEntity: originX=${updatedEntity.originX}, originY=${updatedEntity.originY}');
|
||||
_repository.sendControlMachineCmd(updatedEntity);
|
||||
}
|
||||
}
|
||||
void updateOriginX(int x) {
|
||||
debugPrint('📥 [updateOriginX] 收到参数 x=$x');
|
||||
final updatedEntity = state.controlEntity.copyWith(
|
||||
x: x,
|
||||
);
|
||||
debugPrint('📤 [updateOriginX] 创建 updatedEntity.x=${updatedEntity.originX}');
|
||||
emit(state.copyWith(controlEntity: updatedEntity));
|
||||
debugPrint('✅ [updateOriginX] emit 完成,当前 state.controlEntity.originX=${state.controlEntity.originX}');
|
||||
|
||||
// 🔥 关键修复:如果归零,立即发送停止指令,使用更新后的实体
|
||||
if (x == 0) {
|
||||
_logger.logWithLevel('🛑 [updateOriginX] 检测到归零,立即发送停止指令');
|
||||
debugPrint('🛑 [updateOriginX] 发送 updatedEntity: originX=${updatedEntity.originX}, originY=${updatedEntity.originY}');
|
||||
_repository.sendControlMachineCmd(updatedEntity);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 停止控制循环
|
||||
@@ -416,6 +444,10 @@ class RemoteControlCubit extends Cubit<RemoteControlState> {
|
||||
return 9999;
|
||||
}
|
||||
}
|
||||
//app退出远程遥控界面释放权限
|
||||
Future<bool> releasePermission(String platform) async {
|
||||
return await _repository.releasePermission(platform);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -28,11 +28,13 @@ class RemoteControlPage extends StatefulWidget {
|
||||
class _RemoteControlPageState extends State<RemoteControlPage> {
|
||||
String _videoStreamUrl = "";
|
||||
late RemoteControlCubit _cubit;
|
||||
DevicesCubit? _devicesCubit;
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_cubit = context.read<RemoteControlCubit>();
|
||||
_devicesCubit = context.read<DevicesCubit>();
|
||||
}
|
||||
@override
|
||||
void initState() {
|
||||
@@ -53,9 +55,16 @@ class _RemoteControlPageState extends State<RemoteControlPage> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// 释放远程控制权限
|
||||
// _cubit.releasePermission("app");
|
||||
//print("远程控制要推出啦");
|
||||
final deviceState = _devicesCubit?.state;
|
||||
if (deviceState?.selectedDevice != null) {
|
||||
_cubit.releasePermission("app");
|
||||
}
|
||||
|
||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
// context.read<RemoteControlCubit>().stopControlLoop();
|
||||
_cubit.stopControlLoop();
|
||||
super.dispose();
|
||||
}
|
||||
@@ -138,7 +147,7 @@ class _RemoteControlPageState extends State<RemoteControlPage> {
|
||||
width: sideAreaWidth,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: LeftJoystickArea(isLocked: remoteState.isLocked, width: sideAreaWidth * 0.5 * 0.7),
|
||||
child: LeftJoystickArea(isLocked: remoteState.isLocked, width: sideAreaWidth * 0.45),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -156,7 +165,7 @@ class _RemoteControlPageState extends State<RemoteControlPage> {
|
||||
width: sideAreaWidth,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: RightJoystickArea(isLocked: remoteState.isLocked, width: sideAreaWidth * 0.5 * 0.7),
|
||||
child: RightJoystickArea(isLocked: remoteState.isLocked, width: sideAreaWidth * 0.45),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user