Подошел срок очередной поверки газового счетчика и было принято решение заменить его на счетчик с импульсным выходом. Задача оказалась нетривиальная, так как было жесткое ограничение по параметрам присоединения. Но, слава маркетплейсам, не проходит и недели как заветный гаджет попадает мне в руки.

Умный счетчик природного газа

В руководстве по эксплуатации имеем следующую информацию:

Схема импульсного выхода "открытый коллектор"
Схема импульсного выхода "открытый коллектор"
Разъем TRS 3.5 "мини джек"
Разъем TRS 3.5 "мини джек"

Спасибо производителю - теперь у нас есть все, чтобы подобрать подходящий счетчик импульсов.

Обустройством DIY умного дома я занимаюсь уже не первый год. Сейчас имею такую конфигурацию:

  1. Raspberry Pi 4 (4GB RAM) с Home Assistant OS на борту;

  2. Zig Star LAN в качестве координатора для Zigbee сети;

  3. Порядка 90 Zigbee и 10 Wifi устройств.

Главная страница
Главная страница
Управление отоплением и ГВС
Управление отоплением и ГВС

У меня уже был реализован подсчет потребления холодной воды посредством счетчика импульсов Zigbee (Счетчик импульсов Zigbee — modkam.ru). В последнее время этот счетчик стал отваливаться от сети, но проблема не в самом устройстве, а в его расположении, но об этом чуть позже. 

Подключив это счетчик импульсов к новому газовому счетчику я (вот сюрприз!) не получил адекватных показаний. Причина - он считывает, как мне ответил в комментариях разработчик устройства, ~1 имп/сек. Мы же имеем в даташите и на устройстве - 1 импульс = 0,000125 м3.

Нехитрая математика:

  1. 8000 импульсов за один куб;

  2. 2,73 м3/час максимальный расход газа у котла;

  3. 8000 х 2,73 / 3600 получаем около 6 импульсов в секунду.

Дальнейший поиск решения естественно привел меня к ESPHome. По железу выбор пал на ESP32 DEVKIT V1.

На плате уже есть все что нужно, и разъем питания MicroUSB, и Wifi, и торчащие пины - можно “наколхозить” на коленке без паяльника что угодно.

Изучив документацию на сайте по Pulse Counter Sensor (Pulse Counter Sensor — ESPHome)  и помучив Chat GPT получилась такая конфигурация:

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

Конструктивные комментария/замечания категорически приветствуются, так как я далекий от программирования человек и буду рад советам профессионального сообщества.

Согласно руководству по эксплуатации импульсный выход счетчика - открытый коллектор. Счетчик подключал по такой схеме:

Разъем для подключения импульсного счетчика - TRS 3.5 (мини джек)

Загрузив прошивку на ESP32 получил в интерфейсе HA такие сенсоры:

И такие красивые картинки на панели Энергия в HA:

Умный счетчик воды

Получив положительный опыт я решил заменить счетчик импульсов Zigbee холодной воды на ESP32. У Zigbee очень много плюсов, но в моем случае именно в месте расположения счетчика воды что-то пошло не так. Добиться стабильной работы устройства я не смог. 

Помимо снятия показаний со счетчика холодной воды на вводе в квартиру я также снимаю показания со специально установленного счетчика перед фильтром обратного осмоса для корректного учета ресурсов мембраны и остальных картриджей.

Код для 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

В документации ESPHome по поводу подключения выходов с геркона написано следующее:

inverted: true я ставить не стал, т.к. четкой информации на счетчики я не нашел. Решил оставить так и, в случае некорректных показаний я бы это исправил. Не потребовалось.

Пробное подключение
Пробное подключение

По итогу оба сенсора прекрасно залетели в HA и без проблем отображаются на панели Энергия:

Ну а учет ресурса фильтра обратного осмоса выглядит так:

При нажатии на иконку фильтра выскакивает окно и можно сбросить ресурс при замене картриджа:

Результатом я остался доволен. Теперь мой дом стал еще немного умнее, а 25 числа каждого месяца в телеграм приходят уведомления с показаниями всех счетчиков.  

Комментарии (20)


  1. pruwait
    09.10.2024 22:30

    После реализации подобного импульсного счётчика, стал замечать о серьёзную погрешность, набегающую в ошибку.

    Проблема в дребезге контактов геркона.

    Подбирал несколько месяцев фильтр в строке 72

    #снятие показаний со счетчика через датчик импульсов IN-Z61
    #коричневый ------------ GND
    #зеленый    --+-- 10k -- VCC 3v3
    #.            |
    #.            +--------- GPIO14 (D5) ESP8266
    # WeMos D1 ESP-Wroom-02 ESP8266 Nodemcu WiFi Module With 18650 Battery Charging
    
    substitutions:
      pulse_pin: D2
    
    esphome:
      name: gas-bk-g4t
    
    esp8266:
      board: d1_mini
      restore_from_flash: true
    
    preferences:
      flash_write_interval: 60min
    
    # включаем отладку для поиска причины перезагрузки через лог
    debug:
    
    logger:
    
    # Enable Home Assistant API
    api:
      services:
    # для устаноки начального значения счетчика
    
        - service: update_counter_pulses
          variables:
            counter_pulses: float
          then:
            - globals.set:
                id: pulses_sum
                value: !lambda 'return counter_pulses;'
      
      reboot_timeout: 0s # иначе перезагружается при отключении от hassio        
    
    ota:
      - platform: esphome
    
    wifi:
      ssid: !secret wifi_ssid
      password:  !secret wifi_password
    
      # Enable fallback hotspot (captive portal) in case wifi connection fails
      ap:
        ssid: "GAS-BK-G4T Fallback Hotspot"
        password: !secret ota_pass
      reboot_timeout: 0s # иначе перезагружается при потере wifi
    captive_portal:
    
    
    globals:
      - id: pulses_sum
        type: int
        restore_value: yes
        initial_value: '1000000' 
    
    
    
    binary_sensor:
      - platform: gpio
        id: internal_pulse_counter
        pin:
          number: ${pulse_pin}
          mode: INPUT
        name: "Live-Impuls"
        filters:
          - delayed_on_off: 200ms
        on_press:
          then:
            - lambda: id(pulses_sum) += 1;
            - lambda: id(gas_cons).publish_state(id(pulses_sum));
    
    sensor:
    
      - platform: template
        name: "Gas consumption"
        id: gas_cons
        device_class: gas
        unit_of_measurement: "m³"
        state_class: "total_increasing"
        icon: "mdi:fire"
        accuracy_decimals: 2
        filters:
          lambda: |-
            return x * 0.01;
    
    
    
    # для отслеживания времени работы esp
      - platform: uptime
        name: Uptime Sensor
        id: uptime_sensor
        update_interval: 60s
        internal: true
        on_raw_value:
          then:
            - text_sensor.template.publish:
                id: uptime_human
                state: !lambda |-
                  int seconds = round(id(uptime_sensor).raw_state);
                  int days = seconds / (24 * 3600);
                  seconds = seconds % (24 * 3600);
                  int hours = seconds / 3600;
                  seconds = seconds % 3600;
                  int minutes = seconds /  60;
                  seconds = seconds % 60;
                  return (
                    (days ? to_string(days) + "d " : "") +
                    (hours ? to_string(hours) + "h " : "") +
                    (minutes ? to_string(minutes) + "m " : "") +
                    (to_string(seconds) + "s")
                  ).c_str();        
    
     
    
    text_sensor:
      - platform: template
        name: Uptime Human Readable
        id: uptime_human
        icon: mdi:clock-start


    1. Kononvaler
      09.10.2024 22:30

      RC фильтр не проще было впаять для устранения дребезга?

      И обратите внимание на esp32-c3 mini:

      для одного входа такой огромный боард.


      1. fio
        09.10.2024 22:30

        Столкнулся с тем, что ESP32 Super mini имеет гораздо худший прием WiFi. У модуля компактные размеры - в т.ч. и антенны

        В дальних углах лучше ставить "большие" варианты модулей на ESP32


        1. Kononvaler
          09.10.2024 22:30

          Ну при обильном количестве устройств не мешало бы и сеть подулучшить. Я кинетик орбитер понаставил точек доступа, а то и отопление и движение и много чего на есп.

          И для счетчика наверно напрашивается Seeed Studio XIAO ESP32C3
          с поддержкой батарейки, там и антенна внешняя подключается.

          https://aliexpress.ru/item/1005005382287176.html?sku_id=12000037754252111&spm=a2g2w.productlist.search_results.0.5bc743d0jUypP7


          1. kuzhakhmetov Автор
            09.10.2024 22:30

            Интересная штука (я про Seeed Studio XIAO ESP32C3). Спасибо за наводку.


    1. kuzhakhmetov Автор
      09.10.2024 22:30

      Я тоже пробовал реализовать подсчет через binary_sensor, но добиться корректных показаний не смог. Казалось бы, какая разница через что писать в глобальные переменные.

      А по поводу дребезга контактов - подтверждаю, тоже пришлось поиграться, но только параметром debounce. 10 мс в моем случае было достаточно.


  1. CyberexTech
    09.10.2024 22:30

    А как обстоят дела при отключении электроэнергии? Насколько я понял, устройства не имеют автономного источника питания и, в случае сбоя в электропитании, придется обновлять начальные показания счётчиков.


    1. AlexGluck
      09.10.2024 22:30

      Есть waterius, тоже тут на хабре пишут статьи и у них понадежнее решение для газа и воды.


      1. fio
        09.10.2024 22:30

        Ватериус - это законченное решение. Но кому-то не хочется иметь зависимость от внешних сервисов. ESPhome позволяет таким людям сделать свое устройство внутри HomeAssistant.


        1. AlexGluck
          09.10.2024 22:30

          Ватериус опенсорсный, исходники на гитхабе, отправляет в ваш HomeAssistant, собирается так же на esp. Про какую зависимость вы говорите? Может вы просто не в курсе про возможности?


          1. fio
            09.10.2024 22:30

            Как обстоят дела прямо сейчас я не в курсе. Но какое-то время назад писал разработчику относительно зависимости функций от внешних (за пределами моей квартиры) сервисов. Тогда зависимость для меня была серьезная.

            Поэтому свое устройство сделал на ESPhome.


            1. AlexGluck
              09.10.2024 22:30

              Ну 3 года назад уже был mqtt, возможно когда вам надо было, этот функционал ещё не реализовали.


      1. kuzhakhmetov Автор
        09.10.2024 22:30

        Я писал в поддержку ватериуса по поводу совместимости с выходом "открытый коллектор". Они сказали что не поддерживается.

        Для счетчиков воды их можно рассмотреть, но для моего счетчика газа - не факт.

        Купив плату ESP32 за 300 р я получил работающее решение.

        Купить устройство в 10 раз дороже и потом его пытаться допилить? Избавляться от возможных некорректных измерений?

        Вот когда они сделают устройство под ключ и под мой счетчик газа - тогда цена будет оправдана.


    1. kuzhakhmetov Автор
      09.10.2024 22:30

      После пропажи питания (либо перезагрузки устройства) будет выводиться последнее записанное в глобальную переменную globals: значение. Да, возможны небольшие погрешности (например счетчик не записал импульс перед отключением), но тут выбирает каждый сам для себя. Если перебои с электроснабжением частые, то нужно организовывать независимое питание. Если как у меня - отключения крайне редкие, а когда нет света, то и воды тоже нет, то можно показания счетчиков раз в год и подкрутить к фактическим.


  1. la0
    09.10.2024 22:30

    У меня для аналогичной задачи аналогично мало опыта, но очень хочется сделать счётчик в deep-sleep, отправляя по mqtt только изменения раз в час если они вообще говоря были и раз в сутки статус "я жив".

    Deep sleep хочется чисто из-за возможности жить по полгода от одной батарейки

    https://habr.com/ru/companies/timeweb/articles/827248/#comment_27062038


    1. AlexGluck
      09.10.2024 22:30

      Как я выше писал в комментариях, то что вы хотите реализовано в waterius. Автор на хабре пишет через поиск можно найти.


  1. Microturbine
    09.10.2024 22:30

    Я использовал счётчик воды элехант. Он не имеет никаких выводов (даже экрана), но передаёт все показания по Bluetooth пакетами Advertising.

    Предполагается получение показаний через их лагучее приложение на телефоне, но я пошел другим путём.

    На Raspberry принимал пакеты и парсил, потом в influxDB, визуализировал графики в Grafana. Ещё встречал скрипт для HA на гитхабе (оттуда собственно и разобрался, что собственно посылает счётчик). Преимущество данной схемы в том, что кроме счётчика и Raspberry не нужно дополнительных устройств.

    У элехант, кстати, есть и на газ счётчики.


    1. kuzhakhmetov Автор
      09.10.2024 22:30

      Да, видел решения от Элеханта. Их счетчик газа мне по фланцам не подошел. А в остальном они молодцы. Можно рассмотреть к установке.


  1. foxyrus
    09.10.2024 22:30

    Оффтопно, у вас большие карточки, я у себя все сгруппировал более компактно с помощью room-card

    картинка


    1. kuzhakhmetov Автор
      09.10.2024 22:30

      Спасибо за совет! Давно интерфейс не менял. Как раз повод новую карточку заюзать.