Variáveis persistentes
A maneira mais comum de realizar a troca de dados entre blocos de função é injetando mensagens na linha com um JSON que contém a informação que se deseja repassar. Nesta modalidade, o dado recebido por um bloco de função é acessível somente uma vez pelo algoritmo implementado em On Message. Porém, a depender das necessidades da lógica implementada, podem existir dados que precisam ser armazenados por mais tempo, ou serem acessados por um ou vários blocos de função que não necessariamente se encontram na mesma linha de fluxo da lógica programada.
Nestes casos, é interessante definir tais variáveis utilizando o conceito de variáveis persistentes, que são variáveis que podem ser definidas para além do escopo de On Message. Assim, as variáveis persistentes podem ser acessadas em outras execuções do mesmo On Message de um dado bloco de função, ou até mesmo por outros blocos.
A sintaxe para trabalhar com variáveis persistentes é basicamente <contexto-da-variável>.<método-de-manipulação>(foo). O objeto contexto-da-variável> tem a ver com o escopo programático que se deseja ter acesso àquele dado, havendo três diferentes níveis:
context: acessíveis somente dentro do node de função que a define;flow: acessíveis somente dentro do flow em que foram salvas;global: acessíveis a partir de qualquer parte de todo o programa implementado no Node-RED.
O método de manipulação <método-de-manipulação>(foo) tem a ver com o que se deseja fazer com a variável, sendo possíveis os seguintes métodos:
.set('foo', bar): Atribui o valor de bar a uma variável persistente chamada 'foo'. bar pode ser um valor "hard-coded" ou uma variável..get('foo'): Recupera o valor armazenado na variável persistente** 'foo'. Se 'foo' ainda não tiver sido setado, seu valor por padrão é a palavra JavaScript reservada 'undefined'..keys(): Retorna uma lista das variáveis persistentes salvas naquele contexto.
O algoritmo a seguir implementa um contador de quantas vezes o bloco On Message já foi executado.
let contador = context.get('contador_persistente');
if (contador === undefined) { // caso em que o contador ainda não havia sido definido
contador = 1; // inicia a contagem
} else { // caso em que o contador já havia sido definido
contador += 1; // incrementa a contagem
}
// atualiza a variável de contador
context.set('contador_persistente', contador);
Perceba que o nome da variável que é salva de forma persistente não precisa ter relação com o nome da variável definida dentro do escopo de programação do bloco de função. Assim, vê-se que no exemplo anterior a variável foi definida no bloco de função com o nome contador, enquanto seu nome no contexto persistente era contador_persistente.
Bloco HTTP Request
Um dos blocos básicos disponibilizados pelo Node-RED é o http request, que permite fazer requisições a endpoints (endereços URI) de APIs REST disponíveis.

Para fazer uma requisição online, basta apenas arrastar o bloco http request para o flow, configurá-lo com o tipo de solicitação desejada (GET para obter dados) e inserir o endereço URI da API que se deseja obter os dados. É interessante configurar o parâmetro Return para A parsed JSON object para que o bloco entregue um JSON estruturado.
Utilize o bloco http request para obter os dados de posição da Estação Espacial Internacional (ISS) utilizando esta API, cujo URI é
http://api.open-notify.org/iss-now.json
O resultado esperado é apresentado na figura a seguir.

Mapas
Muitas aplicações de sistemas modernos trabalham com informações geográficas. No Node-RED, é possível utilizar um módulo disponível pela comunidade que permite de forma facilitada criar mapas interativos e dinâmicos, que podem ser atualizados em tempo real com informações provenientes de sensores.
Criando o mapa
Para criar um mapa no Node-RED, instalaremos o módulo node-red-contrib-web-worldmap, cujo manual pode ser encontrado neste link. Note que aparecem os seguintes na paleta de nós:

Arraste o bloco worldmap para o flow e dê 2x cliques nele para acessar suas propriedades. A propriedade Web Path permite configurar qual é o path URI em que estará acessível o mapa. Por exemplo, se o Node-RED possui o endereço (i.e., caminho no navegador) http://localhost:1880 e o path configurado é /worldmap, o mapa poderá ser acessado pelo endereço http://localhost:1880/worldmap.

Pronto! Ao salvar os parâmetros deste bloco e realizar o deploy, o mapa já poderá ser acessado pelo navegador em
<IP_SERVIDOR>:<PORTA_NODERED>/<PATH_DEFINIDO>/
Definições básicas do mapa
Por padrão o mapa irá abrir em uma região específica na Inglaterra (por puro desejo de seus desenvolvedores). Esta vista inicial do mapa pode ser configurada nos parâmetros de Start. Por exemplo, defina latitude = 0, longitude = 0 e zoom = 2.5.
A propriedade Base map permite alterar o estilo de renderização do mapa. Por exemplo, altere-a para ESRI Satellite para ver o mapa renderizado a partir de fotografias de satélite.
Com as configurações acima realizadas, o mapa recém carregado deve ficar parecido com a imagem a seguir:

Inserindo um marcador no mapa
Marcadores são pontos renderizados em uma posição geográfica específica no mapa. Para criar um marcador, deve-se injetar um JSON no nó worldmap com os campos mínimos:
lon: longitude no formato floatxx.xxxxx.lat: latitude no formato floatyy.yyyyy.name: identificador único do objeto no mapa.
Injete o seguinte payload em worldmap para ver um marcador com a posição geográfica do CAP:
msg.payload = {
"name": "UFSJ CAP",
"lat": -20.52208,
"lon": -43.74468
}
O resultado esperado é:

Note que, ao clicar no marcador, surge um balão que exibe o nome daquele marcador e suas coordenadas.
É possível adicionar mais parâmetros ao payload para personalizar o marcador criado no mapa. Algumas das opções principais são:
alt: Define uma altitude para o objeto, em metros.icon: Altera o ícone do marcador. Pode-se inserir um dos nomes de ícone do Font Awesome. Se o nome for inserido sozinho (e.g.,university), o ícone será exibido dentro do símbolo do marcador; se o nome for precedido porfa-(e.g.,fa-university), então o próprio marcador se tornará o ícone.iconColor: String com nome da cor no padrão CSS, ou no formato hexadecimal#RRGGBB. Standard CSS colour name or #rrggbb hex value.weblink: Adiciona um link ao balão de informação do objeto. Pode-se definir o link como uma string (e.g.https://www.ufsj.edu.br/cap/) ou em formato JSON (e.g.,{"name":"Website do CAP", "url":"https://www.ufsj.edu.br/cap/", "target":"_new"}).label: Apresenta o conteúdo deste parâmetro como um label permanente ao lado do marcador.
Injete a mensagem a seguir no nó worldmap para ver um marcador estilizado do CAP:
msg.payload = {
"name": "UFSJ CAP",
"lat": -20.52208,
"lon": -43.74468,
"icon": "fa-university",
"iconColor": "#00FF00",
"weblink": {"name":"Website do CAP", "url":"https://www.ufsj.edu.br/cap/", "target":"_new"},
"label": "CAP/UFSJ"
}
O resultado esperado é:

Para uma visão completa do que pode ser feito no nó de worldmap, consulte o docs do módulo no npm:
DOCS: node-red-contrib-web-worldmap
npmjs.com
Crie um mapa para monitorar a posição da ISS em tempo real.
Requisições de projeto:
- O marcador da ISS deve ser atualizado a cada segundo e possuir o ícone
ISS. - O marcador deve acompanhar um label descrevendo a latitude e longitude atuais, em graus e com duas casas decimais, e a distância em quilômetros percorrida pela ISS desde que o código começou a ser executado. A label deve ser no seguinte formato:
"lat: XX.XX, lon: YY.YY, dist: ZZ.ZZ km".
O resultado final esperado é representado na figura a seguir:

- Para formatar a quantidade de casas decimais no template string, converta a variável para número (se necessário) e utilize a função
toFixed(n). Exemplo:Number(foo.toFixed(2)). - Para calcular a distância percorrida por um objeto em órbita a partir de duas coordenadas em momentos próximos, pode-se utilizar a fórmula de Haversine:
onde