HTTP API noda (LAN, port 80)
Uwierzytelnianie: Authorization: Bearer <PIN> (PIN ustawiony przy dodawaniu noda). GET /info jest otwarte.
| Endpoint | Cel |
|---|---|
GET /info | id, firmware, alias, uptime, lora{board,role,rx_key,open}, gdy jest radio |
GET /data/status | bieżące encje (własne / publiczne / subskrybowane / diagnostyka) |
POST /data {entity_id,value,unit} | zapis encji (own. / natywne pub.) |
GET /data/native | katalog natywnych encji, które zna firmware |
GET/POST /node/mqtt | konfiguracja lokalnego brokera |
GET/POST /node/lora_emerg | zestaw encji awaryjnych + webhook komend |
GET/POST /node/lora_rx {key,open} | fraza klucza odbioru LoRa (nigdy nie zwracana) i opt-in na jawne ramki |
POST /node/lorasend {dst,sub,payload,aes,via?} | nadanie ramki LoRa DATA (własny czujnik: radio; inny node: przez sieć) |
GET /lora/inbox | skrzynka LoRa: cmds (komendy awaryjne) i frames (ramki czujników, via rf/ws/tx) |
GET /lora/last | stan radia wraz z diagnostyką TX (link) |
POST /node/alias | etykieta noda (pokazywana w /info) |
POST /node/pair / DELETE | klucz parowania zdalnego dostępu (tylko LAN, celowo) |
MQTT
Korzeń tematów sensmos/<id8>/. Status, diagnostyka i encje są publikowane z discovery Home Assistant. Wiadomości przychodzą na sensmos/<id8>/msg jako {from, eid, p} — np. {"from":"lora","eid":"lora_frame.3","p":"21.5"} dla ramki LoRa z czujnika 3, {"from":"owner","eid":"lora_cmd","p":"water_off"} dla komendy awaryjnej.
Nody programowe — dane bez sprzętu
POST https://api.sensmos.com/v1/ingest z {key, entities:[{entity_id,value,unit}], lat?, lon?, label?} umieszcza Twoje dane na mapie na żywo jako node programowy (Home Assistant, ESPHome, skrypt — cokolwiek). Klucz ≥ 32 znaków to Twoja tożsamość. Nody programowe są tylko do danych: nie zarabiają i nie są celami sond.
Ramka LoRa DATA (dla budujących czujniki)
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= pierwsze 4 bajty id noda docelowego (8-znakowe id hex pokazywane w apce);sub= numer Twojego czujnika za tym nodem (1–255).flagsbit0 = AES; bit1 = „ostatni skok" — ustawiany tylko przez noda, gdy nadaje do czujnika. Czujnik przyjmuje ramkę tylko wtedy, gdy bit1 jest ustawiony,dstto jego node, asubto jego własny; swoje uplinki wysyła z bit1 = 0.- CRC32 (zlib) payloadu, little-endian, wewnątrz bloku szyfrowanego — zły klucz nie przechodzi CRC.
- AES-256-CTR, klucz = SHA-256(fraza klucza), blok licznika
[nonce 4B][dst 4B][sub][0…], losowy nonce na ramkę. - Radio: EU 868.1 MHz / US 903.9 MHz, BW 125 kHz, SF11, CR 4/5, sync word 0x34, LoRa CRC włączone, normalne IQ. Listen before talk; przestrzegaj duty cycle 1% (≈25 ramek/godzinę przy 30 bajtach).
- Tylko jeden skok radiowy. Uplinki słyszy dowolny node albo brama i dostarcza je do noda docelowego przez sieć; downlinki do czujnika nadaje tylko własny node tego czujnika.
Element wykonawczy, który nigdy nie nadaje, jest dla sieci niewidzialny — wysyłaj krótkie „hello" raz na godzinę, żeby sieć wiedziała, kto go słyszy. Pełny kontrakt inżynierski jest w repozytorium firmware (DOCS/dev/LORA-MESSAGING.md).
Bramy jako odbiorniki
Brama LoRaWAN, którą prowadzisz (Semtech packet forwarder), może słuchać dla całej sieci: pasywny agent przekazuje każdą odebraną ramkę do backendu pod tożsamością Twojego noda — konfiguracja na Brama LoRaWAN, kontrakt (parowanie, tokeny, formaty) na Przystawki i EXT API. Ramki dla nodów Sensmos są routowane; obcy ruch LoRaWAN jest tylko zliczany jako statystyka widma.