python - 将脚本作为并行子进程运行
问题描述
我对python很陌生,所以我的知识很基础。(我是系统工程师)我有一个树莓派、一个 LED 灯条和一个 python 脚本来模拟 LED 灯条上的火灾:D
现在我想通过按下我的 flic 按钮来启动脚本。我在 github 上找到了 fliclib sdk 并安装了它。我现在的问题是,如何正确处理事件。我可以成功启动脚本,但我想通过双击 flic 按钮来停止它。但似乎我一按下按钮就被卡在了 fire.py 脚本中。有人可以帮我如何正确设置吗?:-)
建议后编辑:我刚刚编辑了我的脚本,如下所示。我可以通过此输出看到何时按下按钮一次或两次:
Starting Fire
Stopping Fire
但是led不会打开,好像fire.py没有打开或类似的东西..当我在fire.py本身中设置button = 1时,火就打开了。
主文件
#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-
import flicbutton
import fire
button = 0
按钮.py
#!/usr/bin/env /usr/bin/python3
# -*- coding: utf-8 -*-
import fliclib
client = fliclib.FlicClient("localhost")
MyButton1 = '80:e4:da:71:83:42' #turquoise flic button
def got_button(bd_addr):
cc = fliclib.ButtonConnectionChannel(bd_addr)
cc.on_button_single_or_double_click_or_hold = some_handler
cc.on_connection_status_changed = \
lambda channel, connection_status, disconnect_reason: \
print(channel.bd_addr + " " + str(connection_status) + (" " + str(disconnect_reason) if connection_status == fliclib.ConnectionStatus.Disconnected else ""))
client.add_connection_channel(cc)
def got_info(items):
print(items)
for bd_addr in items["bd_addr_of_verified_buttons"]:
got_button(bd_addr)
def some_handler(channel, click_type, was_queued, time_diff):
if channel.bd_addr == MyButton1:
try:
if click_type == fliclib.ClickType.ButtonSingleClick:
print("Starting Fire")
button=1
if click_type == fliclib.ClickType.ButtonDoubleClick:
print("Stopping Fire")
button=2
if click_type == fliclib.ClickType.ButtonHold:
print("ButtonHold has not been assigned an action")
except Exception:
import datetime
print('An error occured: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()))
client.get_info(got_info)
client.on_new_verified_button = got_button
client.handle_events()
火.py
import RPi.GPIO as GPIO
import threading
import time
import random
import math
R = 17
G = 22
pwms = []
intensity = 1.0
def initialize_gpio():
GPIO.setmode(GPIO.BCM)
GPIO.setup([17,22], GPIO.OUT)
def red_light():
p = GPIO.PWM(R, 300)
p.start(100)
pwms.append(p)
while True:
p.ChangeDutyCycle(min(random.randint(50, 100) * math.pow(intensity + 0.1, 0.75), 100) if intensity > 0 else 0)
rand_flicker_sleep()
def green_light():
global green_dc
p = GPIO.PWM(G, 300)
p.start(0)
pwms.append(p)
while True:
p.ChangeDutyCycle(random.randint(5, 10) * math.pow(intensity, 2) if intensity > 0 else 0)
rand_flicker_sleep()
def rand_flicker_sleep():
time.sleep(random.randint(3,10) / 100.0)
def fan_the_flame(_):
global intensity
intensity = min(intensity + 0.25, 1.0)
def light_candle():
threads = [
threading.Thread(target=red_light),
threading.Thread(target=green_light),
## threading.Thread(target=burning_down)
]
for t in threads:
t.daemon = True
t.start()
for t in threads:
t.join()
def startfire():
try:
initialize_gpio()
print("\nPress ^C (control-C) to exit the program.\n")
light_candle()
except KeyboardInterrupt:
pass
finally:
for p in pwms:
p.stop()
def stopfire():
GPIO.cleanup()
#if __name__ == '__main__':
# main()
if button == 1:
startfire()
if button == 2:
stopfire()
解决方案
Have a common (global variable) that both codes can read, you can put this in a standalone file that both codes can access. So script 1 updates this variable like
if(single press): variable=1
elif(double press): variable=2
then in fire.py you can poll the variable.
if(varaible==1): start/stop fire
elif(variable==2): stop/start fire
else: #throw error
I'm sure there are more efficient ways to do this, but this method should be the easiest to understand.
推荐阅读
- r - 根据条件从不同列复制值(r 代码)
- jquery - Magnific Popup 后备图片源
- c# - 使用 wpf 在窗口之间传递信息
- firebase - 将离子单选按钮表单连接到 Firebase 实时数据库
- flutter - 如何在 GitHub 操作中设置 dart 版本?
- php - stripos 动态过滤
- python - 从下拉列表中随机选择python
- input - Roblox Lua 在按键时运行脚本并且你在一定距离之外
- corda - 为什么我们在 r3 Corda 的 Contracts 中创建空的静态命令类?他们是空的有什么意义?它们的用途是什么?
- arrays - 我无法从 Vuex 遍历数组