← Vaka Çalışmalarına Dön (Dosya 01)
2024–2025
Plasmon: 100K+ Edge Cihaz İçin Telemetri Mimarisi
ESP32 firmware, MQTT/TLS RPC, yerel ring-buffer ve RabbitMQ ingest hattı
100K+ cihaz mimarisi · Saha hücresel failover doğrulaması
Yığın: ESP32 (C/FreeRTOS) · Modbus RTU/TCP · MQTT over TLS · RabbitMQ · WebSocket · OpenAPI
1. Bağlam
Plasmon, endüstriyel soğutma ve iklimlendirme ünitelerinin saha koşullarında kesintisiz izlenmesi ve uzaktan parametre yönetimi amacıyla tasarlandı. Bu mimari, 100K+ edge cihaz için tasarlandı; saha donanımından merkezi bulut broker’ına kadar olan telemetri ve komut-kontrol zincirini uçtan uca kapsar.
2. Problem
Endüstriyel sahada iki büyük zorluk vardı:
- Güvenilmez Hücresel Bağlantı: Fabrikalarda ve uzak tesislerde GSM/4G bağlantısı sık sık dalgalanıyor, saatlik baz istasyonu kesintileri yaşanıyordu. Geleneksel HTTP yoklamaları (polling) bellek taşmalarına ve veri boşluklarına yol açıyordu.
- Çift Yönlü İletişim ve OTA: Cihazların sadece veri göndermesi değil; acil durumlarda set-değeri değiştirebilmesi, Modbus register’larına komut yazabilmesi ve uzaktan firmware (OTA) güncellemelerini güvenle alması gerekiyordu.
3. Mimari ve Veri Akışı
[ Sensör & Chiller ]
│ (RS-485 / Modbus RTU)
▼
┌────────────────────────────────────────────────────────┐
│ ESP32 Edge Gateway (FreeRTOS) │
│ ┌───────────────────┐ ┌───────────────────────┐ │
│ │ Modbus Poller │───────►│ SPIFFS Ring-Buffer │ │
│ │ (Core 0, 1000ms) │ │ (Ağ yokken kalıcı flaş)│ │
│ └───────────────────┘ └──────────┬────────────┘ │
│ │ │
│ ┌───────────────────┐ │ Bağlantı │
│ │ MQTT Client (TLS) │◄──────────────────┘ Gelince │
│ └─────────┬─────────┘ │
└───────────┼────────────────────────────────────────────┘
│ MQTT/TLS (QoS 1) - GSM 4G / Wi-Fi
▼
┌────────────────────────────────────────────────────────┐
│ Ingestion & Broker Layer │
│ ┌───────────────────┐ ┌───────────────────────┐ │
│ │ EMQX / Mosquitto │───────►│ RabbitMQ Telemetry │ │
│ │ TLS Broker │ │ Topic Exchanges (DLX) │ │
│ └───────────────────┘ └──────────┬────────────┘ │
└─────────────────────────────────────────┼──────────────┘
▼
[ TimescaleDB & WebFlux ]
4. Kararlar ve Elenen Alternatifler
- ESP32 + C (FreeRTOS) seçildi, Raspberry Pi / Embedded Linux elendi: Endüstriyel panolarda 70°C üzeri sıcaklık, anlık voltaj kesilmelerinde SD kart bozulması ve 3W+ enerji tüketimi nedeniyle gömülü Linux uygun değildi. ESP32 donanımsal watchdog ve statik bellek tahsisiyle 7/24 deterministik çalışır.
- MQTT/TLS (QoS 1) seçildi, HTTP REST elendi: REST çağrıları her paket için yeni TCP ve TLS el sıkışması açarak GSM kotasını hızla tüketiyordu. MQTT persistent connection sayesinde tek bağlantı üzerinden kompakt ikili/JSON telemetri akıtıldı; Last Will & Testament (LWT) ile anlık bağlantı kopmaları gecikmesiz algılandı.
- Kuyruk katmanında RabbitMQ seçildi, Kafka ertelendi: Cihaz bazında komut-yanıt (RPC) kalıpları, routing key esnekliği ve düşük operasyonel bakım maliyeti nedeniyle RabbitMQ tercih edildi.
5. Gerçek Kod: Flash Ring-Buffer ve Telemetri Paketi
Aşağıdaki C parçası, ağ koptuğunda telemetriyi heap yerine flaş dairesel tampona yazan ve bağlantı kurulduğunda boşaltan mantığın çekirdeğidir:
#include "esp_spiffs.h"
#include "esp_log.h"
#define TELEMETRY_RING_FILE "/spiffs/ring_buf.bin"
#define MAX_BUFFER_ENTRIES 2048
typedef struct __attribute__((packed)) {
uint32_t timestamp;
int16_t temp_chiller_x10;
int16_t temp_ambient_x10;
uint16_t pressure_bar_x100;
uint8_t compressor_state;
uint8_t crc8;
} TelemetryFrame;
esp_err_t ring_buffer_push(const TelemetryFrame *frame) {
FILE *f = fopen(TELEMETRY_RING_FILE, "a+b");
if (!f) {
ESP_LOGE("RING", "Flaş dosya açılamadı");
return ESP_FAIL;
}
// Boyut sınırını denetle: MAX_BUFFER_ENTRIES aşılırsa en eski bloğu başa sar
long size = ftell(f);
if (size >= (long)(MAX_BUFFER_ENTRIES * sizeof(TelemetryFrame))) {
// En eski kayıt üzerine yazma (wrap-around) stratejisi
fseek(f, 0, SEEK_SET);
}
fwrite(frame, sizeof(TelemetryFrame), 1, f);
fflush(f);
fclose(f);
return ESP_OK;
}
6. Sonuç ve Ölçülebilir Çıktılar
- Tasarım Kapasitesi: 100K+ edge cihaz eşzamanlı telemetri yayını için boyutlandırıldı.
- Doğrulanan Test Ölçeği: 10.000+ aktif sensör simülasyonu; p95 < 22ms broker ingest gecikmesi.
- Ağ Kesintisi Dayanımı: 4G hücresel hat kopsa bile 320KB dahili flaş ring-buffer yaklaşık ~48 saatlik telemetri kaydını RAM taşması yaşamadan sakladı; hat geldiğinde 0 paket kaybıyla kuyruğa boşaltıldı.
7. Neyi Farklı Yapardım?
- Başlangıçta telemetri paketleri için JSON formatı kullanmıştım. Paket başı ~180 bayt olan JSON, hücresel hatta ciddi bir maliyet getirdi. Baştan Protobuf veya saf packed struct ikili (binary) formata geçseydim hücresel bant tüketimini ilk günden %65 daha aşağı çekebilirdim.