Thermostat und Template-Logik

AlphaZulu

New member
Hallo zusammen,

ich bin gerade dabei, nach und nach alle Programme und Scripte von Homematic in Home Assistant zu übertragen. An einer Stelle haben aber entweder ich oder HA einen "Denkfehler":

In einem Anbau ist eine kleine Elektroheizung verbaut. Diese soll z. B. eine Temperatur von 10 °C halten. Dazu soll sie bei 3 % unter dem Sollwert eingeschaltet und bei 3 % über dem Sollwert ausgeschaltet werden, so dass die Temperatur z. B. zwischen 9,7 und 10,3 °C pendelt.

Unter Homematic klappte das auch einwandfrei. Ich habe das entsprechende Homematic-Script jetzt in ein Template unter HA übersetzt, aber da denkt dann jemand falsch:


YAML:
{# Heizempfehlung ermitteln #}
                {% if temperatur <= heizungEin %}
                    {{ true }}
                {% elif temperatur >= heizungAus %}
                    {{ false }}
                {% endif %}

Hier soll eigentlich die "Heizempfehlung" auf "true" geschaltet werden, sobald die Ist-Temperatur unter die Einschalttemperatur fällt, was auch klappt. Auf "false" soll das aber erst springen, wenn der Ausschaltwert erreicht wurde. HA schaltet aber bereits dann wieder auf "false", wenn "temperatur" > "heizungEin" ist.

Nach meinem Verständnis müsste es doch so aussehen:

- solange die Ist-Temperatur <= Einschaltwert --> "true"
- Wenn Ist-Temperatur > Einschaltwert sollte nichts passieren, weil es ja kein ELSE gibt.
- Erst dann, wenn die Ist-Temperatur >= Ausschaltwert --> "false"

Warum wird "false" aber schon gesetzt, wenn "if temperatur <= heizungEin" nicht mehr wahr ist?

Scriptende Grüße

Axel
 
Zuletzt bearbeitet von einem Moderator:

Nival

-
Moderator
Kann es sein, dass "keine Rückgabe" hier quasi als false gewertet wird? Das ist in vielen Sprachen so gelöst.
 

AlphaZulu

New member
Hmmm, das wäre aber blöd :) .

Würde denn dann wohl folgender Code klappen?

YAML:
{# Heizempfehlung ermitteln #}
    {% if temperatur <= heizungEin %}
        {{ true }}
    {% elif temperatur >= heizungAus %}
        {{ false }}
    {% else %}
    {% endif %}

Gerade getestet: Klappt auch nicht! Wieder wird auf "false" geändert und die Heizung geht aus.
 
Zuletzt bearbeitet:

Nival

-
Moderator
Nein, ein leerer Rückgabewert ist noch immer kein Rückgabewert :)

YAML:
{% if (temperatur <= heizungEin) or (temperatur >= heizungEin and temperatur <= heizungAus) %}
    {{ true }}
{% else %}
    {{ false }}
{% endif %}
So sollte das funktionieren, der erste Teil zur Absicherung falls es aus irgendeinem Grund mal unter die Wunschtemperatur fällt (Heizung kommt nicht gegen die Temperatur an oder so), der zweite Teil um die Heizung in dem gewünschten Rahmen zu halten.
 

AlphaZulu

New member
OK, dann "pendelt" die Temperatur aber nicht mehr, wenn ich das richtig sehe.

Die Heizung geht jetzt an, wenn die Temperatur unter heizungEin fällt (richtig), bleibt auch an, bis heizungAus erreicht ist (richtig), geht aber auch sofort wieder an, wenn der Wert unter heizungAus fällt (falsch). Das soll aber nicht passieren, sondern erst dann, wenn heizungEin wieder unterschritten wird.

Gerade getestet: Leider ist es so, dass jetzt geheizt wird, sobald heizungEin erreicht wird. Die Heizung schaltet aus, sobald heizungAus erreicht wird und sofort wieder ein, wenn heizungAus unterschritten wird. Im Extremfall wird dann ständig an- und ausgeschaltet.
 

AlphaZulu

New member
neuer Versuch:

YAML:
            {# Heizempfehlung ermitteln #}
                {% if temperatur <= heizungEin %}
                    {% set heizung = "ein" %}
                {% elif heizung == "ein" and temperatur > heizungEin and temperatur < heizungAus %}
                    {% set heizung = "aufheizen" %}
                {% elif heizung == "aus" and temperatur > heizungEin and temperatur < heizungAus %}
                    {% set heizung = "abkühlen" %}
                {% elif temperatur >= heizungAus %}
                    {% set heizung = "aus" %}
                {% endif %}
               
                {% if heizung == "ein" or heizung == "aufheizen" %}
                    {{ true }}
                {% else %}
                    {{ false }}
                {% endif %}

Mal sehen, was jetzt passiert ...
 
Zuletzt bearbeitet:

alexamend

Active member
Könnte so funktionieren, habs nicht getestet, laut Template Editor ok, müsstest nur deine Sensoren eintragen. Ich vermute das Problem ist dein true / false

YAML:
      {% if states.sensor.office_temp.state|int <= 9.7 %}
        homeassistant.turn_on
      {% elif states.sensor.office_temp.state|int >= 10.3 %}
        homeassistant.turn_off
      {% endif %}
 

alexamend

Active member
Das ganze ist Bestandteil eines Sensors, der letztlich true oder false sein kann. Den wiederum wertet dann eine Automation aus und schaltet die Heizung (Schaltsteckdose) ein, wenn nicht gerade ein Fenster gekippt ist.
Das ist absolut korrekt, du must dennoch irgendwo deine Werte von 9,7°C und 10.3°C her bekommen und diese Werte kannst du doch verarbeiten.
 

AlphaZulu

New member
Hmmm, gerade stand da doch noch ein anderer Tipp (die Sache mit dem "NOT").

Das teste ich gerade mal. Zumindest hat geklappt, dass die Heizung ausgeschaltet wurde als heizungAus erreicht wurde. Mal sehen, was passiert, wenn jetzt die Temperatur wieder unter heizungAus fällt ...
 

AlphaZulu

New member
Das ist absolut korrekt, du must dennoch irgendwo deine Werte von 9,7°C und 10.3°C her bekommen und diese Werte kannst du doch verarbeiten.
Die werden errechnet. Hier ist mal der ganze Code (mit der oben wieder gelöschten NOT-Variante und zum Testen nur 1 % Erhöhung):

YAML:
      anbau_2_tauchraum_heizempfehlung:
        friendly_name: "Anbau 2 - Tauchraum - Heizempfehlung"
        unique_id: "anbau2-tauchraum-heizempfehlung"
        value_template: >-
            {# Werte auslesen #}
                {% set tempThermostat = state_attr('climate.anbau2_tauchraum_thermostat', 'current_temperature') | float %}
                {% set tempWand = states('sensor.klimadaten_anbau_2_tauchraum_aussenwand_hm_temperature') | float %}
                {% set tempSoll = state_attr('climate.anbau2_tauchraum_thermostat', 'temperature') | float %}
            {# Temperatur festlegen - normalerweise Themostat und Wand, wenn dort weniger als 5 °C #}
                {% if tempWand < tempThermostat and tempWand < 5.0 %}
                    {% set temperatur = tempWand %}
                {% else %}
                    {% set temperatur = tempThermostat %}
                {% endif %}
            {# Einschalttempertur - Soll -3% - und Ausschalttemperatur - Soll +1% - ermitteln #}
                {% set heizungEin = tempSoll * 0.97 |float %}
                {% set heizungAus = tempSoll * 1.01 |float %}
            {# Heizempfehlung ermitteln #}
                {% if( temperatur <= heizungEin or (temperatur >= heizungEin and (not temperatur >= heizungAus))) %}
                    {{ true }}
                {% else %}
                    {{ false }}
                {% endif %}
        device_class: cold
 

IvoryBalboa90

Active member
Hmmm, gerade stand da doch noch ein anderer Tipp (die Sache mit dem "NOT").

Das teste ich gerade mal. Zumindest hat geklappt, dass die Heizung ausgeschaltet wurde als heizungAus erreicht wurde. Mal sehen, was passiert, wenn jetzt die Temperatur wieder unter heizungAus fällt ...
Jop, der Tip kam von mir. Der wird dir die Heizung aber auch abschalten, sobald temperatur<=heizungAus.
Daher hab ich den - für die Übersicht - wieder gelöscht.

Poste doch mal den yaml-Code von deinem Sensor.
Das lässt sich nämlich easy mit einem triggered-Sensor lösen, dafür brauchen wir aber die Herkunft deiner Temperaturen

Edit: ah da issser ja, dein Sensor 😂
Edit 2: okay, wird doch nicht so easy
 

AlphaZulu

New member
Jop, der Tip kam von mir. Der wird dir die Heizung aber auch abschalten, sobald temperatur<=heizungAus.
Das ist ja auch nicht verkehrt, sondern gewollt. Der Plan ist (so lief das auch über Jahre in Homematic):

Die Temperatur ist niedriger als heizungEin (abhängig von der eingestellten Temperatur am Thermostat): Heizung einschalten

Die Temperatur erreicht heizungAus (abhängig von der eingestellten Temperatur am Thermostat): Heizung ausschalten

Danach bleibt die Heizung aus, bis wieder heizungEin erreicht wird und dann geht es von vorne los ...

Also aktuell hat das Einschalten bei heizungEin und das Ausschalten bei heizungAus geklappt. Wenn die Temperatur im Raum jetzt noch um 0,2 Grad sinkt und die Heizung bleibt aus, dann funktioniert deine "NOT-Variante" ...
 

IvoryBalboa90

Active member
Das war ein Autokorrektur-Fehler (bin am Smartphone) und sollte anschalten heißen, nicht abschalten. Also auch mein Tip wird deinen Wunsch nicht erfüllen.
 

AlphaZulu

New member
Wenn das heute nicht so warm draußen wäre (immer noch 10,4 °C) wüsste ich schon mehr :) .

EDIT: Du hattest recht: Heizung springt an, wenn der Wert unter heizungAus fällt ... o_O

Bei Homematic klappte das einfach mit der Variante:

YAML:
{% if temperatur <= heizungEin %}
    {{ true }}
{% elif temperatur >= heizungAus %}
    {{ false }}
{% endif %}

oder auf "homematicisch":

Code:
    if (tempIst <= heizungEin)
    {
        heizen.State(true);
    }
    else
    {
        if (tempIst >= heizungAus)
        {
            heizen.State(false);
        }
    }
 

IvoryBalboa90

Active member
Vorschlag:
YAML:
{% if temperatur <= heizungEin %}
  {{ true }}
{% elif temperatur >= heizungAus %}
  {{ false }}
{% else %}
{% endif %}

Und als Trigger in deiner Automation:
YAML:
description: ""
mode: single
trigger:
  - platform: state
    entity_id: anbau_2_tauchraum_heizempfehlung
condition: []
action:
  - if:
      - condition: template
        value_template: "{{ trigger.to_state.state == true }}"
    then:
      - ### Heizung anschalten ###
  - if:
      - condition: template
        value_template: "{{ trigger.to_state.state == false }}"
    then:
      - ### Heizung ausschalten ###


Das hat nur einen kosmetischen Makel, nämlich dass dein Sensor einen leeren Status hat.
 

AlphaZulu

New member
Evtl. habe ich jetzt auch noch eine alternative Lösung gefunden, aber da es zu warm ist, kühlt der Raum nicht aus 😀:

YAML:
{# Heizempfehlung ermitteln #}
    {% if temperatur <= heizungEin %}
        {% set merkmal = "aufheizen" %}
        {{ true }}
    {% elif temperatur >= heizungAus %}
        {% set merkmal = "abkühlen" %}
        {{ false }}
    {% elif temperatur < heizungAus and merkmal == "abkühlen" %}
        {{ false }}
    {% elif temperatur < heizungAus and merkmal == "aufheizen" %}
        {{ true }}
    {% endif %}

EDIT: Das klappt leider auch nicht. Es scheint so zu sein, dass mein Flag, das ich in "merkmal" abspeichere, nicht behalten wird. Liegt die Temperatur zwischen Ein- und Ausschalttemperatur wird keines der Kriterien erfüllt. Lege ich ein ELSE an, springt das Script auch dorthin und "merkmal" ist leer. Gibt es analog zu JAVA irgendwelche Instanzvariablen, die ich nutzen könnte?
 
Zuletzt bearbeitet:

AlphaZulu

New member
Das hört sich gut an. Ich werde das mal testen, auch wenn es mich wurmt, dass meine "Hilfsvariable" nicht funktioniert :) .
 

Zurzeit aktive Besucher

Letzte Anleitungen

Statistik des Forums

Themen
1.725
Beiträge
21.436
Mitglieder
1.234
Neuestes Mitglied
Doneinei
Oben