fbpixel
Etiquetas: , ,
0
(0)

O Raspberry Pi é um microcomputador muito potente que tem a particularidade de ser equipado com um chip que gerencia a conexão Wifi. Isso faz dele um equipamento ideal para desenvolver objetos conectados e, sobretudo, servidores web. Neste tutorial, veremos como criar e hospedar uma interface web para controlar o Raspberry Pi.

Pré-requisitos: Programar o Raspberry Pi, Conectar o Raspberry ao Wifi

Material

  • Computador
  • Raspberry Pi 3 B+ ou Zero (com Raspbian e conexão remota VNC)
  • Fonte de alimentação 5V 2A

Obs: Este tutorial foi escrito para um Raspberry Pi, mas pode ser aplicado a qualquer computador com o Python instalado e acesso ao WiFi.

Código

Para criar uma página web, é necessário um sistema de arquivos: um arquivo HTML combinado com um CSS para descrever a página (front-end) e um script Python para tratar os pedidos enviados do navegador para o servidor (back-end). É possível adicionar arquivos PHP e JavaScript para estruturar e dar funcionalidades à aplicação web.

Para organizar esses arquivos, iremos colocá-los em subpastas:

  • Na pasta principal (acwebapp), o script RaspWebInterface.py
  • Uma subpasta static, onde colocamos o script css
  • Uma subpasta templates para o script HTML

Código Python com Flask

Vamos criar um script Python utilizando o Flask para exibir a página rpi3b_webcontroller.html quando o navegador da web o solicitar. A biblioteca utilizada para gerar um aplicativo web de forma simples é o micro-framework Flask.

Funções para lembrar:

  • app=Flask(name) para instanciar o aplicativo Flask
  • @app.route(‘/’) decorador para gerir pedidos de URL
  • return render_template(‘rpi3b_webcontroller.html’,**templateData) para enviar a página web para o navegador
  • return ” OK 200 ” para confirmar a recepção de um pedido
  • app.run(debug=True, port=5000, host=’0.0.0.0′,threaded=True) para executar o aplicativo no IP local com a entrada 5000
import os
import RPi.GPIO as GPIO
from flask import Flask, render_template, Response
import datetime

GPIO.setmode(GPIO.BCM)
dataPin=[i for i in range(2,28)]
for dp in dataPin: GPIO.setup(dp,GPIO.IN)#,pull_up_down=GPIO.PUD_UP)

data=[]
now=datetime.datetime.now()
timeString=now.strftime("%Y-%m-%d %H:%M")
templateData={
	'title':'Raspberry Pi 3B+ Web Controller',
	'time':timeString,
	'data':data,
}

def getData():
	data=[]
	for i,dp in enumerate(dataPin): data.append(GPIO.input(dataPin[i]))
	
	return data

app=Flask(__name__)
	
@app.route('/')
def index():
	#return 'hello world!'
	now=datetime.datetime.now()
	timeString=now.strftime("%Y-%m-%d %H:%M")
	data=getData()
	templateData={
		'title':'Raspberry Pi 3B+ Web Controller',
		'time':timeString,
		'data':data,
	}
	#return render_template('rpi_index.html',**templateData)
	return render_template('rpi3b_webcontroller.html',**templateData)           

@app.route('/<actionid>') 
def handleRequest(actionid):
	print("Button pressed : {}".format(actionid))
	return "OK 200"   
	                      	
if __name__=='__main__':
	os.system("sudo rm -r  ~/.cache/chromium/Default/Cache/*")
	app.run(debug=True, port=5000, host='0.0.0.0',threaded=True)
	#local web server http://192.168.1.200:5000/
	#after Port forwarding Manipulation http://xx.xx.xx.xx:5000/

Código HTML da página

O arquivo .html contém a descrição da página web e também o código JavaScript, que permite gerir os botões.

<!DOCTYPE HTML>
	<html>
		<head>
			<title> AranaCorp </title>

			<meta http-equiv='content-type' content='text/html; charset=UTF-8'>
			<meta name='apple-mobile-web-app-capable' content='yes' />
			<meta name='apple-mobile-web-app-status-bar-style' content='black-translucent' />
			<meta http-equiv='refresh' content='10'>

			<link rel="stylesheet" href='../static/rpi_style.css'/>
			<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
		</head>
		
		<body bgcolor = '#70706F'> 
			<hr/><hr>
			<h1 style='color : #3AAA35;'><center> AranaCorp - {{title}} </center></h1>
			<hr/><hr>
			<br><br>
			<h2><center><p>Date and time :  {{time}}</p></center></h2>
			<br><br><h2> Digital Inputs/Ouputs </h2>
			<div id='btnContainer'>
				  <center>
				  Pin GPIO2
				  <input value={{data[0]}} readonly></input>
				  <button id='dig2on'>Turn On </button></a>
				  <button id='dig2off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO3
				  <input value={{data[1]}} readonly></input>
				  <button id='dig3on'>Turn On </button></a>
				  <button id='dig3off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO4
				  <input value={{data[2]}} readonly></input>
				  <button id='dig4on'>Turn On </button></a>
				  <button id='dig4off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO5
				  <input value={{data[3]}} readonly></input>
				  <button id='dig5on'>Turn On </button></a>
				  <button id='dig5off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO6
				  <input value={{data[4]}} readonly></input>
				  <button id='dig6on'>Turn On </button></a>
				  <button id='dig6off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO7
				  <input value={{data[5]}} readonly></input>
				  <button id='dig7on'>Turn On </button></a>
				  <button id='dig7off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO8
				  <input value={{data[6]}} readonly></input>
				  <button id='dig8on'>Turn On </button></a>
				  <button id='dig8off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO9
				  <input value={{data[7]}} readonly></input>
				  <button id='dig9on'>Turn On </button></a>
				  <button id='dig9off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO10
				  <input value={{data[8]}} readonly></input>
				  <button id='dig10on'>Turn On </button></a>
				  <button id='dig10off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO11
				  <input value={{data[9]}} readonly></input>
				  <button id='dig11on'>Turn On </button></a>
				  <button id='dig11off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO12
				  <input value={{data[10]}} readonly></input>
				  <button id='dig12on'>Turn On </button></a>
				  <button id='dig12off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO13
				  <input value={{data[11]}} readonly></input>
				  <button id='dig13on'>Turn On </button></a>
				  <button id='dig13off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO14
				  <input value={{data[12]}} readonly></input>
				  <button id='dig14on'>Turn On </button></a>
				  <button id='dig14off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO15
				  <input value={{data[13]}} readonly></input>
				  <button id='dig15on'>Turn On </button></a>
				  <button id='dig15off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO16
				  <input value={{data[14]}} readonly></input>
				  <button id='dig16on'>Turn On </button></a>
				  <button id='dig16off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO17
				  <input value={{data[15]}} readonly></input>
				  <button id='dig17on'>Turn On </button></a>
				  <button id='dig17off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO18
				  <input value={{data[16]}} readonly></input>
				  <button id='dig18on'>Turn On </button></a>
				  <button id='dig18off'>Turn Off </button></a><br /> 
				  </center><center>
				  Pin GPIO19
				  <input value={{data[17]}} readonly></input>
				  <button id='dig19on'>Turn On </button></a>
				  <button id='dig19off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO20
				  <input value={{data[18]}} readonly></input>
				  <button id='dig20on'>Turn On </button></a>
				  <button id='dig20off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO21
				  <input value={{data[19]}} readonly></input>
				  <button id='dig21on'>Turn On </button></a>
				  <button id='dig21off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO22
				  <input value={{data[20]}} readonly></input>
				  <button id='dig22on'>Turn On </button></a>
				  <button id='dig22off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO23
				  <input value={{data[21]}} readonly></input>
				  <button id='dig23on'>Turn On </button></a>
				  <button id='dig23off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO24
				  <input value={{data[22]}} readonly></input>
				  <button id='dig24on'>Turn On </button></a>
				  <button id='dig24off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO25
				  <input value={{data[23]}} readonly></input>
				  <button id='dig25on'>Turn On </button></a>
				  <button id='dig25off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO26
				  <input value={{data[24]}} readonly></input>
				  <button id='dig26on'>Turn On </button></a>
				  <button id='dig26off'>Turn Off </button></a><br /> 
				  </center>
				  <center>
				  Pin GPIO27
				  <input value={{data[25]}} readonly></input>
				  <button id='dig27on'>Turn On </button></a>
				  <button id='dig27off'>Turn Off </button></a><br /> 
				  </center>
			 </div>

			 <script>
				// Event Listener
				var buttonClick = document.getElementById('btnContainer').addEventListener('click', function(event) {
				  if (event.target.nodeName == "BUTTON") {
					var tar = event.target.id;
					console.log(tar);
					$.getJSON('/'+tar,
						function(data) {
					  //do nothing
					});

					return false;
				  }
				});
			</script>
	</body>
</html>

Foco no código JavaScript

O código JavaScript permite gerir o acionamento dos botões da interface. Para esse fim, criaremos um listener de eventos “click” no elemento “btnContainer”, que irá detectar se um botão (Button) é clicado e devolver o seu identificador através de um pedido json.

// Event Listener

		var buttonClick = document.getElementById('btnContainer').addEventListener('click', function(event) {

		  if (event.target.nodeName == "BUTTON") {

			var tar = event.target.id;

			console.log(tar);

			$.getJSON('/'+tar,

                function(data) {

              //do nothing

            });

            return false;

		  }

		});

Arquivo rpi_style.css

O arquivo css contém o estilo da página, em particular os botões, para conferir a ela um visual personalizado.

body{
background-color:#70706F;
}

h1{
	color:#3AAA35;
}

h3{
	#width:100%;
	border: 3px solid #3AAA35;
	border-radius: 6px;
	overflow: hidden; 
	text-align:center;
	padding:20px;
}


button{
  width:auto;
  height:60px;
  background-color: #3aaa35;/* Green */
  border: none;
  color: white;
  /*padding: 15px 32px;*/
  text-align: center;
  vertical-align:middle;
  text-decoration: none;
  display: inline-block;
  font-size: 20px;
  border-radius: 12px;
  -webkit-transition-duration: 0.4s; /* Safari */
  transition-duration: 0.4s;
  margin: 5px;
}
button:hover{
  background-color: #4CAF50; /* Green */
  color: white;
}

Obter o endereço IP do Raspberry Pi

Para acessar a interface web hospedada no Raspberry Pi, é preciso conhecer o endereço IP para poder conectar-se à rede local a partir de um navegador web. Para isso, basta introduzir a linha de comando ifconfig no terminal do Raspberry Pi.

Obs: É possível acessar o Raspberry Pi por fora da rede local realizando um procedimento no roteador no qual o Raspberry Pi está conectado. Este procedimento chama-se “Port Forwarding”.

Resultado

Depois de executar o script Python no Raspberry Pi, pode introduzir o endereço IP do seu Raspberry Pi seguido da porta (aqui 192.168.1.200:5000) no seu computador ou smartphone. A página web deverá então aparecer.

Então já pode ver o que acontece quando os botões do terminal são apertados por meio do aplicativo VNC.

Aplicações

  • Criar um sistema de domótica controlável via Wifi
  • Controlar o seu Raspberry Pi de qualquer lugar

Fontes

Retrouvez nos tutoriels et d’autres exemples dans notre générateur automatique de code
La Programmerie

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?