【问题标题】:Python - unreliable shell command execution? Problems running ir-ctl commandsPython - 不可靠的 shell 命令执行?运行 ir-ctl 命令时出现问题
【发布时间】:2020-12-12 14:30:48
【问题描述】:

我正在使用 Raspberry Pi 为我的立体声放大器构建简单的自动化,但我在从 python 执行 shell 命令时遇到了一些问题。我的脚本应该监听来自 spotify 客户端的事件并更改我的放大器上的选定源。我有 IR blaster 连接到我使用 ir-ctl 工具控制的 Raspberry Pi。它可以从命令行完美运行,例如当我运行它时:

ir-ctl -d /dev/lirc0 -S necx:0x856a24

我的放大器上的源更改为 AUX。然后我可以运行:

ir-ctl -d /dev/lirc0 -S necx:0x856a8c

将其更改回 CD。当从 shell 手动运行时,这可以 100% 成功运行。设备通过/boot/config.txt配置:

dtoverlay=gpio-ir-tx

现在我想在 python 脚本中使用它来监听来自我的 spotify 客户端的事件并根据在 spotify 中选择的设备更改源。 这就是问题所在 - 脚本似乎执行了命令,但有时什么也没发生,源代码没有改变。我对此感到非常困惑,因为我可以看到标准输出确认命令执行成功。

这是我的放大器操作脚本:

def sourceCD():
    print("Changing source to CD")
    runCode('0x856a8c')

def sourceAUX():
    print("Changing source to AUX")
    runCode('0x856a24')

def runCode(code):
    necCommand = 'necx:{}'.format(code)
    #result = subprocess.run(["ir-ctl", "-d","/dev/lirc0","-S", necCommand], capture_output=True, check=True)
    result = subprocess.run(['ir-ctl -d /dev/lirc0 -S necx:{}'.format(code)], shell=True, capture_output=True, check=True)
    print(result)

这是我的监听器脚本:

def on_message(ws, message):
    event = json.loads(message)["event"]
    print('Received event: ', event)

    if event == "contextChanged":
        print("Reacting to changed context")
        sourceAUX()

    if event == "inactiveSession":
        print("reacting to inactive session")
        sourceCD()

if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://192.168.0.41:24879/events",
                          on_message = on_message,
                          on_error = on_error,
                          on_close = on_close)
    ws.run_forever()

我可以在控制台输出中看到每次更改 spotify 设备时都会执行 shell 脚本:

Aug 23 23:09:59 raspberrypi python[4571]: Received event:  inactiveSession
Aug 23 23:09:59 raspberrypi python[4571]: reacting to inactive session
Aug 23 23:09:59 raspberrypi python[4571]: Changing source to CD
Aug 23 23:09:59 raspberrypi python[4571]: CompletedProcess(args=['ir-ctl', '-d', '/dev/lirc0', '-S', 'necx:0x856a8c'], returncode=0, stdout=b'', stderr=b'')
Aug 23 23:10:01 raspberrypi python[4571]: Received event:  contextChanged
Aug 23 23:10:01 raspberrypi python[4571]: Reacting to changed context
Aug 23 23:10:01 raspberrypi python[4571]: Changing source to AUX
Aug 23 23:10:02 raspberrypi python[4571]: CompletedProcess(args=['ir-ctl', '-d', '/dev/lirc0', '-S', 'necx:0x856a24'], returncode=0, stdout=b'', stderr=b'')

但是,我的放大器上的源没有更新。这让我非常困惑,为什么直接在 shell 中运行时它可以 100% 工作,而从 python 中运行时却是片状?

值得一提的是,这两个交替出现:

    #result = subprocess.run(["ir-ctl", "-d","/dev/lirc0","-S", necCommand], capture_output=True, check=True)
result = subprocess.run(['ir-ctl -d /dev/lirc0 -S necx:{}'.format(code)], shell=True, capture_output=True, check=True)

似乎确实会影响成功率,这只会让我更加困惑。我是一名程序员,但 python 对我来说是一门新语言,希望能对这个谜语提供任何帮助。

我在 virtualenv,Python 3.7.3 中运行我的脚本。

【问题讨论】:

  • 如果您确实有日志说退出代码为零,我更倾向于责怪ir-ctl。如果 /dev/lirc0 实际上设置为新值,可能会添加一些代码以重新查询。如果它不是正确的变量,请尝试重新设置。
  • 我不确定这是否可能。设备只允许我传输,我可以从设备文件中读取吗?我在这方面的知识不多。来自ir-ctl -f -d /dev/lirc0:接收功能/dev/lirc0:-设备无法接收发送功能/dev/lirc0:-设备可以发送原始红外-红外扫描码编码器-设置载波-设置占空比。 ------- 另外,是否有可能使用 virtualenv(因此使用 python 3 而不是系统默认的 python 2.7)会破坏 ir-ctl 中的某些内容?
  • 嗯,该工具似乎是用 C 编写的,所以我想不太可能受到 python 版本的影响github.com/cz172638/v4l-utils/blob/master/utils/ir-ctl/ir-ctl.c
  • 你它有时有效但并非总是有效?有没有什么情况下你觉得它比其他人更有效?它工作和不工作的比例是多少?
  • 一般来说,它似乎适用于命令的几次运行,然后它会中断,然后它会再次运行。根据变体的不同,大约有 50% 的时间正常或更低。

标签: python python-3.x shell command-line raspberry-pi


【解决方案1】:

也许问题不在于 Python 代码,而在于您的接收器(立体声放大器)处理 IR 信号的性质。仅发送一个命令可能还不够,您需要一次发送多个命令。而不是

ir-ctl -d /dev/lirc0 -S necx:0x856a24

发送

ir-ctl -d /dev/lirc0 -S necx:0x856a24 -S necx:0x856a24 -S necx:0x856a24

来自ir-ctl - a swiss-knife tool to handle raw IR and to set lirc options

-S, --scancode=PROTOCOL:SCANCODE 以指定的协议发送 IR 扫描码。协议必须是以下之一 下面列出的协议,后跟一个冒号和扫描码编号。 如果这个选项 多次指定,按顺序发送所有扫描码,间隔 125 毫秒 可以使用 --gap 修改间隙长度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 2018-05-19
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    相关资源
    最近更新 更多