Gas and water meters on ESP32 in Home Assistant

The time has come for the next verification of the gas meter and it was decided to replace it with a meter with a pulse output. The task turned out to be non-trivial, since there was a strict limitation on connection parameters. But, thank the marketplaces, not even a week passes before the treasured gadget falls into my hands.

Smart natural gas meter

In the instruction manual we have the following information:

Pulse output circuit "open collector"

Open collector pulse output circuit

TRS 3.5 connector "mini jack"

TRS 3.5 “mini jack” connector

Thanks to the manufacturer – now we have everything to choose a suitable pulse counter.

I have been building a DIY smart home for several years now. Now I have this configuration:

  1. Raspberry Pi 4 (4GB RAM) with Home Assistant OS on board;

  2. Zig Star LAN as a coordinator for the Zigbee network;

  3. About 90 Zigbee and 10 Wifi devices.

Home page

Home page

Heating and hot water control

Heating and hot water control

I have already implemented calculation of cold water consumption using a Zigbee pulse counter (Zigbee pulse counter – modkam.ru). Recently, this meter began to fall off the network, but the problem is not in the device itself, but in its location, but more on that later.

Having connected this pulse counter to a new gas meter, I (what a surprise!) did not receive adequate readings. The reason is that it reads, as the device developer answered me in the comments, ~1 pulse/sec. We have in the datasheet and on the device – 1 pulse = 0.000125 m3.

Simple math:

  1. 8000 pulses per cube;

  2. 2.73 m3/hour maximum gas flow of the boiler;

  3. 8000 x 2.73 / 3600 we get about 6 pulses per second.

Further search for a solution naturally led me to ESPHome. For hardware, the choice fell on the ESP32 DEVKIT V1.

The board already has everything you need, a MicroUSB power connector, Wifi, and protruding pins – you can “make up” anything on your knee without a soldering iron.

Having studied the documentation on the website for Pulse Counter Sensor (Pulse Counter Sensor – ESPHome) and tortured Chat GPT with the following configuration:

esphome:
  name: gas-count
  friendly_name: gas_count

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: ******
# Блок для ввода фактических значений показаний из интерфейса HA
  actions:
    - service: set_pulse_total_gas
      variables:
        new_pulse_total: float
      then:
        - lambda: |-
            id(saved_total_gas_consumption) = new_total;
            ESP_LOGD("custom", "Set total gas consumption to: %f", id(saved_total_gas_consumption));
ota:
  - platform: esphome
    password: *******

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Gas-Count Fallback Hotspot"
    password: ********

captive_portal:

globals:
  - id: saved_total_gas_consumption  # Глобальная переменная для сохранения данных при перезагрузке устройства
    type: float
    restore_value: true
    initial_value: '0.0'


sensor:
  - platform: pulse_counter
    pin: GPIO04   
    id: gas_meter_counter  
    name: "Gas Meter Pulse Count"
    unit_of_measurement: "pulses"
    accuracy_decimals: 1
    filters:
      - debounce: 10ms  # Игнорировать сигналы, которые длятся менее 10 мс. По даташиту длительность импульса от 2 до 6 мс.
      - multiply: 0.000125  # Применение коэффициента для пересчета импульсов в м³
      - lambda: |-
          id(saved_total_gas_consumption) += x;
          return id(saved_total_gas_consumption);
# Выводим значения глобальной переменной в HA
  - platform: template
    name: "Saved Total Gas Consumption"
    device_class: gas
    lambda: |-
      return id(saved_total_gas_consumption);
    unit_of_measurement: "m³"
    accuracy_decimals: 6

Constructive comments/remarks are absolutely welcome, since I am far from a programming person and will be glad to receive advice from the professional community.

According to the operating manual, the pulse output of the meter is an open collector. The meter was connected according to this scheme:

Connector for connecting a pulse counter – TRS 3.5 (mini jack)

After downloading the firmware to the ESP32, I received the following sensors in the HA interface:

And such beautiful pictures on the Energy panel in HA:

Smart water meter

Having gained positive experience, I decided to replace the Zigbee cold water pulse counter with an ESP32. Zigbee has a lot of advantages, but in my case, it was in the location of the water meter that something went wrong. I was unable to achieve stable operation of the device.

In addition to taking readings from the cold water meter at the entrance to the apartment, I also take readings from a specially installed meter in front of the reverse osmosis filter to correctly account for the resources of the membrane and other cartridges.

Code for ESPHome:

esphome:
  name: water-count
  friendly_name: water_count

esp32:
  board: esp32dev
  framework:
    type: arduino

# Подключение к Wi-Fi сети
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Water-Count Fallback Hotspot"
    password: *******

captive_portal:

# Enable Home Assistant API
api:
  encryption:
    key: *******
# Блок для ввода фактических значений показаний из интерфейса HA
  services:
    - service: set_water_total
      variables:
        new_total: float
      then:
        - lambda: |-
            id(saved_total_water_consumption) = new_total;
            ESP_LOGD("custom", "Set total water consumption to: %f", id(saved_total_water_consumption));

    - service: set_filter_water_total
      variables:
        new_total: float
      then:
        - lambda: |-
            id(saved_total_filter_water_consumption) = new_total;
            ESP_LOGD("custom", "Set total filter water consumption to: %f", id(saved_total_filter_water_consumption));

ota:
  - platform: esphome
    password: *******

# Веб-сервер для диагностики
web_server:
  port: 80

# Логирование
logger:
   
# Глобальные переменные для хранения количества литров
globals:
  - id: saved_total_water_consumption
    type: float
    restore_value: True
    initial_value: '0.0'
 
  - id: saved_total_filter_water_consumption
    type: float
    restore_value: True
    initial_value: '0.0'

# Настройка для счетчика воды
sensor:
  - platform: pulse_counter
    pin:
      number: GPIO14   # Пин счетчика воды
      mode:
        input: true
        pullup: true
    id: water_meter_counter  # ID счетчика воды
    name: "Water Meter"
    unit_of_measurement: "pulses"
    accuracy_decimals: 1
    filters:
      - multiply: 10  # Применение коэффициента для пересчета импульсов в литры. 1 импульс - 10 литров
      - lambda: |-
          id(saved_total_water_consumption) += x;
          return id(saved_total_water_consumption);

# Настройка для счетчика перед фильтром
  - platform: pulse_counter
    pin:
      number: GPIO27   # Пин счетчика воды перед фильтром
      mode:
        input: true
        pullup: true
    id: filter_water_meter_counter  # ID счетчика перед фильтром
    name: "Filter Water Meter"
    unit_of_measurement: "pulses"
    accuracy_decimals: 1
    filters:
# Для счетчика перед фильтром коэффициент не применяю, т.к. 1 импульс у него равен 1 литру.
      - lambda: |-
          id(saved_total_filter_water_consumption) += x;
          return id(saved_total_filter_water_consumption);
# Выводим значения глобальных переменных в HA
  - platform: template
    name: "Saved Total Water Consumption"
    device_class: water
    lambda: |-
      return id(saved_total_water_consumption);
    unit_of_measurement: "L"
    accuracy_decimals: 1

  - platform: template
    name: "Saved Total Filter Water Consumption"
    device_class: water
    lambda: |-
      return id(saved_total_filter_water_consumption);
    unit_of_measurement: "L"
    accuracy_decimals: 1

The ESPHome documentation regarding connecting outputs from a reed switch says the following:

inverted: true I did not set it because I did not find clear information on the meters. I decided to leave it this way and, in case of incorrect readings, I would correct it. Not needed.

Test connection

Test connection

As a result, both sensors flew perfectly into HA and are displayed without problems in the Energy panel:

Well, accounting for the resource of a reverse osmosis filter looks like this:

When you click on the filter icon, a window pops up and you can reset the resource when replacing the cartridge:

I was pleased with the result. Now my house has become a little smarter, and on the 25th of every month I receive notifications in telegram with readings of all meters.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *