import { parseRadarData } from '../parsers'; /** * 雷达控制模块:管理雷达启停、窄床模式、跌倒参数写入。 * 所有命令发送前均校验鉴权状态。 * @param {object} ble createBleCore 实例 */ export function createRadarModule(ble) { function requireAuthorized() { const state = ble.getState(); // 协议要求:获取雷达校准数据前必须先完成密钥匹配。 if (!state.auth || state.auth.keyMatched !== true) { throw new Error('请先完成密钥匹配,再执行雷达命令'); } } /** * 向 UUID_CMD 写入单字节指令。 * @param {number} commandByte 指令字节(如 0xA1 启动、0xA2 停止) */ async function sendCommand(commandByte) { const { cmd } = ble.getState().characteristics; if (!cmd || !cmd.uuid) { throw new Error('未发现 UUID_CMD 特征值'); } await ble.writeCharacteristic(cmd.uuid, new Uint8Array([commandByte])); } /** 启动雷达数据流(写入 CMD = 0xA1)。 */ async function startRadarStream() { const profile = ble.getProfile(); // 协议1.2.2:先密钥匹配,再向 UUID_CMD 写 0xA1。 requireAuthorized(); await sendCommand(profile.radar.startCommand); return true; } /** 停止雷达数据流(写入 CMD = 0xA2)。 */ async function stopRadarStream() { const profile = ble.getProfile(); // 停止同样要求处于鉴权通过态,避免误发到未鉴权连接。 requireAuthorized(); await sendCommand(profile.radar.stopCommand); return true; } /** * 设置窄床模式(仅 ED713 支持)。 * 协议:CMD=0x7C,参数1byte(0=关, 1=开),设置后雷达重启。 * @param {boolean} enabled true=开启,false=关闭 */ async function setNarrowMode(enabled) { const profile = ble.getProfile(); if (!profile.cmd.supportsNarrowMode) { throw new Error('当前设备不支持窄床模式设置'); } requireAuthorized(); // 协议规定:写入 [0x7C, flag] 两字节 const { cmd } = ble.getState().characteristics; if (!cmd || !cmd.uuid) { throw new Error('未发现 UUID_CMD 特征值'); } await ble.writeCharacteristic( cmd.uuid, new Uint8Array([0x7c, enabled ? 1 : 0]), ); } /** * 写入跌倒参数(仅 ED719 支持,指令前缀 0x67)。 * @param {Uint8Array|number[]} rawParams 跌倒参数字节 */ async function writeFallParams(rawParams) { const profile = ble.getProfile(); if (!profile.cmd.supportsFallParam67) { throw new Error('当前设备不支持 0x67 跌倒参数写入'); } requireAuthorized(); const payload = rawParams instanceof Uint8Array ? rawParams : new Uint8Array(rawParams); const packet = new Uint8Array(1 + payload.length); packet[0] = 0x67; packet.set(payload, 1); const { cmd } = ble.getState().characteristics; if (!cmd || !cmd.uuid) { throw new Error('未发现 UUID_CMD 特征值'); } await ble.writeCharacteristic(cmd.uuid, packet); } /** 按当前 profile 解析雷达通知数据。 */ function parseNotifyPayload(payload) { const profile = ble.getProfile(); return parseRadarData(payload, profile.id); } return { sendCommand, startRadarStream, stopRadarStream, setNarrowMode, writeFallParams, parseNotifyPayload, requireAuthorized, }; }