Warum ich mein eigenes Klimamonitoring wollte
Ich mag Zahlen mehr als Vermutungen. Vor über fünf Wintern installierte ich zwei TFA Dostmann Temperatur-/Luftfeuchtesensoren – einen im Wohnzimmer, einen im Keller. Ziel: Beobachten, wie schnell das Haus über Nacht auskühlt. Die 20€-Sensoren zeigten Werte auf LCDs, doch mit dem Notizbuch durchs Haus zu laufen, verlor schnell seinen Reiz. Ich wollte die Daten zentral, dauerhaft und idealerweise auf einem Dashboard.
Naheliegende Lösung? IoT-Gadgets. Aber die erschienen mir falsch: teuer, Akkulaufzeit von Monaten statt Jahren, dazu proprietäre Clouds. Dann entdeckte ich baycom/tfrec von Georg Acher & Deti Fliegl. Ein kleines Open-Source-Tool, das die 868-MHz-Pakete meiner Sensoren direkt dekodiert. Alles, was man braucht: ein RTL2832U DVB-T Stick, wie er in vielen Bastelschubladen liegt.
Das Tool versteht Daten von KlimaLogg Pro und ähnlichen Sensoren von TFA Dostmann, Technoline oder kompatiblen LaCrosse-Modellen. In sensors.txt findest du eine große Liste unterstützter Geräte, inkl. Wind-, Regen- oder Poolsensoren.
Das war der Aha-Moment: Günstige Hardware, der ich traue. Open-Source-Software. Und batteriefreundliche Sensoren aus dem Baumarkt.
Einkaufsliste
Komponente | Preis | Hinweise |
---|---|---|
RTL2832U DVB-T Stick (mit R820T-Tuner) | 20–30 € | Als SDR-Empfänger für verschiedenste Anwendungen geeignet. |
868-MHz Temperatur-/Feuchtesensor (TFA/Technoline/LaCrosse) | 15–20 € | Mit LCD, 2x AA-Batterien (halten 4–5 Jahre). Auch Modelle für Pool/Wind/Regen verfügbar. |
Linux-Host (Raspberry Pi, altes Notebook, VM) | ab 15 € (z. B. Pi Zero 2 W) | Jedes Gerät, das rtl_sdr ausführen kann. |
Optional: bessere 868 MHz Antenne | 5–10 € | Die Standardantenne reicht meist. Eine größere Antenne verbessert den Empfang in Randzonen. |
Ich begann mit zwei Sensoren. Als das funktionierte, kamen weitere hinzu. Heute erfasse ich das gesamte Haus – 12 Sensoren über drei Etagen Stahlbeton (inkl. Keller). Die Standardantenne des DVB-T-Sticks reicht hierfür völlig.
Ein wertvoller Zusatz für meine eigene Wetterstation.
tfrec installieren
sudo apt install git build-essential rtl-sdr
git clone https://github.com/baycom/tfrec
cd tfrec
make
sudo cp tfrec /usr/bin/
Was tfrec macht:
- Liest rohe I/Q-Daten von
rtl_sdr
- Erfasst das On-Off-Keying-Muster kompatibler Sensoren
- Gibt ID, Temperatur (°C), Luftfeuchte (%), RSSI, Batteriestatus & Zeitstempel aus
- Optional: Führt ein Kommando mit diesen Werten als Parameter aus
Keine Kernelmodule, keine Magie. Nur libusb.
Ein erster manueller Test
Führe tfrec mit -d
aus, um im Debug-Modus zu starten:
sudo /opt/bin/tfrec -d
Beispielausgabe:
16b4 +23.8 41 27 0 -60
92af +22.1 45 18 0 -63
ID + Temperatur + Feuchte + Sequenz + Batterie (0=OK) + Signalstärke (dB).
Wenn nichts erscheint: Antenne weiter vom USB-Anschluss entfernen oder Sensoren / Error Output prüfen.
Automatisierung mit systemd
Ich wollte:
- Alle 30 Minuten 60 Sekunden lang lauschen
- Neustart bei hängendem rtl_sdr (selten, aber passierte gelegentlich in den letzten Jahren, das timeout ist 180 s = 3 min)
- Protokollierung via
journalctl
Service-Unit
Wir erstellen einen simplen systemd Service der unser tfrec Skript startet, unter /etc/systemd/system/tfrec.service
:
[Unit]
Description=Receive 868 MHz climate data and pass to handler
[Service]
Type=simple
User=root
ExecStart=/bin/bash /opt/tfrec.sh
TimeoutStartSec=180
Timer-Unit
Und passend dazu erstellen wir einen systemd timer, der unseren Service (und damit unser Skript) alle 30 Minuten (Minute 0 und 30 jeder Stunde) ausführt, unter /etc/systemd/system/tfrec.timer
:
[Unit]
Description=Run tfrec every 30 minutes
[Timer]
OnCalendar=*:0,30
AccuracySec=1min
Persistent=true
[Install]
WantedBy=timers.target
Beide aktivieren:
sudo systemctl daemon-reload
sudo systemctl enable --now tfrec.timer
Das Wrapper-Skript
In unserem Beispiel legen wir unser Skript hier ab: /opt/tfrec.sh
. Du kannst es an einem anderen Ort ablegen, solange dieser logisch erscheint und das Skript von dort ausgeführt werden kann.
#!/usr/bin/env bash
/usr/bin/tfrec -q -w 60 -e "php /var/www/cli.php climate:add"
exit 0
-q
= stiller Modus-w 60
= Lauschen für 60 Sekunden-e
= Aufruf des PHP-Skripts mit Daten für jedes Paket
Nicht vergessen: chmod +x tfrec.sh
setzen, damit man es ausführen kann.
Daten speichern mit PHP
Falls du lieber Python nutzt: kein Problem. Die Logik bleibt: Werte als Argumente in tfrecs Reihenfolge entgegennehmen, validieren, speichern oder weiterleiten.
Mein Beispiel basiert auf dem Charm Framework, aber dies ist sehr ähnlich zu Laravel und Symfony und somit leicht zu verstehen.
CLI-Befehl climate:add
Der Befehl basiert auf symfony/console. Highlights:
- Prüft
Climate::$sensors
, ignoriert unbekannte IDs - Verwirft Duplikate innerhalb 15 Minuten
- Speichert in MySQL (oder SQLite/PostgreSQL, Laravels Eloquent unterstützt alles)
- Veröffentlicht aktuelle Werte per MQTT via php-mqtt/client
use App\Models\Climate;
use Carbon\Carbon;
use Charm\Bob\Command;
use Charm\Vivid\C;
use PhpMqtt\Client\ConnectionSettings;
use PhpMqtt\Client\MqttClient;
use Symfony\Component\Console\Input\InputArgument;
class ClimateAdd extends Command
{
protected function configure()
{
$this->setName("climate:add")
->setDescription("Store tfrec sensor reading")
->addArgument('id', InputArgument::REQUIRED)
->addArgument('temp', InputArgument::REQUIRED)
->addArgument('hum', InputArgument::REQUIRED)
->addArgument('seq', InputArgument::REQUIRED)
->addArgument('batfail', InputArgument::REQUIRED)
->addArgument('rssi', InputArgument::REQUIRED)
->addArgument('timestamp',InputArgument::OPTIONAL);
}
public function main(): bool
{
$id = $this->io->getArgument('id');
$temp = (double)$this->io->getArgument('temp');
$hum = (int)$this->io->getArgument('hum');
$batfail = (bool)$this->io->getArgument('batfail');
$rssi = (int)$this->io->getArgument('rssi');
$timestamp = $this->io->getArgument('timestamp');
// Validate sensor
if (!array_key_exists($id, Climate::$sensors)) {
return true;
}
// 15‑minute duplicate check
$recent = Climate::where('sensor_id', $id)
->where('time', '>=', Carbon::now()->subMinutes(15))
->first();
if ($recent) {
return true;
}
$c = new Climate();
$c->sensor_id = $id;
$c->temperature = str_replace("+", "", $temp);
$c->humidity = $hum;
$c->rssi = $rssi;
$c->low_battery = $batfail;
$c->time = Carbon::createFromTimestamp($timestamp);
$c->save();
$this->publishViaMqtt($c);
return true;
}
private function publishViaMqtt(Climate $c)
{
$client = new MqttClient(
C::Config()->get('connections:mqtt.server'),
C::Config()->get('connections:mqtt.port'),
C::Config()->get('connections:mqtt.client_id')
);
$settings = (new ConnectionSettings())
->setUsername(C::Config()->get('connections:mqtt.username'))
->setPassword(C::Config()->get('connections:mqtt.password'));
$client->connect($settings, true);
$client->publish("/tfrec/{$c->sensor_id}/temp", $c->temperature);
$client->publish("/tfrec/{$c->sensor_id}/hygro", $c->humidity);
$client->disconnect();
}
}
Datenbankmodell
class Climate extends Model
{
protected $table = 'tfrec';
protected $casts = ['time' => 'datetime'];
public $timestamps = false;
public static $sensors = [
'16b4' => 'Entrance',
'92af' => 'Kitchen',
'5d43' => 'Livingroom',
'6ac9' => 'Bedroom',
];
public static function getTableStructure(): \Closure
{
return function (Blueprint $table) {
$table->increments('id');
$table->string('sensor_id')->index();
$table->decimal('temperature', 4, 1);
$table->decimal('humidity', 4, 1);
$table->tinyInteger('rssi')->nullable();
$table->tinyInteger('low_battery')->nullable();
$table->dateTime('time');
};
}
}
Du kannst MQTT auch alleine verwenden oder SQLite als lokalen Speicher nutzen.
Warum MQTT alles einfacher macht
Wie auch immer dein Skript ausschaut, macht es Sinn, dass dieses die Daten an MQTT weitergibt, damit du diese einfach in deinen Anwendungen nutzen kannst:
- OpenHAB / Home Assistant abonnieren
/tfrec/#
und erkennen Sensoren automatisch - Node-RED kann mit wenigen Klicks Alarme, Schwellen oder Grafana-Feeds erzeugen
- Grafana-Dashboards lassen sich elegant auf einem Wandtablet anzeigen
- Jedes Gerät, jede Sprache kann die Daten lesen
Nach ein wenig Einrichtung zeigt mein OpenHAB Dashboard die Temperatur und Luftfeuchte auf den Raumkarten an, und bietet Diagramme, Zustände und die Möglichkeit zur Automatisierung.
Stabilität nach 5+ Jahren Nutzung
Aspekt | Erfahrung |
---|---|
Batterien | Halten 1–3 Jahre, Austausch selten nötig |
Datenverluste | 1–2 Dropouts pro Woche auf dem entferntesten Sensor |
tfrec Stabilität | Ca. alle 2–3 Monate ein rtl_sdr-Hänger, systemd startet automatisch neu |
Reichweite | Standard-Antenne reicht für 15 m durch zwei Stahlbetondecken, mehr als genug für mich. |
Fast alle Empfangsprobleme lassen sich durch einen Batteriewechsel beheben, sollte ein Sensor mal länger verschwinden.
Warum RTL-SDR-Sticks ideal dafür sind
- Weit verbreitet. In jeder Bastelkiste oder Elektronikladen zu finden
- Vielseitig. ADS-B, Pager, Wetter-Satelliten, alles möglich mit anderer Software
- Günstig. Ersatz kostet 20 €
- Gut unterstützt.
rtl-sdr
ist in fast jeder Linux-Distro enthalten
Fazit
Mit ein paar Komponenten und einem Nachmittag Arbeit kannst du:
- Raumweise Klima-Daten erfassen
- Diese lokal speichern, ohne Anbieterbindung
- Deine Smart-Home-Systeme per MQTT versorgen
- Einfach erweitern: Pooltemperatur, Wind, Regen? tfrec unterstützt es
Was als kleines Experiment mit zwei Sensoren begann, ist heute mein zuverlässiges Haus-Klimanetzwerk. Wenn du es ausprobierst, berichte gern. Zuverlässige Daten haben oft die schönste Nebenwirkung: neue Ideen.
Happy Hacking!
Dieser Beitrag wurde von mir mit Unterstützung durch KI (GPT o3) erstellt. Illustrationen wurden von mir mit Sora generiert. Entdecke, wie KI deine Inhalte inspirieren kann – Neoground GmbH.
Noch keine Kommentare
Kommentar hinzufügen