Wer seinen Wasserzähler in seinem Smarthome auslesen möchte, steht häufig vor der Herausforderung, dass die Installierten Zähler entsprechend alt sind – und damit über noch keinerlei Möglichkeiten verfügen, direkt irgendwo angebunden zu werden.
Eine Häufige Variante ist daher, den Zählerstand mittels einem kleinen Kameramodul (z.B. esp-cam) abzufotografieren und die Zählerstände dann via KI-Implementierung (AI-on-the-Edge) zu interpretieren.
Ich kann es nicht genau beschreiben warum – aber irgend etwas stört mich persönlich bei der Implementierung einer solchen Lösung – daher habe ich mich entschlossen, dort, wo ich den Wasserverbrauch ermitteln möchte, die Vorhandenen Zähler (sofern möglich) zu ersetzen bzw. weitere zu installieren.
Hierzu nutze ich Zähler, welche direkt mit einem Impulsgeber ausgestattet sind.
Diese gibt es in verschiedenen Varianten – 1 Liter pro Impuls, oder 0,25 Liter pro Impuls – sowohl für Kaltwasser, wie auch für Warmwasser.
Ein kleines Metall-Plättchen im Zählwerk sorgt hierbei bei jeder Umdrehung für einen Impuls, welcher dann über z.B. einen ESP registriert und verarbeitet werden kann.
Nun benötigt es zum Auslesen der Sensorwerte noch ein klein wenig „Computer-Technik“.
In meinem Fall übernimmt dies ein ESP32 – oder ein ESP8266, je nachdem, was gerade da ist – und ob man u.U. am Einsatzort noch zusätzlich einen Bluetooth-Proxy benötigen könnte, oder nicht 🙂
Der Code des ESP wird komplett über ESPHome erstellt.
Hierfür nutze ich die Komponente „pulse_meter“ von ESPHome.
sensor:
- platform: pulse_meter
id: cold_water_meter_pulse
name: 'Cold Water Meter - FlowRate'
unit_of_measurement: 'l/min'
device_class: volume_flow_rate
state_class: measurement
internal_filter: 100ms
accuracy_decimals: 0
pin:
number: GPIO14
mode: INPUT_PULLUP
Code-Sprache: JavaScript (javascript)
Hiermit bekommen wir schon einmal die Information der Durchfluss-Menge, also wie viel Liter pro Minute durch den Zähler fließen.
Wir nutzen dabei einen Filter (internal_filter) von 100ms, welcher kürzere Impulse ignoriert.
Hier muss man sich ggf. mit testen an den korrekten Wert seines Zählers heran tasten – der Filter dient letztendlich dazu, die Fehlerrate zu reduzieren.
Um jetzt aber an brauchbare Daten für das Energie-Dashboard zu kommen, brauchen wir noch die gezählten Impulse, also wie viel Liter bzw. Kubikmeter Wasser tatsächlich geflossen sind.
Dazu erweitern wir den Sensor um die Angabe „total“
total:
name: 'Cold Water Meter - Total m³'
id: cold_water_meter_total
unit_of_measurement: 'm³'
accuracy_decimals: 3
state_class: total_increasing
device_class: water
filters:
- multiply: 0.001
Code-Sprache: JavaScript (javascript)
hiermit bekommen wir nun die Information, wie viel m³ durch den Zähler geflossen sind – allerdings, mit einem Neustart des ESPHome werden diese Zähler immer wieder zurück gesetzt.
Für das EnergyDashboard ist das kein Problem, dadurch dass als state_class „total_increasing“ angegeben wurde, weiß HomeAssistant, wie es mit diesen Werten für die Statisitk umgehen muss.
Wollen wir uns aber den Zählerstand als solchen auf unserem Dashboard ausgeben, wäre es sinnvoll, wenn wir den Wert irgendwie speichern könnten.
Und dann haben die Wasseruhren ja meistens bereits ein paar m³ auf der Uhr, wenn wir sie erhalten… dies sollte ggf. auch berücksichtigt werden, wenn wir z.B. den Zählerstand mal irgendwann an den Versorger übermitteln wollen ohne ständig in den Keller zu laufen dafür 😉
Hier benötigen wir daher noch ein paar Unterstützende Elemente…
In HomeAssistant legen wir uns als erstes einen Helfer vom Typ „input_number“ an.
Er bekommt die folgende Konfiguration:
Wichtig sind hier die „Step size“, Unit of Measurement und die Maximale größe…
Der rest kann beliebig vergeben werden und wir müssen uns die Entity_ID lediglich merken um sie in ESPHome zu nutzen.
In den „Sensor“ Block von HomeAssistant kommt jetzt unser angelegter Helfer dazu:
- platform: homeassistant
id: store_count
entity_id: input_number.water_meter_store
accuracy_decimals: 3
internal: False
unit_of_measurement: "m³"
state_class: total
Code-Sprache: PHP (php)
Zusätzlich müssen wir uns eine Globale Variable in ESPHome anlegen, in welcher wir die Werte unseres Zählers speichern.
globals:
- id: water_total_previous
type: float
restore_value: no
initial_value: '0'
Code-Sprache: JavaScript (javascript)
Nun erweitern wir den „total“ Block um eine Lambda Funktion:
on_value:
then:
- lambda: |-
float y = round(x * 1000) / 1000;
id(store_count).state = id(store_count).state - id(water_total_previous) + y ;
id(water_total_previous) = y ;
ESP_LOGD ("global","%f", id(water_total_previous));
ESP_LOGD ("store","%f", id(store_count).state);
- homeassistant.service:
service: input_number.set_value
data:
entity_id: input_number.water_meter_store
value: !lambda return id(store_count).state;
Code-Sprache: JavaScript (javascript)
Letzendlich updaten wir damit den angelegten Helfer bei jeder State-Änderung um den neuen Wert.
Wenn unsere Wasser-Uhr also z.B. beim Einbau schon 0,031 m³ angezeigt hatte, und wir nun 6 L Wasser durch laufen lassen, zeigt unser Helfer 0,037 m³ an.
Jetzt wollen wir uns der Einfachheit halber auch noch den Verbauch in Litern anzeigen lassen, auch, wenn das EnergyDashboard diese Umwandlung von sich aus vornimmt – für unser Dashboard ist das einfach bequemer 🙂
Dazu nutzen wir die „COPY“ platform in ESPHome, da wir keinen weiteren Sensor anlegen können, welcher den gleichen IO Port nutzt.
- platform: copy
name: 'Cold Water Meter - Total L'
unit_of_measurement: 'L'
accuracy_decimals: 0
state_class: total_increasing
device_class: water
source_id: cold_water_meter_total
filters:
- multiply: 1000
Code-Sprache: JavaScript (javascript)
Unser ESP-Code sieht gesamt also wie folgt aus:
globals:
- id: water_total_previous
type: float
restore_value: no
initial_value: '0'
sensor:
- platform: pulse_meter
id: cold_water_meter_pulse
name: 'Cold Water Meter - FlowRate'
unit_of_measurement: 'l/min'
device_class: volume_flow_rate
state_class: measurement
internal_filter: 100ms
accuracy_decimals: 0
pin:
number: GPIO14
mode: INPUT_PULLUP
total:
name: 'Cold Water Meter - Total m³'
id: cold_water_meter_total
unit_of_measurement: 'm³'
accuracy_decimals: 3
state_class: total_increasing
device_class: water
filters:
- multiply: 0.001
on_value:
then:
- lambda: |-
float y = round(x * 1000) / 1000;
id(store_count).state = id(store_count).state - id(water_total_previous) + y ;
id(water_total_previous) = y ;
ESP_LOGD ("global","%f", id(water_total_previous));
ESP_LOGD ("store","%f", id(store_count).state);
- homeassistant.service:
service: input_number.set_value
data:
entity_id: input_number.water_meter_store
value: !lambda return id(store_count).state;
- platform: copy
name: 'Cold Water Meter - Total L'
unit_of_measurement: 'L'
accuracy_decimals: 0
state_class: total_increasing
device_class: water
source_id: cold_water_meter_total
filters:
- multiply: 1000
- platform: homeassistant
id: store_count
entity_id: input_number.water_meter_store
accuracy_decimals: 3
internal: False
unit_of_measurement: "m³"
state_class: total
Code-Sprache: PHP (php)
Wer möchte, kann nun noch weitere Komponenten und Optionen hinzufügen – in meinem Fall ist das ein Bluetooth-Proxy, ein paar zusätzliche Buttons und Sensoren, wie z.B. Uptime, Wifi-Signalstärke und so weiter.
Hallo Christoph,
Ich habe das oben 1 zu 1 so um gesetzt, leider wird mein „Water Meter Store“ in HA um weitere 3 Nachkommastellen (insgesamt also 6) erweitert… weißt du wo das Problem liegt?
Mein Zählerstand im „Water Meter Store“ habe ich auf meinem Wasserzähler abgelesen und eingetragen in HA.
Dieser Beträgt: 1.924,324 m³, Zapfe ich nun 1 Liter Wasser, müsste sich dieser ja auf 1.924,325 m³ erhöhen, stattdessen beträgt dieser dann aber 1.924,324951, es kommen alsoo noochmal 3 Nachkommastellen dazu….
Total m³ und Total L stimmen im Dashboard (0,001 & 1), im Energy Dashboard stimmen die Mengen auch… nur der Zählerstand macht Probleme…
Gruß Pierre
hm…
wie sehen denn die Parameter deines input_number helfers für den „Store“ aus?
Ich hatte solche Messungen in früheren Setups auch, aber nur in den Sensoren, welche aus ESP kamen.
Hier vermute ich, dass der Sensor keinen kompletten L erkennt…
Ich nehme an, die „korrekten“ Sensoren runden auf die entsprechenden Nachkommastellen auf, der „Store“ allerdings nicht.
Erweitere deinen sensor mal um
accuracy_decimals:
Und dahinter die gewünschten Dezimalstellen