保存变量的Python蓝图Flask

0 投票
2 回答
743 浏览
提问于 2025-04-18 10:20

我开发了一个应用程序,可以通过互联网控制一些设备,使用的是Flask和蓝图,运行在树莓派上。在客户端,我有一个安卓应用,它发送HTTP请求,而树莓派上的Flask应用则作为服务器进行响应。我有一个场景是控制风扇,通过设置一个引脚来进行PWM(脉宽调制),然后改变它的占空比来控制风扇的转速。在我改变风扇速度后,应用会返回一个JSON消息,里面包含当前的占空比以及风扇是否在转动(我知道转动的部分没什么用 :))。问题是,我无法把占空比保存在一个变量里,因为每次我重新调用那个只报告状态的函数时,它都会重置(就是那个带有“/”路由的函数)。我想不出一个简单快速的方法来做到这一点,而不想使用文件来保存,如果可以的话,我希望尽量避免用文件。

这是主应用的代码,里面注册了控制风扇的蓝图。

from flask import Flask
from scen3 import scen3_api
from scen2 import scen2_api
app = Flask(__name__)


app.register_blueprint(scen3_api, url_prefix='/scenariu/3')
app.register_blueprint(scen2_api, url_prefix='/scenariu/2')
@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80, debug=True)

这是第二个脚本的代码,里面包含了场景2的内容。基本上,它在设置引脚后有两个函数,一个是在“/”路由上返回占空比和转动状态,另一个是在“/PWMValue/”路由上根据参数改变PWM的值。

import RPi.GPIO as GPIO
from flask import Flask, render_template, request, jsonify, Blueprint

scen2_api= Blueprint('scen2_api', __name__)    

GPIO.setmode(GPIO.BOARD)

GPIO.setup(12, GPIO.OUT)
GPIO.setup(18, GPIO.OUT)

GPIO.output(18, GPIO.HIGH)

GPIO.setup(16,GPIO.OUT)
GPIO.output(16,GPIO.LOW)

dutyCycle=0
spin=0
p = GPIO.PWM(12, 500)

p.start(float(dutyCycle))
#spin=0
@scen2_api.route("/")
def main():
    spin=0  
    if dutyCycle != 0.0:
        spin=1
return jsonify(state=str(spin),pwmvalue=str(dutyCycle))


@scen2_api.route("/PWMValue/<action>")
def action( action):

    dutyCycle=float(action)
    p.ChangeDutyCycle(float(dutyCycle))

    return jsonify(state=str(spin),pwmvalue=str(dutyCycle))

每次我调用报告函数时,它都返回0的占空比和转动状态。我该如何解决这个问题,同时又希望它的行为保持不变,最好是不使用文件?谢谢 :)

2 个回答

0

你可能遇到了作用域的问题,也可能有缩进的问题……但你的问题主要是和作用域有关:

action(action) 这个函数里,你设置了一个叫 dutyCycle 的变量,这个变量只在 action 函数内部有效。我想你是希望改变一个“全局”的变量。为了更好地理解发生了什么,看看下面的内容:

>>> g = 34
>>> g
34
>>> def f(n):
...     g = n
...     print g
...
>>> f(3)
3
>>> g
34
>>>

f 只改变了它自己内部的 g,并没有改变你期待的全局变量。你可以看看这篇博客,了解一下 Python 的执行模型。你可以直接看“块和作用域”那一部分,但我建议你把整篇都读一下。

回到你的代码:

  • 其实没有必要使用全局变量 dutyCyclespin
  • 把所有的 GPIO 初始化放到一个单独的函数里
0

spindutyCycle 是在 mainaction 函数里面的局部变量。你在这些函数里定义的所有变量默认都是局部的。如果你想让 Python 把它们当作全局变量来使用,就需要用 global 这个关键词来告诉它。

@scen2_api.route("/")
def main():
    global spin
    spin=0
    if dutyCycle != 0.0:
        spin=1
    return jsonify(state=str(spin), pwmvalue=str(dutyCycle))


@scen2_api.route("/PWMValue/<action>")
def action( action):
    global dutyCycle
    dutyCycle = float(action)
    p.ChangeDutyCycle(float(dutyCycle))

    return jsonify(state=str(spin), pwmvalue=str(dutyCycle))

撰写回答