[蟒蛇][希罗库]不能经常稳定地向树莓派发送信号



我在Heroku上部署了一个应用程序,该应用程序通过CloudMQTT控制Raspberry Pi GPIO。

这是我的应用程序配置:

Enviroment:Heroku
Front-end: HTML, JavaScript(jQuery)
Server-side: Python(Flask)

但在以下情况下,在这种情况下,它不能经常稳定地向树莓派发送信号。

  • 连续发送信号时
  • 当信号在没有任何时间延迟的情况下发送时

以下情况没有问题。

  • 在本地环境中运行应用程序
  • 从应用程序中删除登录功能时

我认为这个问题发生在登录函数和发送MQTT的函数之间,你怎么看?还是有其他原因?

不管怎样,我能问一下如何解决这个案子吗?

如果你还有其他问题,请告诉我。

这是我的应用程序目录:

RPi_app
│  
├─app.py
├─variable.py
│
├─sendMQTT
│      ca-certificates.crt
│      GPIO_Control_SendMQTT_One.py
│      GPIO_Control_SendMQTT_Three.py
│      GPIO_Control_SendMQTT_Two.py
│
├─static
│      SendToRPi.js
│
└─templates
index.html
login.html

应用程序

# -*- coding: utf-8 -*-
import os
from flask_sqlalchemy import SQLAlchemy
from flask import Flask, render_template, request
from flask_login import UserMixin, LoginManager, login_user, login_required
from werkzeug.security import check_password_hash
import flask_wtf
import wtforms
from wtforms import validators
from itsdangerous.url_safe import URLSafeTimedSerializer
from sendMQTT import GPIO_Control_SendMQTT_One
from sendMQTT import GPIO_Control_SendMQTT_Two
from sendMQTT import GPIO_Control_SendMQTT_Three
import variable
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = variable.SQLALCHEMY_DATABASE_URI
app.config['SECRET_KEY'] = os.urandom(24)
db = SQLAlchemy(app)
app.secret_key = os.urandom(24)
SALT = os.urandom(24)
currentDirctory = os.getcwd()
login_manager = LoginManager()
login_manager.init_app(app)
class NewPwdForm(flask_wtf.FlaskForm):
token = wtforms.HiddenField('token', [
validators.InputRequired()])
new_pwd1 = wtforms.PasswordField('PW', [
validators.InputRequired(),
validators.EqualTo('new_pwd2')])
new_pwd2 = wtforms.PasswordField('PW', [
validators.InputRequired()])
class AddressForm(flask_wtf.FlaskForm):
mail = wtforms.StringField('mail', [
validators.Email(message='WRONG FORMATT'),
validators.InputRequired(message='PUT IN ADDEESS')])
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True) 
username = db.Column(db.String(), nullable=False, unique=True)  
password = db.Column(db.String()) 
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))

@app.route('/', methods=['GET', 'POST'])
def login():
if request.method == "POST":
username = request.form.get('username')  
password = request.form.get('password')  
user = User.query.filter_by(username=username).first()
if user is None:
return render_template('login.html', login_Message="※NO USER※")
if check_password_hash(user.password, password):
login_user(user)
return render_template('index.html', username=str(user.username))
else:
return render_template('login.html', login_Message="※WRONG PW※")
else:
return render_template('login.html')

def create_token(user_id, secret_key, salt):
serializer = URLSafeTimedSerializer(secret_key)
return serializer.dumps(user_id, salt=salt)

def load_token(token, secret_key, salt, max_age=600):
serializer = URLSafeTimedSerializer(secret_key)
return serializer.loads(token, salt=salt, max_age=3600)

@app.route('/sendMovement', methods=['GET', 'POST'])
@login_required
def sendMovement():
if request.method == "POST":
PostMonement = str(request.form['Monement'])  
if PostMonement == "move_one":
GPIO_Control_SendMQTT_One.send()
if PostMonement == "move_two":
GPIO_Control_SendMQTT_Two.send()
if PostMonement == "move_three":
GPIO_Control_SendMQTT_Three.send()

return render_template('index.html')
if __name__ == "__main__":
app.run(host='0.0.0.0', threaded=True, debug=True)

SendToRPi.js

function one_click() {
Movement("move_one");
return;
}
function two_click() {
Movement("move_two");
return;
}

function three_click() {
Movement("move_three");
return;
}

function Movement(strMovement) {
var fData = new FormData();
fData.append('Monement', strMovement);
ajaxSend(fData, '/sendMovement')
return;
}
function ajaxSend(fData, urlFlask) {
//ajax
$.ajax({
url: urlFlask,
type: 'POST',
async: false,
data: fData,
contentType: false,
processData: false,
success: function(data, dataType) {
console.log('Success', data);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log('Error : ' + errorThrown);
}
});
}

index.html

<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="one_click();">ONE</button>
<button type="button" onclick="two_click();">TWO</button>
<button type="button" onclick="three_click();">THREE</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.7.0/qs.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="/static/SendToRPi.js?p=(new Date()).getTime() "></script>
</body>
</html>

检查MQTT qos并保留配置。如果qos=0,则一条消息有可能覆盖另一条消息(意味着该消息最多发送一次(请检查此项:[https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels/][1]

最新更新