Die Kühlhaus-Temperaturüberwachung schützt Lebensmittel, Zutaten, Arzneimittel und Proben, die innerhalb weniger Stunden verloren sein können, wenn ein Tiefkühler oder Kühlraum ausfällt. Dieser Anwendungsfall zeigt, wie Sie MQTT-Sensoren in Tiefkühler und Kühlräume bringen, echte Temperaturabweichungen von harmlosen Türöffnungen unterscheiden, ausgefallene Sensoren erkennen und ein Abweichungsprotokoll führen, das Sie einem Auditor vorlegen können.
Was im Kühlhaus schiefgehen kann
Die meisten Verluste im Kühlhaus entstehen nicht durch spektakuläre Ausfälle, sondern durch alltägliche Ereignisse, die niemand rechtzeitig bemerkt:
- Eine Tür, die nach einer nächtlichen Anlieferung angelehnt bleibt.
- Ein Verdichter, der an einem heißen Nachmittag abschaltet und nicht wieder anläuft.
- Ein Verdampfer, der vereist, sodass sich der Raum über Stunden langsam erwärmt.
- Ein Stromausfall am Wochenende.
- Ein Abtauzyklus, der nach einer Reglerumstellung zu lange läuft.
Ein manuelles Temperaturprotokoll, das zweimal pro Schicht ausgefüllt wird, erkennt nichts davon zwischen den Ablesungen. Kontinuierliche Überwachung mit Alarmen schließt diese Lücke. Dieselben Prinzipien gelten für gekühlte Transporte, die im Artikel zur Kühlkettenüberwachung behandelt werden; dieser hier konzentriert sich auf fest installierte Tiefkühler und Kühlräume in Werk, Lager oder Küche.
Das Setup
| Komponente | Aufgabe | Beispiel |
|---|---|---|
| Temperaturfühler | Misst Luft- oder Produkttemperatur | Wasserdichter DS18B20 an einem Flachkabel durch die Türdichtung |
| Türkontakt | Erklärt kurze Temperaturanstiege | Reedschalter am Türrahmen |
| Sensorknoten | Liest Fühler und Tür, veröffentlicht | ESP32 außerhalb des Tiefkühlers mit Netzversorgung |
| MQTT-Broker | Empfängt Messwerte und Alarme | Verwalteter MQTT-Broker von ConnectMQ |
| Alarmlogik | Erkennung von Abweichungen und Ausfällen | Schwellenwertregeln im Portal plus ein Python-Dienst |
| Abweichungsprotokoll | Nachweis für Audits und Reklamationen | Datenbank, die der Alarmdienst beschreibt |
Halten Sie den ESP32 außerhalb des Kühlbereichs. Elektronik und Batterien kommen mit Tiefkühltemperaturen schlecht zurecht, und WLAN-Signale dringen nicht durch die Metallwände eines Kühlraums. Nur das Fühlerkabel kommt nach innen.
Wo der Fühler hingehört
Die Lufttemperatur nahe dem Verdampfer ändert sich schnell und übertreibt jede Türöffnung. Die Produkttemperatur ändert sich langsam und spiegelt wider, worauf es tatsächlich ankommt. Ein gängiger Kompromiss ist, den Fühler im wärmsten Bereich des Raums, entfernt vom Verdampferauslass, zu platzieren und ihn optional in eine kleine Flasche mit Glykol oder einen Produktsimulator zu stecken, der ihn puffert, sodass die Messwerte der Produkttemperatur folgen statt Luftstößen. Kartieren Sie den Raum einmal mit einigen Fühlern, um die warme Stelle zu finden, bevor Sie die dauerhafte Position wählen.
Sensor-Firmware
Der folgende Sketch veröffentlicht Temperatur und Türzustand alle 30 Sekunden sowie sofort bei einer Türänderung. Er setzt eine Last-Will-Nachricht, sodass der Broker den Sensor als offline meldet, wenn er verschwindet. Installieren Sie PubSubClient, OneWire und DallasTemperature. Details zur Verdrahtung des Sensors finden Sie im Tutorial ESP32 DS18B20 MQTT.
#include <WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* CLIENT_ID = "freezer2-6c0f3b";
const char* BASE = "connectmq/demo/6c0f3b/warehouse/freezer2";
const int PROBE_PIN = 4;
const int DOOR_PIN = 27; // Reedschalter gegen GND, Tür geschlossen = LOW
const uint32_t PERIOD_MS = 30000;
OneWire oneWire(PROBE_PIN);
DallasTemperature probe(&oneWire);
WiFiClient net;
PubSubClient mqtt(net);
char topicTelemetry[96], topicStatus[96];
int lastDoor = -1;
uint32_t lastPub = 0;
void connectAll() {
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(250);
}
while (!mqtt.connected()) {
if (mqtt.connect(CLIENT_ID, topicStatus, 1, true, "offline")) {
mqtt.publish(topicStatus, "online", true);
} else {
delay(3000);
}
}
}
void publishReading(bool doorOpen) {
probe.requestTemperatures();
float t = probe.getTempCByIndex(0);
char payload[128];
if (t == DEVICE_DISCONNECTED_C) {
snprintf(payload, sizeof(payload), "{\"temp_c\":null,\"door_open\":%s,\"fault\":\"probe\"}",
doorOpen ? "true" : "false");
} else {
snprintf(payload, sizeof(payload), "{\"temp_c\":%.2f,\"door_open\":%s,\"rssi\":%d}",
t, doorOpen ? "true" : "false", WiFi.RSSI());
}
mqtt.publish(topicTelemetry, payload, true);
}
void setup() {
pinMode(DOOR_PIN, INPUT_PULLUP);
snprintf(topicTelemetry, sizeof(topicTelemetry), "%s/telemetry", BASE);
snprintf(topicStatus, sizeof(topicStatus), "%s/status", BASE);
probe.begin();
WiFi.mode(WIFI_STA);
mqtt.setServer("broker.connectmq.com", 1883);
connectAll();
}
void loop() {
connectAll();
mqtt.loop();
int door = digitalRead(DOOR_PIN) == HIGH; // HIGH = Magnet entfernt = offen
if (door != lastDoor || millis() - lastPub >= PERIOD_MS) {
publishReading(door);
lastDoor = door;
lastPub = millis();
}
delay(200);
}
Der Last Will ist das Sicherheitsnetz, das ein manuelles Protokoll nie hatte: Verliert der Knoten Strom oder WLAN, veröffentlicht der Broker nach Ablauf des Keepalive-Timeouts offline auf dem Status-Topic. Die Anleitung ESP32 MQTT Last Will erklärt den Mechanismus.
Abweichungslogik ohne Störalarme
Der naive Ansatz, bei jeder Grenzwertüberschreitung zu alarmieren, scheitert innerhalb eines Tages. Jede Anlieferung öffnet die Tür, die Lufttemperatur springt nach oben, und das Personal lernt, den Alarm zu ignorieren. Eine gute Kühlhaus-Temperaturüberwachung kombiniert mehrere Regeln:
- Grenzwert plus Verzögerung. Eine Abweichung wird nur gemeldet, wenn die Temperatur eine festgelegte Zeit über dem Grenzwert bleibt, zum Beispiel 15 Minuten bei einem Tiefkühler.
- Türabhängige Verzögerung. Solange die Tür offen ist, gilt eine längere Karenzzeit, aber ein separater Tür-offen-Alarm wird ausgelöst, wenn sie zu lange offen bleibt.
- Harter Grenzwert. Eine deutlich höhere Temperatur löst unabhängig von der Verzögerung sofort aus.
- Ausfälle und Fühlerfehler. Ein verstummter Sensor oder ein abgeklemmter Fühler ist ein eigener Alarm.
- Abweichungsdatensatz. Jede Abweichung erhält Startzeit, Endzeit, Spitzentemperatur und Dauer.
Die Grenzwerte selbst ergeben sich aus Ihren Produkten und Ihrem Lebensmittelsicherheits- bzw. Qualitätsplan (etwa dem HACCP-Konzept). Verwenden Sie diese Unterlagen statt pauschaler Zahlen.
Abweichungsdienst in Python
import json
import sqlite3
import time
import paho.mqtt.client as mqtt
PREFIX = "connectmq/demo/6c0f3b/warehouse"
LIMIT_C = -15.0 # aus Ihren Produktanforderungen
HARD_LIMIT_C = -5.0
DELAY_S = 15 * 60
DOOR_MAX_S = 5 * 60
STALE_S = 3 * 60
db = sqlite3.connect("excursions.db", check_same_thread=False)
db.execute("""CREATE TABLE IF NOT EXISTS excursions (
unit TEXT, start_ts INTEGER, end_ts INTEGER, peak_c REAL, reason TEXT)""")
units = {}
def alert(client, unit, kind, detail):
msg = {"ts": int(time.time()), "unit": unit, "kind": kind, **detail}
client.publish(f"{PREFIX}/{unit}/alert", json.dumps(msg), qos=1, retain=True)
print("ALERT", msg)
def on_connect(client, userdata, flags, reason_code, properties):
client.subscribe(f"{PREFIX}/+/telemetry", qos=1)
client.subscribe(f"{PREFIX}/+/status", qos=1)
def on_message(client, userdata, msg):
unit = msg.topic.split("/")[4]
now = time.time()
u = units.setdefault(unit, {"above_since": None, "door_since": None,
"excursion": None, "seen": now})
if msg.topic.endswith("/status"):
if msg.payload == b"offline":
alert(client, unit, "offline", {})
return
d = json.loads(msg.payload)
u["seen"] = now
if d.get("temp_c") is None:
alert(client, unit, "probe_fault", {})
return
t = d["temp_c"]
u["door_since"] = (u["door_since"] or now) if d["door_open"] else None
if u["door_since"] and now - u["door_since"] > DOOR_MAX_S:
alert(client, unit, "door_open_too_long", {"seconds": int(now - u["door_since"])})
u["door_since"] = now
if t > LIMIT_C:
u["above_since"] = u["above_since"] or now
delay = DELAY_S * (2 if d["door_open"] else 1)
exc = u["excursion"]
if exc:
exc["peak"] = max(exc["peak"], t)
elif t > HARD_LIMIT_C or now - u["above_since"] > delay:
u["excursion"] = {"start": u["above_since"], "peak": t}
alert(client, unit, "excursion_start", {"temp_c": t, "limit_c": LIMIT_C})
else:
exc = u["excursion"]
if exc:
db.execute("INSERT INTO excursions VALUES (?,?,?,?,?)",
(unit, int(exc["start"]), int(now), exc["peak"], "above_limit"))
db.commit()
alert(client, unit, "excursion_end",
{"duration_min": round((now - exc["start"]) / 60, 1), "peak_c": exc["peak"]})
u["above_since"] = None
u["excursion"] = None
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="cold-alerts-6c0f3b")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
while True:
time.sleep(30)
for unit, u in units.items():
if time.time() - u["seen"] > STALE_S:
alert(client, unit, "stale", {"seconds_silent": int(time.time() - u["seen"])})
u["seen"] = time.time()
Als Startzeit der Abweichung wird der Moment erfasst, in dem die Temperatur den Grenzwert erstmals überschritten hat, nicht der Ablauf der Verzögerung, sodass das Protokoll die tatsächliche Dauer zeigt. Für die einfachsten Fälle können Sie Schwellenwert-Alarmregeln auf das Feld temp_c auch direkt im ConnectMQ-Portal anlegen und jede Überschreitung im Alarmprotokoll nachvollziehen, während der Python-Dienst die Verzögerungs- und Türlogik übernimmt.
Alarme an die richtigen Personen bringen
Der Dienst veröffentlicht Alarme über MQTT; um 3 Uhr nachts muss aber trotzdem etwas ein Telefon erreichen. Da ConnectMQ selbst keine E-Mails oder SMS versendet, ist das ehrliche Muster ein externes Werkzeug, das die Alarm-Topics abonniert: ein Node-RED-Flow mit einem E-Mail- oder Messaging-Node, Home-Assistant-Benachrichtigungen für kleinere Standorte oder ein paar zusätzliche Zeilen im Python-Dienst, die Ihren Benachrichtigungsanbieter aufrufen. Legen Sie einen Eskalationspfad fest: zuerst die Schichtleitung, dann die Rufbereitschaft der Instandhaltung, dann die Standortleitung, falls niemand quittiert.
Umgang mit Abtauzyklen
Automatisches Abtauen ist die andere häufige Ursache für Fehlalarme. Während des Abtauens erwärmt sich der Verdampfer, und die Lufttemperatur in seiner Nähe steigt kurzzeitig an, was normal ist. Drei Maßnahmen verhindern, dass dadurch Abweichungen ausgelöst werden. Erstens halten Sie den Fühler wie oben beschrieben vom Verdampfer fern. Zweitens stellen Sie sicher, dass die Abweichungsverzögerung länger ist als ein normaler Abtauzyklus dieses Geräts, was Sie in den aufgezeichneten Daten eines Tages deutlich sehen. Drittens: Stellt der Kälteregler ein Abtausignal bereit, veröffentlichen Sie es zusammen mit der Temperatur und verlängern die Verzögerung während des Abtauens, genau wie es der Dienst bei Türöffnungen tut. Ein Abtauvorgang, der deutlich länger als üblich dauert, ist selbst einen Alarm wert, denn er deutet oft auf eine defekte Heizung, einen defekten Fühler oder eine falsche Reglereinstellung hin.
Checkliste für den Rollout
- Kartieren Sie jeden Raum einen Tag lang mit mehreren Fühlern, um die warme Stelle zu finden.
- Installieren Sie einen Knoten pro Gerät, Elektronik außen, Fühler an der warmen Stelle.
- Legen Sie Grenzwerte und Verzögerungen anhand Ihrer Produktanforderungen und Ihres Qualitätsplans fest.
- Testen Sie die Alarme: Tür öffnen, Knoten vom Strom trennen, Fühler abklemmen, und bestätigen Sie, dass jeder Alarm ankommt.
- Kalibrieren Sie die Fühler gegen ein Referenzthermometer und dokumentieren Sie die Prüfung.
- Prüfen Sie das Abweichungsprotokoll wöchentlich und gehen Sie Wiederholungsfällen nach, etwa einer Tür, die oft offen bleibt.
- Wechseln Sie vor dem Go-live auf einen privaten Broker mit Zugangsdaten aus dem Portal und TLS auf Port 8883.
Von der Demo zur Produktion
Das Tutorial läuft auf dem öffentlichen MQTT-Broker, auf dem alle Topics für jeden sichtbar sind. Das ist zum Testen in Ordnung, nicht aber für Betriebsdaten. Für die Produktion gibt ein Cloud-MQTT-Broker jedem Tiefkühlknoten eine verschlüsselte, authentifizierte Verbindung und erlaubt Alarmdienst, Dashboards und Qualitätsteam, von überall zu abonnieren. Temperaturaufzeichnungen ergänzen außerdem die IoT-Qualitätskontrolle in der Fertigung und die chargenbezogene Rückverfolgbarkeit in der Fertigung, da sich Abweichungszeiträume mit den zu dieser Zeit gelagerten Losen verknüpfen lassen. Der Smart-Manufacturing-Leitfaden ordnet all das in eine werksweite Architektur ein.
Überwachen Sie Ihr Kühlhaus mit ConnectMQ
ConnectMQ bietet einen privaten MQTT-Broker mit TLS, Last-Will-Unterstützung, retained Messages, einem Live-Dashboard und Schwellenwert-Alarmregeln im Portal. Erstellen Sie unter app.connectmq.com einen Broker im kostenlosen Serverless-Plan, ganz ohne Kreditkarte, und verbinden Sie noch heute Ihren ersten Tiefkühler.
Häufig gestellte Fragen
Wie oft sollte die Kühlhaustemperatur erfasst werden?
Für die kontinuierliche Überwachung sind 30 Sekunden bis 5 Minuten üblich. Schnellere Meldungen ermöglichen schnellere Alarme, während die Abweichungsverzögerung Störalarme verhindert.
Wie vermeide ich Alarme bei jeder Türöffnung?
Verlangen Sie, dass die Temperatur eine Verzögerungszeit lang über dem Grenzwert bleibt, bevor alarmiert wird, verlängern Sie diese Verzögerung bei offener Tür und lösen Sie einen separaten Alarm aus, wenn die Tür zu lange offen bleibt.
Was passiert, wenn ein Sensor keinen Strom mehr hat?
Mit einer Last-Will-Nachricht veröffentlicht der Broker nach Ablauf des Keepalive-Timeouts einen Offline-Status, und der Alarmdienst behandelt ihn als Alarm.
Sollte der Fühler Luft- oder Produkttemperatur messen?
Die Produkttemperatur ist am wichtigsten. Wird der Fühler in einem Puffer wie einer Glykolflasche an der wärmsten Stelle platziert, folgen die Messwerte der Produkttemperatur und ignorieren kurze Luftspitzen.



