Heizungsautomation mit Node-Red

Nachdem ich mit Better Thermostat, Versatile Thermostat und diversen Blueprints nicht zufrieden war, was die Steuerung und vor allem die Nachvollziehbar mancher Aktionen betrifft, habe ich mich ein paar Stunden an Node-Red gesetzt und Flows zusammengebastelt, die ich Euch kurz vorstellen möchte.

Ich weiß, dass es Optimierungsmöglichkeiten gibt, weil ich bin kein Node-Red Spezi bin und es funktionellere Nodes gibt.
Mein Ziel war es, möglichst einfach und übersichtlich zu bleiben, damit Fehler schnell gefunden werden, wenn etwas Unbeabsichtigtes geschieht.
Für Vorschläge, die mich meinem Ziel noch näher bringen, bin ich sehr dankbar. Und bei Interesse stelle ich die Flows zur Verfügung.

Das Ganze habe ich 2 Blöcke gegliedert: Anwesenheitserkennung und Steuerung, wobei mehrere Helfer zum Einsatz kommen.

Die Regelung erfolgt je nach Anwesenheit, Zeitplan, Fenstersensor-Status oder manuellem Eingriff. Außerdem habe ich eine automatische Kalibrierung eingebaut.

Zur Anwesenheit:
Diese definiert sich anhand mehrerer Kriterien: Status zone.home, Status Presence Sensor, Status Stromverbrauch, Status TV. Ist nicht optimal, aber da ich zwei Katzen habe, verringert es die False Positives mit Aqara FP2 (im Wohnimmer) oder Sonoff SNZB-06P (im Büro) dennoch.

Zum Zeitplan:
Der ist recht simpel bei mir: ein Zeitplan Helfer, wenn der on ist, gelten 22°, wenn der off ist, 20°.

Zum manuellen Eingriff:
Wenn ich die Wunschtemperatur temporär ändern möchte, mache ich das mit einem input_number Helfer, der mir die Zieltemperatur in der climate-Entität setzt und einen Timer startet.

Zur Kalbirierung:
Hierfür habe ich einen Template-Helfer erstellt, der die Differenz vom internen Sensor des TRVs zu einem externen Raumsensor ausgibt.
Alle 10 Minuten wird der letzte Offset genullt und die Differenz neu berechnet, ist sie höher als 0,2 oder niedriger als -0,2, wird sie als Offset an das TRV übergeben.

Alle 5 bzw. 10 Minuten werden alle Stati geprüft und dementsprechend geregelt.

Hier eine Karte dafür fürs Dashbord (zeigt des Laufzeit des Timers, sofern aktiv):
image

type: custom:vertical-stack-in-card
cards:
  - type: custom:bubble-card
    card_type: button
    button_type: state
    entity: climate.th_buro
    name: Büro
    icon: mdi:radiator
    show_state: false
    show_attribute: true
    attribute: current_temperature
    sub_button:
      - entity: binary_sensor.c_4_burofenster_contact
      - entity: input_number.burotemperatur
        icon: mdi:minus
        show_background: false
        tap_action:
          action: call-service
          service: input_number.decrement
          target:
            entity_id: input_number.burotemperatur
      - show_icon: false
        show_attribute: true
        attribute: temperature
        state_background: false
        show_background: false
        tap_action:
          action: none
      - entity: input_number.burotemperatur
        icon: mdi:plus
        state_background: false
        show_background: false
        tap_action:
          action: call-service
          service: input_number.increment
          target:
            entity_id: input_number.burotemperatur
    tap_action:
      action: none
    double_tap_action:
      action: none
    hold_action:
      action: none
    button_action:
      hold_action:
        action: none
      double_tap_action:
        action: none
      tap_action:
        action: none
    styles: >-
      * { 
        font-size: 14px !important;
      }

      .bubble-icon {
        color: ${hass.states[entity].attributes.hvac_action === 'idle' ? 'rgba(80,180,239,1)' : 'rgba(250,104,0,1)'} !important;
        --mdc-icon-size: 28px !important;
      }

      .bubble-sub-button-icon {
        --mdc-icon-size: 22px !important;
      }

      .bubble-button-card-container {
        background-color: ${hass.states[entity].attributes.hvac_action === 'idle' ? 'rgba(80,180,239,0.3)' : 'rgba(250,104,0,0.5)'} !important; !important;
      }  

      ${icon.setAttribute("icon", hass.states[entity].attributes.hvac_action ===
      'heating' ? 'mdi:radiator' : 'mdi:radiator-disabled')}
    card_layout: large
  - type: custom:layout-card
    layout_type: custom:grid-layout
    layout:
      margin: "-22px 40px -20px 40px"
    cards:
      - type: custom:timer-bar-card
        entity: timer.heizung_b_man
        layout: full_row
        text_width: 0px
        bar_height: 4px
        bar_background: orange
        bar_foreground: lightgrey
        bar_radius: 12px
        sync_issues: ignore
    visibility:
      - condition: state
        entity: timer.heizung_b_man
        state: active
card_mod:
  style: |
    ha-card {
      background-color: transparent;
    }

hallo

tolle Arbeit könntest du den Flow mal zur verfügung stellen so das man sich selbst ein bild macht und verstehen lernt und es umsetzt?

Danke