Ana içeriğe geç

Modbus Polling

Standard Mode (Template-Based)

Template, register group'larını tanımlar:

{
"groupId": "realtime",
"intervalMs": 5000,
"blocks": [
{"startAddress": 4354, "count": 60, "functionCode": 3}
]
}

Her polling döngüsünde:

  1. UART mutex alınır
  2. Modbus RTU isteği gönderilir (FC 3 veya 4)
  3. Yanıt template'e göre parse edilir
  4. Per-group JSON oluşturulur
  5. TelemetryQueue'ya eklenir
  6. UART mutex serbest bırakılır

Raw Mode (Hex Output)

Template parsing ESP32'de yapılmaz, ham register değerleri hex olarak gönderilir:

{
"slaveId": 1,
"addr": 4354,
"count": 60,
"data": "43E6800043E5999A..."
}

Backend tarafında template ile parse edilir. Legacy ve özel cihazlar için kullanışlıdır.

Backpressure Sistemi

TelemetryQueue doluluk oranına göre 3 kademeli koruma:

KademeEşikAksiyon
Normal< %33 (5 item)Tam hızda polling
Throttle≥ %66 (10 item)500ms gecikme
Critical≥ %86 (13 item)En eski veri düşürülür, polling duraklar

Hysteresis ile kademe geçişlerinde salınım önlenir.

Polling Aralıkları

GrupAralıkİçerik
realtime5sVoltaj, akım, güç, cos(φ)
power_totals5sToplam güç, frekans
energy_kwh60sEnerji sayaçları
step_values30sKompanzasyon basamakları
ct_ratio24hCT/PT konfigürasyon
bms_identity24hBMS seri no, SoH

Desteklenen Cihaz Modelleri

Aşağıdaki tabloda Zeus 2.0 ile test edilmiş ve template'i hazır olan cihaz modelleri listelenmiştir.

MarkaModelTipProtokolBaud Rate
EntesRG3-12CSEnerji AnalizörüModbus RTU9600
EntesRG20CEnerji AnalizörüModbus RTU9600
EntesRGSR-24SReaktif KompanzasyonModbus RTU9600
KaelEnergymeter-02Enerji AnalizörüModbus RTU9600
KaelMultiser-01Multi AnalizörModbus RTU9600
Varkombi12-PC-TFTReaktif KompanzasyonModbus RTU9600
Varkombi18-PC-TFTReaktif KompanzasyonModbus RTU9600
SofarHYD 3-6KHibrit İnvertörModbus RTU9600
SofarKTLX-G3String İnvertörModbus RTU9600
MatismartMTM5MMCCB (Devre Kesici)Modbus RTU9600
ElectronovaPD194Z-9HEnerji AnalizörüModbus RTU9600

Not: Tüm cihazlar Modbus RTU protokolü ve 9600 baud rate ile iletişim kurar. Yeni cihaz desteği eklemek için ilgili marka/model için JSON template dosyası oluşturulmalıdır.


Register Map Yapısı

Template dosyaları JSON formatında register haritası tanımlar. Her template, cihazın Modbus register'larını gruplar halinde organize eder.

Template Yapısı

{
"templateId": "entes-rg3-12cs",
"manufacturer": "Entes",
"model": "RG3-12CS",
"groups": [
{
"groupId": "realtime",
"intervalMs": 5000,
"blocks": [
{
"startAddress": 4354,
"count": 60,
"functionCode": 3
}
],
"fields": [
{
"name": "voltage_l1",
"offset": 0,
"dataType": "float32",
"scaleFactor": 1.0,
"unit": "V"
},
{
"name": "current_l1",
"offset": 2,
"dataType": "float32",
"scaleFactor": 1.0,
"unit": "A"
}
]
}
]
}

Field Tanımı

Her field aşağıdaki özellikleri içerir:

AlanTipAçıklama
namestringMetrik adı (MQTT payload'da kullanılır)
offsetintBlock başlangıcından register offset'i
dataTypestringVeri tipi: uint16, int16, uint32, int32, float32
scaleFactorfloatÖlçek çarpanı (ör: 0.1 = değer/10)
unitstringBirim: V, A, W, kW, kWh, Hz, %, vb.

Function Code'lar

KodAdKullanım
3Read Holding RegistersYapılandırma ve durum register'ları
4Read Input RegistersSalt okunur ölçüm register'ları

Polling Interval Önerileri

Aşağıdaki aralıklar, veri güncellik ihtiyacı ve Modbus bus yükü dengesine göre belirlenmiştir.

GrupIntervalAçıklamaGerekçe
realtime5sVoltaj, akım, güç, güç faktörü (cosφ)Anlık izleme ve alarm tespiti için yüksek çözünürlük
power_totals5sToplam güç ve frekansDashboard'da gerçek zamanlı gösterim
energy_kwh60sEnerji sayaçları (kWh, kVArh)Sayaç değerleri yavaş değişir, sık okuma gereksiz
step_values30sKompanzasyon kademe değerleriKademe değişimleri orta hızda, aşırı yük oluşturmaz
ct_ratio24hCT/PT dönüşüm oranlarıSabit yapılandırma değerleri, nadiren değişir
bms_identity24hBMS kimlik bilgileri (seri no, SoH)Cihaz tanımlama, günde bir kez yeterli

Önemli: Aynı RS-485 bus üzerinde çok sayıda cihaz varsa, toplam polling döngü süresi hesaplanmalıdır. Her Modbus isteği ortalama 50-100ms sürer. 10 cihaz x 6 grup = 60 istek, bu da ~3-6 saniye demektir. Realtime grubunun 5s aralığına sığması için bus üzerindeki toplam cihaz sayısı dikkate alınmalıdır.


raw_modbus Buffer Sizing (Issue #245)

ESP32 firmware'inde raw modbus konfigürasyon parsing'i için kullanılan buffer'lar Sofar HYD entegrasyonu sonrası yetersiz kaldı ve SEV-1 OOM/heap-fragmentation incident'i yaşandı. Aşağıdaki buffer boyutları yeniden boyutlandırıldı.

Buffer Capacity Matrix

SembolEski DeğerYeni DeğerAçıklama
RAW_MAX_DEVICES412Aynı gateway'e bağlanabilecek maksimum cihaz (Sofar HYD + 11 ek)
RAW_MAX_BLOCKS1640Tüm cihazlar genelinde toplam register block sayısı (BMS register grupları artırdı)
RAW_CONFIG_DOC_SIZE4 KB24 KBDynamicJsonDocument pool boyutu (template payload artışı)

ArduinoJson Slot Hesabı

ArduinoJson VariantSlot boyutu platform-bağımlıdır:

PlatformVariantSlotHesap
ESP32 (target)~20 byte/slot24 KB / 20 = 1200 slot
Native test (host)~32 byte/slot24 KB / 32 = 750 slot

Native test ortamında ArduinoJson daha kalın slot kullanır; bu yüzden CI'da pio test -e native cold path test verisi 750 slot altında tutulmalıdır.

MQTT Payload Limit Hizalaması

Buffer pool boyutu, Celery rawconfig payload limitleri ile uyumludur:

  • RAWCONFIG_SIZE_SOFT=12 KB — backend warning, gateway tarafında hâlâ tek payload
  • RAWCONFIG_SIZE_HARD=20 KB — backend chunked publish, gateway reassembly
  • RAW_CONFIG_DOC_SIZE=24 KB — gateway'in tek seferde tutabileceği maksimum (SOFT limit + buffer + chunked reassembly margin)

Toplam pool 24 KB; 1200 slot ile MQTT payload max 12 KB (SOFT) / 20 KB (HARD reassembly) yapılarına %20 margin sağlar.

NACK/ACK Semantik — ModbusPauseGuard

cmd/read_group MQTT komutu geldiğinde Modbus polling geçici olarak duraklatılır (aksi halde ana polling task ile manuel okuma birbirine girer). Bu, RAII pattern'i ile garanti edilir:

class ModbusPauseGuard {
public:
ModbusPauseGuard() { pollingMutex.lock(); pollingPaused = true; }
~ModbusPauseGuard() { pollingPaused = false; pollingMutex.unlock(); }
};

void onReadGroupCommand(const String& groupId) {
ModbusPauseGuard guard; // Lock alınır
// ... Modbus okuma işlemi
publishMqttResponse(result);
// guard scope çıkışında otomatik unlock
}
OlayMQTT Yanıt
Komut başarılıack payload'ı (data ile birlikte)
Modbus timeoutnack payload'ı (reason: "timeout")
CRC hatasınack (reason: "crc")
Buffer overflownack (reason: "buffer_full")

Issue #245 SEV-1 Özeti

Sofar HYD template'inin BMS register grupları (5.10.x) eklendiğinde toplam block sayısı RAW_MAX_BLOCKS=16 limitini aştı. Sonuç: parse fail → cihaz config silently corrupt → 7 saha gateway'inde polling durdu. Düzeltme: yukarıdaki buffer artışları + native test'e regression case eklendi.

Detaylı incident postmortem için Issue #245'e bakınız.