killapp/Assets/Scripts/Base/BLECommunicationManager.cs
2026-03-30 16:25:00 +08:00

2358 lines
75 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
using System;
using System.Collections.Generic;
using BLEProtocol;
/// <summary>
/// BLE通信管理器 - 处理协议层通信
/// 基于 BluetoothManager 进行协议通信
/// </summary>
public class BLECommunicationManager : MonoBehaviour
{
public static BLECommunicationManager Instance { get; private set; }
// 事件定义
public event Action<DeviceRegistrationStatus> OnRegistrationStatusReceived; // 收到注册状态
public event Action<bool, string> OnRegisterResult; // 注册结果 (成功/失败, 消息)
public event Action<UserListResponse> OnUserListReceived; // 收到用户列表
public event Action<UnregisterUserResponse> OnUnregisterUserResult; // 注销用户结果
public event Action<UserLoginResponse> OnUserLoginResult; // 用户登录结果
public event Action<FingerprintEnableResponse> OnFingerprintEnableResult; // 指纹使能设置结果
public event Action<FingerprintRecordResponse> OnFingerprintRecordResult; // 指纹录制结果
public event Action<LanguageSetting> OnLanguageSettingReceived; // 收到语言设置
public event Action<TimeSetting> OnTimeSettingReceived; // 收到时间设置
public event Action<ScheduleTaskListResponse> OnScheduleTaskListReceived; // 收到定时任务列表
public event Action<LCDSleepSetting> OnLCDSleepSettingReceived; // 收到LCD休眠设置
public event Action<LCDBrightnessSetting> OnLCDBrightnessSettingReceived; // 收到LCD亮度设置
public event Action<RGBControl> OnRGBControlReceived; // 收到RGB控制设置
public event Action<WIFIControl> OnWIFIControlReceived; // 收到WIFI控制设置
public event Action<BLEControl> OnBLEControlReceived; // 收到BLE控制设置
public event Action<MultimediaControl> OnMultimediaControlReceived; // 收到多媒体控制设置
public event Action<FillLightControl> OnFillLightControlReceived; // 收到补光灯控制设置
public event Action<FillLightConnectionStatus> OnFillLightConnectionStatusReceived; // 收到补光灯连接状态
public event Action<VisibleLaserControl> OnVisibleLaserControlReceived; // 收到可见光激光器控制设置
public event Action<AngleControl> OnAngleControlReceived; // 收到角度控制设置
public event Action<DistanceControl> OnDistanceControlReceived; // 收到距离控制设置
public event Action<MillimeterWaveSetting> OnMillimeterWaveSettingReceived; // 收到毫米波雷达设置
public event Action<VisualDetectionSetting> OnVisualDetectionSettingReceived; // 收到视觉检测设置
public event Action<AccelerometerSetting> OnAccelerometerSettingReceived; // 收到加速度传感器设置
public event Action<AccelerometerData> OnAccelerometerDataReceived; // 收到加速度传感器数据
public event Action<TemperatureMonitorSetting> OnTemperatureMonitorSettingReceived; // 收到温度监控设置
public event Action<EnvironmentChangeTest> OnEnvironmentChangeStatusReceived; // 收到环境变化状态
public event Action<WorkModeSetting> OnWorkModeSettingReceived; // 收到工作模式设置
public event Action<HardwareStatus> OnHardwareStatusReceived; // 收到硬件状态
public event Action<DeviceInfo> OnDeviceInfoReceived; // 收到设备信息
public event Action<StatisticsData> OnStatisticsDataReceived; // 收到统计数据
public event Action<SensorData> OnSensorDataReceived; // 收到传感器数据
public event Action<MosquitoData> OnMosquitoDataReceived; // 收到蚊虫数据通知
public event Action<byte[]> OnDataReceived; // 收到原始数据
public event Action<string> OnRawDataReceived; // 收到原始数据(十六进制字符串)
public event Action<string> OnRawDataSent; // 发送原始数据(十六进制字符串)
public event Action<string> OnCommunicationError; // 通信错误
// 状态
public bool IsWaitingResponse { get; private set; }
public byte LastCommand { get; private set; }
// 响应超时设置 (OTA传输需要更长时间增加到10秒)
public float ResponseTimeout = 10f;
// 数据接收缓冲区
private List<byte> _receiveBuffer = new List<byte>();
private float _responseTimer;
private Action<BLEResponse> _pendingCallback;
// 服务和特征UUID (根据实际设备配置)
public string ServiceUUID = "0000ffe0-0000-1000-8000-00805f9b34fb";
public string WriteCharacteristicUUID = "0000ffe1-0000-1000-8000-00805f9b34fb";
public string NotifyCharacteristicUUID = "0000ffe1-0000-1000-8000-00805f9b34fb";
// 是否自动初始化通信
public bool AutoInitialize = true;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
Log("[BLECommunicationManager.Start] 开始执行...");
// 订阅蓝牙连接事件
if (BluetoothManager.Instance != null)
{
Log($"[BLECommunicationManager.Start] BluetoothManager.Instance 存在IsConnected={BluetoothManager.Instance.IsConnected}");
BluetoothManager.Instance.OnConnectedSuccess += OnBluetoothConnected;
BluetoothManager.Instance.OnDisconnected += OnBluetoothDisconnected;
BluetoothManager.Instance.OnError += OnBluetoothError;
Log("[BLECommunicationManager.Start] 事件订阅完成");
// 如果已经连接(可能是自动连接已完成),立即初始化
if (BluetoothManager.Instance.IsConnected)
{
Log("[BLECommunicationManager.Start] 检测到蓝牙已连接,立即初始化通信...");
OnBluetoothConnected();
}
else
{
Log("[BLECommunicationManager.Start] 蓝牙未连接,等待连接事件...");
}
}
else
{
LogError("[BLECommunicationManager.Start] BluetoothManager.Instance 为 null");
}
}
/// <summary>
/// 蓝牙错误回调
/// </summary>
private void OnBluetoothError(string error)
{
// 忽略 "Service not found" 错误,因为这是正常的(还没连接设备)
if (error.Contains("Service not found"))
{
Log("蓝牙服务未找到(正常:尚未连接设备)");
return;
}
LogError($"蓝牙错误: {error}");
}
private void OnDestroy()
{
// 取消订阅事件
if (BluetoothManager.Instance != null)
{
BluetoothManager.Instance.OnConnectedSuccess -= OnBluetoothConnected;
BluetoothManager.Instance.OnDisconnected -= OnBluetoothDisconnected;
BluetoothManager.Instance.OnError -= OnBluetoothError;
}
if (Instance == this)
{
Instance = null;
}
}
private void Update()
{
// 响应超时检测
if (IsWaitingResponse)
{
_responseTimer -= Time.deltaTime;
if (_responseTimer <= 0)
{
OnResponseTimeout();
}
}
}
#region
/// <summary>
/// 蓝牙连接成功回调(特征发现完成后调用)
/// </summary>
private void OnBluetoothConnected()
{
if (AutoInitialize)
InitializeCommunication();
}
/// <summary>
/// 蓝牙断开连接回调
/// </summary>
private void OnBluetoothDisconnected(string address)
{
Log($"蓝牙已断开: {address}");
// 清理状态
IsWaitingResponse = false;
_responseTimer = 0;
_pendingCallback = null;
_receiveBuffer.Clear();
}
/// <summary>
/// 初始化BLE通信 (连接成功后自动调用,也可手动调用)
/// </summary>
public void InitializeCommunication()
{
if (BluetoothManager.Instance == null || !BluetoothManager.Instance.IsConnected) return;
ServiceUUID = ServiceUUID.ToLower();
WriteCharacteristicUUID = WriteCharacteristicUUID.ToLower();
NotifyCharacteristicUUID = NotifyCharacteristicUUID.ToLower();
SubscribeToNotifications();
}
/// <summary>
/// 订阅设备通知
/// </summary>
private void SubscribeToNotifications()
{
string deviceAddress = BluetoothManager.Instance.ConnectedDeviceAddress;
ServiceUUID = ServiceUUID.ToLower();
WriteCharacteristicUUID = WriteCharacteristicUUID.ToLower();
NotifyCharacteristicUUID = NotifyCharacteristicUUID.ToLower();
Log($"[BLE-DEBUG] 订阅通知: 地址={deviceAddress}");
try
{
BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress(
deviceAddress,
ServiceUUID,
NotifyCharacteristicUUID,
(notifyAddress, notifyCharacteristic) =>
{
Log($"[BLE-DEBUG] 订阅成功: {notifyCharacteristic}");
},
(address, characteristicUUID, bytes) =>
{
OnNotificationReceived(bytes);
}
);
}
catch (System.Exception ex)
{
LogError($"[BLE-DEBUG] 订阅异常: {ex.Message}");
}
}
/// <summary>
/// 取消订阅通知
/// </summary>
public void UnsubscribeNotifications()
{
if (BluetoothManager.Instance == null || !BluetoothManager.Instance.IsConnected)
return;
string deviceAddress = BluetoothManager.Instance.ConnectedDeviceAddress;
BluetoothLEHardwareInterface.UnSubscribeCharacteristic(
deviceAddress,
ServiceUUID,
NotifyCharacteristicUUID,
null
);
}
#endregion
#region
/// <summary>
/// 查询设备注册状态 (命令 0x01)
/// </summary>
public void QueryRegistrationStatus(Action<DeviceRegistrationStatus> callback = null)
{
if (!CheckConnection()) return;
// 构建查询帧
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_QUERY_REGISTRATION,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
if (response.IsSuccess && response.Data != null)
{
var status = DeviceRegistrationStatus.FromBytes(response.Data);
callback?.Invoke(status);
OnRegistrationStatusReceived?.Invoke(status);
}
else
{
LogError($"查询注册状态失败: 状态码={response.Status:X2}");
callback?.Invoke(new DeviceRegistrationStatus());
}
});
}
/// <summary>
/// 设备注册绑定 (命令 0x02)
/// 注意:根据协议,只发送用户名,不发送密码
/// </summary>
/// <param name="username">用户名</param>
/// <param name="callback">回调 (成功/失败, 消息)</param>
public void RegisterDevice(string username, Action<bool, string> callback = null)
{
if (!CheckConnection()) return;
// 验证输入
if (string.IsNullOrEmpty(username) || username.Length > BLEConstants.MAX_USERNAME_LENGTH)
{
callback?.Invoke(false, $"用户名长度必须在1-{BLEConstants.MAX_USERNAME_LENGTH}之间");
return;
}
// 构建注册请求(只发送用户名)
var request = new DeviceRegisterRequest
{
Username = username
};
byte[] requestData = request.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_DEVICE_REGISTER,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)requestData.Length,
Data = requestData
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
string message = GetStatusMessage(response.Status);
if (success)
{
Log($"设备注册成功: 用户={username}");
if (response.Data != null && response.Data.Length > 0)
{
Log($"注册响应数据: {System.BitConverter.ToString(response.Data)}");
}
}
else
{
LogError($"设备注册失败: {message}");
}
callback?.Invoke(success, message);
OnRegisterResult?.Invoke(success, message);
});
}
/// <summary>
/// 用户登录 (命令 0x03)
/// 数据格式:用户名(16字节) + 解锁状态(1字节)解锁状态固定为1
/// </summary>
/// <param name="username">用户名</param>
/// <param name="callback">回调 (响应结果)</param>
public void UserLogin(string username, Action<UserLoginResponse> callback = null)
{
if (!CheckConnection()) return;
// 验证输入
if (string.IsNullOrEmpty(username) || username.Length > BLEConstants.MAX_USERNAME_LENGTH)
{
LogError($"用户名长度必须在1-{BLEConstants.MAX_USERNAME_LENGTH}之间");
callback?.Invoke(new UserLoginResponse { Status = BLEConstants.STATUS_PARAM_ERROR });
return;
}
// 构建登录请求
var request = new UserLoginRequest
{
Username = username,
UnlockStatus = 0x01 // 解锁状态固定为1
};
byte[] requestData = request.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_USER_LOGIN,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)requestData.Length,
Data = requestData
};
SendFrame(frame, (response) =>
{
var loginResponse = UserLoginResponse.FromBytes(response.Status);
if (loginResponse.IsSuccess)
{
Log($"用户登录成功: {username}");
}
else
{
LogError($"用户登录失败: {username}, 状态码={response.Status:X2}");
}
callback?.Invoke(loginResponse);
OnUserLoginResult?.Invoke(loginResponse);
});
}
/// <summary>
/// 指纹登录使能设置 (命令 0x04)
/// 数据格式:用户名(16字节) + 使能状态(1字节)
/// </summary>
/// <param name="username">用户名</param>
/// <param name="enable">使能状态true=使能, false=禁用</param>
/// <param name="callback">回调 (响应结果)</param>
public void SetFingerprintEnable(string username, bool enable, Action<FingerprintEnableResponse> callback = null)
{
if (!CheckConnection()) return;
// 验证输入
if (string.IsNullOrEmpty(username) || username.Length > BLEConstants.MAX_USERNAME_LENGTH)
{
LogError($"用户名长度必须在1-{BLEConstants.MAX_USERNAME_LENGTH}之间");
callback?.Invoke(new FingerprintEnableResponse { Status = BLEConstants.STATUS_PARAM_ERROR });
return;
}
// 构建请求
var request = new FingerprintEnableRequest
{
Username = username,
Enable = enable
};
byte[] requestData = request.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_FINGERPRINT_ENABLE,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)requestData.Length,
Data = requestData
};
SendFrame(frame, (response) =>
{
var enableResponse = FingerprintEnableResponse.FromBytes(response.Status);
if (enableResponse.IsSuccess)
{
Log($"指纹登录使能设置成功: {username}, 状态={(enable ? "使" : "")}");
}
else
{
LogError($"指纹登录使能设置失败: {username}, 状态码={response.Status:X2}");
}
callback?.Invoke(enableResponse);
OnFingerprintEnableResult?.Invoke(enableResponse);
});
}
/// <summary>
/// 指纹录制请求 (命令 0x05)
/// 启动指纹注册流程
/// </summary>
/// <param name="username">用户名</param>
/// <param name="callback">回调 (响应结果)</param>
public void StartFingerprintRecord(string username, Action<FingerprintRecordResponse> callback = null)
{
if (!CheckConnection()) return;
// 验证输入
if (string.IsNullOrEmpty(username) || username.Length > BLEConstants.MAX_USERNAME_LENGTH)
{
LogError($"用户名长度必须在1-{BLEConstants.MAX_USERNAME_LENGTH}之间");
callback?.Invoke(new FingerprintRecordResponse { Status = BLEConstants.STATUS_PARAM_ERROR });
return;
}
// 构建请求
var request = new FingerprintRecordRequest
{
Username = username
};
byte[] requestData = request.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_FINGERPRINT_RECORD,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)requestData.Length,
Data = requestData
};
SendFrame(frame, (response) =>
{
var recordResponse = FingerprintRecordResponse.FromBytes(response.Status);
if (recordResponse.IsSuccess)
{
Log($"指纹录制请求成功: {username}");
}
else
{
LogError($"指纹录制请求失败: {username}, 状态码={response.Status:X2}");
}
callback?.Invoke(recordResponse);
OnFingerprintRecordResult?.Invoke(recordResponse);
});
}
#region (0x10-0x1F)
/// <summary>
/// 读取语言设置 (命令 0x10)
/// </summary>
public void ReadLanguageSetting(Action<LanguageSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_LANGUAGE_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = LanguageSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnLanguageSettingReceived?.Invoke(setting);
});
}
/// <summary>
/// 写入语言设置 (命令 0x10)
/// </summary>
/// <param name="isChinese">true=中文, false=英文</param>
public void WriteLanguageSetting(bool isChinese, Action<bool> callback = null)
{
if (!CheckConnection()) return;
var setting = new LanguageSetting { Language = isChinese ? (byte)0x01 : (byte)0x00 };
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_LANGUAGE_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"语言设置成功: {(isChinese ? "" : "")}");
else
LogError($"语言设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取时间设置 (命令 0x11)
/// </summary>
public void ReadTimeSetting(Action<TimeSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_TIME_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = TimeSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnTimeSettingReceived?.Invoke(setting);
});
}
/// <summary>
/// 写入时间设置 (命令 0x11)
/// </summary>
public void WriteTimeSetting(TimeSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_TIME_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"时间设置成功: {setting}");
else
LogError($"时间设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取定时任务列表 (命令 0x12)
/// </summary>
public void ReadScheduleTasks(Action<ScheduleTaskListResponse> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_SCHEDULE_TASK,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var taskList = ScheduleTaskListResponse.FromBytes(response.Status, response.Data);
callback?.Invoke(taskList);
OnScheduleTaskListReceived?.Invoke(taskList);
});
}
/// <summary>
/// 写入定时任务 (命令 0x12)
/// 支持一次写入单条或多条定时任务最多5条
/// </summary>
/// <param name="task">单条定时任务</param>
/// <param name="callback">回调 (成功/失败)</param>
public void WriteScheduleTask(ScheduleTask task, Action<bool> callback = null)
{
WriteScheduleTasks(new ScheduleTask[] { task }, callback);
}
/// <summary>
/// 写入多条定时任务 (命令 0x12)
/// 支持一次写入最多5组定时任务硬件已支持批量写入
/// </summary>
/// <param name="tasks">定时任务数组最多5条每条8字节</param>
/// <param name="callback">回调 (成功/失败)</param>
public void WriteScheduleTasks(ScheduleTask[] tasks, Action<bool> callback = null)
{
if (!CheckConnection()) return;
if (tasks == null || tasks.Length == 0)
{
LogError("定时任务数组为空");
callback?.Invoke(false);
return;
}
if (tasks.Length > 5)
{
LogError("定时任务数量不能超过5条");
callback?.Invoke(false);
return;
}
// 计算总数据长度每条任务8字节
int totalLength = tasks.Length * 8;
byte[] data = new byte[totalLength];
// 将所有任务序列化到字节数组
for (int i = 0; i < tasks.Length; i++)
{
byte[] taskBytes = tasks[i].ToBytes();
Buffer.BlockCopy(taskBytes, 0, data, i * 8, 8);
}
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_SCHEDULE_TASK,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
{
if (tasks.Length == 1)
Log($"定时任务设置成功: {tasks[0]}");
else
Log($"定时任务批量设置成功,共 {tasks.Length} 条任务");
}
else
{
LogError($"定时任务设置失败, 状态码={response.Status:X2}");
}
callback?.Invoke(success);
});
}
#endregion
#region (0x20-0x3F)
/// <summary>
/// 读取LCD休眠设置 (命令 0x20)
/// </summary>
public void ReadLCDSleepSetting(Action<LCDSleepSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_LCD_SLEEP_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = LCDSleepSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnLCDSleepSettingReceived?.Invoke(setting);
});
}
/// <summary>
/// 写入LCD休眠设置 (命令 0x20)
/// </summary>
public void WriteLCDSleepSetting(LCDSleepSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_LCD_SLEEP_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"LCD休眠设置成功: 开关={(setting.Enable ? "" : "")}, 时间={setting.GetSleepTimeString()}");
else
LogError($"LCD休眠设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取LCD亮度设置 (命令 0x21)
/// </summary>
public void ReadLCDBrightnessSetting(Action<LCDBrightnessSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_LCD_BRIGHTNESS_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = LCDBrightnessSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnLCDBrightnessSettingReceived?.Invoke(setting);
});
}
/// <summary>
/// 写入LCD亮度设置 (命令 0x21)
/// </summary>
public void WriteLCDBrightnessSetting(LCDBrightnessSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_LCD_BRIGHTNESS_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
Log($"LCD亮度设置响应: 状态码={response.Status:X2}, 成功={success}");
if (success)
Log($"LCD亮度设置成功: 自适应={(setting.AutoBrightness ? "" : "")}, 亮度={setting.Brightness}%");
else
LogError($"LCD亮度设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取RGB指示灯控制 (命令 0x22)
/// </summary>
public void ReadRGBControl(Action<RGBControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_RGB_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = RGBControl.FromBytes(response.Data);
callback?.Invoke(control);
OnRGBControlReceived?.Invoke(control);
});
}
/// <summary>
/// 写入RGB指示灯控制 (命令 0x22)
/// </summary>
public void WriteRGBControl(RGBControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_RGB_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"RGB控制设置成功: 开关={(control.Enable ? "" : "")}, 颜色={control.Red},{control.Green},{control.Blue}");
else
LogError($"RGB控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取WIFI控制 (命令 0x23)
/// </summary>
public void ReadWIFIControl(Action<WIFIControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_WIFI_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = WIFIControl.FromBytes(response.Data);
callback?.Invoke(control);
OnWIFIControlReceived?.Invoke(control);
});
}
/// <summary>
/// 写入WIFI控制 (命令 0x23)
/// </summary>
public void WriteWIFIControl(WIFIControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_WIFI_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"WIFI控制设置成功: 开关={(control.Enable ? "" : "")}, SSID={control.SSID}");
else
LogError($"WIFI控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取BLE控制 (命令 0x24)
/// </summary>
public void ReadBLEControl(Action<BLEControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_BLE_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = BLEControl.FromBytes(response.Data);
callback?.Invoke(control);
OnBLEControlReceived?.Invoke(control);
});
}
/// <summary>
/// 写入BLE控制 (命令 0x24)
/// </summary>
public void WriteBLEControl(BLEControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_BLE_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"BLE控制设置成功: 设备名称={control.DeviceName}");
else
LogError($"BLE控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取多媒体控制 (命令 0x25)
/// </summary>
public void ReadMultimediaControl(Action<MultimediaControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_MULTIMEDIA_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = MultimediaControl.FromBytes(response.Data);
callback?.Invoke(control);
OnMultimediaControlReceived?.Invoke(control);
});
}
/// <summary>
/// 写入多媒体控制 (命令 0x25)
/// </summary>
public void WriteMultimediaControl(MultimediaControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_MULTIMEDIA_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"多媒体控制设置成功: 视频录制={(control.VideoRecordEnable ? "" : "")}, 音效={(control.SoundEnable ? "" : "")}");
else
LogError($"多媒体控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取补光灯控制 (命令 0x26)
/// </summary>
public void ReadFillLightControl(Action<FillLightControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_FILL_LIGHT_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = FillLightControl.FromBytes(response.Data);
callback?.Invoke(control);
OnFillLightControlReceived?.Invoke(control);
});
}
/// <summary>
/// 写入补光灯控制 (命令 0x26)
/// </summary>
public void WriteFillLightControl(FillLightControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_FILL_LIGHT_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"补光灯控制设置成功: 开关={(control.Enable ? "" : "")}, 类型={control.GetLightTypeString()}, 强度={control.GetIntensityString()}");
else
LogError($"补光灯控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取补光灯连接状态 (命令 0x27)
/// </summary>
public void ReadFillLightConnectionStatus(Action<FillLightConnectionStatus> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_FILL_LIGHT_CONNECTION_STATUS,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var status = FillLightConnectionStatus.FromBytes(response.Data);
callback?.Invoke(status);
OnFillLightConnectionStatusReceived?.Invoke(status);
});
}
/// <summary>
/// 读取可见光激光器控制 (命令 0x28)
/// </summary>
public void ReadVisibleLaserControl(Action<VisibleLaserControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_VISIBLE_LASER_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = VisibleLaserControl.FromBytes(response.Data);
callback?.Invoke(control);
OnVisibleLaserControlReceived?.Invoke(control);
});
}
/// <summary>
/// 写入可见光激光器控制 (命令 0x28)
/// </summary>
public void WriteVisibleLaserControl(VisibleLaserControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_VISIBLE_LASER_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"可见光激光器控制设置成功: 开关={(control.Enable ? "" : "")}");
else
LogError($"可见光激光器控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
#endregion
#region (0x40-0x4F)
/// <summary>
/// 读取角度控制设置 (命令 0x40)
/// </summary>
public void ReadAngleControl(Action<AngleControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_ANGLE_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = AngleControl.FromBytes(response.Data);
callback?.Invoke(control);
OnAngleControlReceived?.Invoke(control);
Log($"读取角度控制: {control}");
});
}
/// <summary>
/// 写入角度控制设置 (命令 0x40)
/// </summary>
/// <param name="control">角度控制设置</param>
public void WriteAngleControl(AngleControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_ANGLE_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"角度控制设置成功: {control}");
else
LogError($"角度控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取距离控制设置 (命令 0x41)
/// </summary>
public void ReadDistanceControl(Action<DistanceControl> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_DISTANCE_CONTROL,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var control = DistanceControl.FromBytes(response.Data);
callback?.Invoke(control);
OnDistanceControlReceived?.Invoke(control);
Log($"读取距离控制: {control}");
});
}
/// <summary>
/// 写入距离控制设置 (命令 0x41)
/// </summary>
/// <param name="control">距离控制设置</param>
public void WriteDistanceControl(DistanceControl control, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = control.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_DISTANCE_CONTROL,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"距离控制设置成功: {control}");
else
LogError($"距离控制设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
#endregion
#region (0x50-0x5F)
/// <summary>
/// 读取毫米波雷达设置 (命令 0x50)
/// </summary>
public void ReadMillimeterWaveSetting(Action<MillimeterWaveSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_MILLIMETER_WAVE_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = MillimeterWaveSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnMillimeterWaveSettingReceived?.Invoke(setting);
Log($"读取毫米波雷达设置: {setting}");
});
}
/// <summary>
/// 写入毫米波雷达设置 (命令 0x50)
/// </summary>
public void WriteMillimeterWaveSetting(MillimeterWaveSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_MILLIMETER_WAVE_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"毫米波雷达设置成功: {setting}");
else
LogError($"毫米波雷达设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取视觉检测设置 (命令 0x51)
/// </summary>
public void ReadVisualDetectionSetting(Action<VisualDetectionSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_VISUAL_DETECTION_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = VisualDetectionSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnVisualDetectionSettingReceived?.Invoke(setting);
Log($"读取视觉检测设置: {setting}");
});
}
/// <summary>
/// 写入视觉检测设置 (命令 0x51)
/// </summary>
public void WriteVisualDetectionSetting(VisualDetectionSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_VISUAL_DETECTION_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"视觉检测设置成功: {setting}");
else
LogError($"视觉检测设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 读取加速度传感器设置 (命令 0x52)
/// </summary>
public void ReadAccelerometerSetting(Action<AccelerometerSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_ACCELEROMETER_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = AccelerometerSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnAccelerometerSettingReceived?.Invoke(setting);
Log($"读取加速度传感器设置: {setting}");
});
}
/// <summary>
/// 写入加速度传感器设置 (命令 0x52)
/// </summary>
public void WriteAccelerometerSetting(AccelerometerSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_ACCELEROMETER_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"加速度传感器设置成功: {setting}");
else
LogError($"加速度传感器设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 查询加速度传感器数据 (命令 0x53)
/// </summary>
public void ReadAccelerometerData(Action<AccelerometerData> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_ACCELEROMETER_DATA,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var data = AccelerometerData.FromBytes(response.Data);
callback?.Invoke(data);
OnAccelerometerDataReceived?.Invoke(data);
Log($"读取加速度传感器数据: {data}");
});
}
/// <summary>
/// 读取温度监控设置 (命令 0x55)
/// </summary>
public void ReadTemperatureMonitorSetting(Action<TemperatureMonitorSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_TEMPERATURE_MONITOR_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = TemperatureMonitorSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnTemperatureMonitorSettingReceived?.Invoke(setting);
Log($"读取温度监控设置: {setting}");
});
}
/// <summary>
/// 写入温度监控设置 (命令 0x55)
/// </summary>
public void WriteTemperatureMonitorSetting(TemperatureMonitorSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_TEMPERATURE_MONITOR_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"温度监控设置成功: {setting}");
else
LogError($"温度监控设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
#endregion
#region (0xA0-0xBF)
/// <summary>
/// 读取工作模式 (命令 0xA0)
/// </summary>
public void ReadWorkMode(Action<WorkModeSetting> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_WORK_MODE_SETTING,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var setting = WorkModeSetting.FromBytes(response.Data);
callback?.Invoke(setting);
OnWorkModeSettingReceived?.Invoke(setting);
Log($"读取工作模式: {setting}");
});
}
/// <summary>
/// 写入工作模式 (命令 0xA0)
/// </summary>
public void WriteWorkMode(WorkModeSetting setting, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = setting.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_WORK_MODE_SETTING,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"工作模式设置成功: {setting}");
else
LogError($"工作模式设置失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 查询硬件状态 (命令 0xA1)
/// </summary>
public void ReadHardwareStatus(Action<HardwareStatus> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_HARDWARE_STATUS,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var status = HardwareStatus.FromBytes(response.Data);
callback?.Invoke(status);
OnHardwareStatusReceived?.Invoke(status);
Log($"查询硬件状态: {status}");
});
}
/// <summary>
/// 查询设备信息 (命令 0xA2)
/// </summary>
public void ReadDeviceInfo(Action<DeviceInfo> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_DEVICE_INFO,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var info = DeviceInfo.FromBytes(response.Data);
callback?.Invoke(info);
OnDeviceInfoReceived?.Invoke(info);
Log($"查询设备信息: {info}");
});
}
/// <summary>
/// 写入设备信息 (命令 0xA2 写操作)
/// 写操作接收56字节设备信息
/// </summary>
public void WriteDeviceInfo(DeviceInfoWrite deviceInfo, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = deviceInfo.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_DEVICE_INFO,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"设备信息写入成功: {deviceInfo}");
else
LogError($"设备信息写入失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 查询统计数据 (命令 0xA3)
/// </summary>
public void ReadStatisticsData(Action<StatisticsData> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_STATISTICS_DATA,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var stats = StatisticsData.FromBytes(response.Data);
callback?.Invoke(stats);
OnStatisticsDataReceived?.Invoke(stats);
Log($"查询统计数据: {stats}");
});
}
/// <summary>
/// 查询蚊虫数据 (命令 0xA4)
/// </summary>
public void QueryMosquitoData(MosquitoDataQuery query, Action<bool> callback = null)
{
if (!CheckConnection()) return;
byte[] data = query.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_MOSQUITO_DATA_QUERY,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"蚊虫数据查询成功: {query}");
else
LogError($"蚊虫数据查询失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 查询传感器数据 (命令 0xA5)
/// </summary>
public void ReadSensorData(Action<SensorData> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_SENSOR_DATA,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var data = SensorData.FromBytes(response.Data);
callback?.Invoke(data);
OnSensorDataReceived?.Invoke(data);
Log($"查询传感器数据: {data}");
});
}
#endregion
#region (0xA4 + 0x0B)
/// <summary>
/// 查询蚊虫数据数量 (命令 0xA4 读操作)
/// </summary>
public void ReadMosquitoDataCount(Action<MosquitoDataCount> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_MOSQUITO_DATA_QUERY,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var count = MosquitoDataCount.FromBytes(response.Data);
callback?.Invoke(count);
Log($"查询蚊虫数据数量: {count}");
});
}
/// <summary>
/// 请求蚊虫数据 (命令 0xA4 写操作)
/// 写操作成功后,设备通过通知机制发送数据
/// </summary>
public void RequestMosquitoData(uint count, Action<bool> callback = null)
{
if (!CheckConnection()) return;
// 构建4字节数据读取数量小端序
byte[] data = new byte[]
{
(byte)(count & 0xFF),
(byte)((count >> 8) & 0xFF),
(byte)((count >> 16) & 0xFF),
(byte)((count >> 24) & 0xFF)
};
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_MOSQUITO_DATA_QUERY,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log($"蚊虫数据请求成功,期望接收 {count} 条数据");
else
LogError($"蚊虫数据请求失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 处理蚊虫数据通知 (通知类型 0x0B)
/// </summary>
public void HandleMosquitoDataNotification(byte[] notifyData)
{
if (notifyData == null || notifyData.Length < 22)
{
LogError("蚊虫数据通知格式错误数据长度不足22字节");
return;
}
var mosquitoData = MosquitoData.FromBytes(notifyData);
Log($"收到蚊虫数据通知: {mosquitoData}");
OnMosquitoDataReceived?.Invoke(mosquitoData);
}
/// <summary>
/// 读取环境变化状态 (命令 0x56 读操作)
/// </summary>
public void ReadEnvironmentChangeStatus(Action<EnvironmentChangeTest> callback = null)
{
if (!CheckConnection()) return;
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_ENVIRONMENT_CHANGE_TEST,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
var status = EnvironmentChangeTest.FromBytes(response.Data);
callback?.Invoke(status);
OnEnvironmentChangeStatusReceived?.Invoke(status);
Log($"读取环境变化状态: {status}");
});
}
/// <summary>
/// 触发激光试射测试 (命令 0x56 写操作)
/// 触发激光进行3次试射测试每次间隔1秒每次持续10ms
/// </summary>
public void TriggerLaserTest(Action<bool> callback = null)
{
if (!CheckConnection()) return;
var test = new EnvironmentChangeTest { TriggerTest = true };
byte[] data = test.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_ENVIRONMENT_CHANGE_TEST,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)data.Length,
Data = data
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log("激光试射测试已触发将进行3次试射每次间隔1秒每次持续10ms");
else
LogError($"激光试射测试触发失败, 状态码={response.Status:X2}");
callback?.Invoke(success);
});
}
/// <summary>
/// 恢复出厂设置 (命令 0x60)
/// 需要管理员权限
/// 写操作发送1字节确认码 0x01
/// </summary>
public void FactoryReset(Action<bool> callback = null)
{
if (!CheckConnection()) return;
// 构建恢复出厂设置帧,发送确认码 0x01
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_FACTORY_RESET,
ReadWrite = BLEConstants.RW_WRITE,
Length = 1,
Data = new byte[] { 0x01 }
};
SendFrame(frame, (response) =>
{
bool success = response.IsSuccess;
if (success)
Log("恢复出厂设置命令发送成功,设备将恢复出厂设置");
else if (response.Status == BLEConstants.STATUS_PERMISSION_ERROR)
LogError("恢复出厂设置失败:需要管理员权限");
else
LogError($"恢复出厂设置失败, 状态码=0x{response.Status:X2}");
callback?.Invoke(success);
});
}
#endregion
/// <summary>
/// 查询用户列表 (命令 0x07)
/// </summary>
public void QueryUserList(Action<UserListResponse> callback = null)
{
if (!CheckConnection()) return;
// 构建查询帧
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_QUERY_USER_LIST,
ReadWrite = BLEConstants.RW_READ,
Length = 0,
Data = null
};
SendFrame(frame, (response) =>
{
if (response.IsSuccess && response.Data != null)
{
var userList = UserListResponse.FromBytes(response.Status, response.Data);
callback?.Invoke(userList);
OnUserListReceived?.Invoke(userList);
}
else
{
LogError($"查询用户列表失败: 状态码={response.Status:X2}");
callback?.Invoke(new UserListResponse() { Status = response.Status });
}
});
}
/// <summary>
/// 注销用户 (命令 0x08)
/// </summary>
/// <param name="username">要注销的用户名</param>
/// <param name="callback">回调 (响应结果)</param>
public void UnregisterUser(string username, Action<UnregisterUserResponse> callback = null)
{
if (!CheckConnection()) return;
// 验证输入
if (string.IsNullOrEmpty(username) || username.Length > BLEConstants.MAX_USERNAME_LENGTH)
{
LogError($"用户名长度必须在1-{BLEConstants.MAX_USERNAME_LENGTH}之间");
callback?.Invoke(new UnregisterUserResponse { Status = BLEConstants.STATUS_PARAM_ERROR });
return;
}
// 构建注销请求
var request = new UnregisterUserRequest
{
Username = username
};
byte[] requestData = request.ToBytes();
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_UNREGISTER_USER,
ReadWrite = BLEConstants.RW_WRITE,
Length = (byte)requestData.Length,
Data = requestData
};
SendFrame(frame, (response) =>
{
var unregisterResponse = UnregisterUserResponse.FromBytes(response.Status);
if (unregisterResponse.IsSuccess)
{
Log($"用户注销成功: {username}");
}
else
{
LogError($"用户注销失败: {username}, 状态码={response.Status:X2}");
}
callback?.Invoke(unregisterResponse);
OnUnregisterUserResult?.Invoke(unregisterResponse);
});
}
/// <summary>
/// 主动断开连接 (命令 0x70)
/// 注意设备收到0x70后会立即断开BLE所以不会收到响应需要特殊处理
/// </summary>
public void Disconnect(Action<bool> callback = null)
{
if (!CheckConnection()) return;
// 构建断开连接帧(无数据)
var frame = new BLEFrame
{
Header1 = BLEConstants.FRAME_HEADER_1,
Header2 = BLEConstants.FRAME_HEADER_2,
Command = BLEConstants.CMD_DISCONNECT,
ReadWrite = BLEConstants.RW_WRITE,
Length = 0,
Data = null
};
Log($"[BLE-DEBUG] Disconnect: 发送0x70命令: {System.BitConverter.ToString(frame.ToBytes())}");
SendFrameWithoutResponse(frame);
callback?.Invoke(true);
}
#endregion
#region
/// <summary>
/// 发送协议帧(不等待响应)
/// 用于0x70断开命令等特殊场景
/// </summary>
private void SendFrameWithoutResponse(BLEFrame frame)
{
if (!CheckConnection()) return;
byte[] frameBytes = frame.ToBytes();
string deviceAddress = BluetoothManager.Instance.ConnectedDeviceAddress;
Log($"[BLE-DEBUG] SendFrame: 地址={deviceAddress}, 数据={System.BitConverter.ToString(frameBytes)}, withResponse=false");
try
{
BluetoothLEHardwareInterface.WriteCharacteristic(
deviceAddress,
ServiceUUID.ToLower(),
WriteCharacteristicUUID.ToLower(),
frameBytes,
frameBytes.Length,
false,
(characteristicUUID) =>
{
Log($"[BLE-DEBUG] SendFrame完成");
}
);
}
catch (System.Exception ex)
{
LogError($"[BLE-DEBUG] SendFrame异常: {ex.Message}");
}
}
/// <summary>
/// 发送协议帧内部方法供OTAManager使用
/// </summary>
public void SendFrameInternal(BLEFrame frame, Action<BLEResponse> callback)
{
SendFrame(frame, callback);
}
/// <summary>
/// 发送协议帧
/// </summary>
private void SendFrame(BLEFrame frame, Action<BLEResponse> callback)
{
if (!CheckConnection())
{
LogError("[BLE-DEBUG] CheckConnection failed, invoking callback with error");
callback?.Invoke(new BLEResponse { Status = BLEConstants.STATUS_DEVICE_ERROR });
return;
}
byte[] frameBytes = frame.ToBytes();
IsWaitingResponse = true;
_responseTimer = ResponseTimeout;
LastCommand = frame.Command;
_pendingCallback = callback;
// 清空接收缓冲区
_receiveBuffer.Clear();
// 通过BLE发送数据
string deviceAddress = BluetoothManager.Instance.ConnectedDeviceAddress;
// 确保UUID是小写
ServiceUUID = ServiceUUID.ToLower();
WriteCharacteristicUUID = WriteCharacteristicUUID.ToLower();
string hexData = System.BitConverter.ToString(frameBytes);
// 触发发送数据事件用于UI显示
OnRawDataSent?.Invoke(hexData);
try
{
BluetoothLEHardwareInterface.WriteCharacteristic(
deviceAddress,
ServiceUUID,
WriteCharacteristicUUID,
frameBytes,
frameBytes.Length,
true,
(characteristicUUID) => { }
);
}
catch (System.Exception ex)
{
LogError($"发送帧异常: {ex.Message}");
IsWaitingResponse = false;
callback?.Invoke(new BLEResponse { Status = BLEConstants.STATUS_DEVICE_ERROR });
}
}
/// <summary>
/// 处理收到的通知数据
/// </summary>
private void OnNotificationReceived(byte[] data)
{
if (data == null || data.Length == 0) return;
string hexString = System.BitConverter.ToString(data);
// 触发原始数据事件用于UI显示
OnRawDataReceived?.Invoke(hexString);
// 添加到接收缓冲区
_receiveBuffer.AddRange(data);
// 尝试解析帧
TryParseFrame();
}
/// <summary>
/// 尝试从缓冲区解析帧
/// </summary>
private void TryParseFrame()
{
byte[] buffer = _receiveBuffer.ToArray();
// 查找帧头
for (int i = 0; i < buffer.Length - 1; i++)
{
if (buffer[i] == BLEConstants.FRAME_HEADER_1 &&
buffer[i + 1] == BLEConstants.FRAME_HEADER_2)
{
// 检查是否有足够的数据长度字段
if (i + 4 >= buffer.Length)
{
continue;
}
byte dataLength = buffer[i + 4];
int totalFrameLength = 7 + dataLength; // 帧头(2) + 命令(1) + 读写(1) + 长度(1) + 数据(dataLength) + CRC(2)
// 检查是否有完整的帧
if (i + totalFrameLength > buffer.Length)
{
continue;
}
// 提取帧数据
byte[] frameBytes = new byte[totalFrameLength];
Buffer.BlockCopy(buffer, i, frameBytes, 0, totalFrameLength);
// 解析帧
if (BLEFrame.TryParse(frameBytes, out BLEFrame frame))
{
// 处理解析到的帧
HandleReceivedFrame(frame);
// 从缓冲区移除已解析的数据
_receiveBuffer.RemoveRange(0, i + totalFrameLength);
return;
}
else
{
LogWarning("帧解析失败 (CRC校验可能失败)");
}
}
}
// 清理过期的缓冲区数据 (保留最后100字节)
if (_receiveBuffer.Count > 200)
{
_receiveBuffer.RemoveRange(0, _receiveBuffer.Count - 100);
}
}
/// <summary>
/// 处理收到的帧
/// </summary>
private void HandleReceivedFrame(BLEFrame frame)
{
// 检查是否是对等待命令的响应
if (IsWaitingResponse && frame.Command == LastCommand)
{
IsWaitingResponse = false;
_responseTimer = 0;
var response = BLEResponse.FromFrame(frame);
_pendingCallback?.Invoke(response);
_pendingCallback = null;
}
else if (frame.ReadWrite == BLEConstants.RW_NOTIFY)
{
// 处理设备主动通知
OnDataReceived?.Invoke(frame.Data);
}
else if (IsWaitingResponse)
{
// 尝试处理非匹配的响应,可能是硬件响应延迟
IsWaitingResponse = false;
_responseTimer = 0;
var response = BLEResponse.FromFrame(frame);
_pendingCallback?.Invoke(response);
_pendingCallback = null;
}
}
/// <summary>
/// 响应超时处理
/// </summary>
private void OnResponseTimeout()
{
IsWaitingResponse = false;
_responseTimer = 0;
LogError($"命令超时: 命令={LastCommand:X2}");
var timeoutResponse = new BLEResponse
{
Status = BLEConstants.STATUS_TIMEOUT
};
_pendingCallback?.Invoke(timeoutResponse);
_pendingCallback = null;
}
#endregion
#region
/// <summary>
/// 检查蓝牙连接状态
/// </summary>
private bool CheckConnection()
{
if (BluetoothManager.Instance == null) return false;
if (!BluetoothManager.Instance.IsConnected) return false;
if (IsWaitingResponse) return false;
return true;
}
/// <summary>
/// 获取状态码描述
/// </summary>
private string GetStatusMessage(byte status)
{
switch (status)
{
case BLEConstants.STATUS_SUCCESS: return "成功";
case BLEConstants.STATUS_PARAM_ERROR: return "参数错误";
case BLEConstants.STATUS_PERMISSION_ERROR: return "权限错误";
case BLEConstants.STATUS_DEVICE_BUSY: return "设备忙";
case BLEConstants.STATUS_CMD_NOT_SUPPORT: return "命令不支持";
case BLEConstants.STATUS_DATA_CHECK_FAIL: return "数据校验失败";
case BLEConstants.STATUS_TIMEOUT: return "超时";
case BLEConstants.STATUS_DEVICE_ERROR: return "设备错误";
default: return $"未知错误 (0x{status:X2})";
}
}
private void Log(string message)
{
Debug.Log($"[BLECommunication] {message}");
}
private void LogError(string message)
{
Debug.LogError($"[BLECommunication] {message}");
OnCommunicationError?.Invoke(message);
}
private void LogWarning(string message)
{
Debug.LogWarning($"[BLECommunication] {message}");
}
#endregion
}