Отправить сообщение скрипту Python

5

Я пытаюсь написать небольшую программу python для выключения или перезагрузить мой малиновый PI, с помощью кнопки, подключенной к GPIO. Программа может отображать текущее состояние малинового PI (Booting, Running, Halting, Rebooting) с помощью двух светодиодов. Программа python выполняется как демон, запускаемая init.d bash script (написанная с использованием /etc/init.d/skeleton).

Теперь я могу запустить/остановить/проверить состояние демона, и демон может проверить вход, где кнопка подключена, выполнить команду "shutdown -h now" или "shutdown -r now".

Чтобы показать текущее состояние малинового PI, я подумал о отправке сообщений демону, используя некоторые script в каталогах уровня запуска, чтобы изменить статус светодиодов. Но я не знаю, как получить сообщение в программе python.

Кто-нибудь может мне помочь?

Спасибо.

Теги:
raspberry-pi
daemon

2 ответа

6
Лучший ответ

Существует несколько способов отправить сообщение из одного script/app в другое:

Для вашего приложения действительным методом является использование именованного канала. Создайте его с помощью os.mkfifo, откройте его только для чтения в своем приложении python и ждите сообщений на нем.

Если вы хотите, чтобы ваше приложение выполняло другие вещи во время ожидания, я рекомендую вам открыть канал в неблокирующем режиме, чтобы искать доступность данных, не блокируя ваш script, как показано в следующем примере:

import os, time

pipe_path = "/tmp/mypipe"
if not os.path.exists(pipe_path):
    os.mkfifo(pipe_path)
# Open the fifo. We need to open in non-blocking mode or it will stalls until
# someone opens it for writting
pipe_fd = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK)
with os.fdopen(pipe_fd) as pipe:
    while True:
        message = pipe.read()
        if message:
            print("Received: '%s'" % message)
        print("Doing other stuff")
        time.sleep(0.5)

Затем вы можете отправлять сообщения из сценариев bash с помощью команды

echo "your message" > /tmp/mypipe

EDIT: Я не могу выбрать select.select работать правильно (я использовал его только в программах на C), поэтому я поменял свою рекомендацию на неблокирующий режим.

  • 0
    Большое спасибо! Я попробую "именованную трубу" ...
  • 0
    Я не понимаю использование функции select.select() в случае проверки файла. Можете ли вы помочь мне с примером? Мне нужно ждать сообщений в бесконечном цикле.
Показать ещё 3 комментария
0

Не удобнее ли эта версия? С ценой with внутри цикла while true:? Таким образом, все остальные коды внутри цикла выполняются даже в случае ошибки в управлении файлами канала. В конце концов я могу использовать стоимость try:  для обнаружения ошибки.

import os, time

pipe_path = "/tmp/mypipe"
if not os.path.exists(pipe_path):
    os.mkfifo(pipe_path)
# Open the fifo. We need to open in non-blocking mode or it will stalls until
# someone opens it for writting
pipe_fd = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK)

while True:
    with os.fdopen(pipe_fd) as pipe:
        message = pipe.read()
        if message:
            print("Received: '%s'" % message)

    print("Doing other stuff")
    time.sleep(0.5)
  • 0
    Не безопасно многократно открывать канал / файл с помощью os.open. Когда оператор with выходит из области видимости (предложение print («Doing other stuff»)), он закрывает дескриптор файла и не может быть повторно открыт. Кроме того, если вы закроете канал, когда подключен другой процесс, этот процесс получит сигнал SIGPIPE и, скорее всего, прекратит его выполнение. Вы должны поддерживать трубу открытой все время, пока вы находитесь в цикле.
  • 0
    @Patxitron: Спасибо за информацию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню