Raspbian 在睡眠时检测键盘输入

Posted

技术标签:

【中文标题】Raspbian 在睡眠时检测键盘输入【英文标题】:Raspbian detect keyboard input while sleeping 【发布时间】:2021-05-29 11:36:55 【问题描述】:

我在 Raspbian 中有一个 python 脚本,它无限循环并在主函数执行之间休眠 15 分钟。 Main 是线程化的,但通常需要 3 秒才能运行。我不希望任何代码中断,及时进行下一次调用。在睡眠期间,我想检测按键“r”以选择性地启动另一个函数,也可能是线程的。

我尝试了 pynput 模块,但出现了奇怪的停顿,这似乎与我需要的线程和使用 VNC 签入有关。我还尝试了线程内的常规旧输入,但在没有用户输入的情况下无法结束线程。

键盘模块在 Windows 中运行良好,但没有检测到 Raspbian 的键。我正在使用 sudo "sudo python3 scriptname.py" 运行脚本如果需要,我可以缩短我的睡眠周期,在一分钟左右后调用该函数。我只是不能有一个大的停顿。

import time
import keyboard
import threading

def mainFunc():
    print('does stuff')

def keyFunc():
    print('do key detect stuff')

while True:
    t1 = threading.Thread(target=mainFunc)
    t1.start()
    time.sleep(60)
    t1.join()
    keyboard.on_press_key("r", lambda _:keyFunc())
    for _ in range(14):
        time.sleep(60)
    keyboard.unhook_all()

【问题讨论】:

看起来我可以通过让具有常规旧输入的守护程序线程在主循环之外的自己的循环中运行来解决它,并且注意不要在 mainFunc 运行时使用它。希望它在很长一段时间内保持稳定。 【参考方案1】:

我认为可能有帮助的一种方法是从日期时间对象创建一个时间跨度持续时间并将其用于您的主循环。

这是我创建的一个示例。希望它对您的 pi raspbian 脚本有所帮助。

from datetime import *
import time
import keyboard
import threading

#every 3 second function
x_start = datetime.now()
xSleep=3
def mainFunc():
    newTime = datetime.now()
    if(getTimeDiff(x_start,newTime)>xSleep):
        setXStart(datetime.now())
        return True
#every 15 minute function
y_start = datetime.now()
ySleep=900
def fifteenMinuteFunction():
    newTime = datetime.now()
    if(getTimeDiff(y_start,newTime)>ySleep):
        setYStart(datetime.now())
        return True 
#key press function (from pressing p)
def keyFunc():
    print("do keystuff")
#calculate time difference since last call
def getTimeDiff(start, end):
    span = end - start
    #convert to string
    spanStr = str(span)[0:7]
    hours   = spanStr[0:1]
    minutes = spanStr[2:4]
    seconds = spanStr[5:7]
    #convert to rounded int (seconds)
    seconds = int(seconds) + (int(minutes) * 60) + (int(hours) * 60 * 60)
    return int(seconds)
#set new start time for 3 second function
def setXStart(newTime):
    global x_start 
    x_start = newTime
#set new start tiem for 15 minute function
def setYStart(newTime):
    global y_start 
    y_start = newTime

#bind keyboard keys
keyboard.on_press_key("p", lambda _:keyFunc())                  # p do stuff function

while True:
    if keyboard.is_pressed('x'):                                # exit keybind to x
        exit()
    elif mainFunc():
        print("Doing thingy every "+str(xSleep)+" seconds")     # 3 seconds
    elif fifteenMinuteFunction():
        print("Doing thingy every "+str(ySleep)+" seconds")     # 15 mins
    else:
        time.sleep(.1)                                          

输出:

do keystuff
doing thingy every 3 seconds
do keystuff
doing thingy every 3 seconds
doing thingy every 3 seconds
....
doing thingy every 900 seconds
...

【讨论】:

【参考方案2】:
def inputDaemon():
    while True:
        x = input('r to reload')
        if x == 'r': doTheFunc()

inpD = threading.Thread(target=inputDaemon)
inpD.daemon = True
inpD.start()

我最终使用了它,它运行良好。

【讨论】:

以上是关于Raspbian 在睡眠时检测键盘输入的主要内容,如果未能解决你的问题,请参考以下文章

检测模拟键盘/鼠标输入

如何检测键盘楔形扫描仪条形码输入到网络输入并阻止键盘输入

需要一个用于在代码正确时输出引脚的触摸屏的 Gui 键盘

C++非阻塞键盘缓冲区输入检测或读取函数是啥?

UITextField - 检测内置 iPhone 键盘上的输入?

Cmd 提示未检测到键盘输入