Python 两个物联网应用程序是否可以同时访问一个蜂窝调制解调器,这样我就不会';你不必杀掉ModemManager并失去我的internet连接吗?

Python 两个物联网应用程序是否可以同时访问一个蜂窝调制解调器,这样我就不会';你不必杀掉ModemManager并失去我的internet连接吗?,python,linux,serial-port,gps,modem,Python,Linux,Serial Port,Gps,Modem,从调制解调器获取GPS数据时遇到问题。通常,我可以通过以下代码在Python中获取GPS: 导入时间 从串行导入串行 #如果给定“端口”,则该端口将立即打开。 ser=串行(端口=“/dev/ttyUSB3”,超时=2,写入超时=2) #以下打印为“真” 打印(序列打开) def读取直到超时(ser,超时=5): “”“打开GPS并读取,直到找到所需线路, 或者超时发生 """ #打开GPS 序列写入(b“AT+CGPS=1,1\r\n”) #请求全球定位系统 ser.write(b“AT+CG

从调制解调器获取GPS数据时遇到问题。通常,我可以通过以下代码在Python中获取GPS:

导入时间
从串行导入串行
#如果给定“端口”,则该端口将立即打开。
ser=串行(端口=“/dev/ttyUSB3”,超时=2,写入超时=2)
#以下打印为“真”
打印(序列打开)
def读取直到超时(ser,超时=5):
“”“打开GPS并读取,直到找到所需线路,
或者超时发生
"""
#打开GPS
序列写入(b“AT+CGPS=1,1\r\n”)
#请求全球定位系统
ser.write(b“AT+CGPSINFO=1\r\n”)
#开始循环
time\u start=time.time()
while((time.time()-time\u start)<超时):
打印(“正在尝试ser.readline().decode('ascii',errors='replace')…”)
尝试:
#从串行端口读取数据
line=ser.readline().decode('ascii',errors='replace')
除serial.serialutil.SerialException作为错误外:
打印(f“读取数据时出现问题:{err}”)
如果“+CGPSINFO:”在同一行:
打印(f“在第{line}行中找到“+cgpinfo:”)
打破
在工作网关上,最后一条打印语句将返回一行,如下所示,其中包含GPS纬度和经度:

print(read_until_timeout(ser, timeout=5))
>>> '+CGPSINFO: 5100.506298,N,11404.432885,W,031120,234519.0,1080.1,0.0,204.6\r\n'
有时运行此功能的输出如下所示,我认为这只是意味着GPS无法获得“修复”:

打印(读取直到超时(ser,超时=5))
>>>在:+CGPSINFO:,,,,,,行中找到“+CGPSINFO:”,,,,,,,,
但有时它会说“很忙”,如下所示:

打印(读取直到超时(ser,超时=5))
>>>读取数据时出现问题:读取失败:设备报告已准备好读取,但未返回任何数据(设备已断开连接或端口上有多个访问?)
是因为两个以上的应用程序不能同时访问串行端口吗?

如果我尝试从LinuxBash向调制解调器发送AT消息,它会说调制解调器“忙”

因此,我检查哪些设备正在使用调制解调器:

$ sudo lsof /dev/ttyUSB3
>>> COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ModemMana  800 root   12u   CHR  188,3      0t0  449 /dev/ttyUSB3
python    1706 root    3u   CHR  188,3      0t0  449 /dev/ttyUSB3
但是如果我用sudo kill 800关闭手机,手机网络连接就会中断,我不能这样做,因为这些都是偏远地区的远程物联网设备(我在北美有大约50台)

是否有办法与ModemManager共享调制解调器,以便在蜂窝式互联网连接上从Python或shell访问GPS结果?

这个问题是相关的,所以我也提出了悬赏:

更新日期:2020年11月22日:

@GitFront可以帮助您直接使用ModemManager。很好的建议。还有
gi
库的巧妙技巧

在Ubuntu Bash中,当我尝试直接从ModemManager获取GPS时,我得到了以下结果:

user@user-Default-string:~$ mmcli -m 0 --location-status

/org/freedesktop/ModemManager1/Modem/0
  ----------------------------
  Location |   capabilities: '3gpp-lac-ci'
           |        enabled: '3gpp-lac-ci'
           |        signals: 'no'
请注意,在定位功能下,由于某种原因,没有显示gps原始、gps nmea、agps,只有3gpp lac ci,但我知道这个网关/SIMCom 7600调制解调器具有gps/GNSS功能,并且它有一个正确连接的无源天线

有人知道为什么
gps原始、gps nmea、agps不作为功能出现吗?

在我的办公室里,完全相同的网关/调制解调器/天线组合确实具有gps raw、gps nmea、agps等功能,而且一切都非常适合它。。。唯一的区别是SIM卡,这不重要。相比之下,我办公室中的网关报告了以下功能:

user@ax1000008:~$ mmcli -m 0 --location-status
  ------------------------
  Location | capabilities: 3gpp-lac-ci, gps-raw, gps-nmea, agps
           |      enabled: 3gpp-lac-ci
           |      signals: no
  ------------------------
  GPS      | refresh rate: 30 seconds
我请求通过以下方式启用
gps原始、gps nmea

user@ax1000008:~$ sudo mmcli -m 0 --location-enable-gps-raw --location-enable-gps-nmea
successfully setup location gathering
然后,我通过以下方式成功请求GPS(在我办公室的网关/调制解调器上):

在现场的非工作网关上,以下是我尝试启用
gps raw
gps nmea
时得到的结果:

user@user-Default-string:~$ sudo mmcli -m 0 --location-enable-gps-raw --location-enable-gps-nmea
error: couldn't setup location gathering: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.Unsupported: Cannot enable unsupported location sources: 'gps-raw, gps-nmea''

您应该能够利用ModemManager获取GPS位置,而不是直接获取。这样可以避免使用来自两个服务的相同串行端口

在ModemManager手册页中有关于如何使用
mmcli
工具从命令行执行此操作的文档:

还有一个
libmmglib
库,您应该能够通过GObject内省从Python使用它,而无需运行命令行工具

import gi
gi.require_version('ModemManager', '1.0')
from gi.repository import ModemManager
请记住,当数据会话处于活动状态时,您的设备可能无法提供位置():

位置接口允许设备向客户端应用程序提供位置信息。并非所有设备都能提供此信息,或者即使提供了,也可能无法在数据会话处于活动状态时提供此信息


我想我现在基本上已经明白了这一点,而不必杀掉ModemManager(这可能会破坏物联网远程网关上的互联网连接)

主要的答案是我根本没有得到GPS定位(权限问题除外)

我的Python代码没有做错任何事情,有时ModemManager使用我发送命令的AT端口(或者
/dev/ttyUSB2
或者
/dev/ttyUSB3
)。。。将ModemManager升级到v1.10.0也可能有效,但我不愿意在现场工作的实时网关上这样做

@rm5248建议在类似我的SIMCom 7600上使用位于
/dev/ttyUSB1
的专用NMEA端口,我认为他是对的

我用这个安装了GPSD(GPSDaemon)和它的各种客户端(例如cgps和gpsmon)。GPSD及其客户机非常适合获取GPS信息(如果GPS有修正)

如何测试GPSD软件:

#在调试级别为5的/dev/ttyUSB1上启动GPSD,
#-N(不进行后台监控)和-N(不等待)
#连接到轮询(GPS)的客户端
#没有守护进程,用于调试
$sudo gpsd-d5-N-N/dev/ttyUSB1
#后台运行的守护进程
$sudo gpsd-D 5-n/dev/ttyUSB1
然后运行以下两个客户端中的一个,并查看
/dev上的专用NMEA端口
user@user-Default-string:~$ sudo mmcli -m 0 --location-enable-gps-raw --location-enable-gps-nmea
error: couldn't setup location gathering: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.Unsupported: Cannot enable unsupported location sources: 'gps-raw, gps-nmea''
import gi
gi.require_version('ModemManager', '1.0')
from gi.repository import ModemManager
$ cgps
$ gpsmon /dev/ttyUSB1