{"id":564,"date":"2026-10-11T23:19:22","date_gmt":"2026-10-11T21:19:22","guid":{"rendered":"https:\/\/www.richard-becker.net\/blog\/?p=564"},"modified":"2026-10-23T08:47:35","modified_gmt":"2026-10-23T06:47:35","slug":"kamstrup-flowiq-2200-auslesen-wasserzaehler-mit-tasmota-und-esp8266-smart-machen","status":"publish","type":"post","link":"https:\/\/www.richard-becker.net\/blog\/2026\/10\/11\/kamstrup-flowiq-2200-auslesen-wasserzaehler-mit-tasmota-und-esp8266-smart-machen\/","title":{"rendered":"Kamstrup flowIQ 2200 auslesen: Wasserz\u00e4hler mit Tasmota und ESP8266 smart machen"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><strong>Wasserverbrauch automatisch erfassen, ohne Cloud, ohne Hersteller-App und ohne jeden Monat mit der Taschenlampe in den Keller zu kriechen?<\/strong> Klingt nach einem guten Plan. Mit einem Wemos D1 Mini, einem optischen IR-Lesekopf und Tasmota l\u00e4sst sich der Kamstrup flowIQ 2200 direkt ins eigene Smart Home integrieren. Sogar die verbleibende Batterielaufzeit gibt der Wasserz\u00e4hler preis. Ganz freiwillig allerdings nicht \u2013 wir m\u00fcssen ihn erst danach fragen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Kann das Ding nicht eigentlich funken?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Doch. Kann es. Und genau das macht die Sache ein bisschen absurd. Der Kamstrup flowIQ 2200 bringt n\u00e4mlich bereits eine Funkschnittstelle mit. Theoretisch m\u00fcssten wir uns also gar nicht mit IR-Lesek\u00f6pfen, ESP8266 und kryptischen HEX-Telegrammen besch\u00e4ftigen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Theoretisch.<\/strong> Etwa ein halbes Jahr vor dem angek\u00fcndigten Z\u00e4hlerwechsel hatte ich mich deshalb schon einmal freundlich bei meinem Wasserversorger gemeldet. Mein bisheriger analoger Wasserz\u00e4hler war schlie\u00dflich l\u00e4ngst in mein Smart Home eingebunden und das sollte nach dem Austausch m\u00f6glichst auch so bleiben. Man k\u00f6nnte meinen, ein moderner, funkf\u00e4higer Wasserz\u00e4hler w\u00e4re daf\u00fcr die perfekte Voraussetzung.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die erste Antwort klang auch vielversprechend: Man werde sich melden. Spoiler: Tat man nicht. Ein halbes Jahr Funkstille sp\u00e4ter wurde der Z\u00e4hler ausgetauscht. Also habe ich noch einmal nachgefragt. Wieder vergingen einige Wochen. Inzwischen wusste ich immerhin, welches Modell bei mir verbaut war, und konnte meine Anfrage etwas konkreter formulieren. Geholfen hat das allerdings nur bedingt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Denn f\u00fcr die verschl\u00fcsselte Funkkommunikation ben\u00f6tigt man den passenden <strong>AES-Schl\u00fcssel<\/strong>. Ohne den kann man die Funktelegramme zwar grunds\u00e4tzlich empfangen, aber mit den verschl\u00fcsselten Daten herzlich wenig anfangen. Und genau diesen Schl\u00fcssel wollte man nicht zur Verf\u00fcgung stellen. Die Begr\u00fcndung: Sowohl der Wasserz\u00e4hler als auch der zugeh\u00f6rige Schl\u00fcssel seien Eigentum des Wasserversorgers. Und das solle auch so bleiben. Tja.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Da h\u00e4ngt also ein smarter, funkf\u00e4higer Wasserz\u00e4hler in meinem Keller, der seine Messwerte drahtlos \u00fcbertragen kann. Nur ich als derjenige, dessen Wasserverbrauch da gemessen wird, darf mit den Daten auf diesem Weg nichts anfangen. <strong>Smart ist der Z\u00e4hler damit vor allem f\u00fcr den Wasserversorger. F\u00fcr mich ist er erst einmal ein digitaler Z\u00e4hler mit eingebautem \u201eDu kommst hier nicht rein!\u201c.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Und genau deshalb h\u00e4ngen jetzt ein IR-Lesekopf und ein ESP8266 davor. Manchmal ist sowas eben weniger eine Frage des technisch Sinnvollen als des technisch Erlaubten. <em>Seufz.<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Als Alternative empfahl mir mein Wasserversorger \u00fcbrigens den <strong><a href=\"https:\/\/www.kamstrup.com\/de-de\/product-centre\/pulse-adapter-flowiq-2200-3200\" data-type=\"link\" data-id=\"https:\/\/www.kamstrup.com\/de-de\/product-centre\/pulse-adapter-flowiq-2200-3200\" target=\"_blank\" rel=\"noopener\">Kamstrup Pulse Adapter (Typ 66-99-051)<\/a><\/strong>, einen speziellen Impulsadapter f\u00fcr den flowIQ 2200. Der wird direkt am Wasserz\u00e4hler befestigt und gibt f\u00fcr jeweils zehn Liter Wasserverbrauch einen elektrischen Impuls aus. Kostenpunkt laut Empfehlung: schlanke <strong>170 Euro<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ernsthaft jetzt? Da h\u00e4ngt ein hochmoderner, funkf\u00e4higer Wasserz\u00e4hler an meiner Wand, der die gew\u00fcnschten Daten l\u00e4ngst digital bereitstellt. Aber weil ich den AES-Schl\u00fcssel nicht bekomme, soll ich 170 Euro f\u00fcr ein zus\u00e4tzliches Ger\u00e4t ausgeben, das mir den Wasserverbrauch wieder als simple Z\u00e4hlimpulse ausspuckt? <strong>Digitalisierung r\u00fcckw\u00e4rts. F\u00fcr 170 Euro. Kannste dir nicht ausdenken.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Die Hardware: ESP8266 trifft Wasserz\u00e4hler<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr das Projekt brauchen wir tats\u00e4chlich nicht viel. <strong>Meine Einkaufsliste:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Wemos D1 Mini mit ESP8266<\/li>\n\n\n\n<li>Optischer IR-Schreib-Lesekopf mit TTL-Schnittstelle<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1008\" height=\"756\" src=\"https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/wemosd1mini.jpg\" alt=\"\" class=\"wp-image-571\" srcset=\"https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/wemosd1mini.jpg 1008w, https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/wemosd1mini-300x225.jpg 300w, https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/wemosd1mini-768x576.jpg 768w\" sizes=\"auto, (max-width: 1008px) 100vw, 1008px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Als Lesekopf eignet sich beispielsweise die Variante aus dem <a href=\"https:\/\/wiki.volkszaehler.org\/hardware\/controllers\/ir-schreib-lesekopf-ttl-ausgang\" target=\"_blank\" rel=\"noopener\">Volksz\u00e4hler-Wiki<\/a>. <strong>Wichtig:<\/strong> Der Lesekopf muss senden <strong>und<\/strong> empfangen k\u00f6nnen. Ein einfacher IR-Empf\u00e4nger reicht hier nicht aus. Der Kamstrup sendet seine Informationen n\u00e4mlich nicht einfach permanent in die Gegend, in der Hoffnung, dass zuf\u00e4llig jemand zuh\u00f6rt. Stattdessen m\u00fcssen wir ihm gezielt mitteilen, welche Informationen wir haben m\u00f6chten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Verkabelung: Vier Kabel und die erste Stolperfalle<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Die Verkabelung ist \u00fcberschaubar. Der IR-Lesekopf wird direkt mit dem Wemos D1 Mini verbunden:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Wemos D1 Mini<\/th><th>GPIO<\/th><th>IR-Lesekopf<\/th><\/tr><tr><td>TX<\/td><td>GPIO1<\/td><td>TX<\/td><\/tr><tr><td>RX<\/td><td>GPIO3<\/td><td>RX<\/td><\/tr><tr><td>3V3<\/td><td>\u2013<\/td><td>VCC<\/td><\/tr><tr><td>GND<\/td><td>\u2013<\/td><td>GND<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wir verwenden also die Hardware-UART des ESP8266. GPIO1 dient zum Senden der Daten und GPIO3 zum Empfangen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Achtung bei TX und RX!<\/strong> Das ist einer dieser Momente, bei denen man sich fragt, warum Hardwarehersteller offenbar unterschiedliche Vorstellungen davon haben, was eine eindeutige Beschriftung ist. Je nach Lesekopf beziehen sich TX und RX auf die Signalrichtung des Lesekopfs oder auf die angeschlossene Hardware. Bei der hier verwendeten Belegung verbinden wir TX mit TX und RX mit RX. Bei einem anders beschrifteten Lesekopf kann das abweichen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Falls sp\u00e4ter keine Daten ankommen, ist das also einer der ersten Punkte, die ihr \u00fcberpr\u00fcfen solltet. Der verwendete Lesekopf muss au\u00dferdem f\u00fcr eine Versorgung mit 3,3 Volt geeignet sein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Anschlie\u00dfend wird der Lesekopf auf der optischen Schnittstelle des Wasserz\u00e4hlers positioniert und fixiert. Hier lohnt es sich, etwas sorgf\u00e4ltiger zu arbeiten. Die Infrarotkommunikation ist n\u00e4mlich erstaunlich wenig beeindruckt davon, dass der Lesekopf <em>ungef\u00e4hr<\/em> an der richtigen Stelle sitzt.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1008\" height=\"756\" src=\"https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/zaehler.jpg\" alt=\"\" class=\"wp-image-572\" srcset=\"https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/zaehler.jpg 1008w, https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/zaehler-300x225.jpg 300w, https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/zaehler-768x576.jpg 768w\" sizes=\"auto, (max-width: 1008px) 100vw, 1008px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Tasmota vorbereiten<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Als Firmware kommt Tasmota zum Einsatz. Allerdings ben\u00f6tigen wir eine Version, die sowohl die Scripting-Funktion als auch das Smart Meter Interface unterst\u00fctzt. Die aktuellen Scripting-Builds k\u00f6nnen das, \u00fcber den <a href=\"https:\/\/tasmota.github.io\/install\/\" data-type=\"link\" data-id=\"https:\/\/tasmota.github.io\/install\/\" target=\"_blank\" rel=\"noopener\">Web-Flasher<\/a> k\u00f6nnt ihr euch die also auf euren D1 Mini flashen.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1008\" height=\"756\" src=\"https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/tasmota.jpg\" alt=\"\" class=\"wp-image-573\" srcset=\"https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/tasmota.jpg 1008w, https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/tasmota-300x225.jpg 300w, https:\/\/www.richard-becker.net\/blog\/wp-content\/uploads\/2026\/10\/tasmota-768x576.jpg 768w\" sizes=\"auto, (max-width: 1008px) 100vw, 1008px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Pr\u00fcft vor dem Flashen trotzdem nochmal, ob eure Firmware die beiden Features unterst\u00fctzt. Andernfalls wundert ihr euch sp\u00e4ter \u00fcber fehlende Men\u00fcpunkte, obwohl der ESP8266 ansonsten fr\u00f6hlich vor sich hin blinkt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nach dem Flashen wird der Wemos D1 Mini wie gewohnt ins WLAN eingebunden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Die serielle Konsole muss weg<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Da wir GPIO1 und GPIO3 f\u00fcr die Kommunikation mit dem Wasserz\u00e4hler verwenden, darf Tasmota diese Schnittstelle nicht gleichzeitig f\u00fcr seine Logmeldungen nutzen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In der Tasmota-Webkonsole geben wir deshalb Folgendes ein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SerialLog 0<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit wird die serielle Logausgabe deaktiviert. Die Webkonsole funktioniert selbstverst\u00e4ndlich weiterhin. Ich habe daf\u00fcr folgendes Loglevel gesetzt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>WebLog 2<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Scripting aktivieren<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Anschlie\u00dfend aktivieren wir die Scripting-Funktion:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Script 1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Den Skripteditor findet ihr unter:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Consoles \u2192 Edit Script<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dort hinterlegen wir gleich die gesamte Kommunikation mit dem Wasserz\u00e4hler.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Das komplette Tasmota-Skript<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt wird es interessant: Der Kamstrup flowIQ 2200 stellt seine Werte \u00fcber verschiedene Register bereit. Wir fragen zwei davon ab:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Register <code>0x0044<\/code>: Gesamtwasserverbrauch<\/li>\n\n\n\n<li>Register <code>0x0246<\/code>: Verbleibende Batterielaufzeit<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Damit das funktioniert, m\u00fcssen wir zun\u00e4chst eine Initialisierungsabfrage senden. Anschlie\u00dfend fragt Tasmota in einem Intervall von 120 Sekunden die beiden Register ab. Das komplette Skript sieht folgenderma\u00dfen aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&gt;D\n\n&gt;B\n=&gt;sensor53 r\n\n&gt;S\n; Einmalige Initialisierung beim Start\nif upsecs==2 {\nprint KAMSTRUP INIT\nsml(1 1 \"803F0235E90D\")\n}\n\n; Gesamtvolumen alle 120 Sekunden\nif upsecs%120==10 {\nprint KAMSTRUP VOLUMEN\nsml(1 1 \"803F100100444DC00D\")\n}\n\n; Batterielaufzeit zwei Sekunden spaeter\nif upsecs%120==12 {\nprint KAMSTRUP BATTERIE\nsml(1 1 \"803F100102460BE00D\")\n}\n\n&gt;M 1\n+1,3,rN1,0,1200,Kamstrup,1\n1,=so3,32\n1,0044280443UUuuUUuu@1000,Zaehlerstand,m\u00b3,Volume,3\n1,02463E0200UUuu@1,Batterie Resttage,d,BatteryDays,0\n\n#<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das Skript wird im Tasmota-Skripteditor gespeichert und aktiviert. Keine Sorge, falls euch die vielen Zahlen und Buchstaben gerade ein wenig an die Matrix erinnern. So wild ist es nicht. Schauen wir uns an, was hier passiert&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Was macht das Skript eigentlich?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Das Skript besteht im Wesentlichen aus drei Bereichen:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li>Initialisierung des Smart Meter Interface<\/li>\n\n\n\n<li>Regelm\u00e4\u00dfige Kommunikation mit dem Wasserz\u00e4hler<\/li>\n\n\n\n<li>Auswertung der empfangenen Daten<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 1: Den Kamstrup aufwecken<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Zwei Sekunden nach dem Start wird folgendes Telegramm gesendet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>80 3F 02 35 E9 0D<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Im Skript sieht das so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if upsecs==2 {\nprint KAMSTRUP INIT\nsml(1 1 \"803F0235E90D\")\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit senden wir den KMP-Befehl <code>0x02<\/code>. Diese Initialisierungsabfrage wird einmalig nach dem Ger\u00e4testart ausgef\u00fchrt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Schritt 2: Den Z\u00e4hlerstand abfragen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Zehn Sekunden nach dem Start fragt Tasmota erstmals den Gesamtwasserverbrauch ab. Daf\u00fcr wird folgendes Telegramm an den Wasserz\u00e4hler geschickt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>80 3F 10 01 00 44 4D C0 0D<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Entscheidend ist hier das Register <code>0x0044<\/code>. Im Skript \u00fcbernehmen diese Zeilen die Abfrage:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if upsecs%120==10 {\nprint KAMSTRUP VOLUMEN\nsml(1 1 \"803F100100444DC00D\")\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Bedingung <code>upsecs%120==10<\/code> bewirkt, dass die Abfrage nach zehn Sekunden und anschlie\u00dfend alle 120 Sekunden ausgef\u00fchrt wird.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Schritt 3: Die Batterielaufzeit abfragen<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zwei Sekunden sp\u00e4ter interessiert uns, wie lange die Batterie des Wasserz\u00e4hlers voraussichtlich noch durchh\u00e4lt. Daf\u00fcr verwenden wir Register <code>0x0246<\/code>. Das Abfragetelegramm lautet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>80 3F 10 01 02 46 0B E0 0D<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die entsprechende Stelle im Skript:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if upsecs%120==12 {\nprint KAMSTRUP BATTERIE\nsml(1 1 \"803F100102460BE00D\")\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit fragen wir die Batterielaufzeit jeweils zwei Sekunden nach dem Gesamtvolumen ab. Das ergibt folgenden Ablauf:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Zeit nach dem Start<\/th><th>Aktion<\/th><\/tr><tr><td>2 Sekunden<\/td><td>Initialisierung<\/td><\/tr><tr><td>10 Sekunden<\/td><td>Gesamtwasserverbrauch abfragen<\/td><\/tr><tr><td>12 Sekunden<\/td><td>Batterielaufzeit abfragen<\/td><\/tr><tr><td>130 Sekunden<\/td><td>Gesamtwasserverbrauch abfragen<\/td><\/tr><tr><td>132 Sekunden<\/td><td>Batterielaufzeit abfragen<\/td><\/tr><tr><td>Danach<\/td><td>Wiederholung alle 120 Sekunden<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Damit haben wir die beiden ben\u00f6tigten Werte. Zumindest theoretisch. Denn der Wasserz\u00e4hler antwortet uns zun\u00e4chst nicht mit einer h\u00fcbschen Zahl wie \u201e30,885 Kubikmeter\u201c, sondern mit einer Reihe von HEX-Werten. W\u00e4re ja auch zu einfach.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Serielle Kommunikation: Warum 1200 Baud v\u00f6llig ausreichen<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Im Tasmota-Skript findet sich folgende Zeile:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+1,3,rN1,0,1200,Kamstrup,1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit konfigurieren wir die Kommunikation \u00fcber das Smart Meter Interface. Die Parameter haben folgende Bedeutung:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Parameter<\/th><th>Bedeutung<\/th><\/tr><tr><td><code>1<\/code><\/td><td>Nummer des Z\u00e4hlers<\/td><\/tr><tr><td><code>3<\/code><\/td><td>Empfang \u00fcber GPIO3<\/td><\/tr><tr><td><code>rN1<\/code><\/td><td>Raw-Modus mit 8 Datenbits, keiner Parit\u00e4t und einem Stoppbit<\/td><\/tr><tr><td><code>0<\/code><\/td><td>Standard-Flags<\/td><\/tr><tr><td><code>1200<\/code><\/td><td>Baudrate<\/td><\/tr><tr><td><code>Kamstrup<\/code><\/td><td>Name des Sensors<\/td><\/tr><tr><td><code>1<\/code><\/td><td>Senden \u00fcber GPIO1<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Wir kommunizieren also mit <strong>1200 Baud und 8N1<\/strong>. Das ist aus heutiger Sicht ungef\u00e4hr die Geschwindigkeit, bei der ein alter Modemrouter nostalgisch wird. Aber wir \u00fcbertragen hier schlie\u00dflich keine 4K-Videos, sondern ein paar Bytes mit Z\u00e4hlerst\u00e4nden. Daf\u00fcr reicht es vollkommen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Der Empfangspuffer: Kleine Einstellung, gro\u00dfe Wirkung<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kommen wir zu einer Einstellung, die mich tats\u00e4chlich etwas Zeit gekostet hat. Im Skript steht diese Zeile:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1,=so3,32<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit wird der Raw-Empfangspuffer auf 32 Bytes eingestellt. Klingt unspektakul\u00e4r. War es aber nicht. Bei meinen Versuchen mit einer kleineren Puffergr\u00f6\u00dfe kam es zu Buffer Overflows. Der ESP8266 griff dadurch auf falsche Speicherbereiche zu und verabschiedete sich mit einer Exception in den Neustart. Immer wieder.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Besonders fies daran: Die Antworten des Kamstrup konnten im HEX-Dump teilweise v\u00f6llig normal aussehen. Trotzdem wurden die Messwerte nicht korrekt dekodiert. Erst mit der passenden Pufferkonfiguration funktionierte die Verarbeitung zuverl\u00e4ssig.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Falls ihr die Telegramme im Debug-Modus sehen k\u00f6nnt, aber keine Sensorwerte erhaltet oder der ESP unerwartet neu startet, schaut euch unbedingt diese Einstellung an.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Aus HEX wird Wasserverbrauch<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt haben wir den Wasserz\u00e4hler erfolgreich angesprochen. Aber was machen wir mit seinen Antworten? Schauen wir uns dazu ein echtes Antworttelegramm an:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>40 3F 10 00 44 28 04 43 00 00 78 A5 79 A0 0D<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist die Antwort auf die Abfrage des Gesamtwasserverbrauchs. Auf den ersten Blick wenig hilfreich. Es sei denn, man liest HEX-Dumps zum Fr\u00fchst\u00fcck. Der eigentliche Z\u00e4hlerstand steckt in diesen vier Bytes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>00 00 78 A5<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Umgerechnet ergibt sich:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0x000078A5 = 30885<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dieser Wert muss durch 1000 geteilt werden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>30885 \/ 1000 = 30.885 m\u00b3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Unser Wasserz\u00e4hler steht also bei <strong>30,885 Kubikmetern<\/strong>. Die Umrechnung m\u00fcssen wir gl\u00fccklicherweise nicht selbst programmieren. Daf\u00fcr ist folgende Zeile im Tasmota-Skript zust\u00e4ndig:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1,0044280443UUuuUUuu@1000,Zaehlerstand,m\u00b3,Volume,3<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Sie erkennt das entsprechende Antwortmuster, liest den 32-Bit-Wert aus und teilt ihn durch 1000. Das Ergebnis wird als <code>Volume<\/code> mit drei Nachkommastellen bereitgestellt. Damit l\u00e4sst sich schon deutlich mehr anfangen als mit einer langen Reihe von HEX-Werten.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Und wie lange h\u00e4lt die Batterie noch?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Der Kamstrup liefert auch eine gesch\u00e4tzte verbleibende Batterielaufzeit. Das passende Antworttelegramm sieht beispielsweise so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>40 3F 10 02 46 3E 02 00 16 18 C2 32 0D<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Batterierestlaufzeit steckt in diesen zwei Bytes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>16 18<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Auch hier m\u00fcssen wir den HEX-Wert umrechnen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>0x1618 = 5656<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das entspricht einer verbleibenden Laufzeit von <strong>5656 Tagen<\/strong>. Also noch ein paar J\u00e4hrchen. Die Umrechnung \u00fcbernimmt wieder Tasmota:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>1,02463E0200UUuu@1,Batterie Resttage,d,BatteryDays,0<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Anders als beim Wasserverbrauch ist hier keine Division notwendig. Der Wert wird direkt in Tagen ausgegeben. Es handelt sich \u00fcbrigens um die vom Wasserz\u00e4hler selbst gesch\u00e4tzte Restlaufzeit. Ob die Batterie am Ende wirklich so lange h\u00e4lt, kann nat\u00fcrlich niemand garantieren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Geschafft: Die Werte erscheinen in Tasmota<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn alles funktioniert, erscheinen die beiden Messwerte direkt auf der Tasmota-Hauptseite.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bei meinem Test sah das beispielsweise so aus:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Messwert<\/th><th>Wert<\/th><\/tr><tr><td>Kamstru Zaehlerstand<\/td><td>30,885 m\u00b3<\/td><\/tr><tr><td>Kamstru Batterie Resttage<\/td><td>5656 d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist doch schon einmal ganz ordentlich. Aus einem gew\u00f6hnlichen Wasserz\u00e4hler ist damit ein Ger\u00e4t geworden, das seine Messwerte \u00fcber das heimische WLAN bereitstellt. Und das vollst\u00e4ndig lokal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wer sich jetzt wundert, warum dort <code>Kamstru<\/code> statt <code>Kamstrup<\/code> steht: So lautet der ausgegebene Sensorschl\u00fcssel in der hier getesteten Tasmota-Firmware. Das ist nicht besonders h\u00fcbsch, aber solange die Daten stimmen, kann ich damit leben.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MQTT: Ab ins Smart Home mit den Daten<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dass der Wasserverbrauch jetzt auf der Tasmota-Weboberfl\u00e4che erscheint, ist sch\u00f6n. Aber wir betreiben doch kein Smart Home, nur um anschlie\u00dfend eine andere Webseite aufrufen zu m\u00fcssen. Die Daten sollen nat\u00fcrlich weiterverarbeitet werden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Gl\u00fcck bringt Tasmota die passende MQTT-Unterst\u00fctzung bereits mit. Die Verbindung zu eurem MQTT-Broker richtet ihr unter folgendem Men\u00fcpunkt ein:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Configuration \u2192 Configure MQTT<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Anschlie\u00dfend stellen wir das Telemetrieintervall passend zum Abfrageintervall ein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>TelePeriod 120<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit ver\u00f6ffentlicht Tasmota alle 120 Sekunden seine Telemetriedaten. Falls MQTT noch deaktiviert ist, k\u00f6nnt ihr es mit folgendem Befehl aktivieren:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>MqttEnable 1<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Ein typisches MQTT-Topic lautet dann beispielsweise:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>tele\/tasmota_C86554\/SENSOR<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Die Sensorwerte werden als JSON bereitgestellt. Der f\u00fcr uns interessante Ausschnitt sieht so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"Kamstru\": {\n    \"Volume\": 30.885,\n    \"BatteryDays\": 5656\n  }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit stehen zwei Werte zur Verf\u00fcgung: <strong>Volume:<\/strong> Der bisherige Gesamtwasserverbrauch in Kubikmetern. <strong>BatteryDays:<\/strong> Die gesch\u00e4tzte verbleibende Batterielaufzeit in Tagen. Und damit k\u00f6nnen wir arbeiten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Werte lassen sich beispielsweise in Home Assistant \u00fcbernehmen, in einer Datenbank speichern oder \u00fcber Grafana visualisieren. Aus dem fortlaufenden Z\u00e4hlerstand kann man sich dann auch den t\u00e4glichen oder monatlichen Wasserverbrauch berechnen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Endlich l\u00e4sst sich also nicht nur feststellen, <em>dass<\/em> die Wasserrechnung hoch ist, sondern auch genauer nachvollziehen, wann das ganze Wasser eigentlich verbraucht wurde. Ob man danach noch entspannt duschen kann, ist eine andere Frage.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wie oft sollte man den Wasserz\u00e4hler abfragen?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In meinem Beispiel werden die beiden Register alle 120 Sekunden abgefragt. F\u00fcr die Einrichtung und zum Testen ist das praktisch. Schlie\u00dflich m\u00f6chte man nicht jedes Mal eine viertel Stunde warten, um herauszufinden, ob eine \u00c4nderung am Skript funktioniert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr den dauerhaften Betrieb gibt es allerdings etwas zu bedenken. Der Kamstrup flowIQ 2200 wird \u00fcber eine interne Batterie versorgt. Und auch wenn die optische Schnittstelle keine gro\u00dfen Datenmengen \u00fcbertr\u00e4gt, ben\u00f6tigt jede aktive Kommunikation Energie. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Am idealen Intervall zur Abfrage arbeite ich noch&#8230; schlie\u00dflich soll die Schnittstelle nicht schlafen gehen, aber auch nicht st\u00e4ndig Daten \u00fcbertragen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Weiterf\u00fchrende Links<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/tasmota.github.io\/docs\/Smart-Meter-Interface\/\">Tasmota \u2013 Smart Meter Interface<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/tasmota.github.io\/docs\/Scripting-Language\/\">Tasmota \u2013 Scripting Language<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/wiki.volkszaehler.org\/hardware\/controllers\/ir-schreib-lesekopf-ttl-ausgang\">Volksz\u00e4hler \u2013 IR-Schreib-Lesekopf mit TTL-Ausgang<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Wasserverbrauch automatisch erfassen, ohne Cloud, ohne Hersteller-App und ohne jeden Monat mit der Taschenlampe in&hellip; <a class=\"read-more-link\" href=\"https:\/\/www.richard-becker.net\/blog\/2026\/10\/11\/kamstrup-flowiq-2200-auslesen-wasserzaehler-mit-tasmota-und-esp8266-smart-machen\/\">[Weiterlesen]<\/a><\/p>\n","protected":false},"author":2,"featured_media":570,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[10,11,22,8,119,7,120],"class_list":["post-564","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technologie","tag-hardware","tag-homeserver","tag-open-source","tag-selfhosting","tag-tasmota","tag-technologie","tag-wasserzaehler"],"_links":{"self":[{"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/posts\/564","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/comments?post=564"}],"version-history":[{"count":7,"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/posts\/564\/revisions"}],"predecessor-version":[{"id":575,"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/posts\/564\/revisions\/575"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/media\/570"}],"wp:attachment":[{"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/media?parent=564"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/categories?post=564"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.richard-becker.net\/blog\/wp-json\/wp\/v2\/tags?post=564"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}