Skip to main content

← Rule Service Ana Sayfası

Rule Service - Sık Sorulan Sorular

Durum ve Counter Yönetimi

S: Bir kural hem threshold hem duration koşuludur; duration sayacı ne zaman sıfırlanır?

A: Duration sayacı, eşik koşulu sağlanmadığında sıfırlanır. Eğer bir sonraki window'da koşul tekrar sağlanırsa, sayaç baştan başlar.

Örnek: VRMS_R > 250 for 600 seconds

T=0s: VRMS_R=260, condition=true, counter=50s
T=50s: VRMS_R=260, condition=true, counter=100s
T=100s: VRMS_R=240, condition=false, counter=0 (reset!)
T=150s: VRMS_R=270, condition=true, counter=50s (restart)
T=600s: VRMS_R=270, condition=true, counter=550s
T=650s: VRMS_R=270, condition=true, counter=600s → TRIGGER! ✓

Kural Değerlendirmesi

S: match_type=not tam olarak ne anlama gelir?

A: Gruptaki hiçbir kural true olmamalı. Tüm kurallar false ise grup=true, herhangi biri true ise grup=false.

match_type=not, 3 kural

Senaryo 1 (tümü false):
Rule1: false, Rule2: false, Rule3: false
Sonuç: Grup = TRUE ✓ (hiçbiri true değil)

Senaryo 2 (biri true):
Rule1: false, Rule2: true, Rule3: false
Sonuç: Grup = FALSE ✗ (Rule2 true, not koşulu bozuldu)

Kullanım örneği:
"Pompa çalışmıyor VE akım yok VE alarm yok → Normal durum" gibi
"tüm uyarıcı sinyaller sessiz" durumunu yakalamak için kullanılır

S: Bir grup içinde 5 kural var; tümü true ama match_type=any; ne olur?

A: Grup true olur ve tetiklenme aksiyonu çalışır. Erken çıkış (short-circuit) optimize için uygulanabilir ama tüm kurallar değerlendirilir.

match_type=any

Rule1: false
Rule2: true ← İlk true, ama diğerleri de kontrol edilir (audit için)
Rule3: true
Rule4: true
Rule5: true

Sonuç: Grup = true (any → en az 1 true yeterli)

S: multi_trigger=true ve cooldown_sec=300 ise ne olur?

A: Koşul her window'da sağlansa bile, son tetiklenme üstünden 300 saniye geçmeden yeni tetikleme yapılmaz.

Cooldown_Sec = 300

T=0s: Condition=true → Trigger! ✓ Last_Fired_Time = T+0
T=50s: Condition=true → Skip ✗ (250s cooldown kaldı)
T=200s: Condition=true → Skip ✗ (100s cooldown kaldı)
T=300s: Condition=true → Trigger! ✓ Last_Fired_Time = T+300
T=350s: Condition=true → Skip ✗ (yeniden cooldown başladı)

Kontrol: now() - Last_Fired_Time >= Cooldown_Sec. Last_Fired_Time buffer'da saklanır.


S: Grubun valid_from / valid_to penceresi dışında event gelirse ne olur?

A: Grup skip edilir; mevcut state değiştirilmez.

Grup: valid_from = "08:00", valid_to = "20:00"

Event timestamp = 22:30 → Pencere dışı → Grup skip
- Triggered durumu değiştirilmez
- duration_counter değiştirilmez
- Hiç event üretilmez

Event timestamp = 10:00 → Pencere içi → Normal değerlendirme

valid_from ve valid_to null ise her zaman aktif kabul edilir.


S: multi_trigger=false; aynı kural grubu aynı window'da iki kez tetiklenir se ne olur?

A: Sadece ilk tetiklenme kaydedilir. device_rule_state.is_triggered=true olduğunda, aynı window'da ikinci bir tetiklenme event'i üretilmez.

State: is_triggered = false

Window 1:
- Condition: true
- State change: false → true ✓
- Emit: rule.triggered.v1

Window 2:
- Condition: still true
- State change: none (already true)
- multi_trigger=false → NO event
- is_triggered remains true

Window 3:
- Condition: false
- State change: true → false ✓
- Emit: rule.reset.v1 (if notify_on_reset=true)

Publish ve Bildirim

S: Publish=false iken kural tetiklenir; ne olur?

A: Action tetiklenir (inbox mesajı gönderilir) ama push notification gönderilmez. Audit tablosuna yaz yapılır.

Kural: HighVoltage (trigger_action_plan_id=21)
Publish=false

Aksiyon Plan 21 içinde:
├─ Step 1: WhatsApp (channel=whatsapp)
├─ Step 2: Push (channel=push) ← Gönderilmeyecek!
├─ Step 3: Audit (channel=audit)
└─ Step 4: Email (channel=email) ← Gönderilecek

Sonuç: WhatsApp + Email + Audit yapılır, Push yok.

S: publish_bit=99 ne demek?

A: publish_bit=99 her zaman publish anlamına gelir. Diğer değerler (0-63) measurement_register.publish bitini kontrol eder.

publish_bit = 99
→ Her durumda mesaj publish edilir (measurement_register bit kontrolü yapılmaz)

publish_bit = 5
→ Sadece measurement_register.bit[5]=1 ise publish

Device Rule Buffer

S: Device rule buffer nedir?

A: Device Rule Buffer, bir (device_id, rule_group_id) çifti için tüm durum bilgisini tutan Redis object'idir.

Saklanan Veriler:

  • Register geçmişi (transition'lar için eski değer)
  • Duration counter'lar (her kural için)
  • Grup state (is_triggered, trigger_count)
  • Publish cache (measurement_register.publish snapshot)
  • Last accessed timestamp

TTL: 24 saat (güncelleme ile reset)

[Detay bkz: Device Rule Buffer Design - TBD]


Kural Priority'si

S: Rule priority ne zaman kullanılır?

A: Kural priority, bir grup içundeki kuralların değerlendirme sırasını belirler. Düşük sayı daha önceliklidir.

Grup: HighCurrentCheck (match_type=all)
├─ Rule1 (priority=0): IRMS > 50
├─ Rule2 (priority=1): i_imb < 20
└─ Rule3 (priority=2): duration >= 30s

Evaluation order: Rule1 → Rule2 → Rule3

AND logic: tüm kurallar true olmalı
If Rule1=false → short-circuit, Rule2/3 skip

Grup level priority:

GroupA (priority=1) → evaluated first
GroupB (priority=2) → evaluated second
GroupC (priority=3) → evaluated third

Aksiyon sırası da grup priority'ye göre

Register Transition

S: Register transition'da joker (*) nasıl çalışır?

A: Bit masking ile. 0x01** demek "ilk 2 bit 01, sonrası önemsiz" demek.

Rule: old_value=0x0101 → new_value=0x0111 (mask: 0xFF00)

Device Status Changes:
0x0100 → 0x0101: Matches ✓ (last 2 bit changed)
0x0101 → 0x0111: Matches ✓
0x0100 → 0x0110: No match ✗ (ilk 2 bit aynı kaldı)

State Persistence

S: device_rule_state ve rule_events arasındaki fark ne?

A:

  • device_rule_state: Güncel state (snapshot) - one row per (device_id, rule_group_id)

    • is_triggered: true/false
    • trigger_count: toplam tetik sayısı
    • last_trigger_time, last_reset_time
  • rule_events: Append-only audit log - her tetikleme/sıfırlama/reset bir satır

    • Event type: triggered, reset, notified, command_sent
    • Details JSON ile sebep kaydı
Senaryo: Kural 5 kez tetiklendi, 2 kez sıfırlandı

device_rule_state:
├─ is_triggered: false
├─ trigger_count: 5
├─ last_trigger_time: 2026-03-14 20:30:15Z
└─ last_reset_time: 2026-03-14 20:45:30Z

rule_events (append-only):
├─ Event 1: triggered, 2026-03-14 20:15:00Z
├─ Event 2: triggered, 2026-03-14 20:15:50Z
├─ Event 3: triggered, 2026-03-14 20:16:40Z
├─ Event 4: reset, 2026-03-14 20:45:25Z
├─ Event 5: triggered, 2026-03-14 20:20:00Z
├─ Event 6: triggered, 2026-03-14 20:20:50Z
└─ Event 7: reset, 2026-03-14 20:45:30Z

Cache ve Fallback

S: Redis'te kural yoksa ne olur?

A: DB'den yüklenir ve Redis'e cachelenir (TTL=24h).

Lookup Order:
1. Redis: rule:{group_id}
└─ Found → Use immediately (Fast path ~1-5ms)
└─ Not found → Step 2

2. PostgreSQL: SELECT * FROM rule_groups WHERE id=X
└─ Found → Load to Redis (TTL=24h), use
└─ Not found → Error, skip evaluation

Operasyon Notları

S: Kural değişikliğinde ne olur?

A: Cache invalidation yapılmalı. Yaklaşım:

  1. Rule tanımı PostgreSQL'de update edilir
  2. Redis cache key'den sil (DEL rule:{group_id})
  3. Sonraki evaluation'da DB'den yeni tanım yüklenir

Not: rule_hash alanı değişiklik tespit etmek için kullanılır.


S: Cooldown nedir?

A: Aynı grubu çok hızlı tetiklemekten korumak için. multi_trigger=true ise zorunlu.

group.cooldown_sec = 300

T=0s: Condition true → Trigger Event ✓
T=50s: Condition still true → Skip (300s cooldown'da)
T=200s: Condition still true → Skip (cooldown'da)
T=300s: Condition still true → Trigger Event ✓ (cooldown reset)

Hata Senaryoları

S: Kural değerlendirme sırasında hata olursa?

A: Observer pattern:

  • Kritik hata (e.g., corrupted rule) → rule.failed.v1 emit, device skip
  • Cache miss (e.g., Redis down) → DB fallback
  • Kısmi başarısızlık (e.g., 5/10 cihaz başarısız) → Log and continue
Processing Device E2E-001:
├─ GroupA: ✓ Success
├─ GroupB: ✗ Cache miss → DB fallback → ✓ Success
├─ GroupC: ✗ Invalid variable → rule.failed.v1, skip, continue
├─ GroupD: ✓ Success

Sonuç: 3/4 group başarılı, error logged