Ana içeriğe geç

API Endpoint Listesi

Tüm endpoint'ler JWT authentication gerektirir (aksi belirtilmedikçe).

Auth

MethodPathAçıklamaAuth
POST/api/auth/loginEmail/password ile girişHayır
POST/api/auth/refreshToken yenilemeHayır
GET/api/auth/meMevcut kullanıcı profiliEvet

Users & Roles

MethodPathAçıklama
GET/api/usersKiracı kullanıcıları
POST/api/usersYeni kullanıcı
GET/POST/api/rolesRol listele/oluştur

Regions & Subregions

MethodPathAçıklama
GET/POST/api/regionsBölge listele/oluştur
GET/PUT/DELETE/api/regions/{id}Bölge detay/güncelle/sil
GET/POST/api/subregionsAlt bölge listele/oluştur
GET/PUT/DELETE/api/subregions/{id}Alt bölge detay/güncelle/sil

Gateways

MethodPathAçıklama
GET/api/gatewaysGateway listesi
GET/api/gateways/mqttLightweight MQTT gateway listesi
POST/api/gatewaysYeni gateway
PUT/DELETE/api/gateways/{id}Gateway güncelle/sil
POST/api/gateways/{id}/rawconfig/syncRaw config push
GET/api/gateways/{id}/rawconfig/previewConfig önizleme

Devices

MethodPathAçıklama
GET/POST/api/devicesCihaz listele/oluştur
GET/PUT/DELETE/api/devices/{id}Cihaz detay/güncelle/sil
GET/api/devices/{id}/hierarchyCihaz ağacı
GET/api/devices/{id}/childrenAlt cihazlar
GET/api/devices/{id}/energy-consumptionEnerji tüketimi
GET/api/devices/device-templatesTemplate listesi
GET/api/devices/device-templates/{id}Template detay
GET.../register-map/downloadRegister map indir
PUT.../register-mapRegister map yükle

Measurements

MethodPathAçıklama
GET/api/measurements/map-dataHarita snapshot
GET/api/measurements/aggregatedAggregated veri (hourly/daily/weekly/monthly)
GET/api/measurements/reactive-ratioReaktif oran
POST/api/measurements/exportCSV/Excel/PDF export

Alarms

MethodPathAçıklama
GET/POST/api/alarmsAlarm policy listele/oluştur
GET/PUT/DELETE/api/alarms/{id}Policy detay/güncelle/sil
GET/api/alarms/incidentsTetiklenen alarmlar
GET/api/alarms/incidents/countAktif alarm sayıları
GET/api/alarms/incidents/{id}Alarm detay
POST/api/alarms/incidents/{id}/ackAlarm onayla
POST/api/alarms/incidents/{id}/snoozeAlarm ertele
POST/api/alarms/incidents/{id}/closeAlarm kapat
GET/api/alarms/incidents/{id}/eventsAlarm audit trail

Firmware & OTA

MethodPathAçıklama
POST/api/firmware/versionsFirmware upload
GET/api/firmware/versionsFirmware listesi
GET/api/firmware/versions/{id}Firmware detay
GET/api/firmware/versions/{id}/downloadFirmware indir
PATCH/api/firmware/versions/{id}Metadata güncelle
POST/api/firmware/versions/{id}/releaseRelease
POST/api/firmware/versions/{id}/deprecateDeprecated işaretle
POST/api/ota/updatesTekil OTA başlat
POST/api/ota/updates/batchBatch OTA
GET/api/ota/updatesOTA listesi
GET/api/ota/updates/{id}OTA detay
POST/api/ota/updates/{id}/cancelOTA iptal
POST/api/ota/updates/{id}/retryOTA tekrar dene

LOTO

MethodPathAçıklama
GET/POST/api/loto/pointsİzolasyon noktaları
GET/POST/api/loto/sessionsLOTO oturumları
GET/PUT/api/loto/sessions/{id}Oturum detay/güncelle
POST/api/loto/sessions/{id}/approveOnayla
POST/api/loto/sessions/{id}/rejectReddet
POST/api/loto/sessions/{id}/applyUygula
POST/api/loto/sessions/{id}/releaseSerbest bırak
POST/api/loto/locksKilit uygula
DELETE/api/loto/locks/{id}Kilit kaldır

Zigbee

MethodPathAçıklama
POST/api/v1/zigbee/claims/generateClaim code oluştur
GET/api/v1/zigbee/claims/pendingBekleyen claim'ler
DELETE/api/v1/zigbee/claims/{id}Claim iptal
GET/api/v1/zigbee/gatewaysZigbee gateway'ler
GET/PUT/DELETE/api/v1/zigbee/gateways/{id}Gateway CRUD
GET/api/v1/zigbee/gateways/{id}/devicesGateway cihazları

Widgets

MethodPathAçıklama
GET/api/subregions/{id}/widgetsWidget listesi
POST/api/widgetsWidget oluştur
PUT/DELETE/api/widgets/{id}Widget güncelle/sil

WebSocket

ProtocolPathAçıklama
WS/ws/telemetry?token=JWT&devices=id1,id2Gerçek zamanlı ölçüm
GET/ws/statsHub istatistikleri

Sistem

MethodPathAçıklamaAuth
GET/healthSağlık kontrolüHayır
GET/readinessDB hazırlıkHayır
GET/api/config/publicFrontend configHayır
POST/api/internal/gateway/connectedEMQX webhookHayır*
POST/api/internal/gateway/disconnectedEMQX webhookHayır*

*Internal endpoint'ler firewall/network seviyesinde korunmalıdır.


API Kullanım Örnekleri

1. Auth Akışı (Login ve Authenticated Request)

Adım 1 — Giriş yaparak token al:

curl -X POST https://api.example.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "operator@firma.com", "password": "GucluSifre123!"}'

Response (200 OK):

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBl...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBl...",
"token_type": "bearer"
}

Adım 2 — Token ile authenticated request gönder:

curl -X GET https://api.example.com/api/devices \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI1NTBl..."

2. POST /api/auth/login

Request:

{
"email": "operator@firma.com",
"password": "GucluSifre123!"
}

Response (200 OK):

{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer"
}

Response (401 Unauthorized):

{
"detail": "E-posta veya şifre hatalı",
"error_code": "INVALID_CREDENTIALS"
}

3. GET /api/devices

Request:

curl -X GET "https://api.example.com/api/devices?skip=0&limit=10&sort_by=name&sort_order=asc" \
-H "Authorization: Bearer <access_token>"

Response (200 OK):

{
"items": [
{
"id": "d1a2b3c4-...",
"name": "Entes RG3-12CS #01",
"device_type": "energy_analyzer",
"gateway_id": "gw-uuid-...",
"slave_id": 1,
"template_id": "tpl-uuid-...",
"subregion_id": null,
"is_online": true,
"last_seen": "2026-04-07T12:30:00Z",
"created_at": "2025-11-01T08:00:00Z"
},
{
"id": "e5f6a7b8-...",
"name": "Sofar HYD 5K",
"device_type": "inverter",
"gateway_id": "gw-uuid-...",
"slave_id": 2,
"template_id": "tpl-uuid-...",
"subregion_id": null,
"is_online": false,
"last_seen": "2026-04-07T11:15:00Z",
"created_at": "2025-12-15T10:00:00Z"
},
{
"id": "c0ffee99-...",
"name": "Beny AC-22kW #03",
"device_type": "charger",
"device_role": "charger",
"gateway_id": null,
"mqtt_gateway_id": null,
"subregion_id": "d729c579-1877-4aba-8c0b-ac3c1278ec1a",
"is_online": true,
"last_seen": "2026-05-13T09:42:11Z",
"created_at": "2026-03-20T14:10:00Z"
}
],
"total": 24,
"skip": 0,
"limit": 10
}

subregion_id alanı (B Paketi — OCPP charger consumption)

DeviceResponse.subregion_id: string | null opsiyonel alan; backward-compatible additive değişiklik (eski client'lar etkilenmez).

Cihaz tipisubregion_id değeri
OCPP charger (device_role='charger')OcppCharger.subregion_id LEFT JOIN ile doldurulur; atama yoksa null.
Modbus / MQTT gateway tabanlı cihazŞu an null — gateway resolution backend tarafında bu endpoint'te uygulanmıyor. Subregion bilgisi gerekiyorsa frontend GET /api/gateways/{id} üzerinden gateway.subregion_id'i çeker.
Bağımsız / dangling cihaznull.

Kullanım örnekleri (frontend):

  • Energy Consumption analiz filtreleri Tümü / Region / Subregion / Charger modunda OCPP charger'ları subregion'a göre filtrelemek için bu alanı kullanır.
  • SLD ve charger listesi sayfaları zaten OcppChargerListItem.subregion_id (PR-E2, #287) üzerinden çalışıyor; DeviceResponse.subregion_id aynı semantiği /api/devices ortak yüzeyine taşır.

4. GET /api/measurements/aggregated

Request:

curl -X GET "https://api.example.com/api/measurements/aggregated?device_id=d1a2b3c4-...&start=2026-04-01T00:00:00Z&end=2026-04-07T23:59:59Z&interval=daily" \
-H "Authorization: Bearer <access_token>"

Response (200 OK):

{
"device_id": "d1a2b3c4-...",
"interval": "daily",
"start": "2026-04-01T00:00:00Z",
"end": "2026-04-07T23:59:59Z",
"data": [
{
"timestamp": "2026-04-01T00:00:00Z",
"voltage_avg": 231.4,
"current_avg": 12.8,
"power_avg": 2.96,
"energy_kwh": 71.04,
"power_factor_avg": 0.97
},
{
"timestamp": "2026-04-02T00:00:00Z",
"voltage_avg": 229.8,
"current_avg": 13.1,
"power_avg": 3.01,
"energy_kwh": 72.24,
"power_factor_avg": 0.96
}
]
}

Error Model

Tüm API hataları aşağıdaki standart yapıda döner:

{
"detail": "Hata mesajı açıklaması",
"error_code": "HATA_KODU"
}

HTTP Durum Kodları

KodAdAçıklamaÖrnek error_code
400Bad Requestİstek gövdesi veya parametrelerde doğrulama hatasıVALIDATION_ERROR
401UnauthorizedToken eksik, süresi dolmuş veya geçersizTOKEN_EXPIRED, INVALID_CREDENTIALS
403ForbiddenYetki yetersiz (rol/izin kontrolü)PERMISSION_DENIED
404Not Foundİstenen kaynak bulunamadıRESOURCE_NOT_FOUND
409ConflictKaynak çakışması (duplicate, state conflict)DUPLICATE_ENTRY, STATE_CONFLICT
422Unprocessable EntitySözdizimi doğru fakat iş mantığı kuralı ihlaliBUSINESS_RULE_VIOLATION
429Too Many RequestsRate limit aşıldıRATE_LIMITED
500Internal Server ErrorSunucu tarafı beklenmeyen hataINTERNAL_ERROR

Doğrulama Hatası Detaylı Yapısı (422)

Pydantic doğrulama hataları FastAPI tarafından şu formatta döner:

{
"detail": [
{
"loc": ["body", "email"],
"msg": "field required",
"type": "value_error.missing"
}
]
}

Pagination Kuralları

Tüm liste endpoint'leri (GET /api/devices, GET /api/alarms, vb.) ortak pagination parametreleri kullanır.

Query Parametreleri

ParametreTipVarsayılanAçıklama
skipint0Atlanacak kayıt sayısı (offset)
limitint50Döndürülecek maksimum kayıt (max: 200)
sort_bystringcreated_atSıralama alanı
sort_orderstringdescSıralama yönü: asc veya desc

Response Yapısı

{
"items": [ ... ],
"total": 142,
"skip": 0,
"limit": 50
}
  • items: Kayıt dizisi
  • total: Filtrelere uyan toplam kayıt sayısı
  • skip: Kullanılan offset değeri
  • limit: Kullanılan limit değeri

Filtreleme

Alan bazlı filtreleme query parametreleri ile yapılır:

GET /api/devices?device_type=inverter&is_online=true
GET /api/alarms/incidents?severity=critical&status=active

Sıralama

GET /api/devices?sort_by=name&sort_order=asc
GET /api/alarms/incidents?sort_by=triggered_at&sort_order=desc

Rate Limiting

API istekleri Nginx seviyesinde rate limit ile korunmaktadır.

Endpoint GrubuLimitAçıklama
/api/auth/login, /api/auth/refresh5 istek/dakikaBrute-force koruması
/api/* (genel)30 istek/saniyeGenel API koruması

Aşım Durumunda

Rate limit aşıldığında HTTP 429 Too Many Requests döner:

{
"detail": "Çok fazla istek gönderildi. Lütfen bekleyin.",
"error_code": "RATE_LIMITED"
}

Retry-After header'ı ile beklenmesi gereken süre (saniye) belirtilir. Client tarafında bu header kontrol edilerek yeniden deneme stratejisi uygulanmalıdır.


Cihaz Güncelleme Endpoint'i (PUT) Davranışları

PUT /api/devices/<id> endpoint'i partial update semantiği taşır; tüm alanlar opsiyoneldir, gönderilmeyenler değişmez. İki kritik özel davranış vardır.

extra_metadata MERGE Semantiği

extra_metadata JSONB kolonu şallow merge stratejisi ile güncellenir. Frontend'in mevcut metadata'yı kaybetmesini engellemek için aşağıdaki kurallar geçerlidir:

Gönderilen DeğerDavranış
Field hiç gönderilmemiş (request body'de yok)Mevcut değer korunur (no-op)
"extra_metadata": nullMevcut değer korunur (kasıtlı no-op)
"extra_metadata": \{\}Tüm metadata silinir, boş dict olur (clear)
"extra_metadata": \{"key": "val"\}Shallow merge: mevcut diğer key'ler korunur, yeni key eklenir/üzerine yazılır

Örnek:

// Mevcut: {"templateId": "sofar-hyd", "color": "blue", "notes": "ana"}

// Request body
{ "extra_metadata": { "color": "red" } }

// Sonuç: {"templateId": "sofar-hyd", "color": "red", "notes": "ana"}

null gönderiminin "alanı silmek" anlamına gelmemesi, frontend'in eksik state ile request gönderdiği durumlarda veri kaybını engeller.

MQTT Cihaz template_id Invariant

MQTT-bağlı cihazlar (mqtt_gateway_id IS NOT NULL) için template kuralı:

DurumYanıt
template_id boş422 Unprocessable Entity
template_id MQTT-uyumsuz template (yalnızca Modbus TCP için)422 Unprocessable Entity
template_id MQTT-uyumlu template200 OK

Service katmanında _validate_mqtt_template_invariant() fonksiyonu çağrılır:

{
"error_code": "MQTT_TEMPLATE_REQUIRED",
"message": "MQTT-bağlı cihaz için MQTT-uyumlu template seçilmelidir",
"device_id": "...",
"current_template_id": null
}

Bu invariant, ESP32 gateway'in cihazı doğru parse edebilmesi için zorunludur. Modbus TCP gateway'ler için template_id opsiyonel olabilir (raw mode'da çalışabilir).