KRYONOS

Cloud Sync & Device Pairing

How to pair KryonOS microcontrollers to the cloud dashboard using Outbound Reverse Long-Polling.

Cloud Sync & Outbound Pairing

KryonOS uses an Outbound Zero-Trust Handshake (Reverse Long-Polling Tunnel) to connect devices to user accounts over the internet without port forwarding or local network restrictions.


3-Step Instant Pairing Flow

KryonOS (ESP32)                     Cloud Server                    User Dashboard
      │                                  │                                 │
      │ 1. POST /api/devices/pair/init   │                                 │
      ├─────────────────────────────────►│                                 │
      │◄── Returns: "7K4P-92QX" ─────────┤                                 │
      │                                  │                                 │
      │ [Shows "7K4P-92QX" on screen]    │                                 │
      │                                  │                                 │
      │ 2. GET /api/devices/pair/wait    │                                 │
      │    ?code=7K4P-92QX               │                                 │
      ├─────────────────────────────────►│                                 │
      │                                  │  3. Types "7K4P-92QX" on web    │
      │                                  │◄────────────────────────────────┤
      │                                  │                                 │
      │ 4. 200 OK with live credentials  │                                 │
      │◄─────────────────────────────────┤                                 │
      │                                  │                                 │
 [Saves token to NVS Flash]       [Device Status: Online]

Arduino C++ Pairing Implementation

#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Preferences.h>

const char* SERVER_URL = "https://kryonos.harislab.tech";
Preferences prefs;

void pairDevice() {
  HTTPClient http;
  
  // 1. Initialize session
  http.begin(String(SERVER_URL) + "/api/devices/pair/init");
  http.addHeader("Content-Type", "application/json");
  
  String payload = "{\"specs\":{\"chipModel\":\"ESP32\",\"macAddress\":\"" + WiFi.macAddress() + "\"}}";
  int code = http.POST(payload);
  
  if (code == 200) {
    StaticJsonDocument<512> doc;
    deserializeJson(doc, http.getString());
    String pairingCode = doc["pairingCode"].as<String>();
    
    Serial.printf("[Pairing] Display Code on Screen: %s\n", pairingCode.c_str());
    http.end();
    
    // 2. Open Outbound Long-Polling Tunnel
    HTTPClient waitHttp;
    waitHttp.setTimeout(55000);
    waitHttp.begin(String(SERVER_URL) + "/api/devices/pair/wait?code=" + pairingCode);
    
    int waitCode = waitHttp.GET();
    if (waitCode == 200) {
      StaticJsonDocument<1024> resDoc;
      deserializeJson(resDoc, waitHttp.getString());
      
      if (resDoc["status"] == "success" || resDoc["status"] == "PAIRING_COMPLETE") {
        String token = resDoc["token"].as<String>();
        prefs.begin("kryon_auth", false);
        prefs.putString("token", token);
        prefs.end();
        Serial.println("[Pairing] Device successfully paired!");
      }
    }
    waitHttp.end();
  }
}

On this page