Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- substitutions:
- devicename: esp32-odwodnienie
- v_flood_low: "1.9" # próg startu pompy
- v_dry_low: "2.5" # próg pompa off
- v_flood_high: "1.3" # próg alarmu
- v_clear_high: "2.9" # anulowanie alarmu
- esphome:
- name: $devicename
- on_boot:
- priority: 600
- then:
- - output.turn_on: sonda_power
- - delay: 80ms
- - component.update: adc_low
- - delay: 20ms
- - component.update: adc_high
- - delay: 20ms
- - output.turn_off: sonda_power
- - script.execute: apply_pump_logic
- esp32:
- board: esp32dev
- framework:
- type: arduino
- # Enable logging
- logger:
- level: DEBUG
- web_server:
- port: 80
- time:
- - platform: homeassistant
- id: homeassistant_time
- api:
- ota:
- platform: esphome
- password: "xxxxxxxxxxxxxxxxxxxxxxxxxx"
- wifi:
- ssid: !secret wifi_ssid
- password: !secret wifi_password
- manual_ip:
- static_ip: 192.168.1.240
- gateway: 192.168.1.1
- subnet: 255.255.255.0
- ap:
- ssid: "Esp32-Odwodnienie Fallback Hotspot"
- password: "xxxxxxxxxx"
- captive_portal:
- globals:
- - id: pump_active
- type: bool
- restore_value: yes
- initial_value: 'false'
- - id: post_run_running
- type: bool
- restore_value: no
- initial_value: 'false'
- # Licznik kolejnych cykli, w których górna sonda wskazuje wodę a dolna NIE.
- - id: low_probe_fault_timer
- type: int
- restore_value: no
- initial_value: '0'
- # Aktualny stan awarii (publikowany przez binary_sensor)
- - id: low_probe_fault_state
- type: bool
- restore_value: no
- initial_value: 'false'
- button:
- - platform: restart
- name: 'Kotlownia restart'
- output:
- - platform: gpio
- id: sonda_power
- pin: GPIO25
- - platform: gpio
- id: pump_output
- pin:
- number: GPIO23
- mode: OUTPUT
- inverted: false
- text_sensor:
- - platform: version
- name: ESPHome Version
- - platform: wifi_info
- ip_address:
- name: $devicename IP
- ssid:
- name: $devicename SSID
- bssid:
- name: $devicename BSSID
- sensor:
- - platform: adc
- id: adc_low
- name: "Napięcie sondy (pompa)"
- pin: GPIO36
- attenuation: 11db
- update_interval: never
- accuracy_decimals: 1
- unit_of_measurement: "V"
- device_class: "voltage"
- filters:
- - lambda: |-
- return floor(x * 10.0f) / 10.0f;
- - platform: adc
- id: adc_high
- name: "Napięcie sondy (alarm)"
- pin: GPIO33
- attenuation: 11db
- update_interval: never
- accuracy_decimals: 1
- unit_of_measurement: "V"
- device_class: "voltage"
- filters:
- - lambda: |-
- return floor(x * 10.0f) / 10.0f;
- binary_sensor:
- - platform: template
- name: "Zalanie (włącz pompę)"
- id: flood_low
- device_class: moisture
- lambda: |-
- static bool flooded = false;
- const float V = id(adc_low).state;
- if (flooded && V > ${v_dry_low}) flooded = false;
- else if (!flooded && V < ${v_flood_low}) flooded = true;
- return flooded;
- - platform: template
- name: "Zalanie (alarm)"
- id: flood_high
- device_class: safety
- lambda: |-
- static bool high = false;
- const float V = id(adc_high).state;
- if (high && V > ${v_clear_high}) high = false;
- else if (!high && V < ${v_flood_high}) high = true;
- return high;
- on_press:
- - switch.turn_on: pump_switch # spróbuj ratować
- # - delay: 2s
- # - homeassistant.service:
- # service: notify.mobile_app_telefon
- # data:
- # message: "‼️ Wysoki poziom w studzience – pompa nie nadąża!"
- - platform: template
- name: "Awaria sondy niskiej"
- id: low_probe_fault
- device_class: problem
- entity_category: diagnostic
- lambda: |-
- return id(low_probe_fault_state);
- - platform: template
- name: "Tryb dobiegu pompy"
- lambda: |-
- return id(post_run_running);
- entity_category: diagnostic
- interval:
- - interval: 10s
- then:
- - output.turn_on: sonda_power
- - delay: 80ms
- - component.update: adc_low
- - delay: 20ms
- - component.update: adc_high
- - delay: 20ms
- - output.turn_off: sonda_power
- - script.execute: apply_pump_logic
- switch:
- - platform: output
- name: "Pompa odpompowująca"
- id: pump_switch
- output: pump_output
- restore_mode: RESTORE_DEFAULT_OFF
- script:
- - id: pump_off_delayed
- mode: restart
- then:
- - lambda: |-
- id(post_run_running) = true;
- ESP_LOGD("pump","Post-run started");
- - delay: 5min
- - lambda: |-
- float Vl = id(adc_low).state;
- float Vh = id(adc_high).state;
- bool both_dry = (Vl > ${v_dry_low}) && (Vh > ${v_clear_high});
- if (both_dry) {
- ESP_LOGI("pump","Post-run finished (Vl=%.2f V, Vh=%.2f V) -> pump OFF", Vl, Vh);
- id(pump_switch).turn_off();
- id(pump_active) = false;
- } else {
- ESP_LOGW("pump","Post-run aborted (Vl=%.2f V, Vh=%.2f V) -> keep pump ON", Vl, Vh);
- // Pompa zostaje ON; wciąż zalanie lub powrót zalania
- }
- id(post_run_running) = false;
- # Główna logika – wywoływana na starcie i po każdym cyklu pomiarowym
- - id: apply_pump_logic
- mode: queued
- then:
- - lambda: |-
- float Vl = id(adc_low).state; // napięcie sondy sterującej pompą
- float Vh = id(adc_high).state; // napięcie sondy alarmowej (wysokiej)
- // Warunki zalania (dowolny poziom aktywny)
- bool flood_low_cond = (Vl < ${v_flood_low});
- bool flood_high_cond = (Vh < ${v_flood_high});
- bool any_flood = flood_low_cond || flood_high_cond;
- // Warunek pozwalający rozpocząć dobieganie: obie sondy wskazują "sucho"
- // (Wyższe progi dla opuszczenia stanu zalania)
- bool can_stop = (Vl > ${v_dry_low}) && (Vh > ${v_clear_high});
- // --- Sterowanie pompą ---
- if (any_flood) {
- // Wymuś / utrzymaj ON
- if (!id(pump_switch).state) {
- ESP_LOGW("pump","Forcing pump ON (Vl=%.2f < %.2f || Vh=%.2f < %.2f)",
- Vl, (float)${v_flood_low}, Vh, (float)${v_flood_high});
- id(pump_switch).turn_on();
- }
- id(pump_active) = true;
- // Jeśli trwał post-run i znów pojawiło się zalanie – przerwij
- if (id(post_run_running)) {
- ESP_LOGD("pump","Cancelling post-run due to renewed flood (Vl=%.2f, Vh=%.2f)", Vl, Vh);
- id(pump_off_delayed).stop();
- id(post_run_running) = false;
- }
- } else {
- // Brak aktywnego zalania; jeśli wcześniej było – możemy przejść do post-run
- if (id(pump_active)) {
- if (can_stop) {
- if (!id(post_run_running)) {
- ESP_LOGD("pump","Starting post-run (Vl=%.2f > %.2f && Vh=%.2f > %.2f)",
- Vl, (float)${v_dry_low}, Vh, (float)${v_clear_high});
- id(pump_off_delayed).execute();
- }
- } else {
- // (teoretycznie tu nie trafimy – bo gdyby jedna sonda była mokra, any_flood byłby true)
- if (!id(pump_switch).state) {
- id(pump_switch).turn_on();
- }
- }
- }
- }
- // --- DETEKCJA AWARII DOLNEJ SONDY ---
- // Kryterium: górna sonda stale zalana (flood_high_cond == true) przez N kolejnych cykli,
- // podczas gdy dolna nie sygnalizuje (flood_low_cond == false).
- // N * (interval) = czas opóźnienia zgłoszenia (tu 6 * 10 s = 60 s).
- const int FAULT_CYCLES = 3;
- if (flood_high_cond && !flood_low_cond) {
- id(low_probe_fault_timer)++;
- if (id(low_probe_fault_timer) > FAULT_CYCLES) {
- if (!id(low_probe_fault_state)) {
- id(low_probe_fault_state) = true;
- id(low_probe_fault).publish_state(true);
- ESP_LOGE("pump","LOW PROBE FAULT suspected: High flooded, low dry (Vl=%.2f, Vh=%.2f)", Vl, Vh);
- }
- }
- } else {
- // Warunki dla zalania niskiego lub brak wysokiego poziomu – reset licznika/awarii
- if (id(low_probe_fault_state)) {
- id(low_probe_fault_state) = false;
- id(low_probe_fault).publish_state(false);
- ESP_LOGI("pump","LOW PROBE FAULT cleared (Vl=%.2f, Vh=%.2f)", Vl, Vh);
- }
- id(low_probe_fault_timer) = 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment