mirror of
https://github.com/CopterExpress/clever-show.git
synced 2026-05-26 23:19:33 +00:00
Added file transfer (server => copter)
This commit is contained in:
@@ -1,17 +1,11 @@
|
||||
import os
|
||||
from json import loads
|
||||
from flask import Blueprint, request, jsonify
|
||||
from web_server_models import copters
|
||||
|
||||
file_sender_api = Blueprint('file_sender_api', __name__, template_folder='templates')
|
||||
|
||||
|
||||
@file_sender_api.route('/set/animation', methods=['GET', 'POST'])
|
||||
def set_animation():
|
||||
if request.method == 'POST':
|
||||
f = request.files['file']
|
||||
print(f, 'ip', request.args.get('ip'))
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@file_sender_api.route('/set/config', methods=['GET', 'POST'])
|
||||
def set_config():
|
||||
if request.method == 'POST':
|
||||
@@ -23,6 +17,30 @@ def set_config():
|
||||
@file_sender_api.route('/set/aruco', methods=['GET', 'POST'])
|
||||
def set_aruco():
|
||||
if request.method == 'POST':
|
||||
f = request.files['file']
|
||||
print(f, 'ip', request.args.get('ip'))
|
||||
for key_name in request.files.keys():
|
||||
request.files[key_name].save(os.path.join('files', key_name))
|
||||
for ip in loads(request.args.get('ips')):
|
||||
for copter in copters:
|
||||
if copter.ip == ip:
|
||||
copter.client.send_file('files/' + key_name, "/home/pi/catkin_ws/src/clever/aruco_pose/map/animation_map.txt")
|
||||
copter.client.send_message("service_restart", {"name": "clever"})
|
||||
os.remove('files/' + key_name)
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@file_sender_api.route('/set/animation', methods=['GET', 'POST'])
|
||||
def set_animation():
|
||||
if request.method == 'POST':
|
||||
files = []
|
||||
names = []
|
||||
for key_name in request.files.keys():
|
||||
names.append(key_name.replace('.csv', ''))
|
||||
request.files[key_name].save(os.path.join('files', key_name))
|
||||
files.append('files/' + key_name)
|
||||
for file, name in zip(files, names):
|
||||
for copter in copters:
|
||||
if name == copter.name:
|
||||
copter.client.send_file(file, "animation.csv")
|
||||
for filename in files:
|
||||
os.remove(filename)
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from flask import Blueprint, request, jsonify
|
||||
from web_server_models import delay, set_delay_manually, get_delay_manually
|
||||
from web_server_models import set_delay_manually, get_delay_manually, copters
|
||||
from server import Client
|
||||
|
||||
misc_api = Blueprint('misc_api', __name__, template_folder='templates')
|
||||
|
||||
@@ -13,3 +14,57 @@ def set_delay():
|
||||
@misc_api.route('/get/delay', methods=['GET', 'POST'])
|
||||
def get_delay():
|
||||
return jsonify(get_delay_manually())
|
||||
|
||||
|
||||
@misc_api.route('/stop/all', methods=['GET', 'POST'])
|
||||
def stop_all():
|
||||
Client.broadcast_message("stop")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@misc_api.route('/disarm/all', methods=['GET', 'POST'])
|
||||
def disarm_all():
|
||||
Client.broadcast_message("disarm")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@misc_api.route('/land/all', methods=['GET', 'POST'])
|
||||
def land_all():
|
||||
Client.broadcast_message("land")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@misc_api.route('/flip/selected', methods=['GET', 'POST'])
|
||||
def flip_selected():
|
||||
ip = request.args.get("ip")
|
||||
for copter in copters:
|
||||
if copter.ip == ip:
|
||||
copter.client.send_message("flip")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@misc_api.route('/takeoff/selected', methods=['GET', 'POST'])
|
||||
def takeoff_selected():
|
||||
ip = request.args.get("ip")
|
||||
for copter in copters:
|
||||
if copter.ip == ip:
|
||||
copter.client.send_message("takeoff")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@misc_api.route('/pause/selected', methods=['GET', 'POST'])
|
||||
def pause_selected():
|
||||
ip = request.args.get("ip")
|
||||
for copter in copters:
|
||||
if copter.ip == ip:
|
||||
copter.client.send_message("pause")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@misc_api.route('/resume/selected', methods=['GET', 'POST'])
|
||||
def resume_selected():
|
||||
ip = request.args.get("ip")
|
||||
for copter in copters:
|
||||
if copter.ip == ip:
|
||||
copter.client.send_message("resume")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
@@ -3,13 +3,41 @@ let configInput = document.getElementById('configFile');
|
||||
let arucoInput = document.getElementById('arucoFile');
|
||||
|
||||
animationInput.onchange = function (e) {
|
||||
sendRows(table.getSelectedRows(), animationInput.files[0], 'animation');
|
||||
spinner.style.display = 'inline-block';
|
||||
setTimeout(function () {
|
||||
if (animationInput.files.length > 0) {
|
||||
let fileReq = new XMLHttpRequest();
|
||||
let fileFormData = new FormData();
|
||||
for (let i = 0; i < animationInput.files.length; i++) {
|
||||
fileFormData.append(animationInput.files[i].name, animationInput.files[i]);
|
||||
}
|
||||
fileReq.open("POST", '/set/animation', false);
|
||||
fileReq.send(fileFormData);
|
||||
deselectAll();
|
||||
spinner.style.display = 'none';
|
||||
}
|
||||
}, 20);
|
||||
};
|
||||
configInput.onchange = function (e) {
|
||||
sendRows(table.getSelectedRows(), configInput.files[0], 'config');
|
||||
};
|
||||
arucoInput.onchange = function (e) {
|
||||
sendRows(table.getSelectedRows(), arucoInput.files[0], 'aruco');
|
||||
spinner.style.display = 'inline-block';
|
||||
setTimeout(function () {
|
||||
if (arucoInput.files.length > 0) {
|
||||
let fileReq = new XMLHttpRequest();
|
||||
let fileFormData = new FormData();
|
||||
let ips = [];
|
||||
table.getSelectedRows().forEach(function (element) {
|
||||
ips.push(element._row.data.ip);
|
||||
});
|
||||
fileFormData.append(arucoInput.files[0].name, arucoInput.files[0]);
|
||||
fileReq.open("POST", '/set/aruco?ips=' + encodeURIComponent(JSON.stringify(ips)), false);
|
||||
fileReq.send(fileFormData);
|
||||
deselectAll();
|
||||
spinner.style.display = 'none';
|
||||
}
|
||||
}, 20);
|
||||
};
|
||||
|
||||
function sendRows(selectedRows, file, file_type) {
|
||||
|
||||
@@ -77,30 +77,28 @@ function deselectAll() {
|
||||
});
|
||||
}
|
||||
|
||||
function testLedSelected() {
|
||||
function sendCommandToSelected(command) {
|
||||
spinner.style.display = 'inline-block';
|
||||
setTimeout(function () {
|
||||
table.getSelectedRows().forEach(function (element) {
|
||||
let req = new XMLHttpRequest();
|
||||
req.open('POST', '/test_led/selected?ip=' + element._row.data.ip);
|
||||
req.open('POST', '/' + command + '/selected?ip=' + element._row.data.ip);
|
||||
req.send();
|
||||
element.deselect();
|
||||
});
|
||||
deselectAll();
|
||||
spinner.style.display = 'none';
|
||||
}, 20);
|
||||
}
|
||||
|
||||
function pauseCopters() {
|
||||
|
||||
function testLedSelected() {
|
||||
sendCommandToSelected('test_led');
|
||||
}
|
||||
|
||||
function stopCopters() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
function emLand() {
|
||||
|
||||
let req = new XMLHttpRequest();
|
||||
req.open('POST', '/stop/all', false);
|
||||
req.send();
|
||||
}
|
||||
|
||||
function setStartTime() {
|
||||
@@ -108,11 +106,57 @@ function setStartTime() {
|
||||
title: "Set animation delay",
|
||||
form: {delay: "Delay"}
|
||||
}).done(function (ui) {
|
||||
setDelay(parseInt(ui.data.delay));
|
||||
updateDelay();
|
||||
if (ui.state) {
|
||||
setDelay(parseInt(ui.data.delay));
|
||||
updateDelay();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function startAnimation() {
|
||||
function takeOff() {
|
||||
sendCommandToSelected('takeoff');
|
||||
}
|
||||
|
||||
function flipCopters() {
|
||||
sendCommandToSelected('flip');
|
||||
}
|
||||
|
||||
function land() {
|
||||
let req = new XMLHttpRequest();
|
||||
req.open('POST', '/land/all', false);
|
||||
req.send();
|
||||
}
|
||||
|
||||
function disarm() {
|
||||
let req = new XMLHttpRequest();
|
||||
req.open('POST', '/disarm/all', false);
|
||||
req.send();
|
||||
}
|
||||
|
||||
function pauseCopters() {
|
||||
sendCommandToSelected('pause');
|
||||
}
|
||||
|
||||
function resumeCopters() {
|
||||
sendCommandToSelected('resume');
|
||||
}
|
||||
|
||||
function emLand() {
|
||||
spinner.style.display = 'inline-block';
|
||||
setTimeout(function () {
|
||||
let req = new XMLHttpRequest();
|
||||
req.open('POST', '/em_land', false);
|
||||
req.send();
|
||||
spinner.style.display = 'none';
|
||||
}, 20);
|
||||
}
|
||||
|
||||
function startAnimation() {
|
||||
spinner.style.display = 'inline-block';
|
||||
setTimeout(function () {
|
||||
let req = new XMLHttpRequest();
|
||||
req.open('POST', '/start_animation', false);
|
||||
req.send();
|
||||
spinner.style.display = 'none';
|
||||
}, 20);
|
||||
}
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item">
|
||||
<label for="animationFile" class="btn">Set animation</label>
|
||||
<input id="animationFile" style="visibility:hidden;" type="file">
|
||||
<input accept=".csv" id="animationFile" style="visibility:hidden;" type="file">
|
||||
</div>
|
||||
<div class="dropdown-item">
|
||||
<label for="configFile" class="btn">Set configuration</label>
|
||||
@@ -36,7 +36,7 @@
|
||||
</div>
|
||||
<div class="dropdown-item">
|
||||
<label for="arucoFile" class="btn">Set ArUco map</label>
|
||||
<input id="arucoFile" style="visibility:hidden;" type="file">
|
||||
<input accept=".txt" id="arucoFile" style="visibility:hidden;" type="file">
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@@ -78,11 +78,20 @@
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-warning btn-lg" onclick="pauseCopters()">Pause</button>
|
||||
<button type="button" class="btn btn-warning btn-lg" onclick="resumeCopters()">Resume</button>
|
||||
<button type="button" class="btn btn-warning btn-lg" onclick="stopCopters()">Stop</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-danger btn-lg" onclick="emLand()">Emergency landing</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-primary btn-lg" onclick="takeOff()">Take off</button>
|
||||
<button type="button" class="btn btn-outline-primary btn-lg" onclick="flipCopters()">Flip</button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-primary btn-lg" onclick="land()">Land</button>
|
||||
<button type="button" class="btn btn-outline-primary btn-lg" onclick="disarm()">Disarm</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-container"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from server import Server
|
||||
from flask import Flask, render_template
|
||||
from web_server_models import copters, get_delay_manually
|
||||
from flask import Flask, render_template, jsonify, request
|
||||
from app_routes.selfcheck import selfcheck_api, refresh_copters
|
||||
from app_routes.file_sender import file_sender_api
|
||||
from app_routes.misc import misc_api
|
||||
@@ -17,6 +18,20 @@ def home():
|
||||
return render_template('main.html', data=data)
|
||||
|
||||
|
||||
@app.route('/start_animation', methods=['GET', 'POST'])
|
||||
def resume_selected():
|
||||
for copter in copters:
|
||||
server.send_starttime(copter.client, get_delay_manually())
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
@app.route('/em_land', methods=['GET', 'POST'])
|
||||
def em_land_selected():
|
||||
for copter in copters:
|
||||
copter.client.send_message("land")
|
||||
return jsonify({'m': 'ok'})
|
||||
|
||||
|
||||
server = Server()
|
||||
server.start()
|
||||
app.run(host='0.0.0.0', debug=False)
|
||||
|
||||
Reference in New Issue
Block a user