Sensör Olaylarına Otomatik Yanıt
Sıcaklık > eşik → uyarı → çalıştırma: aracı güdümlü IoT denetim döngüleri.
Sensör Olaylarına Otomatik Yanıt, CoddyKit'te ücretsiz bir AI Agents dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, AI Agents öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. AI Agents kursu toplamda 4 dersten oluşur.
Olaya Dayalı Otomatik Ajan Yanıtları
Bir sensör bir eşiği aştığında ajan, insan müdahalesi olmadan otomatik olarak yanıt vermelidir. Temel zorluklar şunlardır: hangi eylemin gerçekleştirileceğine karar vermek, aynı olayın yinelenen eylemleri tetiklememesini sağlamak ve ajanın çalıştırıcılara komut yağdırmaması için soğuma süresine uymak.
Eylem İlkelerini Tanımlama
Bir eylem ilkesi, sensör koşullarını ajan yanıtlarıyla eşleştirir. Mantık koduna dokunmadan kolayca okunup değiştirilebilmeleri için ilkeleri bildirimsel olarak tanımlayın. Her ilkenin bir koşulu, önceliği ve bir veya daha fazla eylemi vardır.
ACTION_POLICIES = [
{
'name': 'HIGH_TEMP_ALERT',
'topic': 'sensors/temperature',
'condition': lambda v: v > 38,
'priority': 'critical',
'actions': ['TURN_ON_COOLING', 'ALERT_MAINTENANCE', 'LOG_EVENT']
},
{
'name': 'HIGH_TEMP_WARNING',
'topic': 'sensors/temperature',
'condition': lambda v: 35 < v <= 38,
'priority': 'warning',
'actions': ['ALERT_MAINTENANCE', 'LOG_EVENT']
},
{
'name': 'LOW_HUMIDITY',
'topic': 'sensors/humidity',
'condition': lambda v: v < 30,
'priority': 'warning',
'actions': ['TURN_ON_HUMIDIFIER', 'LOG_EVENT']
}
]
def match_policies(topic: str, value: float) -> list:
return [
p for p in ACTION_POLICIES
if p['topic'] == topic and p['condition'](value)
]
if __name__ == '__main__':
matches = match_policies('sensors/temperature', 39)
print('Matched policies for temperature=39:')
for p in matches:
print(f" {p['name']} ({p['priority']}): {p['actions']}")
Eylem Kuyruğu
Bir eylem kuyruğu, olay algılama ile eylem yürütmeyi birbirinden ayırır. Olaylar kuyruğa eklenir; bir işleyici bunları kuyruktan alıp yürütür. Bu, MQTT alma döngüsünün engellenmesini önler ve bir eylem başarısız olursa yeniden denemelere olanak tanır.
import queue
import threading
from datetime import datetime
action_queue: queue.Queue = queue.Queue(maxsize=500)
def enqueue_action(action_name: str, context: dict, priority: str = 'normal'):
item = {
'action': action_name,
'context': context,
'priority': priority,
'enqueued_at': datetime.utcnow().isoformat()
}
try:
action_queue.put_nowait(item)
print(f'Enqueued: {action_name}')
except queue.Full:
print(f'WARNING: Action queue full, dropping {action_name}')
def action_worker(executor_fn):
"""Run in a background thread, executing actions from the queue."""
while True:
item = action_queue.get()
try:
executor_fn(item['action'], item['context'])
except Exception as e:
print(f'Action failed: {item["action"]} — {e}')
finally:
action_queue.task_done()
# Start worker thread:
# worker_thread = threading.Thread(target=action_worker, args=(execute_action,), daemon=True)
# worker_thread.start()
if __name__ == '__main__':
enqueue_action('TURN_ON_COOLING', {'zone': 'server-room'}, priority='critical')
enqueue_action('LOG_EVENT', {'msg': 'temperature nominal'})
print('Queue size:', action_queue.qsize())
Olay Tekilleştirme
Tekilleştirme olmadan, 1 okuma/saniye hızında 10 dakika boyunca 38°C'nin üzerinde kalan bir sıcaklık 600 özdeş olay üretir. Tekilleştirme, aynı (konu, koşul, eylem) birleşiminin bir olay boyunca yalnızca bir kez tetiklenmesini ve koşul ortadan kalktığında sıfırlanmasını sağlar.
class EventDeduplicator:
def __init__(self):
# active_events: (topic, policy_name) -> event_start_time
self._active: dict = {}
def is_new_event(self, topic: str, policy_name: str) -> bool:
key = (topic, policy_name)
return key not in self._active
def mark_active(self, topic: str, policy_name: str):
self._active[(topic, policy_name)] = datetime.utcnow()
def clear_event(self, topic: str, policy_name: str):
key = (topic, policy_name)
if key in self._active:
duration = (datetime.utcnow() - self._active.pop(key)).seconds
print(f'Event cleared: {policy_name} (lasted {duration}s)')
def clear_topic_if_normal(
self, topic: str, value: float, normal_fn
):
if normal_fn(value):
keys = [k for k in self._active if k[0] == topic]
for k in keys:
self.clear_event(k[0], k[1])
dedup = EventDeduplicator()
dedup.mark_active('sensors/temperature', 'HIGH_TEMP_ALERT')
print('New event?', dedup.is_new_event('sensors/temperature', 'HIGH_TEMP_ALERT'))Soğuma Süresi
Bir olay sona erip yeniden tetiklense bile soğuma süresi, hızlı şekilde yeniden tetiklenmesini önler. Tekilleştirmeyi (koşul sürdüğü sürece bir kez tetikle) soğuma süresiyle (koşul ortadan kalktıktan sonra aynı uyarının yeniden tetiklenmesine izin vermeden önce N dakika bekle) birleştirin.
from datetime import datetime, timedelta
class CoolDownManager:
def __init__(self, cool_down_minutes: int = 15):
self.cool_down = timedelta(minutes=cool_down_minutes)
self._cleared_at: dict = {} # (topic, policy) -> cleared_datetime
def is_in_cool_down(self, topic: str, policy_name: str) -> bool:
key = (topic, policy_name)
cleared_at = self._cleared_at.get(key)
if cleared_at is None:
return False
return datetime.utcnow() - cleared_at < self.cool_down
def record_clear(self, topic: str, policy_name: str):
self._cleared_at[(topic, policy_name)] = datetime.utcnow()
def time_remaining(self, topic: str, policy_name: str) -> int:
key = (topic, policy_name)
cleared_at = self._cleared_at.get(key)
if cleared_at is None:
return 0
elapsed = datetime.utcnow() - cleared_at
remaining = self.cool_down - elapsed
return max(0, int(remaining.total_seconds()))
cooldown = CoolDownManager(cool_down_minutes=15)
cooldown.record_clear('sensors/temperature', 'HIGH_TEMP_ALERT')
print('In cool-down?', cooldown.is_in_cool_down('sensors/temperature', 'HIGH_TEMP_ALERT'))LLM Destekli Eylem Kararı
Birden çok eş zamanlı uyarı, çelişen ilkeler veya alışılmadık okuma birleşimleri gibi karmaşık durumlarda kararı LLM'ye devredin. LLM, sensör bağlamının tamamını alır ve önceliklendirilmiş bir eylem planı önerir.
import anthropic
import json
def llm_decide_actions(
sensor_readings: dict,
active_policies: list
) -> list:
client = anthropic.Anthropic(api_key='YOUR_API_KEY')
context = json.dumps({
'readings': sensor_readings,
'triggered_policies': [p['name'] for p in active_policies]
}, indent=2)
prompt = (
f'Current sensor state:\n{context}\n\n'
'Multiple alert policies are active. '
'Recommend an ordered list of actions to take. '
'Consider conflicting effects (e.g., humidifier and cooling may conflict).\n'
'Return JSON: {"recommended_actions": [str], "reasoning": str}'
)
response = client.messages.create(
model='claude-opus-4-5', max_tokens=512,
messages=[{'role': 'user', 'content': prompt}]
)
return json.loads(response.content[0].text)Eylemleri MQTT Üzerinden Yürütme
Eylemler, cihaza özgü MQTT konularına komut mesajları yayımlanarak yürütülür. Komut yükü standart bir şemayı izler: eylem adı, parametreler, onay için istek kimliği ve TTL (cihaz çok uzun süre çevrimdışı kalırsa komutun süresi dolar).
import json
import uuid
from datetime import datetime, timedelta
ACTION_TOPICS = {
'TURN_ON_COOLING': 'devices/hvac/commands',
'TURN_OFF_COOLING': 'devices/hvac/commands',
'TURN_ON_HUMIDIFIER': 'devices/humidifier/commands',
'ALERT_MAINTENANCE': 'notifications/maintenance',
'LOG_EVENT': 'logs/agent_events'
}
def execute_action(action_name: str, context: dict, mqtt_client) -> str:
topic = ACTION_TOPICS.get(action_name)
if not topic:
print(f'No topic defined for action: {action_name}')
return 'unknown_action'
request_id = str(uuid.uuid4())[:8]
ttl = (datetime.utcnow() + timedelta(minutes=5)).isoformat()
payload = json.dumps({
'action': action_name,
'request_id': request_id,
'context': context,
'ttl': ttl
})
mqtt_client.publish(topic, payload, qos=1)
print(f'Executed {action_name} -> {topic} (req={request_id})')
return request_id
if __name__ == '__main__':
class FakeMQTT:
def publish(self, topic, payload, qos=1):
pass
execute_action('TURN_ON_COOLING', {'zone': 'server-room'}, FakeMQTT())
Eylem Onayı
Cihazlar, alınan komutları bir onay konusuna yayımlayarak onaylamalıdır. Ajan onay konularına abone olur ve bir zaman aşımı süresi içinde onay alınmazsa yeniden deneyebilir.
import threading
from collections import defaultdict
class AckTracker:
def __init__(self, timeout_seconds: int = 30):
self.timeout = timeout_seconds
self._pending: dict = {} # request_id -> {'action', 'send_time', 'ack_event'}
def register(self, request_id: str, action_name: str):
event = threading.Event()
self._pending[request_id] = {
'action': action_name,
'send_time': datetime.utcnow(),
'ack_event': event
}
# Schedule timeout check
t = threading.Timer(self.timeout, self._on_timeout, args=[request_id])
t.daemon = True
t.start()
def acknowledge(self, request_id: str):
entry = self._pending.pop(request_id, None)
if entry:
entry['ack_event'].set()
print(f'Ack received for {entry["action"]} (req={request_id})')
def _on_timeout(self, request_id: str):
if request_id in self._pending:
action = self._pending.pop(request_id)['action']
print(f'TIMEOUT: No ack for {action} (req={request_id}) — retry?')Tam Sensör Olayı İşlem Hattı
Tüm bileşenlerin bir araya getirilmesi: MQTT alımı → ilke eşleştirme → tekilleştirme + soğuma denetimi → eylemleri kuyruğa alma → işleyicinin MQTT yayımlamasıyla yürütmesi → onay izleme. Bu mimari, engelleme yapmadan dakikada binlerce sensör olayını işler.
class IoTAgentPipeline:
def __init__(self, mqtt_client):
self.mqtt = mqtt_client
self.dedup = EventDeduplicator()
self.cooldown = CoolDownManager(cool_down_minutes=15)
self.ack_tracker = AckTracker(timeout_seconds=30)
def on_sensor_message(self, topic: str, value: float):
policies = match_policies(topic, value)
self.dedup.clear_topic_if_normal(
topic, value,
normal_fn=lambda v: v <= 35 # below warning threshold
)
for policy in policies:
name = policy['name']
if not self.dedup.is_new_event(topic, name):
continue # already active, skip
if self.cooldown.is_in_cool_down(topic, name):
print(f'In cool-down: {name}')
continue
self.dedup.mark_active(topic, name)
ctx = {'topic': topic, 'value': value, 'policy': name}
for action in policy['actions']:
enqueue_action(action, ctx, policy['priority'])Üst Makama Bildirim Yolu
Bazı durumlar insanlara bildirim gönderilmesini gerektirir: bir komutun onaylanması için yinelenen başarısızlıklar, devam eden kritik koşullar veya birden çok çelişen ilke. Anlık bildirim gönderen ya da bir destek talebi oluşturan bir bildirim yolu tanımlayın.
import requests
def escalate_to_human(
reason: str,
sensor_data: dict,
webhook_url: str = 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'
):
message = {
'text': (
f'*IoT Agent Escalation* \n'
f'Reason: {reason}\n'
f'Sensor data: {sensor_data}\n'
f'Time: {datetime.utcnow().isoformat()}'
)
}
try:
response = requests.post(webhook_url, json=message, timeout=5)
response.raise_for_status()
print(f'Escalation sent: {reason}')
except requests.RequestException as e:
print(f'Escalation failed: {e}')
# Fall back: log to file
with open('escalations.log', 'a') as f:
import json
f.write(json.dumps({'reason': reason, 'data': sensor_data}) + '\n')Olay İşlem Hattını Sınama
Olay işlem hattınızı üretime almadan önce sensör olaylarını benzeten ve doğru eylemlerin kuyruğa alındığını doğrulayan otomatik sınamalar yazın. Her ilkeyi ayrı ayrı, tekilleştirme davranışını ve soğuma süresinin dolmasını sınayın.
import time
def test_high_temp_policy_fires_once():
dedup = EventDeduplicator()
cooldown = CoolDownManager(cool_down_minutes=0) # disable cooldown for test
pipeline = IoTAgentPipeline(None)
pipeline.dedup = dedup
pipeline.cooldown = cooldown
actions_fired = []
action_queue.queue.clear()
# Fire same event 5 times in a row
for _ in range(5):
pipeline.on_sensor_message('sensors/temperature', 40.0)
# Only 1 set of actions should have been enqueued
actions = list(action_queue.queue)
assert len(actions) > 0, 'At least one action should fire'
print(f'Actions enqueued: {len(actions)} (expected: just 1 event worth)')
return True
result = test_high_temp_policy_fires_once()
print('Test passed:', result)Bilgi Kontrolü
Bir sensör olay işlem hattında olay tekilleştirmenin temel amacı nedir?
Özet: Sensör Olaylarına Otomatik Yanıt
Harika! Öğrendikleriniz:
- Eylem ilkeleri: önceliklere sahip bildirimsel koşuldan eyleme eşleme
- Eylem kuyruğu: algılamayı yürütmeden ayırır; iş parçacığı eylemleri işler
- Tekilleştirme: okuma başına değil, olay başına bir kez tetikleme
- Soğuma süresi: koşul ortadan kalktıktan hemen sonra yeniden tetiklenmeyi önleme
- LLM'ye bildirim: karmaşık, çok ilkeli durumları LLM'nin değerlendirmesine devretme
- Onay izleme: onaylanmayan komutları algılama ve yeniden deneme
Sırada: Raspberry Pi gibi uç cihazlara hafif ajanları dağıtma.
Sıkça Sorulan Sorular
“Sensör Olaylarına Otomatik Yanıt” dersi ücretsiz mi?
Evet — “Sensör Olaylarına Otomatik Yanıt” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve AI Agents kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. AI Agents kursu toplamda 4 dersten oluşur.
“Sensör Olaylarına Otomatik Yanıt” dersinde ne öğreneceğim?
Sıcaklık > eşik → uyarı → çalıştırma: aracı güdümlü IoT denetim döngüleri. AI Agents ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
AI Agents öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te AI Agents, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Sensör Olaylarına Otomatik Yanıt” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu AI Agents dersinde kod yazıp çalıştırabilir miyim?
Evet. Her AI Agents dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Aracı Entegrasyonu İçin MQTT Protokolü
- Aracılarda Zaman Serisi Verisi İşleme
- Sensör Olaylarına Otomatik Yanıt
- Hafif Aracıların Uçta Dağıtımı