Batch proses izleme, her an hangi partinin hangi fazda olduğunu, proses değerlerinin reçete limitleri içinde kalıp kalmadığını ve serbest bırakmadan önce hangi sapmaların imza gerektirdiğini bilmek demektir. Bu eğitimde MQTT ile küçük ama eksiksiz bir hat kuracaksınız: simüle edilmiş bir kazan fazları ve okumaları yayınlar, bir Python izleyicisi bunları set değerleriyle karşılaştırır ve her sapmayı kaydeder.
Batch Proses İzleme Kesikli İzlemeden Neden Farklıdır?
Kesikli üretimde parça sayarsınız. Proses üretiminde (gıda, içecek, kimya, boya ve kaplama, ilaç, kozmetik) ise bir dizi faz üzerinden belirli miktarda malzeme üretirsiniz: şarj, ısıtma, bekletme, soğutma, transfer. Bir fazda tamamen normal olan bir proses değeri, bir sonraki fazda sapmadır. 75 °C'lik bir okuma ısıtma sırasında beklenir, ancak soğutma fazında bir sorundur.
Bunun izleme açısından üç sonucu vardır:
- Bağlam zorunludur. Her okuma batch ID'yi, reçeteyi ve mevcut fazı taşımalıdır; aksi halde değerlendirilemez.
- Limitler zamanla değişir. İzleyici, set değerlerini ve toleransları tag başına değil, faz başına yüklemelidir.
- Serbest bırakma için geçmiş önemlidir. Kalite ekiplerinin bir batch kaydına ihtiyacı vardır: her fazın ne zaman başlayıp bittiği ve süresi ile tepe değeriyle birlikte her sapma.
ISA-88 standardı, çoğu tesisin zaten kullandığı terminolojiyi sağlar: ünitelerde çalışan prosedürler, ünite prosedürleri, operasyonlar ve fazlar. Yapılandırılmış izlemeden faydalanmak için tam bir ISA-88 batch motoruna ihtiyacınız yok, ancak onun adlandırmasını ödünç almak verilerinizi proses mühendisleri için anlaşılır kılar.
Batch Verisi için MQTT Topic Tasarımı
MQTT batch verisi için iyi çalışır, çünkü bir faz değişimi bir olaydır ve olaylar tam olarak publish/subscribe modelinin ele aldığı şeydir. Bir MQTT broker her olayı bir kez alır ve ilgilenen tüm tüketicilere dağıtır: HMI, historian, kalite panosu ve aşağıda kuracağınız izleyici.
Tek bir ünite için pratik bir yapı şöyledir:
| Topic | Payload | Retained | Amaç |
|---|---|---|---|
.../kettle1/batch/state |
batch ID, reçete, durum | Evet | Ünitedeki mevcut parti |
.../kettle1/batch/phase |
faz adı, başlangıç zamanı, set değerleri | Evet | Mevcut faz ve limitleri |
.../kettle1/pv |
sıcaklık, karıştırıcı hızı, seviye | Hayır | Birkaç saniyede bir proses değerleri |
.../kettle1/batch/deviation |
parametre, değer, limit, faz | Hayır | Batch kaydı için sapma olayları |
state ve phase topic'lerini retained tutmak, parti ortasında bağlanan herhangi bir client'ın bağlamı hemen bilmesini sağlar. Proses değerleri retained değildir, çünkü bir sonraki okuma zaten saniyeler sonra gelir.
Üretim ortamında bunların önüne, ISA-95 MQTT topic'leri yazısında anlatıldığı gibi ISA-95 yolunuzu (kuruluş, saha, alan, hat veya hücre) ekleyin. Bu eğitimde en fazla 8 topic seviyesine izin veren genel test broker'ını kullanıyoruz, bu yüzden öneki kısa tutuyoruz: connectmq/demo/<random-id>/kettle1/....
Adım 1: Genel Broker Üzerinde Bir Partiyi Simüle Edin
broker.connectmq.com adresindeki ücretsiz genel MQTT test broker'ı, boş olmayan benzersiz herhangi bir client ID ile anonim bağlantıları kabul eder. Orada yayınlanan her şey herkes tarafından okunabilir; bu yüzden rastgele bir topic öneki kullanın ve asla gerçek reçete verisi göndermeyin.
Client kütüphanesini kurun:
pip install "paho-mqtt>=2.0"
Aşağıdaki simülatör dört fazlı kısa bir reçete çalıştırır, retained batch durumunu ve fazını yayınlar ve her saniye proses değerlerini gönderir. İzleyicinin yakalayacağı bir şey olsun diye bekletme sıcaklığını kasıtlı olarak aşar.
import json
import random
import time
import uuid
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/batch-7f3a/kettle1" # 7f3a'yı kendi rastgele kimliğinizle değiştirin
BATCH_ID = "B" + time.strftime("%Y%m%d-%H%M%S")
RECIPE = [
{"phase": "CHARGE", "duration": 10, "temp_sp": 20, "temp_tol": 5, "rpm_min": 0},
{"phase": "HEAT", "duration": 15, "temp_sp": None, "temp_tol": None, "rpm_min": 60},
{"phase": "HOLD", "duration": 20, "temp_sp": 72, "temp_tol": 2, "rpm_min": 60},
{"phase": "COOL", "duration": 15, "temp_sp": None, "temp_tol": None, "rpm_min": 30},
]
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"batch-sim-{uuid.uuid4().hex[:8]}")
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_start()
def publish(subtopic, payload, retain=False):
client.publish(f"{PREFIX}/{subtopic}", json.dumps(payload), qos=1, retain=retain)
publish("batch/state", {"batchId": BATCH_ID, "recipe": "SAUCE-A", "status": "RUNNING"}, retain=True)
temp = 18.0
for step in RECIPE:
publish("batch/phase", {"batchId": BATCH_ID, "ts": time.time(), **step}, retain=True)
for second in range(step["duration"]):
if step["phase"] == "HEAT":
temp += 3.5
elif step["phase"] == "HOLD":
temp = 72 + random.uniform(-1.5, 1.5)
if 8 <= second <= 11:
temp = 75.2 # kasıtlı eklenen aşım
elif step["phase"] == "COOL":
temp -= 3.0
rpm = 0 if step["phase"] == "CHARGE" else 80 + random.uniform(-5, 5)
publish("pv", {"batchId": BATCH_ID, "ts": time.time(),
"temp": round(temp, 2), "rpm": round(rpm, 1)})
time.sleep(1)
publish("batch/state", {"batchId": BATCH_ID, "recipe": "SAUCE-A", "status": "COMPLETE"}, retain=True)
time.sleep(1)
client.loop_stop()
client.disconnect()
Adım 2: Batch Proses İzleme Servisini Oluşturun
İzleyici üniteye abone olur, mevcut fazı ve limitlerini hatırlar, her proses değerini kontrol eder ve bir değer bandının dışına çıktığında bir sapma olayı yayınlar. Ayrıca sapmanın süresini ve tepe değerini de takip eder; bir batch kaydının gerçekten ihtiyaç duyduğu şey budur.
import json
import time
import uuid
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/batch-7f3a/kettle1"
current_phase = {}
open_deviation = None
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe(f"{PREFIX}/batch/#", qos=1)
client.subscribe(f"{PREFIX}/pv", qos=1)
def check(client, pv):
global open_deviation
sp, tol = current_phase.get("temp_sp"), current_phase.get("temp_tol")
out_of_spec = sp is not None and abs(pv["temp"] - sp) > tol
if out_of_spec and open_deviation is None:
open_deviation = {"batchId": pv["batchId"], "phase": current_phase["phase"],
"parameter": "temp", "limit": f"{sp}+/-{tol}",
"start": pv["ts"], "peak": pv["temp"]}
print("DEVIATION START", open_deviation)
elif out_of_spec:
open_deviation["peak"] = max(open_deviation["peak"], pv["temp"], key=lambda v: abs(v - sp))
elif open_deviation is not None:
open_deviation["end"] = pv["ts"]
open_deviation["durationS"] = round(pv["ts"] - open_deviation["start"], 1)
client.publish(f"{PREFIX}/batch/deviation", json.dumps(open_deviation), qos=1)
print("DEVIATION CLOSED", open_deviation)
open_deviation = None
def on_message(client, userdata, msg):
global current_phase
data = json.loads(msg.payload)
if msg.topic.endswith("/batch/phase"):
current_phase = data
print(f"Phase -> {data['phase']} (batch {data['batchId']})")
elif msg.topic.endswith("/batch/state"):
print(f"Batch {data['batchId']} is {data['status']}")
elif msg.topic.endswith("/pv") and current_phase:
if data["rpm"] < current_phase.get("rpm_min", 0):
print(f"Agitator below minimum in {current_phase['phase']}: {data['rpm']} rpm")
check(client, data)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"batch-mon-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_forever()
Önce izleyiciyi, ardından ikinci bir terminalde simülatörü başlatın. Faz geçişlerini, ardından HOLD fazının yaklaşık sekizinci saniyesinde açılan ve tepe değeri ile süresiyle birlikte yaklaşık dört saniye sonra kapanan bir sapmayı göreceksiniz. Aynı anda ham trafiği Mosquitto CLI ile izleyin:
mosquitto_sub -h broker.connectmq.com -p 1883 -i watcher-7f3a -t "connectmq/demo/batch-7f3a/kettle1/#" -v
Adım 3: Olayları Bir Batch Kaydına Dönüştürün
Sapma topic'i, elektronik batch kaydınızın ham maddesidir. Ayrı bir abone (küçük bir Python servisi, Node-RED akışı veya Telegraf örneği), faz değişimlerini ve sapmaları batch ID ile anahtarlanmış bir veritabanına yazabilir. Serbest bırakma zamanında bir sorgu tüm hikayeyi döndürür: faz başlangıç ve bitiş zamanları, geçerli set değerleri ve her sapmanın süresi ile tepe değeri.
Tasarlarken şu kuralları aklınızda tutun:
- Set değerlerini her faz olayıyla birlikte yazın. Reçeteler değişir; kayıt bugünün değerlerini değil, bu partiye uygulanan limitleri göstermelidir.
- Faz ve sapma olayları için QoS 1 kullanın. Bir faz değişimini kaybetmek sonraki her değerlendirmeyi bozar. Proses değerleri için QoS 0 genellikle yeterlidir.
- Zaman damgasını kaynakta basın.
tsalanı aboneden değil, kontrolörden veya gateway'den gelir; böylece ağ gecikmesi faz sınırlarını kaydırmaz. - Tekrarlanan mesajları normal kabul edin. QoS 1 en az bir kez teslimattır; bu yüzden veritabanı eklemesini batch ID, faz ve zaman damgası üzerinden idempotent yapın.
Çok sayıda parti üzerindeki istatistiksel trendler için aynı veri gerçek zamanlı SPC sistemini besler; batch ID'leri hammadde lotlarına bağlamak ise bir üretim izlenebilirlik sisteminin omurgasını oluşturur.
Batch İzleme Hatlarında Sorun Giderme
| Belirti | Olası neden | Çözüm |
|---|---|---|
| İzleyici ilk okumaları yok sayıyor | Faz yayınlandıktan sonra bağlandı, retained faz yok | batch/phase topic'ini retain=True ile yayınlayın |
| Sapmalar açılıp kapanıp duruyor | Değer tam limitin üzerinde gidip geliyor | Ölü bant ekleyin veya N ardışık örnek şartı koyun |
| Faz sınırları yanlış görünüyor | Kaynak yerine abone zaman damgaları kullanılıyor | ts değerini kontrolörde veya gateway'de basın |
| Tekrarlanan sapma satırları | Yeniden bağlanma sonrası QoS 1 yeniden teslimatı | Doğal anahtar üzerinde idempotent ekleme |
| Client sürekli bağlantıyı kaybediyor | İki client aynı client ID'yi paylaşıyor | Her süreç için benzersiz bir ID üretin |
ConnectMQ ile Üretime Geçiş
Genel broker deneyler içindir. Gerçek partiler için özel kimlik bilgileri, TLS ve dünyayla paylaşılmayan bir broker istersiniz. ConnectMQ, MQTT 3.1.1 ve 5.0, 8883 portunda TLS ve her broker için üretilmiş kullanıcı adı, parola ve client ID ile yönetilen bir MQTT broker sunar. Her iki betikteki bağlantı satırlarını değiştirin:
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set() # sistem CA deposunu kullanır; broker bir Let's Encrypt sertifikası sunar
client.connect("YOUR_BROKER_HOST", 8883, keepalive=30)
ConnectMQ portalında canlı topic gezgini, ünite başına retained batch durumunu gösterir; eşik tabanlı uyarı kuralları ise faz farkındalıklı izleyicinizin yanında ikinci bir savunma hattı olarak sabit bir limiti aşan proses değerlerini işaretleyebilir. Batch verisinin bir tesiste nereye oturduğuna dair genel resim akıllı üretim rehberinde ele alınıyor.
ConnectMQ'da Partileri İzlemeye Başlayın
Kredi kartı gerekmeden ücretsiz Serverless planında app.connectmq.com adresinde bir broker oluşturun, kimlik bilgilerini yukarıdaki betiklere yapıştırın ve ilk izlenen partinizi dakikalar içinde çalıştırın.
Sık Sorulan Sorular
MQTT ile batch proses izleme için bir ISA-88 batch motoruna ihtiyacım var mı?
Hayır. Batch motorunun veya PLC'nin yalnızca mevcut fazı ve set değerlerini değiştiklerinde yayınlaması yeterlidir. Bunu doğrudan veya bir gateway üzerinden yapabilen her kontrolör izleyiciyi besleyebilir.
Batch olayları hangi QoS seviyesini kullanmalı?
Faz değişimleri, batch durumu ve sapmalar için en az bir kez teslim edilmeleri adına QoS 1 kullanın ve tüketicileri idempotent yapın. Ara sıra kaybolan bir örneğin önemli olmadığı yüksek frekanslı proses değerleri QoS 0 kullanabilir.
Ücretsiz plan gerçek bir batch hattını kaldırabilir mi?
Ücretsiz Serverless plan en fazla 25 bağlantıyı, QoS 1'e kadar seviyeyi ve 256 KB mesajları destekler; bu, birkaç ünitelik bir pilot için yeterlidir. Daha büyük tesisler ücretli Serverless veya Dedicated planlara geçer.
Batch kaydı nerede saklanmalı?
Kalite sisteminizin sahip olduğu bir veritabanında. Broker olayları gerçek zamanlı taşır; bir abone servisi bunları inceleme ve serbest bırakma için kalıcı depolamaya yazar.



