python - Python - 不可靠的 shell 命令执行?运行 ir-ctl 命令时出现问题
问题描述
我正在使用 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 中运行我的脚本。
解决方案
也许问题不在于 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 - 一种用于处理原始 IR 和设置 lirc 选项的瑞士刀工具:
-S, --scancode=PROTOCOL:SCANCODE 以指定的协议发送红外扫描码。协议必须是下面列出的协议之一,后跟冒号和扫描码编号。如果多次指定此选项,请按顺序发送所有扫描码,它们之间的间隔为 125 毫秒。可以使用--gap 修改间隙长度。
推荐阅读
- javascript - 这个简单的连接有什么问题
- c# - 最新版本 Xamarin.Forms Button.CornerRadius 出错
- java - Grails Spring 安全认证提供者和自定义过滤器
- javascript - 将每行上的每个单元格命名为 1 到 9
- c# - 如何使用 C# 将字符串转换为 json?
- python - Matplotlib 散点图在指定颜色时给出 ValueError(msg.format(c.shape, x.size, y.size))
- php - cakephp 模型验证错误消息未显示在 hasOne 关联中
- html - CSS网格的图像错位问题
- c# - 如何检测 ExpandoObject 与动态对象?
- jquery - 点击 jquery 更改 img src