Получение вывода Bosch BSEC от BME680

Привет всем!

Что я сделал

Я использую библиотеку Bosch BSEC для получения данных качества воздуха в помещении от подключенного к I2C BME680, запустив его как подпроцесс в 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)

Затем я проверяю вывод с регулярными интервалами, чтобы обработать все, что подпроцесс мог бы записать в stdout:

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

Это работает надежно, как и предполагалось.

Проблема и мои подозрения

Программа BSEC выполняет некоторую внутреннюю калибровку и сохраняет свой статус в двоичный файл с именем bsec_iaq.state. Я подозреваю, что то, как я его запускаю, каким-то образом препятствует процессу записи в этот файл. Цикл калибровки довольно длинный (4 дня), и файл обычно записывается примерно каждые 8 ​​часов, поэтому отладка того, что на самом деле происходит, представляет собой небольшую проблему.

Плохой обходной путь

Проверив все тривиальные вещи, такие как правильные пути к файлам и так далее, я решил просто запустить процесс дважды: один раз из моей программы на Python и один раз вручную. Я решил, что подпроцесс должен, по крайней мере, иметь возможность читать файл состояния. К моему удивлению, это сработало, файл состояния теперь регулярно обновляется, а калибровка стабильна.
Это явно не лучшая идея, и через несколько дней я заметил, что датчик время от времени начинал немного подергиваться (резкие скачки разных значений). Полагаю, это результат одновременного запуска двух экземпляров bsec.

Прав ли я в своем предположении, что я блокирую подпроцесс от записи в файл состояния?
Как я мог поймать вывод и по-прежнему позволить ему записывать свое состояние? Я ошибся?

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)
Другие вопросы по тегам