Base URL: http://localhost:8000
Content-Type: application/json unless stated otherwise.
Liveness + robot bağlantı durumu.
{ "status": "ok", "app": "stai-backend", "robot_connected": false }Frame al, CNN inference çalıştır, karar ver, (defect ise) robota komut gönder.
- Content-Type:
multipart/form-data - Fields:
image(required) — JPEG/PNG bytesitem_id(optional) — string, conveyor parça kimliği
Response 200:
{
"label": "DEFECT",
"confidence": 0.92,
"action": "PICK",
"reason": "distance_above_defect",
"inspection_id": 42,
"latency_ms": 87.4,
"pick_sent": true,
"distance": 0.2143,
"quality_score": null
}label—"DEFECT","OK","UNSURE"veya"INVALID"action—"PICK","PASS","REVIEW"veya"SKIP"reason— karar sebebi (distance_below_ok,distance_in_uncertainty_band, vb.)pick_sent— robot komutu gerçekten gönderildi mi (robot bağlı değilsefalse)distance— Siamese modelin golden sample'a uzaklığı (raw, stub moddanull)quality_score— kalite metriği (bu sürümdenull)
Şu anki config.
{
"defect_threshold": 0.5,
"robot_enabled": false,
"pick_target": { "x": 300.0, "y": 200.0, "z": 50.0, "angle": 0.0 }
}Threshold runtime'da güncellenir (Frontend slider için).
{ "defect_threshold": 0.6 }Döner: güncel ConfigState.
{
"total": 42,
"defects": 7,
"ok": 30,
"unsure": 5,
"defect_rate": 0.1666,
"avg_latency_ms": 84.2,
"robot_connected": true,
"model_ready": true
}Kaydedilmiş frame'ler static olarak sunulur (Frontend Live Feed için).
Frontend bağlanır, backend push eder. İstemciden gelen mesajlar yok sayılır (keep-alive).
Event envelope:
{ "kind": "<event-kind>", "payload": { ... }, "ts": "2026-04-15T10:30:00.123Z" }Kinds:
| kind | payload | Ne zaman |
|---|---|---|
hello |
{ "message": "welcome" } |
Bağlantı kurulduğunda |
inspection |
{ id, label, confidence, action, latency_ms, pick_sent, item_id, image } |
Her /inspect sonrası |
robot_connected |
{ ip, port } |
RobotStudio'ya bağlandığında |
robot_disconnected |
{ reason } |
Bağlantı koptuğunda |
robot_command_sent |
{ command } |
Backend robota komut yazdığında |
robot_send_failed |
{ command } |
Robot kapalıyken komut düştüğünde |
robot_pick_complete |
{ args, raw } |
PICK_COMPLETE geldiğinde |
robot_place_complete |
{ args, raw } |
PLACE_COMPLETE geldiğinde |
robot_error |
{ args, raw } |
ERROR,<code> geldiğinde |
image alanı sadece dosya adı (örn. "20260415_1030_a1b2c3d4.jpg"). Frontend tam URL'i şöyle kurar: ${API_URL}/data/incoming/${payload.image} — backend base path'i prepend etmez.
cURL:
curl -X POST http://localhost:8000/inspect \
-F "image=@sample.jpg" \
-F "item_id=conveyor-001"Python (Physical Input takımı için):
import requests
r = requests.post(
"http://localhost:8000/inspect",
files={"image": ("frame.jpg", jpeg_bytes, "image/jpeg")},
data={"item_id": "001"},
timeout=5,
)
print(r.json())TypeScript (Frontend):
const ws = new WebSocket("ws://localhost:8000/ws/dashboard");
ws.onmessage = (e) => {
const { kind, payload, ts } = JSON.parse(e.data);
// route to panel
};