killapp/Assets/Scripts/Base/BLECommunicationManager.cs

2358 lines
75 KiB
C#
Raw Normal View History

2026-03-30 16:25:00 +08:00
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
}