using UnityEngine; using System; using System.Collections.Generic; using BLEProtocol; /// /// BLE通信管理器 - 处理协议层通信 /// 基于 BluetoothManager 进行协议通信 /// public class BLECommunicationManager : MonoBehaviour { public static BLECommunicationManager Instance { get; private set; } // 事件定义 public event Action OnRegistrationStatusReceived; // 收到注册状态 public event Action OnRegisterResult; // 注册结果 (成功/失败, 消息) public event Action OnUserListReceived; // 收到用户列表 public event Action OnUnregisterUserResult; // 注销用户结果 public event Action OnUserLoginResult; // 用户登录结果 public event Action OnFingerprintEnableResult; // 指纹使能设置结果 public event Action OnFingerprintRecordResult; // 指纹录制结果 public event Action OnLanguageSettingReceived; // 收到语言设置 public event Action OnTimeSettingReceived; // 收到时间设置 public event Action OnScheduleTaskListReceived; // 收到定时任务列表 public event Action OnLCDSleepSettingReceived; // 收到LCD休眠设置 public event Action OnLCDBrightnessSettingReceived; // 收到LCD亮度设置 public event Action OnRGBControlReceived; // 收到RGB控制设置 public event Action OnWIFIControlReceived; // 收到WIFI控制设置 public event Action OnBLEControlReceived; // 收到BLE控制设置 public event Action OnMultimediaControlReceived; // 收到多媒体控制设置 public event Action OnFillLightControlReceived; // 收到补光灯控制设置 public event Action OnFillLightConnectionStatusReceived; // 收到补光灯连接状态 public event Action OnVisibleLaserControlReceived; // 收到可见光激光器控制设置 public event Action OnAngleControlReceived; // 收到角度控制设置 public event Action OnDistanceControlReceived; // 收到距离控制设置 public event Action OnMillimeterWaveSettingReceived; // 收到毫米波雷达设置 public event Action OnVisualDetectionSettingReceived; // 收到视觉检测设置 public event Action OnAccelerometerSettingReceived; // 收到加速度传感器设置 public event Action OnAccelerometerDataReceived; // 收到加速度传感器数据 public event Action OnTemperatureMonitorSettingReceived; // 收到温度监控设置 public event Action OnEnvironmentChangeStatusReceived; // 收到环境变化状态 public event Action OnWorkModeSettingReceived; // 收到工作模式设置 public event Action OnHardwareStatusReceived; // 收到硬件状态 public event Action OnDeviceInfoReceived; // 收到设备信息 public event Action OnStatisticsDataReceived; // 收到统计数据 public event Action OnSensorDataReceived; // 收到传感器数据 public event Action OnMosquitoDataReceived; // 收到蚊虫数据通知 public event Action OnDataReceived; // 收到原始数据 public event Action OnRawDataReceived; // 收到原始数据(十六进制字符串) public event Action OnRawDataSent; // 发送原始数据(十六进制字符串) public event Action OnCommunicationError; // 通信错误 // 状态 public bool IsWaitingResponse { get; private set; } public byte LastCommand { get; private set; } // 响应超时设置 (OTA传输需要更长时间,增加到10秒) public float ResponseTimeout = 10f; // 数据接收缓冲区 private List _receiveBuffer = new List(); private float _responseTimer; private Action _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!"); } } /// /// 蓝牙错误回调 /// 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 蓝牙连接和通知设置 /// /// 蓝牙连接成功回调(特征发现完成后调用) /// private void OnBluetoothConnected() { if (AutoInitialize) InitializeCommunication(); } /// /// 蓝牙断开连接回调 /// private void OnBluetoothDisconnected(string address) { Log($"蓝牙已断开: {address}"); // 清理状态 IsWaitingResponse = false; _responseTimer = 0; _pendingCallback = null; _receiveBuffer.Clear(); } /// /// 初始化BLE通信 (连接成功后自动调用,也可手动调用) /// public void InitializeCommunication() { if (BluetoothManager.Instance == null || !BluetoothManager.Instance.IsConnected) return; ServiceUUID = ServiceUUID.ToLower(); WriteCharacteristicUUID = WriteCharacteristicUUID.ToLower(); NotifyCharacteristicUUID = NotifyCharacteristicUUID.ToLower(); SubscribeToNotifications(); } /// /// 订阅设备通知 /// 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}"); } } /// /// 取消订阅通知 /// public void UnsubscribeNotifications() { if (BluetoothManager.Instance == null || !BluetoothManager.Instance.IsConnected) return; string deviceAddress = BluetoothManager.Instance.ConnectedDeviceAddress; BluetoothLEHardwareInterface.UnSubscribeCharacteristic( deviceAddress, ServiceUUID, NotifyCharacteristicUUID, null ); } #endregion #region 设备注册与认证接口 /// /// 查询设备注册状态 (命令 0x01) /// public void QueryRegistrationStatus(Action 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()); } }); } /// /// 设备注册绑定 (命令 0x02) /// 注意:根据协议,只发送用户名,不发送密码 /// /// 用户名 /// 回调 (成功/失败, 消息) public void RegisterDevice(string username, Action 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); }); } /// /// 用户登录 (命令 0x03) /// 数据格式:用户名(16字节) + 解锁状态(1字节),解锁状态固定为1 /// /// 用户名 /// 回调 (响应结果) public void UserLogin(string username, Action 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); }); } /// /// 指纹登录使能设置 (命令 0x04) /// 数据格式:用户名(16字节) + 使能状态(1字节) /// /// 用户名 /// 使能状态:true=使能, false=禁用 /// 回调 (响应结果) public void SetFingerprintEnable(string username, bool enable, Action 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); }); } /// /// 指纹录制请求 (命令 0x05) /// 启动指纹注册流程 /// /// 用户名 /// 回调 (响应结果) public void StartFingerprintRecord(string username, Action 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) /// /// 读取语言设置 (命令 0x10) /// public void ReadLanguageSetting(Action 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); }); } /// /// 写入语言设置 (命令 0x10) /// /// true=中文, false=英文 public void WriteLanguageSetting(bool isChinese, Action 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); }); } /// /// 读取时间设置 (命令 0x11) /// public void ReadTimeSetting(Action 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); }); } /// /// 写入时间设置 (命令 0x11) /// public void WriteTimeSetting(TimeSetting setting, Action 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); }); } /// /// 读取定时任务列表 (命令 0x12) /// public void ReadScheduleTasks(Action 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); }); } /// /// 写入定时任务 (命令 0x12) /// 支持一次写入单条或多条定时任务(最多5条) /// /// 单条定时任务 /// 回调 (成功/失败) public void WriteScheduleTask(ScheduleTask task, Action callback = null) { WriteScheduleTasks(new ScheduleTask[] { task }, callback); } /// /// 写入多条定时任务 (命令 0x12) /// 支持一次写入最多5组定时任务(硬件已支持批量写入) /// /// 定时任务数组(最多5条,每条8字节) /// 回调 (成功/失败) public void WriteScheduleTasks(ScheduleTask[] tasks, Action 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) /// /// 读取LCD休眠设置 (命令 0x20) /// public void ReadLCDSleepSetting(Action 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); }); } /// /// 写入LCD休眠设置 (命令 0x20) /// public void WriteLCDSleepSetting(LCDSleepSetting setting, Action 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); }); } /// /// 读取LCD亮度设置 (命令 0x21) /// public void ReadLCDBrightnessSetting(Action 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); }); } /// /// 写入LCD亮度设置 (命令 0x21) /// public void WriteLCDBrightnessSetting(LCDBrightnessSetting setting, Action 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); }); } /// /// 读取RGB指示灯控制 (命令 0x22) /// public void ReadRGBControl(Action 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); }); } /// /// 写入RGB指示灯控制 (命令 0x22) /// public void WriteRGBControl(RGBControl control, Action 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); }); } /// /// 读取WIFI控制 (命令 0x23) /// public void ReadWIFIControl(Action 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); }); } /// /// 写入WIFI控制 (命令 0x23) /// public void WriteWIFIControl(WIFIControl control, Action 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); }); } /// /// 读取BLE控制 (命令 0x24) /// public void ReadBLEControl(Action 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); }); } /// /// 写入BLE控制 (命令 0x24) /// public void WriteBLEControl(BLEControl control, Action 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); }); } /// /// 读取多媒体控制 (命令 0x25) /// public void ReadMultimediaControl(Action 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); }); } /// /// 写入多媒体控制 (命令 0x25) /// public void WriteMultimediaControl(MultimediaControl control, Action 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); }); } /// /// 读取补光灯控制 (命令 0x26) /// public void ReadFillLightControl(Action 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); }); } /// /// 写入补光灯控制 (命令 0x26) /// public void WriteFillLightControl(FillLightControl control, Action 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); }); } /// /// 读取补光灯连接状态 (命令 0x27) /// public void ReadFillLightConnectionStatus(Action 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); }); } /// /// 读取可见光激光器控制 (命令 0x28) /// public void ReadVisibleLaserControl(Action 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); }); } /// /// 写入可见光激光器控制 (命令 0x28) /// public void WriteVisibleLaserControl(VisibleLaserControl control, Action 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) /// /// 读取角度控制设置 (命令 0x40) /// public void ReadAngleControl(Action 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}"); }); } /// /// 写入角度控制设置 (命令 0x40) /// /// 角度控制设置 public void WriteAngleControl(AngleControl control, Action 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); }); } /// /// 读取距离控制设置 (命令 0x41) /// public void ReadDistanceControl(Action 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}"); }); } /// /// 写入距离控制设置 (命令 0x41) /// /// 距离控制设置 public void WriteDistanceControl(DistanceControl control, Action 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) /// /// 读取毫米波雷达设置 (命令 0x50) /// public void ReadMillimeterWaveSetting(Action 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}"); }); } /// /// 写入毫米波雷达设置 (命令 0x50) /// public void WriteMillimeterWaveSetting(MillimeterWaveSetting setting, Action 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); }); } /// /// 读取视觉检测设置 (命令 0x51) /// public void ReadVisualDetectionSetting(Action 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}"); }); } /// /// 写入视觉检测设置 (命令 0x51) /// public void WriteVisualDetectionSetting(VisualDetectionSetting setting, Action 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); }); } /// /// 读取加速度传感器设置 (命令 0x52) /// public void ReadAccelerometerSetting(Action 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}"); }); } /// /// 写入加速度传感器设置 (命令 0x52) /// public void WriteAccelerometerSetting(AccelerometerSetting setting, Action 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); }); } /// /// 查询加速度传感器数据 (命令 0x53) /// public void ReadAccelerometerData(Action 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}"); }); } /// /// 读取温度监控设置 (命令 0x55) /// public void ReadTemperatureMonitorSetting(Action 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}"); }); } /// /// 写入温度监控设置 (命令 0x55) /// public void WriteTemperatureMonitorSetting(TemperatureMonitorSetting setting, Action 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) /// /// 读取工作模式 (命令 0xA0) /// public void ReadWorkMode(Action 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}"); }); } /// /// 写入工作模式 (命令 0xA0) /// public void WriteWorkMode(WorkModeSetting setting, Action 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); }); } /// /// 查询硬件状态 (命令 0xA1) /// public void ReadHardwareStatus(Action 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}"); }); } /// /// 查询设备信息 (命令 0xA2) /// public void ReadDeviceInfo(Action 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}"); }); } /// /// 写入设备信息 (命令 0xA2 写操作) /// 写操作:接收56字节设备信息 /// public void WriteDeviceInfo(DeviceInfoWrite deviceInfo, Action 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); }); } /// /// 查询统计数据 (命令 0xA3) /// public void ReadStatisticsData(Action 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}"); }); } /// /// 查询蚊虫数据 (命令 0xA4) /// public void QueryMosquitoData(MosquitoDataQuery query, Action 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); }); } /// /// 查询传感器数据 (命令 0xA5) /// public void ReadSensorData(Action 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通知) /// /// 查询蚊虫数据数量 (命令 0xA4 读操作) /// public void ReadMosquitoDataCount(Action 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}"); }); } /// /// 请求蚊虫数据 (命令 0xA4 写操作) /// 写操作成功后,设备通过通知机制发送数据 /// public void RequestMosquitoData(uint count, Action 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); }); } /// /// 处理蚊虫数据通知 (通知类型 0x0B) /// public void HandleMosquitoDataNotification(byte[] notifyData) { if (notifyData == null || notifyData.Length < 22) { LogError("蚊虫数据通知格式错误,数据长度不足22字节"); return; } var mosquitoData = MosquitoData.FromBytes(notifyData); Log($"收到蚊虫数据通知: {mosquitoData}"); OnMosquitoDataReceived?.Invoke(mosquitoData); } /// /// 读取环境变化状态 (命令 0x56 读操作) /// public void ReadEnvironmentChangeStatus(Action 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}"); }); } /// /// 触发激光试射测试 (命令 0x56 写操作) /// 触发激光进行3次试射测试,每次间隔1秒,每次持续10ms /// public void TriggerLaserTest(Action 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); }); } /// /// 恢复出厂设置 (命令 0x60) /// 需要管理员权限 /// 写操作:发送1字节确认码 0x01 /// public void FactoryReset(Action 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 /// /// 查询用户列表 (命令 0x07) /// public void QueryUserList(Action 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 }); } }); } /// /// 注销用户 (命令 0x08) /// /// 要注销的用户名 /// 回调 (响应结果) public void UnregisterUser(string username, Action 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); }); } /// /// 主动断开连接 (命令 0x70) /// 注意:设备收到0x70后会立即断开BLE,所以不会收到响应,需要特殊处理 /// public void Disconnect(Action 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 底层通信方法 /// /// 发送协议帧(不等待响应) /// 用于0x70断开命令等特殊场景 /// 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}"); } } /// /// 发送协议帧(内部方法,供OTAManager使用) /// public void SendFrameInternal(BLEFrame frame, Action callback) { SendFrame(frame, callback); } /// /// 发送协议帧 /// private void SendFrame(BLEFrame frame, Action 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 }); } } /// /// 处理收到的通知数据 /// 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(); } /// /// 尝试从缓冲区解析帧 /// 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); } } /// /// 处理收到的帧 /// 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; } } /// /// 响应超时处理 /// 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 辅助方法 /// /// 检查蓝牙连接状态 /// private bool CheckConnection() { if (BluetoothManager.Instance == null) return false; if (!BluetoothManager.Instance.IsConnected) return false; if (IsWaitingResponse) return false; return true; } /// /// 获取状态码描述 /// 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 }