我需要使用烧瓶网络浏览器应用程序控制Adafruit DotStar lighttrip。我已经能够让烧瓶应用程序工作,我已经做了一个简单的概念验证,打开和关闭LED等等,我可以启动我的灯光脚本,但我试图为灯光运行的代码需要循环,仍然能够改变“模式”。我有几个不同的图像显示在灯条上,我希望能够选择正在播放哪一个,但现在主要是我希望能够启动和停止“随机播放”模式。如果我在while循环中运行模块,它只是永远循环,我不能将参数更改为不同的“模式”。我建立了一个基于Adafruit的DotStar库的简单脚本(特别是视觉脚本的图像持久性,我只是使用PNG图像作为不同灯光“地图”的地图)。
这一切目前都有效,除了它只能显然运行一次模式。我在一个循环中完成了所有这一切,它只是永远循环第一个选定的模式,我无法将其关闭或切换模式。我也想过也许我应该使用多处理,然后我开始研究它是否正常工作,但是一旦它开始,我就无法弄清楚如何停止它。
这是灯条脚本:
('关闭'模式只是一个黑色图像。我确信这是一个更干净的方法,但我不知道如何做到这一点)
import Image
from dotstar import Adafruit_DotStar
import random
def lightstrip(mode):
loopLength = 120 #loop length in pixels
fade = "/home/pi/lightshow/images/fade.png"
sparkle = "/home/pi/lightshow/images/sparkle.png"
steeplechase = "/home/pi/lightshow/images/steeplechase.png"
bump = "/home/pi/lightshow/images/bump.png"
spaz = "/home/pi/lightshow/images/spaz.png"
sine = "/home/pi/lightshow/images/sine.png"
bounce = "/home/pi/lightshow/images/bounce.png"
off = "/home/pi/lightshow/images/null.png"
numpixels = 30
datapin = 23
clockpin = 24
strip = Adafruit_DotStar(numpixels, 100000)
rOffset = 3
gOffset = 2
bOffset = 1
strip.begin()
if mode == 1:
options = [fade, sparkle, steeplechase, bump, spaz, sine, bounce]
print "Shuffling All..."
if mode == 2:
options = [bump, spaz, sine, bounce]
print "Shuffling Dance..."
if mode == 3:
options = [fade, sparkle, steeplechase]
print "Shuffling Chill..."
if mode == 0:
choice = off
print "Lightstrip off..."
if mode != 0:
choice = random.choice(options)
print "Loading..."
img = Image.open(choice).convert("RGB")
pixels = img.load()
width = img.size[0]
height = img.size[1]
print "%dx%d pixels" % img.size
# Calculate gamma correction table, makes mid-range colors look 'right':
gamma = bytearray(256)
for i in range(256):
gamma[i] = int(pow(float(i) / 255.0, 2.7) * 255.0 + 0.5)
# Allocate list of bytearrays, one for each column of image.
# Each pixel REQUIRES 4 bytes (0xFF, B, G, R).
print "Allocating..."
column = [0 for x in range(width)]
for x in range(width):
column[x] = bytearray(height * 4)
# Convert entire RGB image into column-wise BGR bytearray list.
# The image-paint.py example proceeds in R/G/B order because it's counting
# on the library to do any necessary conversion. Because we're preparing
# data directly for the strip, it's necessary to work in its native order.
print "Converting..."
for x in range(width): # For each column of image...
for y in range(height): # For each pixel in column...
value = pixels[x, y] # Read pixel in image
y4 = y * 4 # Position in raw buffer
column[x][y4] = 0xFF # Pixel start marker
column[x][y4 + rOffset] = gamma[value[0]] # Gamma-corrected R
column[x][y4 + gOffset] = gamma[value[1]] # Gamma-corrected G
column[x][y4 + bOffset] = gamma[value[2]] # Gamma-corrected B
print "Displaying..."
count = loopLength
while (count > 0):
for x in range(width): # For each column of image...
strip.show(column[x]) # Write raw data to strip
count = count - 1
用于运行Web应用程序的main.py脚本:
from flask import *
from lightshow import *
from multiprocessing import Process
import RPi.GPIO as GPIO
import Image
from dotstar import Adafruit_DotStar
import random
import time
app = Flask(__name__)
@app.route("/")
def hello():
return render_template('index.html')
@app.route("/lightstrip/1", methods=['POST'])
def shuffleall():
lightstrip(1)
return ('', 204)
@app.route("/lightstrip/2", methods=['POST'])
def shuffledance():
lightstrip(2)
return ('', 204)
@app.route("/lightstrip/3", methods=['POST'])
def shufflechill():
lightstrip(3)
return ('', 204)
@app.route("/lightstrip/0", methods=['POST'])
def off():
lightstrip(0)
return ('', 204)
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
我再次在这里有点亏,这可能是一个简单的修复,或者我可能正在接近它完全错误,但任何和所有的帮助将不胜感激。我是一个完全初学者,可以解决这样的问题。谢谢
答案 0 :(得分:0)
以下是一个示例,说明如何使用multiprocessing和psutil启动和停止流程。在此示例中,task_runner
会在开始新进程之前终止所有正在运行的进程。
from flask import Flask
import multiprocessing
import psutil
app = Flask(__name__)
def blink(var):
while True:
# do stuff
print(var)
def task_runner(var):
processes = psutil.Process().children()
for p in processes:
p.kill()
process = multiprocessing.Process(target=blink, args=(var,))
process.start()
@app.route("/red")
def red():
task_runner('red')
return 'red started'
@app.route("/blue")
def blue():
task_runner('blue')
return 'blue started'
if __name__ == "__main__":
app.run()
对于您的问题,task_runner
看起来像:
def task_runner(mode):
processes = psutil.Process().children()
for p in processes:
p.kill()
process = multiprocessing.Process(target=lightstrip, args=(mode,))
process.start()