Localização aproximada via IP com ESP8266 – Parte 2

Localização aproximada com ESP8266
Este post faz parte da série Localização aproximada via IP com ESP8266

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:

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:

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).

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.

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.

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.

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:

<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:

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);
}
Localização aproximada via IP com ESP8266 - Página Web com o mapa em uma localização qualquer.
Figura 1 – Página Web com o mapa em uma localização qualquer.

Quando o locationEvent é acionado, redirecionamos o mapa para as novas coordenadas e colocamos um marcador no mapa:

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:

Localização aproximada via IP com ESP8266 - Página Web com um marcador na localização aproximada do ESP8266.
Figura 2 – Página Web com um marcador na localização aproximada do ESP8266.

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:

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:

<!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

https://expressjs.com/en/starter/installing.html
https://developers.google.com/maps/documentation/javascript/
https://socket.io/get-started/chat/
https://ip-api.com/docs/api:json
https://www.w3schools.com/tags/ref_httpmethods.asp
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
https://www.json.org/

Localização aproximada via IP com ESP8266

Localização aproximada via IP com ESP8266 – Parte 1
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
0 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Home » Internet Das Coisas » Localização aproximada via IP com ESP8266 – Parte 2

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: