fix(ble): 协议一致性修复、WiFi面板超时修复、搜索行为优化
- 修正 ED713/ED719 MSG 解析分路与雷达 shieldNum 偏移 - 雷达窄床模式命令格式改为两字节 [0x7C, flag] - 鉴权流程 rejectOnUnexpected=false 避免中间态阻断 - readDeviceInfo 增加 msgTimeout 4秒超时保护 - config.vue prepareWifiConfig 超时修正(800000→8000) - 搜索 30s 自动停止,暂停保留设备数据 - closeAdapter 重置 handler 引用,每次搜索前完整适配器重开
This commit is contained in:
parent
68b1485d52
commit
2a6eeccbed
|
|
@ -19,6 +19,7 @@
|
|||
4. 标准业务阶段
|
||||
- 读取设备信息:`read(F501)`
|
||||
- 鉴权:`write(F402, A7分包key)`,监听 `F301` 状态码
|
||||
- 当前项目约定:**已知密钥 = 设备 MAC 去分隔符后 + `0000`**,例如 `10:52:1C:81:64:F4` → `10521C8164F40000`
|
||||
- 鉴权成功后进行功能操作:
|
||||
- WiFi 配网:`write(F401, A7分包ssid|pass)`
|
||||
- 控制命令:`write(F403, [cmd])`
|
||||
|
|
@ -69,6 +70,7 @@ utils/ble/
|
|||
- `scanAndPickDevice/connectAndDiscover/cleanup`
|
||||
- 业务模块
|
||||
- `createAuthModule(ble).ensureAuthorized(key)`
|
||||
- `createAuthModule(ble).ensureAuthorizedByMac({ suffix: '0000' })`
|
||||
- `createWifiModule(ble).configureWifi(ssid, password)`
|
||||
- `createRadarModule(ble).startRadarStream()/stopRadarStream()/writeFallParams()`
|
||||
- 工具
|
||||
|
|
@ -122,3 +124,45 @@ async function runStandardFlow({ key, ssid, password }) {
|
|||
- `cmd.supportsNarrowMode`: ED713=true
|
||||
- `cmd.supportsFallParam67`: ED719=true
|
||||
- 未知设备先用 `UNKNOWN`,收到 `F302` 数据后按签名字节自动识别 profile。
|
||||
|
||||
|
||||
## 6. 修改记录
|
||||
|
||||
### 2026-04-30 对照协议文档第二轮修复
|
||||
|
||||
#### commonParser.js
|
||||
- `parseDeviceInfo(payload, profileId)`: 重写为按 ED713/ED719 分路解析
|
||||
- ED713:MAC[0:6] + bindStatus[6] + 其它[7:10] + productId[10:12] + baseBoard[12] + coreBoard[13] + 其它[14:16] + deviceType[16] + wifiStatus[17] + cellularStatus[18]
|
||||
- ED719:布局与 ED713 一致(bindStatus/productId 偏移相同,文档仅省略标注),复用 `parseEd713DeviceInfo`
|
||||
- `parseEd719Radar`: 修正 `shieldNum` 从 bytes[27] → bytes[24](按文档结构体偏移累加 header[4]+event+people+num+nodata+height+mode+beeper+left+right+front+back+sensitive+nodata1+stateDelay=24)
|
||||
- 新增 `wallOption`、`peopleHaveSwitch`、`peopleActivitySwitch` 字段解析
|
||||
|
||||
#### radar.js
|
||||
- `setNarrowMode(enabled)`: 修正命令格式,从单字节 `0x7C`/`0x7D` 改为两字节 `[0x7C, flag]`,flag 0=关 1=开(符合协议文档 CMD=0x7C + 1byte参数)
|
||||
|
||||
#### auth.js
|
||||
- `readDeviceInfo(options)`: 新增 `msgTimeout` 参数与 4 秒超时保护,防止 UUID_MSG 无回包时页面挂死
|
||||
- `readDeviceInfo()`: 调用 `parseDeviceInfo` 时传入 `ble.getProfile().id`
|
||||
- `ensureAuthorized`/`ensureAuthorizedByMac`: 透传 `options` 到 `readDeviceInfo`
|
||||
- `writeKeyAndExpectStates`: `rejectOnUnexpected` 从 `true` 改为 `false`,避免设备中间态(-1/0)直接 reject 阻断鉴权
|
||||
- `ensureAuthorizedWithDeviceInfo`: 移除 `bindStatus === null` 分支(ED719 实际布局与 ED713 一致,bindStatus 可正常读取)
|
||||
|
||||
#### controller.js
|
||||
- 特征分发器 `createCharacteristicDispatcher` 中 `parseDeviceInfo` 调用传入 `profile.id`
|
||||
|
||||
#### bleCore.js
|
||||
- `closeAdapter()`: 新增重置 `adapterStateHandler`/`connectionStateHandler`/`characteristicValueHandler`/`deviceFoundHandler` 为 `null`,确保 `openAdapter` 后 `init()` 可重新注册所有原生监听
|
||||
|
||||
#### pages/device/config.vue
|
||||
- `openWifiPanel`: `prepareWifiConfig` 超时从 `800000` 改为 `8000`,新增 `msgTimeout: 4000`
|
||||
- `wifiPanelVisible = true` 后加 `await this.$nextTick()` 确保 Vue DOM 更新后再调原生 toast
|
||||
|
||||
#### hooks/useBluetoothDiscovery.js
|
||||
- 新增 `SCAN_DURATION_MS = 30000`,蓝牙搜索 30 秒后自动停止
|
||||
- `startSearch`: 搜索开始前同步设置 `isSearching = true`(避免异步导致无法暂停);先 `stopDiscoverySilently()` 再 `resetDeviceMap()`(新搜索刷新数据);启动 30 秒自动停止定时器
|
||||
- `startSearch`: `stopDiscoverySilently()` 后执行完整适配器重置(`unwatch*` 注销所有原生监听 → `closeAdapter` 关闭适配器 → `initialized = false`),由 `ensureInitialized` 重新打开并注册全部监听,确保每次搜索都从干净适配器状态开始,修复二次搜索找不到设备的问题
|
||||
- `stopSearch`: 移除 `resetDeviceMap()` 调用,暂停搜索时保留已发现设备数据;清除自动停止定时器
|
||||
|
||||
### 2026-04-29 对照协议文档修复
|
||||
|
||||
(初次修复,记录同上,已被 2026-04-30 条目覆盖)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {showToast} from '@/utils/toast'
|
|||
const FILTER_SCAN_TIMEOUT_MS = 4000
|
||||
const RESTART_SCAN_DELAY_MS = 120
|
||||
const DISCOVERY_POLL_INTERVAL_MS = 1200
|
||||
const SCAN_DURATION_MS = 30000
|
||||
const TARGET_NAME_KEYWORDS = Object.freeze(['ED713', '713WQ', 'ED719', 'EP832'])
|
||||
|
||||
function promisifyUniApi(apiName, params = {}) {
|
||||
|
|
@ -77,6 +78,7 @@ export function createBluetoothDiscovery(options = {}) {
|
|||
let acceptingDeviceEvents = false
|
||||
let filterFallbackTimer = null
|
||||
let discoveryPollTimer = null
|
||||
let autoStopTimer = null
|
||||
|
||||
let offDeviceFound = null
|
||||
let offAdapterState = null
|
||||
|
|
@ -273,6 +275,15 @@ export function createBluetoothDiscovery(options = {}) {
|
|||
discoveryPollTimer = null
|
||||
}
|
||||
|
||||
function clearAutoStopTimer() {
|
||||
if (!autoStopTimer) {
|
||||
return
|
||||
}
|
||||
|
||||
clearTimeout(autoStopTimer)
|
||||
autoStopTimer = null
|
||||
}
|
||||
|
||||
function delay(ms) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms)
|
||||
|
|
@ -597,8 +608,23 @@ export function createBluetoothDiscovery(options = {}) {
|
|||
return
|
||||
}
|
||||
|
||||
// 立即标记搜索中,防止 await 期间用户重复点击或 stopSearch 被覆盖
|
||||
isSearching = true
|
||||
onSearchingChange(true)
|
||||
clearFallbackTimer()
|
||||
clearDiscoveryPollTimer()
|
||||
clearAutoStopTimer()
|
||||
|
||||
// 先停止上一次残留扫描
|
||||
await stopDiscoverySilently()
|
||||
|
||||
// 重置 BLE 适配器:关闭并重开,确保每次搜索都是干净的初始状态
|
||||
if (initialized) {
|
||||
unbindControllerEvents()
|
||||
await controller.ble.closeAdapter()
|
||||
await delay(RESTART_SCAN_DELAY_MS)
|
||||
initialized = false
|
||||
}
|
||||
|
||||
searchSessionId += 1
|
||||
const sessionId = searchSessionId
|
||||
|
|
@ -614,8 +640,6 @@ export function createBluetoothDiscovery(options = {}) {
|
|||
throw {errCode: 10001}
|
||||
}
|
||||
|
||||
await stopDiscoverySilently()
|
||||
|
||||
acceptingDeviceEvents = true
|
||||
|
||||
try {
|
||||
|
|
@ -628,12 +652,19 @@ export function createBluetoothDiscovery(options = {}) {
|
|||
return
|
||||
}
|
||||
|
||||
setSearching(true)
|
||||
startDiscoveryPolling(sessionId)
|
||||
await fallbackToUnfilteredDiscoveryIfNeeded(sessionId)
|
||||
|
||||
// 30s 自动停止搜索
|
||||
autoStopTimer = setTimeout(() => {
|
||||
if (searchSessionId === sessionId) {
|
||||
stopSearch(false)
|
||||
}
|
||||
}, SCAN_DURATION_MS)
|
||||
} catch (error) {
|
||||
acceptingDeviceEvents = false
|
||||
setSearching(false)
|
||||
isSearching = false
|
||||
onSearchingChange(false)
|
||||
showToast(getBluetoothErrorText(error))
|
||||
throw error
|
||||
}
|
||||
|
|
@ -642,12 +673,14 @@ export function createBluetoothDiscovery(options = {}) {
|
|||
async function stopSearch(showStopToast = true) {
|
||||
clearFallbackTimer()
|
||||
clearDiscoveryPollTimer()
|
||||
clearAutoStopTimer()
|
||||
|
||||
searchSessionId += 1
|
||||
acceptingDeviceEvents = false
|
||||
|
||||
await stopDiscoverySilently()
|
||||
|
||||
// 暂停搜索保留已发现的设备数据,不做 resetDeviceMap
|
||||
setSearching(false)
|
||||
if (showStopToast) {
|
||||
showToast('已停止搜索')
|
||||
|
|
|
|||
|
|
@ -331,15 +331,18 @@ export default {
|
|||
|
||||
try {
|
||||
/**
|
||||
* 按需求先执行 MAC+0000 密钥鉴权,成功后再允许进入 WiFi 弹层。
|
||||
* 先按项目固定已知密钥规则(MAC+0000)完成鉴权,成功后再允许进入 WiFi 弹层。
|
||||
*/
|
||||
await this.discoveryController.prepareWifiConfig(targetDeviceId, {
|
||||
suffix: '0000',
|
||||
timeout: 800000
|
||||
timeout: 8000,
|
||||
msgTimeout: 4000
|
||||
})
|
||||
|
||||
this.wifiPrepared = true
|
||||
this.wifiPanelVisible = true
|
||||
// 确保 Vue 完成 DOM 更新后再调原生 toast,避免原生层覆盖 Vue 弹层
|
||||
await this.$nextTick()
|
||||
showToast('密钥鉴权成功,请填写WiFi信息')
|
||||
} catch (error) {
|
||||
showToast(getErrorMessage(error))
|
||||
|
|
|
|||
|
|
@ -109,6 +109,12 @@ export function createBleCore(options = {}) {
|
|||
logger.warn('[BLE] close adapter failed', error)
|
||||
}
|
||||
|
||||
// 重置原生 handler 引用,以便 openAdapter 后 init() 可重新注册
|
||||
adapterStateHandler = null
|
||||
connectionStateHandler = null
|
||||
characteristicValueHandler = null
|
||||
deviceFoundHandler = null
|
||||
|
||||
patchState({
|
||||
stage: BLE_STAGE.IDLE,
|
||||
available: false,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ function createCharacteristicDispatcher(ble) {
|
|||
ble.emit('protocol:msg', {
|
||||
...event,
|
||||
profileId: profile.id,
|
||||
deviceInfo: parseDeviceInfo(event.value)
|
||||
deviceInfo: parseDeviceInfo(event.value, profile.id)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,9 +86,11 @@ async function writePacketsToKeyCharacteristic(ble, keyText) {
|
|||
* @param {object} options 超时等配置
|
||||
*/
|
||||
async function writeKeyAndExpectStates(ble, keyText, expectedStateCodes, options = {}) {
|
||||
// 设备订阅 STATE 后可能先发送 -1(未写密钥)/0(空闲) 等中间态,
|
||||
// 若 rejectOnUnexpected:true 会导致中间态直接 reject,阻断鉴权流程。
|
||||
const waitPromise = waitForProtocolState(ble, {
|
||||
allowedCodes: expectedStateCodes,
|
||||
rejectOnUnexpected: true,
|
||||
rejectOnUnexpected: false,
|
||||
timeout: options.timeout || 6000,
|
||||
timeoutMessage: '等待 UUID_STATE 超时',
|
||||
unexpectedMessage: '密钥流程状态异常'
|
||||
|
|
@ -105,12 +107,12 @@ async function writeKeyAndExpectStates(ble, keyText, expectedStateCodes, options
|
|||
|
||||
/**
|
||||
* 根据设备绑定状态执行鉴权流程:
|
||||
* - bindStatus=0(未绑定):生成随机密钥写入,等待 STATE=5(绑定成功)
|
||||
* - bindStatus=1(已绑定):使用已知密钥匹配,等待 STATE=7(匹配成功)
|
||||
* - bindStatus=0(未绑定):生成随机密钥写入,等待 STATE=5
|
||||
* - bindStatus=1(已绑定):使用已知密钥匹配,等待 STATE=7
|
||||
* - 其他状态:尝试用提供的密钥匹配,等待 STATE=7 或 5
|
||||
*/
|
||||
async function ensureAuthorizedWithDeviceInfo(ble, info, keyText, options = {}) {
|
||||
const bindStatus = Number(info.bindStatus)
|
||||
const bindStatus = info.bindStatus !== null ? Number(info.bindStatus) : null
|
||||
const profile = ble.getProfile()
|
||||
|
||||
ble.setAuthState({
|
||||
|
|
@ -170,24 +172,37 @@ export function createAuthModule(ble) {
|
|||
* 读取 UUID_MSG 获取设备信息(MAC/绑定状态/产品ID等)。
|
||||
* 先订阅 protocol:msg 事件,再触发 read,保证不丢通知。
|
||||
*/
|
||||
async function readDeviceInfo() {
|
||||
async function readDeviceInfo(options = {}) {
|
||||
const {msg} = ble.getState().characteristics
|
||||
|
||||
if (!msg || !msg.uuid) {
|
||||
throw new Error('未发现 UUID_MSG 特征值')
|
||||
}
|
||||
|
||||
const valuePromise = new Promise((resolve) => {
|
||||
const off = ble.on('protocol:msg', (payload) => {
|
||||
off()
|
||||
resolve(payload)
|
||||
})
|
||||
const timeout = Number(options.msgTimeout) || 4000
|
||||
let timer = null
|
||||
let off = null
|
||||
|
||||
const valuePromise = new Promise((resolve, reject) => {
|
||||
const finish = (callback) => {
|
||||
if (timer) clearTimeout(timer)
|
||||
if (off) off()
|
||||
callback()
|
||||
}
|
||||
|
||||
off = ble.on('protocol:msg', (payload) => finish(() => resolve(payload)))
|
||||
timer = setTimeout(() => finish(() => reject(new Error('读取 UUID_MSG 超时'))), timeout)
|
||||
})
|
||||
|
||||
try {
|
||||
await ble.readCharacteristic(msg.uuid)
|
||||
const payload = await valuePromise
|
||||
|
||||
return parseDeviceInfo(payload.value)
|
||||
return parseDeviceInfo(payload.value, ble.getProfile().id)
|
||||
} catch (error) {
|
||||
if (timer) clearTimeout(timer)
|
||||
if (off) off()
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,18 +213,18 @@ export function createAuthModule(ble) {
|
|||
*/
|
||||
async function ensureAuthorized(keyText, options = {}) {
|
||||
ble.setStage(BLE_STAGE.AUTHORIZING)
|
||||
const info = await readDeviceInfo()
|
||||
const info = await readDeviceInfo(options)
|
||||
return ensureAuthorizedWithDeviceInfo(ble, info, keyText, options)
|
||||
}
|
||||
|
||||
/**
|
||||
* 固定规则鉴权:密钥 = 设备MAC(去分隔符) + "0000"。
|
||||
* 用于“先鉴权再进行 WiFi 配置”的页面流程。
|
||||
* 固定规则鉴权:密钥 = 设备MAC(去分隔符) + “0000”。
|
||||
* 用于”先鉴权再进行 WiFi 配置”的页面流程。
|
||||
*/
|
||||
async function ensureAuthorizedByMac(options = {}) {
|
||||
ble.setStage(BLE_STAGE.AUTHORIZING)
|
||||
|
||||
const info = await readDeviceInfo()
|
||||
const info = await readDeviceInfo(options)
|
||||
const profile = ble.getProfile()
|
||||
const keyByMac = buildKeyFromMac(info.mac, options.suffix || '0000', profile.auth.keyLength)
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ export function createRadarModule(ble) {
|
|||
|
||||
/**
|
||||
* 设置窄床模式(仅 ED713 支持)。
|
||||
* @param {boolean} enabled true=开启(0x7D),false=关闭(0x7C)
|
||||
* 协议:CMD=0x7C,参数1byte(0=关, 1=开),设置后雷达重启。
|
||||
* @param {boolean} enabled true=开启,false=关闭
|
||||
*/
|
||||
async function setNarrowMode(enabled) {
|
||||
const profile = ble.getProfile()
|
||||
|
|
@ -61,7 +62,13 @@ export function createRadarModule(ble) {
|
|||
}
|
||||
|
||||
requireAuthorized()
|
||||
await sendCommand(enabled ? 0x7D : 0x7C)
|
||||
|
||||
// 协议规定:写入 [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]))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import {bytesToHex, bytesToMac} from '../utils/hex'
|
||||
import {joinLowHigh, readUint16LE, toUint8Array} from '../utils/bytes'
|
||||
import {DEVICE_PROFILE} from '../protocols/profiles'
|
||||
|
||||
/**
|
||||
* 解析 UUID_STATE 的状态字节,转为有符号 8bit。
|
||||
|
|
@ -14,41 +15,61 @@ export function parseStateCode(payload) {
|
|||
}
|
||||
|
||||
/**
|
||||
* 解析 UUID_MSG 设备信息(ED713/ED719 通用字段优先)。
|
||||
* ED713 MSG 解析。
|
||||
* 文档布局:MAC(6) + bindStatus(1) + 其它(3) + productId_H(1) + productId_L(1)
|
||||
* + baseBoard(1) + coreBoard(1) + 其它(2) + deviceType(1)
|
||||
* + wifiStatus(1) + cellularStatus(1) + 其它(1)
|
||||
*/
|
||||
export function parseDeviceInfo(payload) {
|
||||
function parseEd713DeviceInfo(bytes) {
|
||||
if (!bytes.length) {
|
||||
return {
|
||||
raw: bytes, mac: '', bindStatus: null, productId: null,
|
||||
deviceType: null, wifiStatus: null, cellularStatus: null
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
raw: bytes,
|
||||
mac: bytesToMac(bytes.slice(0, 6)),
|
||||
bindStatus: bytes.length > 6 ? bytes[6] : null,
|
||||
productId: bytes.length > 11 ? joinLowHigh(bytes[11], bytes[10]) : null,
|
||||
baseBoardVersion: bytes.length > 12 ? bytes[12] : null,
|
||||
coreBoardVersion: bytes.length > 13 ? bytes[13] : null,
|
||||
deviceType: bytes.length > 16 ? bytes[16] : null,
|
||||
wifiStatus: bytes.length > 17 ? bytes[17] : null,
|
||||
cellularStatus: bytes.length > 18 ? bytes[18] : null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ED719 MSG 解析。
|
||||
* 实际偏移与 ED713 一致(文档省略了 bindStatus/productId 但底板数据布局相同):
|
||||
* MAC(6) + bindStatus(1) + 其它(3) + productId_H(1) + productId_L(1)
|
||||
* + baseBoard(1) + coreBoard(1) + 其它(2) + deviceType(1)
|
||||
* + wifiStatus(1) + cellularStatus(1) + 其它(1)
|
||||
*/
|
||||
function parseEd719DeviceInfo(bytes) {
|
||||
return parseEd713DeviceInfo(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 UUID_MSG 设备信息(按 profile 区分 ED713/ED719)。
|
||||
*/
|
||||
export function parseDeviceInfo(payload, profileId = DEVICE_PROFILE.UNKNOWN) {
|
||||
const bytes = toUint8Array(payload)
|
||||
|
||||
if (!bytes.length) {
|
||||
return {
|
||||
raw: bytes,
|
||||
mac: '',
|
||||
bindStatus: null,
|
||||
productId: null,
|
||||
deviceType: null,
|
||||
wifiStatus: null,
|
||||
cellularStatus: null
|
||||
raw: bytes, mac: '', bindStatus: null, productId: null,
|
||||
deviceType: null, wifiStatus: null, cellularStatus: null
|
||||
}
|
||||
}
|
||||
|
||||
const macBytes = bytes.slice(0, 6)
|
||||
const bindStatus = bytes.length > 6 ? bytes[6] : null
|
||||
const productId = bytes.length > 10 ? joinLowHigh(bytes[10], bytes[9]) : null
|
||||
const deviceType = bytes.length > 14 ? bytes[14] : null
|
||||
const wifiStatus = bytes.length > 15 ? bytes[15] : null
|
||||
const cellularStatus = bytes.length > 16 ? bytes[16] : null
|
||||
if (profileId === DEVICE_PROFILE.ED713) return parseEd713DeviceInfo(bytes)
|
||||
if (profileId === DEVICE_PROFILE.ED719) return parseEd719DeviceInfo(bytes)
|
||||
|
||||
return {
|
||||
raw: bytes,
|
||||
mac: bytesToMac(macBytes),
|
||||
bindStatus,
|
||||
productId,
|
||||
deviceType,
|
||||
wifiStatus,
|
||||
cellularStatus,
|
||||
baseBoardVersion: bytes.length > 11 ? bytes[11] : null,
|
||||
coreBoardVersion: bytes.length > 12 ? bytes[12] : null
|
||||
}
|
||||
// UNKNOWN:按 ED713 布局兼容
|
||||
return parseEd713DeviceInfo(bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -86,7 +107,12 @@ export function parseEd713Radar(payload) {
|
|||
|
||||
/**
|
||||
* ED719 雷达数据解析。
|
||||
* 屏蔽区数量由 shieldNum 控制,每块固定 9 字节。
|
||||
* 按文档结构体定义:
|
||||
* header[4] + event(1) + people(1) + num(1) + nodata(1)
|
||||
* + height(2) + mode(1) + beeper(1) + left(2) + right(2) + front(2) + back(2)
|
||||
* + sensitive(1) + nodata1(1) + stateDelay(2) = 24 bytes
|
||||
* shield_num 在 offset 24,屏蔽区在 offset 25
|
||||
* 屏蔽区之后:wallOption + peopleHaveSwitch + peopleActivitySwitch
|
||||
*/
|
||||
export function parseEd719Radar(payload) {
|
||||
const bytes = toUint8Array(payload)
|
||||
|
|
@ -100,10 +126,12 @@ export function parseEd719Radar(payload) {
|
|||
}
|
||||
}
|
||||
|
||||
const shieldNum = bytes[27] || 0
|
||||
const shieldStart = 28
|
||||
const shieldNum = bytes[24] || 0
|
||||
const shieldStart = 25
|
||||
const shieldBlockLength = Math.min(Math.max(shieldNum, 0), 4) * 9
|
||||
|
||||
const wallOffset = shieldStart + shieldBlockLength
|
||||
|
||||
return {
|
||||
type: 'ED719',
|
||||
valid: true,
|
||||
|
|
@ -122,6 +150,8 @@ export function parseEd719Radar(payload) {
|
|||
stateDelay: readUint16LE(bytes, 22),
|
||||
shieldNum,
|
||||
shieldZoneRaw: Array.from(bytes.slice(shieldStart, shieldStart + shieldBlockLength)),
|
||||
wallOption: bytes[shieldStart + shieldBlockLength] ?? null
|
||||
wallOption: bytes[wallOffset] ?? null,
|
||||
peopleHaveSwitch: bytes[wallOffset + 1] ?? null,
|
||||
peopleActivitySwitch: bytes[wallOffset + 2] ?? null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue