Gaszähler für Gasuhr mit Magnet

u5zzug

Member
ist jemand daran interessiert?
Nachdem das mit einem Reedkontakt nie funktionierte, habe ich es letztes Jahr in ESPHome mit einem
Magnetometer umgesetzt.
 

u5zzug

Member
Verwendet wurde ein ESP8266 mit einem Dallas Temperatursensor (ich wollte den Gasverbrauch mit der Temperatur verrechnen, aber ich habe keine passenden Zustandszahlen gefunden und so heftig ändert sich die Temperatur auch nicht) und ein
HMC5883L Magnetometer, dass sich als QMC5883L entpuppte. Die haben verschiedene Adressen und Ablesewerte.

In ESPHome kann mas substitutions verwenden, das sind Variablen.
Außerdem kan man mit packages: Dateien mit für jedes Gerät benötigtem Code einbinden.
DIe Ordner und Dateien muss man händisch anlegen Passwörter u.ä stehen wie bei HA in einer secrets.yaml.

Das ist die Konfiguration für den Gaszähler.
YAML:
#######################################################################
# Substitutions - use like $substitution_key or ${substitution_key}
#######################################################################
substitutions:
  # Project Name, upper/lowercase characters, digits and underscores.
  # Used as: hostname, mdns name, folder name
  project_name: 'esp-wh'
  project_id: 'esp_wh'

  # Used as: AP SSID, Common (Wifi, Uptime, Switch) Sensors
  friendly_name: 'esp Waschhaus'

  # Wifi Configuration
  wifi_ssid: !secret wifi_ssid
  wifi_password: !secret wifi_password
  static_ip: 192.168.1.161

  # AP (Access Point) Configuration
  ap_password: !secret ap_password
  ap_channel: '6'
  ap_timeout: '5min'

  # API Configuration
  api_password: !secret api_password

  # OTA Configuration
  ota_password: !secret ota_password

  # Log Level
  log_level: DEBUG

  # which sensor to use for puls detection
  magnetometer: "${project_id}_qmc5883ly"

#######################################################################
# Device config
#######################################################################
esphome:
  name: ${project_name}

esp8266:
  board: d1_mini

#######################################################################
# Include common config
#######################################################################
packages:
  common: !include common/common.yaml
  wifi_sensors: !include common/wifi.diag.yaml
  uptime: !include common/uptime.diag.yaml

preferences:
  flash_write_interval: 3min

i2c:
  scan: true        # Default true
  frequency: 100kHz # Default 50kHz. Values: 10kHz, 50kHz, 100kHz, 200kHz, … 800kHz

# Dallas Temp. Sensoren, Dreibein
dallas:
  - pin: D4

# global variables
globals:
   - id: gas_counter_total
     type: double
     restore_value: no
#     initial_value: '2717.94'
   - id: gas_counter
     type: int
     restore_value: no
     initial_value: '0'
   - id: gas_high
     type: bool
     restore_value: no
     initial_value: 'false'
   - id: magnetometer_last_value
     type: int
     restore_value: no
   - id: heating
     type: bool
     restore_value: no
   - id: heating_paused
     type: bool
     restore_value: no

# run actions at fixed time intervals
interval:
  - interval: 5s
    then:
    # convert magnetometer values to boolean gas_hight for counting pulses.
    # adapt numbers regarding your measured values
    - lambda: |-
       if (id($magnetometer).state >= 500 && !id(gas_high)) {
          id(gas_counter_total) += 0.01;
          id(gas_counter) += 1;
          id(gas_high) = true;
          ESP_LOGD("Gas", "+1");
        } else if (id($magnetometer).state <= 150 && id(gas_high)) {
          id(gas_high) = false;
        }

  - interval: 10s
    then:
    # boolean sensor for heating on/off to show when burner is on
#          ESP_LOGD("Gas", "+1");
    - lambda: |-
        // ESP_LOGI("Gas", "letzter Wert: %d", int(id(magnetometer_last_value)))
        // ESP_LOGI("Gas", "  aktuel. Wert: %d", int(id(${magnetometer}_delta).state));
       
        if (int(id(magnetometer_last_value)) == int(id(${magnetometer}_delta).state)) {
          if (id(heating_paused)) {
            id(${project_id}_heating).publish_state(false);
          }else{
            id(heating_paused) = true;
          }
        } else {
          id(heating_paused) = false;
          id(${project_id}_heating).publish_state(true);
        }
        id(magnetometer_last_value) = id(${magnetometer}_delta).state;      

binary_sensor:
# burner on/of
  - platform: template
    name: "${friendly_name} - Heizung heizt"
    id: ${project_id}_heating
    icon: 'mdi:fire'
    device_class: heat
   
sensor:
# Dallas Temperatur Sensor
# Waschhaus, Gasleitung
  - platform: dallas
    address: 0xf200000a304a6328
    id: ${project_id}_ds18b20_gas
    name: "${friendly_name} - Temperatur Gasleitung"
    device_class: temperature
    unit_of_measurement: "°C"

# Magnetometer / Gasmeter
# there are similar sensors - hmc5883l and qmc5883l
# if it looks like a hmc5883l, but dont work consider it may be a qmc5883l
  - platform: qmc5883l
    address: 0x0D
# Gasmeter X  
    field_strength_x:
      name: "${friendly_name} - Gasmeter X"
      id: ${project_id}_qmc5883lx
      accuracy_decimals: 0
      filters:
      - multiply: -1
# Gasmeter Y    
    field_strength_y:
      name: "${friendly_name} - Gasmeter Y"
      id: ${project_id}_qmc5883ly
      accuracy_decimals: 0
      filters:
      - multiply: -1
# Gasmeter Z    
    field_strength_z:
      name: "${friendly_name} - Gasmeter Z"
      id: ${project_id}_qmc5883lz
      accuracy_decimals: 0
      filters:
      - multiply: -1
    oversampling: 64x
    range: 800uT
    update_interval: 1s
   
# Gasfluss für An/Aus Erkennung
# ich habe versucht, hier einen möglichst eindeutigen Impuls zu bekommen, ohne Impulse zu verpassen, wenn er sich schnell dreht.
# Wenn der Magnet an einer ungünstigen Stelle stehen bleibt, wackelt der Wert furchtbar herum.
# ausprobieren!
  - platform: template
    name: "${friendly_name} - Gasmeter Y Delta"
    id: ${magnetometer}_delta
    lambda: |-
      return id($magnetometer).state/2;
    update_interval: 2s
    accuracy_decimals: 0
    icon: 'mdi:fire'
    device_class: gas
    state_class: measurement
    unit_of_measurement: "uT"
    filters:
    - max:
#        window_size: 3
#        send_every: 5
#        send_first_at: 3  
    - delta: 5  

# Gas Durchfluss/min
  - platform: template
    name: "${friendly_name} - Gas Durchfluss"
    id: ${project_id}_gas_momentan
    lambda: |-
      int temp = id(gas_counter);
      id(gas_counter) -= temp;
      return temp;
    update_interval: 60s
    unit_of_measurement: "Pulse"

# Gas gesamt
  - platform: template
    name: "${friendly_name} - Gas Gesamt"
    id: "${project_id}_gas_total"
    lambda: |-
      return id(gas_counter_total);
    update_interval: 600s
    unit_of_measurement: "m³"
    accuracy_decimals: 2
    icon: 'mdi:fire'
    device_class: gas
    state_class: total_increasing

# Gas kWh
  - platform: template
    name: "${friendly_name} - Gas kWh"
    id: "${project_id}_gas_kwh"
# Gasvolumen in m³ x Zustandszahl x Brennwert = Gasverbrauch in kWh
# Zustandszahl: 0.8934
# Brennwert Flüssiggas: 25,88
    filters:
    lambda: |-
      return (id(gas_counter_total) * (25.88));
    update_interval: 5s
    unit_of_measurement: "kWh"
    accuracy_decimals: 2
    icon: 'mdi:fire'
    device_class: energy
    state_class: total_increasing

# Gas  Liter
# 1 m³ = 3,93 Liter
  - platform: template
    name: "${friendly_name} - Gas Liter"
    id: "${project_id}_gas_liter"
    filters:
    lambda: |-
      return (id(gas_counter_total) * (3.93));
    update_interval: 60s
    unit_of_measurement: "L"
    accuracy_decimals: 2
    icon: 'mdi:waves'
    device_class: gas
    state_class: total_increasing
 

u5zzug

Member
in den eingebundenen Dateien steht folgendes:

YAML:
# esphome/common/common.yaml
###################################################################
# WiFi Component - https://esphome.io/components/wifi.html
wifi:
# if no WiFi connection exists, reboot after this time.
  reboot_timeout: 30s  #default: 15min
  fast_connect: true
  ap:
    ssid: ${project_name}
    password: ${ap_password}
    channel: ${ap_channel}
    ap_timeout: ${ap_timeout}
  networks:
    - ssid: ${wifi_ssid}
      password: ${wifi_password}
  manual_ip:
    static_ip: ${static_ip}
    gateway: 192.168.1.254
    subnet: 255.255.255.0
captive_portal:
###################################################################
# Web Server Component - https://esphome.io/components/web_server.html
web_server:
  port: 80
###################################################################
# Native Home Assistant API - https://esphome.io/components/api.html
api:
  port: 6053
  password: ${api_password}
  reboot_timeout: 0s
###################################################################
# Over the Air Mode - https://esphome.io/components/ota.html
ota:
  safe_mode: true
  password: ${ota_password}
###################################################################
# Logger Component - https://esphome.io/components/logger.html
logger:
  level: $log_level


Wifi Diagnose
YAML:
# esphome/common/wifi.diag.yaml
###################################################################
# Diagnostic Wifi Sensors
sensor:
  # Wireless Signal - RSSI
  - platform: wifi_signal
    id: wifisignal
    name: ${friendly_name} - Wifi Signal
    icon: "mdi:wifi"
    update_interval: 60s
    unit_of_measurement: 'dB'
    accuracy_decimals: 0

  # Wireless Signal - Quality
  - platform: template
    id: wifi_quality
    name: ${friendly_name} - Wifi Quality
    icon: "mdi:wifi"
    update_interval: 60s
    unit_of_measurement: '%'
    accuracy_decimals: 0
    lambda: |-
      if (id(wifisignal).state < -92.0)
        return 100.0;
      if (id(wifisignal).state > -21.0)
        return 1.0;
      else
        return round(( -0.0154 * id(wifisignal).state * id(wifisignal).state )-( 0.3794 * id(wifisignal).state ) + 98.182 );

###################################################################
# Text Sensor Component - https://esphome.io/components/text_sensor/

Uptime kann man auch weglassen, wenn man es nicht braucht. Ich hatte anfangs Probleme mit dem wlan im Keller, weshalb ich den automatischen Neustart und die Uptime eingebaut habe.
YAML:
# esphome/common/uptime.diag.yaml
###################################################################
# Diagnostic Uptime Sensor
sensor:
  # Platform Uptime
  - platform: uptime
    id: ${project_id}_uptime
    name: "${friendly_name} - Uptime"
    icon: "mdi:timer"
    update_interval: 60s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: ${project_id}_uptime_human
            state: !lambda |-
              int seconds = round(id(${project_id}_uptime).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();
binary_sensor:
  - platform: status
    name: "${friendly_name} - Status"
    id: ${project_id}_status
    device_class: running
text_sensor:
  - platform: template
    name: "${friendly_name} - Uptime lesbar"
    id: ${project_id}_uptime_human
    icon: mdi:clock-start
 

u5zzug

Member
Wenn man die ESPs vom Browser aus flashen will, braucht man https, da ich das lokal nicht habe, verwende ich https://web.esphome.io/ - geht nur in Chromium oä. oder Edge.
Unter Linux durfte ich nicht auf die nötige Schnittstelle zugreifen.
ttyUSB0 gehört dem user root und der Gruppe dialout.
Also den eigenen Nutzer zur Gruppe dialout hinzufügen und neu starten oder zumindest neu anmelden, damit die Änderung greift.
 

u5zzug

Member
Von den 3 Magnetometer/Kompasskurven habe ich mir die ausgesucht, die mir am besten auswertbar erschien.Gas Y.pngHeizung.png
 

Zurzeit aktive Besucher

Letzte Anleitungen

Statistik des Forums

Themen
968
Beiträge
14.034
Mitglieder
499
Neuestes Mitglied
John58
Oben