EXEMPLO DE INSTALAÇÃO MQTT BROKER

*VISUALIZE ESTA DOCUMENTAÇÃO NO FORMATO CLICK-AND-SWIPE DOCS GALLERY

**NO PARÂMETRO CLIENT-ID, COLOCAR UM VALOR DE PRÓPRIA ESCOLHA COM NO MÍNIMO 10 CARACTERES

 

Introdução

,

A fim de habilitar uma rápida inicialização (quick start) para a visualização de um dado sendo transmitido de um sensor, sendo gerenciado pelo Network Server, foi desenvolvido um código para uma aplicação padrão implementada em Node-RED.

 

Para o exemplo demonstrado a seguir é primordial que se tenha seguido os passos de como executar a instalação do Node-RED segundo  os passos descritos anteriormente.. De acordo com o repositório de projetos no GitHub, e desde que se tenha acesso a uma plataforma Node-RED, bastam os passos a seguir para utilizar-se do exemplo de aplicação.

 

 

 

Dicionário de seção

  • Background: Aplicação executada por um código fonte não visível no dashboard. Corresponde à programação em blocos da interface web.
  • Client-ID: Identificação de um usuário do sistema. Nesta documentação não será utilizado.
  • Clipboard: Área de transferência. Importar para o Clipboard Ctrl+C. Exportar do Clipboard (Ctrl+V).
  • Dashboard: Painel de instrumentos gerados a partir dos blocos cujo index refere-se a este no menu de blocos.
  • Deploy: Compilação do projeto Node-RED. Botão localizado no canto superior direito da interface web.
  • Done: Botão de finalização das janelas de edição de cada bloco a ser programado.
  • End-nodes: Dispositivos de aplicação embarcados com sensor, microcontrolador e transmissor rádio frequência padrão LoRa
  • Flow: Estrutura de blocos de programação Node-RED que se interligam para prover um caminho à informação.
  • Gauge: Mostrador de valores no dashboard.
  • GitHub: Site para se disponibilizar projetos à comunidade por meio de repositórios.
  • Groups: Blocos que podem conter outros diversos blocos em um dashboard.
  • Interface web Node-RED: Interface de programação onde serão alocados os blocos de programação.
  • json: Sigla para JavaScript Object Notation. Estrutura de objetos para envio de informações indexadas.
  • Manage Palette: ´Gerenciamento de plugins disponíveis e instalados no Node-RED.
  • Menu de blocos: Localizado ao lado esquerdo da interface web contendo os blocos possíveis e disponíveis para a programação Node-RED.
  • Menu principal: Botão característico de Menu localizado no canto superior direito da interface web.
  • MQTT: Sigla para Message Queueing Telemetry Transport.
  • MQTT broker: Serviço que gerencia usuários, senhas, tópicos e aplicações de uma comunicação do tipo MQTT.
  • MQTT client: Conecta-se ao servidor MQTT broker para receber e/ou enviar dados.
  • MQTT server: Servidor MQTT propriamente dito, instanciado em networkserver.maua.br
  • msg.payload: Variável principal de um flow que armazena as variáveis a serem trasnmitidas de um bloco a outro.
  • Network Server: Servidor LoRaWAN que gerencia gateways, end-nodes e aplicações.
  • Node-RED: Servidor para criação de aplicação. Pode ser instalado localmente ou em nuvem.
  • Parsing: Análise ou decomposição de uma variável em outra desejada.
  • Password: Senha de usuário correspondente ao cadastro do usuário no Network Server.
  • Port: Porta de um servidor em que se está disponibilizado um serviço.
  • Publish: Ação de publicar em um determinado Topic para enviar dados da aplicação ao end-node.
  • QoS: Sigla para Quality of Service. Não explorado nesta documentação.
  • Repositório: Lugar em que se encontram os arquivos de um projeto no GitHub, por exemplo.
  • Server: Nesta documentação, corresponde ao endereço em que se encontra o Network Server.
  • Subscribe: Ação de se inscrever em um determinado Topic para receber os dados do end-node à aplicação.
  • Tab: Cada Tab representa uma página dentre as diversas possíveis em um dashboard.
  • Topic: Endereçamento em que se está disponibilizado o acesso à aplicação por meio do MQTT broker.
  • Username: Nome de usuário correspondente ao cadastro do usuário no Network Server.
  • Update: Botão de atualização das janelas de edição de cada bloco a ser programado.
  • Widgets: Blocos mostradores em um dashboard. o Gauge é um deles, por exemplo. 
  • .zip: Estrutura de compactação de arquivos

 

 

 

Repositório GitHub

 

O repositório imt-smartcampus está totalmente disponível para downloads de códigos fontes acerca do projeto Smart Campus do Instituto Mauá de Tenologia.

 

 

 

Acesso ao Projeto de Exemplo

 

O acesso ao projeto de exemplo para uma conexão bidirecional de aplicação ao end-node é realizado através do repositório nodered-applications.

 

O acesso à página de repositórios está evidenciado na Figura 1 abaixo.

 

Figura 1 –  Página inicial de Repositórios GitHub do projeto Smart Campus

 

 

 

 

Download do Projeto

 

Ao clicar sobre o link do repositório nodered-applications, hádisponível na aba clone or download  a ção de se clonar o projeto para um diretório na máquina local ou mesmo executar o download em extensão tipo zip para o diretório de downloads default do navegador web. Outra opção é clicar sobre cada arquivo e será aberto no próprio GitHub a visualização dos códigos fonte dos arquivos listados o repositório.

 

Figura 2- Projeto de exemplo de aplicação em Node-RED utilizando o MQTT broker. Exemplo disponível para download.

 

A Figura 3 abaixo caracteriza a abertura do arquivo conterBlock.json após o download em extensão .zip e abertura em wordpad, programa padrão Windows. É necessário copiar o conteúdo deste arquivo para que se importe na interface web Node-RED conforme os passos descritos a seguir.

 

Figura 3 –  Código fonte do arquivo counterBlock.json aberto após a descompactação dodownload do arquivo.

 

 

 

 

Aplicação Node-RED

 

Para proseguir com o exemplo aqui demonstrado é necessário que se tenha corretamente o Node-RED sendo executado em  uma instalação de um servidor local ou público. Para saber como proceder com a instalação de um servidor Node-RED, deve ser executados os passos referentes na documentação Instalação Node-RED + Segurança.

 

 

 

Interface web

 

A partir da interface web disponível no endereço IP(máquina virtual):8080, é possível inciar a aplicação e o desenvolvimento de programação de blocos conforme Figura 4 a seguir.

 

Figura 4 – Interface web de programação do Node-RED ao acessar o IP(máquina virtual):1880

 

 

 

Verificação requisitos de plugins

 

Como o exemplo aqui demonstrado se utiliza de alguns plugins como também descritos na documentação Instalação Node-RED + Segurança, é bom que se verifique se estão estes corretamente instalados.

 

No menu principal do Node-RED (  ) há a opção Manage Pallets. Esta opção gerencia os plugins instalados e possibilita a instalação de novos plugins a partir da interface web do Node-RED sem a necessidade de se alterar o código fonte e reiniciá-lo.

 

Figura 5 – Menu  principal de Interface web Node-RED

 

Clicando-se sobre esta opção, deve ser verificada a instalação dos plugins node-red-contrib-crypto-js e node-red-dashboard.

 

plugin node-red-contrib-crypto-js é responsável por decodificar o pacote de dados enviados em base 64 e codificá-lo para base hexadecimal, conforme o tratamento do dado e envio do end-node ao network server.

 

Já o plugin node-red-dashboard é responsável por gerenciar a parte de visialização conforme a construção do dashboard realizada através da interface web do Node-RED.

 

 

 

Importação de flow

 

Após a verificação dos plugins instalados, deve-se novamente acessar o menu principal do Node-RED (  ). A este ponto, passar o cursor sobre Import e clicar sobre Clipboard conforme a Figura abaixo.

 

Figura 6 – Menu de importação de um código fonte de um Clipboard.

 

A partir de então, será aberta uma janela para a importação do código fonte referente ao flow que caracteriza a aplicação. Simplesmente basta colar o código fonte do arquivo counterBlock.json, por exemplo, escolher a opção current flow para que o flow seja inserifo na aba da atual da interface web ou new flow para que seja criado uma nova aba de programação. Com o código fonte json corretamente copiado para a caixa de texto conforme Figura abaixo, deve-se clicar no botão Import.

 

Figura 7 –  Importação do Clipboard para o Node-RED Interface web

 

Flow de exemplo

 

Importando-se o código json conforme descrito acima, ao clicar sobre a interface web, será exibido o seguinte flow na interface web de programação em blocos do Node-RED. Neste exemplo de programação pode-se observar dois flows. Um referente ao recebimento de dados do end-node, denominado uplink. Outro, porém denominado downlink que envia da aplicação ao end-node um pacote de dados referente ao desejado pelo usuário desta aplicação.

 

Portanto, conforme os passos a seguir demonstrados em detalhes, será configurada uma conexão para recebimendo e envio de dados através da comunicação MQTT disponibilizada pelo Network server do Instituto Mauá de Tecnologia.

 

Figura 8 –  Flow importado através do Clipboard de exemplo do repositório GitHub

 

A programação em blocos acima demonstrada, define através dos blocos de dashboard, o group demonstrado na Figura abaixo. A esta documentação será detalhada tanto a formação de cada widget dentro deste group bem como visualmente como o background do tráfego de informação a partir do MQTT broker server do Network Server.

 

Figura 9 –  Dashboard referente ao flow importado através do Clipboard de exemplo do repositório GitHub

 

 

 

 

UPLINK

A partir de uma entrada de dados em conexão com o servidor MQTT broker instanciado no network server é possível estabelecer um fluxo de código para se obter a parte da mensagem desejada através dos blocos a seguir.

 

Node Input

Na Figura a seguir, está importado o bloco de conexão ao servidor MQTT broker.

 

Figura 10 –  Node para input de dados através de um cliente MQTT broker.

 

Clicando-se no bloco para editar suas configurações, nota-se os seguintes campos como evidenciado na Figura a seguir:

  • Server: networkserver.maua.br
  • Topic: application/+/node/0004a30b001a1s6/rx
  • QoS: 2
  • Name: DET-01

 

Os campos ServerTopicQoS estão, com maiores detalhes, explanados na documentação Acesso ao MQTT broker (Network Server).

 

Para editar as propriedades de conexão, deve-se clicar sobre o ícone como na figura abaixo.

 

Figura 11 –  Janela de edição de propriedades gerais do node.

 

Figura 12 –  Add new mqtt broker server.

 


A seguir é possível editar a Conexão descrita no passo anterior. Não deve-se utilizar o campo Client-ID.

 

Figura 13 –  Janela de edição de conexão ao servidor MQTT broker.

 

Na aba Security, deve ser digitado o usuário e a senha cadastrados de Acesso ao Network Server (IMT) resultantes dos usuários de aplicação cadastrados pelo Centro de Pesquisas.

 

Figura 14 –  Janela de edição e segurança para conexão do cliente ao servidor MTT broker.

 

As alterações devem ser confirmadas clicando-se sobre o botão Update e Done no canto superior direito da janela de edição.

 

Node Function

Os blocos referentes às funções podem exercer influência direta na mensagem encaminhada através do flow.

 

JSON

Através do cliente MQTT broker, a mensagem chega no formato json, porém no tipo de string. Para formatar em objeto Json em que os campos sejam objetos com acesso aos valores correspondentes, deve-se inserir um bloco de função json.

 

Figura 15 –  Node de função para converter um dado string json em um objeto json

 

Não é necessária nenhuma configuração adicional neste bloco. Somente a presença dele já é o suficiente para formatar a string em um objeto json. Nenhuma configuração adicional significa deixar a opção Format JSON string desmarcada. Em Name a configuração é opcional. O que estiver escrito aqui será somente o nome lido no bloco da interface web do Node-RED. Em nada altera no código da mensagem.

 

Figura 16 –  Janela de edição do node de função json.

 

FUNCTION PARSING FROM MQTT

Seguindo o flow, o próximo bloco da sequência tem a função de separar somente o valor referente ao objeto campo .data.

 

Figura 17 – Node de função para executar o parse de um objeto json de forma a separar a string que contém o pacote que contém o protocolo da informação  enviada pelo end-node LoRa ao network server.

 

Esta informação recuperada do objeto json será passada adiante pelo nome msg.payload. Em suma toda a mensagem em Json será substituída por somente uma parte dela.

 

Figura 18 –  Função para a obtenção do campo referente ao pacote enviado do end-node ao network server. A saber, o campo .data.

 

//1. msg.payload receives the value of json message .data object
msg.payload = msg.payload.data;

//2. return msg with modified msg.payload object value
return msg;

 

CRYPTO (DECODE E ENCODE)

A mensagem ainda não se parecerá com a enviada através do end-node pois se encontra codificada em base 64.

 

Figura 19 –  Node para decodificação em base 64 do pacote de informação enviado.

 

A configuração do bloco decode deve possuir o Campo encode como Base64 conforme a Figura a seguir. Em Name, será apenas o nome descrito no bloco da interface web do Node-RED.

 

Figura 20 –  Janela de edição para o node de decodificação em base 64.

 

Para a codificação em formato hexadecimal, deve-se, após a decodificação em base 64, a codificação em base hexadecimal. Para isso, há o bloco de função encode.

 

Figura 21 –  Node para codificação em base hexadecimal do pacote de informação enviado.

 

Configurando o bloco encode para o Campo Encode hex (hexadecimal), é possível recuperar os dados como foram enviados pelo end-node ao networkserver. A partir daí, serão retiradas desta variável, os valores segundo os índices referentes ao protocolo LoRa Mauá.

 

Figura 22 – Janela de edição para o node de decodificação em hexadecimal.

 

FUNCTION PARSING CONTADOR

Tratando-se de um end-node de aplicação em que é enviado um pacote de contador segundo o index 0b, é possível utilizar de um bloco de função para identificar a variável 0b e então, a partir disso separar os bytes correspondentes ao valor de contador.

 

Figura 23 –  Node de função para a fragmentação e obtenção do valor contador segundo o protocolo Mauá.

 

Sabe-se que, segundo o protocolo Mauá, após o index 0b existem 6 bytes em seguida que se caracterizam pelo contador enviado pelo sensor da aplicação ao end-node este ao network server.

 

A função a seguir descrita não estabelece uma busc pelo index. Ao invés disso, sabe-se que os primeiros dois bytes são o index 0b. Então conta-se a partir do terceiro byte, outros 6 e então separam-se apenas estes para ser a variável de contador. Lembrando-se que esta técnica não é recomendada, uma vez que deve ser feita a busca pelo index, visto que de acordo com a aplicação, a mensagem poderá ser alterada de acordo com o protocolo Mauá.

 

Figura 24 – Janela de edição para inserção de código em javascript para a obtenção do valor tipo inteiro referente à variável contador.

 

//1.1. msg.payload="0bCCCCCC0cBBBB";
//1.2. msg.payload=msg.payload.substr(2,6) -> from the position 2 (starting from zero), receive 6 bytes from on; 
//1.3. msg.payload="CCCCCC";
//1.4. parseInt(msg.payload,16) -> parse string to int as hexadecimal to decimal value;
msg.payload = parseInt(msg.payload.substr(2,6),16);

//2. return msg with modified msg.payload object value 
return msg;

A partir do retorno deste valor para uma variável, esta informação consiste naquela enviada pelo end-node referente à variável contadora. Agora, pois como esta informação será tratada, depende da aplicação. Neste caso de exemplo será exibido o valor em um dashboard. Mas esta variável pode ser um parâmetro de input de dados em um sistema de deep-learning , por exemplo.

 

DASHBOARD WAVE

A demonstração deste valor pode ser exibida em um dashboard através dos blocos ali disponíveis. No caso da demonstração desta variável contadora foi utilizado um bloco de saída para o dashboard do tipo Gauge e configurado o display para o tipo gauge.

 

 

Figura 25 –  Node de dashboard que define o tipo de gauge  ser escolhido segundo a variável contador.

Nas configurações de gauge foi escolhido, do campo Type, o tipo level.

 

Figura 26 – Janela de edição que define o tipo de gauge  ser escolhido segundo a variável contador.

 

FUNCTION PARSING NÍVEL DE BATERIA

No envio de um pacote do end-node ao networkserver também foi inserido o valor de tensão de bateria segundo o index 0c. Sendo 0c im indicador também de que os próximos quatro bytes serão referentes ao nível de bateria em um valor inteiro vezes 1000.

 

Figura 27 –  Node de função para a fragmentação e obtenção do valor nível de tensão de bateria segundo o protocolo Mauá.

 

Na configuração deste bloco de função são separados os bytes da mensagem para os respectivos valores de tensão de bateria.

 

Figura 28 – Janela de edição para inserção de código em javascript para a obtenção do valor tipo float com uma casa decimal referente à variável nível de tensão de bateria.

 

//1.1. msg.payload="0bCCCCCC0cBBBB";
//1.2. msg.payload=msg.payload.substr(10,4) -> from the position 10 (starting from zero), receive 4 bytes from on;
//1.3. msg.payload="BBBB";
//1.4. parseInt(msg.payload,16) -> parse string to int as hexadecimal to decimal value;
//1.5. Divide the value by 1000 to match real batery's voltage data;
//1.6. Units fixes with 2 decimal cases.
msg.payload = (parseInt(msg.payload.substr(10,4),16)/1000).toFixed(2);

//2. return msg with modified msg.payload object value 
return msg;

 

DASHBOARD NÍVEL DE BATERIA

Para a visualização no dashboard, escolheu-se um gauge no menu de blocos no canto esquerdo da interface Node-RED.

 

Figura 29 – Node de dashboard que define o tipo de gauge  ser escolhido segundo a variável Bateria.

 

O tipo gauge foi escolhido para representar o nível da tensão da bateria. Este gauge está configurado segundo a Figura a seguir.

 

Figura 30 –  Janela de edição para node de dashboard gauge Gauge.

 

INPUT PARA OFFSET PARA TEMPO DE ATUALIZAÇÃO DE MENSAGEM RECEBIDA

De maneira a gerar um intervalo de tempo com uma variável diferente de msg.payload o que iria sempre zerar o contador de tempo, foi indroduzida uma variável de tempos em tempos que atualiza o tempo da última atualização enquanto o end-node não envie a informação através do MQTT broker.

 

Figura 31 –  Node de input para contagem de tempo para definição da variável Atualizado há no dashboard.

 

As configurações de temporização desta variável auxiliar podem ser definidas conforme a figura abaixo.

 

Figura 32 –  Edição de node de input para definição da variável Atualizado há” no dashboard.

 

Portanto, a cada 5 segundos, neste caso, a variável msg.time_sample é introduzida paralelamente ao bloco  de função de atualização.

 

FUNCTION PARSING ATUALIZAÇÃO DE MENSAGEM RECEBIDA

A esta função de atualização da última mensagem, o pacote enviado através do MQTT serve apenas como um trigger, não sendo necessário nenhum parse ou decomposição de informação. Segundo o bloco abaixo de função fi inserido paralelamente na saída do bloco decode com o bloco de entrada msg.time_sambple.

 

Figura 33 –  Node de function que calcula o tempo da última mensagem recebida pelo end-node.

 

A programação deste bloco pode ser evidenciada a seguir segundo a Figura e a programação comentada.

 

Figura 34 – Janela de edição para a inserção da função que calcula o tempo da última mensagem recebida pelo end-node e retorna para exibição do valor no dashboard.

 

//1. Call constructor Date() and pass to now
var now = new Date();
//2. time_now receive current time
var time_now = now.getTime();

//3. last_broker_time receives time_now if type of last_broker_time is still undefined
if (typeof last_broker_time === 'undefined'){
 last_broker_time = time_now;
}

//4. If msg.payload is true, last_broker_time receives time_now value
if (msg.payload){
 last_broker_time = time_now;
 }

//5.1. Calculate diference between times
//5.2. Divide per 1000 to parse miliseconds to second
//5.3. Divide per 60 to parse second to minute
//5.4. Units fixed to none decimal cases -> .toFixed(0) return an int value
//5.5. parseInt("string",10) --> returns a decimal value based on own string value
var difference_between_times = parseInt(((time_now - last_broker_time)/60000).toFixed(0),10);

//6. Pass to msg.payload the desire value to show on gauge in dashboard
msg.payload = difference_between_times; 

//7. return msg with modified msg.payload object value 
return msg;

 

DASHBOARD ATUALIZADO HÁ

Para amostrar no dashboard foi escolhido o gauge to tipo donut.

 

Figura 35 – Node de dashboard que define o tipo de gauge  ser escolhido segundo a variável Atualizado há.

 

Conforme o maior tempo passado da última atualização, conforme calculado, o indicador torna-se em outra cor em um gradiente segundo o programado na janela de edição a seguir.

 

Figura 36 –  Janela de edição para node de dashboard gauge Donut.

 

 

 

Downlink

A partir de uma entrada de dados em conexão com o servidor MQTT broker instanciado no network server, é possível estabelecer um fluxo de código para publicar uma mensagem desejada através dos blocos a seguir. O envio de dados de uma aplicação para o end-node em uma rede LoRaWAN, denomina-se downlink.

 

Para isso é necessário um método de entrada em uma interface com o usuário. O bloco representado pela Figura representa um botão de interface com o usuário na área de dashboard.

 

Figura 37 – Bloco de botão no painel para o envio de downlink ao end-node.

 

Configurando o botão na janela de edição segundo as configurações de grupo para o group DET-01 na tab IMT-CP-DET. pode ser visto na Figura a seguir.

Figura 38 – Janela de edição do bloco de botão no dashboard.

 

A partir de um comando de acionamento da variável msg.payload tendo o botão acima descrito como um trigger, é necessário incluir na varíavel uma string no formato json para que a informação seja corretamente aceita pelo network server e este, por sua vez, gerencie a fila de downlink a ser enviado ao node quando este enviar um pacote ao servidor.

 

Lembrando-se que está habilitado somente o modo Classe A, em que janelas de recebimento do node estarão disponíveis apenas quando for enviado um pacote de uplink.

 

Figura 39 – Bloco que concatena as variáveis pré definidas para string json.

 

Abaixo está descrito na Figura o código de inserção de uma variável desejada no campo “data”. É necessário notar que o valor deste campo não estará restrito somente a um tipo. A criatividade na hora de implementar uma mensagem será crucial para como o usuário manipulará a mensagem enviada ao end-node. O exemplo a seguir demonstra a maneira mais simples e correta de se enviar um dado através da aplicação ao end-node.

 

Figura 40 – Janela de edição para concatenação dos dados necessários para um downlink.

 

 

//1. msg.payload receivers a concatenated json string to format and publishover MQTT client publisher. 
msg.payload = '{ "reference": "test-node-red", "confirmed": false, "fPort": 100, "data": "AAE=" }'; 

//2. return msg with modified msg.payload object value. 
return msg;

Para formatar a string JSON em um objeto JSON, é necessário utilizar o bloco representado pela Figura abaixo.

 

Figura 41 – Bloco de formatação para um objeto em json.

 

Nas configurações deste bloco ão é necessária nenhum outro parâmentro. Apenas a presença do bloco já é o suficiente.

 

Figura 42 – Janela de edição para configuração do bloco json.

 

Para permitir a conexão ao MQTT broker do network server é necessário um MQTT client que publica as informações fomentadas neste flow. Ao bloco a seguir representado pela Figura está um bloco MQTT client de publish. Em que as informações chegadas até ele serão publicadas de acordo com as configurações da janela de edição.

 

Figura 43 – Bloco correspondente ao MQTT client

 

Semelhantemente ao MQTT client de subscribe as configurações correspondentes ao campo Server serão as mesmas. Entretanto, deve-se notar que o tópico será outro. Ao invés de rx , terminará com a variável tx.

 

No tópico somente será mudado o equivalente ao dev_eui. Para quaisquer dúvidas referente a estes termos deve ser lido o documento Acesso ao MQTT broker (Network Server).

 

Figura 44 – Janela de edição para configuração do bloco MQTT client publish

 

 

 

 

Um outro exemplo

 

Um outro exemplo de mostrador, e um dos que permitem o maior número de modificaões, é o exemplo de template, conforme o bloco da Figura a seguir.

 

Figura 45 – Bloco de dashboard para templates

 

Percebe-se que não há nenhuma configuração adicional que seja autoconfigurável como no caso dos gauges demonstrados neste exemplo. Entretanto, conforme a Figura a seguir, percebe-se um espaço para programação.

 

Figura 46 – Janela de edição do bloco de dashboard template

 

Neste bloco pode-se programar um dashboard em html. Isto é, criar-se gráficos totalmete personalizáveis e importar templates de amostragens pré exisistentes.

 

No caso da Figura, a amostragem é de uma grandeza de temperatura. Para isso, optou-se por mostrar o valor em uma fonte que se destaca das demais informações do dashboard.

 

Figura 47 – Dashboard para amostragem de temperatura como elemento principal.

 

Inúmeras outras possibilidades podem ser criadas de maneira a permitir ao usuário final a melhor experiência possível.

 

CLICK-AND-SWIPE DOCS GALLERY

 

 

<–  Acesso ao MQTT broker (Network Server)

Exemplo em Node-RED com vários mostradores em um dashboard online  –>

Scroll to Top