Regulator Pogodowy do C.O. ESPHome

Witam,
Pracuję obecnie nad regulatorem pogodowym do sterowania C.O., który ma byś oparty w całości na platformie ESPHome.
Wstępne założenia zostały zrealizowane:

  1. Pomiar temperatury zewnętrznej za pomocą DS18b20 i na jej podstawie obliczanie (autorski wzór) krzywej grzewczej, z której wyznaczana jest temperatura obiegu C.O., jaka ma występować za zaworem mieszającym:
- platform: template
    name: "Mix Temperature Set"
    id: mixtemperatureset
    lambda: |-
      int t_external = static_cast<int>(id(tempexternal).state);
      float t_mixer;
      t_mixer = id(curve) * ( 20 - t_external ) + 20;
      return static_cast<int>(t_mixer);
    update_interval: 10s
    accuracy_decimals: 0
    unit_of_measurement: "°C"
  1. Pomiar temperatury za zaworem mieszającym czujnikiem DS18b20, na podstawie, której ustawiany jest zawór mieszający aby uzyskać temperaturę krzywej grzewczej:
platform: template
    name: "Temp Behind the Mixer"
    id: tempbehindmixer
    update_interval: 10s
    unit_of_measurement: "°C"
    accuracy_decimals: 0
    lambda: |-
      return static_cast<int>(id(tempmixer).state);
  1. Procentowe wskazanie otwarcia zaworu:
  - platform: template
    name: "Mixer Open"
    update_interval: 10s
    unit_of_measurement: "%"
    icon: mdi:valve
    lambda: |-
      return id(valveopening);
  1. Możliwość wybrania krzywej grzewczej, czasu zadziałania zaworu mieszającego i czasu przerwy pomiędzy zadziałaniem zaworu mieszającego:
number:
  - platform: template
    name: "Mixer Pulse Time"
    id: mixerpulsetime
    optimistic: True
    min_value: 0
    max_value: 20
    step: 0.5
    restore_value: true
    on_value:
      then:
        - globals.set:
            id: pulsetime
            value: !lambda |-
                    return id(pulsetime) = x;

  - platform: template
    name: "Mixer Pulse Period"
    id: mixerpulseperiod
    optimistic: True
    min_value: 20
    max_value: 120
    step: 0.5
    restore_value: true
    on_value:
      then:
        - globals.set:
            id: periodtime
            value: !lambda |-
                    return id(periodtime) = x;

  - platform: template
    name: "Heating Curve"
    id: heatingcurve
    optimistic: True
    min_value: 0.1
    max_value: 1
    step: 0.1
    restore_value: true
    on_value:
      then:
        - globals.set:
            id: curve
            value: !lambda |-
                    return id(curve) = x;

Na ten moment te podstawowe funkcje działają, będę dodawał kolejne, aby regulator był rozbudowany do moich potrzeb.
Na ten moment muszę uporać się z dwoma problemami, aby ruszyć dalej.

  1. Problem, który mocno mnie blokuje, czyli czas przerwy pomiędzy zadziałaniem mieszacza ustawiam ręcznie jak w kodzie poniżej, a ma być na podstawie nastawy. Jak to zrealizować aby oprzeć się na zmiennej z nastawy lub skorzystać może z innej platformy? Pomysły już mi się skończyły. Kod działania mieszacza:
interval:
  - interval: 60s
    then:
      lambda: |-
        if( id(tempbehindmixer).state < id(mixtemperatureset).state )
        {
            id(valveopening) = id(valveopening) + id(pulsetime);
            if( id(valveopening) > 120 ) id(valveopening) = 120;
            id(cw).turn_on();
            delay(id(pulsetime) * 1000);
            id(cw).turn_off();
        }else if( id(tempbehindmixer).state > id(mixtemperatureset).state )
        {
            id(valveopening) = id(valveopening) - id(pulsetime);
            if( id(valveopening) < 0 ) id(valveopening) = 0;
            id(ccw).turn_on();
            delay(id(pulsetime) * 1000);
            id(ccw).turn_off();
        }else id(valveopening) = id(valveopening);

Najlepszym sposobem było by aby w “interval” podstawić zmienną, ale można tylko wartość, chyba, że można zrobić to inaczej.
2. Problem mniejszej wagi, ale nienależny go bagatelizować. Nastawione wartości zapisywać do pamięci flash w przypadku utraty nagłej zasilania luz zrobienie przycisku, który będzie zapisywał je do flash. Szukałem różnych opcji oraz je testowałem, ale działają tylko po restarcie ale nie po nagłym zaniku napięcia. Wydaje mi się, że najbardziej rozsądnym wyjściem było by zapisywanie do flash z poziomu przycisku w ESPHome.

Proszę o jakieś podpowiedzi, jak zrobię kompletny regulator, kod zostanie w całości udostępniony.

Czyli chciałbyś aby …

interval:
  - interval: !lambda |-
      return id(moj_interwal);

nasłuchiwał na mqtt w EspHome wiadomości z HA, która zawierałaby nastawę (input_number) ?

Jak można to tak zapisać to jak najbardziej.

Ale taki zapis nie działa, zwraca taki błąd “This option is not templatable!.”

EDIT

Chyba rozwiązałem problem z interwałem czasu, Zastosowałem taki zapis i na razie działa, potestuje i działam dalej:

interval:
  - interval: 1s
    then:
      lambda: |-
        id(metertime) += 1;
        if(id(periodtime) == id(metertime)){
          if( id(tempbehindmixer).state < id(mixtemperatureset).state )
          {
              id(valveopening) = id(valveopening) + id(pulsetime);
              if( id(valveopening) > 120 ) id(valveopening) = 120;
              id(cw).turn_on();
              delay(id(pulsetime) * 1000);
              id(cw).turn_off();
              id(metertime) = 0;
          }else if( id(tempbehindmixer).state > id(mixtemperatureset).state )
          {
              id(valveopening) = id(valveopening) - id(pulsetime);
              if( id(valveopening) < 0 ) id(valveopening) = 0;
              id(ccw).turn_on();
              delay(id(pulsetime) * 1000);
              id(ccw).turn_off();
              id(metertime) = 0;
          }else id(valveopening) = id(valveopening);
        }

Został jeszcze do rozwiązania problem nr 2.

Fajny projekt, czy mierzysz temperaturę na powrocie?

Na razie jest to co opisalem na samym poczatku. Docelowo chce dodac:

  1. Pomiar temp kotla/sprzegla i sterowanie pompa na podstawie tych pomiarow.
  2. Pomiar CWU i sterowanie zaworem/pompa na jej podstawie.
  3. Histereza pomiaru za zaworem mieszajacym.
  4. Pomiar temp powrotu i reagowanue sterownika na podstawie tych pomiarow.
  5. Wyjscie beznapiecuowe do sterowania wl/wyl kotla.
  6. Pomiary bufora w dwóch punktach i sterowanie kotla na ich podstawie.

I cos tam na pewno jeszcze wyjdzie w trakcie.