Raspberry Pi Python-Flask Server Sensor Application

Raspberry Pi Python-Flask Server Sensor Application

flask_led_server_ws.zip

ws_sensor_led.svg

Server Side ( RPI ) :

$ python3 app.py

Client Side :

192.168.0.2:5000 in a web browser.

app.py
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
from sense_hat import SenseHat
import subprocess
import datetime

app = Flask(__name__)
socketio = SocketIO(app)

#=======================================================================
#				index.html
#=======================================================================
@app.route('/')
def index():
    """Serve the index HTML"""
    return render_template('index.html')

#=======================================================================
#				gauge.js
#=======================================================================
@app.route('/gauge.js')
def gauge():
    return render_template('gauge.js')

#=======================================================================
#				led action + response
#=======================================================================
@app.route("/gpio4/<led_state>")
def control_led_action(led_state):
    print("control_led_action")
    if led_state == "true": 
        print("action==true")
        bashCommand = "echo 1 > /sys/class/gpio/gpio4/value"
        output = subprocess.check_output(['bash','-c', bashCommand]) 
        ledS="ON"      
 
    else: 
        print("action==false")
        bashCommand = "echo 0 > /sys/class/gpio/gpio4/value"
        output = subprocess.check_output(['bash','-c', bashCommand]) 
        ledS="OFF"
      
    now = datetime.datetime.now()
    timeString = now.strftime("%Y-%m-%d %H:%M:%S")
    templateData = {
    'time': timeString ,
    'ledS' : ledS
      }                  
    return render_template('ajax_led_response.html',**templateData)

#=======================================================================
#				socketio ( websocket ) 
#=======================================================================
@socketio.on('create')
def on_create(data):
    print("create")
    it=data['iterations']
    for i in range(it):
        sense = SenseHat()
        press = sense.get_pressure()
        temp = sense.get_temperature()
        print("pressure=",press)
        socketio.sleep(1)
        emit('mess_from_server', {'pressure': round(press,2), 'temperature' : round(temp,2)})

#=======================================================================        
if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', debug=True)
# RPI TERM
$ python3 app.py
* Restarting with stat
* Debugger is active!
* Debugger PIN: 955-561-534
(2499) wsgi starting up on http://0.0.0.0:5000
(2499) accepted ('192.168.0.1', 36052)
(2499) accepted ('192.168.0.1', 36054)
192.168.0.1 - - [25/Oct/2018 11:53:31] "GET / HTTP/1.1" 200 4178 0.062617
192.168.0.1 - - [25/Oct/2018 11:53:31] "GET /gauge.js HTTP/1.1" 200 1670 0.012142
192.168.0.1 - - [25/Oct/2018 11:53:36] "GET /socket.io/?EIO=3&transport=polling&t=1540461216423-0 HTTP/1.1" 200 381 0.002522
		...

index.html

templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>RPI Python-Flask Sensor App </title>
</head>
<body>
<!--=================================================================-->
<!--				DISPLAYS										 -->
<!--=================================================================-->
<script>
display_log=function(msg)
{
	  var logArea = 0;		
	  
	  if(!logArea)
	  { logArea=document.getElementById("log"); }
	  if(msg==null)
	  { logArea.textContent='';}
	  else { logArea.textContent+=msg+'\n'; }
};
</script> 
<script src="gauge.js"></script>
<!--=================================================================-->
<!--				WEBSOCKET SCRIPT								 -->
<!--=================================================================-->
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
	   	    
    var socket = io.connect('http://' + document.domain + ':' + location.port);
	<!----------------------------------------------------------------->    
    socket.on('connect', function() {
        console.log('Websocket connected!');
    });
	<!----------------------------------------------------------------->    
    // listen to the event
    socket.on('mess_from_server', function(msg) {
        console.log(msg);
        display_log("pressure = "+msg.pressure + " temperature = "+msg.temperature) ;
		var gauge=new Gauge('gauge'); 
		gauge.draw(msg.pressure);
		
       });
	<!----------------------------------------------------------------->
    function start() {
      console.log('start...');
      nbr_meas = document.getElementById("nbr_meas");
      socket.emit('create', {iterations:  parseInt(nbr_meas.value)});
    }    
</script>
<!--=================================================================-->
<!--				AJAX REQUEST FOR LED CONTROL					 -->
<!--=================================================================--> 
<script>
	function do_onclick(led, label)
	{
		  var xmlhttp=new XMLHttpRequest();
		  
		  // register callback : function to be called when we receive the response
		  xmlhttp.onreadystatechange=function() {
			if (xmlhttp.readyState==4 && xmlhttp.status==200) {
			  label.innerHTML=xmlhttp.responseText;
			}
		  }
		  
		  // send request and poll for asynchronous response
		  xmlhttp.open("GET","gpio4/"+led.checked,true)
		  xmlhttp.send();
	}
</script>	
<!--=================================================================-->
<!--				INIT					 						 -->
<!--=================================================================--> 
<script>
	window.onload = function() {
			var led=document.getElementById("tLed");
			var label=document.getElementById("tLedLabel");
			led.checked=false;
			do_onclick(led, label);
	};
</script>
<!--=================================================================-->
<!--				HTML											 -->
<!--=================================================================-->

<p>[<a href="/">home</a>]</p>

<hr> <!---------------------------------------------------------------->

<h2>Control GPIO4 LED</h2>

<table>
	<tr>
	<td > 
			<h3>Static Part :</h3>
			Control GPIO4 led <input type="checkbox" id="tLed" onclick="do_onclick(this, document.getElementById('tLedLabel'))">
	</td>
	<td>	
			<span id="tLedLabel"> GPIO4 led turned off</span>		
	</td>
	</tr>
</table>

<hr> <!---------------------------------------------------------------->

<h2>Get Measured data through Websocket</h2>  
<table>
	<tr>
	<td > 
			<strong> Number of Measurements :  </strong><br/>   
			<input type="text" id="nbr_meas"/>     <br/>   
			<button onclick="start()">Start</button>
	</td>
	<td>	
			<h3> Pressure Measurement </h3>
			<div >
			<canvas id="gauge" width="170" height="170"></canvas>
			</div>			
	</td>
	</tr>
</table>

<p><b>Log:</b></p>
<p></p><pre id="log"></pre><p></p>	

<hr> <!---------------------------------------------------------------->
  
</body>
</html>
<!--=================================================================-->