Служба Systemd не записывает скрипт python в файл, скрипт python выполняется номинально при выполнении из cli

#python #raspberry-pi #systemd

#python #raspberry-pi #systemd

Вопрос:

Работая с raspberry pi zero w, настройте скрипт для мониторинга датчика bme280 со значениями, записанными в файл. Это отлично работает, когда скрипт запускается из командной строки, при запуске скрипта через systemd файл не записывается. Пожалуйста, ознакомьтесь ниже со сценарием и службой systemd.

Безуспешно установили стандартный вывод на абсолютный путь, директива python script write также установлена на абсолютный путь.

Служба Systemd:

 [Unit]
Description=bme280 sensor log startup
After=network.target

[Service]
ExecStart=/usr/bin/python3 -u /home/pi/bme.py
WorkingDirectory=/home/pi
StandardOutput=file:/home/pi/senselog.csv
StandardError=inherit
Restart=always
User=pi

[Install]
WantedBy=multi-user.target
  

скрипт python:

 import time
from time import strftime
import board
import busio
import adafruit_bme280

# Create library object using our Bus I2C port
i2c = busio.I2C(board.SCL, board.SDA)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c,address=0x76)

# OR create library object using our Bus SPI port
#spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
#bme_cs = digitalio.DigitalInOut(board.D10)
#bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, bme_cs)

# change this to match the location's pressure (hPa) at sea level
bme280.sea_level_pressure = 1013.25

with open("/home/pi/senselog.csv", "a") as log:
    while True:

        temp_h = bme280.temperature
        humidity = bme280.humidity
        pressure = bme280.pressure
        log.write("{0},{1}n".format(strftime("%Y-%m-%d %H:%M:%S"),str([temp_h,humidity,pressure])))
        time.sleep(60)
  

Если я удалю файл senselog.csv, то при загрузке служба systemd создаст файл заново, но без данных, приветствуется любая помощь.

Комментарии:

1. Должно ли это быть file:///home/pi/senselog.csv вместо file:/home/pi/senselog.csv , в любом случае, это не проблема, я думаю

2. Не могли бы вы проверить и посмотреть journalctl -xe -f -u <your_service_name> ?

3. @hansolo вот выходные данные journalctl: « journalctl -xe -f -u bme.service — Журналы начинаются с Чт 2016-11-03 10:16:44 PDT. — 26 марта 10:08:39 raspberrypi systemd[1]: запущен запуск журнала датчика bme280. — Тема: Unit bme.служба завершила запуск — Определено: systemd — Поддержка: debian.org/support — — Модуль bme.service завершил запуск. — — Результат запуска выполнен. «`

4. Эй, только сейчас я заметил, что вы не определили Type службы. Учитывая ваш скрипт, не могли бы вы попробовать Type=simple в [Service] разделе?

5. Добавлен Type=simple в службу без изменения поведения..

Ответ №1:

Таким образом, решение состоит в том, чтобы фактически вызвать .close() для файла, в который мы записываем в скрипте python, тогда служба systemd работает должным образом. Обратите внимание на этот поток: https://askubuntu.com/questions/83549/python-script-wont-write-data-when-ran-from-cron самый последний ответ = f.close()

и рабочий файл скрипта:

 from time import strftime
import board
import busio
import adafruit_bme280

# Create library object using our Bus I2C port
i2c = busio.I2C(board.SCL, board.SDA)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c,address=0x76)

# OR create library object using our Bus SPI port
#spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
#bme_cs = digitalio.DigitalInOut(board.D10)
#bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, bme_cs)

# change this to match the location's pressure (hPa) at sea level
bme280.sea_level_pressure = 1013.25

with open("/home/pi/senselog.csv", "w") as log:
    while True:

        temp_h = bme280.temperature
        humidity = bme280.humidity
        pressure = bme280.pressure
        log.write("{0},{1}n".format(strftime("%Y-%m-%d %H:%M:%S"),str([temp_h,humidity,pressure])))
        log.close()
        time.sleep(60) ```
  

Ответ №2:

file Атрибут to StandardOutput стал доступен только с systemd версией 236. Какая у вас версия?

 pi@wifi-relay:~ $ systemd --version

systemd 232
 PAM  AUDIT  SELINUX  IMA  APPARMOR  SMACK  SYSVINIT  UTMP  LIBCRYPTSETUP  GCRYPT  GNUTLS  ACL  XZ  LZ4  SECCOMP  BLKID  ELFUTILS  KMOD  IDN
  

Если он меньше версии 236 и вы не можете / не хотите обновляться, вы могли бы просто обновить свою ExecStart строку до:

 /usr/bin/python3 -u /home/pi/bme.py >1 /home/pi/senselog.csv
  

… затем верните StandardOutput строку обратно к значению по умолчанию.

Комментарии:

1. Спасибо за предупреждение, pi находится на версии 233, поэтому я отредактировал службу, как вы указали, без изменений в поведении записи файла. Другие мысли?