# LoRaWAN

> Referência do driver LoRaWAN: o servidor de rede Basics Station embutido, certificados de gateway, os registros de sensor e de concentrador, e o endereçamento no payload.

O driver LoRaWAN transforma o Ganter Lab num pequeno **servidor de rede LoRaWAN**. O
sentido da relação é invertido em comparação com a maioria dos drivers: a estação não
alcança um sensor, o **gateway conecta ao Ganter Lab**, e os sensores entregam
as leituras deles como uplinks por aquele gateway. O Ganter Lab embute um servidor de rede
que fala o protocolo **LoRa Basics Station** da Semtech, então qualquer gateway com firmware
Basics Station pode usar esta estação como LNS dele.

O servidor embutido inicia quando o primeiro dispositivo LoRaWAN habilitado é carregado no
connector em execução, e não na inicialização da aplicação, e para quando o último é removido ou
desabilitado: sem nenhum sensor e nenhum concentrador configurado, nada escuta na porta.
Adicionar um o traz de volta, sem reiniciar a aplicação.

Cada dispositivo sob o driver é um de **dois registros**, escolhido no painel dele:

- Um **sensor**, identificado pelo DevEUI dele e admitido com a chave de aplicação dele. As
  tags dele decodificam o payload do uplink.
- Um **concentrador de rádio** (o gateway), identificado pelo Station EUI dele e
  registrado numa **região de rádio** escolhida de uma lista. Ele não carrega tags próprias: a página dele mantém **Acrescentar tag** em cinza, dizendo o motivo, até o dispositivo ser registrado como sensor de campo.

Registre o concentrador além dos sensores. Um concentrador Basics Station pede
a configuração de rádio dele assim que conecta e não repassa absolutamente nada até ser
respondido, então uma estação que nunca viu o Station EUI dele deixa todo sensor
atrás dele sem valor, enquanto a conexão em si parece saudável. A resposta é
montada aqui a partir da região que você escolheu; não há texto de configuração para colar.

## Preparar o gateway {#prepare-the-gateway}

O gateway é quem disca para esta estação, pelo LoRa Basics Station, e de fábrica não
sabe onde ela está. A página de cada dispositivo registrado como concentrador de rádio
traz o cartão **Preparar o gateway** com o que informar nas configurações do Basics
Station no gateway, escrito para esta estação:

| O que configurar no gateway | O que o cartão dá |
|---|---|
| Endereço do LNS (o `tc.uri` do Basics Station) | `wss://<endereço>:5001`, primeiro com o endereço pelo nome desta estação (o "Nome de rede" da configuração do servidor OPC UA embutido, ou o nome do computador enquanto ele está vazio), depois uma vez para cada endereço IPv4 que esta estação tem numa rede, cada um com botão de copiar. Um gateway que confere o nome do servidor, como o Basics Station faz de fábrica (`TLS_SNI`), precisa do endereço pelo nome; um que não confere aceita qualquer um deles, e então o da rede dele basta. |
| EUI da estação | O EUI da estação do concentrador, com botão de copiar: a identidade com que este dispositivo registra o gateway. Cada gateway é um dispositivo concentrador próprio. Enquanto ele está vazio, o cartão diz para informá-lo no cartão Conexão. |
| Certificado de cliente (`tc.crt`, com a chave em `tc.key`) | TLS mútuo: o gateway apresenta um certificado de cliente que traz o EUI da estação dele no nome comum ou em um nome alternativo DNS (veja [Certificados](#certificates)). |
| Certificado do servidor em que confiar (`tc.trust`) | O caminho inteiro de `GanterLabConnector-<station>.pem`, o certificado raiz desta estação, com o botão **Abrir a pasta**, que mostra o arquivo no gerenciador de arquivos do Windows. O botão funciona na janela da própria estação; num navegador em outro aparelho ele fica acinzentado e diz por quê. O arquivo é gravado na primeira vez que o servidor de rede inicia, e até lá o cartão diz isso. |

O cartão fica aberto enquanto o gateway não conectou desde que a estação abriu, e se
recolhe depois que ele conecta: continua na página para a próxima vez que o gateway
for configurado. Um gateway cujo certificado nenhuma raiz instalada no Windows
garante é recusado na primeira conexão e espera em
[Acesso a equipamentos](#equipment-access). Um gateway que só fala o protocolo
Semtech UDP packet forwarder não consegue conectar: ele precisa de firmware Basics
Station.

O arquivo é o mesmo para todos os gateways desta estação, e ele não muda quando o nome ou
os endereços da estação mudam. Um gateway com a configuração de fábrica do Basics Station
aceita a estação: nada precisa ser desligado na configuração dele.

**Todo gateway que recebeu um arquivo de uma versão anterior precisa deste, instalado uma
vez como `tc.trust`.** No primeiro início desta versão, uma estação cujos gateways podem
ter um arquivo anterior mostra no cartão um aviso, **O arquivo desta estação mudou**, só
nessa execução. O aviso é um lembrete, não a instrução: instale o arquivo novo uma vez em
cada gateway de uma estação que já tinha gateways, o cartão mostrando o aviso ou não.

## Servidor de rede e portas {#network-server-and-ports}

| O quê | Valor |
|---|---|
| Protocolo | LoRa Basics Station (WebSocket, JSON) |
| Escuta | Todas as interfaces, porta TCP **5001**, só TLS |
| Endereço do gateway | `wss://<station-address>:5001` |
| Endpoint de descoberta | A requisição `router-info` do Basics Station é atendida na mesma escuta |
| Conexão de dados | Endereçada pelo Station EUI do gateway, na última parte do caminho do WebSocket |

A escuta é sempre TLS. Não existe definição que desligue a criptografia: uma
escuta em HTTP simples é recusada em qualquer lugar, exceto no loopback, que é inalcançável
da rede da planta e existe só para testes em processo.

## Certificados {#certificates}

A admissão é por TLS mútuo: o servidor prova quem é com o certificado dele,
e todo gateway precisa provar quem é com um certificado de cliente.

**Certificado do servidor.** O servidor de rede apresenta um certificado assinado pela raiz
própria desta estação, a mesma de que o sistema central OCPP depende. A raiz é criada uma vez
por perfil, na primeira vez que qualquer um dos dois servidores inicia, e guardada na pasta
de dados da aplicação:

- `GanterLabConnector.pfx`, em `ua\pki\own\private`, a chave privada, criptografada sob uma
  senha aleatória que, por sua vez, é protegida por usuário do Windows (DPAPI), então o par
  de arquivos não abre para ninguém quando copiado para outro lugar.
- `GanterLabConnector-<station>.pem`, em `ua\pki\station`, o certificado raiz público. Este é o
  arquivo que você instala no gateway como `tc.trust` para que ele confie nesta estação.

O assunto da raiz é `Ganter Lab Connector (<station>)`, em que `<station>` é o nome de rede
no dia em que ela foi criada, e ela **não expira**. Você instala a metade pública dela em
cada concentrador uma vez, à mão, então uma raiz que vencesse derrubaria a rede de
sensores inteira no aniversário dela, recusada no concentrador, onde esta
estação não enxerga nada, e custaria uma visita a cada concentrador para voltar. Não há
aviso de vencimento nem comando de renovação, porque não há o que renovar; o cartão
**Certificado raiz da estação**, na página do driver, mostra a data que ela carrega como
leitura (**Válido até**), com o caminho inteiro do arquivo público e o botão **Abrir a
pasta**, que o mostra no gerenciador de arquivos do Windows (na janela da própria estação;
num navegador em outro aparelho o botão fica acinzentado e diz por quê).

O certificado que o servidor de rede apresenta sob essa raiz traz o nome de rede da estação
(o "Nome de rede" da configuração do servidor OPC UA embutido; o nome do computador enquanto
está vazio), `localhost` e todos os endereços IPv4 da estação, e por isso um gateway que confere
o nome do servidor o aceita. Renomear o computador, mudar o nome de rede ou mudar os endereços
da estação não troca a raiz: só o certificado sob ela é emitido de novo, sozinho, sem nada a
fazer nos concentradores.

A raiz é criada de novo só quando a guardada não pode mais ser aberta, por exemplo porque foi
escrita por outra conta do Windows. Nesse caso, e na primeira vez que esta versão inicia numa
estação que já pode ter dado um arquivo anterior aos concentradores, a página do driver diz,
uma vez, sob **Os concentradores precisam do arquivo de certificado novo**, que todo
concentrador precisa receber o novo `GanterLabConnector-<station>.pem` como `tc.trust`.
Enquanto não receberem, eles não conseguem conectar.

**Certificado de cliente do gateway.** Todo gateway precisa apresentar um certificado de cliente
durante o handshake TLS; um handshake sem ele é descartado antes de qualquer dado passar.
O certificado precisa:

1. Ser confiável de um de dois jeitos: forma uma cadeia válida nesta máquina Windows, até
   uma raiz instalada nela; ou você aprovou este mesmo certificado em **Acesso a
   equipamentos** na página deste driver (abaixo). Nos dois casos ele precisa estar dentro
   das datas de validade. Uma conferência que falha recusa a conexão, e o diário registra
   qual conferência falhou.
2. Carregar o **EUI da estação** do gateway no nome comum do titular ou num nome alternativo
   de titular do tipo DNS. O identificador é lido como valor, então `AABBCCDDEEFF0011`,
   `AA-BB-CC-DD-EE-FF-00-11` e `AA:BB:CC:DD:EE:FF:00:11` nomeiam todos a mesma estação.
3. Nomear a **mesma estação** que a conexão de dados afirma ser: um certificado que
   nomeia um gateway diferente daquele do endereço da conexão é recusado.

### Acesso a equipamentos {#equipment-access}

Um gateway cujo certificado nenhuma raiz instalada no Windows garante, por ser autoassinado
ou emitido pela autoridade do próprio fabricante, não precisa dessa raiz instalada neste
computador. A primeira conexão dele é recusada, e o certificado espera em **Acesso a
equipamentos**, no fim da página do driver LoRaWAN, o mesmo cartão da página do driver
OPC UA, até você decidir:

| Grupo | O que ele lista | O que você pode fazer |
|---|---|---|
| Esperando aprovação | Cada certificado recusado, sob o EUI da estação que ele carrega: a impressão digital SHA-256, quando tentou pela última vez e quantas vezes, e os detalhes (titular, emissor, nomes de domínio, datas de validade). | **Aprovar** admite o certificado a partir da próxima conexão do gateway. **Bloquear** continua recusando o certificado sem listá-lo aqui de novo. **Descartar todos os certificados pendentes** esvazia a lista sem aprovar nem bloquear nada. |
| Equipamentos aprovados | Os certificados que você aprovou ou importou, com quem decidiu e quando. | **Retirar a aprovação** encerra a conexão do gateway e devolve o certificado à lista. **Importar certificado** aprova o certificado público de um gateway antes da primeira conexão dele. |
| Equipamentos bloqueados | Os certificados que você bloqueou. Um certificado bloqueado é recusado mesmo que o Windows confie nele. | **Desbloquear** devolve o certificado à lista, sem aprová-lo. |

Cada certificado é aprovado por si, nunca a autoridade que o assinou, então um segundo
gateway do mesmo fabricante espera a própria aprovação. Confira a impressão digital com a
que o gateway informa antes de aprovar. Aprovar não muda qual gateway o certificado é: ele
continua admitido só sob o EUI da estação que carrega, e só dentro das datas de validade.
Um certificado em que o Windows já confia é admitido como antes e nunca aparece aqui; nada
é aprovado automaticamente.

As decisões ficam na pasta de dados da estação, em `ua\pki\lorawan`, e sobrevivem a um
reinício. Só um papel que pode configurar o Connector tem os comandos desenhados, e eles
agem só na janela da própria estação: um navegador em outro dispositivo lê o cartão sem
mudá-lo, e nenhuma ferramenta de agente aprova um certificado. A lista guarda até 100
certificados esperando aprovação; quando está cheia, um novo continua recusado mas não é
listado, e o cartão avisa.

## Campos de conexão {#connection-fields}

Um dispositivo LoRaWAN não tem host nem porta próprios: um sensor é alcançado por qualquer
concentrador que leve o tráfego de rádio dele, e um concentrador alcança esta estação. O
painel mostra primeiro o seletor de registro e depois os campos de que aquele registro precisa.

| Campo | O que é | Formato | Padrão |
|---|---|---|---|
| Registrado como | Qual dos dois registros este dispositivo é: **Sensor de campo** ou **Concentrador de rádio**. Trocar isso limpa o campo abaixo, porque uma chave de aplicação e uma região não são a mesma coisa. | Sensor / Concentrador de rádio | Sensor |
| DevEUI (sensor) | O DevEUI do sensor, a identidade que ele apresenta na requisição de join. | 16 dígitos hexadecimais, puros (`8899AABBCCDDEEFF`), com traços (`88-99-AA-BB-CC-DD-EE-FF`) ou com dois-pontos. | vazio |
| Chave de aplicação (sensor) | A chave de aplicação OTAA do sensor (AppKey). Ela autentica o join e deriva as chaves de sessão. | Exatamente 32 dígitos hexadecimais, sem separadores. | vazio |
| Station EUI (concentrador) | O Station EUI do concentrador, o mesmo identificador que o certificado de cliente dele precisa carregar e o que ele põe no endereço de conexão. | 16 dígitos hexadecimais, em qualquer das grafias acima. | vazio |
| Região de rádio (concentrador) | Onde o concentrador está. Ela decide os canais, as taxas de dados e as janelas de recepção que esta estação entrega a ele na conexão. Escolhida da lista; não há texto livre. | Europa 868 MHz, Estados Unidos 915 MHz, Austrália 915 MHz, Ásia 923 MHz, China 470 MHz (revisão 1), China 470 MHz (revisão 2) | Europa 868 MHz |
| Tempo máximo sem transmissão (sensor) | Segundos que este sensor pode ficar quieto antes de os valores guardados dele pararem de contar como leituras. 0 desliga o vencimento. Veja abaixo. | 0 ou mais | 3600 |

Um dispositivo cujo DevEUI (sensor) ou EUI da estação (concentrador) ainda está vazio, como
o que você acabou de adicionar, espera por ele. A estação não o registra no servidor de rede
e nenhuma conexão é tentada, a linha dele na árvore e o aviso no alto da página dele dizem
"DevEUI ainda não informado" ou "EUI da estação ainda não informado" em vez de mostrar um
erro, **Reconectar** não tem nada a reabrir, e a saúde dele continua em Ainda não se sabe.
Informe o identificador no cartão Conexão e a estação registra o dispositivo. Um dispositivo
salvo com o identificador vazio e chamado pelo seu EUI (dezesseis dígitos hexadecimais, sem
separadores) não espera: registra-se sob o nome dele, como sempre fez.

A chave de aplicação é um segredo, e a estação a trata como tal. O painel a esconde
atrás de pontos, com uma caixa **Mostrar a senha** que a revela enquanto você confere o
que digitou; o banco de configuração a guarda protegida sob a conta do Windows que a
digitou; e ela não aparece nem no diário nem no endereço que o driver lê, que carrega
só o DevEUI. Abra a mesma configuração em outra conta do Windows e a chave não abre
junto: o campo volta vazio, dizendo "Não pode ser lido nesta conta do Windows: ele só
abre na máquina e na conta do Windows que o digitou. Digite de novo aqui.", e o sensor
para de entrar na rede até você digitar a chave de novo. Uma configuração levada num
backup mantém a chave, porque o backup é selado com a senha que você dá a ele.

O join é **só OTAA**: o sensor faz um join pelo ar através do concentrador, e o servidor
de rede o responde usando a AppKey configurada. Uma requisição de join vinda de um
DevEUI que nenhum dispositivo configurado carrega é recusada e registrada no diário. A
ativação por personalização (ABP, chaves de sessão pré-provisionadas) não é suportada. A
sessão de um sensor pertence a esta estação, não ao concentrador que repassou o join
dele: com mais de um concentrador ao alcance, os uplinks dele chegam por qualquer um que
os ouça, e um concentrador que cai ou é removido não leva nenhum sensor junto.

Desabilitar ou excluir um dispositivo o tira do servidor de rede na hora, sem esperar
por um reinício: a chave dele sai do registro, a sessão que ele mantinha nesta estação é
liberada, e o próximo join dele é recusado. Desabilitar ou excluir um concentrador
também fecha a conexão dele na hora, e os sensores que ele repassava mantêm as sessões
deles.

Um registro que o servidor não aceita nem chega a ser feito: um DevEUI ou Station EUI
que foi informado e não tem 16 dígitos hexadecimais, uma chave de aplicação que falta ou que não tem 32
dígitos hexadecimais, ou uma região que esta estação não sabe configurar. O dispositivo
lê como não conectado, a linha dele na árvore e o texto vermelho sob o cabeçalho da
página dele nomeiam o campo que foi recusado e o que ele precisa conter, e o diário
guarda a mesma linha. O servidor de rede não é iniciado por causa dele, e a estação não
tenta o mesmo registro de novo: corrigir o campo é o que traz o dispositivo de volta, e
**Reconectar** responde com a mesma recusa.

### A saúde do concentrador {#the-concentrators-health}

Um concentrador não carrega tags, então nenhuma leitura pode dizer se ele está lá. A saúde
dele, o ponto na linha dele na árvore e a coluna **Saúde** na página do driver, é se o
gateway dele está conectado a esta estação:

| Situação | Saúde |
|---|---|
| EUI da estação ainda vazio | **Ainda não se sabe**: nada está registrado |
| Registrado, o gateway ainda não conectado (o certificado dele ainda esperando aprovação, por exemplo) | **Desconectado** |
| O gateway conectado | **Conectado** |
| O gateway caiu: parado, desligado da tomada ou isolado da rede | **Desconectado**, até ele conectar de novo |
| Desabilitado | **Desabilitado** |

Por até dez segundos depois que uma mudança no concentrador é salva, ou que o Connector
inicia, ele lê **Ainda não se sabe**: registrá-lo de novo fecha a conexão do gateway, e o
gateway leva um momento para conectar de novo. Os sensores mantêm a saúde deles, pelas
leituras deles, seja qual for a do concentrador: com mais de um concentrador ao alcance, um
que cai deixa os outros entregando.

### O que é enviado ao concentrador {#what-the-concentrator-is-sent}

Quando um concentrador registrado termina o handshake de versão, esta estação responde
com a configuração de rádio da região dele: a faixa de frequência, as taxas de dados e
quais delas são só de downlink, e o plano de canais padrão da região. Se o
Station EUI não estiver registrado aqui, nada é enviado, e o diário diz qual
estação perguntou e que ela não está registrada. Essa é a entrada a procurar quando um
concentrador conecta e nenhum sensor atrás dele jamais reporta um valor.

Não há campos de intervalo de leitura. O LoRaWAN é baseado em push: o sensor decide quando
faz uplink, o servidor guarda os payloads decodificados mais recentes por dispositivo, e os valores
das tags se atualizam desse cache num ciclo fixo de um segundo.

Um sensor que ainda não fez uplink, portanto, **não tem leitura**, e não uma leitura que falhou. As
tags ficam vazias, o dispositivo relata que nada foi observado, em vez de ficar
offline, e nenhuma falha é registrada no diário: esperar o primeiro uplink é o protocolo
funcionando. Um endereço que não resolve para nada num payload que o sensor de fato enviou é
outra coisa, e é relatado como a falha de leitura que é.

### Quando um sensor fica quieto {#when-a-sensor-goes-quiet}

Como nada lê um sensor ciclicamente, o payload que ele enviou por último fica naquele cache até ele
enviar outro. Deixado assim, um sensor cuja bateria acabou continuaria publicando o
mesmo número como leitura boa enquanto a estação rodasse, alimentando gráficos, histórico
e alarmes com um valor que deixou de ser verdade.

Todo sensor carrega, por isso, um **tempo máximo sem transmissão**, em segundos,
no painel dele. O padrão é **3600 segundos**, uma hora, que cobre com folga a cadência de
dez a trinta minutos de um sensor comum; um sensor que reporta
mais raramente eleva o próprio. Passado esse prazo:

- As tags dele param de carregar valor e publicam qualidade ruim, em vez de repetir o último
  uplink.
- O painel do dispositivo diz quando o sensor transmitiu pela última vez, para você ver há quanto tempo
  ele está quieto.

Deixar o campo em **0** desliga o vencimento naquele sensor: o último uplink dele continua
lendo como bom por tempo indeterminado. Nada mais muda, e nenhum payload guardado é descartado.

## Endereçamento da tag {#tag-addressing}

Uma tag LoRaWAN endereça **bytes dentro do payload decodificado do uplink**. Não há
endereço em texto livre; o cartão Origem oferece campos tipados em dois modos, trocados pela
caixa de seleção **Endereçar por canal/tipo Cayenne LPP**:

| Campo | O que faz | Valores | Padrão |
|---|---|---|---|
| Endereçar por canal/tipo Cayenne LPP | Desligado: o campo de canal é um deslocamento de byte simples. Ligado: o payload é varrido atrás de um par canal/tipo do Cayenne LPP. | ligado / desligado | desligado |
| Canal / deslocamento no payload | Modo de deslocamento: o deslocamento de byte, em base 0, em que o valor começa. Modo LPP: o número de canal LPP a procurar. | 0 ou mais | 0 |
| Código de tipo LPP | Só no modo LPP: o byte de tipo de dado do Cayenne LPP que vem depois do byte de canal (por exemplo, 103 para temperatura). Os bytes de valor são lidos logo depois do par canal/tipo que casar, e quando vários payloads casam, o mais novo vence. | 0 ou mais | 0 |
| Comprimento de leitura (bytes, em branco = automático) | Quantos bytes do payload compõem o valor. Em branco, isso é derivado do tipo de dado: 1 em Boolean e Byte, 2 em Int16, 4 em Int32 e Float, 16 em String. | 1 ou mais, ou em branco | em branco |
| Máscara de bits (hex, em branco = nenhuma) | Uma máscara hexadecimal aplicada com E lógico sobre os bytes brutos antes de qualquer outra coisa (por exemplo `0x0FFF` para descartar bits de estado). O prefixo `0x` é opcional e uma máscara de comprimento ímpar é preenchida à esquerda. A máscara precisa cobrir exatamente tantos bytes quanto o comprimento de leitura, senão a leitura dá erro. | texto hexadecimal ou em branco | em branco |
| Byte mais significativo primeiro (MSB first, big-endian) | Declara que o payload carrega o valor em big-endian; os bytes lidos são invertidos antes da conversão. Não há caixa de ordem de palavras aqui: um payload de comprimento arbitrário não tem palavras de 16 bits a trocar. | ligado / desligado | desligado |
| Multiplicador (em branco = nenhum) | Um fator do lado do barramento, aplicado pelo servidor de rede logo depois da decodificação, antes de o valor entrar na cadeia de conversão da própria tag. Vale só para tipos numéricos. Um 0 é recusado onde é digitado ("Um multiplicador 0 zeraria toda leitura."), porque relataria toda leitura da tag como 0 com qualidade boa. | qualquer número diferente de 0, ou em branco | em branco |

A ordem das operações numa leitura é: pegar os bytes endereçados → aplicar a máscara de bits →
inverter se o byte mais significativo vier primeiro → converter para o tipo de dado da tag → aplicar o
multiplicador (tipos numéricos).

Exemplos, para um sensor cujo payload de 11 bytes carrega uma temperatura Int16 em big-endian
no deslocamento 2:

- Modo de deslocamento: canal/deslocamento `2`, comprimento de leitura `2`, byte mais significativo primeiro ligado.
- Modo LPP, o mesmo sensor falando Cayenne LPP no canal 1 com tipo 103: marque a
  caixa LPP, canal `1`, código de tipo `103`, comprimento de leitura `2`.

## Tipos de dado suportados {#supported-data-types}

| Tipo | Bytes lidos (automático) | Como os bytes são interpretados |
|---|---|---|
| Boolean | 1 | Zero é falso, qualquer outra coisa é verdadeiro |
| Byte | 1 | Byte sem sinal |
| Int16 | 2 | Inteiro de 16 bits com sinal |
| Int32 | 4 | Inteiro de 32 bits com sinal |
| Float | 4 | Precisão simples IEEE 754 |
| String | 16 | Texto UTF-8 do comprimento de leitura |

## Escritas e descoberta {#writes-and-discovery}

Tags LoRaWAN são **somente leitura**: os valores vêm apenas dos uplinks do sensor, o campo
de acesso não oferece escolha gravável, e o runtime recusa uma escrita em vez de fingir
sucesso. Downlinks existem no protocolo como tráfego de rede (aceites de join, comandos
MAC), nunca como escrita de valor de tag.

O driver não tem varredura de descoberta. Adicione o concentrador à mão, com o Station EUI
e a região dele, e cada sensor à mão, com o DevEUI e a AppKey dele; o fluxo geral de
adicionar um dispositivo está descrito na página [Connector](connector).
