Wiederverwertbare ESPHome-Codeblöcke in eigene YAML-Datei auslagern

ESPHome Codepassage auslagern
SONOFF NSPanel
SONOFF NSPanel
58,90 €

Irgendwann wird jeder mal bei dem ein oder anderen Projekt den Fall haben, dass einige Objekte im YAML-Code sich mehrfach wiederholen. Wenn man zum Beispiel mehrere LED-Stripes mit den selben Effekten in einem Projekt erstellen möchte, müsste man eigentlich alle Effekte unter jedem Light-Objekt erneut einfügen und hätte somit den exakt gleichen Code mehrfach in seiner YAML-Datei.

Dies lässt sich aber mit einem kleinen Trick umgehen. Und zwar kann man im genannten Beispiel die Effekte in eine eigene YAML-Datei auslagern und diese bei jeder Light-Komponente einfach referenzieren.
So muss nur noch eine Zeile mit dem Befehl zum laden der Effekte unter jedem Licht eingetragen werden anstatt jedes mal den vollständigen Code aller Effekte dort zu platzieren.

Dieses Vorgehen ist natürlich auch anwendbar, wenn man den selben Code in mehreren verschiedenen Projekten verwenden möchte.

Codebeispiel

Im Normalfall würde die YAML-Datei wie folgt aussehen:

light:
  - platform: neopixelbus
    id: neopixel_ring
    name: ${friendly_name} LED-Ring
    pin: D8
    num_leds: 60
    variant: WS2811
    type: GRBW
    default_transition_length: 1s
    effects:
      - addressable_rainbow:
          name: "Rainbow"
          speed: 20
          width: 50

  - platform: neopixelbus
    id: neopixel_ring2
    name: ${friendly_name} LED-Ring2
    pin: D7
    num_leds: 30
    variant: WS2811
    type: GRBW
    default_transition_length: 1s
    effects:
      - addressable_rainbow:
          name: "Rainbow"
          speed: 20
          width: 50

  - platform: neopixelbus
    id: neopixel_ring3
    name: ${friendly_name} LED-Ring3
    pin: D5
    num_leds: 20
    variant: WS2811
    type: GRBW
    default_transition_length: 1s
    effects:
      - addressable_rainbow:
          name: "Rainbow"
          speed: 20
          width: 50

Wie man sieht, ist nun der selbe Rainbow-Effekt unter jeder der Lampen vorhanden.
Dieser Effekt soll nun ausgelagert werden.


Neue Datei mit ausgelagertem Code

Als erstes muss die Datei mit dem mehrfach verwendeten Code unterhalb des Verzeichnis /config/esphome angelegt werden. Ich empfehle hierzu einen Unterordner (z.B. includes) anzulegen und darin alle Wiederverwertbaren Code-Dateien abzulegen. Man kann die Dateien natürlich auch direkt ins /config/esphome Verzeichnis legen, dann werden sie jedoch von ESPHome als neue Projekte erkannt.

Die neue Datei „/config/esphome/includes/led_effekte.yaml“ sieht dann wie folgt aus:

effects:
  - addressable_rainbow:
      name: "Rainbow"
      speed: 20
      width: 50


Ausgelagerten Code im ESPHome Projekt einbinden

Jetzt können die Effekte aus der Projekt-Datei entfernt werden. Statt dessen wird nun an den entsprechenden Stellen die neu angelegte Datei mit den Effekten eingebunden.
Zum Einbinden wird der !include Befehl verwendet. Dieser lädt an exakt der Stelle wo der Befehl steht den gesamten Inhalt der im Anschluss angegebenen YAML-Datei. Das heißt auch beim !include Befehl muss auf die korrekte Einrückung geachtet werden.

Damit der Dateiinhalt nun auch wirklich dem Licht zugeordnet wird, muss hier noch mit dem „<<„-Operator gearbeitet werden. Dieser nennt sich „Merge Key Language-Independent Type for YAML„.

Mit diesem Operator sorgt man dafür, dass die darunterliegenden Elemente dem darüberliegenden Element zugewiesen werden.

Die neue Projekt-Datei mit Verwendung des ausgelagerten Codes sähe dann wie folgt aus:

light:
  - platform: neopixelbus
    id: neopixel_ring
    name: ${friendly_name} LED-Ring
    pin: D8
    num_leds: 60
    variant: WS2811
    type: GRBW
    default_transition_length: 1s
    <<: !include includes/led_animationen.yaml

  - platform: neopixelbus
    id: neopixel_ring2
    name: ${friendly_name} LED-Ring2
    pin: D7
    num_leds: 30
    variant: WS2811
    type: GRBW
    default_transition_length: 1s
    <<: !include includes/led_animationen.yaml

  - platform: neopixelbus
    id: neopixel_ring3
    name: ${friendly_name} LED-Ring3
    pin: D5
    num_leds: 20
    variant: WS2811
    type: GRBW
    default_transition_length: 1s
    <<: !include includes/led_animationen.yaml