Uma forma de exibir informações de equipamentos eletrônicos com Internet das Coisas (IoT) são as páginas da web. daí a importância de saber como implementar IoT em páginas web. Neste artigo mostraremos como utilizar o protocolo MQTT para internet das coisas (IoT), em páginas web com a linguagem javascript.
MQTT (Message Queuing Telemetry Transport) é um protocolo de mensagens usado para a Internet das Coisas (IoT). Este protocolo é baseado em dados transmitidos usando o protocolo de internet. Os dados (mensagens) transmitidos pelo protocolo MQTT possuem 2 partes: uma: o “tópico” e a outra: o “valor”. A figura a seguir mostra como um sensor de temperatura envia dados para o tópico: “temperatura”:
Os dados ou mensagens são recebidos por um programa chamado: "MQTT Broker" instalado em um servidor, que é responsável por recebê-los e transmiti-los para quem deseja ler a mensagem. Para isso, o protocolo MQTT trata do conceito de: publicador/assinante. Assim, o “editor” é quem envia a mensagem para a corretora e o “assinante” é quem lê as mensagens da corretora conforme a imagem a seguir:
É importante observar que tanto o publicador quanto o assinante devem estar usando o mesmo tópico para que a mensagem chegue aos assinantes. No exemplo acima foi utilizado o tópico: “Temperatura”. Observe que os tópicos diferenciam maiúsculas de minúsculas, ou seja, o corretor diferencia maiúsculas de minúsculas. Por exemplo: o tópico "Temperatura" é diferente do tópico: "temperatura". Além disso, é possível agrupá-los, de forma semelhante à forma como os arquivos são tratados em um computador. Veja os exemplos de tópicos a seguir:
casa/cozinha/temperatura
casa/jardim/umidade
máquina/sensor/proximidade
Como o MQTT utiliza o protocolo TCP/IP como base para transmitir e receber mensagens, a implementação é relativamente simples, nas aplicações que vão utilizá-los, pois o transporte e direcionamento das mensagens são feitos pelo protocolo de internet: "TCP / PI”. Observe a seguinte imagem:
A imagem a seguir mostra esquematicamente uma mensagem MQTT, onde podemos ver o cabeçalho do protocolo IP e os dados da mensagem MQTT:
Para desenvolver a página web, nesta seção, usaremos a linguagem: "JavaScript".
JavaScript é uma linguagem interpretada e usa “script”; lá, você pode escrever o código. As páginas da Web que utilizam JavaScript são compostas basicamente por um documento: "html" e um script, conforme a figura a seguir:
O arquivo "html" é direcionado para a apresentação da página web e o script é direcionado para o comportamento. O arquivo ou documento “html” é composto de tags e elementos. Os rótulos sempre vão entre os caracteres: “<>”. Existem tags de abertura e tags de fechamento. Observe a figura a seguir:
Nesta figura foi representado um elemento do tipo: "botão", que possui uma tag de abertura, um atributo, um conteúdo e uma tag de fechamento. A maioria dos elementos usados no documento "html" contém a tag de abertura e a tag de fechamento, mas alguns elementos precisam apenas da tag de abertura. Para começar a escrever em “html”, você pode usar qualquer editor de texto. Existem alguns editores como “visual studio code”, Notepad++, Sublime Text, etc, que são amplamente utilizados para editar a linguagem “html”. Para o exemplo a seguir, você pode usar uma pasta e um arquivo conforme mostrado abaixo:
A linguagem "html" mais básica para uma página da web é composta pelas seguintes tags:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>
As tags: “ ” compõem todo o documento “html”, que é formado por duas partes: o cabeçalho (cabeçalho) e o corpo (corpo). Diretivas para o navegador geralmente são colocadas no cabeçalho, como: onde encontrar um arquivo, que tipo de conjunto de caracteres usar, o título da página da web, etc.
O seguinte é o programa mais básico em "html":
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h3>Hello world.</h3>
</body>
</html>
Dentro da tag: <h3>, foi utilizado um elemento de título: “Hellow word"
Existe um elemento para parágrafos, chamado: “<p>”. O seguinte é um programa que usa o elemento para parágrafos:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>Hello world.</p>
</body>
</html>
A saída produzida pelo navegador, para o programa anterior, seria assim:
No programa “html” a seguir, um elemento de título e um elemento de parágrafo foram usados:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h3>Hello world.</h3>
<p>Welcome</p>
</body>
</html>
A saída produzida no navegador, para o programa anterior, seria assim:
Os scripts javascript podem ser executados no documento "html" da página web, mas o mais prático e recomendado é usar um arquivo separado para o script. Além disso, é recomendável criar uma pasta ou pasta para conter os scripts. No exemplo a seguir criamos uma pasta chamada: “js” para armazenar os scripts. Esse é o método que usaremos neste capítulo. Para fazer referência a um script do documento “html”, utiliza-se a tag: “
Para o exemplo a seguir, você pode usar pastas e arquivos conforme mostrado abaixo:
Com este elemento <script> você pode obter a biblioteca MQTT e começar a usá-la em seu script. A linguagem "html" para isso seria assim:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js">
</script>
<hr id="system-readmore"><p> </head>
<body>
<h3 id="state"></h3>
</body>
</html>
Script
var client = mqtt.connect("ws://test.mosquitto.org:8080/mqtt")
function EventoConectar(){
client.subscribe("x1x2x3x4/temp", function (err) {
if(!err){
client.publish("x1x2x3x4/temp", "30")
}
})
}
function EventoMensaje(topic, message){
if(topic == "x1x2x3x4/temp"){
document.getElementById("state").innerHTML = message
}
}
client.on("connect", EventoConectar)
client.on("message", EventoMensaje)
No script, a primeira coisa que se faz é criar uma variável: “client” do broker MQTT. Isso é feito com a linha:
var client = mqtt.connect(“ws://test.mosquitto.org:8080/mqtt)
Para os fins desta seção, usaremos o corretor: “mosquitto”, que é gratuito e pode ser usado para fins gerais e testes.
O script cria dois eventos: um evento para quando for feita a conexão com o broker, que é feito com a linha:
client.on(“connect”, EventoConectar)
O outro evento é para quando chega uma mensagem do broker; isso é feito com a linha:
client.on(“message”, EventoMensaje)
Uma vez conectado com o corretor, fazemos uma assinatura no tópico: “x1x2x3x4/temp”. Isso é feito com a linha:
client.subscribe(“x1x2x3x4/temp”, function (err) {
Se a assinatura for bem-sucedida, postaremos no tópico: “x1x2x3x4/temp”. Isso é feito com a linha:
cliente.publish("x1x2x3x4/temp", "30")
Quando o broker retornar a mensagem para o tópico: “x1x2x3x4/temp”, a função “MessageEvent(topic, message)” será chamada. Dentro desta função o tópico é avaliado como sendo o mesmo: “x1x2x3x4/temp” e se sim, então é exibido no navegador. Para isso criamos no documento "html" um elemento de título "h3" e foi dado a ele um atributo com um identificador (id) chamado: "estado". Isso foi feito com a linha:
<h3 id=”state”></h3>
Portanto, quando recebemos uma mensagem do corretor, podemos exibi-la neste elemento de título. Isso é feito com a linha:
document.getElementById(“state”).InnerHTML = message
Como fizemos uma publicação para o tópico: "x1x2x3x4/temp", com valor: "30", o navegador mostra esse valor na tela, conforme a imagem a seguir:
Quando uma aplicação é desenvolvida em JavaScript, é normal a utilização de uma ferramenta chamada: "console", onde podemos ver e observar como o programa está sendo executado. Para isso é necessário usar a função do console assim:
console.log("")
Dentro das patentes da função: “console.log()”, escrevemos o que queremos observar no console, quando esta função é executada. Para o exemplo a seguir, você pode criar pastas e arquivos da seguinte maneira:
Observe no código a seguir como esta função foi utilizada para acompanhar o funcionamento do programa:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js">
</script>
<hr id="system-readmore"><p> </head>
<body>
<h3 id="state"></h3>
</body>
</html>
Script
var client = mqtt.connect("ws://test.mosquitto.org:8080/mqtt")
function EventoConectar(){
console.log("connected.")
client.subscribe("x1x2x3x4/temp", function (err) {
console.log("subscribe to: x1x2x3x4/temp.")
if(!err){
client.publish("x1x2x3x4/temp", "30")
console.log("public to: x1x2x3x4/temp.")
}
})
}
function EventoMensaje(topic, message){
if(topic == "x1x2x3x4/temp"){
console.log("receive from the topic: " + topic + " the value: " + message)
document.getElementById("state").innerHTML = message
}
}
client.on("connect", EventoConectar)
client.on("message", EventoMensaje)
No navegador, pressione a tecla: "F12" e podemos ver no console, os respectivos "logs" que foram feitos no programa:
Em scripts, é comum o uso de variáveis para armazenar os dados do programa que está sendo executado. No script a seguir, criamos duas variáveis chamadas:
- This topic
- Value
Essas variáveis foram inicializadas com os seguintes valores:
thisTopic="x1x2x3x4/temp"
value ="17"
Para o exemplo a seguir, você pode usar pastas e arquivos conforme mostrado:
Observe no script a seguir, como as variáveis são utilizadas para executar o programa:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js">
</script>
<hr id="system-readmore"><p> </head>
<body>
<h3 id="state"></h3>
</body>
</html>
Script
var client = mqtt.connect("ws://test.mosquitto.org:8080/mqtt")
thisTopic = "x1x2x3x4/temp"
value = "17"
function EventoConectar(){
console.log("connected.")
client.subscribe(thisTopic, function (err) {
console.log("subscribe to: " + thisTopic)
if(!err){
client.publish(thisTopic, value)
console.log("public to: " + thisTopic)
}
})
}
function EventoMensaje(topic, message){
if(topic == thisTopic){
console.log("receive from the topic: " + topic +
" the value: " + message)
document.getElementById("state").innerHTML = message
}
}
client.on("connect", EventoConectar)
client.on("message", EventoMensaje)
A saída no navegador e no console é a mesma do programa anterior, conforme mostrado na imagem a seguir:
Como os navegadores são usados em todo o mundo, é comum ter muitos formatos de caracteres. No caso deste programa, é necessário utilizar o formato: "utf-8". Para isso utilizamos o elementocom um atributo chamado: “charset”. Esta linha é colocada no cabeçalho (cabeçalho) do documento:
Assim, o navegador não apresenta caracteres estranhos quando inserimos algum texto com til ou outros caracteres incomuns nas variáveis.
Outra técnica usada ao desenvolver programas é usar variáveis para nos informar o estado de um programa. Assim, por exemplo, quando um determinado bloco de código é executado, podemos aumentar um contador ou atribuir algum dado a uma variável e saber no navegador o que aconteceu. No caso deste programa, adicionamos as seguintes variáveis para ver o estado do programa:
let connected = “No”
let subs = 0
let pubs = 0
let topics_temp = 0
let topics_totals = 0
A variável: "connected", é usada para saber se o programa conseguiu se comunicar com a corretora. A variável: "subs" é um contador que é incrementado quando o programa faz uma assinatura na corretora. A variável: "pubs" é um contador que é incrementado quando o programa faz uma publicação para o broker. A variável: “topics_temp” é um contador que é incrementado quando o programa recebe uma mensagem do broker, com o tópico: “x1x2x3x4/temp”. A variável: “topics_totals” é um contador que é incrementado quando o programa recebe alguma mensagem do broker. Assim, podemos incrementar os contadores em seus devidos lugares onde cada finalidade tem efeito e chamar a função: "update()", que é responsável por formatar essas variáveis e exibi-las no elemento parágrafo com o identificador: "state" .
Para o exemplo a seguir, você pode criar pastas e arquivos da seguinte maneira:
O programa para fazer isso seria o seguinte:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js">
</script>
<hr id="system-readmore"><p> </head>
<body>
<p id="state"></p>
</body>
</html>
Script
var client = mqtt.connect("ws://test.mosquitto.org:8080/mqtt")
const thisTopic = "x1x2x3x4/temp"
const value = "17"
let connected = "No"
let subs = 0
let pubs = 0
let topics_temp = 0
let topics_totals = 0
function update(){
str = "State:: connected: " + connected +
" subs: " + subs + " pubs: " + pubs +
" topics_temp: " + topics_temp +
" topics_totals: " + topics_totals
document.getElementById("state").innerHTML = str
}
function EventoConectar(){
console.log("connected.")
connected = "Yes"
update()
client.subscribe(thisTopic, function (err) {
console.log("subscribe to: " + thisTopic)
subs += 1
update()
if(!err){
client.publish(thisTopic, value)
console.log("public to: " + thisTopic)
pubs += 1
update()
}
})
}
function EventoMensaje(topic, message){
topics_totals += 1
update()
if(topic == thisTopic){
console.log("receive from the topic: " + topic +
" the value: " + message)
topics_temp += 1
update()
}
}
client.on("connect", EventoConectar)
client.on("message", EventoMensaje)
O navegador agora nos mostra uma linha com informações sobre o estado do programa conforme a figura a seguir:
O próximo passo é adicionar dois botões ao documento "html" com seus respectivos eventos no script. Para isso vamos utilizar o elemento: “
Duas funções são criadas no script que são chamadas quando o botão é clicado. Cada botão tem sua respectiva função: “onclick”. O elemento
serve para o navegador gerar um espaço entre os botões. Este elemento não necessita de tag de fechamento, conforme o programa a seguir:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js">
</script>
<hr id="system-readmore"><p> </head>
<body>
<p id="state"></p>
<button onclick="subscription()">Subscription</button>
<br>
<br>
<button onclick="publication()">Publication</button>
</body>
</html>
Script
var client = mqtt.connect("ws://test.mosquitto.org:8080/mqtt")
const thisTopic = "x1x2x3x4/temp"
const value = "17"
let connected = "No"
let subs = 0
let pubs = 0
let topics_temp = 0
let topics_totals = 0
function subscription(){
}
function publication(){
}
function update(){
str = "State:: connected: " + connected +
" subs: " + subs + " pubs: " + pubs +
" topics_temp: " + topics_temp +
" topics_totals: " + topics_totals
document.getElementById("state").innerHTML = str
}
function EventoConectar(){
console.log("connected.")
connected = "Yes"
update()
client.subscribe(thisTopic, function (err) {
console.log("subscribe to: " + thisTopic)
subs += 1
update()
if(!err){
client.publish(thisTopic, value)
console.log("public to: " + thisTopic)
pubs += 1
update()
}
})
}
function EventoMensaje(topic, message){
topics_totals += 1
update()
if(topic == thisTopic){
console.log("receive from the topic: " + topic +
" the value: " + message)
topics_temp += 1
update()
}
}
client.on("connect", EventoConectar)
client.on("message", EventoMensaje)
A seguir está a saída do navegador para o programa acima. Observe que agora os contadores são aumentados quando os botões são pressionados e a respectiva ação é observada no console:
Vamos adicionar três caixas de texto para poder editar os tópicos e o valor a publicar. Para isso usamos o elemento: “<input>”, assim:
<input type=”text” value=”Type here the topic”>
O elemento <input> não possui uma tag de fechamento. O seguinte programa cria as caixas de texto:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js">
</script>
<hr id="system-readmore"> </head>
<body>
<p id="state"></p>
<input type="text" value="Type here the topic">
<button onclick="subscription()">Subscription</button>
<br>
<br>
<input type="text" value="Type here the topic">
<br>
<br>
<input type="text" value="Type here the value">
<button onclick="publication()">Publication</button>
</body>
</html>
O navegador mostra a página com os elementos: caixa de texto, assim:
Agora, cada caixa de texto recebe um identificador, para que possa ser utilizada no script. Também adicionamos dois elementos de título para separar a seção de assinatura e publicação, assim:
<h3> Subcription </h3>
<h3> Publicationtion </h3>
Acrescentamos um parágrafo, para ver o tema e seu valor, quando o corretor envia uma mensagem, assim:
<p id=””subscriptionReceive”> receive from the topic: </p>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/mqtt/4.3.7/mqtt.js">
</script>
<hr id="system-readmore"><p> </head>
<body>
<p id="state"></p>
<h3>Subscription:</h3>
<p>Topic:</p>
<input type="text" id="subscriptionTopicText" value="Type here the topic sub">
<button onclick="subscription()">Subscription</button>
<br>
<p id="subscriptionReceive">receive from the topic:</p>
<br>
<br>
<h3>Publication:</h3>
<p>Topic:</p>
<input type="text" id="publicationTopicText" value="Type here the topic pub">
<br>
<br>
<p>Message:</p>
<input type="text" id="publicationMessageText" value="Type here the message pub">
<button onclick="publication()">Publication</button>
</body>
</html>
O programa seria o seguinte:
var client = mqtt.connect("ws://test.mosquitto.org:8080/mqtt")
var subscriptionTopicTextElem
let connected = "No"
let subs = 0
let pubs = 0
let topics_temp = 0
let topics_totals = 0
function subscription(){
subscriptionTopicTextElem = document.getElementById("subscriptionTopicText")
client.subscribe(subscriptionTopicTextElem.value, function (err) {
console.log("subscribe to: " + subscriptionTopicTextElem.value)
subs += 1
update()
})
}
function publication(){
var publicationTopicTextElem = document.getElementById("publicationTopicText")
var publicationMessageTextElem = document.getElementById("publicationMessageText")
client.publish(publicationTopicTextElem.value, publicationMessageTextElem.value)
console.log("public to: " + publicationTopicTextElem.value)
pubs += 1
update()
}
function update(){
str = "State:: connected: " + connected +
" subs: " + subs + " pubs: " + pubs +
" topics_temp: " + topics_temp +
" topics_totals: " + topics_totals
document.getElementById("state").innerHTML = str
}
function EventoConectar(){
console.log("connected.")
connected = "Yes"
update()
}
function EventoMensaje(topic, message){
topics_totals += 1
update()
if(topic == subscriptionTopicTextElem.value){
resultStr = "receive from the topic:: " + "'" + topic + "'" +
" the message:: " + "'" + message+ "'"
console.log(resultStr)
document.getElementById("subscriptionReceive").innerHTML = resultStr
topics_temp += 1
update()
}
}
client.on("connect", EventoConectar)
client.on("message", EventoMensaje)
O navegador exibe os elementos como este:
Você pode tentar se inscrever e postar no tópico que deseja. Lembre-se de que, para receber qualquer mensagem, o assunto deve ser o mesmo. Se por acaso você receber mensagens com valores diferentes, é porque outra pessoa está postando em um tópico semelhante.
Como podemos ver, incluir mensagens MQTT em uma página da web é relativamente simples. Você pode fazer muitos testes e observar a operação. Leve em consideração que o MQTT utiliza filas ou linhas (Queues) em seu protocolo, portanto, as mensagens sempre chegam. Bons projetos com MQTT.