Я совершенствую систему удаленного управления телескопом. Raspberry Pi запускает колбу и предоставляет видеопоток для камеры, прикрепленной к телескопу. Фокусер телескопа приводится в действие шаговым двигателем, управляемым Arduino. Сервер предоставляет веб-сайт, который показывает видеопоток, и предлагает две кнопки для перемещения и фокусировки фокуса.
При нажатии любой кнопки клиент отправляет сообщение POST в RasPi, а затем RasPi сообщает Arduino о перемещении фокусера. Но принципиально я не хотел, чтобы страница обновлялась при перефокусировке. Поэтому я использовал jQuery и Ajax для подавления обновления страницы.
Соответствующие фрагменты кода здесь:
Код Python / Flask:
@app.route('/stream/<wcam>', methods=['GET'])
def stream_get(wcam):
class FocuserForm(FlaskForm):
nsteps = IntegerField('# steps: ', default=1)
focuser_in = SubmitField('Focuser in')
focuser_out = SubmitField('Focuser out')
form = FocuserForm()
return render_template('stream.html', wcam=wcam, form=form)
@app.route('/stream/<wcam>', methods=['POST'])
def stream_post(wcam):
results = request.form
arduino_serial = SerialFocuser()
if results['caller'] == "focuser_in":
command = "MVD" + results['steps'] + "\n"
arduino_serial.send_command(command)
elif results['caller'] == "focuser_out":
command = "MVU" + results['steps'] + "\n"
arduino_serial.send_command(command)
return ''
Интернет (stream.html):
<html>
<head>
<title>Video Streaming</title>
<style>
...
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(document).ready(function() {});
</script>
</head>
<body>
<h1>Streaming camera {{ wcam }}</h1>
<br>
<img id="bg" src="{{ url_for('video_feed', wcam=wcam) }}", height="480" width="640">
<a href="{{ url_for('index') }}">Back</a>
<br>
<!--######################################################-->
<!--# Focuser handling -->
<!--######################################################-->
<br>
<form id="flaskform" method="POST">
<p>
{{ form.nsteps.label }} {{ form.nsteps() }}
{{ form.focuser_in() }}
{{ form.focuser_out() }}
</p>
</form>
<script>
// $(document).ready(function() { // Moved to header
var form = document.getElementById('flaskform');
function onSubmit(event) {
console.log('onSubmit function');
var objectID = event.explicitOriginalTarget.id;
var nsteps = form.nsteps.value;
var return_data = {caller: "", steps: nsteps};
if (objectID == "focuser_in") {
return_data.caller = objectID;
console.log("Focuser_in detected");
} else if (objectID == "focuser_out") {
return_data.caller = objectID;
console.log("Focuser_out detected");
} else if (objectID == "nsteps") {
console.log("nsteps detected");
event.preventDefault();
return;
} else {
console.log("No matches");
return;
}
console.log("About to run Ajax");
$.ajax({
url: "stream.html",
type: "post",
data: return_data,
success: function(response) {
console.log('It worked!');
},
error: function(xhr, status, text) {
console.log('An error occurred:', status,"; ", text);
},
timeout: 1000 // 1s
}); // Ajax
console.log("After running Ajax");
if (event) { event.preventDefault(); }
}
// prevent when a submit button is clicked
form.addEventListener('submit', onSubmit, false);
//<!--form.addEventListener('submit', onSubmit, false);-->
// prevent submit() calls by overwriting the method
form.submit = onSubmit;
//}); // Moved to header
</script>
</body>
</html>
Проблема заключается в следующем:
Если я обновлю страницу в браузере клиента, а затем нажму кнопку, ajax выполнит POST, но колба не получит ее. Время ожидания запроса истекло.
Если я теперь перезагружаю сервер (я разрабатываю это с помощью PyCharm, поэтому я просто нажимаю повторно запустить), не обновляя страницу в клиенте, а затем нажимаю кнопку, колба получает POST, и фокусер работает как шарм.
Если я обновлю страницу еще раз, кнопки перестанут работать, пока я не перезагружу сервер.
Почему это происходит? Очевидно, что код работает по своему основному назначению, но каким-то образом обновление страницы что-то ломает.