设置与调试页(pageSetting)
设置与调试页(pageSetting)是 JLOTA 微信小程序中面向开发与调试的功能中心,聚合了设备认证开关、自动化测试参数、日志等级、开发调试模式、BLE 通讯 UUID 配置以及自定义命令测试等能力,并通过 app.globalData 与本地存储将配置传递给底层的 BluetoothOTAManager。
Purpose and Scope
本页文档覆盖 pages/pageSetting 目录下的完整设置与调试能力:
- 主设置页
pageSetting:设备认证、自动化测试次数/MTU、日志等级、开发调试开关、开发者模式、配置持久化; - 子页面
pageBLEDataSet:BLE 通讯 Service / Notify / Write 三个 UUID 的查看与修改; - 子页面
pageCustomCmd:向已连接设备发送自定义 RCSP 命令并接收回复/推送的调试工具。
与设置页相关的底层基础设施(BLE 连接管理 bluetoothOTAManager、RCSP 协议 jl_rcsp_ota、日志模块 logger/log)属于各自独立的能力,本页仅在它们被设置页调用时做交叉引用说明,不展开其内部实现。OTA 升级主流程请参见 OTA 相关目录页。
Overview
设置与调试页承担了三类职责:
- 配置聚合与下发:把用户在 UI 上调整的开关(设备认证、自动化测试)、数值(测试次数、MTU)与日志等级,统一写入
app.globalData与wx.setStorageSync,并通过BluetoothConfigure对象同步给全局唯一的BluetoothOTAManager实例,使配置在连接与 OTA 流程中生效。 - 开发调试入口:提供
wx.setEnableDebug打开/关闭小程序调试面板、日志等级切换、日志文件列表跳转,以及"开发者模式"的进出切换。 - 协议级调试工具:子页面
pageCustomCmd允许开发者手工拼装 ByteArray(十六进制)或文本数据,经 RCSP 自定义命令通道(CMD_EXTRA_CUSTOM)发送给设备,并实时显示设备推送与回复的原始 payload;子页面pageBLEDataSet则允许修改蓝牙通信所用 UUID。
这些设置大多面向 OTA 联调与产线测试场景:例如自动化测试参数为未来的自动化 OTA 测试预留(代码中 isAutoTestOTA 仍为 false),日志等级决定 logv/logd/logi/logw/loge 各通道是否输出,MTU 直接影响 BLE 分片传输的包长。
Architecture
flowchart TD
subgraph sg_PageSetting["pageSetting 主设置页"]
PageSetting["pageSetting.ts<br/>开关/弹窗/跳转入口"]
Storage["wx.setStorageSync<br/>持久化键值"]
GlobalData["app.globalData<br/>gbIsHandshake / gbMtuNum / gbEnableDebug ..."]
end
subgraph sg_SubPages["子页面"]
BLEDataSet["pageBLEDataSet.ts<br/>UUID 编辑与校验"]
CustomCmd["pageCustomCmd.ts<br/>RCSP 自定义命令收发"]
LogFileList["pageLogFileList<br/>日志文件列表"]
end
subgraph sg_Lib["底层库"]
BTManager["BluetoothOTAManager<br/>bluetoothOTAManager.ts"]
Configure["BluetoothConfigure<br/>isUseAuth / changeMTU / serviceUUID..."]
Logger["logger.ts / log.ts<br/>日志等级控制"]
RCSP["jl_rcsp_ota_2.1.1<br/>CmdCustom / CmdOpCodeBase"]
end
PageSetting -->|"navigateTo"| BLEDataSet
PageSetting -->|"navigateTo"| CustomCmd
PageSetting -->|"navigateTo"| LogFileList
PageSetting --> Storage
PageSetting --> GlobalData
PageSetting -->|"setLogGrade"| Logger
PageSetting -->|"new BluetoothConfigure() + setConfigure"| Configure
Configure --> BTManager
BLEDataSet -->|"getConfigure / setConfigure"| BTManager
CustomCmd -->|"sendCustomCmd / registerRcspCallback"| BTManager
CustomCmd --> RCSP
BTManager --> RCSP
架构说明:主设置页是纯配置面,不直接操作蓝牙;所有 BLE 相关配置通过 BluetoothConfigure 注入全局 BluetoothOTAManager(app.globalData.bluetoothManager),子页面则直接调用该管理器的方法。pageCustomCmd 额外注册了 OTAWrapperListenner 回调,监听设备连接状态、命令推送与命令回复,实现双向调试。持久化统一走 wx.setStorageSync,页面 onLoad 时再从 app.globalData 回读,保证刷新/重启后配置不丢失。
主设置页实现详解
页面数据模型与生命周期
pageSetting.ts 的 data 定义了全部可调状态(pageSetting.ts#L17-L30):
| 字段 | 默认值 | 含义 |
|---|---|---|
isTimesView | false | 测试数量/MTU 弹窗显隐 |
mStatusTimesView | 0 | 弹窗模式:0=测试数量,1=MTU |
isHandshake | true | 是否需要设备认证 |
isAutoTest | false | 是否开启自动化测试 |
isEnableDebug | false | 是否打开小程序开发调试 |
logViewVisible | false | 上传 log 弹窗显隐 |
logGradeArray | ['logv','logd','logi','logw','loge'] | 日志等级候选 |
logGrade | 0 | 当前日志等级索引 |
developMode | false | 开发者模式 |
mTestNum | 1 | 自动化测试次数 |
mMtuNum | 23 | BLE MTU 值(默认 23 为 BLE 最小 MTU) |
mPlatform | 'android' | 运行平台(来自 wx.getSystemInfoSync) |
onLoad(pageSetting.ts#L35-L48)从 app.globalData 回读全部配置并同步到视图,同时用 getLogGrade() 读取当前日志等级(注意存储值比索引大 1,因此 logGrade: logGrade - 1)。onShow 则将自定义 tabBar 的 selected 置为 2,保证从其他 tab 返回时底部导航高亮正确。
配置写入的统一出口 _saveSettings
所有影响 BLE 行为的配置最终都汇聚到 _saveSettings()(pageSetting.ts#L210-L218):
_saveSettings() {
const configure = new BluetoothConfigure()
configure.isUseAuth = this.data.isHandshake
configure.changeMTU = this.data.mMtuNum
//todo 目前未实现自动化测试OTA
configure.isAutoTestOTA = false;
configure.autoTestOTACount = 20;
sBluetoothManager.setConfigure(configure)
},
Source: pageSetting.ts#L210-L218
设计意图:BluetoothConfigure 是设置页与 BluetoothOTAManager 之间的"传输对象",把 UI 状态翻译为管理器可消费的配置;isAutoTestOTA 与 autoTestOTACount 目前硬编码为 false/20,为自动化 OTA 测试预留接口,避免把未实现的功能暴露给用户。
设备认证开关
onIsHandshakeDevice(pageSetting.ts#L57-L66)接收 switch 的 detail.value,同步更新 data.isHandshake、app.globalData.gbIsHandshake,并持久化到存储键 IsHandshake,最后调用 _saveSettings() 让 BluetoothConfigure.isUseAuth 生效——该值决定连接设备时是否执行认证握手流程。
自动化测试与 MTU 弹窗
onIsAutoTestDevice(pageSetting.ts#L68-L85)切换自动化测试开关;关闭时把测试次数与 MTU 重置为1/23,并同步gbTestNum/gbMtuNum与存储键IsAutoTest。onShowTestNumberView/onShowMtuNumberView(pageSetting.ts#L88-L100)通过mStatusTimesView区分弹窗模式并切换isTimesView显隐。onTimesSelectTestNumber(pageSetting.ts#L145-L155)处理测试次数选择,0被规整为1(至少测试一次),随后保存。onTimesSelectMTU(pageSetting.ts#L156-L165)处理 MTU 选择并写入gbMtuNum与存储键MtuNum。onTimesSelectCancel(pageSetting.ts#L166-L182)根据e.detail(0=测试次数,1=MTU)恢复原值并关闭弹窗。
弹窗组件由 timesSelectView 自定义组件提供,在 pageSetting.json#L1-L7 中注册为 Times-View。
日志等级与开发调试
onLogGradePickerChange(pageSetting.ts#L124-L130)将 picker 索引 +1 得到日志等级(1~5 对应logv~loge),写入存储键LogGrade并调用setLogGrade立即生效。onEnableDebug(pageSetting.ts#L132-L138)持久化IsEnableDebug后,延迟 100ms 调用wx.setEnableDebug——延迟是为了让存储写入先完成,避免调试面板开启瞬间的竞态。onDevelopMode(pageSetting.ts#L188-L209)是开发者模式的进出切换:退出时若调试开关开着会一并关闭调试并清除IsEnableDebug;进入时仅写DevelopMode=true。该模式用于隐藏/显示更多调试入口。onShowLogFileView(pageSetting.ts#L117-L123)跳转到日志文件列表页/pages/pageSetting/pageLogFileList/pageLogFileList。onUploadLogFile系列(pageSetting.ts#L101-L115)仅控制上传 log 弹窗的显隐。
子页面入口
onBLEDataSetting(pageSetting.ts#L140-L144)跳转pageBLEDataSet;onTestCustomCmd(pageSetting.ts#L183-L187)跳转pageCustomCmd。
子页面:pageBLEDataSet(BLE 通讯配置)
该页用于查看/修改蓝牙通信使用的三个 UUID,默认值均为杰理标准服务 0000ae00-0000-1000-8000-00805f9b34fb(pageBLEDataSet.ts#L10-L14)。
onLoad通过app.globalData.bluetoothManager.getConfigure()读取当前生效的 UUID 并回填页面(pageBLEDataSet.ts#L19-L26)。- 三个
onEdit*处理器(onEditService/onEditNotifyCharacteristic/onEditWriteCharacteristic)使用wx.showModal的editable能力弹出可编辑对话框,确认后先校验 UUID 格式,非法则 toast "uuid格式错误",合法才更新页面数据。 - 保存时(pageBLEDataSet.ts#L87-L97)写入存储键
ServiceUUID/NotifyCharacteristicUUID/WriteCharacteristicUUID,并同步回BluetoothConfigure后setConfigure,提示"修改成功,请断开设备后重新连接"——因为 UUID 变更只在下次连接时生效。
UUID 校验逻辑(pageBLEDataSet.ts#L98-L104)支持三种合法形态:4 位 16 位短 UUID、8 位 32 位短 UUID、标准 128 位 UUID,统一转大写后正则匹配:
_isValidBluetoothUUID(uuidStr: string) {
const uuid = uuidStr.toLocaleUpperCase()
const regex16 = /^[0-9A-F]{4}$/;
const regex32 = /^[0-9A-F]{8}$/;
const regex128 = /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/;
return regex16.test(uuid) || regex32.test(uuid) || regex128.test(uuid);
}
Source: pageBLEDataSet.ts#L98-L104
子页面:pageCustomCmd(自定义命令测试)
该页是协议级调试工具,允许向已连接设备发送任意 RCSP CMD_EXTRA_CUSTOM 数据并实时观察回复。
数据模型与生命周期
- 数据项数组
dataObjArr:每项为{ dataType, value },dataType为0(ByteArray 十六进制)或1(文本);缓存于存储键CacheDataObjArr,onLoad读取、onUnload写回(pageCustomCmd.ts#L36-L63)。 onLoad同时执行registerRcspCallback(),并从sBluetoothManager.getConnectedDevice()取第一个已连接设备作为sTargetDev;无连接时 toast "蓝牙未连接,请先连接蓝牙设备"。
发送流程 onSendData
(pageCustomCmd.ts#L67-L130)核心算法:
- 累加拼包:遍历
dataObjArr,ByteArray 项要求值为非空、偶数长度且全为十六进制(_isHexadecimal),通过hexToBytes转字节后追加到Uint8Array;文本项用string2buffer按 UTF-8 编码追加。任一 ByteArray 项非法立即 toast 并终止。 - 连接校验:
sTargetDev == null || !sBluetoothManager.isConnected(sTargetDev)时 toast "蓝牙未连接"。 - 构造回调:
commandCallback的onCmdResponse在STATUS_SUCCESS时取response.getPayload()转 hex;onError按ErrorCode分支处理(含ERROR_RESPONSE_TIMEOUT超时),并 toast 错误信息。 - 发送:
sBluetoothManager.sendCustomCmd(...)成功则记录发送时间与 hex 内容,关闭对话框并回写缓存。
接收回调 registerRcspCallback
(pageCustomCmd.ts#L131-L179)注册 OTAWrapperListenner 三路回调:
onConnectStateChange:目标设备断开时 toast "蓝牙已断开";onRcspCommand:设备主动推送的CMD_EXTRA_CUSTOM命令,取getParam().getData()显示为接收数据;onRcspResponse:对端回复的自定义命令,取getResponse().getPayload()显示。
三者均先比较 device.deviceId === sTargetDev?.deviceId,确保只展示目标设备的数据。onUnload 时调用 unregisterRcspCallback() 解除监听,避免页面销毁后回调泄漏。
if (sBluetoothManager.sendCustomCmd(sTargetDev, dataCacheArray, commandCallback)) {
const time = formatTime(new Date())
const sendDataHexStr = byteArrayToHex(dataCacheArray)
this.setData({
sendDataUpdateTime: time,
sendDataHexStr: sendDataHexStr,
isShowSendDialog: false
})
wx.setStorageSync('CacheDataObjArr', this.data.dataObjArr)
}
Source: pageCustomCmd.ts#L120-L129
Core Flow
配置保存与下发流程
sequenceDiagram
participant U as 用户
participant P as pageSetting
participant G as app.globalData
participant S as wx Storage
participant C as BluetoothConfigure
participant M as BluetoothOTAManager
U->>P: 切换开关/选择数值
P->>P: setData 更新视图
P->>G: 写入 gbIsHandshake / gbMtuNum ...
P->>S: setStorageSync(IsHandshake / MtuNum ...)
P->>C: new BluetoothConfigure() 并赋值
P->>M: setConfigure(configure)
M-->>P: 配置在下次连接/OTA 时生效
说明:设置页对每次交互都执行"视图 → globalData → 存储 → Configure → Manager"五步同步。BluetoothConfigure 是唯一面向管理器的配置通道,因此 _saveSettings 被多个 handler 复用,避免各 handler 直接耦合管理器。
自定义命令收发流程
sequenceDiagram
participant D as 开发者
participant P as pageCustomCmd
participant M as BluetoothOTAManager
participant W as OTAWrapperListenner
participant B as BLE 设备
D->>P: 编辑 dataObjArr 并点击发送
P->>P: 拼装 Uint8Array(hex/UTF-8)
P->>M: sendCustomCmd(dev, payload, callback)
M->>B: 写特征下发 CMD_EXTRA_CUSTOM
B-->>M: 回复/推送命令
M-->>W: onRcspCommand / onRcspResponse
W-->>P: 过滤 deviceId 后 setData 显示 hex
B-->>M: 超时或错误
M-->>P: onError → toast + loge
说明:发送与接收是两条独立链路——发送走 sendCustomCmd 的 commandCallback,接收走注册到管理器的 OTAWrapperListenner。onRcspCommand 处理设备主动推送,onRcspResponse 处理对命令的回复;两条路径都通过 deviceId 过滤保证只显示目标设备的数据。
Configuration Options
本地存储键(wx.setStorageSync)
| 存储键 | 类型 | 写入位置 | 含义 |
|---|---|---|---|
IsHandshake | boolean | pageSetting | 是否启用设备认证 |
IsAutoTest | boolean | pageSetting | 是否启用自动化测试 |
MtuNum | number | pageSetting | BLE MTU 值 |
LogGrade | number | pageSetting | 日志等级 1~5 |
IsEnableDebug | boolean | pageSetting | 开发调试开关 |
DevelopMode | boolean | pageSetting | 开发者模式 |
ServiceUUID | string | pageBLEDataSet | BLE Service UUID |
NotifyCharacteristicUUID | string | pageBLEDataSet | 通知特征 UUID |
WriteCharacteristicUUID | string | pageBLEDataSet | 写入特征 UUID |
CacheDataObjArr | Array | pageCustomCmd | 自定义命令数据项缓存 |
app.globalData 全局配置
| 字段 | 来源页面 | 说明 |
|---|---|---|
gbIsHandshake | pageSetting | 认证开关(onLoad 回读) |
gbIsAutoTest | pageSetting | 自动化测试开关 |
gbTestNum | pageSetting | 测试次数 |
gbMtuNum | pageSetting | MTU 数值 |
gbEnableDebug | pageSetting | 调试开关 |
gbDevelop | pageSetting | 开发者模式 |
bluetoothManager | 全局 | BluetoothOTAManager 单例 |
BluetoothConfigure 生效字段
| 字段 | 设置来源 | 说明 |
|---|---|---|
isUseAuth | isHandshake | 连接时是否认证 |
changeMTU | mMtuNum | 请求协商的 MTU |
isAutoTestOTA | 硬编码 false | 自动化 OTA(未实现) |
autoTestOTACount | 硬编码 20 | 自动化测试次数(预留) |
serviceUUID / notifyCharacteristicUUID / writeCharacteristicUUID | pageBLEDataSet | 蓝牙通信 UUID |
Failure Modes, Edge Cases & Concurrency
- 蓝牙未连接:
pageCustomCmd.onLoad检测不到已连接设备时 toast 提示;onSendData发送前二次校验连接状态,防止发送失败。 - UUID 格式错误:
pageBLEDataSet在确认编辑后立即校验,仅接受 4/8/128 位十六进制 UUID;非法值不写入,避免污染连接参数。 - ByteArray 数据不合法:
onSendData要求十六进制字符串为偶数长度且全为[0-9A-Fa-f],否则 toast 并中止拼包——这是为防止半字节数据被静默截断导致设备端解析错乱。 - 命令超时:
onError分支显式处理ERROR_RESPONSE_TIMEOUT,其余错误码走默认分支;所有错误都通过loge记录,便于联调追溯。 - 设备断开竞态:
onConnectStateChange在设备断开时 toast 提示;回调均以deviceId过滤,避免多设备场景下串台。 - 监听器生命周期:
pageCustomCmd在onUnload中unregisterRcspCallback(),防止页面销毁后回调继续触发setData造成内存泄漏。 - 调试开关时序:
wx.setEnableDebug延迟 100ms 调用,规避存储写入与 API 调用间的竞态。 - 并发/重入:设置页均为单页面 UI 交互,无并发写问题;
setStorageSync为同步接口,_saveSettings在 handler 内顺序执行,保证 globalData 与存储最终一致。
Performance & Operational Considerations
- 同步存储开销:每次开关切换都执行
setStorageSync,键值很小(boolean/number/string),对性能影响可忽略;CacheDataObjArr随数据项增长,建议控制条目数量。 - 日志等级即时生效:
setLogGrade无重启成本,便于现场快速调整日志量。 - MTU 语义:默认 23 是 BLE 4.0 的最小 MTU;调大可减少分包数、提升 OTA 吞吐,但受设备端能力限制,需以协商结果为准。
- UUID 修改需重连:
pageBLEDataSet保存后明确提示"断开设备后重新连接",因为连接参数在连接建立时定格。
Extension Points
- 自动化 OTA 预留:
BluetoothConfigure.isAutoTestOTA/autoTestOTACount已定义但硬编码,未来可在设置页暴露 UI 并接入BluetoothOTAManager的自动化测试流程。 - OTAWrapperListenner 回调面:
pageCustomCmd展示了三路回调(连接状态、命令推送、命令回复)的标准用法,可作为新增调试功能的模板(如扩展其他 RCSP OpCode)。 - UUID 校验规则:
_isValidBluetoothUUID已覆盖 16/32/128 位形态,新增协议形态时只需扩展正则分支。
Related Links
- pageSetting.ts — 主设置页逻辑
- pageSetting.json — 组件注册与页面配置
- pageBLEDataSet.ts — BLE UUID 配置子页
- pageCustomCmd.ts — 自定义命令调试子页
- 底层依赖:
lib/bluetoothOTAManager(BluetoothOTAManager / BluetoothConfigure)、lib/logger(getLogGrade/setLogGrade)、lib/log(logv/loge)、lib/otaWrapper(OTAWrapperListenner)、lib/jl_lib/jl_rcsp_ota_2.1.1(CmdCustom / ErrorCode)——这些属于各自的独立目录页,本页不做展开。