WWAN and GNSS priority automatization
蜂窝连接和 GNSS 无法同时工作(BG77 模块中的 WWAN 和 GNSS Rx 链路共享某些硬件模块,这意味着该模块不支持 WWAN 和 GNSS 的并发运行。)。这就是引入 at+qgpscfg="priority",(0-1) 命令的原因。借助该命令,您可以手动更改其中一方的优先级。
概述
蜂窝连接和 GNSS 无法同时工作(BG77 模块中的 WWAN 和 GNSS Rx 链路共享某些硬件模块,这意味着该模块不支持 WWAN 和 GNSS 的并发运行。)。这就是引入 at+qgpscfg="priority",(0-1) 命令的原因。借助该命令,您可以手动更改其中一方的优先级。
at+qgpscfg="priority",0 命令设置 GNSS 的最高优先级。
at+qgpscfg="priority",1 命令设置 LTE (WWAN) 的最高优先级。
在实际应用中,手动更改优先级并不太方便,因此,为了自动更改优先级,我们建议使用下面展示的方法。
信息
从 7.1rc3 固件版本开始,可以检查设备最后一次获取 NMEA 数据(GPS 数据)的时间。此信息可用于故障排查目的。您可以在 CLI 中使用命令 "system gps monitor once" 检查此参数。"data-age" 参数用于显示设备最后一次收到 NMEA 消息的时间。
检测到无出站流量时自动切换到 GNSS
可以使用 ppp profile 的 "on-down" 脚本、"idle-timeout" 功能以及 PPP 接口的 "dial on demand" 设置来实现自动化。
实施后,当存在互联网流量时,BG77 调制解调器将使用蜂窝数据(在此期间不会接收 GNSS 坐标),而在检测到无互联网流量时,将自动启用 GPS 接收。
Idle-timeout 参数指定在没有活动的情况下链路将在多长时间后被终止。
On-down 脚本字段允许您配置一个脚本,该脚本将在每次 PPP 接口断开时运行(包括在 idle-timeout 不活动之后)。该脚本将把调制解调器的优先级设置为 GNSS 接收。
Dial-on-demand 将确保 PPP 接口仅在存在出站流量时才尝试建立连接(此外,调制解调器将自动设置 WWAN/蜂窝连接优先级)。这将确保在发生 idle-timeout 后,除非检测到出站数据包,否则连接不会自动重新建立。
通过组合这三个功能,您可以实现以下场景:
- 如果您有出站流量,PPP 接口将处于 up 状态(因为 "dial on demand"),并且优先级将设置为蜂窝连接。将发送 PPP 接口的调制解调器初始化 AT 命令(在 PPP 接口的
modem-init="AT+QGPSCFG="priority",1"设置下配置)以设置 WWAN 优先级。在此期间,不会接收 GPS 坐标。 - 如果在 "idle-timeout" 不活动窗口之后未检测到流量,PPP 接口将断开,并且由于 "dial on demand" 设置,它不会建立连接,直到检测到出站数据包。此时将运行 "on-down" 脚本,将 WWAN 优先级切换为 GNSS 优先级。 要实现它,只需添加一个新的 PPP profile:
/ppp profile add idle-timeout=30s name=BG77 on-down="/interface ppp-client at-chat [find where modem-init=\"AT+QGPSCFG=\\\"priority\\\",1\"] input=\"AT+QGPSCFG=\\\"priority\\\",0\""
```ros
上面的示例创建了一个名为 "BG77" 的新 profile,将 **idle-timeout** 设置为 30 秒,并启用将发送 GNSS 优先级 AT 命令的 **on-down** 脚本。
之后,确保将此新建的 profile 应用到 PPP 接口:
```ros
/interface ppp-client set profile=BG77 0
```ros
并确认它已被应用(`profile=BG77`):
```ros
/interface ppp-client print
Flags: X - disabled; R - running
0 R name="ppp-out1" max-mtu=1500 max-mru=1500 mrru=disabled port=modem data-channel=2 info-channel=2
apn="internet" pin="" user="" password="" profile=BG77 phone="" dial-command="ATDT"
modem-init="AT+QGPSCFG="priority",1" null-modem=no dial-on-demand=yes add-default-route=yes
default-route-distance=1 use-peer-dns=yes keepalive-timeout=30 allow=pap,chap,mschap1,mschap2
```ros
## 使用脚本和 scheduler 切换到 GNSS
下面的脚本应配置一个 scheduler。scheduler 将确保脚本每 ***x*** 小时/分钟启动一次(每当您需要时)。
:global lat
:global lon
:global spd
:global alt
/interface ppp-client set ppp-out1 disabled=yes
log info ("disabling WWAN to get GPS coordinates")
/interface ppp-client at-chat ppp-out1 input="AT+QGPSCFG="priority",0"
log info ("enabling priority for GPS")
###the time in the delay below is the time that the device will wait for to get the coordinate fix
delay 32000ms
log info ("reading GPS coordinates")
/system gps monitor once do={
:set $lat $("latitude")
:set $lon $("longitude")
:set $spd $("speed")
:set $alt $("altitude")
}
:set $spd [:pick $spd 0 [find $spd " km"]]
:set $alt [:pick $alt 0 [find $alt "m"]]
if ($lat != "none") do={
log info ("enabling priority back to WWAN")
/interface ppp-client at-chat ppp-out1 input="AT+QGPSCFG="priority",1"
log info ("enabling WWAN")
/interface ppp-client set ppp-out1 disabled=no
delay 1000ms
###if dial on demand is enabled
###/ping 1.1.1.1 count=1
#the delay below waits for 5 seconds for the ppp connection to get established - this time can differ based on the signal strength
delay 5000ms
log info ("posting coordinates via fetch")
/tool fetch http-method=post output=user http-header-field="content-type:application/json" http-data="[
{
"payload":{
"lat":$lat,
"lng":$lon,
"speed":$spd,
"altitude":$alt
}
}
]" url="https://change-this-URL-accordingly"}\
else={
log info ("could not read GPS coordinates...enabling back WWAN")
/interface ppp-client at-chat ppp-out1 input="AT+QGPSCFG="priority",1"
/interface ppp-client set ppp-out1 disabled=no
delay 1000ms
###if dial on demand is enabled
###/ping 1.1.1.1 count=1
}
如果启用了 "dial on demand",请取消注释(删除 "###")脚本中的 ping 行 "/ping 1.1.1.1 count=1",因为如果没有出站流量 → ppp 接口将不会建立连接。
此脚本将执行的操作是禁用 ppp 接口,发送 GNSS 优先级命令,并等待 32 秒直到设备获得坐标(这是建议 Quectel 调制解调器获得坐标定位的时间/周期)。您可以根据自己的偏好和信号强度更改此时间。每种情况可能都是独特的。在 32 秒延迟之后,如果成功接收到坐标(如果纬度不等于 "none" 而等于任何其它值),脚本将发送 WWAN 优先级命令,重新启用 ppp 接口,并使用 "/tool fetch" 将坐标发布到已配置的 HTTP 服务器。如果在 32 秒延迟之后未接收到坐标(如果纬度为 "none"),脚本将发送 WWAN 优先级命令并重新启用 ppp 接口,但不发布任何结果。
不要忘记根据您的 HTTP 服务器配置/要求相应地修改脚本的 "/tool fetch" 部分。
您也可以使用 MQTT 代替 HTTP post。为此,将配置中的 "/tool fetch" 部分从:
/tool fetch http-method=post output=user http-header-field="content-type:application/json" http-data="[
{
"payload":{
"lat":$lat,
"lng":$lon,
"speed":$spd,
"altitude":$alt
}
}
]" url="https://change-this-URL-accordingly"}\
更改为 MQTT:
/iot mqtt publish broker="AWS" topic="my/test/topic" message="{
"lat":$lat,
"lng":$lon,
"speed":$spd,
"altitude":$alt \
}"}\
按您认为合适的方式更改 broker、topic 和 message。您可以点击链接找到有关如何配置 MQTT 的更多信息。
例如,如果 MQTT 服务器/broker 是 AWS,发布的结果将如下所示:

## 使用脚本和 scheduler 在检测到无出站流量时切换到 GNSS
第 1 个脚本用于检查是否存在任何流量,并据此来回切换优先级。
第 2 个脚本可用于启用 WWAN 优先级并将 GPS 坐标发布到您选择的服务器。您可以使用任何受支持的协议,例如 HTTPS post (fetch) 或 MQTT 来发布坐标。
### 第 1 个脚本
下面的脚本将自动创建一个 scheduler:
/system scheduler
add name="GPS/WWAN enabler" on-event=":delay 30s\r
\n\r
\n:local pppName ppp-out1\r
\n:local pppModemInitInit "AT+QGPSCFG=\"priority\",1"\r
\n:local gpsCmd "AT+QGPSCFG=\"priority\",0"\r
\n:local idleCount 5\r
\n\r
\n\r
\n:local pppStats\r
\n:local pppStatsPrev\r
\n:local pppStatsReset\r
\n:local idleCounter\r
\n\r
\n:while (true) do={\r
\n\r
\n:if ( \\r
\n [/interface ppp-client get $pppName running] \\r
\n && [/system gps get enabled] \\r
\n && [/interface ppp-client get $pppName dial-on-demand] \\r
\n && $pppModemInitInit=[/interface ppp-client get $pppName modem-init]
_) \\r
\n do={\r
\n :set pppStats [:toarray ([/interface print stats as-value where name
=ppp-out1]->0)] \r
\n :if ( \\r
\n $pppStats->"rx-packet"=$pppStatsPrev->"rx-packet" \\r
\n && $pppStats->"tx-packet"=$pppStatsPrev->"tx-packet" ) \\r
\n do={\r
\n :set idleCounter ($idleCounter+1)\r
\n:put ("debug: idle ".$idleCounter)\r
\n :if ( \\r
\n $idleCounter>=$idleCount \\r
\n && $pppStats->"rx-packet"!=$pppStatsReset->"rx-packet"
\\r
\n && $pppStats->"tx-packet"!=$pppStatsReset->"tx-packet" )
_\\r
\n do={\r
\n :set pppStatsReset $pppStats\r
\n :set idleCounter 0\r
\n :log info ($pppName." idling - reseting dial-on-demand, pr
ioritizing GPS")\r
\n /interface ppp-client set $pppName disabled=yes\r
\n :do { /interface ppp-client at-chat $pppName input=$gpsCmd
_} \\r
\n on-error={\r
\n:put ("debug: GPS at-chat error") \r
\n :set idleCounter 0\r
\n :set pppStatsReset ({})\r
\n }\r
\n /interface ppp-client set $pppName disabled=no\r
\n }\r
\n :delay 1s\r
\n } \\r
\n else={\r
\n:put ("debug: no idle") \r
\n :set idleCounter 0\r
\n :set pppStatsPrev $pppStats\r
\n :delay 1s \r
\n }\r
\n } \\r
\n else={\r
\n:put ("debug: unsupported config")\r
\n :set idleCounter 0\r
\n :set pppStatsReset ({})\r
\n :delay 1s\r
\n }\r
\n}" policy=
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon
start-time=startup
复制上面的所有行并将它们粘贴到一个新脚本中。运行该脚本,您将创建一个 "scheduler"。您可以在 System>Scheduler>"GPS/WWAN enabler" 下检查该 "scheduler"。
原始脚本如下所示:
:local pppName ppp-out1
:local pppModemInitInit "AT+QGPSCFG="priority",1"
:local gpsCmd "AT+QGPSCFG="priority",0"
:local idleCount 5
:local pppStats
:local pppStatsPrev
:local pppStatsReset
:local idleCounter
:while (true) do={
:if (
[/interface ppp-client get $pppName running]
&& [/system gps get enabled]
&& [/interface ppp-client get $pppName dial-on-demand]
&& $pppModemInitInit=[/interface ppp-client get $pppName modem-init] )
do={
:set pppStats [:toarray ([/interface print stats as-value where name=ppp-out1]->0)]
:if (
$pppStats->"rx-packet"=$pppStatsPrev->"rx-packet"
&& $pppStats->"tx-packet"=$pppStatsPrev->"tx-packet" )
do={
:set idleCounter ($idleCounter+1)
:put ("debug: idle ".$idleCounter)
:if (
$idleCounter>=$idleCount
&& $pppStats->"rx-packet"!=$pppStatsReset->"rx-packet"
&& $pppStats->"tx-packet"!=$pppStatsReset->"tx-packet" )
do={
:set pppStatsReset $pppStats
:set idleCounter 0
:log info ($pppName." idling - reseting dial-on-demand, prioritizing GPS")
/interface ppp-client set $pppName disabled=yes
:do { /interface ppp-client at-chat $pppName input=$gpsCmd }
on-error={
:put ("debug: GPS at-chat error")
:set idleCounter 0
:set pppStatsReset ({})
}
/interface ppp-client set $pppName disabled=no
}
:delay 1s
}
else={
:put ("debug: no idle")
:set idleCounter 0
:set pppStatsPrev $pppStats
:delay 1s
}
}
else={
:put ("debug: unsupported config")
:set idleCounter 0
:set pppStatsReset ({})
:delay 1s
}
}
为了使脚本正常工作,必须满足几个条件。
第一个条件是 ppp 接口(Interfaces>Interface)和 GPS(System>GPS)都必须启用并同时工作。您可能需要先禁用 ppp 再启用 GPS,因为它们使用同一个串口。当 GPS 和 ppp 都启用后,请确保满足第二个条件。
第二个条件是 AT 命令 "***AT+QGPSCFG="priority",1***" 在 ppp 接口的 "Modem Init" 字段下配置:

这样做的效果是,每当 ppp 连接成功建立时,就发送一条 WWAN 优先级命令。
最后,第三个条件是 ppp 接口启用了 "dial on demand":

这是必需的,因为否则当 "dial on demand" 被禁用时 → 每当端口重新启用时,ppp 接口将自动发送带有 WWAN 优先级设置的 AT 命令(尝试建立连接)。当 "dial on demand" 启用时 → 接口重新启用后,ppp 连接将不会建立,并且在检测到出站数据包之前不会发送 WWAN 优先级的 AT 命令。
当所有 3 个条件都满足时 → 脚本将执行以下操作:
脚本将比较 "计数器" 以判断是否存在流量(基于 ppp 接口的 Tx 数据包和 Rx 数据包)。如果没有流量,"计数器" 会增加,当它达到 "idleCount" 时,ppp 接口被禁用、重新启用,并发送 GNS 优先级命令。在此期间,如果仍然没有出站流量,GPS 坐标应被更新(位于 System>GPS 下)。一旦检测到任何流量,"计数器" 会被重置,并通过建立 ppp 连接发送 WWAN 优先级命令。
一旦满足所有 3 个条件且 scheduler 准备就绪,请重启设备以使脚本生效。
### 第 2 个脚本
第二个脚本用于收集 GPS 坐标并将其发送到服务器。
:global lat
:global lon
:global spd
:global alt
/system gps monitor once do={
:set $lat $("latitude")
:set $lon $("longitude")
:set $spd $("speed")
:set $alt $("altitude")
}
:set $spd [:pick $spd 0 [find $spd " km"]]
:set $alt [:pick $alt 0 [find $alt "m"]]
:if ($lat != "none") do={
/ping 1.1.1.1 count=1
:delay 3000ms;
/tool fetch http-method=post output=user http-header-field="content-type:application/json" http-data="[
{
"payload":{
"lat":$lat,
"lng":$lon,
"speed":$spd,
"altitude":$alt
}
}
]" url="https://change-this-URL"}\
else={log info ("could not read GPS coordinates")}
该脚本将 "读取" GPS 坐标,如果纬度能够成功 "读取"(如果纬度不等于 "none" 而等于任何其它值),则 ping "1.1.1.1" 一次(以产生出站流量),等待 3 秒以便 ppp 连接建立,并启动 "/tool fetch"(HTTP post)。否则,如果无法确定纬度(在脚本启动时),则不会发生任何事情(您将看到一条日志消息,表明设备无法读取 GPS 坐标)。
您可以将脚本中的 "delay" 行更改为您的设备成功与 ISP 建立 ppp (CAT-M/NB-IoT) 连接所需的实际时间。
您可以设置一个 scheduler 以在您喜欢的任何时候运行该脚本。
脚本的 "/tool fetch" 部分应根据您的服务器设置进行相应配置。
您也可以使用 MQTT 代替 HTTP post。如果您希望这样做,请将 "/tool fetch" 部分从:
/tool fetch http-method=post output=user http-header-field="content-type:application/json" http-data="[
{
"payload":{
"lat":$lat,
"lng":$lon,
"speed":$spd,
"altitude":$alt
}
}
]" url="https://change-this-URL-accordingly"}\
更改为:
/iot mqtt publish broker="AWS" topic="my/test/topic" message="{
"lat":$lat,
"lng":$lon,
"speed":$spd,
"altitude":$alt \
}"}\
不要忘记按您认为合适的方式更改 broker、topic 和 message。您可以点击链接找到有关如何配置 MQTT 的更多信息。
例如,如果 MQTT 服务器是 AWS,结果将如下所示:
