Ana içeriğe geç

Raw Writer Servisi

Raw Writer Servisi, calibration.ready.v1 eventini tüketip kalibre edilmiş verileri ham segment tablolarına kalıcı olarak yazan mikroservistir.

Bu servis sentez hesaplaması yapmaz; yalnızca normalize/kalibre veriyi doğru tabloya, doğru stream_id ile yazar ve bir sonraki katmanı tetikler.

Kanonik State Sozlesmesi

device_buffer alanlari, ownership ve stage gecisleri icin Device Buffer Redis Kaydi Sozlesmesi sayfasina bakiniz.

Sorumluluk

  • calibration.ready.v1 eventini consume etmek
  • Redis device_buffer:{device_id} içinden kalibre ve pass-through veri setlerini okumak
  • Kalibrasyon segmentleri (buffers.measurements): voltage, current, power, energy
  • Pass-through segmentleri (buffers.measurements): device, register, environment, water, location
  • Veriyi segment bazında doğru tablolarına dağıtmak
  • Yazım tutarlılığını stream_id üzerinden korumak (idempotent upsert)
  • Başarıda raw.persisted.v1, hatada raw.failed.v1 üretmek
Akış Diyagramı

Detaylı işlem akışı için Raw Writer Servisi Akış Diyagramı sayfasına bakınız.

Veri Katmanları Yazım Sırası

Raw Writer servisinde Redis okuma, segment DB yazımları ve Kafka yazım sırasını görmek için Veri Katmanları Arası Yazım Sırası sayfasına bakınız.

Tablo Dağıtım Kuralı

Her tabloda ortak alanlar: stream_id, device_id, device_time, sample_period_sec, is_valid.

Kalibrasyon Segmentleri

Kaynak: device_buffer.buffers.measurements (CT dönüşümü + gain/offset uygulanmış)

Hedef tabloYazılan alan grubu
measurements_voltagevrms_r/s/t/a, fq, vfund_r/s/t, vharm_r/s/t_3/5/7/9
measurements_currentirms_r/s/t/a, ipeak_r/s/t, ifund_r/s/t, iharm_r/s/t_3/5/7/9
measurements_powerp_r/s/t/tot, q_r/s/t/tot, s_r/s/t/tot, pf_r/s/t/tot, pfund_r/s/t, qfund_r/s/t
measurements_energyae_r/s/t/tot, re_ind_r/s/t/tot, re_cap_r/s/t/tot

Pass-through Segmentleri

Kaynak: device_buffer.buffers.measurements (canonical + kalibre akis baglami)

Hedef tabloKaynak alanYazılan alan grubuZorunluluk
measurements_devicemeasurementsb_iv, b_av, b_ic, b_ac, b_cs, b_soc, rssi, wds, tac, cell_idHer pakette
measurements_registermeasurementsregister_status, register_stop, register_publishHer pakette
measurements_environmentmeasurementsah, ap, at, at_dew, at_fl, hi, il, pcb_h, pcb_t, r, sm*, st*, uv, vlOpsiyonel
measurements_watermeasurementswpOpsiyonel
measurements_locationmeasurementslatitude, longitude, altitude, speed, p_accOpsiyonel

Generic (Catch-all) Segment

Yukarıdaki segment tablolarından hiçbirine girmeyen skalar değişkenler measurements tablosuna narrow-row formatında yazılır. Her değişken ayrı satır olarak kaydedilir.

  • variable_id: Değişken adı (örn. TEMP, HUM)
  • value: Skalar ölçüm değeri
  • calibrated: Bu değere kalibrasyon uygulanmış mı
  • stream_id + variable_id kombinasyonu unique'tir; aynı stream içinde aynı değişken iki kez yazılamaz.

Yazım Kuralları

  • Yazım anahtarı stream_id’dir.
  • Aynı stream_id tekrar işlenirse idempotent upsert uygulanır.
  • Segmentlerden biri başarısız olursa event raw.failed.v1 ile işaretlenir.
  • Transaction modeli all-or-nothing olarak çalışır: segment yazımlarının tamamı başarılıysa commit edilir, aksi durumda rollback uygulanır.
  • Önerilen transaction isolation: READ COMMITTED + idempotent upsert (yüksek throughput için dengeli varsayılan).

Yazım Sonrası Akış

DB yazımı tamamlandıktan sonra servis:

  1. Redis device_buffer:{device_id} icinde kendi sorumlulugundaki raw_writer blogunu gunceller.
  2. Başarılıysa raw.persisted.v1 üretir.
  3. Downstream sentez katmanını tetikler.

Not: raw_writer blogundaki kesin alan adlari ve ownership kurallari icin Device Buffer Redis Kaydi Sozlesmesi esas alinmalidir.

Device Buffer Flow

calibration.ready.v1 sonrasinda Raw Writer Servisinin device_buffer uzerinde olusturdugu ornek fixture:

Tum asamalari tek sayfada gormek icin Device Buffer Flow dokumanina bakiniz.

{
"device_id": "64000000C466EF70",
"device_time": "2026-04-13T11:18:09Z",
"current_stage": "raw_written",
"ingest": {
"ingest_time": "2026-04-13T11:18:10Z",
"is_valid": true,
"raw_id": 2841023,
"process_time_ms": 8
},
"stream": {
"stream_id": 10248764,
"stream_time": "2026-04-13T11:18:11Z",
"process_time_ms": 13
},
"calibration": {
"calibration_time": "2026-04-13T11:18:12Z",
"process_time_ms": 11,
"ct_ratio": 1,
"vt_ratio": 1,
"calibrated_value_count": 3
},
"raw_writer": {
"write_time": "2026-04-13T11:18:13Z",
"process_time_ms": 15,
"table_write_counts": {
"measurements_voltage": 1,
"measurements_current": 1,
"measurements_power": 1,
"measurements_energy": 1,
"measurements_device": 1,
"measurements_harmonics": 1,
"measurements_register": 1
}
},
"buffers": {
"measurements": {
"VRMS_R": 220.006,
"VRMS_S": 223.792,
"VRMS_T": 221.671,
"IRMS_R": 3.995,
"IRMS_S": 4.073,
"IRMS_T": 3.887,
"IFUND_R": 3.999,
"IFUND_S": 4.067,
"IFUND_T": 3.863,
"IPEAK_R": 6.012,
"IPEAK_S": 6.246,
"IPEAK_T": 5.925,
"VFUND_R": 219.997,
"VFUND_S": 223.793,
"VFUND_T": 221.752,
"P_R": 746.184,
"P_S": 764.792,
"P_T": 777.262,
"Q_R": 467.521,
"Q_S": 496.76,
"Q_T": 360.724,
"S_R": 879.551,
"S_S": 911.181,
"S_T": 861.344,
"PF_R": 0.85,
"PF_S": 0.84,
"PF_T": 0.9,
"AE_R": 62,
"AE_S": 64,
"AE_T": 65,
"FQ": 49.98,
"STOP": 36702270,
"IHARM_R_3": 0.036,
"IHARM_R_5": 0.059,
"IHARM_R_7": 0.07,
"IHARM_R_9": 0.004,
"IHARM_S_3": 0.143,
"IHARM_S_5": 0.093,
"IHARM_S_7": 0.061,
"IHARM_S_9": 0.008,
"IHARM_T_3": 0.362,
"IHARM_T_5": 0.105,
"IHARM_T_7": 0.17,
"IHARM_T_9": 0.055,
"VHARM_R_3": 2.598,
"VHARM_R_5": 0.951,
"VHARM_R_7": 4.972,
"VHARM_R_9": 0.205,
"VHARM_S_3": 1.999,
"VHARM_S_5": 4.082,
"VHARM_S_7": 3.597,
"VHARM_S_9": 0.537,
"VHARM_T_3": 3.705,
"VHARM_T_5": 4.228,
"VHARM_T_7": 0.372,
"VHARM_T_9": 0.92,
"PCB_T": 22.95,
"PCB_H": 48.34,
"RSSI": 6,
"STATUS": 1073741839
},
"synthesis": {},
"window": {}
},
"device_metadata": {
"device_id": "64000000C466EF70",
"iccid": "899001190805082918",
"firmware": "05.00.05",
"device_type": "multi_function_meter"
},
"schema_version": 2,
"state_version": 4
}

Bu dosya, bir sonraki adimda Synthesis Servisine input olarak kullanilabilir.

Başarısızlıkta:

  1. raw_writer segmenti başarı state'i ile güncellenmez.
  2. raw.failed.v1 üretilir.
  3. Hata kodu log + DLQ akışına taşınır.
  4. Tekrar işleme idempotent olarak stream_id üstünden yapılır.

Not: Sentez Servisi, yalniz raw.persisted.v1 ile teyit edilen veya state tarafinda current_stage = raw_persisted durumuna gelmis stream setlerini islemeye alir.

Event Sözleşmeleri

raw.persisted.v1 ve raw.failed.v1 dahil tüm event payload sözleşmeleri için Event Sözleşmeleri sayfasına bakınız.

Çıktı

Raw Writer Servisinin çıktısı:

  • Ham segment tablolarında kalıcı veri
  • Kafka’da raw.persisted.v1 (veya hata durumunda raw.failed.v1)

Sentez Servisi raw.persisted.v1 eventini tüketerek hesap aşamasını başlatır.

Sık Sorulan Sorular

Raw Writer FAQ

Troubleshooting ve operasyonel sık sorular için Sık Sorulan Sorular sayfasına bakınız.