Günstige Bits, klare Daten: So entsteht dein eigenes Klima-Monitoring fürs ganze Haus
share forum

Günstige Bits, klare Daten: So entsteht dein eigenes Klima-Monitoring fürs ganze Haus


Technik • von Sven Reifschneider • 14. Mai 2025 • 0 Kommentare

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:

  1. Prüft Climate::$sensors, ignoriert unbekannte IDs
  2. Verwirft Duplikate innerhalb 15 Minuten
  3. Speichert in MySQL (oder SQLite/PostgreSQL, Laravels Eloquent unterstützt alles)
  4. 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:

  1. Raumweise Klima-Daten erfassen
  2. Diese lokal speichern, ohne Anbieterbindung
  3. Deine Smart-Home-Systeme per MQTT versorgen
  4. 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.


Teile diesen Beitrag

Wenn dir dieser Artikel gefallen hat, teile ihn doch mit deinen Freunden und Bekannten! Das hilft mir dabei, noch mehr Leute zu erreichen und motiviert mich, weiterhin großartige Inhalte für euch zu erstellen. Nutze einfach die Sharing-Buttons hier unten, um den Beitrag auf deinen bevorzugten sozialen Medien zu teilen. Danke dir!

Please consider sharing this post
Please consider donating

Unterstütze den Blog

Falls du meine Arbeit und diesen Blog besonders schätzen solltest, würde ich mich riesig freuen, wenn du mich unterstützen möchtest! Du kannst mir zum Beispiel einen Kaffee spendieren, um mich bei der Arbeit an neuen Artikeln zu erfrischen, oder einfach so, um den Fortbestand des Blogs zu fördern. Jede noch so kleine Spende ist herzlich willkommen und wird sehr geschätzt!

currency_bitcoin Spende via Kryptowährungen
Bitcoin (BTC):1JZ4inmKVbM2aP5ujyvmYpzmJRCC6xS6Fu
Ethereum (ETH):0xC66B1D5ff486E7EbeEB698397F2a7b120e17A6bE
Litecoin (LTC):Laj2CkWBD1jt4ZP6g9ZQJu1GSnwEtsSGLf
Sven Reifschneider
Über den Autor

Sven Reifschneider

Herzliche Grüße! Ich bin Sven, ein technischer Innovator und begeisterter Fotograf aus der malerischen Wetterau, in der Nähe des lebendigen Frankfurt/Rhein-Main-Gebiets. In diesem Blog verbinde ich mein umfangreiches technisches Wissen mit meiner künstlerischen Leidenschaft, um Geschichten zu erschaffen, die fesseln und erleuchten. Als Leiter von Neoground spreng ich die Grenzen der KI-Beratung und digitalen Innovation und setze mich für Veränderungen ein, die durch Open Source Technologie Widerhall finden.

Die Fotografie ist mein Portal, um die flüchtige Schönheit des Lebens auszudrücken, die ich nahtlos mit technologischen Einsichten verbinde. Hier trifft Kunst auf Innovation, jeder Beitrag strebt nach Exzellenz und entfacht Gespräche, die inspirieren.

Neugierig, mehr zu erfahren? Folge mir in den sozialen Medien oder klicke auf "Mehr erfahren", um das Wesen meiner Vision zu erkunden.


Noch keine Kommentare

Kommentar hinzufügen

In deinem Kommentar kannst du **Markdown** nutzen. Deine E-Mail-Adresse wird nicht veröffentlicht. Mehr zum Datenschutz findest du in der Datenschutzerklärung.