I had decided to write this after not been able to find a tutorial to use a reed sensor to measure the consumption of gas in my home.
Requirements
- A meter (not necesarily a gas meter) that has a magnet attached to one of the numbers that rotate in the screen.
- An Beetle ESP32-C6 board (mine cost me around 7USD from Botland.pl).
- A reed sensor compatible with your meter*
- A Li-Pol battery pack (I bought a 4000mAh for 12USD)
*I had to purchase the Apator NI-3 pulse transmissor since my gas meter has a special socket for it. No other reed sensor gets close enought to the magnet to work.
Once I got the board I solder the pins into the it and connected the cables in this way:
This is the EspHome configuration I used:
I had removed sections for configuring openthread/wifi, ota, logger, etc.
esphome:
name: gas-meter
friendly_name: Gas Meter
on_boot:
then:
- globals.set:
# This is used below to avoid updating the global total_pulses BEFORE pulse_counter.set_total_pulses is executed. Otherwise "total_pulses" will be set to 0
id: data_was_restored
value: 'true'
- pulse_counter.set_total_pulses:
id: gas_pulse_counter
value: !lambda 'return id(total_pulses);'
preferences:
# This reduces the number of writes in the onboard memory and extends its lifespan
flash_write_interval: 60s
globals:
- id: total_pulses
type: int
restore_value: yes
initial_value: "0" # This is not a mistake. Globals are all stored as strings.
- id: data_was_restored
type: bool
initial_value: "0"
esp32:
variant: esp32c6
board: esp32-c6-devkitc-1
framework:
type: esp-idf
sensor:
- platform: pulse_counter
id: gas_pulse_counter
name: "Current consumption"
unit_of_measurement: "mÂł/hour"
device_class: "gas"
state_class: "measurement"
icon: "mdi:meter-gas"
count_mode:
rising_edge: DISABLE
falling_edge: INCREMENT
pin:
number: 7
inverted: true
mode:
input: true
pullup: true
update_interval: 600s # 10 minutes
accuracy_decimals: 2
filters:
# According to my meter's manual, it makes a pulse every 0.01 m3. It could be different for yours
- multiply: 0.06 # 1 pulse = 0.01 m3. 1h = 3600s. That's 6 times the update_interval.
total:
name: "Total consumption"
id: total_gas_consumption
unit_of_measurement: "mÂł"
icon: "mdi:meter-gas"
accuracy_decimals: 2
device_class: "gas"
state_class: "total_increasing"
on_value:
then:
- if:
# This avoids overriding the total_gas_consumption global before the value is restored by on_boot
condition:
lambda: 'return id(data_was_restored);'
then:
- lambda: 'id(total_pulses) = id(total_gas_consumption).raw_state;'
filters:
- multiply: 0.01
- platform: adc
name: "Battery voltage"
pin: GPIO0 # The voltage of the battery is connected to this internal pin to messure its voltage
accuracy_decimals: 2
update_interval: 60s
attenuation: 12dB
samples: 10
filters:
- multiply: 2.0 # The voltage divider requires us to multiply by 2
# Enable Home Assistant API
api:
encryption:
key: "YOU NEED TO GENERATE THIS"
actions:
# This will create an HASS action you can use to manually update the total count of recorded pulses
- action: set_pulse_total
variables:
new_pulse_total: int
then:
- pulse_counter.set_total_pulses:
id: gas_pulse_counter
value: !lambda 'return new_pulse_total;'
I bought the C6 because I wanted to use it with opentread in the hope the battery will last for months, not days.
I have it running for 113 hours using Wifi. The battery has drop from 4.16v to 3.54v so far. That’s 0.0054v per hour. Assuming the voltage will keep dropping at a similar rate, that means the 4000mAh battery will give me 8.8 days with the current configuration.
Today I’ll re-fjash it using openthread and compare the difference. I’ll post the results here in a few days.


