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.

2 Likes

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.

EDIT:

Chciałbym pewne zmienne/wartości zapisywać do pamięci ESP, na wypadek utraty zasilania aby zostały przywrócone. Podpowie ktoś jak zrobić to poprawnie, ale z użyciem przycisku w Home Assistan, że po jego naciśnięciu zostaje ona zapisana do pamięci wewnętrznej ESP? Oczywiście poproszę o jakiś przykład itp.

1 Like

W jaki sposób sterujesz zaworem mieszającym?

Kod sterujący zaworem mieszającym jest w poście 3. Obecnie sterowanie jest zrobione dla zaworu 3D, bo takiego używam i na tym się skupiłem. Na podstawie zmierzonej temperatury zewnętrznej, i wybraniu charakterystyki krzywej grzewczej, ustalana jest temperatura zadana za zaworem. Drugim czujnikiem dokonywany jest pomiar temperatury za zaworem i w zależności od potrzeby automatycznie jest otwierany/zamykany tak aby uzyskać zmierzoną temperaturę za zaworem jak najbliżej temperatury zadanej z obliczeń.

Jakim urządzeniem otwierasz zawór mieszający ?? Rozumiem że jest on całkowicie otwarty lub zamknięty, ja bym chciał mieć kontrolę otwierania np. otwarcie 30%

Do sterowania zaworu mieszającego wykorzystany został siłownik STZ-120T. Jak sama nazwa wskazuje zawór mieszający odpowiedzialny jest za mieszanie wody ciepłej z powracającą z układu grzewczego zimną. Zawór musi być otwarty w jakimś stopniu % aby dostosować temperaturę do zadanych potrzeb. Piec grzeje wodę do 65 st. a ogrzewanie podłogowe potrzebuje w okolicach 30 st. więc po to jest ten zawór z siłownikiem aby otworzyć go o ileś stopni by na wyjściu otrzymać 30 st.
Sterowanie obecnie jest testowane i na bieżąco modyfikowane, tak to wygląda w ESPHome:

W HA będzie to osobna karta z wizualizacją pieca i naniesionymi parametrami oraz opcją sterowania i możliwością zmiany ustawień.

Dzięki za odp, przymierzam się do zakupu STZ-120T , póki co nie mam pojęcia jak tym sterować. Domyślam się że będzie to na esp jakiś relay ale nie wiem jak to podpiąć aby były lewe/prawe obroty :thinking:

Do sterowania tego siłownika potrzebujesz 2 przekaźników jeden do CW drugi do CCW. Sterowanie tego typu siłownikiem w przypadku zaworu 3D, odbywa się na zasadzie włączenie przekaźnika CW lub CCW w zależności od potrzeby czy temp ma być zwiększona czy zmniejszona na kilka sekund i później kilkudziesięcioma przerwa w celu ustabilizowania się temp wyjściowej z zaworu aby znowu dokonać otwarcie lub zamknięcie zaworu. Działanie siłownika możesz oprzeć o stałą zadaną temperaturę lub zadaną z krzywej grzewczej. Dokładasz jeden czujnik temp za zaworem/pompą i na podstawie jego wskazań dokonuje się regulacja zaworu. Aby to wszystko poprawnie działało musi być za zaworem dodatkowa pompa obiegowa. Jak masz jakieś pytania lub potrzebujesz aby szczegółowo w krokach opisać działanie to pisz.

Zasadę działania układu rozumiem , mam już czujniki temp ( wemos + 2x ds18b20 ) zamontowane, pompa CO załączana przez smart switch. Nie jestem elektronikiem i problem dla mnie to te przekaźniki CW/CCW. Znalazłem rozwiązanie na 2-kanałowym esp8266 , są jakieś lepsze rozwiązania ?? Jakie Ty masz przekaźniki CW / CCW ??

Siłownik zasilany jest 230V, więc na razie zastosowałem przekaźniki elektromechaniczne sterowane 5V z ESP i załączają zasilanie 230V na siłownik. Ale zamienię je na SSR. Obecnie stosuje takie przekaźniki:


A zamieni na SSR:

Super, dzięki za naprowadzenie, schemat podłączenia SSR już mam. Czekam na graty :slight_smile:

Cześć podłączę się do tematu.
Zamierzam wykorzystać do starowania gotową płytkę Kinkony kc868-e16s

Czy jest szansa żebyście podzielili się kodem krzywych grzewczych??

Jak na razie udało mi się osiągnąć termostaty różnicowe do Cyrkulacji CWU i Solarów.
Do pomiaru temperatur wykorzystuje DS18B20 RS485 w celu wyeliminowania przyszłej potrzeby przepisywania kodu jeśli jakiś czujnik przestanie działać.

Macie może jakiś pomysł jak sterować Zaworem strefowym, który jest podłączony do solarów i przełącza się między zasobnikiem CWU i Buforem ogrzewania z priorytetem na grzanie Wody??

Cześć,
Kod krzywej grzewczej:

platform: template
    name: "Zadana Temperatura Mieszacza"
    id: zadanatemperaturamieszacza
    lambda: |-
      int t_zewnetrzna = static_cast<int>(id(temperaturazewnetrzna).state);
      float t_mieszacz;
      t_mieszacz = (id(krzywagrzewcza).state * (25 - t_zewnetrzna) + 25)-((id(krzywagrzewcza).state * 10) / 2);
      return static_cast<int>(t_mieszacz);
    update_interval: 60s
    accuracy_decimals: 0
    unit_of_measurement: "°C"

Parametrem “krzywagrzewcza” wybierasz sobie jaką chcesz aktualnie charakterystykę:

  - platform: template
    name: "Krzywa Grzewcza"
    id: krzywagrzewcza
    optimistic: True
    min_value: 0.1
    max_value: 1
    step: 0.1
    restore_value: True

A tak to wygląda graficznie:

udało ci się rozwiązac problem zapisu w ESP