Jeder kennt es, in der Regel taugt die Anzeige für den Tankinhalt für Frischwasser nicht die Bohne. Zu ungenau, oft Fehlfunktionen. Sensoren mit Ultraschall oder Messung des Drucks sind teuer und je nach Tank auch nicht viel besser. Lange habe ich mich mit der Frage beschäftigt, wie ich das Problem löse. Natürlich ist die Schätzung für viele Camper die beste Messung, aber ich mag es genau und außerdem smart.
Solltest Du Fragen haben oder Unterstützung brauchen, nutze bitte das Kontaktformular, um uns anzuschreiben.
Ich habe eine ganze Reihe von Durchflusssensoren ausprobiert. Viele davon funktionieren gut im Trockentest (Zuhause an einem Schlauch und einem Eimer mit Wasser). Eingebaut zeigen sich aber einige Probleme. z.B. macht der Sensor keinen Sinn hinter der Druckpumpe (anders bei Tauchpumpen), denn dann steht der Sensor mit seinen Anschlüssen immer unter Druck. Das funktioniert zwar, birgt aber eine zusätzliche Gefahr für Undichtigkeiten.
Also ab dafür und vor die Druckpumpe. Das scheint erstmal wunderbar, allerdings hatte ich bei vielen der Durchflusssesnoren das Problem, das die Druckpumpe anfing zu stottern. Die Menge an Wasser die durch den Sensor ging war nicht ausreichend um das Ansaug- zu Druckverhalten richtig hin zu bekommen, auch aufbohren der Anschlüsse brachte keine wesentliche Verbesserung. Dann hielt ich eines Tages einen Sensor in der Hand von den ich erst dachte, das er zu klein sei. Allerdings ist er ordentlich im Durchfluss da es keinen Kreisel- sondern eine turbinenatrigen Aufbau hat. Dazu kommt, dass der Sensor sogar genauer ist als die anderen.

Das Schöne an diesen Sensoren ist, dass sie über einen HALL Sensor verfügen und somit hervorragend an einem ESP32 betrieben werden können. Kurzerhand habe ich mir also einen ESP32-C3 geschnappt, das Ganze in ESPHome in mehreren Anläufen zu einem brauchbaren Wasserverbrauchssensor zusammengebaut.

Der ESP32 hat noch ein kleines Gehäuse mit einem 12v zu 5v Step-Down bekommen und wurde dann in die Leitung von Frischwassertank zur Druckpumpe eingebaut. Dadurch, dass kaum Druck auf dem Stück ist, muss ich mich auch nicht um Undichtigkeiten sorgen.
Der Sensor kann in ein bestehendes WiFi Netz und somit in Homeassistant übernommen werden, oder einzeln als AP und per Handy angesprochen werden. Den aktuellen Wert und wie der Verbrauch aussieht, bekommt man natürlich nur brauchbar angezeigt, wenn man sich das Ganze dann auf ein Dashboard bringt.

Die benötigten Teile bekommt man soweit alle auf Amazon, hier eine Liste der Teile:
Wasserdurchflusssensor -> https://www.amazon.de/dp/B0CZRZ3CB1
Lilie Anschlüsse -> https://www.amazon.de/dp/B07QS55GTM
ESP32-C3 Super Mini -> https://amzn.eu/d/0bo8eZLd
Gehäuse -> https://www.amazon.de/dp/B09PTJ492D
Der entsprechende ESPHome Code (jeder Sensor muss mit Wasserentnahmen (Messbecher) eingemessen werden):
###
# Version 20260606-1400
esphome:
name: esp-water-sensor
friendly_name: "ESP Water Sensor"
name_add_mac_suffix: false
platformio_options:
board_build.flash_mode: dio
on_boot:
then:
- light.turn_off:
id: led_status
# effect: none
# brightness: 40%
# red: 100%
# green: 100%
# blue: 0%
- component.update: template_refill_total
- component.update: template_total_consumed
- component.update: template_tank_current
- component.update: template_last_taken
- component.update: template_count_taken
esp32:
board: lolin_c3_mini
variant: esp32c3
cpu_frequency: 160MHZ
framework:
type: esp-idf
version: recommended
sdkconfig_options:
CONFIG_BT_ENABLED: "n"
CONFIG_BT_NIMBLE_ENABLED: "n"
globals:
- id: int_wifireconnect
type: int
restore_value: no
initial_value: '-1'
- id: float_tank_volume
type: float
restore_value: yes
initial_value: "0"
- id: float_tank_refilled
type: float
restore_value: yes
initial_value: "0"
- id: float_total_consumed
type: float
restore_value: yes
initial_value: "0"
- id: float_last_taken
type: float
restore_value: yes
initial_value: "0"
- id: float_count_taken
type: float
restore_value: yes
initial_value: '0'
- id: int_is_water_flow_status
type: int
initial_value: "0"
logger:
level: WARN
baud_rate: 0
api:
encryption:
key: "<NEW-API-KEY>"
ota:
- platform: esphome
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
min_auth_mode: WPA2
fast_connect: true
# output_power: 20dB
enable_btm: true
enable_rrm: false
on_connect:
- lambda: id(int_wifireconnect)+=1;
ap:
ssid: "ESP-WATER-SENSOR"
password: !secret ap_fallback_password
captive_portal:
#web_server:
# port: 80
# include_internal: true
# version: 3
# auth:
# username: !secret web_server_username
# password: !secret web_server_password
time:
- platform: homeassistant
id: homeassistant_time
timezone: Europe/Berlin
sensor:
- platform: pulse_counter
# #YF-S201C
pin:
number: 4
mode:
input: true
pullup: true
name: "Durchfluss"
id: water_pulses
internal: false
update_interval: 1s
unit_of_measurement: "L/min"
accuracy_decimals: 3
filters:
# pulse_counter liefert Pulse/min → × (1L / 300 Pulse) = L/min
- multiply: 0.003386 # = 1/300 Pulse pro Liter (YF-S201C: 300 P/L)
- sliding_window_moving_average:
window_size: 3
send_every: 1
- filter_out: nan
total:
unit_of_measurement: "L"
name: "Entnahme"
id: total_count_zwischenverbrauch
icon: mdi:water-pump
accuracy_decimals: 3
filters:
- multiply: 0.003386
count_mode:
rising_edge: INCREMENT
falling_edge: DISABLE
- platform: template
name: "Aufgefüllt"
id: template_refill_total
icon: mdi:water
unit_of_measurement: "L"
accuracy_decimals: 3
update_interval: never
lambda: |-
return id(float_tank_refilled);
- platform: template
name: "Gesamte Entnahme"
id: template_total_consumed
icon: mdi:water-pump
unit_of_measurement: "L"
accuracy_decimals: 3
update_interval: never
lambda: |-
return id(float_total_consumed);
- platform: template
name: "Tankinhalt"
id: template_tank_current
icon: mdi:waves
unit_of_measurement: "L"
accuracy_decimals: 3
update_interval: never
lambda: |-
return id(float_tank_volume);
- platform: template
name: "Letzte Entnahme"
id: template_last_taken
icon: mdi:water-pump
unit_of_measurement: "L"
accuracy_decimals: 3
update_interval: never
lambda: |-
return id(float_last_taken);
- platform: template
name: "Entnahmen"
id: template_count_taken
icon: mdi:numeric-1-box-multiple-outline
unit_of_measurement: "x"
accuracy_decimals: 0
update_interval: never
lambda: |-
return (int) id(float_count_taken);
- platform: internal_temperature
id: esp_internal_temperatur
name: "ESP Temperatur"
- platform: uptime
name: "ESP Uptime"
id: esp_uptime_sensor
update_interval: 60s
- platform: template
id: esp_wifi_reconnect
name: "ESP Wifi reconnect"
accuracy_decimals: 0
icon: mdi:wifi-sync
unit_of_measurement: "x"
entity_category: "diagnostic"
update_interval: 60s
lambda: |-
return (int) id(int_wifireconnect);
- platform: wifi_signal
name: "WiFi Signal dB"
id: wifi_signal_db
icon: mdi:wifi
update_interval: 60s
entity_category: "diagnostic"
disabled_by_default: false
internal: true
- platform: copy
source_id: wifi_signal_db
name: "WiFi Signal Percent"
icon: mdi:wifi
filters:
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
unit_of_measurement: "%"
entity_category: "diagnostic"
device_class: ""
disabled_by_default: false
button:
- platform: restart
name: "ESP Restart"
entity_category: config
disabled_by_default: false
- platform: template
name: "Reset Data"
id: button_reset_data
disabled_by_default: false
entity_category: config
on_press:
- lambda: |-
id(float_tank_refilled) = 0;
id(float_total_consumed) = 0;
id(float_tank_volume) = 0;
id(float_last_taken) = 0;
id(float_count_taken) = 0;
global_preferences->sync();
- component.update: template_refill_total
- component.update: template_total_consumed
- component.update: template_tank_current
- component.update: template_last_taken
- component.update: template_count_taken
- platform: template
name: "Nachfüllen"
id: button_refill
entity_category: config
on_press:
- lambda: |-
id(float_tank_refilled) = id(number_refill_amount).state;
id(float_tank_volume) += id(number_refill_amount).state;
- number.set:
id: number_refill_amount
value: 0
- component.update: template_refill_total
- component.update: template_tank_current
number:
- platform: template
name: "Nachfüllmenge (L)"
id: number_refill_amount
entity_category: config
icon: mdi:waves
optimistic: true
restore_value: true
min_value: -125
max_value: 125
step: 0.001
unit_of_measurement: "L"
text_sensor:
- platform: version
hide_timestamp: true
hide_hash: true
name: "ESP Version"
disabled_by_default: false
- platform: wifi_info
ip_address:
name: "IP Address"
mac_address:
name: "Mac Address"
light:
- platform: esp32_rmt_led_strip
name: "Status LED"
id: led_status
pin: GPIO10
num_leds: 1
rgb_order: GRB
chipset: ws2812
default_transition_length: 250ms
effects:
- pulse:
name: Pulse
transition_length: 100ms
update_interval: 250ms
interval:
- interval: 250ms
then:
- if:
condition:
lambda: 'return id(water_pulses).state <= 0.01 && id(int_is_water_flow_status) == 1;'
then:
- lambda: |-
id(int_is_water_flow_status) = 0;
id(float_tank_volume) -= id(total_count_zwischenverbrauch).state;
id(float_total_consumed) += id(total_count_zwischenverbrauch).state;
id(float_last_taken) = id(total_count_zwischenverbrauch).state;
id(float_count_taken) += 1;
- component.update: template_refill_total
- component.update: template_total_consumed
- component.update: template_tank_current
- component.update: template_last_taken
- component.update: template_count_taken
- pulse_counter.set_total_pulses:
id: water_pulses
value: 0
- light.control:
id: led_status
effect: none
brightness: 50%
red: 0%
green: 100%
blue: 0%
- if:
condition:
lambda: 'return id(water_pulses).state >= 0.02&& id(int_is_water_flow_status) == 0;'
then:
- lambda: |-
id(int_is_water_flow_status) = 1;
- light.control:
id: led_status
effect: none
brightness: 50%
red: 100%
green: 0%
blue: 0%
Solltest Du Fragen haben oder Unterstützung brauchen, nutze bitte das Kontaktformular, um uns anzuschreiben.
