I finally chose Flask for my project. The reason is that Django is too complex for my project. I think Django is good for a clean and structured web site. I think it can be useful for collaborative. The formation to Django is also violent for a guy like me who just dived in the web. I think real-life formation on Django is needed.
While I looked at some tutorial on Django, I finished my project with Flask.
Django has a bigger community and much more contributions but Flask framework complexity is very small.
Here is an example of real-time web interface with Flask :
Folder
—>app.py
—>templates
------>index.html
The folder must have a ‘templates’ folder in which you have the following index.html file :
<!DOCTYPE HTML>
<html>
<head>
<title>Flask-SocketIO Test</title>
<script type="text/javascript" src="//code.jquery.com/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.5/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
namespace = '/test'; // change to an empty string to use the global namespace
if(window.DeviceOrientationEvent) {
window.addEventListener("deviceorientation", process, false);
} else {
// Le navigateur ne supporte pas l'événement deviceorientation
}
// the socket.io documentation recommends sending an explicit package upon connection
// this is specially important when using the global namespace
var socket = io.connect('http://' + document.domain + ':' + location.port + namespace);
// event handler for server sent data
// the data is displayed in the "Received" section of the page
socket.on('flow', function(msg) {
$('#time').html(msg.data);
});
$('#slider').live('input', function() {
socket.emit('robot', {motor: 'NECK_YAW',value: $(this).val()});
return false;
});
function process(event) {
var alpha = event.alpha;
var beta = event.beta;
var gamma = event.gamma;
socket.emit('pad', {alpha: alpha,beta: beta,gamma: gamma});
}
});
</script>
</head>
<body>
<h1>Test</h1>
<div id="time"></div>
<h2>Orientation du regard</h2> <br>
<input id="slider" type="range" min="0" max="1" value="0.5" step="0.01"/> <br>
</body>
</html>
In the folder, create the app.py file in which :
#!/usr/bin/env python
# Set this variable to "threading", "eventlet" or "gevent" to test the
# different async modes, or leave it set to None for the application to choose
# the best option based on available packages.
async_mode = None
if async_mode is None:
try:
import eventlet
async_mode = 'eventlet'
except ImportError:
pass
if async_mode is None:
try:
from gevent import monkey
async_mode = 'gevent'
except ImportError:
pass
if async_mode is None:
async_mode = 'threading'
print('async_mode is ' + async_mode)
# monkey patching is necessary because this application uses a background
# thread
if async_mode == 'eventlet':
import eventlet
eventlet.monkey_patch()
elif async_mode == 'gevent':
from gevent import monkey
monkey.patch_all()
import time
from threading import Thread
from flask import Flask, render_template, url_for
from flask_socketio import SocketIO, emit
import csv
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, async_mode=async_mode)
thread = None
class Engine(Thread):
def __init__(self):
Thread.__init__(self)
self.flow = {}
def run(self):
display = ''
while True:
time.sleep(0.05)
self.flow["t"] = time.time()
flowstr = str(self.flow)
flowstr = flowstr.replace(',','<br>')
flowstr = flowstr.replace('{','')
flowstr = flowstr.replace('}','')
socketio.emit('flow',
{'data': flowstr},
namespace='/test')
@app.route('/')
def index():
global thread
if thread is None:
thread = Engine()
thread.daemon = True
thread.start()
return render_template('index.html')
@socketio.on('robot', namespace='/test')
def handle_robot(message):
thread.flow[message['motor']]=message['value']
@socketio.on('pad', namespace='/test')
def handle_pad(message):
thread.flow['alpha']=message['alpha']
thread.flow['beta']=message['beta']
thread.flow['gamma']=message['gamma']
if __name__ == '__main__':
socketio.run(app,host='0.0.0.0',debug=True)
Then run the app.py script and open a web browser at http://127.0.0.1:5000
You will see this page :
The Thread Engine can synchronise the web page with the robot as wanted.
The small feature here is that the value of the slider is read and directed to the flow which can be accessed by the robot.
Passing by the javascript, if the robot is commanded by a tablet, you can get the orientation of the tablet (alpha, beta and gamma) here it is None because it is on my laptop which has no inertial measurement
I think, having the equivalent of this example with Django could be much more complex.
BUT, I have to see now the robustness…