[Zlecę] napisanie Yaml na ESPHome

Witam, czy ktoś z kolegów który ma czas i ESPhome w " jednym palcu" jest w stanie napisać mi yaml sterownika obiegów grzewczych ? Oczywiście zapłacę ile trzeba. :slight_smile:

Pozdrawiam :slight_smile:

Cześć, przecież wrzuciłem taki sterownik :slight_smile: Sterowanie ogrzewaniem podłogowym

Nie do końca jest on dla mnie rozwiązaniem takim jak potrzebuję.
Potrzebuję zawrzeć w ESPHome krzywą grzewczą ( mam krzywą ale w HA) , sterowanie zaworami trójdrogowymi ( to już mam zrobione) sterowanie pompami cyrkulacyjnymi. Nie potrzebuję sterowania siłownikami obiegów to mam w HA, tylko temperaturą wody dostarczaną do rozdzielaczy .

No to już mamy jakąś informację czego potrzebujesz. Wrzuć może cały opis swoich wymagań, z czego chcesz liczyć tą krzywą itd to może uda się to skleić.

Tu na esp mam sterownik dwóch obiegów grzewczych, sterownie zaworami 3D na podstawie temperatury zadanej wyliczonej z krzywej grzewczej z HA i sterowanie dwiema pompami cyrkulacyjnymi.

esphome:
  name: sterownik-obiegow-grzewczych

  on_boot:
    then:
      - switch.turn_on: pompa_1
      - switch.turn_on: pompa_2
      - delay: 30s
      - switch.turn_off: pompa_1
      - switch.turn_off: pompa_2  
      - switch.turn_on: z3d_minus
      - switch.turn_on: z3d_minus_2
      - delay: 150s
      - switch.turn_off: z3d_minus
      - switch.turn_off: z3d_minus_2

    
      - lambda: |- 
          auto call = id(kotlownia_3d).make_call();
          call.set_position(0);
          call.perform();
      - lambda: |- 
          auto call = id(kotlownia_3d_2).make_call();
          call.set_position(0);
          call.perform();

esp32:
  board: esp32dev
  framework:
    type: arduino

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16

  manual_ip:
    static_ip: 192.168.0.0
    gateway: 192.168.0.1
    subnet: 255.255.255.0

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "+R4Y7adcgQPezgvsCAsSF5zmWCJ0iCtPMXoVyBOIwp8="

ota:
  password: "46367005"

web_server:
  port: 80

time:
  - platform: homeassistant
    id: homeassistant_time 
    on_time:
      - seconds: /5
        
        then:
          - lambda: |- 
              if (id(automat_3d).state) {         
                if (id(kotlownia1_temp_dom_zas).state < id(temp_zas).state-1) {
                  if (id(kotlownia_3d).position<1) {
                    auto call = id(kotlownia_3d).make_call();
                    call.set_position(id(kotlownia_3d).position+0.02);
                    call.perform();
                  }
                }
                if (id(kotlownia1_temp_dom_zas).state > id(temp_zas).state+1) {
                  if (id(kotlownia_3d).position>0) {
                    auto call = id(kotlownia_3d).make_call();
                    call.set_position(id(kotlownia_3d).position-0.02);
                    call.perform();
                  }                  
                }
              }

          - lambda: |- 
              if (id(automat_3d_2).state) {         
                if (id(kotlownia1_temp_dom_zas_2).state < id(temp_zas_2).state-1) {
                  if (id(kotlownia_3d_2).position<1) {
                    auto call = id(kotlownia_3d_2).make_call();
                    call.set_position(id(kotlownia_3d_2).position+0.02);
                    call.perform();
                  }
                }
                if (id(kotlownia1_temp_dom_zas_2).state > id(temp_zas_2).state+1) {
                  if (id(kotlownia_3d_2).position>0) {
                    auto call = id(kotlownia_3d_2).make_call();
                    call.set_position(id(kotlownia_3d_2).position-0.02);
                    call.perform();
                  }                  
                }
              }
              





sensor:
  - platform: homeassistant
    name: "Temperatura zasilania parter"
    entity_id: sensor.temp_zas_parter
    internal: false
    id: kotlownia1_temp_dom_zas
    accuracy_decimals: 1
    
  - platform: homeassistant
    name: "Temperatura zasilania piętro"
    entity_id: sensor.temp_zas_pietro
    internal: false
    id: kotlownia1_temp_dom_zas_2
    accuracy_decimals: 1



  - platform: homeassistant
    name: "Temperatura zadana parter"
    entity_id: sensor.temperatura_krzywa_grzewcza_obieg_1
    internal: false
    id: temp_zas
    accuracy_decimals: 1
  
  - platform: homeassistant
    name: "Temperatura zadana piętro"
    entity_id: sensor.temperatura_krzywa_grzewcza_obieg_2
    internal: false
    id: temp_zas_2
    accuracy_decimals: 1
  


binary_sensor:

  - platform: homeassistant
    name: "Kocioł pompa obiegowa"
    icon: "mdi:pump"
    entity_id: binary_sensor.boiler_heating_pump
    
    internal: false
    publish_initial_state: true
    id: kociol_pompa


    
    
  - platform: homeassistant
    name: "Kocioł ogrzewanie"
    entity_id: binary_sensor.boiler_heating_active
    internal: false
    publish_initial_state: true
    id: ogrzewanie_aktywne



    

switch: 
- platform: gpio
  name: "Zawór 3D parter zamykanie"
  id: z3d_minus
  pin:    
    number: 2
    mode:
      output: true
    inverted: true
  restore_mode: RESTORE_DEFAULT_OFF

- platform: gpio
  name: "Zawór 3D parter otwieranie"
  id: z3d_plus    
  pin:    
    number: 4
    mode:
      output: true
    inverted: true
  restore_mode: RESTORE_DEFAULT_OFF

- platform: gpio
  name: "Zawór 3D piętro zamykanie "
  id: z3d_minus_2
  pin:    
    number: 12
    mode:
      output: true
    inverted: true
  restore_mode: RESTORE_DEFAULT_OFF

- platform: gpio
  name: "Zawór 3D piętro otwieranie"
  id: z3d_plus_2
  pin:    
    number: 14
    mode:
      output: true
    inverted: true
  restore_mode: RESTORE_DEFAULT_OFF

- platform: gpio
  name: "Pompa obiegowa parter"
  icon: "mdi:pump"
  id: pompa_1
  pin:    
    number: 15
    mode:
      output: true
    inverted: true
  restore_mode: ALWAYS_OFF

- platform: gpio
  name: "Pompa obiegowa pietro"
  icon: "mdi:pump"
  id: pompa_2
  pin:    
    number: 17
    mode:
      output: true
    inverted: true
  restore_mode: ALWAYS_OFF

- platform: gpio
  name: "Pompa cyrkulacyjna"
  icon: "mdi:pump"
  id: pompa_3
  pin:    
    number: 32
    mode:
      output: true
    inverted: true
  restore_mode: ALWAYS_OFF

- platform: gpio
  name: "Włącz grzanie"
  icon: "mdi:pump"
  id: grzanie_on
  pin:    
    number: 33
    mode:
      output: true
    inverted: true
  restore_mode: ALWAYS_OFF

- platform: template
  name: "Grzanie parter auto"
  id: automat_3d 
  optimistic: true
  restore_state: True

- platform: template
  name: "Grzanie piętro auto"
  id: automat_3d_2
  optimistic: true
  restore_state: True



cover:
  - platform: time_based
    name: "Zawór 3D parter manual"
    id: kotlownia_3d

    open_action:
      - switch.turn_on: z3d_plus
    open_duration: 2.5 min

    close_action:
      - switch.turn_on: z3d_minus
    close_duration: 2.5 min

    stop_action:
      - switch.turn_off: z3d_minus
      - switch.turn_off: z3d_plus

  - platform: time_based
    name: "Zawór 3D piętro manual"
    id: kotlownia_3d_2

    open_action:
      - switch.turn_on: z3d_plus_2
    open_duration: 2.5 min 

    close_action:
      - switch.turn_on: z3d_minus_2
    close_duration: 2.5 min

    stop_action:
      - switch.turn_off: z3d_minus_2
      - switch.turn_off: z3d_plus_2


Tu jest Yaml krzywej grzewczej z HA

# Krzywa grzewcza obieg 1

  - platform: template
    sensors:
      temperatura_krzywa_grzewcza_obieg_1:
        value_template: >
          {% set OT = states("sensor.bme280_1_temperatura") | float(default=15) %}
          {% set CurveMove = states("input_number.krzywa_grzewcza_przesuniecie_obieg_1") | float %}
          {% set System = ("0") | float %}
          {% set HC = states("input_select.krzywa_grzewcza_nachylenie_obieg_1") | float %}
          {% if HC == 0.1 %}
            {{ "%.1f"%( CurveMove - System + 36.4 - ( 0.00495 * OT**2 ) - ( 0.32 *  OT)) | float}}
          {% elif HC == 0.2 %}
            {{ "%.1f"%( CurveMove - System + 37.7 - ( 0.0052 * OT**2 ) - ( 0.38 *  OT)) | float}}
          {% elif HC == 0.3 %}
            {{ "%.1f"%( CurveMove - System + 39.0 - ( 0.00545 * OT**2 ) - ( 0.44 *  OT)) | float}}
          {% elif HC == 0.4 %}
            {{ "%.1f"%( CurveMove - System + 40.3 - ( 0.0057 * OT**2 ) - ( 0.5 *  OT)) | float}}
          {% elif HC == 0.5 %}
            {{ "%.1f"%( CurveMove - System + 41.6 - ( 0.00595 * OT**2 ) - ( 0.56 *  OT)) | float}}
          {% elif HC == 0.6 %}
            {{ "%.1f"%( CurveMove - System + 43.1 - ( 0.0067 * OT**2 ) - ( 0.62 *  OT)) | float}}
          {% elif HC == 0.7 %}
            {{ "%.1f"%( CurveMove - System + 44.6 - ( 0.00745 * OT**2 ) - ( 0.68 *  OT)) | float}}
          {% elif HC == 0.8 %}
            {{ "%.1f"%( CurveMove - System + 46.1 - ( 0.0082 * OT**2 ) - ( 0.74 *  OT)) | float}}
          {% elif HC == 0.9 %}
            {{ "%.1f"%( CurveMove - System + 47.6 - ( 0.00895 * OT**2 ) - ( 0.8 *  OT)) | float}}
          {% elif HC == 1.0 %}
            {{ "%.1f"%( CurveMove - System + 49.1 - ( 0.0097 * OT**2 ) - ( 0.86 *  OT)) | float}}
          {% elif HC == 1.1 %}
            {{ "%.1f"%( CurveMove - System + 50.8 - ( 0.01095 * OT**2 ) - ( 0.92 *  OT)) | float}}
          {% elif HC == 1.2 %}
            {{ "%.1f"%( CurveMove - System + 52.5 - ( 0.0122 * OT**2 ) - ( 0.98 *  OT)) | float}}
          {% elif HC == 1.3 %}
            {{ "%.1f"%( CurveMove - System + 54.2 - ( 0.01345 * OT**2 ) - ( 1.04 *  OT)) | float}}
          {% elif HC == 1.4 %}
            {{ "%.1f"%( CurveMove - System + 55.9 - ( 0.0147 * OT**2 ) - ( 1.1 *  OT)) | float}}
          {% elif HC == 1.5 %}
            {{ "%.1f"%( CurveMove - System + 57.5 - ( 0.0157 * OT**2 ) - ( 1.16 *  OT)) | float}}
          {% elif HC == 1.6 %}
            {{ "%.1f"%( CurveMove - System + 59.4 - ( 0.01644 * OT**2 ) - ( 1.24 *  OT)) | float}}
          {% elif HC == 1.7 %}
            {{ "%.1f"%( CurveMove - System + 61.3 - ( 0.01718 * OT**2 ) - ( 1.32 *  OT)) | float}}
          {% elif HC == 1.8 %}
            {{ "%.1f"%( CurveMove - System + 63.2 - ( 0.01792 * OT**2 ) - ( 1.4 *  OT)) | float}}
          {% elif HC == 1.9 %}
            {{ "%.1f"%( CurveMove - System + 65.1 - ( 0.01866 * OT**2 ) - ( 1.48 *  OT)) | float}}
          {% elif HC == 2.0 %}
            {{ "%.1f"%( CurveMove - System + 67.0 - ( 0.0194 * OT**2 ) - ( 1.56 *  OT)) | float}}
          {% elif HC == 2.1 %}
            {{ "%.1f"%( CurveMove - System + 69.1 - ( 0.0197 * OT**2 ) - ( 1.66 *  OT)) | float}}
          {% elif HC == 2.2 %}
            {{ "%.1f"%( CurveMove - System + 71.2 - ( 0.01995 * OT**2 ) - ( 1.76 *  OT)) | float}}
          {% elif HC == 2.3 %}
            {{ "%.1f"%( CurveMove - System + 73.3 - ( 0.0202 * OT**2 ) - ( 1.86 *  OT)) | float}}
          {% elif HC == 2.4 %}
            {{ "%.1f"%( CurveMove - System + 75.4 - ( 0.02045 * OT**2 ) - ( 1.96 *  OT)) | float}}
          {% elif HC == 2.5 %}
            {{ "%.1f"%( CurveMove - System + 77.5 - ( 0.02007 * OT**2 ) - ( 2.06 *  OT)) | float}}
          {% elif HC == 2.6 %}
            {{ "%.1f"%( CurveMove - System + 79.8 - ( 0.02045 * OT**2 ) - ( 2.18 *  OT)) | float}}
          {% elif HC == 2.7 %}
            {{ "%.1f"%( CurveMove - System + 82.1 - ( 0.0202 * OT**2 ) - ( 2.3 *  OT)) | float}}
          {% elif HC == 2.8 %}
            {{ "%.1f"%( CurveMove - System + 84.4 - ( 0.01995 * OT**2 ) - ( 2.42 *  OT)) | float}}
          {% elif HC == 2.9 %}
            {{ "%.1f"%( CurveMove - System + 86.7 - ( 0.0197 * OT**2 ) - ( 2.54 *  OT)) | float}}
          {% elif HC == 3.0 %}
            {{ "%.1f"%( CurveMove - System + 89.0 - ( 0.01945 * OT**2 ) - ( 2.66 *  OT)) | float}}
          {% endif %}
        friendly_name: Temperatura krzywa grzewcza parter
        unit_of_measurement: °C
        

      
# Krzywa grzewcza obieg 2

  - platform: template
    sensors:
      temperatura_krzywa_grzewcza_obieg_2:
        value_template: >
          {% set OT = states("sensor.bme280_1_temperatura") | float(default=15) %}
          {% set CurveMove = states("input_number.krzywa_grzewcza_przesuniecie_obieg_2") | float %}
          {% set System = ("0") | float %}
          {% set HC = states("input_select.krzywa_grzewcza_nachylenie_obieg_2") | float %}
          {% if HC == 0.1 %}
            {{ "%.1f"%( CurveMove - System + 36.4 - ( 0.00495 * OT**2 ) - ( 0.32 *  OT)) | float}}
          {% elif HC == 0.2 %}
            {{ "%.1f"%( CurveMove - System + 37.7 - ( 0.0052 * OT**2 ) - ( 0.38 *  OT)) | float}}
          {% elif HC == 0.3 %}
            {{ "%.1f"%( CurveMove - System + 39.0 - ( 0.00545 * OT**2 ) - ( 0.44 *  OT)) | float}}
          {% elif HC == 0.4 %}
            {{ "%.1f"%( CurveMove - System + 40.3 - ( 0.0057 * OT**2 ) - ( 0.5 *  OT)) | float}}
          {% elif HC == 0.5 %}
            {{ "%.1f"%( CurveMove - System + 41.6 - ( 0.00595 * OT**2 ) - ( 0.56 *  OT)) | float}}
          {% elif HC == 0.6 %}
            {{ "%.1f"%( CurveMove - System + 43.1 - ( 0.0067 * OT**2 ) - ( 0.62 *  OT)) | float}}
          {% elif HC == 0.7 %}
            {{ "%.1f"%( CurveMove - System + 44.6 - ( 0.00745 * OT**2 ) - ( 0.68 *  OT)) | float}}
          {% elif HC == 0.8 %}
            {{ "%.1f"%( CurveMove - System + 46.1 - ( 0.0082 * OT**2 ) - ( 0.74 *  OT)) | float}}
          {% elif HC == 0.9 %}
            {{ "%.1f"%( CurveMove - System + 47.6 - ( 0.00895 * OT**2 ) - ( 0.8 *  OT)) | float}}
          {% elif HC == 1.0 %}
            {{ "%.1f"%( CurveMove - System + 49.1 - ( 0.0097 * OT**2 ) - ( 0.86 *  OT)) | float}}
          {% elif HC == 1.1 %}
            {{ "%.1f"%( CurveMove - System + 50.8 - ( 0.01095 * OT**2 ) - ( 0.92 *  OT)) | float}}
          {% elif HC == 1.2 %}
            {{ "%.1f"%( CurveMove - System + 52.5 - ( 0.0122 * OT**2 ) - ( 0.98 *  OT)) | float}}
          {% elif HC == 1.3 %}
            {{ "%.1f"%( CurveMove - System + 54.2 - ( 0.01345 * OT**2 ) - ( 1.04 *  OT)) | float}}
          {% elif HC == 1.4 %}
            {{ "%.1f"%( CurveMove - System + 55.9 - ( 0.0147 * OT**2 ) - ( 1.1 *  OT)) | float}}
          {% elif HC == 1.5 %}
            {{ "%.1f"%( CurveMove - System + 57.5 - ( 0.0157 * OT**2 ) - ( 1.16 *  OT)) | float}}
          {% elif HC == 1.6 %}
            {{ "%.1f"%( CurveMove - System + 59.4 - ( 0.01644 * OT**2 ) - ( 1.24 *  OT)) | float}}
          {% elif HC == 1.7 %}
            {{ "%.1f"%( CurveMove - System + 61.3 - ( 0.01718 * OT**2 ) - ( 1.32 *  OT)) | float}}
          {% elif HC == 1.8 %}
            {{ "%.1f"%( CurveMove - System + 63.2 - ( 0.01792 * OT**2 ) - ( 1.4 *  OT)) | float}}
          {% elif HC == 1.9 %}
            {{ "%.1f"%( CurveMove - System + 65.1 - ( 0.01866 * OT**2 ) - ( 1.48 *  OT)) | float}}
          {% elif HC == 2.0 %}
            {{ "%.1f"%( CurveMove - System + 67.0 - ( 0.0194 * OT**2 ) - ( 1.56 *  OT)) | float}}
          {% elif HC == 2.1 %}
            {{ "%.1f"%( CurveMove - System + 69.1 - ( 0.0197 * OT**2 ) - ( 1.66 *  OT)) | float}}
          {% elif HC == 2.2 %}
            {{ "%.1f"%( CurveMove - System + 71.2 - ( 0.01995 * OT**2 ) - ( 1.76 *  OT)) | float}}
          {% elif HC == 2.3 %}
            {{ "%.1f"%( CurveMove - System + 73.3 - ( 0.0202 * OT**2 ) - ( 1.86 *  OT)) | float}}
          {% elif HC == 2.4 %}
            {{ "%.1f"%( CurveMove - System + 75.4 - ( 0.02045 * OT**2 ) - ( 1.96 *  OT)) | float}}
          {% elif HC == 2.5 %}
            {{ "%.1f"%( CurveMove - System + 77.5 - ( 0.02007 * OT**2 ) - ( 2.06 *  OT)) | float}}
          {% elif HC == 2.6 %}
            {{ "%.1f"%( CurveMove - System + 79.8 - ( 0.02045 * OT**2 ) - ( 2.18 *  OT)) | float}}
          {% elif HC == 2.7 %}
            {{ "%.1f"%( CurveMove - System + 82.1 - ( 0.0202 * OT**2 ) - ( 2.3 *  OT)) | float}}
          {% elif HC == 2.8 %}
            {{ "%.1f"%( CurveMove - System + 84.4 - ( 0.01995 * OT**2 ) - ( 2.42 *  OT)) | float}}
          {% elif HC == 2.9 %}
            {{ "%.1f"%( CurveMove - System + 86.7 - ( 0.0197 * OT**2 ) - ( 2.54 *  OT)) | float}}
          {% elif HC == 3.0 %}
            {{ "%.1f"%( CurveMove - System + 89.0 - ( 0.01945 * OT**2 ) - ( 2.66 *  OT)) | float}}
          {% endif %}
        friendly_name: Temperatura krzywa grzewcza piętro
        unit_of_measurement: °C

Tak to wygląda w HA:
image

Teraz założenia:
W momenie podania napięcia na sterownik, zamykane zostają zawory 3D i uruchamiane na kilkanaście sekund pompy obiegowe ( to działa)
Potrzebny tryb LATO/ZIMA
W trybie LATO pompy uruchamiane są co określony czas ( może być podany w Yaml), zawory 3D zamykane są i otwierane też co określony czas, j.w. Chodzi o to aby ruszyć pompami i zaworami aby się nie zastały ( chociaż jeszcze mi się to nie zdarzyło)
W trybie ZIMA
Załączamy tryb AUTO danego obiegu, temperaturę zadaną ma podawać krzywa zawarta w ESPHome a nie w HA jak to jest teraz ( chcę aby sterownik działał mimo braku komunikacji z HA)
Nachylenie i przesunięcie krzywej wybierane z pola wyboru tak jak teraz.
Potrzebuję wyłączać pracę pompy i zamknąć mieszacze w momencie gdy grupa siłowniki w rozdzielaczach są zamknięte.
Temperaturę zewnętrzną teraz pobieram z HA, a chcę pobierać z esp ( czujnik DS lub BME, obojętne)
Aktualne temperatury zasilania i powrotów obiegów pobieram z HA przez DS, trzeba przenieść do esp
Wyjścia i wejścia z modułu PCF8575

Niektóre dane chciałbym jeszcze wyświetlać na jakimś OLED.
To tak pokrótce na tę chwilę :slight_smile:
Miałem taki sterownik fabryczny ale z miesiąc temu wyzionął ducha.

To jest takie dość śliskie założenie, problem można obejść, ale jak to będzie wyglądało w praktyce nie wiem

Dlaczego " śliskie" ? Masz na myśli " reboot_timeout, bedzie ponownie startował gdy nie będzie połączenia z HA i to zakłuci cały proces ?

Tak sądzę, oczywiście można wyłączyć te rebooty, ale ne wiem czy w przypadku problemów z siecią coś się głębiej nie posypie.

Można w ESPHome wyprodukować urządzenia autonomiczne, ale wtedy nie stosuje się api: więc się nie łączą z HA.

W sumie i na to jest obejście - wykorzystanie komunikacji z brokerem MQTT zamiast z HA po API.

I to jest dobra wiadomość :slight_smile:

MQTT niestety w ESPHome jest niestabilne przy wielu topicach więc po stronie HA musisz to wszystko zmergować i tak i w jednym topicu puścić, inaczej problemy z połączeniem sieciowym w randomowych momentach gwarantowane - ćwiczone przy 8 topicach. Przy zmniejszaniu topiców problem się zmniejsza, przy pozostawieniu jednego znika.

1 polubienie

Ma ktoś z Kolegów trochę czasu aby to ogarnąć ?