Servidor Raspberry – Comunicação com ESPs
Neste artigo iremos finalizar o servidor para Home Automation desenvolvido com o nosso Raspberry Pi. Para acompanhar este artigo irá necessita dos seguintes componentes:
Imagem | Produto | Comprar |
---|---|---|
NodeMcu Esp8266 |
||
Relé 5v 1 Canal |
||
Cabos Jumper Femêa-Femêa |
||
Kit Raspberry Pi 4 |
Atenção
Relembramos que as quantidades a adquirir devem coincidir com a quantidade de elementos que pretende controlar através do seu servidor.
Sobre o Projeto
Relembramos que este artigo é uma continuação dos artigos anteriores, aconselhamos fortemente a que consulte os posts anteriores para estar atualizado.
- Como Hospedar um Servidor Local com Raspberry Pi e Flask
- Página de Noticias Atualizada
- Servidor Raspberry Pi com Flask – Final da Estrutra
Neste artigo iremos elaborar a comunicação entre o nosso servidor e Esp/Nodemcu.
Código – Lado Servidor
Iremos começar por efetuar algumas alterações ao código anterior
routes.py
from flask import render_template, url_for, request from servidor import app from servidor.getNoticias import getNoticias from servidor.sendRequest import sendRequest from servidor.getCuriosidade import getCuriosidade from servidor.getTempo import getMetereologia from servidor.config import userData userData() @app.route("/") def homepage(): username = userData.user dadosTempo = getMetereologia() randomFact = getCuriosidade() return render_template("home.html", username = username, dadosTempo = dadosTempo, randomFact = randomFact) @app.route("/noticias") def noticias(): noticias = getNoticias() return render_template("noticias.html", noticias = noticias) @app.route("/sensores") def sensores(): return render_template("sensores.html") #Interpretar Requests #Quarto #Quarto Luz Principal #Ligar @app.route("/ligar_Luz", methods=['POST']) def ligar_LuzQuarto (): if request.method == "POST": requestType = "a" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") #Desligar @app.route("/desligar_Luz", methods=['POST']) def desligar_LuzQuarto (): if request.method == "POST": requestType = "b" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") #Quarto Luz Candeeiro #Ligar @app.route("/ligar_LuzCandeeiro", methods=['POST']) def ligar_LuzCandeeiro(): if request.method == "POST": requestType = "c" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") #Desligar @app.route("/desligar_LuzCandeeiro", methods=['POST']) def desligar_LuzCandeeiro(): if request.method == "POST": requestType = "d" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") #Sala #Luz Sala de Estar #Ligar @app.route("/ligar_LuzSaladeEstar", methods=['POST']) def ligar_LuzSaladeEstar(): if request.method == "POST": requestType = "e" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") #Desligar @app.route("/desligar_LuzSaladeEstar", methods=['POST']) def desligar_LuzSaladeEstar(): if request.method == "POST": requestType = "f" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") #Luz Sala de Jantar #Ligar @app.route("/ligar_LuzSaladeJantar", methods=['POST']) def ligar_LuzSaladeJantar(): if request.method == "POST": requestType = "g" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") @app.route("/desligar_LuzSaladeJantar", methods=['POST']) def desligar_LuzSaladeJantar(): if request.method == "POST": requestType = "h" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") @app.route("/ligar_FichaCarregamento", methods=['POST']) def ligar_FichaCarregamento(): if request.method == "POST": requestType = "i" target = "IP" sendRequest(target, requestType) return render_template("sensores.html") @app.route("/desligar_FichadeCarregamento", methods=['POST']) def desligar_FichadeCarregamento(): if request.method == "POST": requestType = "j" target = "IP" sendRequest(target, requestType) return render_template("sensores.html")
sensores.html
{% extends "base.html" %} {% block title %} Sensores Locais {% endblock %} {% block sensoresActive %} active {% endblock %} {% block content %} <div style ="padding-top:2%;color:#e7b851; padding-left:5%;"> <h3>Quarto Principal</h3> </div> <div class="row" style ="padding-top:2%; padding-left:5%; padding-right:5%;"> <div class="col-sm-3"> <div class="card border-0"> <div class="card-body"> <form class="text-center" method = "post"> <h5 class="card-title">Luz Principal</h5> <input type = "submit" class="btn btn-secondary" value = "Ligar" formaction="/ligar_Luz"> <input type = "submit" class="btn btn-secondary" value = "Desligar" formaction="/desligar_Luz"> </form> </div> </div> </div> <div class="col-sm-3"> <div class="card border-0"> <div class="card-body"> <form class="text-center" method = "post"> <h5 class="card-title">Luz Candeeiro</h5> <input type = "submit" class="btn btn-secondary" value = "Ligar" formaction="/ligar_LuzCandeeiro"> <input type = "submit" class="btn btn-secondary" value = "Desligar" formaction="/desligar_LuzCandeeiro"> </form> </div> </div> </div> </div> <div style ="padding-top:2%;color:#e7b851; padding-left:5%;"> <h3>Sala</h3> </div> <div class="row" style ="padding-top:2%; padding-left:5%; padding-right:5%;"> <div class="col-sm-3"> <div class="card border-0"> <div class="card-body"> <form class="text-center" method = "post"> <h5 class="card-title">Luz Sala de Estar</h5> <input type = "submit" class="btn btn-secondary" value = "Ligar" formaction="/ligar_LuzSaladeEstar"> <input type = "submit" class="btn btn-secondary" value = "Desligar" formaction="/desligar_LuzSaladeEstar"> </form> </div> </div> </div> <div class="col-sm-3"> <div class="card border-0"> <div class="card-body"> <form class="text-center" method = "post"> <h5 class="card-title">Luz Sala de Jantar</h5> <input type = "submit" class="btn btn-secondary " value = "Ligar" formaction="/ligar_LuzSaladeJantar"> <input type = "submit" class="btn btn-secondary" value = "Desligar" formaction="/desligar_LuzSaladeJantar"> </form> </div> </div> </div> <div class="col-sm-3"> <div class="card border-0"> <div class="card-body"> <form class="text-center" method = "post"> <h5 class="card-title">Ficha Sala</h5> <input type = "submit" class="btn btn-secondary" value = "Ligar" formaction="/ligar_FichaCarregamento"> <input type = "submit" class="btn btn-secondary" value = "Desligar" formaction="/desligar_FichadeCarregamento"> </form> </div> </div> </div> </div> <style> .card-body{ background-color: #343a40; color:rgb(236, 236, 236); } .btn-secondary:hover{ background-color:#c0a469!important; } </style> {% endblock %}
sendRequest.py
import socket from time import sleep def sendRequest(target, requestType): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((target, 80)) s.sendall(requestType.encode('UTF-8')) sleep(1)
Explicação Código Servidor
Na pagina sensores é criado um formulário com método POST:
<form class="text-center" method = "post"> <h5 class="card-title">Luz Principal</h5> <input type = "submit" class="btn btn-secondary" value = "Ligar" formaction="/ligar_Luz"> <input type = "submit" class="btn btn-secondary" value = "Desligar" formaction="/desligar_Luz"> </form>
Sempre que o botão é pressionado é enviado um POST-Request formaction=”/XXXX” que dependendo do conteúdo enviará um socket para o nosso controlador especificado pelo IP correspondente acionando o script sendRequest.py
if request.method == “POST”:
requestType = “a”
target = “IP_CONTROLADOR”
sendRequest(target, requestType)
return render_template(“sensores.html”)
No sendRequest.py é responsavel por efetivamente efetuar a comunicação com o seu controlador – requestType é uma variável usada como flag para ser interpretada pelo controlador, desta forma deve ser única e não deve ser repetida. A variável target deve ser substituido pelo IP do seu controlador.
Relembramos que todo este código pode ser copiado as vezes que pretender para acrescentar mais sensores ou controladores.
Código Lado Cliente
Este é o código que deve ser inserido no seu controlador. Iremos partilhar apenas o fundamental para que a comunicação e o controlo de um relé seja possível.
#include <ESP8266WiFi.h> //Outputs #define luz_principal_quarto 2 const char* ssid = "SSID"; const char* password = "PASSWORD"; WiFiServer wifiServer(80); void setup() { pinMode(luz_principal_quarto, OUTPUT); Serial.begin(115200); delay(1000); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting.."); } Serial.print("Connected to WiFi. IP:"); Serial.println(WiFi.localIP()); wifiServer.begin(); } void loop() { WiFiClient client = wifiServer.available(); if (client) { while (client.connected()) { while (client.available() > 0) { char c = client.read(); processReceivedValue(c); Serial.write(c); } delay(10); } client.stop(); Serial.println("Client disconnected"); } } //Descodifica array para string void processReceivedValue(char command) { if (command == 'a') { digitalWrite(luz_principal_quarto, HIGH); Serial.write("Ligado"); } else if (command == 'b') { digitalWrite(luz_principal_quarto, LOW); Serial.write("Desligado"); } return; }
Como funciona
Inicialmente deverá substituir SSID e PASSWORD pelos dados correspondentes a sua rede.
Assim que carregar o código, deverá aceder a consola de serial para obter o endereço de ip do seu controlador para ser substituído no target no routes.py
@app.route("/ligar_Luz", methods=['POST']) def ligar_LuzQuarto (): if request.method == "POST": requestType = "a" target = "IP" sendRequest(target, requestType) return render_template("sensores.html")
Finalmente temos que interpretar o socket enviado pelo servidor
void processReceivedValue(char command) { if (command == 'a') { digitalWrite(luz_principal_quarto, HIGH); Serial.write("Ligado"); } else if (command == 'b') { digitalWrite(luz_principal_quarto, LOW); Serial.write("Desligado"); } return; }
Caso pretenda adicionar mais deverá adicionar mais condições para interpretar os socket recebidos e variáveis para controlar o respetivo GPIO.
Esquema de Montagem – Sugerido
Para mais projetos, percorram o nosso blog, onde podem encontrar vários artigos interessantes relacionados com eletrónica, robótica e muito mais! Visitem também o nosso site, onde encontram tudo para eletrónica e robótica!