ENPLDEPT
Flash
Toda a documentação
Attachments · API EXT

Attachments e a API EXT — emparelhe um gateway LoRaWAN, SDR ou outro recetor através de um node Sensmos

Um attachment é qualquer dispositivo ou programa que ouve algo útil mas não é, nem vai ser, um node Sensmos — um gateway LoRaWAN, um SDR, um recetor. Não tem carteira nem atestação. Um node na mesma LAN responde por ele e o backend emite-lhe um token restrito e revogável.

O modelo de confiança

Duas barreiras, cada uma a fechar uma porta diferente:

barreiraprovaverificada por
PIN do nodeque você está fisicamente na rede do donoo node
grant do backendque o node existe, tem dono, tem uma vaga livreo backend

Três perguntas são mantidas separadas em cada pedido:

perguntatransportada por
quem é vocêtoken (sma_…)
o que pode fazerscopes (linhas no servidor, não bytes no token)
que formato enviao URL

Um token são 24 bytes aleatórios com o prefixo sma_ — não codifica nada. As permissões vivem do lado do servidor e podem ser editadas ou revogadas sem reemitir nada.

Emparelhamento — como obter um token

Tudo isto acontece na LAN, contra o servidor HTTP local do node (porta 80). Precisa do IP do node e do seu PIN. (Para descobrir nodes, consulte /info por toda a sub-rede — o que responder é um node.)

1 — verificar o node

GET http://<node-ip>/info
→ 200 { "device_id": "…", "firmware": "1.00", "ws_connected": true }

ws_connected tem de ser true — o node retransmite o seu pedido ao backend pela sua própria ligação.

2 — pedir autorização

POST http://<node-ip>/ext/authorize
Authorization: Bearer <PIN>
{ "kind": "lora-gw", "name": "rooftop RAK", "scopes": "radio.frames,radio.spectrum" }

scopes é uma string separada por vírgulas, não um array JSON. Respostas: 202 {"req":"<id>"} retransmitido, consulte para obter a resposta · 403 PIN errado · 400 falta kind/scopes.

3 — consultar o grant

GET http://<node-ip>/ext/authorize?req=<id>
Authorization: Bearer <PIN>
→ { "status": "pending" }
→ { "status": "granted", "token": "sma_…", "id": "<attachment-id>", "exp": "<iso>" }
→ { "status": "denied",  "reason": "…" }

Consulte uma vez por segundo; o node guarda a resposta durante cerca de 5 minutos. Guarde o token com modo 0600 — a partir daí fala diretamente com o backend e o node fica fora do circuito.

Um token concedido mas não usado expira ao fim de 30 minutos. A sua vida completa (30 dias, renovável) começa no primeiro uso. Um node responde por no máximo quatro attachments; o dono pode revogar qualquer um deles a partir da app, o que torna o token inerte de imediato.

Falar com o backend

URL base https://sensmos.com/v1/ext, cada pedido com Authorization: Bearer sma_….

chamadafinalidade
GET /v1/ext/meainda está vivo, o que pode enviar, que integrações/formatos o servidor aceita (catalog) — chame no arranque
POST /v1/ext/renewprolongar a validade do token; uma vez por dia chega
POST /v1/ext/<integration>/<format>enviar dados → 200 {"ok":true,"accepted":n}

Endpoints ativos:

URLscopecorpo
/v1/ext/radio/rxpkradio.framesJSON PUSH_DATA do packet forwarder Semtech, tal como está
/v1/ext/radio/framesradio.framesformato de frame nativo (abaixo)
/v1/ext/radio/channelradio.spectrumuma leitura de espectro (abaixo)

Formatos de dados

rxpk — packet forwarder Semtech, um para um. Envie o objeto exatamente como o forwarder o produziu em PUSH_DATA:

{ "rxpk": [ {
    "time": "2026-08-21T20:48:11Z",
    "freq": 867.3, "datr": "SF9BW125", "modu": "LORA",
    "rssi": -44, "lsnr": 12.0, "size": 38, "stat": 1,
    "data": "4FNNT1MgY2Nk…"
} ] }

datr só é interpretado para LoRa; a modulação vem de modu. stat segue a Semtech (1 CRC OK, -1 falha, 0 nenhum). tmst é ignorado; sem time o servidor marca a hora de chegada.

frames — formato nativo, para attachments escritos para nós (recetor próprio, SDR, bridge Meshtastic):

{ "frames": [ {
    "ts": 1755808091, "freq": 867.3, "sf": 9, "mode": 0,
    "rssi": -44, "snr": 12.0, "len": 38, "crc": true,
    "hex": "e0534d4f53…", "dir": "rx"
} ] }

mode 0 LoRa / 1 FSK; sf 0 para FSK; hex = payload PHY, os primeiros 128 bytes são guardados. dir: "tx" é para transmissões que o seu gateway faz e que outros conseguem ouvir (downlinks normais com IQ invertido não provam nada — ignore-os); para tx, rssi transporta a potência de TX.

channel — uma leitura de espectro:

{ "freq": 869.618, "bw": 62.5, "sf": 8, "sync": 18, "noise": -118, "peak": -97 }

freq obrigatório, o resto tem 0 por padrão; noise/peak em dBm.

Limites e erros

códigocorposignificado
401invalid_tokentoken desconhecido, expirado ou revogado
403missing_scopetoken válido, mas não para este endpoint
400mensagem do parsero corpo não corresponde ao formato
404unknown_endpoint + catalognão existe essa integração/formato
413too_manyacima do limite do lote — 200 frames por pedido

Agrupe do seu lado — uma vez por segundo, ou quando acumular 50 frames, o que acontecer primeiro. Os payloads de aplicação permanecem encriptados de ponta a ponta: o servidor trabalha com metadados de rádio e reconhece frames Sensmos no meio do tráfego; não tem chaves para os payloads LoRaWAN de ninguém e não as quer.

O que os dados fazem

Os frames chegam às mesmas tabelas e ao mesmo mapa que os frames ouvidos pelo rádio do próprio node — um attachment não é um ser à parte, é uma antena melhor para o node que respondeu por ele. As transmissões de emergência e os frames de sensores Sensmos são reconhecidos e entregues aos seus donos; os beacons Sensmos verificados constroem arestas de cobertura de rádio entre nodes; o perfil de dados do node que responde ganha a categoria RF.

Attachments prontos a usar: Gateway LoRaWAN (ouvinte passivo). O código de ambos os agentes está no GitHub.

Adicionar um novo tipo de integração

O lado do servidor de cada integração é uma entrada declarativa num registo (scopes, formatos, parser, handler). Candidatos no mesmo padrão, nenhum deles ativo ainda: vista do céu GNSS e interferência (gnss.sky, deliberadamente sem posição), resumos de receção ADS-B e AIS por janela, rtl_433, contadores de energia. Se tem hardware e quer um formato aceite, fale connosco no Discord — uma entrada de formato é uma alteração pequena e fácil de rever.

Perguntas, respostas diretas

Que attachments existem hoje?

Gateways LoRaWAN — o ouvinte passivo para packet forwarders Semtech (testado, a correr em gateways de terceiros) e um agente para o ChirpStack Gateway Bridge por MQTT (completo mas por testar — não há gateway desses para verificar). Ambos reportam frames de rádio recebidos; tudo o resto nesta página é o contrato que usam, aberto a qualquer pessoa com hardware.

Os attachments ganham?

Não. São só de dados; o node que responde por eles é a única identidade que ganha. O que ouvem é entregue exatamente como os frames ouvidos pelo rádio do próprio node.

Quantos attachments por node?

Quatro. O dono vê-os e revoga-os na app, dentro do node.

Um attachment pode fazer alguma coisa na minha LAN?

O emparelhamento só acontece contra a API local do node com o PIN do node, de dentro da LAN. O backend nunca entra na LAN; um token só permite enviar dados para /v1/ext.

Atualizado: 2026-09-03