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:
- UART mutex alınır
- Modbus RTU isteği gönderilir (FC 3 veya 4)
- Yanıt template'e göre parse edilir
- Per-group JSON oluşturulur
- TelemetryQueue'ya eklenir
- 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:
| Kademe | Eşik | Aksiyon |
|---|---|---|
| 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ı
| Grup | Aralık | İçerik |
|---|---|---|
| realtime | 5s | Voltaj, akım, güç, cos(φ) |
| power_totals | 5s | Toplam güç, frekans |
| energy_kwh | 60s | Enerji sayaçları |
| step_values | 30s | Kompanzasyon basamakları |
| ct_ratio | 24h | CT/PT konfigürasyon |
| bms_identity | 24h | BMS 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.
| Marka | Model | Tip | Protokol | Baud Rate |
|---|---|---|---|---|
| Entes | RG3-12CS | Enerji Analizörü | Modbus RTU | 9600 |
| Entes | RG20C | Enerji Analizörü | Modbus RTU | 9600 |
| Entes | RGSR-24S | Reaktif Kompanzasyon | Modbus RTU | 9600 |
| Kael | Energymeter-02 | Enerji Analizörü | Modbus RTU | 9600 |
| Kael | Multiser-01 | Multi Analizör | Modbus RTU | 9600 |
| Varkombi | 12-PC-TFT | Reaktif Kompanzasyon | Modbus RTU | 9600 |
| Varkombi | 18-PC-TFT | Reaktif Kompanzasyon | Modbus RTU | 9600 |
| Sofar | HYD 3-6K | Hibrit İnvertör | Modbus RTU | 9600 |
| Sofar | KTLX-G3 | String İnvertör | Modbus RTU | 9600 |
| Matismart | MTM5M | MCCB (Devre Kesici) | Modbus RTU | 9600 |
| Electronova | PD194Z-9H | Enerji Analizörü | Modbus RTU | 9600 |
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:
| Alan | Tip | Açıklama |
|---|---|---|
name | string | Metrik adı (MQTT payload'da kullanılır) |
offset | int | Block başlangıcından register offset'i |
dataType | string | Veri tipi: uint16, int16, uint32, int32, float32 |
scaleFactor | float | Ölçek çarpanı (ör: 0.1 = değer/10) |
unit | string | Birim: V, A, W, kW, kWh, Hz, %, vb. |
Function Code'lar
| Kod | Ad | Kullanım |
|---|---|---|
| 3 | Read Holding Registers | Yapılandırma ve durum register'ları |
| 4 | Read Input Registers | Salt 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.
| Grup | Interval | Açıklama | Gerekçe |
|---|---|---|---|
| realtime | 5s | Voltaj, akım, güç, güç faktörü (cosφ) | Anlık izleme ve alarm tespiti için yüksek çözünürlük |
| power_totals | 5s | Toplam güç ve frekans | Dashboard'da gerçek zamanlı gösterim |
| energy_kwh | 60s | Enerji sayaçları (kWh, kVArh) | Sayaç değerleri yavaş değişir, sık okuma gereksiz |
| step_values | 30s | Kompanzasyon kademe değerleri | Kademe değişimleri orta hızda, aşırı yük oluşturmaz |
| ct_ratio | 24h | CT/PT dönüşüm oranları | Sabit yapılandırma değerleri, nadiren değişir |
| bms_identity | 24h | BMS 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
| Sembol | Eski Değer | Yeni Değer | Açıklama |
|---|---|---|---|
RAW_MAX_DEVICES | 4 | 12 | Aynı gateway'e bağlanabilecek maksimum cihaz (Sofar HYD + 11 ek) |
RAW_MAX_BLOCKS | 16 | 40 | Tüm cihazlar genelinde toplam register block sayısı (BMS register grupları artırdı) |
RAW_CONFIG_DOC_SIZE | 4 KB | 24 KB | DynamicJsonDocument pool boyutu (template payload artışı) |
ArduinoJson Slot Hesabı
ArduinoJson VariantSlot boyutu platform-bağımlıdır:
| Platform | VariantSlot | Hesap |
|---|---|---|
| ESP32 (target) | ~20 byte/slot | 24 KB / 20 = 1200 slot |
| Native test (host) | ~32 byte/slot | 24 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 payloadRAWCONFIG_SIZE_HARD=20 KB— backend chunked publish, gateway reassemblyRAW_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
}
| Olay | MQTT Yanıt |
|---|---|
| Komut başarılı | ack payload'ı (data ile birlikte) |
| Modbus timeout | nack payload'ı (reason: "timeout") |
| CRC hatası | nack (reason: "crc") |
| Buffer overflow | nack (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.