IoT ve Yapay Zekâ

LLM ile Sensör Verisi Özetleme: MQTT'den Vardiya Raporları ve Anomali Açıklamaları Üretin

İstatistikleri kodda hesaplayıp LLM'e yalnızca anlatıyı yazdırarak MQTT sensör okuma akışlarını okunabilir vardiya raporlarına ve anomali açıklamalarına nasıl dönüştüreceğinizi öğrenin.

MQTT telemetri grafiklerini operatörler için yazılı bir vardiya raporuna dönüştüren LLM ile sensör verisi özetleme
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

LLM ile sensör verisi özetleme, binlerce ham okumayı bir operatörün vardiya devrinde okuyabileceği birkaç paragrafa dönüştürür: ne normal çalıştı, ne kaydı ve neyin ilgilenilmesi gerekiyor. Bu eğitimde MQTT topic'lerinden telemetri toplayacak, istatistikleri Python'da hesaplayacak ve bir dil modelinden yalnızca bu hesaplanmış olgulara dayanarak bir vardiya raporu ve sade dilde anomali açıklamaları yazmasını isteyeceksiniz.

Neden Ham Veriyi Doğrudan Modele Göndermiyoruz?

Bir günlük okumayı prompt'a yapıştırıp özet istemek cazip gelir. Pratikte bu üç şekilde başarısız olur:

  • Aritmetik güvenilmezdir. Dil modelleri dilde iyi, uzun listeler üzerinde ortalama hesaplamada zayıftır. Makul görünen ama yanlış sayılar üretirler.
  • Bağlam sınırlı ve pahalıdır. Yüksek frekanslı telemetri, bir prompt'a sığabilecek miktarı hızla aşar ve her token zaman maliyeti getirir.
  • Sonuçlar denetlenemez. Rapordaki bir sayı yanlışsa nereden geldiğini anlayamazsınız.

Güvenilir desen işi böler. Sayı olan her şeyi kod hesaplar: sayımlar, ortalamalar, minimumlar, maksimumlar, eşiğin üzerinde geçen süre, verideki boşluklar. Model kompakt bir JSON olgu belgesi alır ve onu düzyazıya dönüştürür. Rapordaki her sayı olgu belgesine kadar izlenebilir.

Görev Yapan Neden
Okumaları toplamak MQTT abonesi Sürekli ve hafif
İstatistikler ve eşik kontrolleri Python Kesin ve test edilebilir
Boşlukları ve güncellenmeyen sensörleri tespit etmek Python Basit zaman aritmetiği
Neyin önemli olduğunu sıralamak Python kuralları, ifade için model Öncelikleri deterministik tutar
Anlatı, açıklamalar, devir teslim üslubu LLM Modellerin iyi yaptığı iş

Mimari

sensors --MQTT--> broker --> collector.py (window buffer, stats) --> facts JSON
                                                              |
                                                              v
                                                   LLM (summary prompt)
                                                              |
                         broker <-- reports/shift (retained) <-+

Rapor broker'a retained bir topic üzerinden geri yayınlanır; böylece bir dashboard, bir sohbet botu köprüsü veya bir yazıcı servisi en son raporu istediği zaman alabilir.

Adım 1: Biraz Test Telemetrisi Yayınlayın

Henüz cihazınız yoksa bu simülatör iki makine için iki saniyede bir sıcaklık, titreşim ve basınç yayınlar; ara sıra da bir titreşim sıçraması üretir. b62d1f değerini kendi rastgele dizinizle değiştirin.

# sim_line.py
import json
import random
import time
import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/b62d1f/line1"
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="sim-line-b62d1f")
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()

while True:
    for machine in ("press-1", "press-2"):
        vib = random.gauss(2.0, 0.2)
        if machine == "press-2" and random.random() < 0.05:
            vib += random.uniform(3, 5)  # occasional spike
        payload = {
            "temp_c": round(random.gauss(58 if machine == "press-1" else 63, 1.5), 2),
            "vib_mm_s": round(vib, 2),
            "pressure_bar": round(random.gauss(5.0, 0.1), 2),
            "ts": int(time.time() * 1000),
        }
        client.publish(f"{PREFIX}/{machine}/telemetry", json.dumps(payload), qos=0)
    time.sleep(2)

Adım 2: Olguları Toplayın ve Hesaplayın

Toplayıcı bir wildcard ile abone olur, okumaları makine ve metrik bazında tamponlar ve her pencerenin sonunda olgu belgesini oluşturur. Eşikler modelden değil, yapılandırmadan gelir.

# collector.py
import json
import statistics
import threading
import time
from collections import defaultdict

import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/b62d1f/line1"
THRESHOLDS = {"temp_c": 65.0, "vib_mm_s": 4.5, "pressure_bar": 5.4}
UNITS = {"temp_c": "C", "vib_mm_s": "mm/s", "pressure_bar": "bar"}

buffer = defaultdict(list)       # (machine, metric) -> [(ts, value)]
last_seen = {}
lock = threading.Lock()


def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe(f"{PREFIX}/+/telemetry", qos=0)


def on_message(client, userdata, msg):
    machine = msg.topic.split("/")[-2]
    try:
        data = json.loads(msg.payload)
    except json.JSONDecodeError:
        return
    ts = data.get("ts", int(time.time() * 1000))
    with lock:
        last_seen[machine] = ts
        for metric in THRESHOLDS:
            if isinstance(data.get(metric), (int, float)):
                buffer[(machine, metric)].append((ts, float(data[metric])))


def build_facts(window_start, window_end):
    with lock:
        items = {k: list(v) for k, v in buffer.items()}
        buffer.clear()
        seen = dict(last_seen)
    machines = defaultdict(dict)
    for (machine, metric), points in items.items():
        values = [v for _, v in points]
        limit = THRESHOLDS[metric]
        breaches = [(ts, v) for ts, v in points if v > limit]
        machines[machine][metric] = {
            "unit": UNITS[metric],
            "count": len(values),
            "mean": round(statistics.fmean(values), 2),
            "min": round(min(values), 2),
            "max": round(max(values), 2),
            "stdev": round(statistics.pstdev(values), 2),
            "threshold": limit,
            "breaches": len(breaches),
            "firstBreach": time.strftime("%H:%M:%S", time.localtime(breaches[0][0] / 1000)) if breaches else None,
            "peakDuringBreach": round(max(v for _, v in breaches), 2) if breaches else None,
        }
    stale = [m for m, ts in seen.items() if window_end * 1000 - ts > 60_000]
    return {
        "line": "line1",
        "window": {
            "start": time.strftime("%Y-%m-%d %H:%M", time.localtime(window_start)),
            "end": time.strftime("%Y-%m-%d %H:%M", time.localtime(window_end)),
        },
        "machines": machines,
        "staleMachines": stale,
    }

Eşik aşım sayılarını, ilk aşım zamanını ve tepe değeri tutmak, modelin bir anomaliyi hiçbir şey uydurmadan somut biçimde açıklamasını sağlar ("press-2'deki titreşim 4,5 mm/s'yi 6 kez aştı; ilki 14:12'de oldu ve 6,8 ile zirve yaptı").

Adım 3: Özeti LLM'e Yazdırın

Prompt en az veri kadar önemlidir. Modele raporun ne için olduğunu, neleri yapıp neleri yapamayacağını ve çıktının nasıl bir biçimde olması gerektiğini söyleyin. Bu örnek Ollama üzerinden yerel bir model kullanıyor, ancak aynı prompt herhangi bir sohbet API'siyle çalışır.

# summarize.py
import json
import ollama

MODEL = "llama3.1:8b"

INSTRUCTIONS = """You write shift handover reports for production operators.
Use ONLY the numbers in the FACTS JSON. Do not calculate new numbers and do not guess causes as facts.
Structure:
1. One-sentence overall status.
2. 'Needs attention' bullet list: every metric with breaches > 0 and every stale machine. Quote count, first breach time and peak.
3. 'Normal operation' bullet list: one short line per machine.
4. 'Possible explanations' (max 3 bullets): plausible causes worded as suggestions to check, e.g. 'check ...'.
Keep it under 200 words. Plain text, no tables."""


def write_report(facts: dict) -> str:
    resp = ollama.chat(
        model=MODEL,
        messages=[
            {"role": "system", "content": INSTRUCTIONS},
            {"role": "user", "content": "FACTS:\n" + json.dumps(facts, indent=1)},
        ],
        options={"temperature": 0.2},
    )
    return resp.message.content

Adım 4: Pencere Döngüsünü Çalıştırın ve Raporu Yayınlayın

# main.py
import json
import time

import paho.mqtt.client as mqtt

import collector
from summarize import write_report

WINDOW_SECONDS = 600   # 10 minutes for testing; use 8 hours for a real shift
REPORT_TOPIC = f"{collector.PREFIX}/reports/shift"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="summarizer-b62d1f")
client.on_connect = collector.on_connect
client.on_message = collector.on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()

while True:
    start = time.time()
    time.sleep(WINDOW_SECONDS)
    facts = collector.build_facts(start, time.time())
    if not facts["machines"]:
        continue
    report = write_report(facts)
    message = {"facts": facts, "report": report, "generatedAt": int(time.time() * 1000)}
    client.publish(REPORT_TOPIC, json.dumps(message), qos=1, retain=True)
    print(report)

LLM çağrısı MQTT trafiğine kıyasla yavaştır; ancak paho ağ döngüsünü loop_start() ile arka planda bir thread'de çalıştırdığından, rapor üretilirken mesajlar tampona akmaya devam eder. Olguları raporla birlikte yayınlamak, raporu okuyan herkesin her sayıyı kontrol edebilmesi anlamına gelir.

En son raporu her yerden okuyun:

mosquitto_sub -h broker.connectmq.com -p 1883 -i reader-b62d1f -t "connectmq/demo/b62d1f/line1/reports/shift" -C 1

Pencereleri, Eşikleri ve Hedef Kitleyi Seçmek

Aynı olgular, pencereyi nasıl çerçevelediğinize ve sonucu kimin okuduğuna bağlı olarak çok farklı raporlar üretebilir.

Hedef kitle Pencere Odak
Devir teslimdeki operatörler Bir vardiya Ne değişti, ne hâlâ açık, sırada neye dikkat edilmeli
Bakım ekibi Bir gün veya hafta Tekrarlanan eşik aşımları, eğilimler, incelenmesi gereken makineler
Vardiya amirleri Bir alarmdan sonra talep üzerine Tek bir olayın çevresindeki bağlamla kısa açıklaması

Eşikler, modelin genel bilgisinden değil, alarmlarınızla aynı kaynaktan gelmelidir; örneğin ekipman spesifikasyonları veya mühendislikle üzerinde anlaşılmış proses limitleri. Bir eşik değişirse, olgu belgesinin parçası olduğu için bir sonraki rapor bunu otomatik olarak yansıtır.

Olay güdümlü raporlar için, bir alarm tetiklendiğinde özeti başlatın ve yalnızca etkilenen makinenin son 30 ila 60 dakikalık olgularını, referans olarak da önceki günün aynı penceresini iletin. Model böylece tam bir vardiya raporu yerine odaklı bir açıklama yazar. Olgu belgesini küçük tutmak, üretimi de açıklamanın olay hâlâ güncelken ulaşacağı kadar hızlı tutar.

Daha İyi LLM Sensör Verisi Özetleri Yazmak

Raporları belirgin şekilde iyileştiren birkaç pratik ders:

  1. Ad ve bağlam verin. "press-2 (hidrolik pres, hat 1)" çıplak bir kimlikten daha iyi açıklamalar üretir. Açıklamaları yapılandırmada saklayın ve olgulara ekleyin.
  2. Sorunları önceden sıralayın. Göndermeden önce makineleri kodda önem derecesine göre sıralayın. Model büyük ölçüde sıranızı korur; böylece en önemli madde ilk sırada görünür.
  3. Normalin neye benzediğini ekleyin. Önceki vardiyanın ortalamalarını eklemek, modelin sizin hesapladığınız sayılarla "sıcaklık önceki vardiyaya göre 3 derece yüksek" demesini sağlar.
  4. Olguları hipotezlerden ayırın. Olası açıklamaları kontrol edilecek öneriler olarak isteyin. Bir model bir rulmanın arızalandığını bilemez; kontrol edilmesini önerebilir.
  5. Çıktıyı doğrulayın. Rapordaki her sayının olgu JSON'unda da bulunduğunu kontrol eden basit bir denetim, uydurulmuş rakamların çoğunu yakalar.
  6. Bir yedek plan bulundurun. Model kullanılamıyorsa, vardiyanın yine de bir özet alması için aynı olgulardan şablon tabanlı bir rapor yayınlayın.

Anomalileri en başta tespit etmek için bunu IoT anomali tespiti rehberimizdeki uygun bir dedektörle birleştirin ve özetin tespiti kendisi yapmak yerine dedektörün bulgularını açıklamasına izin verin.

Veri Nerede Yaşar?

Toplayıcı herhangi bir MQTT kaynağıyla çalışır. Bir fabrikada onu Sparkplug B yayınlayan PLC gateway'lerinden besleyebilirsiniz; ConnectMQ, Sparkplug B'yi çözümleyip toplaması ve açıklaması çok daha kolay olan okunabilir ISA-95 topic'lerine yeniden yayınlayabilir. Denemeler için herkese açık MQTT test broker'ı yeterlidir, ancak üretim telemetrisinin yeri TLS ve cihaz başına kimlik bilgileri olan özel bir bulut MQTT broker'dır. Modeli sahada tutmak istiyorsanız Ollama ile MQTT yazısında gösterildiği gibi bir gateway üzerinde çalıştırın; canlı değerleri ekipman kılavuzlarıyla birleştiren yanıtlar için de endüstriyel veri için RAG yazımıza bakın. Daha geniş tablo yapay zeka ve IoT rehberimizde ele alınıyor.

ConnectMQ ile Başlayın

Telemetrinizi, raporlarınızın özetlediği okumalar için canlı topic gezgini, dashboard ve eşik tabanlı alarm kuralları sunan tam yönetilen bir MQTT servisi olan ConnectMQ üzerinde toplayın. Kredi kartı gerektirmeden ücretsiz bir Serverless broker açın ve yapay zekanın yazdığı ilk vardiya raporunuzu bugün yayınlayın.

Sık Sorulan Sorular

LLM istatistikleri kendisi hesaplayabilir mi?

Deneyebilir, ancak çok sayıda değer üzerinde sonuçlar güvenilmezdir. İstatistikleri kodda hesaplayıp modele iletin; böylece rapordaki her sayı kesin ve izlenebilir olur.

Özetler ne sıklıkla üretilmeli?

İşin ritmine uyun: devir teslim için vardiya başına, amirler için saatlik ya da bir alarm tetiklendiğinde talep üzerine. Toplayıcı penceresi bu takvimi izler.

Hangi modeli kullanmalıyım?

Bir olgu belgesinden kısa ve yapılandırılmış özetler için küçük bir yerel model yeterlidir. Daha büyük modeller daha akıcı açıklamalar yazar; olgu öncelikli yaklaşım her ikisiyle de çalışır.

Modelin neden uydurmasını nasıl engellerim?

Nedenleri kontrol edilecek şeyler olarak ifade etmesini söyleyin, prompt'a yalnızca olguları koyun ve çıktıdaki sayıların olgu JSON'uyla eşleştiğini doğrulayın.

İlgili yazılar

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.