Um mal etwas YAML in den Raum zu werfen, hier meine Config für den Gaszähler:
YAML:
esphome:
name: esphome-web-1cebf6
esp8266:
board: d1_mini
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esphome-Web-XXXXXX"
password: "****************"
captive_portal:
globals:
- id: total_pulses
type: int
restore_value: false
initial_value: '9086948' # hier kann der Gaszählerstand initialisiert werden
binary_sensor:
- platform: gpio
id: internal_pulse_counter
pin:
number: GPIO5 # "D1"
mode: INPUT_PULLUP
name: "Live-Impuls"
filters:
- delayed_on: 100ms
on_press:
then:
- lambda: id(total_pulses) += 1;
sensor:
- platform: template
name: "Gasverbrauch"
device_class: gas
unit_of_measurement: "m³"
state_class: "total_increasing"
icon: "mdi:fire"
accuracy_decimals: 2
lambda: |-
return id(total_pulses) * 0.01;
Was immer recht aufwändig ist, die IO-Pins zu identifizeren, ebenso das richtige Board. Die Erfassung selbst mache ich mit einem Reed-Kontakt (Meeder) nachdem ich über Tage verzweifelt versucht habe das mit einem Hall-Sensor oder einem optischen Sensor (IR-Reflex) stabil an laufen zu bekommen. Der gute alte Reed funktioniert hier noch am zuverlässigsten und ist auch am billigsten ;-)
Die config habe ich geklaut und versuche sie noch zu verstehen. Die Idee dahinter ist den "binary_sensor" zu verwenden um quasi die Ein/Aus-Schaltzeitpunkte zu erfassen. Bei jedem Übergang von 1->0 wird eine Zählervariable hochgezählt. Das entspricht dann immer einer vollen Umdrehung der letzten (3.) Nachkommastelle am Gaszähler und somit 0,01 m³ Gasverbrauch.
Die erste Zeilen zeigen wohl an das "esphome" als Integrationsplugin genutzt werden soll?
YAML:
esphome:
name: esphome-web-1cebf6
Der Name ist das was angezeigt und intern verwendet wird. Den kann man nachträglich nicht mehr ändern ohne seine Dashboards zu killen. Daher "wähle weise!".
Dann folgt die Angabe des Board-typs an dem der Sensor angeschlossen ist. Ich verwende hier ein Shield von az-delivery was wohl ein clone der bekannten Wemos D1 mini Serie ist. Der Wifi-Chip auf dem Shield ist ein "Espressif 8266 12-F":
Anhang anzeigen 1868Anhang anzeigen 1870
Da ich vermute das diese Settings im Kontext mit ESPHome zu verstehen sind, habe ich hier bei den Devices geschaut:
https://esphome.io/devices/index.html was am besten passen könnte und bin auf den
https://esphome.io/devices/esp8266.html gestoßen, was ja dem Chipsatz entspricht. Auf dieser Seite gibt es dann einen Link wo alle möglichen Boards aufgelistet sind:
https://registry.platformio.org/platforms/platformio/espressif8266/boards
Den az-delivery sucht man da vergebens, aber den Wemos D1 mini ist enthalten:
https://docs.platformio.org/en/latest/boards/espressif8266/d1_mini.html
Da drin wiederum ist der Hinweis auf den Board-Typ "d1_mini". Über diese Wahl wird wohl neben der richtigen Toolchain zum kompilieren der Firmware auch das Pinout bestimmt, welches für mein o.g. Board so aussieht:
Anhang anzeigen 1869
Den Reed-Kontakt habe ich zwischen "GND" und "D1" verbunden. Meine Idee war das der active-low schalten soll, daher muss der Pin dann einen Pullup haben. Den hätte ich per 10k Widerstand gegen +3.3V (WICHTIG! Der ESP8266 hat eine IO-Spannung von 3.3V) hochziehen können, aber der Chip hat auch interne Pullups, da spart man ein Bauteil.
Beachten muss man hier das der Chipsatz (ESP8266 12-F) ja eigene Pins und Bezeichnungen hat. Die weichen von dem was auf dem Board aufgedruckt ist erheblich ab und ohne eine solche Legende hat man eigentlich keine Chance den richtigen Pin zu treffen. Auch sind nicht immer alle Pins rausgeführt bzw. gibt es eigene Komponenten auf dem Board die an Pins liegen. Das macht es unglaublich "würzig"...
Ich habe diesen Meder MK4-1A66B genommen:
Anhang anzeigen 1871
Entscheidend ist hier das "B", es gibt nämlich die Empfindlichkeit an, also die magnetische Kraft welche benötigt wird um den Kontakt zu schließen. Diese wiederum ist natürlich von der Ausrichtung und Entfernung zum Magneten abhängig. Laut Datenblatt ist der Wert "10-15 AT", keine Ahnung was das in Tesla bedeutet.
Zur Erfassung hat man hier den "binary_sensor" genommen
https://esphome.io/components/binary_sensor/index.html um Ein/Ausschaltimpulse zu zählen. Dann kommt wieder so ein wirres Stück YAML was eine "platform" einstellt (keine Ahnung was das wieder ist). Der "pin" wird definiert mit "GPIO5" was oben in der Legende "IO5" und letztlich dem Aufdruck "D1" auf dem Board entspricht. Mit "mode: INPUT_PULLUP" wird der interne Pullup-Widerstand aktiviert. Das ist wichtig bei Active-Low ohne externen Pullup. Über einen "delayed_on" filter wird der Kontakt entprellt, sodass leicht zittriges anziehen keine Mehrfachauslösung erzeugt. Ich habe 100ms Entprellzeit gewählt, das scheint mir ausreichend groß um prellen jeder art zu unterdrücken und klein genug um keinen Umdrehungsimpuls zu verpassen.
YAML:
binary_sensor:
- platform: gpio
id: internal_pulse_counter
pin:
number: GPIO5 # "D1"
mode: INPUT_PULLUP
name: "Live-Impuls"
filters:
- delayed_on: 100ms
on_press:
then:
- lambda: id(total_pulses) += 1;
MIt "on_press" wird wohl eine Triggerfunktion ausgelöst, in diesem Fall eine sog. Lambda-Funktion. In anderen Programmiersprachen versteht man darunter eine Unterroutine ohne eigenen Funktionsnamen, quasi "Inline - on the fly code". Die Funktion "id()" kenne ich nicht, könnte aber sein das daruch ein Wert irgendwo hin geschrieben wird. Der Wert der aus der Gleichung heraus kommt ist der letzte Wert von "total_pulses" plus 1. total_pulses ist der Name der Variablen in der er gespeichert ist. Eventuell gibt es diese Variable nur im Arbeitsspeicher auf dem Board, aber evtl. auch in der Datenbank von HA?
Diese Variable wird hier definiert, als globale Variable vom Typ Integer:
YAML:
globals:
- id: total_pulses
type: int
restore_value: false
initial_value: '9086948' # hier kann der Gaszählerstand initialisiert werden
Das "initial_value" sorgt dafür das die Variable nicht mit "0" anfängt (oder ggf. sogar UNDEF ist), sondern eben dem abgelesenen Gaszählerstand entspricht. Wichtig hierbei ist das die Nachkommastellen, bis auf die letzte Zählerstelle, als gesamte Ganzzahl eingegeben wird. Vermutlich kann man das auch anders machen und anstelle einem "int" einen "float" definieren, mit "90869.48" initialisieren und dann nicht "+= 1" zählen, sondern "+= 0.01" ?
Zuletzt folgt noch der "sensor" Block:
YAML:
sensor:
- platform: template
name: "Gasverbrauch"
device_class: gas
unit_of_measurement: "m³"
state_class: "total_increasing"
icon: "mdi:fire"
accuracy_decimals: 2
lambda: |-
return id(total_pulses) * 0.01;
Den verstehe ich so das mit "sensor" eine Liste von Entities entstehen kann. Hierr entsteht nur einer mit dem Name "Gasverbrauch" (sicher wieder eine schlechte Wahl, besser wäre wohl ein technischer Name?). Dann kommen viele interessante Angaben die man zwar versteht, aber ich nicht weiss wie man darauf kommt das da hin schreiben zu können...
Das "icon: mdi:fire" sorgt für die kleine Flamme. Ich habe mal geschaut was es alles für icons gibt, das ist uferlos, tausende.
Am Ende erhält man bei "+ADD DEVICE" und Auswahl des Sensors "Gasverbrauch" im Dashboard einen Gaszähler, nicht schick aber er tut was er soll:
Anhang anzeigen 1875