Hi, @nickrout, very useful. Now I understand it, and as NodeMcu offers an input pull up mode (having internally the adequate resistor, it can just be connected as @MatthewFlamm pointed out: one wire to the input pin (in pullup mode) and the other to ground. Thank you both!!
OK, I’ve read the espHome code docs and now I get that teh platform pulse_counter already takes into account what I was talking about, but I’m still getting more counts than the real ones and I don’t understand why. Just in case I have included this to the code:
count_mode:
rising_edge: INCREMENT
falling_edge: DISABLE
filters:
- debounce: 15s
But the same issue still happens, it’s counting more than real. I’ve no idea why I could have this problem. Now my gas meter it’s not really accurate at all.
@jolaca: have you found a solution for accurate values? I also tried to build up the version @saruter mentioned, but get incorrect values.
What does your NodeMCU setup look like? I used that setup:
Hi, sorry, currently I’m not living where I have it installed and I don’t remember how I connected it. If I have time I’ll take a look at it and report back.
anyone a solution ? ve the same problem, more counts as in real.
try it with pulse_counter and pulse_meter, both the same
Hi,
I try too but I have more count than real. Anybody found solutions?
Thx
For me, the following setting solved the problem:
filters:
- debounce: 1.5s
Consider reconsidering your design/architecture. (this may alarm some readers)
The sensor is not necessarily the best place to be tracking the ongoing state of the meter. And, it’s harder to make the sensor be robust enough to store state across power glitches, etc.
Whereas, your HA installation - the receiver and ultimate database supporting your goal - is more likely to be fortified (UPS?) against power outage, but also will remember its data during an actual outage.
So in such a rebalanced design, you put the emphasis on how HA processes and retains the usage ‘tick’ events for you.
For example:
Shift the ‘weight’ of your design inboard, away from the ‘sensor’ (the ESP) and toward the layer where the database will live.
Instead of having the ESP retaining state, let HA do that for you.
Let the ESP merely send HA the events when the pointer passes its mark, using the sensing equipment and setup you already have.
Turn your focus to how to make HA retain and present the data as you want.
Or consider using an alternative data gathering/presentation system (nagios, munin?) if HA doesn’t provide what the graph(s) you want to see.
Under this rebalanced design, in case of outage you may lose some usage events as the pointer passes the mark without being counted, but you won’t lose the cumulative usage that’s already stored in HA. That seemed to be your ultimate goal, if I understood your OP at all.
I did, at least for my setup.
The issue is that the counter is susceptible to false counts as an effect of other electrical devices kicking in, in your house, and causing some effect on the ESP power supply.
I’ve tested 4 different 5V power supplies, all connected to the same socket in my kitchen, then to another socket also in the kitchen. Checked 3 different ESP-WROOM-32 boards as well. The external reed switch was disconnected, but when my oven, dishwasher pump or kettle was switched on, the counter would increment a few times.
When I switched to a power bank for the 5V, the issue went away completely and after 48h my gas usage was exactly correct down to 0.001m3. Ergo, the power supply is to blame for all the issue I and probably at least some of you are having.
Not sure how, how to fix it for AC powered setups, but since I am moving to a solar array for this one, I am not investing more time, which I already did an insane amount to get it resolved.
Hello!
I don’t know if this is still helpful. I had a similar problem with the inaccurate values. I have now found a solution that is sufficient for my needs. My goal is to track the gas consumption as a whole, i.e. total gas.
My setup:
ESP D1 mini, reed contact with AD converter (like this : Reed Switch).
The solution with pulse_counter and pulse_meter did not work satisfactorily.
My approach with binary_sensor and a template:
binary_sensor:
- platform: gpio
id: internal_pulse_counter
pin: D5
internal: true
filters:
- delayed_on: 100ms
on_press:
then:
- lambda: id(total_pulses) += 1;
sensor:
- platform: template
name: "total_gas"
device_class: gas
unit_of_measurement: "m³"
state_class: "total_increasing"
icon: "mdi:fire"
accuracy_decimals: 2
lambda: |-
return id(total_pulses) * 0.01;
globals:
- id: total_pulses
type: int
initial_value: '0'
@navierstokes could it be that you missed the “sensor” component entry for this?
(as a binary sensor it doies not compile)
Exactly, sorry for the confusion. I have corrected this.
This is my yaml, works great for the total amount consumed.
But I’m still struggling with the flow rate
sensor:
- platform: pulse_meter
name: "${device_friendly_name} Gasverbrauch"
id: ${device_entity_id}_gasverbrauch
unit_of_measurement: 'm³/min'
internal_filter: 3 min # the flow rate would never get so fast that the pulse meter would get more than 1 pulse in 3 minutes (in my case)
timeout: 10 min # after 10 min, the pulse meter assumes 0 m³/min
state_class: measurement
device_class: gas
icon: mdi:meter-gas
#accuracy_decimals: 3
pin:
number: $gas_read_pin # GPIO5 on my D1 mini pro
mode: INPUT_PULLUP # reed contact connects pin to ground
filters: # I'm still struggling to get the flow rate right 😬
- lambda: return x * (1.0 / ${gas_imp_value});
total: # this sensor tracks the total gas consumed in m³
name: "${device_friendly_name} Gasverbrauch Total"
id: ${device_entity_id}_gasverbrauch_total
unit_of_measurement: 'm³'
icon: mdi:meter-gas-outline
state_class: total_increasing
device_class: gas
accuracy_decimals: 1
filters: # 1 imp / 0.1 m³ = 10 imp / m³ (in my case); gas_imp_value = 10;
- lambda: return x * (1.0 / ${gas_imp_value});
on_value: # I have a led that blinks for every impulse
then:
- script.execute: gas_led_blink
At the end i adjusted the code again, so it works perfectly for me now, to be honest I don’t know if the flow rate is correct, because it is generally very low with gas.
I’ve added the parameter “inverted” to the pin-configuration and changed how the code keeps track of the impulses.
substitutions:
# Device informations
device_friendly_name: "Keller Zähler Gas"
device_name: "keller-zaehler-gas"
device_entity_id: "keller_zaehler_gas"
# Pinout
gas_read_pin: GPIO5
# Gas Meter Settings
gas_imp_value: '10' # impulses / m³
gas_imp_debounce_on: '0.01 s'
gas_imp_debounce_off: '0.1 s'
globals:
- id: gas_impulses
type: int
restore_value: true # if set to false, the value will be 0 at reboot
initial_value: '0'
binary_sensor:
- platform: gpio
id: gas_impulse
internal: true
pin:
number: $gas_read_pin
mode: INPUT_PULLUP
inverted: true
filters:
- delayed_off: $gas_imp_debounce_off
on_press:
then:
- lambda: id(gas_impulses) += 1;
sensor:
- platform: pulse_meter
name: "${device_friendly_name} Gasverbrauch"
id: ${device_entity_id}_gasverbrauch
unit_of_measurement: 'm³/min'
internal_filter: $gas_imp_debounce_on
timeout: 1 min
state_class: measurement
device_class: gas
icon: mdi:meter-gas
#accuracy_decimals: 3
pin:
number: $gas_read_pin
mode: INPUT_PULLUP
inverted: true
filters: # 1 imp / 0.1 m³ = 10 imp / m³ (in my case); gas_imp_value = 10;
- lambda: return x * (1.0 / ${gas_imp_value});
- platform: template
name: "${device_friendly_name} Gasverbrauch Total"
id: ${device_entity_id}_gasverbrauch_total
unit_of_measurement: 'm³'
icon: mdi:meter-gas-outline
state_class: total_increasing
device_class: gas
accuracy_decimals: 2
lambda: return id(gas_impulses) * (1.0 / ${gas_imp_value});
update_interval: 10 s
Hallo Callen!
A little help is appreciated Where can I set the initial total verbrauch as a starting point.
(In grafana I can group verbrauch in Weekly, monthly, year aspect → it’s clear)
Thanks, Stefan
hey,
you can put an global with an initial value.
I did this with my gas meter for 327,63 m³
globals:Preformatted text
- id: total_pulses
type: int
restore_value: false
initial_value: '32763'
...
- platform: template
name: "total_gas_1"
device_class: gas
unit_of_measurement: "m³"
state_class: total_increasing
icon: "mdi:fire"
accuracy_decimals: 2
lambda: |-
return id(total_pulses) * 0.01;
Hi, when I try to compile, i get the following error. It doesnt seem to like using the same GPIO for the sensor and the binary sensor. Any ideas
INFO ESPHome 2024.6.4
INFO Reading configuration /config/esphome/esphome-web-9949a4.yaml...
WARNING GPIO5 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
WARNING GPIO5 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
Failed config
binary_sensor.gpio: [source /config/esphome/esphome-web-9949a4.yaml:69]
Pin 5 is used in multiple places.
platform: gpio
id: gas_impulse
internal: True
pin:
number: 5
mode:
input: True
pullup: True
output: False
open_drain: False
pulldown: False
inverted: True
sensor.pulse_meter: [source /config/esphome/esphome-web-9949a4.yaml:83]
Pin 5 is used in multiple places.
platform: pulse_meter
name: Gas Meter Home
id: gas_meter_home
unit_of_measurement: m³/min
internal_filter: 10ms
timeout: 1min
state_class: measurement
device_class: gas
icon: mdi:meter-gas
pin:
number: 5
mode:
managed to get the reed switch and calculations working with this yaml code for ESPhome, but for some reason they sensors are not showing up in home assistant?
esphome:
name: gas-heater
friendly_name: gas-heater
min_version: 2024.6.0
name_add_mac_suffix: false
project:
name: esphome.web
version: '1.0'
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
# Allow Over-The-Air updates
ota:
platform: esphome
wifi:
networks:
- ssid: removed
password: removed
priority: 1
# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:
dashboard_import:
package_import_url: removed
import_full_config: true
# Sets up Bluetooth LE (Only on ESP32) to allow the user
# to provision wifi credentials to the device.
esp32_improv:
authorizer: none
# To have a "next url" for improv serial
web_server:
globals:
- id: gas_impulses
type: int
restore_value: true
initial_value: '0'
sensor:
- platform: pulse_meter
name: "Gas Usage"
id: "gas_usage"
unit_of_measurement: 'm³/min'
internal_filter: '0.01 s'
timeout: 1 min
state_class: measurement
device_class: gas
icon: mdi:meter-gas
pin:
number: GPIO05
mode: INPUT_PULLUP
inverted: true
filters:
# Since each pulse is 0.01 m³, we multiply the pulse count (x) by 0.01.
- lambda: return x * 0.01;
total:
unit_of_measurement: 'm³'
name: "Gas Total Consumption"
id: "gas_total_consumption"
state_class: total_increasing
icon: mdi:meter-gas-outline
accuracy_decimals: 2
filters:
# Here we also multiply the total pulse count by 0.01 to get the total volume.
- multiply: 0.01
on_value:
then:
- lambda: id(gas_impulses) += 1;
In the end, I used this
Doesnt give you gas flow rate though
thanks svenwal