0

大家好!

我做了什么

我正在使用博世 BSEC 库从连接 I2C 的 BME680 获取 IAQ 数据,方法是将其作为 python 中的子进程运行:

proc = subprocess.Popen(['path_to_bsec_bme680'],stdout=subprocess.PIPE, stderr=subprocess.STDOUT,shell=False)

为了不卡在这个永远运行的过程中,我将文件属性设置为非阻塞:

flags = fcntl(proc.stdout, F_GETFL)
fcntl(proc.stdout, F_SETFL, flags | O_NONBLOCK)

然后我定期检查输出以处理子进程可能写入标准输出的任何内容:

output = proc.stdout.readline().decode()

这可以按预期可靠地工作。

问题和我的怀疑

BSEC 程序进行一些内部校准并将其状态保存到名为bsec_iaq.state. 我怀疑我运行它的方式,我以某种方式阻止了该进程写入该文件。校准周期很长(4 天),文件通常大约每 8 小时写入一次,因此调试实际发生的情况有点麻烦。

一个糟糕的解决方法

在检查了所有琐碎的事情(如正确的文件路径等)之后,我决定简单地运行该过程两次,一次来自我的 python 程序,一次是手动运行。我认为子进程至少应该能够读取状态文件。令我惊讶的是,这行得通,状态文件现在定期更新并且校准稳定。
这显然不是一个好主意,几天后,我注意到传感器会时不时地开始抽搐(不同值的突然跳跃)。我想这是同时运行两个 bsec 实例的结果。

我对我阻止子进程写入状态文件的假设是否正确?
我怎样才能捕获输出并仍然允许它写入其状态?我完全错了吗?

4

1 回答 1

0

大家好!

我自己解决了它,也许我的解决方案对那里的任何人都有用,重复我以前犯的错误。

bsec_iaq.state预计该位置相对于已编译的二进制 bsec 程序的位置。

当 subprocess.Popen 调用此程序时,当前工作目录设置为调用它的 python 程序的位置。

路径不匹配,bsec_iaq.state找不到文件,随后校准失败。

我可以更改已编译的 bsec 二进制文件中的文件路径,或者为子进程设置不同的工作目录。我决定使用后者并添加参数 cwd。

proc = subprocess.Popen(['path_to_bsec_bme680'],cwd='path_to_bsec_working_dir',stdout=subprocess.PIPE, stderr=subprocess.STDOUT,shell=False)
于 2020-11-25T16:24:47.293 回答