外挂 ADR(mt-adr)
模型清单
可使用下列名称或 ID 在 ThinkLink 中搜索对应模型。
| 模型类型 | 名称 | id_name | 平台模型 ID |
|---|---|---|---|
| RPC | External ADR Config | mt_adr_config | 118745136434671616 |
| RPC | External ADR Engine | mt_adr_engine | 118745135679696896 |
| Trigger | External ADR Trigger (generic) | mt_adr_trigger | 118745137390972928 |
运维 Skill
配置 ADR 参数、分析触发闸门、SNR/DR 算法或 LinkADRReq 下行时,使用 mt-adr-operations。该 Skill 要求先确认频段和 ADR 所有权,再验证后续上行的实际 DR。
适用平台版本:ThinkLink ≥ 2.00.031 | 最后更新:2026-06-14
是什么
ThinkLink 平台的网络服务器(NS)不执行服务端 ADR(自适应数据率)。本能力在应用层外挂一套 ADR 引擎,通过上行触发 → 边距算法 → MAC 下发 LinkADRReq 的闭环,自动为 LoRaWAN 设备调整数据率(DR/SF)。
- 只调整 DR/SF;TX 功率和 NbTrans 保持不变。
- 支持多频段:CN470 / EU868 / US915(US915 见注意事项)。
- 引擎状态保存在设备
server_attrs.adr_ext.state,平台侧零持久化改造。
组成
| 产物 | 标识符 | 作用 |
|---|---|---|
| 触发器 | mt_adr_trigger | 上行钩子 + 闸门:过滤无效帧,调用引擎 RPC |
| 引擎 RPC | mt_adr_engine | 边距算法 + 滑动窗口状态 + 生成 MAC 下发 |
| 配置 RPC | mt_adr_config | 写入 server_attrs.adr_ext(启用/参数) |
启用步骤
确认前置条件:目标设备绑定的物模型必须在遥测中暴露
snr、adr、datr三个字段(见下节)。配置参数:在设备详情页执行
mt_adr_configRPC,填写以下参数后提交:参数 说明 默认值/推荐值 enabled是否开启 ADR 引擎 false(需手动设为true)margin_db安全余量(dB),向下调速的保守缓冲 10window_size滑动窗口帧数,取最大 SNR 的样本数 20min_samples开始决策前必须积累的最少帧数 8min_interval_frames两次 DR 调整之间的最小间隔帧数(防抖) 5band频段: CN470/EU868/US915按部署频段填写(默认 CN470)chmask信道掩码(16-bit,全开=65535) 65535chmask_cntlChMaskCntl(EU868/CN470=6 全开;US915 125k=6) 6绑定物模型(待 owner 操作):将触发器
mt_adr_trigger的thing_model_ids绑定到目标物模型。绑定完成前触发器对该物模型的上行保持静默。
前置:物模型须暴露三字段
目标设备绑定的物模型的 payload_parser 必须向遥测数据写入 snr、adr、datr。
frameInfo.rssi = true已自动注入snr(和rssi)。adr和datr需从上行userdata.motetx中显式提取。
在对应物模型的 payload_parser 函数体中加入以下片段:
if (this.msg?.userdata?.motetx) {
this.tdata.adr = this.msg.userdata.motetx.adr === true; // 上行 ADR 位
this.tdata.datr = this.msg.userdata.motetx.datr; // 如 "SF7BW125"
}修改物模型后须重新推送并确认遥测中出现 adr / datr 字段,再执行步骤 2。
闸门(不触发的情形)
以下任一条件成立时,触发器直接返回 null,引擎不运行:
| 条件 | 说明 |
|---|---|
server_attrs.adr_ext.enabled !== true | ADR 功能未通过配置 RPC 开启 |
上行帧 adr !== true | 设备本身未开启 ADR 位(NS 要求设备同意才下发 ADR 指令) |
遥测缺少 snr 或 datr | 物模型未正确暴露前置字段,无法运算 |
算法
引擎在每次有效上行时更新滑动窗口,并按以下逻辑决策:
积累样本:收集最近
window_size帧的 SNR 值。样本数未达min_samples时不做决策。计算边距:
maxSNR = max(SNR over last window_size frames) margin = maxSNR - requiredSNR(currentDR) - margin_db drStep = floor(margin / 3)requiredSNR 参考值(各 SF 解调门限,单位 dB):
SF / DR requiredSNR (dB) SF7 −7.5 SF8 −10.0 SF9 −12.5 SF10 −15.0 SF11 −17.5 SF12 −20.0 防抖:自上次 DR 调整起,不足
min_interval_frames帧时跳过本次决策。调整:
drStep > 0时提速(DR+),drStep < 0时降速(DR−);drStep == 0时维持当前 DR。
MAC 下发
决策产生后,引擎 RPC 返回一个 thinkOne 动作,触发平台向设备下发 LinkADRReq FOpts:
{
"type": "mac",
"userdata": {
"port": -1,
"payload": "0x03..."
}
}port: -1表示 MAC 命令(FOpts 层),不占用应用端口。payload是 LinkADRReq 的十六进制字节串,NS 自动完成加密与成帧,应用层无需额外处理。
注意事项
信道掩码会覆盖既有信道计划(CN470 / EU868 / US915 通用)
每条 LinkADRReq 都会携带 ChMask(命令必填字段),引擎默认下发全开(ChMask=0xFFFF、ChMaskCntl=6)。这意味着每次 DR 调整都会把设备信道计划重置为全开,覆盖运营方此前下发的任何自定义信道掩码。若部署中对信道有定制(如固定子带、避让干扰信道),请通过 mt_adr_config 的 chmask/chmask_cntl 显式配置与现网信道计划一致的掩码值,避免被引擎全开覆盖。 配置 RPC 已校验 chmask≠0(chmask=0 会关闭全部信道致设备失联,直接拒绝)。
US915 信道掩码
US915 的信道掩码分页逻辑较复杂(ChMaskCntl 0–5 各管不同 125 kHz 子带,ChMaskCntl=6 表示全部 125 kHz 信道开启,ChMaskCntl=7 表示全部 500 kHz 信道开启)。当前 v1 实现将 US915 视为"全部 125 kHz 信道开启"(ChMaskCntl=6, ChMask=0xFFFF),适用于标准 8 信道网关已覆盖所有子带的场景。在 US915 环境部署前,请先与网关/NS 运营方核对信道计划,确认掩码设置符合实际信道配置,否则可能导致设备失联。 注:引擎从 datr 解析当前 DR 时已按 SF + 带宽精确匹配(2026-06-15 修复 BUG-035),US915 SF8BW500(DR4) 与 SF8BW125(DR2)、EU868 SF7BW250(DR6) 与 SF7BW125(DR5) 已能正确区分,不再有"仅按 SF 误映射"的问题;dr_min/dr_max 仍建议按实际网关支持的 DR 范围限制。
引擎不跟踪 LinkADRAns(fire-and-forget)
引擎下发 LinkADRReq 后不解析设备回送的 LinkADRAns(PowerACK/DataRateACK/ChannelMaskACK 状态位),即设备 NACK 时引擎无显式感知。当前依赖「下一帧 datr 未变 → margin 仍满足 → 再次尝试」的自纠机制,可接受但不强健。如需严格闭环(ACK 三位回写 + NACK 退避/告警),属后续增强项。state.last_dr 记录引擎上次下发的目标 DR,仅作诊断/排查用途(不参与决策,curDR 永远从本帧 datr 现算)。
state 字段禁止手动编辑
server_attrs.adr_ext.state 由引擎全权维护(滑动窗口、上次调整帧计数器等)。运营人员不得通过平台界面或脚本直接修改该字段,否则将破坏防抖逻辑或导致状态机错位。如需重置,执行一次 mt_adr_config 重写 server_attrs.adr_ext(不含 state),引擎将以空状态重新初始化。
绑定待 owner 操作
触发器 mt_adr_trigger 的 thing_model_ids 目前留空(待 owner 按实际部署决定绑定范围)。未绑定物模型时,触发器对该设备的上行保持完全静默,不产生任何 DR 调整指令。