gednet

Studnia odwadniająca sterowanie pompą

Jul 19th, 2025
332
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
YAML 8.67 KB | None | 0 0
  1. substitutions:
  2.   devicename: esp32-odwodnienie
  3.   v_flood_low:  "1.9"       # próg startu pompy
  4.   v_dry_low:    "2.5"       # próg pompa off
  5.   v_flood_high: "1.3"       # próg alarmu
  6.   v_clear_high: "2.9"       # anulowanie alarmu
  7.  
  8. esphome:
  9.   name: $devicename
  10.   on_boot:
  11.     priority: 600
  12.     then:
  13.       - output.turn_on: sonda_power
  14.       - delay: 80ms  
  15.       - component.update: adc_low
  16.       - delay: 20ms
  17.       - component.update: adc_high
  18.       - delay: 20ms
  19.       - output.turn_off: sonda_power
  20.       - script.execute: apply_pump_logic
  21.  
  22.  
  23. esp32:
  24.   board: esp32dev
  25.   framework:
  26.     type: arduino
  27.  
  28. # Enable logging
  29. logger:
  30.   level: DEBUG
  31.  
  32. web_server:
  33.     port: 80
  34.  
  35. time:
  36.   - platform: homeassistant
  37.     id: homeassistant_time
  38.  
  39. api:
  40. ota:
  41.   platform: esphome
  42.   password: "xxxxxxxxxxxxxxxxxxxxxxxxxx"
  43.  
  44. wifi:
  45.   ssid: !secret wifi_ssid
  46.   password: !secret wifi_password
  47.   manual_ip:
  48.     static_ip: 192.168.1.240
  49.     gateway: 192.168.1.1
  50.     subnet: 255.255.255.0
  51.  
  52.   ap:
  53.     ssid: "Esp32-Odwodnienie Fallback Hotspot"
  54.     password: "xxxxxxxxxx"
  55.  
  56. captive_portal:
  57. globals:
  58.   - id: pump_active
  59.     type: bool
  60.     restore_value: yes
  61.     initial_value: 'false'
  62.  
  63.   - id: post_run_running
  64.     type: bool
  65.     restore_value: no
  66.     initial_value: 'false'
  67.  
  68.   # Licznik kolejnych cykli, w których górna sonda wskazuje wodę a dolna NIE.
  69.   - id: low_probe_fault_timer
  70.     type: int
  71.     restore_value: no
  72.     initial_value: '0'
  73.  
  74.   # Aktualny stan awarii (publikowany przez binary_sensor)
  75.   - id: low_probe_fault_state
  76.     type: bool
  77.     restore_value: no
  78.     initial_value: 'false'
  79.  
  80. button:
  81.   - platform: restart
  82.     name: 'Kotlownia restart'
  83.  
  84. output:
  85.   - platform: gpio
  86.     id: sonda_power
  87.     pin: GPIO25
  88.   - platform: gpio
  89.     id: pump_output
  90.     pin:
  91.       number: GPIO23
  92.       mode: OUTPUT
  93.       inverted: false  
  94.  
  95. text_sensor:
  96.   - platform: version
  97.     name: ESPHome Version
  98.   - platform: wifi_info
  99.     ip_address:
  100.       name: $devicename IP
  101.     ssid:
  102.       name: $devicename SSID
  103.     bssid:
  104.       name: $devicename BSSID
  105.  
  106. sensor:
  107.   - platform: adc
  108.     id: adc_low
  109.     name: "Napięcie sondy (pompa)"
  110.     pin: GPIO36
  111.     attenuation: 11db
  112.     update_interval: never
  113.     accuracy_decimals: 1
  114.     unit_of_measurement: "V"
  115.     device_class: "voltage"
  116.     filters:
  117.       - lambda: |-
  118.           return floor(x * 10.0f) / 10.0f;
  119.  
  120.   - platform: adc
  121.     id: adc_high
  122.     name: "Napięcie sondy (alarm)"
  123.     pin: GPIO33
  124.     attenuation: 11db
  125.     update_interval: never
  126.     accuracy_decimals: 1
  127.     unit_of_measurement: "V"
  128.     device_class: "voltage"
  129.     filters:
  130.       - lambda: |-
  131.           return floor(x * 10.0f) / 10.0f;
  132.  
  133. binary_sensor:
  134.   - platform: template
  135.     name: "Zalanie (włącz pompę)"
  136.     id: flood_low
  137.     device_class: moisture
  138.     lambda: |-
  139.       static bool flooded = false;
  140.       const float V = id(adc_low).state;
  141.       if (flooded && V > ${v_dry_low})  flooded = false;
  142.       else if (!flooded && V < ${v_flood_low}) flooded = true;
  143.       return flooded;
  144.  
  145.   - platform: template
  146.     name: "Zalanie (alarm)"
  147.     id: flood_high
  148.     device_class: safety
  149.     lambda: |-
  150.       static bool high = false;
  151.       const float V = id(adc_high).state;
  152.       if (high && V > ${v_clear_high})  high = false;
  153.       else if (!high && V < ${v_flood_high}) high = true;
  154.       return high;
  155.     on_press:
  156.       - switch.turn_on: pump_switch             # spróbuj ratować
  157. #      - delay: 2s
  158. #      - homeassistant.service:
  159. #          service: notify.mobile_app_telefon
  160. #          data:
  161. #            message: "‼️ Wysoki poziom w studzience – pompa nie nadąża!"
  162.  
  163.   - platform: template
  164.     name: "Awaria sondy niskiej"
  165.     id: low_probe_fault
  166.     device_class: problem
  167.     entity_category: diagnostic
  168.     lambda: |-
  169.       return id(low_probe_fault_state);
  170.  
  171.   - platform: template
  172.     name: "Tryb dobiegu pompy"
  173.     lambda: |-
  174.       return id(post_run_running);
  175.     entity_category: diagnostic
  176.  
  177. interval:
  178.   - interval: 10s
  179.     then:
  180.       - output.turn_on: sonda_power
  181.       - delay: 80ms  
  182.       - component.update: adc_low
  183.       - delay: 20ms
  184.       - component.update: adc_high
  185.       - delay: 20ms
  186.       - output.turn_off: sonda_power
  187.       - script.execute: apply_pump_logic
  188.  
  189. switch:
  190.   - platform: output
  191.     name: "Pompa odpompowująca"
  192.     id: pump_switch
  193.     output: pump_output
  194.     restore_mode: RESTORE_DEFAULT_OFF
  195.  
  196. script:
  197.   - id: pump_off_delayed
  198.     mode: restart
  199.     then:
  200.       - lambda: |-
  201.           id(post_run_running) = true;
  202.           ESP_LOGD("pump","Post-run started");
  203.       - delay: 5min
  204.       - lambda: |-
  205.           float Vl = id(adc_low).state;
  206.           float Vh = id(adc_high).state;
  207.           bool both_dry = (Vl > ${v_dry_low}) && (Vh > ${v_clear_high});
  208.           if (both_dry) {
  209.             ESP_LOGI("pump","Post-run finished (Vl=%.2f V, Vh=%.2f V) -> pump OFF", Vl, Vh);
  210.             id(pump_switch).turn_off();
  211.             id(pump_active) = false;
  212.           } else {
  213.             ESP_LOGW("pump","Post-run aborted (Vl=%.2f V, Vh=%.2f V) -> keep pump ON", Vl, Vh);
  214.             // Pompa zostaje ON; wciąż zalanie lub powrót zalania
  215.           }
  216.           id(post_run_running) = false;
  217.  
  218.   # Główna logika – wywoływana na starcie i po każdym cyklu pomiarowym
  219.   - id: apply_pump_logic
  220.     mode: queued
  221.     then:
  222.       - lambda: |-
  223.           float Vl = id(adc_low).state;    // napięcie sondy sterującej pompą
  224.           float Vh = id(adc_high).state;   // napięcie sondy alarmowej (wysokiej)
  225.          
  226.           // Warunki zalania (dowolny poziom aktywny)
  227.           bool flood_low_cond  = (Vl < ${v_flood_low});
  228.           bool flood_high_cond = (Vh < ${v_flood_high});
  229.           bool any_flood = flood_low_cond || flood_high_cond;
  230.  
  231.           // Warunek pozwalający rozpocząć dobieganie: obie sondy wskazują "sucho"
  232.             // (Wyższe progi dla opuszczenia stanu zalania)
  233.           bool can_stop = (Vl > ${v_dry_low}) && (Vh > ${v_clear_high});
  234.  
  235.           // --- Sterowanie pompą ---
  236.           if (any_flood) {
  237.             // Wymuś / utrzymaj ON
  238.             if (!id(pump_switch).state) {
  239.               ESP_LOGW("pump","Forcing pump ON (Vl=%.2f < %.2f || Vh=%.2f < %.2f)",
  240.                         Vl, (float)${v_flood_low}, Vh, (float)${v_flood_high});
  241.               id(pump_switch).turn_on();
  242.             }
  243.             id(pump_active) = true;
  244.  
  245.             // Jeśli trwał post-run i znów pojawiło się zalanie – przerwij
  246.             if (id(post_run_running)) {
  247.               ESP_LOGD("pump","Cancelling post-run due to renewed flood (Vl=%.2f, Vh=%.2f)", Vl, Vh);
  248.               id(pump_off_delayed).stop();
  249.               id(post_run_running) = false;
  250.             }
  251.           } else {
  252.             // Brak aktywnego zalania; jeśli wcześniej było – możemy przejść do post-run
  253.             if (id(pump_active)) {
  254.               if (can_stop) {
  255.                 if (!id(post_run_running)) {
  256.                   ESP_LOGD("pump","Starting post-run (Vl=%.2f > %.2f && Vh=%.2f > %.2f)",
  257.                             Vl, (float)${v_dry_low}, Vh, (float)${v_clear_high});
  258.                   id(pump_off_delayed).execute();
  259.                 }
  260.               } else {
  261.                 // (teoretycznie tu nie trafimy – bo gdyby jedna sonda była mokra, any_flood byłby true)
  262.                 if (!id(pump_switch).state) {
  263.                   id(pump_switch).turn_on();
  264.                 }
  265.               }
  266.             }
  267.           }
  268.  
  269.           // --- DETEKCJA AWARII DOLNEJ SONDY ---
  270.           // Kryterium: górna sonda stale zalana (flood_high_cond == true) przez N kolejnych cykli,
  271.           // podczas gdy dolna nie sygnalizuje (flood_low_cond == false).
  272.           // N * (interval) = czas opóźnienia zgłoszenia (tu 6 * 10 s = 60 s).
  273.           const int FAULT_CYCLES = 3;
  274.  
  275.           if (flood_high_cond && !flood_low_cond) {
  276.             id(low_probe_fault_timer)++;
  277.             if (id(low_probe_fault_timer) > FAULT_CYCLES) {
  278.               if (!id(low_probe_fault_state)) {
  279.                 id(low_probe_fault_state) = true;
  280.                 id(low_probe_fault).publish_state(true);
  281.                 ESP_LOGE("pump","LOW PROBE FAULT suspected: High flooded, low dry (Vl=%.2f, Vh=%.2f)", Vl, Vh);
  282.               }
  283.             }
  284.           } else {
  285.             // Warunki dla zalania niskiego lub brak wysokiego poziomu – reset licznika/awarii
  286.             if (id(low_probe_fault_state)) {
  287.               id(low_probe_fault_state) = false;
  288.               id(low_probe_fault).publish_state(false);
  289.               ESP_LOGI("pump","LOW PROBE FAULT cleared (Vl=%.2f, Vh=%.2f)", Vl, Vh);
  290.             }
  291.             id(low_probe_fault_timer) = 0;
  292.           }
Advertisement
Add Comment
Please, Sign In to add comment