python - Notify2 在 Python3 IDLE 中工作,但并不总是在终端中

标签 python linux python-3.x notifications raspbian

为了让它在 Raspbian Jessie 桌面上显示通知,我已经与这段代码斗争了好几天。我已经尝试过 Notify、notify2 和 notify-send,它们都在 IDLE 下工作,但不是在命令行下工作。 Notify 使 python 代码崩溃,notify-send(通过 subprocess.Popen 调用)什么也没做(直接从终端调用时工作正常),notify2 在从 IDLE 运行后从命令行工作了一段时间,但最终停止提供通知。从来没有给出错误。

我正在使用通知系统,因为一旦按下按钮,系统可能需要 10 秒以上的时间才能启动 rtsp 摄像头源,我希望用户知道他们的输入已收到。如果有另一种方法可以从 Python 弹出快速通知,我愿意接受想法(tkinter?)。

代码是从 LXDE-pi/autostart 中调用的 bash 脚本调用的:

#!/bin/sh
# launcher.sh
cd /
cd home/pi/py_switch
while true; do
             python3.4 buttons.py
             echo -----------------------RESTARTING CODE------------
         done
cd /

这里是 buttons.py:

#!/usr/bin/env python
import RPi.GPIO as GPIO
import time
import schedule
import subprocess
import os
from subprocess import call
import notify2
import sys; print(sys.executable)
print(os.getcwd())
notify2.init("Buttons")

os.environ.setdefault('XAUTHORITY', '/home/user/.Xauthority')
os.environ.setdefault('DISPLAY', ':0.0')
GPIO.setmode(GPIO.BCM)

GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_UP)   #*
GPIO.setup(19, GPIO.IN, pull_up_down=GPIO.PUD_UP)   #MIC
GPIO.setup(13, GPIO.IN, pull_up_down=GPIO.PUD_UP)   #CAM
GPIO.setup(6, GPIO.IN, pull_up_down=GPIO.PUD_UP)    #BRIGHTNESS
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)    #POWER


input_state1 = GPIO.input(26)
input_state2 = GPIO.input(19)
input_state3 = GPIO.input(13)
input_state4 = GPIO.input(6)
input_state5 = GPIO.input(5)
print(time.asctime( time.localtime(time.time())))
print('Button State: ', input_state1, input_state2, input_state3, input_state4, input_state5)
cam_state=False

n = notify2.Notification("Buttons!", "Waiting for you to push something.")
n.show()
brightness = str(subprocess.check_output(["ddcutil", "getvcp", "10"]))
brightness = brightness[brightness.find('=',4):brightness.find(',')]
brightness = brightness[1:].strip(' ')
if brightness == '0':
    disp_state=1
    print('Startup brightness is 0%')
elif brightness == '1':
    disp_state=0
    print('Display is off')
else:
    disp_state=2
    print('Startup brightness is >0%')  

def job():
    rc = subprocess.call(["/home/pi/py_switch/cams.sh", "repair"])
    print('Checking for down cameras')

def night():
    rc = subprocess.call(["ddcutil", "setvcp", "10", "1"])
    rc = subprocess.call(["ddcutil", "setvcp", "0xd6", "04"])
    disp_state=0
    print('Starting night mode')

def day():
    rc = subprocess.call(["ddcutil", "setvcp", "0xd6", "01"])
    rc = subprocess.call(["ddcutil", "setvcp", "10", "100"])
    disp_state=2
    print('Starting day mode')

schedule.every().day.at("23:30").do(night)
schedule.every().day.at("06:00").do(day)
schedule.every().wednesday.at("07:15").do(night)
schedule.every().thursday.at("07:15").do(night)

while True:
    input_state1 = GPIO.input(26)   #*
    input_state2 = GPIO.input(19)   #MIC
    input_state3 = GPIO.input(13)   #CAM
    input_state4 = GPIO.input(6)    #BRIGHTNESS
    input_state5 = GPIO.input(5)    #POWER

    if input_state3 == False:
        print('Camera Button Pressed')
        time.sleep(0.2)
        if cam_state == False:
            n = notify2.Notification("Starting Cameras", "May take up to 10 seconds...", "camera-video")
            rc = subprocess.call(["/home/pi/py_switch/cams.sh", "repair"]) #repair like start but won't double start if running
            cam_state=True
            schedule.every(3).minutes.do(job).tag('repair-cams')
        else:
            n = notify2.Notification("Stopping Cameras", "Standby...", "camera-video")
            rc = subprocess.call(["/home/pi/py_switch/cams.sh", "stop"])
            cam_state=False
            schedule.clear('repair-cams')
    if input_state4 == False:
        print('Brightness button Pressed')
#        rc = subprocess.Popen('DISPLAY=:0 notify-send "Changing Brightness..." "100% -> 0% -> Off ->" -i dialog-information', shell=True)
        n = notify2.Notification("Changing brightness", "100% -> 0% -> Off ->", "dialog-information")
        time.sleep(0.2)
        if disp_state == 3:
               rc = subprocess.call(["ddcutil", "setvcp", "10", "50"])
               disp_state=2
        elif disp_state == 2:
                rc = subprocess.call(["ddcutil", "setvcp", "10", "0"])
                disp_state=1
        elif disp_state == 1:
                rc = subprocess.call(["ddcutil", "setvcp", "10", "1"])
                rc = subprocess.call(["ddcutil", "setvcp", "0xd6", "04"])
                disp_state=0
        elif disp_state == 0:
                rc = subprocess.call(["ddcutil", "setvcp", "0xd6", "01"])
                rc = subprocess.call(["ddcutil", "setvcp", "10", "100"])
                disp_state=2 #changed to 2 to from 3 to bypass 50% brighness
    if input_state5 == False:
        print('Power button Pressed')
        start = time.time()
        time.sleep(0.2)
 #       rc = subprocess.Popen('DISPLAY=:0 notify-send "Hold for 5s to shutdown." -i system-shutdown', shell=True)
        n = notify2.Notification("Shutdown?", "Hold for 5s to shutdown.", "system-shutdown")
        while input_state5 == False:
            time.sleep(0.1)
            print('Holding down 3')
            end = time.time()
            press_time = end-start
           # print(press_time)
            input_state5 = GPIO.input(5)
            if press_time > 5:
                print('Shutting down?')
                os.system('sudo shutdown -h now')

    if input_state2 == False:
        print('Microphone button Pressed')
        time.sleep(0.2)
        #rc = subprocess.call(["ddcutil", "setvcp", "10", "100"])
    if input_state1 == False:
        print('Star button Pressed')
        time.sleep(0.2)
    time.sleep(0.1)
    schedule.run_pending()

我是否需要做一些特殊的事情来保持通知守护进程的运行?我有 notification-daemon、notify-osd 以及 Google 搜索建议我安装的所有其他软件包:

(zcat $(ls -tr /var/log/apt/history.log*.gz); cat /var/log/apt/history.log) 2>/dev/null |
  egrep '^(Start-Date:|Commandline:)' |
  grep -v aptdaemon |
  egrep -B1 '^Commandline:'
Commandline: apt-get install notification-daemon
Commandline: apt-get install python-notify
Commandline: apt-get install python-dev python-rpi.gpio
Commandline: apt-get install python-gobject libnotify-bin libnotify-dev
Commandline: apt-get install xorg-dev libglu1-mesa-dev
Commandline: apt-get install libudev-dev
Commandline: apt-get install libusb-dev
Commandline: apt-get install libusb-1.0.0-dev
Commandline: apt-get install screen
Commandline: apt-get install xosd-bin
Commandline: apt-get install libgtk2.0-dev libglib2.0-dev libnotify-dev
Commandline: apt-get install libnotify-cil-dev
Commandline: apt-get install notify-osd
Commandline: apt-get install unclutter
Commandline: apt-get install python3-notify2

最佳答案

问题中发布的代码间歇性地工作,但没有导致任何错误消息。我尝试添加将紧急程度设置为关键 (n.set_urgency(notify2.URGENCY_CRITICAL)) 但它没有帮助。

我发现通过使用 --urgency=critical 调用通知发送,通知会可靠地显示。

工作示例:

rc = subprocess.Popen('DISPLAY=:0 notify-send --urgency=critical "Changing Brightness..." "100% -> 0% -> Off ->" -i dialog-information', shell=True)

关于python - Notify2 在 Python3 IDLE 中工作,但并不总是在终端中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43567302/

相关文章:

linux - 无法 `go get` 离线教程

python - @reboot crontab 没有执行

python - 有没有办法在删除后恢复内置函数?

python - 优化 NumPy 中各部分进行的向量化运算

python - 如何在 Pandas 中用滚动平均值填充南值

python - 有没有一种简单的方法可以将目录的特定部分复制到 Dockerfile 中?

python - 如何在 R 中使用带有网状包的 Python 代码构建 lapply 风格的函数?

c++ - GLEW 1.10.0段错误

windows - 克隆 Anaconda 基础环境时出现断言错误

python-3.x - 如何在 multiprocessing.Pool 中使用 pandas