API Dokumentace

Spotové relé Standalone — REST API & WebSocket

Nepřihlášen
Všechny API endpointy (kromě /api/auth/login) vyžadují autentizaci. Pošlete header Authorization: Bearer <JWT_TOKEN>, nebo použijte HTTP Basic Auth.

🔒 Autentizace

POST/api/auth/login
Přihlášení — vrátí JWT token
{"username": "admin", "password": "heslo"}
Odpověď:
{"token": "eyJ...", "role": "admin"}
POST/api/auth/password🔒 auth
Změna hesla
{"oldPassword": "stare", "newPassword": "nove"}

📈 Stav systému

GET/api/status🔒 auth
Kompletní stav — čas, relé, spot cena, WiFi, NTP, Modbus
GET/api/system/info🔒 admin
Informace o hardware — CPU, flash, heap, LittleFS
POST/api/system/restart🔒 admin
Restart zařízení
POST/api/system/factory-reset🔒 admin
Smazání veškeré konfigurace a restart
GET/api/system/config-export🔒 admin
Export kompletní konfigurace jako JSON

⚡ Relé

GET/api/relays🔒 auth
Stav všech relé
PUT/api/relays/{id}🔒 auth
Změna relé — název, výchozí stav (0=Last, 1=ON, 2=OFF)
{"name": "Bojler", "defaultState": 1}

📋 Pravidla

GET/api/rules🔒 auth
Seznam všech pravidel s podmínkami a akcemi
POST/api/rules🔒 auth
Vytvořit nové pravidlo
{
  "name": "Levný proud",
  "enabled": true,
  "priority": 10,
  "action": {"relay": 0, "command": "on"},
  "conditions": [
    {"type": "spotPrice", "compare": "lt", "threshold": 2.5}
  ]
}

Typy podmínek

typePopisParametry
timeČasový rozsahfromH, fromM, toH, toM
weekdayDny v týdnudays: [0=Ne, 1=Po, ..., 6=So]
dateRangeRozsah datumůfrom, to (YYYY-MM-DD)
spotPriceSpot cenacompare (lt/le/gt/ge), threshold NEBO cheapHours

Příkazy akce

commandPopis
onZapnout
offVypnout
togglePřepnout stav
PUT/api/rules/{id}🔒 auth
Upravit existující pravidlo
DELETE/api/rules/{id}🔒 auth
Smazat pravidlo
PUT/api/rules/reorder🔒 auth
Změna pořadí pravidel
{"order": [3, 1, 2, 0]}

💲 Spot ceny

GET/api/spot🔒 auth
Aktuální spot data — dnešní/zítřejší ceny, konfigurace, kurz
PUT/api/spot/config🔒 auth
Nastavení spot cen
{
  "enabled": true,
  "cheapHours": 8,
  "useCzk": true,
  "eurToCzkRate": 25.2
}
POST/api/spot/fetch🔒 auth
Vynutit stažení dnešních spot cen
POST/api/spot/fetch-tomorrow🔒 auth
Vynutit stažení zítřejších spot cen
POST/api/spot/fetch-rate🔒 auth
Vynutit stažení kurzu EUR/CZK z ČNB

🕒 NTP (čas)

GET/api/ntp🔒 auth
Stav NTP — čas, timezone, sync interval
PUT/api/ntp🔒 admin
Nastavení NTP
{
  "timezone": "1",
  "syncIntervalMin": 30,
  "servers": [
    {"url": "pool.ntp.org", "enabled": true}
  ]
}
POST/api/ntp/sync🔒 admin
Vynutit NTP synchronizaci
POST/api/ntp/sync-pc🔒 admin
Nastavit čas z PC (epoch v sekundách)
{"epoch": 1712678400}

📶 WiFi

GET/api/wifi🔒 admin
WiFi konfigurace
PUT/api/wifi🔒 admin
Změna WiFi konfigurace (po uložení se zařízení restartuje)
{
  "ssid": "MojeWiFi",
  "password": "heslo123",
  "hostname": "spot-rele",
  "staticIp": false
}
POST/api/wifi/scan🔒 admin
Skenování dostupných WiFi sítí

⚙ Modbus TCP entity

Modbus TCP entity jsou výstupy ovládané pravidly (jako relé). Systém zapisuje do Modbus TCP slave zařízení přes raw TCP (FC 05 Write Coil / FC 06 Write Register). Každá entita má konfigurovatelnou adresu zařízení (Unit ID) pro TCP/RTU gateway.
GET/api/modbus🔒 auth
Seznam všech Modbus entit se stavy a konfigurací
POST/api/modbus🔒 admin
Vytvořit novou Modbus entitu
{
  "name": "Střídač",
  "ip": "192.168.1.50",
  "port": 502,
  "unitId": 1,
  "register": 100,
  "type": "binary",
  "enabled": true,
  "valueOn": 1,
  "valueOff": 0
}

Typy entit

typePopisZápis
binaryBinární 0/1FC 05 (Write Coil): 0xFF00=ON, 0x0000=OFF
analogAnalogová hodnotaFC 06 (Write Register): int16 hodnota
PUT/api/modbus/{id}🔒 admin
Upravit entitu (lze poslat jen měněná pole)
DELETE/api/modbus/{id}🔒 admin
Smazat entitu
POST/api/modbus/{id}/write🔒 admin
Ruční test zápisu hodnoty do Modbus slave
{"value": 1}
Pravidla s Modbus cílem: V akci pravidla nastavte targetType: "modbus" a modbusEntity: ID. Pro binární entity použijte command: "on"/"off". Pro analogové entity navíc zadejte analogValue: číslo.

🔐 Zabezpečení

GET/api/security🔒 admin
Bezpečnostní nastavení
PUT/api/security🔒 admin
Změna bezpečnostních nastavení
{
  "jwtEnabled": true,
  "sessionTimeoutMin": 60,
  "otaEnabled": true,
  "viewerEnabled": true,
  "viewerUsername": "viewer",
  "viewerPassword": "heslo"
}

📋 Logy

GET/api/system/logs🔒 admin
Systémové logy. Parametry: ?level=INFO&limit=50&offset=0
DELETE/api/system/logs🔒 admin
Smazat všechny logy

💾 OTA Update

POST/api/system/ota🔒 admin
Nahrání firmware souboru (.bin) přes multipart/form-data
curl -X POST -H "Authorization: Bearer TOKEN" \
  -F "firmware=@firmware.bin" \
  http://IP/api/system/ota

🔌 WebSocket

ws[s]://HOST/ws

Real-time aktualizace stavu. Po připojení pošlete auth zprávu:
{"type": "auth", "token": "JWT_TOKEN"}
Server odpovídá:
{"type": "auth_ok"}   // nebo "auth_fail"
Status broadcast (každých ~10s):
{
  "type": "s",
  "t": "2026-04-09 17:30:00",
  "up": 3600,
  "heap": 180000,
  "ntp": 1,
  "rs": [0,1,0,0],
  "rssi": -55,
  "spot": "2.54",
  "dow": 3,
  "slot": 70,
  "ar": 6,
  "ms": [0,1,0]
}
Relay change:
{"type": "rc", "id": 0, "s": 1}
Modbus change:
{"type": "mc", "id": 1, "v": 255}
Rule fired:
{"type": "rf", "id": 2}
Ping/pong:
{"type": "ping"} → {"type": "pong", "time": 1712678400}

🛠 Příklady (curl)

Přihlášení a získání tokenu

TOKEN=$(curl -s -X POST http://IP/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"heslo"}' | jq -r .token)

Čtení stavu

curl -s -H "Authorization: Bearer $TOKEN" http://IP/api/status | jq

Zapnutí relé 0 (přes pravidlo)

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Manual ON","enabled":true,"priority":99,
       "action":{"relay":0,"command":"on"},"conditions":[]}' \
  http://IP/api/rules

Zápis do Modbus entity

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value": 1}' \
  http://IP/api/modbus/1/write

Pravidlo s Modbus cílem

curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Stridac levny","enabled":true,"priority":20,
       "action":{"targetType":"modbus","modbusEntity":1,
                 "command":"on","analogValue":0},
       "conditions":[{"type":"spotPrice","compare":"lt",
                      "threshold":2.0}]}' \
  http://IP/api/rules