Tarımsal sulama · IoT · NB-IoT

İnternet olmasa bile
motor korunur.

BOCU BC-01, tarımsal sulamada kullanılan 3 fazlı dalgıç ve dinamo pompaları uzaktan izleyen, koruyan ve kontrol eden bir cihazdır. Koruma kararı cihazın kendisindedir; sunucu koruma kesmesi yapmaz — konfigürasyonun kaynağı, kayıt tutucusu ve kullanıcı arayüzüdür. Bu sayfadaki demo, cihazla sunucu arasındaki gerçek MQTT protokolünü birebir uygular.

3 fazakım + gerilim
60 sntelemetri aralığı
0.1 Aölçüm çözünürlüğü
HMACimzalı komut
19olay kodu
Python 3.12 · FastAPI EMQX (MQTT 3.1.1) aiomqtt · asyncpg Supabase (Postgres + RLS) React Native · Expo Arduino Nano + SIM7020E Docker Compose · Caddy
Koruma zinciri şeması Şebekeden gelen üç faz BC-01 cihazında ölçülüp korunuyor ve kontaktörün A1 bobini üzerinden pompayı sürüyor. Buluta giden hat kopsa bile bu zincir cihazın içinde kapanıyor. 3 FAZLI ŞEBEKE R S T BC-01 akım + gerilim ölçümü koruma lojiği · gecikme kesme kararı · kilit KONTAKTÖR A1 bobin kumandası POMPA / MOTOR 3 fazlı dalgıç · dinamo bu zincir cihazın içinde kapanır kopabilir BULUT broker · sunucu telefon izleme · ayar · kayıt koruma kararı burada verilmez
Koruma kararı cihazın içindedir. Sağdaki kol yalnızca izleme, ayar ve kayıt içindir;
kapsama gitse de motorun koruması çalışmaya devam eder.

İnteraktif Demo

senaryoyu seç, cihazı kendin kontrol et

Aşağıdaki telefon uygulamayı, yanındaki günlük ise telefonla cihaz arasında gerçekten akan MQTT trafiğini gösterir. Payload'lar protokol sözleşmesindeki birebir formattır: akım desiamper, gerilim volt, zaman UTC epoch saniye. Demo hızlandırılmıştır — telemetri 60 sn yerine 2 sn'de bir, ACK zaman aşımı 90 sn yerine 8 sn'de dolar.

09:41◍ ▮▮▮ ▰
Tarla Pompası 1BC01-2504001
ÇEVRİMİÇİ
DURDU
röle kapalı · koruma: otomatik

AKIM (A)

ortalama: 0.0 A

GERİLİM (V)

ortalama: 227 V

UZAKTAN KONTROL

hazır

KORUMA MODU

otomatik: limit aşılınca cihaz röleyi keser

Senaryo

simülatörün gerçek senaryolarıyla aynı adlar

Kablo üzerinde ne oluyor

b/{id}/t · e · s · c · a · g

  • bağlantı kuruluyor…

Komut kuyruğu

uygulama satır yazar, köprü imzalar

  • henüz komut yok
Neden böyle? Uygulama komutu doğrudan cihaza göndermez; commands tablosuna queued satırı yazar. HMAC anahtarı yalnızca köprüde durur, telefona hiç inmez — çalınan bir oturumla pompa çalıştırılamaz. ACK 90 saniye beklenir, gelmezse komut timeout olur ve otomatik tekrar gönderilmez: sessizce tekrarlanan bir röle komutu sahada tehlikelidir.

Sistem

cihazdan telefona kadar
BC-01 (Arduino Nano + SIM7020E NB-IoT)
   │  MQTT / Turkcell M2M
   ▼
EMQX Broker ──────► ingest worker ──► Postgres (Supabase) + bölümlenmiş telemetri
   ▲                     │
   │                     └────────► notifier worker ──► Expo Push (FCM / APNs)
   │
   ├─ commander worker ◄── commands tablosu ◄──── RN Expo uygulaması
   │                                                    │
   └─────────── MQTT over WSS (canlı veri) ─────────────┘
Kısıt

2 KB RAM'e sığan protokol

Cihaz tarafı Arduino Nano: 2 KB RAM, 32 KB flash, RTC yok, yedek besleme yok. Payload'lar bu yüzden tek harfli alanlarla yazıldı ve ölçüler tam sayı tutuluyor.

  • Akım desiamper — 52 = 5,2 A
  • Saat sunucudan: time komutu, tv=0 iken zamanlayıcı çalışmaz
  • Offline eşiği 200 sn (telemetri 60 sn)
Sınır

Koruma kararı cihazda

Sunucu hiçbir koşulda röle kesmez. Şebeke veya kapsama gittiğinde motorun korumasız kalmaması ürünün ana vaadi; bu yüzden karar zinciri buluta bağlanmadı.

  • Sunucu yalnızca kayıt, konfigürasyon ve arayüz
  • Kesme sonrası röle kilitli kalır, latch_reset ister
  • Kilitliyken gelen relay:1 cihazda reddedilir
  • Röle geri beslemesi yok: "gerçekten çalıştı mı" sorusu akım ölçümüyle doğrulanır (NOLOAD)
Güvenlik

Sırlar ayrı tabloda

RLS satırları filtreler, sütunları değil. Kendi cihazını görebilen kullanıcı aynı satırdaki imza anahtarını da okuyabiliyordu; ilk RLS test koşusunda iki test bunu yakaladı.

  • hmac_key, secret_hash, claim_code → device_secrets
  • Bu tabloda istemci politikası yok, yalnızca service_role
  • Yerel Postgres'e karşı koşan 20 RLS testiyle doğrulanıyor

Protokol Sözleşmesi

firmware ekibiyle ortak, tek taraflı değişmez

Cihaz firmware'ini harici bir ekip yazıyor. Entegrasyon gününde "kimin hatası" tartışmasını bitirmek için protokol tek bir dokümana yazıldı, simülatör de sunucuyla aynı protokol modülünü kullanıyor: simülatörün yaptığı şey, tanımın kendisi.

TopicYönQoSRetainedİçerik
b/{id}/tcihaz → sunucu0hayırTelemetri, 60 sn
b/{id}/ecihaz → sunucu1hayırAlarm / olay, seq ile tekrar elenir
b/{id}/scihaz → sunucu1evetDurum özeti + LWT ({"o":0})
b/{id}/csunucu → cihaz1hayırHMAC imzalı komut
b/{id}/acihaz → sunucu1hayırKomut ACK'i
b/{id}/gsunucu → cihaz1evetKonfigürasyon, cv sürümlü
ACL: cihaz yalnızca kendi {id} ağacına yazabilir. Mobil istemci JWT ile bağlanır, yetkili olduğu cihazların t/e/s/a topic'lerini yalnızca okur — telefondan hiçbir şeye yazılamaz.

Gidişat

son güncelleme: 8 Eylül 2026

Proje kapalı test aşamasında: sunucu tarafı bir sunucuda konteyner olarak 7/24 çalışıyor, mobil uygulama kapalı teste dağıtıldı ve bir cihaz sahada gerçek bir üç fazlı pompaya bağlı. Her fazın kendi kabul kriterleri var; kriterler geçmeden sonraki faza geçilmiyor.

KatmanDurum
Protokol + simülatörTamam. Protokol tek bir modülde tanımlı; sahte cihaz 14 senaryo koşuyor (overcurrent, dry_run, phase_loss, no_ack, bad_hmac, offline_queue ve diğerleri). Bu sayfadaki demo bunlardan altısını tarayıcıda canlandırır. Ayrıca bir kabul aracı gerçek cihazı dinleyip 25 protokol maddesini tek tek derecelendiriyor.
Veritabanı + yetkilendirmeSupabase üzerinde canlı. Cihaz sahiplenme, cihaz paylaşımı, hesap silme, bölümlenmiş telemetri, konfigürasyon/zamanlayıcı ve abonelik şeması uygulandı. RLS politikaları 53 testle korunuyor.
Sunucu servisleriBeş konteyner ayakta: EMQX, Redis, ingest, komutçu, bildirim. Yanlarında bir izleyici var — sağlıklıyken susuyor, yalnızca müdahale gerektireni bildiriyor ve aynı sebebi saat içinde tekrarlamıyor.
Komut yoluTamam. İmzalama, ACK takibi, 90 saniyelik zaman aşımı, retained konfigürasyon yayını ve saat senkronu. Cihaz başına aynı anda tek röle komutu tutuluyor; yenisi gelince eskisi bekletilmeden iptal ediliyor — geç teslim edilen bir "aç" komutu boş tarlada pompayı kaldırır.
BildirimUçtan uca doğrulandı. FCM kurulu, cihaz jetonu kayıtlı; saha testinde 21 bildirim telefona düştü.
Mobil uygulama15 ekran, 5 sekmeli navigasyon: canlı ölçüm, cihaz listesi, alarmlar, grafikler, olay geçmişi, haftalık zamanlayıcı, cihaz ayarları, cihaz paylaşımı ve hesap. Giriş e-posta, Google veya Apple ile; parola sıfırlama ve hesap silme dahil.
Test237 test: RLS 53, protokol 39, komutçu 38, ingest 32, bildirim 30, protokol uyumluluğu 20, sahiplenme 9, provisioning 7, simülatör 7, sağlık 2. ruff + mypy --strict temiz.

5 Eylül 2026 — ilk saha testi. O güne kadar her şey tezgâhta, ısıtıcı yüküyle denenmişti. Cihaz tarlaya götürülüp gerçek bir üç fazlı pompaya bağlandı; korumaların hepsi gerçek yükte tetiklendi. Tezgâhta günlerce sıfır okuyan gerilim ölçümü de burada kapandı — sahada üç faz da okudu.

KanıtlananÖlçüm
Üç faz gerilim + akım240 / 240 / 239 V, 31 A
Uzaktan aç / kapatMotor komutu izledi; kalkış akımı 24.3 → 31.1 A yakalandı
Aşırı akım korumasıOC — 30.6 A, limit 6.9 A: kesti ve kilitledi
Düşük akım korumasıUC — 0.1 A, limit 8.0 A: kesti
Faz kaybıPL — R fazı, alan seti şartnameye tam uygun
Çalıştırma reddiNOSTART — 241 V, limit 240: çalıştırmadı, kilitlemedi
Bildirim zinciri21 bildirim telefona düştü
Komut başarısı64 komut onaylandı (%77); kaybolan komut yok, düşenlerin sebebi saat gecikmesi
Bu sayfadaki demo ne gösteriyor? Demo, uygulamanın akışını tarayıcıda canlandıran bağımsız bir maket: gerçek protokolün senaryolarını çalıştırır ama sahadaki cihaza bağlı değildir. Sahadaki sistem mobil uygulamadan kullanılıyor; buradaki demo, aynı akışın kimse bir pompaya bağlanmadan denenebilen hâli.
Faz 0 — Tamamlandı

Monorepo, docker-compose (EMQX, Redis, Caddy), .env.example, ruff/mypy/pytest, Expo projesi, CI.

Faz 1 — Tamamlandı

Protokol modülü (encode/decode, HMAC, birim dönüşümleri), sahte cihaz simülatörü, firmware ekibine verilen protocol.md.

Faz 2 — Tamamlandı

Şema, RLS, kimlik doğrulama, cihaz sahiplenme (QR/claim kodu) ve üretim provisioning script'i. Mimari burada Supabase'e taşındı: auth ve CRUD hazır alındı, kendi servisimiz "köprü" boyutuna indi.

Faz 3 — Tamamlandı

Ingest worker, telemetri doğrulama, seq tabanlı tekrar eleme, aylık bölümlenmiş telemetri tablosu.

Faz 4 — Tamamlandı

Komut yolu ve konfigürasyon senkronu: imzalama, ACK, zaman aşımı, pending/applied/failed durumları, saat senkronu.

Faz 5 — Tamamlandı

Bildirim worker'ı: FCM push, alarm cooldown'ı, normale dönüş bildirimi, LINK_LOST gecikmesi. Saha testinde uçtan uca doğrulandı.

Faz 6 — Tamamlandı

Mobil temel: giriş, cihaz listesi, dashboard, canlı veri, röle kontrolü, kilit akışı, QR ile cihaz ekleme.

Faz 7 — Tamamlandı

Mobil ayarlar, haftalık zamanlayıcı, grafikler, alarm ve olay listesi, cihaz paylaşımı, hesap silme.

Faz 8 — Şu an burada

Kapalı test ve sertleştirme: rate limit, metrik, yedekleme, yük testi, mağaza hazırlığı. Uygulama kapalı test dağıtımında, sistem sahada gerçek bir pompayla çalışıyor.

Açık madde

Elektrik kesintisi

Cihazda yedek besleme yok. Süperkapasitör olmadan "elektrik kesildi" (PF) mesajı üretilemez; sunucu bu durumda yalnızca LINK_LOST diyebilir, yani şebeke kesintisi ile kapsama sorunu ayırt edilemez. Protokol iki durumu da destekliyor, karar donanım tarafında.

Açık madde

Yapışmış kontaktör alarmı

Uygulamanın gönderebileceği en ağır mesaj bu — kişiden tarlaya gidip şalteri indirmesini ister. Cihaz değerlendirmeyi röleyi açtıktan hemen sonra yaptığı için kaçak akımda da tetikleniyordu. Sunucu artık ölçümüyle çelişen alarmı telefona taşımıyor; kalıcı çözüm, kararın kesmeden birkaç saniye sonra ve üst üste birkaç örnekle verilmesi.

Açık madde

Sinyal

Saha kurulumunda sinyal sınırda ölçüldü (CSQ 2–8). Koruma bundan etkilenmiyor — karar cihazın kendisinde, internet gitse de motor korunur — ama uzaktan kontrolün güvenilir olması için antenin metal panonun dışına alınması gerekiyor.