Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- esphome:
- name: $devicename
- #on_boot:
- # then:
- # - pzemac.reset_energy: pzemac_1
- esp32:
- board: nodemcu-32s
- #board_flash_mode: dout
- framework:
- type: esp-idf
- version: recommended
- debug:
- update_interval: 60s
- substitutions:
- devicename: reku-logger
- friendly_name: Rekuperator
- wifi:
- ssid: !secret wifi_ssid
- password: !secret wifi_pass
- # Enable fallback hotspot (captive portal) in case wifi connection fails
- ap:
- ssid: "sweet-fallback-${devicename}"
- password: cvbcbcbcvbdfbgte4
- captive_portal:
- logger:
- baud_rate: 0
- level: DEBUG
- # Enable Home Assistant API
- api:
- #password: !secret api-password
- ota:
- - platform: esphome
- # Enable Web server
- #web_server:
- # port: 80
- i2c:
- - id: bus_a
- sda: 21
- scl: 22
- scan: false
- # frequency: 50kHz
- - id: bus_b
- sda: 18
- scl: 19
- scan: false
- # frequency: 50kHz
- uart:
- - id: mod_bus #reku
- tx_pin: 16
- rx_pin: 17
- baud_rate: 9600
- stop_bits: 1
- - id: mod_bus2 #pzem
- tx_pin: 1
- rx_pin: 3
- baud_rate: 9600
- stop_bits: 2 #1 dla esp8266
- time:
- - platform: sntp
- id: czas_systemowy
- # Example configuration entry
- button:
- - platform: restart
- name: "ESP Reku Restart"
- globals:
- - id: przewietrzanie_timer_koniec_timestamp # <--- DODAJ TĘ LINIĘ
- type: int
- restore_value: yes
- initial_value: '0'
- - id: okap_timer_koniec_timestamp
- type: int
- restore_value: yes # Zachowaj stan po restarcie
- initial_value: '0' # 0 oznacza, ze timer nie jest aktywny
- - id: impreza_timer_koniec_timestamp
- type: int
- restore_value: yes
- initial_value: '0' # 0 oznacza, ze timer nie jest aktywny
- - id: licznik_korekt
- type: int
- restore_value: no
- initial_value: '0'
- - id: ostatni_timestamp_korekty # Nowa zmienna globalna
- type: int
- restore_value: yes # Ważne: przywróć wartość po restarcie, aby opóźnienie działało poprawnie
- initial_value: '0' # Domyślnie 0, co oznacza, że pierwsza korekta może nastąpić od razu po uruchomieniu
- - id: limit_korekt_na_godzine
- type: int
- restore_value: no
- initial_value: '10'
- - id: stary_nawiew
- type: int
- restore_value: no
- initial_value: '0'
- - id: stary_wywiew
- type: int
- restore_value: no
- initial_value: '0'
- # Aktualny tryb z podtypem dla trybu auto
- - id: tryb_auto_status
- type: std::string
- initial_value: '"normal"'
- # Aktualny aktywny tryb
- - id: aktywny_tryb
- type: std::string
- initial_value: '"auto"'
- - id: ostatnie_obroty
- type: int
- restore_value: no
- initial_value: '0'
- - id: czy_przewietrzanie
- type: bool
- restore_value: no
- initial_value: 'false'
- modbus:
- - id: mod_bus_reventon
- uart_id: mod_bus
- send_wait_time: 200ms
- # flow_control_pin: GPIO4
- - id: mod_bus_pzem
- # send_wait_time: 200ms
- uart_id: mod_bus2
- modbus_controller:
- - id: reventon_reku
- address: 0x01
- modbus_id: mod_bus_reventon
- update_interval: 15s
- - id: pzem1
- modbus_id: mod_bus_pzem
- address: 0x1
- #command_throttle: 0ms
- setup_priority: -10
- update_interval: 5s
- text_sensor:
- - platform: debug
- device:
- name: "Device Info"
- reset_reason:
- name: "Reset Reason"
- - platform: template
- name: "Aktywny tryb rekuperatora"
- lambda: |-
- std::string tryb = id(aktywny_tryb);
- if (tryb == "auto") {
- std::string status = id(tryb_auto_status);
- //return std::string("Tryb auto - ") + status;
- return std::string(status);
- }
- return tryb;
- update_interval: 30s
- - platform: template
- name: "Ostatni reset korekt"
- id: ostatni_reset_korekt
- lambda: |-
- char str[20];
- time_t curr_time = id(czas_systemowy).now().timestamp;
- strftime(str, sizeof(str), "%H:%M", localtime(&curr_time));
- return std::string(str);
- update_interval: 1h
- - platform: template
- name: $friendly_name Uptime
- id: uptime_human
- icon: mdi:clock-start
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Status
- id: reku_status
- register_type: holding
- address: 0x0012 #18
- response_size: 2
- raw_encode: HEXBYTES
- #bitmask: 0
- lambda: |-
- std::string z = "";
- int idx = item->offset+1;
- if ((data[idx] & 0x0001) != 0) z += "Alarm pożarowy ON, ";
- if ((data[idx] & 0x0002) != 0) z += "Bypass ON, ";
- if ((data[idx] & 0x0004) != 0) z += "Bypass OFF, ";
- if ((data[idx] & 0x0008) != 0) z += "Odladzanie, ";
- if(z.length() > 0){
- z.pop_back();
- }
- return {z};
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Status2
- id: reku_status2
- register_type: holding
- address: 0x0012 #18
- response_size: 2
- raw_encode: HEXBYTES
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Fault Message
- id: reku_fault_message
- register_type: holding
- address: 0x0014 #20
- response_size: 2
- raw_encode: HEXBYTES
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Fault Message2
- id: reku_fault_message2
- register_type: holding
- address: 0x0014 #20
- response_size: 2
- #raw_encode: HEXBYTES
- lambda: |-
- std::string z = "";
- int idx = item->offset+1;
- if ((data[idx] & 0x0001) != 0) z += "Błąd czujnika temperatury powietrza zewnętrznego (OA), ";
- if ((data[idx] & 0x0002) != 0) z += "Błąd pamięci EEPROM, ";
- if ((data[idx] & 0x0004) != 0) z += "Błąd czujnika temperatury powietrza wywiewanego (RA) lub SW4-3 jest w pozycji ON, ale bez podłączenia do czujnika wilgotności, ";
- if ((data[idx] & 0x0008) != 0) z += "Błąd czujnika temperatury powietrza usuwanego (EA), ";
- if ((data[idx] & 0x0010) != 0) z += "Błąd komunikacji, ";
- if ((data[idx] & 0x0020) != 0) z += "Błąd czujnika temperatury powietrza nawiewanego (SA), ";
- if ((data[idx] & 0x0040) != 0) z += "Błąd wentylatora wywiewnego, ";
- if ((data[idx] & 0x0080) != 0) z += "Błąd wentylatora nawiewnego, ";
- if(z.length() > 0){
- z.pop_back();
- }
- return {z};
- script:
- - id: sprawdz_ograniczenie_korekt
- mode: single
- parameters:
- korekta_id: int
- then:
- - if:
- condition:
- lambda: return id(licznik_korekt) < id(limit_korekt_na_godzine);
- then:
- - lambda: 'id(licznik_korekt) += 1;'
- - logger.log:
- format: "Wykonano korektę. Licznik: %d / %d"
- args:
- - id(licznik_korekt)
- - id(limit_korekt_na_godzine)
- - if:
- condition:
- lambda: return korekta_id == 1;
- then:
- - script.execute: korekta_do_nadcisnienia
- - if:
- condition:
- lambda: return korekta_id == 2;
- then:
- - script.execute: korekta_do_podcisnienia
- # --- DODAJ AKTUALIZACJĘ TIMESTAMPU PO WYKONANIU KOREKTY ---
- - lambda: 'id(ostatni_timestamp_korekty) = id(czas_systemowy).now().timestamp;'
- - logger.log: "Zaktualizowano timestamp ostatniej korekty."
- else:
- - logger.log: "Limit korekt na godzinę osiągnięty – korekta zablokowana."
- - id: korekta_do_nadcisnienia # Zwiększa wywiew, aby zredukować nadciśnienie (nawiew > wywiew)
- mode: restart
- then:
- - lambda: |-
- const int max_fan_difference = 3;
- int current_nawiew = id(wentylator_nawiewny).state; // Nawiew jest referencją (stała wartość)
- int current_wywiew = id(wentylator_wywiewny).state;
- int new_wywiew = current_wywiew + 1; // Próbujemy zwiększyć wywiew
- // Warunki:
- // 1. New_wywiew nie może przekroczyć 10.
- // 2. Różnica (nawiew - new_wywiew) musi być <= max_fan_difference.
- // (Czyli wywiew może być max o 3 biegi mniejszy od nawiewu)
- if (new_wywiew <= 10 && (current_nawiew - new_wywiew) <= max_fan_difference) {
- id(wentylator_wywiewny).make_call().set_value(new_wywiew).perform();
- ESP_LOGI("Korekta_Nadcisnienia", "Zwiekszono wywiew: wywiew = %d (nawiew = %d). Roznica: %d",
- new_wywiew, current_nawiew, current_nawiew - new_wywiew);
- } else {
- ESP_LOGI("Korekta_Nadcisnienia", "Korekta nadcisnienia zablokowana: wywiew=%d, nawiew=%d. Roznica %d, limit %d. (Wywiew min/max lub poza roznica)",
- current_wywiew, current_nawiew, current_nawiew - current_wywiew, max_fan_difference);
- }
- - id: korekta_do_podcisnienia # Zmniejsza wywiew, aby zredukować podciśnienie (nawiew < wywiew)
- mode: restart
- then:
- - lambda: |-
- const int max_fan_difference = 3;
- int current_nawiew = id(wentylator_nawiewny).state; // Nawiew jest referencją (stała wartość)
- int current_wywiew = id(wentylator_wywiewny).state;
- int new_wywiew = current_wywiew - 1; // Próbujemy zmniejszyć wywiew
- // Warunki:
- // 1. New_wywiew nie może schodzić poniżej 0.
- // 2. Różnica (new_wywiew - nawiew) musi być <= max_fan_difference.
- // (Czyli wywiew może być max o 3 biegi większy od nawiewu)
- if (new_wywiew >= 0 && (new_wywiew - current_nawiew) <= max_fan_difference) {
- id(wentylator_wywiewny).make_call().set_value(new_wywiew).perform();
- ESP_LOGI("Korekta_Podcisnienia", "Zmniejszono wywiew: wywiew = %d (nawiew = %d). Roznica: %d",
- new_wywiew, current_nawiew, new_wywiew - current_nawiew);
- } else {
- ESP_LOGI("Korekta_Podcisnienia", "Korekta podcisnienia zablokowana: wywiew=%d, nawiew=%d. Roznica %d, limit %d. (Wywiew min/max lub poza roznica)",
- current_wywiew, current_nawiew, current_wywiew - current_nawiew, max_fan_difference);
- }
- - id: wlacz_przewietrzanie
- mode: single
- then:
- - logger.log: "TRYB PRZEWIETRZANIA: aktywacja"
- - switch.turn_off: balans_przeplywu_switch
- - lambda: |-
- id(czy_przewietrzanie) = true;
- id(stary_nawiew) = (int)id(wentylator_nawiewny).state;
- id(stary_wywiew) = (int)id(wentylator_wywiewny).state;
- id(przewietrzanie_timer_koniec_timestamp) = id(czas_systemowy).now().timestamp + (int)id(czas_przewietrzania_minuty).state * 60;
- - number.set:
- id: wentylator_nawiewny
- value: 10
- - number.set:
- id: wentylator_wywiewny
- value: 10
- - lambda: |-
- int czas = (int)id(czas_przewietrzania_minuty).state;
- ESP_LOGI("przewietrzanie", "Czas przewietrzania: %d min", czas);
- - delay: !lambda 'return id(czas_przewietrzania_minuty).state * 60 * 1000;'
- - switch.turn_off: tryb_przewietrzania_switch
- - id: zakoncz_przewietrzanie
- mode: single
- then:
- - logger.log: "TRYB PRZEWIETRZANIA: zakończenie – przywracanie poprzednich ustawień"
- - lambda: |-
- id(czy_przewietrzanie) = false;
- id(przewietrzanie_timer_koniec_timestamp) = 0; // Wyzeruj timer
- - number.set:
- id: wentylator_nawiewny
- value: !lambda 'return id(stary_nawiew);'
- - number.set:
- id: wentylator_wywiewny
- value: !lambda 'return id(stary_wywiew);'
- - switch.turn_on: balans_przeplywu_switch
- - homeassistant.event:
- event: esphome.przewietrzanie_zakonczone
- data:
- message: "Tryb przewietrzania zakończony"
- nawiew: !lambda 'return id(wentylator_nawiewny).state;'
- wywiew: !lambda 'return id(wentylator_wywiewny).state;'
- # - id: set_mode
- # mode: single
- # parameters:
- # tryb: std::string
- # then:
- # - lambda: |-
- # id(aktywny_tryb) = tryb;
- # id(tryb_select_esp).publish_state(tryb);
- # ESP_LOGI("tryb", "Ustawiono tryb: %s", tryb.c_str());
- # - switch.turn_on: balans_przeplywu_switch
- # - if:
- # condition:
- # lambda: return tryb == "nocny";
- # then:
- # - switch.turn_off: balans_przeplywu_switch
- # - number.set:
- # id: wentylator_nawiewny
- # value: 2
- # - number.set:
- # id: wentylator_wywiewny
- # value: 2
- # - if:
- # condition:
- # lambda: return tryb == "intensywny";
- # then:
- # - number.set:
- # id: wentylator_nawiewny
- # value: 10
- # - number.set:
- # id: wentylator_wywiewny
- # value: 10
- # - delay: 2h
- # - script.execute:
- # id: set_mode
- # tryb: "normalny"
- # - if:
- # condition:
- # lambda: return tryb == "gosc";
- # then:
- # - number.set:
- # id: wentylator_nawiewny
- # value: 10
- # - number.set:
- # id: wentylator_wywiewny
- # value: 10
- # - switch.turn_off: balans_przeplywu_switch
- # - delay: 4h
- # - homeassistant.event:
- # event: esphome.tryb_goscia
- # data:
- # message: "Tryb gość zakończony. Powrót do normalnego trybu."
- # - script.execute:
- # id: set_mode
- # tryb: "normalny"
- # - if:
- # condition:
- # lambda: return tryb == "urlopowy";
- # then:
- # - switch.turn_off: balans_przeplywu_switch
- # - number.set:
- # id: wentylator_nawiewny
- # value: 1
- # - number.set:
- # id: wentylator_wywiewny
- # value: 1
- # - if:
- # condition:
- # lambda: return tryb == "serwisowy";
- # then:
- # - switch.turn_off: balans_przeplywu_switch
- # - switch.turn_off: tryb_przewietrzania_switch
- # - if:
- # condition:
- # lambda: return tryb == "auto";
- # then:
- # - switch.turn_on: balans_przeplywu_switch
- # - if:
- # condition:
- # lambda: return tryb == "normalny";
- # then:
- # - switch.turn_on: balans_przeplywu_switch
- # - if:
- # condition:
- # lambda: return tryb == "okno";
- # then:
- # - switch.turn_off: balans_przeplywu_switch
- # - number.set:
- # id: wentylator_nawiewny
- # value: 1
- # - number.set:
- # id: wentylator_wywiewny
- # value: 3
- # - lambda: id(ostatnie_obroty) = 3;
- - id: set_mode
- mode: single
- parameters:
- mode: std::string
- target_reku_speed: int
- then:
- - lambda: |-
- std::string new_mode = mode;
- int obroty_nawiew = 0;
- int obroty_wywiew = 0;
- if (new_mode == "auto") {
- obroty_nawiew = 3;
- obroty_wywiew = 3;
- ESP_LOGI("set_mode", "Tryb AUTO: Poczatkowe obroty: Nawiew=%d, Wywiew=%d. Dalsza regulacja w interval.", obroty_nawiew, obroty_wywiew);
- id(reku_on_off_switch).make_call().set_value(true).perform(); // Upewnij sie, ze glowny przelacznik jest ON
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- // W trybie auto dalsze obroty sa dynamicznie ustalane przez interval: 1min
- } else if (new_mode == "nocny") {
- obroty_nawiew = 2;
- obroty_wywiew = 2;
- ESP_LOGI("set_mode", "Tryb NOCNY: Poczatkowe obroty: Nawiew=%d, Wywiew=%d. Dalsza regulacja w interval.", obroty_nawiew, obroty_wywiew);
- id(reku_on_off_switch).make_call().set_value(true).perform();
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- } else if (new_mode == "okno") {
- obroty_nawiew = 1;
- obroty_wywiew = 4;
- ESP_LOGI("set_mode", "Tryb OKNO: Nawiew=%d, Wywiew=%d.", obroty_nawiew, obroty_wywiew);
- id(reku_on_off_switch).make_call().set_value(true).perform();
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- } else if (new_mode == "normalny") {
- obroty_nawiew = 2;
- obroty_wywiew = 2;
- ESP_LOGI("set_mode", "Tryb NORMALNY Nawiew=%d, Wywiew=%d.", obroty_nawiew, obroty_wywiew);
- id(reku_on_off_switch).make_call().set_value(true).perform();
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- } else if (new_mode == "serwisowy") {
- id(reku_on_off_switch).make_call().set_value(false).perform();
- id(tryb_przewietrzania_switch).turn_off();
- id(balans_przeplywu_switch).turn_off();
- ESP_LOGI("set_mode", "Tryb SERWISOWY: Wylaczam rekuperator. Wentylatory: Nawiew=%d, Wywiew=%d.", obroty_nawiew, obroty_wywiew);
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- } else if (new_mode == "urlopowy") {
- obroty_nawiew = 1;
- obroty_wywiew = 1;
- ESP_LOGI("set_mode", "Tryb URLOPOWY: Wentylatory wylaczone (Nawiew=%d, Wywiew=%d).", obroty_nawiew, obroty_wywiew);
- id(reku_on_off_switch).make_call().set_value(true).perform();
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- } else if (new_mode == "okap_auto") {
- obroty_nawiew = target_reku_speed;
- obroty_wywiew = target_reku_speed;
- ESP_LOGI("set_mode", "Tryb OKAP_AUTO: Nawiew=%d, Wywiew=%d (zalezne od predkosci okapu).", obroty_nawiew, obroty_wywiew);
- id(reku_on_off_switch).make_call().set_value(true).perform();
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- } else if (new_mode == "wylaczony") {
- ESP_LOGI("set_mode", "Tryb WYLACZONY: Rekuperator wylaczony (Nawiew=%d, Wywiew=%d).", obroty_nawiew, obroty_wywiew);
- id(reku_on_off_switch).make_call().set_value(false).perform();
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer imprezy
- id(tryb_przewietrzania_switch).turn_off();
- id(balans_przeplywu_switch).turn_off();
- } else if (new_mode == "impreza") {
- obroty_nawiew = 7;
- obroty_wywiew = 7;
- ESP_LOGI("set_mode", "Tryb IMPREZA: Nawiew=%d, Wywiew=%d. Aktywny na %d godzin.", obroty_nawiew, obroty_wywiew, (int)id(impreza_czas_trwania_godz).state);
- id(reku_on_off_switch).make_call().set_value(true).perform();
- // Ustaw timer zakonczenia trybu Impreza (teraz + zdefiniowany czas w minutach)
- id(impreza_timer_koniec_timestamp) = id(czas_systemowy).now().timestamp + (int)id(impreza_czas_trwania_godz).state * 3600;
- }
- else {
- ESP_LOGW("set_mode", "Nieznany tryb: %s", new_mode.c_str());
- return;
- }
- // Wykonaj zmiany obrotow tylko jesli tryb sie zmienil LUB
- // jesli to tryb 'okap_auto' i jego obroty sie zmienily (bo sa dynamiczne)
- // UWAGA: Jesli reku_on_off_switch zostal wylaczony wczesniej, wentylatory i tak zostana ustawione na 0.
- if (id(aktywny_tryb) != new_mode ||
- (new_mode == "okap_auto" && (id(wentylator_nawiewny).state != obroty_nawiew || id(wentylator_wywiewny).state != obroty_wywiew))) {
- id(aktywny_tryb) = new_mode;
- id(ostatnie_obroty) = obroty_nawiew; // Aktualizuj dla spójności
- // Aktualizacja select.tryb_select_esp ---
- id(tryb_select_esp).publish_state(new_mode);
- // Logika ustawiania obrotow wentylatorow (wykonuje sie nawet jesli sa na 0)
- ESP_LOGI("set_mode", "Przelaczono na tryb: '%s'. Ustawiam obroty: Nawiew=%d, Wywiew=%d.", new_mode.c_str(), obroty_nawiew, obroty_wywiew);
- id(wentylator_nawiewny).make_call().set_value(obroty_nawiew).perform();
- id(wentylator_wywiewny).make_call().set_value(obroty_wywiew).perform();
- } else {
- ESP_LOGD("set_mode", "Tryb '%s' juz jest aktywny z obrotami Nawiew=%d. Brak zmian.", new_mode.c_str(), obroty_nawiew);
- }
- interval:
- - interval: 1h
- then:
- - lambda: 'id(licznik_korekt) = 0;'
- - component.update: licznik_korekt_sensor
- - component.update: licznik_korekt_pozostale
- - component.update: ostatni_reset_korekt
- - interval: 1min
- then:
- - lambda: |-
- // Sprawdz glowny przelacznik rekuperatora. Jesli jest wylaczony, przerwij logike sterowania.
- // Tryby "serwisowy", "urlopowy", "wylaczony" obsluguja to poprzez wylaczenie reku_on_off_switch.
- if (!id(reku_on_off_switch).state) {
- ESP_LOGD("interval", "Rekuperator wylaczony glownym przelacznikiem. Pomijam logike sterowania.");
- id(tryb_auto_status) = "reku wylaczony (switch OFF)"; // Uaktualnij status
- return; // Przerwij dalsze wykonywanie lambdy
- }
- // --- LOGIKA DLA TRYBU OKAPU (z wykorzystaniem sensora predkosci z Home Assistant) ---
- float hood_fan_speed_percent = 0.0;
- if (id(okap_predkosc_ha).has_state()) { // Sprawdz, czy sensor ma juz stan
- hood_fan_speed_percent = id(okap_predkosc_ha).state;
- } else {
- // W przypadku braku stanu sensora, traktujemy okap jako wylaczony
- ESP_LOGW("okap_logic", "Sensor okap_predkosc_ha nie ma stanu! Traktuje okap jako wylaczony.");
- }
- bool okap_is_on = hood_fan_speed_percent > 0.0; // Okap jest wlaczony, jesli predkosc > 0
- int reku_speed_for_okap = 0;
- std::string okap_status_text = "";
- if (okap_is_on) {
- // Dostosuj progi i obroty rekuperatora do swoich biezacych potrzeb
- // Przyjmujemy 3 biegi okapu: niski, sredni, wysoki
- if (hood_fan_speed_percent > 66.0) { // Np. powyzej 66% to Bieg 3 okapu
- reku_speed_for_okap = 9; // Najwyzsze obroty rekuperatora
- okap_status_text = "Okap: Bieg 3 (Wysoki)";
- } else if (hood_fan_speed_percent > 33.0) { // Np. powyzej 33% to Bieg 2 okapu
- reku_speed_for_okap = 7; // Srednie obroty rekuperatora
- okap_status_text = "Okap: Bieg 2 (Sredni)";
- } else { // Pomiedzy 0% a 33% to Bieg 1 okapu
- reku_speed_for_okap = 5; // Nizsze obroty rekuperatora
- okap_status_text = "Okap: Bieg 1 (Niski)";
- }
- // Aktywuj tryb okap_auto i ustaw odpowiednie obroty
- if (id(aktywny_tryb) != "okap_auto" ||
- id(wentylator_nawiewny).state != reku_speed_for_okap) {
- ESP_LOGI("tryb", "Wykryto aktywny Okap (%s) - przelaczam w tryb OKAP_AUTO. Obroty reku: %d.", okap_status_text.c_str(), reku_speed_for_okap);
- id(set_mode)->execute("okap_auto", reku_speed_for_okap);
- }
- id(tryb_auto_status) = okap_status_text;
- // Ustaw "timer" okapu: oblicz czas zakonczenia na teraz + czas trwania z number.okap_czas_trwania_min
- id(okap_timer_koniec_timestamp) = id(czas_systemowy).now().timestamp + (int)id(okap_czas_trwania_min).state * 60;
- ESP_LOGI("tryb", "Timer OKAP_AUTO zresetowany na %d minut. Koniec o: %s", (int)id(okap_czas_trwania_min).state, id(czas_systemowy).now().strftime("%Y-%m-%d %H:%M:%S").c_str());
- return; // Zakoncz, bo tryb okap ma priorytet
- } else { // Okap jest wylaczony (hood_fan_speed_percent jest 0)
- if (id(aktywny_tryb) == "okap_auto") {
- // Jesli bylismy w trybie okap_auto, ale okap sie wylaczyl, sprawdzamy "timer"
- if (id(czas_systemowy).now().timestamp >= id(okap_timer_koniec_timestamp)) {
- ESP_LOGI("tryb", "Okap wylaczony, timer OKAP_AUTO minal - powracam do trybu AUTO.");
- id(set_mode)->execute("auto", 0);
- id(okap_timer_koniec_timestamp) = 0; // Wyzeruj timer po zakonczeniu
- } else {
- int remaining_seconds = id(okap_timer_koniec_timestamp) - id(czas_systemowy).now().timestamp;
- id(tryb_auto_status) = "Okap wylaczony (timer aktywny)";
- ESP_LOGD("tryb", "Okap wylaczony, timer OKAP_AUTO nadal aktywny. Pozostalo: %d s", remaining_seconds);
- }
- return;
- }
- }
- // --- KONIEC LOGIKI TRYBU OKAPU ---
- // --- LOGIKA TRYBU IMPREZA (NAJWYŻSZY PRIORYTET PO OKAPIE) ---
- if (id(aktywny_tryb) == "impreza") {
- if (id(czas_systemowy).now().timestamp >= id(impreza_timer_koniec_timestamp)) {
- ESP_LOGI("tryb", "Timer trybu IMPREZA minal - powracam do trybu AUTO.");
- id(set_mode)->execute("auto", 0);
- id(impreza_timer_koniec_timestamp) = 0; // Wyzeruj timer po zakonczeniu
- return; // Zakoncz, bo tryb zmieniony
- } else {
- int remaining_minutes = (id(impreza_timer_koniec_timestamp) - id(czas_systemowy).now().timestamp) / 60;
- id(tryb_auto_status) = "Impreza (" + std::to_string(remaining_minutes) + " min do konca)";
- ESP_LOGD("tryb", "Tryb IMPREZA nadal aktywny. Pozostalo: %d min", remaining_minutes);
- return; // Zakoncz, bo tryb impreza ma priorytet nad auto/nocny
- }
- }
- // --- KONIEC LOGIKI TRYBU IMPREZA ---
- // Pobierz aktualny czas
- auto t = id(czas_systemowy).now();
- int hour = t.hour;
- // --- NOWA LOGIKA: Wyjście z trybu nocnego ---
- // Jeśli jesteśmy w trybie nocnym, a godzina nie jest już nocna (np. >= 6 rano i < 23)
- if (id(aktywny_tryb) == "nocny" && (hour >= 6 && hour < 23)) {
- ESP_LOGI("tryb", "Koniec trybu nocnego - przechodzę w tryb AUTO.");
- id(set_mode)->execute("auto", 0);
- return; // Zakończ, by w tej minucie już być w trybie auto
- }
- // --- KONIEC NOWEJ LOGIKI ---
- // 1. Logika otwartego okna
- if (id(czy_jakies_okno_otwarte).state) {
- // Jeśli okno jest otwarte i system jest włączony, ale nie jest w trybie "okno"
- if (id(reku_on_off_switch).state && id(aktywny_tryb) != "okno") {
- ESP_LOGI("tryb", "Okno otwarte — przełączam w tryb OKNO");
- id(set_mode)->execute("okno", 0);
- }
- // Zawsze kończ działanie, jeśli jakiekolwiek okno jest otwarte
- return;
- }
- // Jeśli doszliśmy tutaj, to znaczy, że wszystkie okna są ZAMKNIĘTE.
- // Sprawdź, czy trzeba wyjść z trybu "okno"
- if (id(aktywny_tryb) == "okno") {
- ESP_LOGI("tryb", "Wszystkie okna zamknięte — przywracam tryb AUTO");
- id(set_mode)->execute("auto", 0);
- return; // Zakończ, aby w następnej minucie już działać w trybie auto
- }
- // Sprawdź warunki do wejścia w tryb nocny
- if ((hour >= 23 || hour < 6) &&
- id(reku_on_off_switch).state == 1 &&
- !id(czy_przewietrzanie) &&
- id(aktywny_tryb) != "serwisowy" &&
- id(aktywny_tryb) != "urlopowy" &&
- id(aktywny_tryb) != "nocny" &&
- id(aktywny_tryb) != "okno" &&
- !id(dom_pusty).state) { // <--- TUTAJ USUNIĘTO DODATKOWY NAWIAS ZAMYKAJĄCY
- ESP_LOGI("tryb", "Automatyczne przełączenie na tryb nocny");
- id(set_mode)->execute("nocny", 0);
- return; // pomiń dalej logikę w tej minucie
- }
- if (id(reku_on_off_switch).state != 1) {
- id(tryb_auto_status) = "reku wyłączony";
- return;
- }
- if (id(czy_przewietrzanie)) {
- id(tryb_auto_status) = "przewietrzanie aktywne";
- return;
- }
- std::string tryb = id(aktywny_tryb);
- // Deklaracje zmiennych na tym poziomie
- float hum = 0.0;
- int co2 = 0;
- bool pusty = id(dom_pusty).state; // Pobranie stanu 'dom_pusty' raz
- // Pobranie wartości z globalnych sensorów
- if (id(max_humidity_all_sensors).has_state()) {
- hum = id(max_humidity_all_sensors).state;
- } else {
- // Wartość domyślna, jeśli sensor max_humidity_all_sensors nie ma jeszcze stanu
- // To jest tylko na wypadek braku odczytu na samym starcie
- hum = 0.0;
- ESP_LOGW("Wilgotnosc", "Maksymalna wilgotność nie jest dostępna!");
- }
- if (id(co2_value).has_state()) {
- co2 = (int)id(co2_value).state;
- }
- if (tryb == "nocny") {
- // Logika CO2 i wilgotności dla trybu nocnego
- int obroty = id(ostatnie_obroty);
- std::string status;
- if (co2 > id(co2_nocny_high).state) {
- obroty = 5;
- status = "nocny - wysoki CO2";
- } else if (co2 < id(co2_nocny_low).state) {
- obroty = 2;
- status = "nocny - niski CO2";
- }
- // Dodatkowa logika wilgotności nocnej
- if (hum > id(wilgotnosc_nocna_high).state && obroty < 4) {
- obroty = 4;
- status = "nocny - wysoka wilgotność";
- } else if (hum < id(wilgotnosc_nocna_low).state && obroty > 2) {
- obroty = 2;
- status = "nocny - niska wilgotność";
- }
- // Wykonaj tylko jeśli się zmieniło
- if (obroty != id(ostatnie_obroty)) {
- id(wentylator_nawiewny).make_call().set_value(obroty).perform();
- id(wentylator_wywiewny).make_call().set_value(obroty).perform();
- id(ostatnie_obroty) = obroty;
- }
- // Zawsze ustaw status, nawet gdy obroty się nie zmieniają
- if (status.empty()) {
- status = "nocny - bez zmian";
- }
- id(tryb_auto_status) = status;
- return;
- }
- if (tryb == "auto") {
- // **NOWA LOGIKA: Sprawdź najpierw, czy dom jest pusty**
- if (pusty) { // Używamy zmiennej 'pusty' zdeklarowanej i ustawionej wcześniej
- // Jeśli dom jest pusty, wymuś obroty na 1 i zakończ logikę dla trybu auto
- int obroty = 1; // Minimalne obroty dla trybu "dom pusty"
- if (obroty != id(ostatnie_obroty)) {
- id(wentylator_nawiewny).make_call().set_value(obroty).perform();
- id(wentylator_wywiewny).make_call().set_value(obroty).perform();
- id(ostatnie_obroty) = obroty;
- }
- id(tryb_auto_status) = "dom pusty";
- } else {
- // **ISTNIEJĄCA LOGIKA: Uruchamiana tylko, gdy dom NIE jest pusty**
- // Używamy już zdeklarowanych i ustawionych zmiennych hum i co2
- // Usuwamy podwójne deklaracje hum i co2 tutaj!
- // Obroty z logiki CO2
- int obroty_co2 = 3;
- std::string status_co2 = "normalny";
- if (co2 > id(co2_auto_high).state) {
- obroty_co2 = 9;
- status_co2 = "wysoki CO2";
- } else if (co2 > id(co2_auto_medium).state) {
- obroty_co2 = 6;
- status_co2 = "średni CO2";
- } else if (co2 > id(co2_auto_low).state) {
- obroty_co2 = 4;
- status_co2 = "niski CO2";
- }
- // Obroty z logiki wilgotności
- int obroty_hum = 3;
- std::string status_hum = "";
- if (hum > id(wilgotnosc_wysoka).state) {
- obroty_hum = 9;
- status_hum = "wilgotność";
- } else if (hum < id(wilgotnosc_niska).state) {
- obroty_hum = 3;
- }
- // Wybór wyższych obrotów
- int obroty = std::max(obroty_co2, obroty_hum);
- if (obroty != id(ostatnie_obroty)) {
- id(wentylator_nawiewny).make_call().set_value(obroty).perform();
- id(wentylator_wywiewny).make_call().set_value(obroty).perform();
- id(ostatnie_obroty) = obroty;
- }
- // Ustawienie statusu
- if (obroty == obroty_hum && status_hum != "") {
- id(tryb_auto_status) = "Tryb auto - " + status_hum;
- } else {
- id(tryb_auto_status) = "Tryb auto - " + status_co2;
- }
- }
- }
- # Example configuration entry
- psram:
- mode: quad
- speed: 40MHZ
- sensor:
- - platform: template
- name: "Okap - czas do końca"
- id: okap_czas_do_konca
- unit_of_measurement: "min"
- icon: "mdi:stove-fan"
- update_interval: 10s # Odświeżaj co 10 sekund dla płynniejszego liczenia
- lambda: |-
- int now_timestamp = id(czas_systemowy).now().timestamp;
- int end_timestamp = id(okap_timer_koniec_timestamp);
- if (end_timestamp > now_timestamp) {
- // Oblicz pozostały czas w sekundach, a następnie w minutach
- int remaining_seconds = end_timestamp - now_timestamp;
- return (float)std::ceil(remaining_seconds / 60.0); // Zaokrągl w górę do najbliższej minuty
- } else {
- return 0; // Jeśli tryb się zakończył lub nieaktywny
- }
- - platform: template
- name: "Impreza - czas do końca"
- id: impreza_czas_do_konca
- unit_of_measurement: "min"
- icon: "mdi:party-popper"
- update_interval: 60s
- lambda: |-
- int now_timestamp = id(czas_systemowy).now().timestamp;
- int end_timestamp = id(impreza_timer_koniec_timestamp);
- if (end_timestamp > now_timestamp) {
- // Oblicz pozostały czas w sekundach, a następnie w minutach
- int remaining_seconds = end_timestamp - now_timestamp;
- return (float)std::ceil(remaining_seconds / 60.0); // Zaokrągl w górę do najbliższej minuty
- } else {
- return 0; // Jeśli tryb się zakończył lub nieaktywny
- }
- - platform: template
- name: "Przewietrzanie - czas do końca"
- id: przewietrzanie_czas_do_konca
- unit_of_measurement: "min"
- icon: "mdi:timer-sand"
- update_interval: 60s # Odświeżaj co 10 sekund dla płynniejszego liczenia
- lambda: |-
- int now_timestamp = id(czas_systemowy).now().timestamp;
- int end_timestamp = id(przewietrzanie_timer_koniec_timestamp);
- if (end_timestamp > now_timestamp) {
- // Oblicz pozostały czas w sekundach, a następnie w minutach
- int remaining_seconds = end_timestamp - now_timestamp;
- return (float)std::ceil(remaining_seconds / 60.0); // Zaokrągl w górę do najbliższej minuty
- } else {
- return 0; // Jeśli przewietrzanie się zakończyło lub nieaktywne
- }
- # Nowy sensor do odczytu predkosci okapu z Home Assistant
- - platform: homeassistant
- name: "Predkosc Okapu z HA"
- id: okap_predkosc_ha
- entity_id: fan.fan_hood # <--- ZMIEŃ TO NA PRAWIDŁOWE entity_id TWOJEGO OKAPU W HA!
- attribute: percentage # Odczytujemy atrybut 'percentage' z encji typu fan w HA
- unit_of_measurement: "%"
- accuracy_decimals: 0
- internal: true # Ten sensor jest uzywany tylko wewnetrznie przez ESPHome
- - platform: template
- name: "Maksymalna Wilgotność w Domu"
- id: max_humidity_all_sensors # Nowy ID dla sensora maksymalnej wilgotności
- unit_of_measurement: "%"
- accuracy_decimals: 1
- update_interval: 60s # Ustaw interwał aktualizacji np. na 10 sekund
- lambda: |-
- float max_h = 0.0;
- if (id(wilgotnosc_lazienka).has_state()) {
- max_h = std::max(max_h, id(wilgotnosc_lazienka).state);
- }
- if (id(wilgotnosc_kuchnia).has_state()) {
- max_h = std::max(max_h, id(wilgotnosc_kuchnia).state);
- }
- if (id(wilgotnosc_kotlownia).has_state()) {
- max_h = std::max(max_h, id(wilgotnosc_kotlownia).state);
- }
- //Jeśli masz więcej sensorów, dodaj kolejne bloki if i std::max()
- return max_h;
- - platform: debug
- free:
- name: "Heap Free"
- block:
- name: "Heap Max Block"
- loop_time:
- name: "Loop Time"
- psram:
- name: "Free PSRAM"
- cpu_frequency:
- name: "CPU Frequency"
- - platform: internal_temperature
- name: "Internal Temperature"
- - platform: uptime
- id: uptime_sensor
- internal: True
- update_interval: 60s
- on_raw_value:
- then:
- - text_sensor.template.publish:
- id: uptime_human
- state: !lambda |-
- int seconds = round(id(uptime_sensor).raw_state);
- int days = seconds / (24 * 3600);
- seconds = seconds % (24 * 3600);
- int hours = seconds / 3600;
- seconds = seconds % 3600;
- int minutes = seconds / 60;
- seconds = seconds % 60;
- return (
- (days ? to_string(days) + "d " : "") +
- (hours ? to_string(hours) + "h " : "") +
- (minutes ? to_string(minutes) + "m " : "") +
- (to_string(seconds) + "s")
- ).c_str();
- - platform: homeassistant
- id: co2_value
- entity_id: sensor.co2_salon
- internal: true
- - platform: homeassistant
- id: wilgotnosc_lazienka
- entity_id: sensor.atc_lazienka_parter_humidity
- internal: true
- - platform: homeassistant
- entity_id: sensor.ble_kuchnia_humidity
- id: wilgotnosc_kuchnia
- internal: true
- - platform: homeassistant
- entity_id: sensor.atc_04e8_humidity
- id: wilgotnosc_kotlownia
- internal: true
- - platform: template
- name: "Wykonane korekty (w tej godzinie)"
- id: licznik_korekt_sensor
- unit_of_measurement: "x"
- lambda: 'return id(licznik_korekt);'
- update_interval: 60s
- - platform: template
- name: "Pozostale korekty"
- id: licznik_korekt_pozostale
- unit_of_measurement: "x"
- lambda: 'return id(limit_korekt_na_godzine) - id(licznik_korekt);'
- update_interval: 60s
- #####################################################################
- # KANAL NAWIEWU (POWIETRZE WCHODZACE) #
- #####################################################################
- # 1. Czujnik SDP810 dla nawiewu - surowe ciśnienie
- - platform: sdp3x
- name: "Cisnienie Roznicowe Nawiew"
- id: nawiew_raw_pressure
- address: 0x25
- i2c_id: bus_a # Zmień na ID Twojej magistrali dla nawiewu
- update_interval: 5s
- filters:
- # Pierwszy filtr w liście
- - exponential_moving_average:
- alpha: 0.7 # Wcięcie 2 spacje pod 'exponential_moving_average'
- # Drugi filtr w liście. Wcięcie jak pierwszy filtr (myślnik w tej samej kolumnie).
- # - lambda: 'return x > 0 ? x : 0;'
- # 2. Sensor szablonowy - oblicza przepływ dla nawiewu w m3/h
- - platform: template
- name: "Przeplyw Nawiew m3/h"
- id: nawiew_airflow_m3_h
- update_interval: 5s
- icon: "mdi:air-filter"
- unit_of_measurement: "m³/h"
- lambda: |-
- // Stałe fizyczne
- const float p_atm = 101325.0; // Ciśnienie atmosferyczne w Pa
- const float R = 287.05; // Stała gazowa dla powietrza J/(kg·K)
- // Pobierz temperaturę (°C) i przelicz na Kelwiny
- float temp_c = id(nawiew_temp).state;
- float temp_k = temp_c + 273.15;
- // Oblicz gęstość powietrza (rho)
- float rho = p_atm / (R * temp_k);
- // Średnica i pole przekroju kanału (0.2 m)
- float duct_diameter = 0.2;
- float duct_radius = duct_diameter / 2.0;
- float duct_area = M_PI * pow(duct_radius, 2.0);
- // Odczytaj ciśnienie w hPa i przelicz na Pa
- float pressure_hpa = id(nawiew_raw_pressure).state;
- float pressure_pa = pressure_hpa * 100.0;
- // Sprawdź, czy ciśnienie dodatnie
- if (pressure_pa <= 0) {
- return 0;
- }
- // Oblicz prędkość i przepływ
- float velocity_mps = sqrt((2.0 * pressure_pa) / rho);
- float flow_m3_s = velocity_mps * duct_area;
- // Przelicz na m³/h
- return flow_m3_s * 3600.0;
- #####################################################################
- # KANAL WYWIEWU (POWIETRZE WYCHODZACE) #
- #####################################################################
- # 3. Czujnik SDP810 dla wywiewu - surowe ciśnienie
- - platform: sdp3x
- name: "Cisnienie Roznicowe Wywiew"
- id: wywiew_raw_pressure
- address: 0x25
- i2c_id: bus_b # Zmień na ID Twojej magistrali dla wywiewu
- update_interval: 5s
- filters:
- - exponential_moving_average:
- alpha: 0.7
- #- lambda: 'return x > 0 ? x : 0;'
- # 4. Sensor szablonowy - oblicza przepływ dla wywiewu w m3/h
- - platform: template
- name: "Przeplyw Wywiew m3/h"
- id: wywiew_airflow_m3_h
- icon: "mdi:air-filter"
- unit_of_measurement: "m³/h"
- update_interval: 5s
- lambda: |-
- // Stałe fizyczne
- const float p_atm = 101325.0; // Ciśnienie atmosferyczne w Pa
- const float R = 287.05; // Stała gazowa dla powietrza J/(kg·K)
- // Pobierz temperaturę wywiewu i przelicz na Kelwiny
- float temp_c = id(wywiew_temp).state;
- float temp_k = temp_c + 273.15;
- // Oblicz gęstość powietrza (kg/m³) z równania gazu doskonałego
- float rho = p_atm / (R * temp_k);
- // Parametry kanału
- float duct_diameter = 0.2; // Średnica kanału (m)
- float duct_radius = duct_diameter / 2.0;
- float duct_area = M_PI * pow(duct_radius, 2.0); // Pole przekroju (m²)
- // Ciśnienie dynamiczne w hPa → Pa
- float pressure_hpa = id(wywiew_raw_pressure).state;
- float pressure_pa = pressure_hpa * 100.0;
- // Jeśli ciśnienie ≤ 0, zwróć 0
- if (pressure_pa <= 0) {
- return 0.0;
- }
- // Oblicz prędkość przepływu (m/s)
- float velocity_mps = sqrt((2.0 * pressure_pa) / rho);
- // Oblicz przepływ objętościowy (m³/s) → przelicz na m³/h
- float flow_m3_s = velocity_mps * duct_area;
- return flow_m3_s * 3600.0;
- # 5. Sensor szablonowy - oblicza różnicę przepływu (Nawiew - Wywiew)
- - platform: template
- name: "Roznica Przeplywu"
- id: flow_difference_m3_h
- icon: "mdi:compare-arrows"
- unit_of_measurement: "m³/h"
- update_interval: 10s
- lambda: |-
- if (isnan(id(nawiew_airflow_m3_h).state) || isnan(id(wywiew_airflow_m3_h).state)) {
- return 0.0;
- }
- return id(nawiew_airflow_m3_h).state - id(wywiew_airflow_m3_h).state;
- on_value:
- - if:
- condition:
- # 1. Sprawdź, czy balans przepływu jest włączony
- - switch.is_on: balans_przeplywu_switch
- # 2. Sprawdź, czy minął wystarczający czas od ostatniej korekty
- - lambda: |-
- // Czas opóźnienia w minutach (np. 5 minut)
- const int delay_minutes = 5; // <--- TUTAJ ZMIENIASZ CZAS OPÓŹNIENIA W MINUTACH
- const int delay_seconds = delay_minutes * 60; // Przeliczenie na sekundy
- time_t current_time = id(czas_systemowy).now().timestamp;
- int last_correction_time = id(ostatni_timestamp_korekty);
- return (current_time - last_correction_time) >= delay_seconds;
- then:
- - logger.log:
- format: "Różnica przepływu: %.1f m³/h"
- args: ["id(flow_difference_m3_h).state"]
- - if:
- condition:
- lambda: return id(flow_difference_m3_h).state > 30; # Nadciśnienie - nawiew o 25 m³/h większy od wywiewu
- then:
- - script.execute:
- id: sprawdz_ograniczenie_korekt
- korekta_id: 1 # Wywołuje korekta_do_nadcisnienia (zwiększa wywiew)
- - if:
- condition:
- lambda: return id(flow_difference_m3_h).state < -30; # Podciśnienie - wywiew o 25 m³/h większy od nawiewu
- then:
- - script.execute:
- id: sprawdz_ograniczenie_korekt
- korekta_id: 2 # Wywołuje korekta_do_podcisnienia (zmniejsza wywiew)
- ############ PZEM-004T V3 Reku
- - platform: pzemac
- modbus_id: mod_bus_pzem
- address: 1
- id: pzemac_1
- current:
- name: "Rekuperator prąd"
- accuracy_decimals: 2
- id: reku_prad
- voltage:
- name: "Rekuperator napięcie"
- unit_of_measurement: V
- accuracy_decimals: 2
- id: reku_napiecie
- energy:
- name: "Rekuperator zużycie energii"
- filters:
- # Wh to kWh is 0.001
- - multiply: 0.001
- unit_of_measurement: kWh
- accuracy_decimals: 3
- id: pg_energia
- power:
- name: "Rekuperator moc"
- unit_of_measurement: W
- accuracy_decimals: 2
- id: reku_moc
- frequency:
- name: "Rekuperator częstotliwość"
- unit_of_measurement: Hz
- accuracy_decimals: 2
- power_factor:
- name: "Rekuperator współczynnik mocy"
- accuracy_decimals: 2
- id: reku_power_factor
- update_interval: 5s
- - platform: total_daily_energy
- name: "Rekuperator dzienne zużycie energii"
- power_id: pg_energia
- unit_of_measurement: "kWh"
- accuracy_decimals: 3
- id: pg_daily_kwh
- icon: mdi:counter
- device_class: energy
- filters:
- # Multiplication factor from W to kW is 0.001
- - multiply: 0.001
- - platform: template
- name: ${friendly_name} sprawność
- unit_of_measurement: "%"
- lambda: |-
- float dzielnik = id(wywiew_temp).state - id(czerpnia_temp).state;
- if (dzielnik != 0) {
- float dzielna = id(nawiew_temp).state - id(czerpnia_temp).state;
- return (dzielna / dzielnik) * 100.0;
- } else {
- // Zwróć 0 lub inną domyślną wartość, gdy nie można wykonać obliczeń
- return 0;
- }
- accuracy_decimals: 1
- update_interval: 15s
- # sprawność temperaturowa = (T2-T1)/(T3-T1)
- # T1 – temperatura powietrza zewnętrznego (nawiewanego przed wymiennikiem) [°C]
- # T2 – temperatura powietrza nawiewanego za wymiennikiem [°C]
- # T3– temperatura powietrza wywiewanego z pomieszczeń przed wymiennikiem [°C]
- - platform: wifi_signal
- name: ${friendly_name} RSSI
- update_interval: 60s
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Temperatura wywiew
- id: wywiew_temp
- register_type: holding
- address: 0x000c #12
- unit_of_measurement: "°C"
- device_class: "temperature"
- value_type: U_WORD
- filters:
- - lambda: return x - 40.0;
- #accuracy_decimals: 1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Temperatura czerpnia
- id: czerpnia_temp
- register_type: holding
- address: 0x000d #13
- unit_of_measurement: "°C"
- device_class: "temperature"
- value_type: U_WORD
- filters:
- - lambda: return x - 40.0;
- #accuracy_decimals: 1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Temperatura wyrzutnia
- id: wyrzutnia_temp
- register_type: holding
- address: 0x000f #15
- unit_of_measurement: "°C"
- device_class: "temperature"
- value_type: U_WORD
- filters:
- - lambda: return x - 40.0;
- #accuracy_decimals: 1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Temperatura nawiew
- id: nawiew_temp
- register_type: holding
- address: 0x000e #14
- unit_of_measurement: "°C"
- device_class: "temperature"
- value_type: U_WORD
- filters:
- - lambda: return x - 40.0;
- #accuracy_decimals: 1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} CO2
- id: co2_reku
- register_type: holding
- address: 0x0300 #768
- unit_of_measurement: "ppm"
- device_class: "carbon_dioxide"
- value_type: U_WORD
- skip_updates: 100
- #accuracy_decimals: 1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Fan running time
- id: fan_running_time
- register_type: holding
- address: 0x0301 #769
- unit_of_measurement: "min"
- value_type: U_WORD
- filters:
- - lambda: return x * 6.0;
- skip_updates: 12
- #accuracy_decimals: 1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Wilgotność
- id: wilgotnosc_reku
- register_type: holding
- address: 0x0302 #770
- unit_of_measurement: "%"
- device_class: "humidity"
- value_type: U_WORD
- skip_updates: 10
- #accuracy_decimals: 1
- binary_sensor:
- - platform: homeassistant
- id: okno_salon
- entity_id: binary_sensor.shelly_blu_door_window_ce04_window
- - platform: homeassistant
- id: okno_salon2
- entity_id: binary_sensor.shelly_blu_door_window_24b7_window
- - platform: homeassistant
- id: okno_gabinet_l
- entity_id: binary_sensor.shelly_blu_door_window_cc52_window
- - platform: homeassistant
- id: okno_gabinet_p
- entity_id: binary_sensor.shelly_blu_door_window_882d_window
- - platform: homeassistant
- id: okno_lazienka
- entity_id: binary_sensor.shelly_blu_door_window_06b3_window
- - platform: homeassistant
- id: dom_pusty
- entity_id: input_boolean.dom_pusty
- internal: False
- name: Dom pusty
- - platform: template
- id: czy_jakies_okno_otwarte
- name: "Czy jakiekolwiek okno otwarte"
- lambda: |-
- return id(okno_salon).state || id(okno_salon2).state || id(okno_gabinet_l).state
- || id(okno_gabinet_p).state || id(okno_lazienka).state;
- #on_press:
- # then:
- # - if:
- # condition:
- # lambda: return id(aktywny_tryb) != "okno";
- # then:
- # - logger.log: "Wykryto otwarte okno — przełączam na tryb OKNO"
- # - script.execute:
- # id: set_mode
- # tryb: "okno"
- #on_release:
- # then:
- # - if:
- # condition:
- # lambda: return id(aktywny_tryb) == "okno";
- # then:
- # - logger.log: "Wszystkie okna zamknięte — przywracam tryb AUTO"
- # - script.execute:
- # id: set_mode
- # tryb: "auto"
- - platform: status
- name: ${friendly_name} Logger Status
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} On/Off status
- #device_class: running
- register_type: holding
- #entity_category: diagnostic
- address: 0x0009 #9
- #bitmask: 0x1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Auto restart status
- #device_class: running
- register_type: holding
- #entity_category: diagnostic
- address: 0x0000 #0
- #bitmask: 0x1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Nagrzewnica status
- #device_class: running
- register_type: holding
- #entity_category: diagnostic
- address: 0x0001 #1
- #bitmask: 0x1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Zewnętrzny sygnał ON/OFF
- #device_class: running
- register_type: holding
- #entity_category: diagnostic
- address: 0x0010 #16
- #bitmask: 0x1
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Sygnał ON/OFF czujnika CO2
- #device_class: running
- register_type: holding
- #entity_category: diagnostic
- address: 0x0011 #17
- #bitmask: 0x1
- switch:
- - platform: template
- name: "Tryb przewietrzania"
- id: tryb_przewietrzania_switch
- optimistic: true
- restore_mode: RESTORE_DEFAULT_OFF
- on_turn_on:
- - script.execute: wlacz_przewietrzanie
- on_turn_off:
- - script.execute: zakoncz_przewietrzanie
- - platform: template
- name: "Automatyczny Balans Przeplywu"
- id: balans_przeplywu_switch
- icon: "mdi:light-switch"
- # Ustawia przełącznik na wyłączony po restarcie ESP
- restore_mode: RESTORE_DEFAULT_OFF
- optimistic: true
- - platform: template
- name: ${friendly_name} switch
- id: reku_switch
- restore_mode: RESTORE_DEFAULT_OFF
- lambda: |-
- if (id(reku_on_off_switch).state==1) {
- return true;
- } else {
- return false;
- }
- turn_on_action:
- - number.set:
- id: reku_on_off_switch
- value: 1
- turn_off_action:
- - number.set:
- id: reku_on_off_switch
- value: 0
- number:
- - platform: template
- name: "Czas trwania trybu Impreza"
- id: impreza_czas_trwania_godz
- min_value: 1
- max_value: 8
- step: 1
- unit_of_measurement: "h"
- mode: BOX
- restore_value: yes
- initial_value: 5 # Domyslny czas trwania 5 godzin
- optimistic: true
- - platform: template
- name: "Czas trwania trybu Okap"
- id: okap_czas_trwania_min
- min_value: 5
- max_value: 60
- step: 5
- unit_of_measurement: "min"
- mode: BOX
- restore_value: yes
- initial_value: 15 # Domyslny czas trwania 15 minut
- optimistic: true
- - id: co2_auto_high
- name: "CO2 Auto High"
- min_value: 400
- max_value: 2000
- step: 10
- unit_of_measurement: "ppm"
- optimistic: true
- initial_value: 1200
- platform: template
- mode: box
- - id: co2_auto_medium
- name: "CO2 Auto Medium"
- min_value: 400
- max_value: 2000
- step: 10
- unit_of_measurement: "ppm"
- optimistic: true
- initial_value: 1000
- platform: template
- mode: box
- - id: co2_auto_low
- name: "CO2 Auto Low"
- min_value: 400
- max_value: 2000
- step: 10
- unit_of_measurement: "ppm"
- optimistic: true
- initial_value: 800
- platform: template
- mode: box
- - id: co2_nocny_high
- name: "CO2 Nocny High"
- min_value: 400
- max_value: 2000
- step: 10
- unit_of_measurement: "ppm"
- optimistic: true
- initial_value: 800
- platform: template
- mode: box
- - id: co2_nocny_low
- name: "CO2 Nocny Low"
- min_value: 400
- max_value: 2000
- step: 10
- unit_of_measurement: "ppm"
- optimistic: true
- initial_value: 700
- platform: template
- mode: box
- - id: wilgotnosc_wysoka
- name: "Wilgotność Wysoka"
- min_value: 40
- max_value: 100
- step: 1
- unit_of_measurement: "%"
- optimistic: true
- initial_value: 70
- platform: template
- mode: box
- - id: wilgotnosc_niska
- name: "Wilgotność Niska"
- min_value: 30
- max_value: 100
- step: 1
- unit_of_measurement: "%"
- optimistic: true
- initial_value: 55
- platform: template
- mode: box
- - id: wilgotnosc_nocna_high
- name: "Wilgotność nocna wysoka"
- min_value: 60
- max_value: 100
- step: 1
- unit_of_measurement: "%"
- optimistic: true
- initial_value: 80
- platform: template
- mode: box
- - id: wilgotnosc_nocna_low
- name: "Wilgotność nocna niska"
- min_value: 30
- max_value: 100
- step: 1
- unit_of_measurement: "%"
- optimistic: true
- initial_value: 65
- platform: template
- mode: box
- - platform: template
- name: "Czas przewietrzania"
- id: czas_przewietrzania_minuty
- min_value: 1
- max_value: 30
- step: 1
- unit_of_measurement: "min"
- optimistic: true
- restore_value: true
- initial_value: 10
- mode: box
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- id: reku_on_off_switch
- address: 0x0009 #9
- value_type: U_WORD
- min_value: 0
- max_value: 1
- step: 1
- mode: box
- internal: true
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Temperatura X otwarcia bypass’u
- address: 0x0002 #2
- unit_of_measurement: "°C"
- id: temp_x_bypass
- value_type: U_WORD
- min_value: 5
- max_value: 30
- step: 1
- mode: box
- entity_category: config
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Temperatura Y otwarcia bypass’u
- address: 0x0003 #3
- unit_of_measurement: "°C"
- id: temp_y_bypass
- value_type: U_WORD
- min_value: 2
- max_value: 15
- step: 1
- mode: box
- entity_category: config
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Interwał odszraniania
- address: 0x0004 #4
- unit_of_measurement: "min"
- #device_class: "temperature"
- id: defrosting_interval
- value_type: U_WORD
- min_value: 15
- max_value: 99
- step: 1
- mode: box
- entity_category: config
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Temperatura odszraniania
- address: 0x0005 #5
- unit_of_measurement: "°C"
- id: defrosting_enter_temperature
- value_type: U_WORD
- min_value: -9
- max_value: 5
- lambda: "return x - 40.0;"
- write_lambda: "return x + 40.0;"
- step: 1
- mode: box
- entity_category: config
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Czas odszraniania
- address: 0x0006 #6
- unit_of_measurement: "min"
- #device_class: "temperature"
- id: defrost_duration_time
- value_type: U_WORD
- min_value: 2
- max_value: 20
- step: 1
- mode: box
- entity_category: config
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Czujnik CO2
- address: 0x0007 #7
- unit_of_measurement: "ppm"
- id: co2_set
- value_type: U_WORD
- min_value: 00
- max_value: 2500
- lambda: "return x * 10.0;"
- write_lambda: "return x / 10.0;"
- step: 1
- mode: box
- entity_category: config
- skip_updates: 20
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Wentylator nawiewny
- icon: "mdi:fan-speed-1"
- address: 0x000a #10
- lambda: |-
- if (x == 2) {
- return 1;
- }
- if (x == 3) {
- return 2;
- }
- if (x == 5) {
- return 3;
- }
- if (x == 8) {
- return 4;
- }
- if (x == 9) {
- return 5;
- }
- if (x == 10) {
- return 6;
- }
- if (x == 11) {
- return 7;
- }
- if (x == 12) {
- return 8;
- }
- if (x == 13) {
- return 9;
- }
- if (x == 14) {
- return 10;
- } else {
- return NAN;
- }
- write_lambda: |-
- if (x == 1) {
- return 2;
- }
- if (x == 2) {
- return 3;
- }
- if (x == 3) {
- return 5;
- }
- if (x == 4) {
- return 8;
- }
- if (x == 5) {
- return 9;
- }
- if (x == 6) {
- return 10;
- }
- if (x == 7) {
- return 11;
- }
- if (x == 8) {
- return 12;
- }
- if (x == 9) {
- return 13;
- }
- if (x == 10) {
- return 14;
- } else {
- return NAN;
- }
- #unit_of_measurement: "%"
- id: wentylator_nawiewny
- value_type: U_WORD
- entity_category: ""
- min_value: 1
- max_value: 10
- step: 1
- mode: slider
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Wentylator wywiewny
- icon: "mdi:fan-speed-1"
- address: 0x000b #11
- lambda: |-
- if (x == 2) {
- return 1;
- }
- if (x == 3) {
- return 2;
- }
- if (x == 5) {
- return 3;
- }
- if (x == 8) {
- return 4;
- }
- if (x == 9) {
- return 5;
- }
- if (x == 10) {
- return 6;
- }
- if (x == 11) {
- return 7;
- }
- if (x == 12) {
- return 8;
- }
- if (x == 13) {
- return 9;
- }
- if (x == 14) {
- return 10;
- } else {
- return NAN;
- }
- write_lambda: |-
- if (x == 1) {
- return 2;
- }
- if (x == 2) {
- return 3;
- }
- if (x == 3) {
- return 5;
- }
- if (x == 4) {
- return 8;
- }
- if (x == 5) {
- return 9;
- }
- if (x == 6) {
- return 10;
- }
- if (x == 7) {
- return 11;
- }
- if (x == 8) {
- return 12;
- }
- if (x == 9) {
- return 13;
- }
- if (x == 10) {
- return 14;
- } else {
- return NAN;
- }
- #unit_of_measurement: "%"
- id: wentylator_wywiewny
- value_type: U_WORD
- entity_category: ""
- min_value: 1
- max_value: 10
- step: 1
- mode: slider
- select:
- - platform: template
- name: "Tryb rekuperatora (ESP)"
- id: tryb_select_esp
- optimistic: true
- options:
- - auto
- - normalny
- - nocny
- - impreza
- - urlopowy
- - serwisowy
- - okno
- - okap_auto
- initial_option: auto
- restore_value: yes
- on_value:
- then:
- - script.execute:
- id: set_mode
- mode: !lambda 'return x;'
- target_reku_speed: 0
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Ustawienia wielofunkcyjne
- icon: "mdi:fan"
- id: multi_sel
- address: 0x0018 #24
- entity_category: config
- value_type: U_WORD
- optimistic: false
- optionsmap:
- "Kasuj": 0
- "Usunięcie alarmu filtra": 1
- "Usunięcie harmonogramu tygodniowego": 2
- - platform: modbus_controller
- modbus_controller_id: reventon_reku
- name: ${friendly_name} Ustawienia alarmu filtra
- icon: "mdi:fan"
- id: filter_sel
- address: 0x0019 #25
- entity_category: config
- value_type: U_WORD
- optimistic: false
- optionsmap:
- "45 dni": 0
- "60 dni": 1
- "90 dni": 2
- "180 dni": 3
Advertisement
Add Comment
Please, Sign In to add comment