API HTTP do node (LAN, porta 80)
Autenticação: Authorization: Bearer <PIN> (o PIN que definiu ao adicionar o node). GET /info é aberto.
| Endpoint | Finalidade |
|---|---|
GET /info | id, firmware, alias, uptime, lora{board,role,rx_key,open} quando há um rádio presente |
GET /data/status | entidades atuais (próprias / públicas / subscritas / diagnósticos) |
POST /data {entity_id,value,unit} | escrever uma entidade (own. / pub. nativas) |
GET /data/native | catálogo das entidades nativas que o firmware conhece |
GET/POST /node/mqtt | configuração do broker local |
GET/POST /node/lora_emerg | conjunto de entidades de emergência + webhook de comando |
GET/POST /node/lora_rx {key,open} | frase-chave de receção LoRa (nunca devolvida) e opt-in de frames em claro |
POST /node/lorasend {dst,sub,payload,aes,via?} | transmitir um frame LoRa DATA (sensor próprio: rádio; outro node: pela rede) |
GET /lora/inbox | inbox LoRa: cmds (comandos de emergência) e frames (frames de sensores, via rf/ws/tx) |
GET /lora/last | estado do rádio incl. diagnósticos de TX (link) |
POST /node/alias | etiqueta do node (mostrada em /info) |
POST /node/pair / DELETE | chave de emparelhamento do acesso remoto (só na LAN, por design) |
MQTT
Raiz dos tópicos sensmos/<id8>/. Estado, diagnósticos e entidades são publicados com discovery do Home Assistant. As mensagens chegam em sensmos/<id8>/msg como {from, eid, p} — p. ex. {"from":"lora","eid":"lora_frame.3","p":"21.5"} para um frame LoRa do sensor 3, {"from":"owner","eid":"lora_cmd","p":"water_off"} para um comando de emergência.
Nodes de software — dados sem hardware
POST https://api.sensmos.com/v1/ingest com {key, entities:[{entity_id,value,unit}], lat?, lon?, label?} coloca os seus dados no mapa ao vivo como um node de software (Home Assistant, ESPHome, um script — o que for). Uma chave com ≥ 32 caracteres é a sua identidade. Os nodes de software são só de dados: não ganham e não são alvos de sondas.
Frame LoRa DATA (para quem constrói sensores)
plain: [0xE0][0x02][flags][dst 4B][sub 1B][payload 1..128 B][CRC32 LE]
encrypted: [0xE0][0x02][flags][dst 4B][sub 1B][nonce 4B][AES-256-CTR(payload+CRC32)]
dst= primeiros 4 bytes do id do node de destino (o id de 8 hex mostrado na app);sub= o número do seu sensor atrás desse node (1–255).flagsbit0 = AES; bit1 = "último salto" — definido só pelo node quando transmite para um sensor. Um sensor só aceita um frame quando bit1 está definido,dsté o seu node esubé o seu próprio; envia os seus uplinks com bit1 = 0.- CRC32 (zlib) do payload, little-endian, dentro do bloco encriptado — uma chave errada falha o CRC.
- AES-256-CTR, chave = SHA-256(frase-chave), bloco de contador
[nonce 4B][dst 4B][sub][0…], nonce aleatório por frame. - Rádio: EU 868.1 MHz / US 903.9 MHz, BW 125 kHz, SF11, CR 4/5, sync word 0x34, CRC LoRa ligado, IQ normal. Listen before talk; respeite o duty cycle de 1% (≈25 frames/hora a 30 bytes).
- Só um salto de rádio. Os uplinks são ouvidos por qualquer node ou gateway e entregues ao node de destino pela rede; os downlinks para um sensor são transmitidos só pelo node do próprio sensor.
Um atuador que nunca transmite é invisível para a rede — envie um "hello" curto uma vez por hora para que a rede saiba quem o ouve. O contrato de engenharia completo vive no repositório do firmware (DOCS/dev/LORA-MESSAGING.md).
Gateways como ouvintes
Um gateway LoRaWAN que tenha a correr (Semtech packet forwarder) pode ouvir para toda a rede: um agente passivo reencaminha cada frame recebido para o backend sob a identidade do seu node — configuração em Gateway LoRaWAN, o contrato (emparelhamento, tokens, formatos) em Attachments e a API EXT. Os frames para nodes Sensmos são encaminhados; o tráfego LoRaWAN de terceiros conta apenas como estatística de espectro.