ÍNDICE DE CONTEÚDO
- Localização aproximada via IP com ESP8266 – Parte 1
- Localização aproximada via IP com ESP8266 – Parte 2
Introdução
Essa é a parte 2 da série “Localização Aproximada via IP com ESP8266”. Na parte 1 foi desenvolvido um Web Client com ESP8266 onde o mesmo é capaz de fazer requisições HTTP GET e POST, recebendo sua localização aproximada e posteriormente enviando esses dados a um Web Server.
Na parte 2 desta série será desenvolvido um Web Server escrito em Node.js, sendo executado em uma Raspberry Pi, que recebe a localização aproximada do ESP8266 e exibe, para os clientes que se conectam ao servidor via navegador, um marcador em uma página do Google Maps. Faremos uso do Express, Socket.io, HTML, Javascript e Google Maps API.
Pré Requisitos
Para a reprodução deste artigo, é necessário ter:
- Experimentado com os passos da parte 1 desta série;
- Uma Raspberry Pi com conexão à internet;
- Raspbian com Node.js instalado;
- Noções do protocolo HTTP e seus métodos de requisição GET e POST;
- Noções de JSON;
- Noções de Node.js, Express, Socket.io, HTML, Javascript, Google Maps API.
O que são Express, Socket.io e Google Maps API?
Para desenvolver um pequeno servidor em Node.js que precisa lidar com requisições HTTP pode-se usar o Express. Siga os passos para instalação no sistema encontrados aqui.
Como exemplo de um pequeno servidor que responde a uma requisição GET temos o seguinte:
1 2 3 4 5 6 7 8 9 10 |
var express = require('express') var app = express() app.get('/', function (req, res) { res.send('Hello World!') }) app.server.listen(3000, '192.168.0.24', function() { console.log('Example app listening on port 3000!') }) |
Se acessarmos em um navegador o endereço https://192.168.0.24:3000/, ou seja, fazemos um requisição GET, veremos no navegador a mensagem “Hello World!”. Se tentarmos acessar qualquer outro link (diretório) nesta página, como https://192.168.0.24:3000/algumaCoisa, o servidor retorna a mensagem “404 Not Found”.
O servidor desenvolvido neste artigo consegue lidar com requisições HTTP GET e POST da seguinte maneira:
Quando recebemos uma requisição GET, retornamos ao cliente uma página web (arquivo index.html).
1 2 3 |
app.get('/', function (req, res) { res.sendFile(__dirname + '/index.html'); }); |
Quando recebemos requisição POST no link “/location”, armazenamos o body (corpo) da mensagem, em formato JSON, na variável ‘locationData’ e enviamos essa variável aos clientes conectados.
1 2 3 4 |
app.post('/location', function(req, res) { locationData = req.body io.emit('locationEvent', locationData); }); |
Lembrando que quem faz requisição GET é o navegador e POST é o ESP8266 com o JSON contendo sua geolocalização.
Com o Socket.io (siga os passos para instalação aqui) podemos fazer troca de informações em tempo real entre servidor e cliente. No caso, o servidor envia os dados de geolocalização para os clientes que acessam a página via navegador.
1 |
io.emit('locationEvent', locationData); |
A linha acima emite um evento chamado locationEvent com os dados da variável locationData. O cliente, por sua vez, escuta pelo evento chamado locationEvent, e salva em variáveis cada objeto JSON quando o evento é acionado.
1 2 3 4 5 6 7 8 |
socket.on('locationEvent', function(locationData) { city = locationData.city country = locationData.country lat = location.lat lon = location.lon query = location.query region = location.region }); |
Agora podemos usar essas variáveis com a API do Google Maps.
Para exibirmos um mapa em uma página HTML devemos ter basicamente o seguinte componente:
1 |
<div id="map"></div> |
O importante é o id do elemento, pois ele será usado ao inicializarmos o mapa.
Então “desenhamos” o mapa, inicialmente com coordenadas quais queres, usando o seguinte código:
1 2 3 4 5 6 7 8 9 |
var map; function myMap() { var mapCanvas = document.getElementById("map"); var mapOptions = { center: new google.maps.LatLng(51.5, -0.2), zoom: 11 } map = new google.maps.Map(mapCanvas, mapOptions); } |
Quando o locationEvent é acionado, redirecionamos o mapa para as novas coordenadas e colocamos um marcador no mapa:
1 2 3 4 5 6 7 |
map.setCenter(new google.maps.LatLng(lat, lon)) var marker = new google.maps.Marker({ position: {lat: lat, lng: lon}, map: map, title: 'Hello World!' }); |
Será adicionado um marcador na localização aproximada do ESP8266, no caso ele está em Artur Nogueira, interior de São Paulo:
Abaixo segue um vídeo mostrando o sistema em ação:
Código Completo do Servidor
O código a seguir, escrito em Node.js, pode ser testado em uma Raspberry Pi conectada à internet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var server = require('http').Server(app); var io = require('socket.io')(server); var path = require('path'); app.use(bodyParser.json()) app.use(express.static(path.join(__dirname, '/public'))); var locationData; server.listen(3000, '192.168.0.24', function() { var host = server.address().address var port = server.address().port console.log("Server listening on %s:%s...", host, port); }); app.get('/', function (req, res) { res.sendFile(__dirname + '/index.html'); }); app.post('/location', function(req, res) { locationData = req.body io.emit('locationEvent', locationData); }); |
Código Completo do index.html
O código a seguir, contendo alguns scripts em javascript, é a página que o servidor envia aos clientes que se conectam via navegador:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP Location Server</title> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/css/materialize.min.css"> </head> <body> <div class="grey lighten-5"> <div class="col s12 amber darken-3" style="height:5px;"></div> <nav class="light-blue lighten-1" role="navigation"> <div class="nav-wrapper container"><a id="logo-container" href="https://embarcados.com.br" target="_blank" class="brand-logo"><img class="responsive-img" style="max-width: 50%" src="https://embarcados.com.br/wp-content/uploads/2016/04/logo-380x124.png"></a> <ul class="right hide-on-med-and-down"> <li><a href="https://github.com/giobauermeister" target="_blank">Code on GitHub</a></li> </ul> <ul class="right hide-on-med-and-down"> <li><a href="#link_para_artigo" target="_blank">Read the Article</a></li> </ul> <ul id="nav-mobile" class="side-nav"> <li><a href="#">Navbar Link</a></li> </ul> <a href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a> </div> </nav> <div class="section no-pad-bot" id="index-banner"> <div class="container"> <h3 class="header center orange-text">Localização Aproximada via IP com ESP8266</h3> <div class="row center"> <div class="col s12 grey lighten-3" id="map" style="height:450px;">Google Maps Div</div> </div> </div> </div> <div class="grey lighten-5" style="width:100%;height:40px;"></div> </div> <script src="/socket.io/socket.io.js"></script> <script> var map; function myMap() { var mapCanvas = document.getElementById("map"); var mapOptions = { center: new google.maps.LatLng(51.5, -0.2), zoom: 12 } map = new google.maps.Map(mapCanvas, mapOptions); } var socket = io.connect(); socket.on('locationEvent', function(locationData) { city = locationData.city country = locationData.country lat = locationData.lat lon = locationData.lon query = locationData.query region = locationData.region var markerInfoText = (city + ", " + region + " - " + country + "<br>" + "lat: " + lat + " lon: " + lon + "<br>" + "IP: " + query) var infowindow = new google.maps.InfoWindow({ content: markerInfoText }); map.setCenter(new google.maps.LatLng(lat, lon)) map.setZoom(14) var marker = new google.maps.Marker({ position: {lat: lat, lng: lon}, map: map, title: 'Hello World!' }); marker.addListener('click', function() { infowindow.open(map, marker); }); }); </script> <script src="https://code.jquery.com/jquery-2.1.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.8/js/materialize.min.js"></script> <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCXA-c5NqxpQ6mYBQRZIrOViL6M0Qg_i24&callback=myMap"></script> </body> </html> |
Conclusão
Neste artigo foi desenvolvido um Web Server usando Node.js, Express, Socket.io e Google Maps API mostrando em uma página web a localização aproximada de um ESP8266 conectado à internet. Esse tipo de aplicação mostra que é possível usar poucos recursos de hardware como um ESP8266, sem a necessidade de módulos GSM ou GPS, para fazer um sistema de monitoramento remoto.
O ESP8266 poderia ser incorporado a um Arduino, como visto no artigo Estação Meteorológica com Arduino, fazendo leitura de sensores e possibilitando o monitoramento remoto desses sensores.
Chegamos ao final dessa série de 2 artigos! Espero que tenham gostado e qualquer dúvida entre em contato da forma que desejar.
Referências