Yeni Nesil IoT Tabanlı PDKS: MQTT, Spring Boot ve React ile Gerçek Zamanlı Personel Takibi
Merhaba, ben Ahmet Hilmi Güler. Sakarya Üniversitesi Yazılım Mühendisliği öğrencisiyim. Bu yazıda, Elfatek Teknoloji A.Ş. Ar-Ge bölümünde gerçekleştirdiğim staj kapsamında geliştirdiğim PDKS (Personel Destek Kontrol Sistemi) projesinden bahsedeceğim. Keyifli okumalar 🙂
Projenin Amacı ve Geleneksel Sistemlerden Farkı
PDKS sistemleri, şirketlerin güvenlik ve insan kaynakları operasyonlarının kalbinde yer almasına rağmen, geleneksel sistemler genellikle hantal, gerçek zamanlı veriden uzak ve sadece ‘sabah giriş – akşam çıkış’ mantığıyla çalışan yapılardır. Günümüzde ise devasa tesisler, iç içe geçmiş departmanlar ve esnek çalışma modelleri, çok daha akıllı ve dinamik bir çözümü zorunlu kılıyor. Staj sürecim boyunca baştan sona mimarisini tasarlayıp geliştirdiğim projede tam olarak bu ihtiyaca odaklandım: Nesnelerin İnterneti (IoT) cihazlarıyla MQTT protokolü üzerinden milisaniyeler içinde haberleşen, personelin şirket içindeki mikro hareketlerini (ofis/bölge değişimlerini, mola giriş-çıkış saatlerini) adım adım izleyen, ‘Bölge Bazlı Anti-Passback’ gibi gelişmiş güvenlik kuralları barındıran ve tüm bu devasa veriyi React ile modern, anlaşılır, gerçek zamanlı grafiklere dönüştüren yeni nesil bir Personel Devam Kontrol Sistemi geliştirdim.
Mimari Tasarım ve Teknoloji Yığını (Tech Stack)
-
Haberleşme Katmanı (MQTT): MQTT, sınırlı bant genişliği ve sınırlı işlem kaynaklarına sahip kısıtlı ağlarda iletişim için orijinal olarak tasarlanmış hafif, düşük gecikmeli ve güvenli bir mesajlaşma protokolüdür.
Edge (uç) cihazlar olan kart okuyucuların sunucuyla HTTP üzerinden haberleşmesi, hem ağ yükü hem de hız açısından verimsizdir. Çünkü HTTP’de istemci, sunucudan veri ister (request), sunucu veriyi gönderir (response) ve sonrasında bağlantı kapanır. Bunun aksine MQTT kalıcı TCP bağlantısı kullanır. Bu sebeplerden dolayı düşük gecikme (low-latency), hafif paket boyutu ve QoS (Quality of Service) gibi avantajları nedeniyle MQTT protokolünü kullandık.MQTT, Üç farklı Hizmet Kalitesi (QoS) seviyesi destekler: QoS 0, QoS 1 ve QoS 2. Biz PDKS projemizde QoS 1 kullandık. QoS 1, mesajların en az bir kez iletilmesini sağlar; yani mesajlar onaylanır ve gerekirse yeniden gönderilir. QoS 1 kullanıldığında, Publisher mesajı broker’a gönderir ve devam etmeden önce onay bekler. Eğer broker belirlenen süre içinde yanıt vermezse, yayıncı mesajı tekrar gönderir.
-
Backend (Spring Boot & PostgreSQL): İş kurallarının (Business Logic) işletildiği backend tarafında, Java ve Spring Boot kullanarak MQTT Broker ile (test süreçlerimizde kullandığımız) MQTTX platformu arasındaki gerçek zamanlı veri alışverişini sağlayan temel yapıyı kurduk. Bu katmanda, IoT cihazlarından gelen ham geçiş verilerini anlık olarak işleyip logların veritabanına yazılmasını sağladık. Eşzamanlı olarak, web arayüzü üzerinden gelen (yeni cihaz tanımlama, personel ekleme, yetkilendirme gibi) yönetimsel verilerin PostgreSQL veritabanına güvenli ve tutarlı bir biçimde kaydedilmesini yönettik. Tüm bu süreçleri Model-DTO-Controller-Service-Repository mimarisi ile inşa edip, SoC (Separation of Concerns) prensiplerine sadık kalarak son derece modüler ve genişletilebilir bir altyapı oluşturduk.
-
Frontend (React & Tailwind CSS): Kullanıcı deneyimini (UX) bölmemek için SPA (Single Page Application) mimarisini kullandık. Karmaşık veri setlerini Recharts ile görselleştirdik.
Gelişmiş Güvenlik ve Geçiş Kontrolü (Access Control)
Fiziksel güvenliği sağlamak adına geleneksel kuralları esnetip, modern iş yerlerine uygun algoritmalar geliştirdik:
Geleneksel sistemlerde personel girdiği kapıdan çıkmadan başka bir işlem yapamaz. Biz bunu “Bölge Bazlı” hale getirdik. Personel zaten “Üretim” bölgesindeyse tekrar Üretim’e giremez (kartını başkasına vermiş olabilir), ancak doğrudan “Yönetici Ofisi”ne geçiş yapabilir.

(Anti-Passback İhlali Örnek Görsel)
İç bölgelerdeki bu esnekliğin bir zafiyet doğurmaması için katı bir kural ekledik. Sistemde güncel konumu “Dışarıda” görünen bir personel, şirketin iç ofis kapılarından okutma yapamaz; güne mutlaka dış dünya ile bağlantılı bir ana kapıdan başlamak zorundadır.

(Son konumu dışarısı olan personel, ilk önce ana kapıdan giriş yapmalıdır.)
Şirketlerdeki bazı kart okuyucular tek yönlü (sadece giriş veya sadece çıkış) hizmet verirken bazı kart okuyucular çift yönlüdür (yani aynı kart okuyucu hem giriş hem çıkış işlemini kontrol eder). Mimariye esneklik katmak adına Device modelimize dynamicDirection ve deviceDirection parametrelerini ekledik. Eğer bir cihaz fiziksel olarak çift yönlü çalışıyorsa (dynamicDirection = true), cihazdan gelen veride yön bilgisi olmasa bile sistem personelin mevcut bulunduğu bölgeye (Zone) bakarak bu geçişin bir “Giriş (IN)” mi yoksa “Çıkış (OUT)” mı olduğunu algoritmik olarak anında tespit ediyor. Tek yönlü cihazlarda ise deviceDirection parametresi (deviceDirection = EventType.IN gibi) ile donanımın sabit yönünü sisteme tanıtarak donanım ve yazılımın senkronizasyonunu sağladık.

Yön bağımsız bir algoritma geliştirerek, personel tarafından yapılabilecek ardışık çift okutmaların (Duplicate Tap) cihazın yön parametrelerini bozmasını engelledik ve zamana dayalı bir filtreleme uyguladık. Eğer bir personel aynı cihazda 5 saniye içerisinde 2 defa kart okutursa kapıyı açık tutmaya devam ettik (ALLOW mesajı gönderildi).
(Çift yönlü bir kapıda çift okutma kontrolü)
IoT dünyasında cihazların bağlantısının kopması kaçınılmazdır. Kart okuyucu cihazın elektrik veya ağ bağlantısı koptuğunda, MQTT’nin LWT (Last Will and Testament) özelliği sayesinde broker anında backend’i bilgilendirir. Ayrıca geçici ağ kopmalarında veri kaybı yaşamamak adına QoS=1 ve cleanSession=false ayarlarıyla cihaz çevrimdışıyken bile mesajların broker’da kuyruklanmasını sağladık.

Veriyi Anlamlandırmak: Algoritmalar ve Raporlama
Şirket bünyesindeki departmanlar; gündüz, gece veya esnek saatler gibi çeşitli vardiyalarda çalışıyor olabilir ve her vardiyanın kendine özgü çalışma periyotları ile mola süreleri bulunur. Geliştirdiğimiz sistem sayesinde İK personeli, web arayüzü üzerinden istedikleri kadar vardiya tanımlayabiliyor ve bu vardiyalara özel yasal mola saatleri atayabiliyor.

İşin mühendislik açısından en zorlu kısımlarından biri, veritabanında Log tablosunda biriken binlerce satırlık ham geçiş loglarını bu dinamik vardiya kurallarıyla çaprazlayarak totalInsideMinutes (toplam içeride kalma), lateArrivalMinutes (geç kalma), authorizedOutsideMinutes (yasal mola) gibi anlamlı ve kesin İK metriklerine dönüştürmekti. Bu sorunu çözmek için Timeline algoritması yazdık: Personel saat 08:00’de girip 18:00’de çıktığında, veritabanında devasa bir 10 saatlik “İçeride” bloğu oluşur. Yazdığımız makaslama algoritması ile; personelin gün içindeki şirket içi ofis geçişlerini (INTERNAL) ve İK tarafından atanan resmi mola saatlerini birer kesme noktası (checkpoint) olarak kullandık. Bu sayede tek parça halinde duran günlük çalışma süresini “Üretim (2 saat) -> Mola (15 dk) -> Ar-Ge (3 saat)” şeklinde dinamik, okunabilir ve anlamlı alt parçalara böldük.
Frontend: Büyük Veriyi Şık ve Anlaşılır Kılmak (UI/UX)
Kullanıcıya sunmamız gereken bunca karmaşık analitik veriyi, ekranı boğmadan bir dashboard’da sunmamız gerektiğinde kritik tasarım kararları aldık. Özellikle personelin gün içindeki yoğun şirket içi hareketliliğini tek bir ekrana sığdırırken görsel bir kaosa yol açmamak için şu mimarileri kurduk:
Zaman çizelgesinde (Timeline) şirket içerisindeki her bir bölgeye rastgele farklı bir renk atamak, dar bir alanda göz yoran “renkli bir barkod” görünümüne sebep oluyordu. Bunu engellemek için özel bir Deterministik Renk Algoritması (Hash-to-HSL) yazdık. Bu algoritma, bölge isimlerini (Örn: A-Blok Üretim) ASCII değerleri üzerinden matematiksel bir hash’e, ardından da HSL renk uzayına çeviriyor. Renk özünü (Hue) yeşil ve turkuaz tonlarına sabitleyerek, sistemdeki tüm çalışma alanlarının birbirine yakın, kurumsal ve soft (pastel) tonlarda üretilmesini garanti altına aldık.
Dar alanda veri sunmanın en büyük zorluğu olan “küçük zaman dilimlerinin okunamazlığı” problemini CSS tabanlı tooltipler ile çözdük. Ekranda metin kalabalığı yaratmak yerine, 1-2 dakikalık mikro geçişleri bile sadece imleç üzerine geldiğinde (hover) açılan, bölge adı ve net süre bilgilerini içeren şık detay kartlarına gizledik.

(Bir çalışana ait günlük çalışma-mola-geç geliş/erken çıkış sürelerini gösteren dashboard)
Timeline Bar’da gördüğünüz kırmızı renkler, personelin geç giriş-erken çıkışlarını gösterirken, sarı renkli alanlar yasal mola sürelerini, mavi-turkuaz renkler ise şirket içi ofisler arasındaki geçişlerini gösterir.
İK yetkililerinin personelin anlık yerini görebilmesi için React üzerinde HTTP Polling mekanizması kurduk. Sayfayı yenilemeye gerek kalmadan, her 5 saniyede bir arka planda sessizce atılan isteklerle arayüzdeki yeşil “radar” noktası güncellendi.
Günlük ve haftalık devasa verileri aynı sayfada sunabilmek için React’ın SPA (Single Page Application) özelliğinden yararlandık. Sekme (Tab) mantığı ile sayfalar arası geçiş yükünü ortadan kaldırdık. Haftalık analizler için Recharts kütüphanesi kullanılarak “Yığılmış Çubuk Grafik (Stacked Bar Chart)” geliştirdik. Yeşil (Net Çalışma), Sarı (Yasal Mola) ve Kırmızı (İhlaller/Kayıp Zaman) alanlar dar bir yatay eksende üst üste bindirilerek, 7 günlük performansı tek bakışta okunabilir hale getirdik.

(Bir çalışana ait haftalık çalışma-mola-geç geliş/erken çıkış sürelerini gösteren dashboard.)
Geliştirdiğimiz bu dashboard ekranları sayesinde İK personeli veya şirket yöneticileri, çalışanlarının verimliliğini ve anlık konumlarını tek bir ekrandan görebilecek, haftalık performanslarını analiz edebilecektir.
Sonuç
Bu proje, MQTT mesaj yapısından, Backend’in karmaşık veri tabanı optimizasyonlarına ve oradan da Frontend’in modern kullanıcı deneyimi tasarımlarına uzanan tam teşekküllü bir mühendislik yolculuğuydu.
Bu süreçte; Clean Code prensiplerini, kod tekrarını önlemeyi (DRY), state yönetimindeki ince detayları ve müşteri/kullanıcı ihtiyaçlarını bir sistem tasarımına nasıl dönüştüreceğimi öğrendim.
Staj süresince çalışmalarımızda bilgi ve deneyimleriyle destek olan Elfatek Teknoloji A.Ş. Ar-Ge ekibine teşekkür ederim.
Ahmet Hilmi Güler
Sakarya Üniversitesi Yazılım Mühendisliği