我正在使泵自动化,只有当土壤湿度值(从土壤湿度传感器获得)超过某个值时才打开。就是这样:
用户从下拉列表中选择一个值(土壤湿度的阈值)
python脚本不断检查传感器的值是否大于下拉列表中选择的值(这就是为什么我需要让它作为后台任务运行)
用户可以使用网页上的OFF按钮终止后台任务来关闭自动化过程。
我尝试了以下操作,但我收到working outside of request context
错误:
web_plants.py (调用python soil_on.py脚本):
@app.route("/threshold", methods=['POST', 'GET'])
def threshold():
tvalue= -1 #get value from dropdown
msg = ''
if request.method == "POST":
msg= "rating above 3"
os.system("python soil_on.py&")
templateData = template(text = msg) #display text using template()
return render_template('index.html', **templateData)
soil_on.py (从auto_Irrigation()
类调用water
函数:
import water
if __name__ == "__main__":
water.auto_Irrigation()
water.py (有auto_Irrigation()
)
app = Flask(__name__)
def template(title = "HELLO!", text = ""):
templateDate = {
'text' : text,
'tvalues' : getTValues(),
'selected_tvalue' : -1
}
return templateDate
def getTValues():
return (10, 11, 15, 2, 1)
@app.route("/", methods=['POST', 'GET'])
def auto_Irrigation():
tvalue= -1 #get value from dropdown
# msg = ''
if request.method == "POST":
tvalue = int(request.form['tvalue'])
if tvalue> 3:
GPIO.output(40, GPIO.HIGH)
else:
GPIO.output(40, GPIO.LOW)
return render_template('index.html', **templateData)
的index.html :
<h2> {{text}} </h2>
<form action= "{{ url_for('threshold') }}" method="POST">
<select name= 'tvalue'>
{% for tvalue in tvalues %}
{% if selected_tvalue == tvalue %}
<option value="{{ tvalue }}" selected='selected'>{{ tvalue }}</option>
{% else %}
<option value="{{ tvalue }}" >{{ tvalue }}</option>
{% endif %}
{% endfor %}
</select>
<input type="submit" value="Submit" />
</form>
我不确定如何将该功能作为后台任务。目前这对我有用,但该功能没有作为后台任务运行(所以它只检查值并打开/关闭泵):
的index.html :
<h2> {{text}} </h2>
<form action= "{{ url_for('threshold') }}" method="POST">
<select name= 'tvalue'>
{% for tvalue in tvalues %}
{% if selected_tvalue == tvalue %}
<option value="{{ tvalue }}" selected='selected'>{{ tvalue }}</option>
{% else %}
<option value="{{ tvalue }}" >{{ tvalue }}</option>
{% endif %}
{% endfor %}
</select>
<input type="submit" value="Submit" />
</form>
web_plants.py:(为了使这篇文章更容易理解,简化了函数threshold()
)
def template(title = "HELLO!", text = ""):
templateDate = {
'text' : text,
'tvalues' : getTValues(),
'selected_tvalue' : -1
}
return templateDate
def getTValues():
return (10, 11, 15, 2, 1)
@app.route("/threshold", methods=['POST', 'GET'])
def threshold():
tvalue= -1 #default value
msg = ''
if request.method == "POST":
tvalue = int(request.form['tvalue'])
if tvalue> 3:
msg= "rating above 3"
#generating template data
templateData = template(text = msg)
templateData['selected_tvalue'] = tvalue
return render_template('index.html', **templateData)
答案 0 :(得分:1)
考虑使用Celery,它是一个异步任务队列。您可以继续运行长时间运行的作业,获取状态更新(甚至是自定义更新)。
这些链接可以帮助您了解它的工作原理:
https://github.com/miguelgrinberg/flask-celery-example
https://blog.miguelgrinberg.com/post/using-celery-with-flask
您甚至可以查看Celery文档。
这是您如何实现功能的示例。你可以从那里继续前进。
/tasks.py
@celery.task
def my_task(self, threshold):
if sensor_val < threshold:
self.update_state(state="Sensor Value below threshold", meta={'sensor_val':sensor_val, 'threshold':threshold})
else:
self.update_state(state="Sensor Value past threshold. Please check.", meta={'sensor_val':sensor_val, 'threshold':threshold})
"""Do whatever you would like to do"""
/views.py
def sensor_check(request):
if request.method == "POST":
threshold = request.POST['threshold']
from tasks import my_task
job = my_task.delay(threshold)
return HttpResponseRedirect(reverse("task_status")+"?job_id="+job.id)
def task_status(request):
if 'job_id' in request.GET:
job_id = request.GET['job_id']
job = AsyncResult(job_id)
data = job._get_task_meta()
return JsonResponse(data)
else:
JsonResponse("No job ID given")