Letzter täglicher Build · 2 YAML-Konfigurationen
Build erfolgreich
Zuletzt gebaut: 26.09.2026, 15:13

pcb-back.png
23.8 KB

pcb-front.png
32.6 KB

pcb-layout.png
433.1 KB
1substitutions:
2 # -----------------------
3 # Geräte-Identifikation
4 # -----------------------
5 device_name: bewaesserung
6 device_friendly_name: "Bewässerung"
7
8
9 # -----------------------
10 # Friendly Names
11 # -----------------------
12 sensor1_name: "Feuchtigkeit Sensor 1"
13 sensor2_name: "Feuchtigkeit Sensor 2"
14 sensor3_name: "Feuchtigkeit Sensor 3"
15 sensor4_name: "Feuchtigkeit Sensor 4"
16
17 pumpe1_name: "Pumpe 1"
18 pumpe2_name: "Pumpe 2"
19 pumpe3_name: "Pumpe 3"
20 pumpe4_name: "Pumpe 4"
21
22 wasserschwimmer_name: "Wassertank Schwimmer"
23
24
25 # -----------------------
26 # Anzahl aktiver Pumpen
27 # -----------------------
28 anzahl_pumpen: "4" # 1-4: wie viele Pumpen verwendet werden
29
30 # -----------------------
31 # Timing (Fix)
32 # -----------------------
33 # Pause zwischen Pumpen im Auto-Modus
34 pause_zwischen_pumpen: "2s"
35
36 # Sensor Update Intervall
37 sensor_update_interval: "10s"
38
39
40 # -----------------------
41 # Standardwerte (Für Number / in HA änderbar)
42 # -----------------------
43 # Schwellwerte für Sensoren (in Volt)
44 # Kapazitive Sensoren: Hoher Wert = trocken (ca. 2V), niedriger Wert = feucht (ca. 0,6V)
45 # Schwellwert bei ca. 1,5V = bewässern wenn trockener als dieser Wert
46 initial_threshold_sensor1: "1.5"
47 initial_threshold_sensor2: "1.5"
48 initial_threshold_sensor3: "1.5"
49 initial_threshold_sensor4: "1.5"
50
51 # Pumpendauer für Auto-Modus (Sekunden)
52 initial_pumpen_dauer_auto: "10"
53
54 # Pumpendauer bei Set-Button Kurzdruck (Sekunden)
55 initial_pumpen_dauer_set: "5"
56
57 # Max. Laufzeit pro Pumpe (Timeout in Sekunden)
58 initial_max_laufzeit: "60"
59
60 # Auto-Modus Prüfintervall (Sekunden)
61 initial_auto_intervall: "300" # 5 Minuten
62
63
64
65 # -----------------------
66 # Sicherheit & Netzwerk
67 # -----------------------
68 wifi_ssid: !secret wifi_ssid
69 wifi_password: !secret wifi_password
70 ap_ssid: "Bewaesserung Fallback"
71 ap_password: !secret ap_password
72
73 api_encryption_key: !secret api_encryption_key
74 ota_password: !secret ota_password
75
76
77 # -----------------------
78 # I2C Adressen
79 # -----------------------
80 mcp23017_address: "0x20"
81 ads1115_address: "0x48"
82
83
84 # -----------------------
85 # Hardware GPIO Pins
86 # -----------------------
87 # I2C Bus
88 sda_pin: GPIO4
89 scl_pin: GPIO5
90
91 # Buttons
92 pin_mode_button: GPIO14
93 pin_set_button: GPIO16
94
95
96 # -----------------------
97 # MCP23017 Pin-Mapping
98 # -----------------------
99 # Wasserschwimmer
100 pin_wasserschwimmer: "7"
101
102 # Pumpen (MOSFETs)
103 pin_pumpe1: "8"
104 pin_pumpe2: "9"
105 pin_pumpe3: "10"
106 pin_pumpe4: "11"
107
108
109 # -----------------------
110 # Konfiguration ENDE
111 # -----------------------
112
113
114esphome:
115 name: ${device_name}
116 friendly_name: ${device_friendly_name}
117 comment: "Automatische Bewässerung mit 4 Bodenfeuchtesensoren und 4 Pumpen"
118 project:
119 name: "smarthomeyourself.bewaesserung"
120 version: "1.0.0"
121
122esp8266:
123 board: esp01_1m
124
125logger:
126 level: INFO
127
128api:
129 encryption:
130 key: ${api_encryption_key}
131 # ⚠️ WICHTIG für autonomen Betrieb (ohne Home Assistant):
132 # Wenn die API nicht mit einem Client verbunden werden soll,
133 # muss der reboot_timeout auf 0s gesetzt werden, sonst startet
134 # das Gerät nach 15min automatisch neu!
135 # Für autonomen Betrieb auskommentieren:
136 # reboot_timeout: 0s
137
138ota:
139 - platform: esphome
140 password: ${ota_password}
141
142# ⚠️ OPTIONAL: Web-Interface für autonomen Betrieb
143# Ermöglicht lokalen Zugriff auf Sensoren/Schalter ohne Home Assistant
144# Auskommentieren um Web-Interface zu aktivieren:
145# web_server:
146# port: 80
147# # Auth ist optional - für ungeschützten Zugriff weglassen:
148# auth:
149# username: admin
150# password: !secret web_server_password # In secrets.yaml definieren
151
152wifi:
153 ssid: ${wifi_ssid}
154 password: ${wifi_password}
155 min_auth_mode: WPA2
156 # ⚠️ WICHTIG für autonomen Betrieb (ohne WiFi):
157 # Wenn kein WiFi verfügbar ist, startet das Gerät nach 15min neu.
158 # Für Betrieb ohne WiFi (nur Access Point) auskommentieren:
159 # reboot_timeout: 0s
160
161 ap:
162 ssid: ${ap_ssid}
163 password: ${ap_password}
164
165captive_portal:
166
167# I2C Bus
168i2c:
169 sda: ${sda_pin}
170 scl: ${scl_pin}
171 id: i2c_component
172 scan: true
173
174# 16x Binary GPIO Portexpander
175mcp23017:
176 - id: mcp1
177 address: ${mcp23017_address}
178
179# 4x Analog Input Portexpander
180ads1115:
181 - address: ${ads1115_address}
182 id: ads1
183
184# Globale Variablen
185globals:
186 # Aktuelle Pumpe für Set-Button (1-4)
187 - id: current_pump
188 type: int
189 restore_value: true
190 initial_value: '1'
191
192
193
194
195# ============================================================================
196# SWITCHES
197# ============================================================================
198
199# Interne GPIO Switches (nicht für HA freigegeben)
200# Werden nur über Template Switches mit Sicherheitsprüfung gesteuert
201switch:
202 - platform: gpio
203 id: pumpe1_gpio
204 internal: true
205 restore_mode: ALWAYS_OFF
206 pin:
207 mcp23xxx: mcp1
208 number: ${pin_pumpe1}
209 mode: OUTPUT
210
211 - platform: gpio
212 id: pumpe2_gpio
213 internal: true
214 restore_mode: ALWAYS_OFF
215 pin:
216 mcp23xxx: mcp1
217 number: ${pin_pumpe2}
218 mode: OUTPUT
219
220 - platform: gpio
221 id: pumpe3_gpio
222 internal: true
223 restore_mode: ALWAYS_OFF
224 pin:
225 mcp23xxx: mcp1
226 number: ${pin_pumpe3}
227 mode: OUTPUT
228
229 - platform: gpio
230 id: pumpe4_gpio
231 internal: true
232 restore_mode: ALWAYS_OFF
233 pin:
234 mcp23xxx: mcp1
235 number: ${pin_pumpe4}
236 mode: OUTPUT
237
238 # Template Switches mit Sicherheitsprüfung (für HA freigegeben)
239 # Prüfen Wasserstand + Interlock vor Einschalten
240 - platform: template
241 name: ${pumpe1_name}
242 id: pumpe1
243 icon: "mdi:water-pump"
244 optimistic: false
245 turn_on_action:
246 - script.execute: pumpe1_an
247 turn_off_action:
248 - script.execute: pumpe1_aus
249 lambda: |-
250 return id(pumpe1_gpio).state;
251
252 - platform: template
253 name: ${pumpe2_name}
254 id: pumpe2
255 icon: "mdi:water-pump"
256 optimistic: false
257 turn_on_action:
258 - script.execute: pumpe2_an
259 turn_off_action:
260 - script.execute: pumpe2_aus
261 lambda: |-
262 return id(pumpe2_gpio).state;
263
264 - platform: template
265 name: ${pumpe3_name}
266 id: pumpe3
267 icon: "mdi:water-pump"
268 optimistic: false
269 turn_on_action:
270 - script.execute: pumpe3_an
271 turn_off_action:
272 - script.execute: pumpe3_aus
273 lambda: |-
274 return id(pumpe3_gpio).state;
275
276 - platform: template
277 name: ${pumpe4_name}
278 id: pumpe4
279 icon: "mdi:water-pump"
280 optimistic: false
281 turn_on_action:
282 - script.execute: pumpe4_an
283 turn_off_action:
284 - script.execute: pumpe4_aus
285 lambda: |-
286 return id(pumpe4_gpio).state;
287
288
289
290# Gain Messbereich (±V) Auflösung (in µV)
291# 6.144 ±0.256 V 7.8125
292# 4.096 ±0.512 V 15.625
293# 2.048 ±1.024 V 31.25
294# 1.024 ±2.048 V 62.5
295# 0.512 ±4.096 V 125
296# 0.256 ±6.144 V 250
297
298sensor:
299 # ═══════════════════════════════════════════════════════════════════════
300 # Bodenfeuchtesensoren (ADS1115 4x 16-Bit Analog Inputs)
301 # ═══════════════════════════════════════════════════════════════════════
302 # Gain 6.144 = ±6.144V Messbereich (unterstützt 3.3V und 5V Sensoren)
303 #
304 # ⚙️ WICHTIG: Jumper J6 auf der PCB (Sensor-Spannungswahl):
305 # - Pin 1-2: Sensoren mit 3.3V versorgen → Messbereich 0-3.3V
306 # - Pin 2-3 (Standard): Sensoren mit 5V versorgen → Messbereich 0-5V
307 # ═══════════════════════════════════════════════════════════════════════
308
309 - platform: ads1115
310 ads1115_id: ads1
311 gain: 6.144
312 multiplexer: 'A0_GND'
313 name: ${sensor1_name}
314 id: feuchtigkeit1
315 update_interval: ${sensor_update_interval}
316 unit_of_measurement: "V"
317 accuracy_decimals: 3
318 device_class: voltage
319 state_class: measurement
320 filters:
321 - sliding_window_moving_average:
322 window_size: 5
323 send_every: 1
324
325 - platform: ads1115
326 ads1115_id: ads1
327 gain: 6.144
328 multiplexer: 'A1_GND'
329 name: ${sensor2_name}
330 id: feuchtigkeit2
331 update_interval: ${sensor_update_interval}
332 unit_of_measurement: "V"
333 accuracy_decimals: 3
334 device_class: voltage
335 state_class: measurement
336 filters:
337 - sliding_window_moving_average:
338 window_size: 5
339 send_every: 1
340
341 - platform: ads1115
342 ads1115_id: ads1
343 gain: 6.144
344 multiplexer: 'A2_GND'
345 name: ${sensor3_name}
346 id: feuchtigkeit3
347 update_interval: ${sensor_update_interval}
348 unit_of_measurement: "V"
349 accuracy_decimals: 3
350 device_class: voltage
351 state_class: measurement
352 filters:
353 - sliding_window_moving_average:
354 window_size: 5
355 send_every: 1
356
357 - platform: ads1115
358 ads1115_id: ads1
359 gain: 6.144
360 multiplexer: 'A3_GND'
361 name: ${sensor4_name}
362 id: feuchtigkeit4
363 update_interval: ${sensor_update_interval}
364 unit_of_measurement: "V"
365 accuracy_decimals: 3
366 device_class: voltage
367 state_class: measurement
368 filters:
369 - sliding_window_moving_average:
370 window_size: 5
371 send_every: 1
372
373 # WiFi Signal
374 - platform: wifi_signal
375 name: "WiFi Signal"
376 update_interval: 60s
377
378 # Uptime
379 - platform: uptime
380 name: "Uptime"
381 update_interval: 60s
382
383
384# ============================================================================
385# BINARY SENSOREN
386# ============================================================================
387
388binary_sensor:
389 # Wassertank Schwimmer (Füllstand-Sensor)
390 # ON = Wasser verfügbar, OFF = Tank leer
391 - platform: gpio
392 name: ${wasserschwimmer_name}
393 id: wasserstand
394 device_class: moisture
395 pin:
396 mcp23xxx: mcp1
397 number: ${pin_wasserschwimmer}
398 mode: INPUT_PULLUP
399 inverted: true
400 filters:
401 - delayed_on: 100ms
402 - delayed_off: 100ms
403 on_press:
404 then:
405 - logger.log: "✅ Wassertank: VOLL"
406 # Wenn im Notaus-Modus: Automatisch zurück zu Auto
407 - if:
408 condition:
409 lambda: |-
410 std::string mode = id(betriebsmodus).current_option();
411 return mode == "Notaus";
412 then:
413 - select.set:
414 id: betriebsmodus
415 option: "Auto"
416 - logger.log: "✅ Notaus beendet - Wechsel zu Auto-Modus"
417 on_release:
418 then:
419 - script.execute: notaus
420 - logger.log:
421 format: "🚨 NOTAUS: Wassertank LEER!"
422 level: ERROR
423
424 # Mode-Button (Betriebsmodus wechseln: Auto ↔ Manuell)
425 # Hardware-Pullup (R7 10k) auf PCB vorhanden
426 # Sperre: Deaktiviert bei leerem Wassertank
427 - platform: gpio
428 name: "Mode-Button"
429 id: mode_button
430 pin:
431 number: ${pin_mode_button}
432 mode: INPUT
433 inverted: true
434 filters:
435 - delayed_on: 50ms
436 - delayed_off: 50ms
437 on_press:
438 - if:
439 condition:
440 binary_sensor.is_on: wasserstand
441 then:
442 - script.execute: switch_mode
443 else:
444 - logger.log:
445 format: "🚫 Mode-Button gesperrt - Wassertank leer!"
446 level: WARN
447
448 # Set-Button (Pumpen manuell aktivieren)
449 # Hardware-Pullup (R11 10k) auf PCB vorhanden
450 # Kurzdruck (<500ms): nächste Pumpe für X Sekunden
451 # Langdruck (>1s): Pumpe aktivieren solange gedrückt
452 - platform: gpio
453 name: "Set-Button"
454 id: set_button
455 pin:
456 number: ${pin_set_button}
457 mode: INPUT
458 inverted: true
459 filters:
460 - delayed_on: 50ms
461 - delayed_off: 50ms
462 # Kurzdruck: < 500ms
463 on_click:
464 min_length: 50ms
465 max_length: 500ms
466 then:
467 - script.execute: set_button_short
468 # Langdruck: > 1s, aktiviert Pumpe solange gedrückt
469 on_multi_click:
470 - timing:
471 - ON for at least 1s
472 then:
473 - script.execute: set_button_long
474
475 # Status
476 - platform: status
477 name: "Status"
478
479
480 # Unbenutzte MCP23017 GPIOs neutralisieren
481 - platform: gpio
482 name: "GPA0"
483 pin: { mcp23xxx: mcp1, number: 0, mode: INPUT_PULLUP }
484 internal: true
485 - platform: gpio
486 name: "GPA1"
487 pin: { mcp23xxx: mcp1, number: 1, mode: INPUT_PULLUP }
488 internal: true
489 - platform: gpio
490 name: "GPA2"
491 pin: { mcp23xxx: mcp1, number: 2, mode: INPUT_PULLUP }
492 internal: true
493 - platform: gpio
494 name: "GPA3"
495 pin: { mcp23xxx: mcp1, number: 3, mode: INPUT_PULLUP }
496 internal: true
497 - platform: gpio
498 name: "GPA4"
499 pin: { mcp23xxx: mcp1, number: 4, mode: INPUT_PULLUP }
500 internal: true
501 - platform: gpio
502 name: "GPA5"
503 pin: { mcp23xxx: mcp1, number: 5, mode: INPUT_PULLUP }
504 internal: true
505 - platform: gpio
506 name: "GPA6"
507 pin: { mcp23xxx: mcp1, number: 6, mode: INPUT_PULLUP }
508 internal: true
509 - platform: gpio
510 name: "GPB4"
511 pin: { mcp23xxx: mcp1, number: 12, mode: INPUT_PULLUP }
512 internal: true
513 - platform: gpio
514 name: "GPB5"
515 pin: { mcp23xxx: mcp1, number: 13, mode: INPUT_PULLUP }
516 internal: true
517 - platform: gpio
518 name: "GPB6"
519 pin: { mcp23xxx: mcp1, number: 14, mode: INPUT_PULLUP }
520 internal: true
521 - platform: gpio
522 name: "GPB7"
523 pin: { mcp23xxx: mcp1, number: 15, mode: INPUT_PULLUP }
524 internal: true
525
526# ============================================================================
527# TEXT SENSOREN
528# ============================================================================
529
530text_sensor:
531 - platform: version
532 name: "ESPHome Version"
533 hide_timestamp: true
534
535 - platform: wifi_info
536 ip_address:
537 name: "IP Adresse"
538 ssid:
539 name: "SSID"
540 mac_address:
541 name: "MAC Adresse"
542
543# ============================================================================
544# NUMBER INPUTS (konfigurierbare Werte)
545# ============================================================================
546
547number:
548 # Schwellwerte für Bodenfeuchtesensoren (in Volt)
549 - platform: template
550 name: "Schwellwert Sensor 1"
551 id: threshold_sensor1
552 icon: "mdi:water-percent"
553 unit_of_measurement: "V"
554 mode: box
555 min_value: 0.0
556 max_value: 6.0
557 step: 0.1
558 initial_value: ${initial_threshold_sensor1}
559 optimistic: true
560 restore_value: true
561
562 - platform: template
563 name: "Schwellwert Sensor 2"
564 id: threshold_sensor2
565 icon: "mdi:water-percent"
566 unit_of_measurement: "V"
567 mode: box
568 min_value: 0.0
569 max_value: 6.0
570 step: 0.1
571 initial_value: ${initial_threshold_sensor2}
572 optimistic: true
573 restore_value: true
574
575 - platform: template
576 name: "Schwellwert Sensor 3"
577 id: threshold_sensor3
578 icon: "mdi:water-percent"
579 unit_of_measurement: "V"
580 mode: box
581 min_value: 0.0
582 max_value: 6.0
583 step: 0.1
584 initial_value: ${initial_threshold_sensor3}
585 optimistic: true
586 restore_value: true
587
588 - platform: template
589 name: "Schwellwert Sensor 4"
590 id: threshold_sensor4
591 icon: "mdi:water-percent"
592 unit_of_measurement: "V"
593 mode: box
594 min_value: 0.0
595 max_value: 6.0
596 step: 0.1
597 initial_value: ${initial_threshold_sensor4}
598 optimistic: true
599 restore_value: true
600
601 # Pumpendauer für Auto-Modus
602 - platform: template
603 name: "Pumpendauer (Auto-Modus)"
604 id: pumpen_dauer_auto
605 icon: "mdi:timer"
606 unit_of_measurement: "s"
607 mode: box
608 min_value: 1
609 max_value: 60
610 step: 1
611 initial_value: ${initial_pumpen_dauer_auto}
612 optimistic: true
613 restore_value: true
614
615 # Pumpendauer bei Set-Button Kurzdruck
616 - platform: template
617 name: "Pumpendauer (Set-Button)"
618 id: pumpen_dauer_set
619 icon: "mdi:timer"
620 unit_of_measurement: "s"
621 mode: box
622 min_value: 1
623 max_value: 30
624 step: 1
625 initial_value: ${initial_pumpen_dauer_set}
626 optimistic: true
627 restore_value: true
628
629 # Max. Laufzeit (Timeout)
630 - platform: template
631 name: "Max. Laufzeit (Timeout)"
632 id: max_laufzeit
633 icon: "mdi:timer-alert"
634 unit_of_measurement: "s"
635 mode: box
636 min_value: 10
637 max_value: 300
638 step: 5
639 initial_value: ${initial_max_laufzeit}
640 optimistic: true
641 restore_value: true
642
643 # Auto-Modus Prüfintervall
644 - platform: template
645 name: "Auto-Modus Intervall"
646 id: auto_intervall
647 icon: "mdi:clock-outline"
648 unit_of_measurement: "s"
649 mode: box
650 min_value: 60
651 max_value: 3600
652 step: 60
653 initial_value: ${initial_auto_intervall}
654 optimistic: true
655 restore_value: true
656
657# ============================================================================
658# SELECT (Betriebsmodus)
659# ============================================================================
660
661select:
662 - platform: template
663 name: "Betriebsmodus"
664 id: betriebsmodus
665 icon: "mdi:cog"
666 options:
667 - "Manuell"
668 - "Auto"
669 - "Notaus"
670 initial_option: "Auto"
671 optimistic: true
672 restore_value: true
673 on_value:
674 then:
675 - logger.log:
676 format: "Betriebsmodus gewechselt: %s"
677 args: ['x.c_str()']
678 # Bei Wechsel zu Notaus: Alle Pumpen ausschalten
679 - if:
680 condition:
681 lambda: return x == "Notaus";
682 then:
683 - switch.turn_off: pumpe1_gpio
684 - switch.turn_off: pumpe2_gpio
685 - switch.turn_off: pumpe3_gpio
686 - switch.turn_off: pumpe4_gpio
687 - logger.log:
688 format: "🚨 NOTAUS aktiviert - Alle Pumpen gestoppt"
689 level: WARN
690
691# ============================================================================
692# BUTTONS
693# ============================================================================
694
695button:
696 # Mode-Button (virtuell für HA)
697 # Sperre: Deaktiviert bei leerem Wassertank
698 - platform: template
699 name: "Mode-Button"
700 icon: "mdi:format-list-bulleted"
701 on_press:
702 - if:
703 condition:
704 binary_sensor.is_on: wasserstand
705 then:
706 - script.execute: switch_mode
707 else:
708 - logger.log:
709 format: "🚫 Mode-Button gesperrt - Wassertank leer!"
710 level: WARN
711
712 # Set-Button (virtuell für HA)
713 - platform: template
714 name: "Set-Button"
715 icon: "mdi:rotate-right"
716 on_press:
717 - script.execute: set_button_short
718
719 # Notaus Button
720 - platform: template
721 name: "🚨 NOTAUS"
722 icon: "mdi:alert-octagon"
723 on_press:
724 then:
725 - script.execute: notaus
726 - logger.log:
727 format: "🚨 NOTAUS manuell ausgelöst!"
728 level: WARN
729
730 # Neustart
731 - platform: restart
732 name: "Neustart"
733 icon: "mdi:restart"
734
735# ============================================================================
736# INTERVAL (Automatik-Steuerung)
737# ============================================================================
738
739interval:
740 # Automatik-Steuerung (prüft Sensoren und bewässert bei Bedarf)
741 - interval: 60s
742 then:
743 - script.execute: automatik_steuerung
744
745
746
747
748
749
750# ============================================================================
751# SCRIPTS
752# ============================================================================
753
754script:
755 # ===================================
756 # NOTAUS - Modus auf Notaus setzen
757 # ===================================
758 - id: notaus
759 mode: restart
760 then:
761 - select.set:
762 id: betriebsmodus
763 option: "Notaus"
764 - logger.log:
765 format: "🚨 NOTAUS aktiviert!"
766 level: ERROR
767
768 # ===================================
769 # INTERLOCK - Andere Pumpen abschalten
770 # ===================================
771 - id: interlock_off
772 parameters:
773 except_pump: int
774 then:
775 - lambda: |-
776 if (except_pump != 1) id(pumpe1_gpio).turn_off();
777 if (except_pump != 2) id(pumpe2_gpio).turn_off();
778 if (except_pump != 3) id(pumpe3_gpio).turn_off();
779 if (except_pump != 4) id(pumpe4_gpio).turn_off();
780
781 # ===================================
782 # PUMPEN AN/AUS mit Sicherheitsprüfung
783 # ===================================
784
785 # Pumpe 1
786 - id: pumpe1_an
787 mode: restart
788 then:
789 - if:
790 condition:
791 and:
792 - binary_sensor.is_on: wasserstand
793 - lambda: |-
794 std::string mode = id(betriebsmodus).current_option();
795 return mode != "Notaus";
796 then:
797 - script.execute:
798 id: interlock_off
799 except_pump: 1
800 - switch.turn_on: pumpe1_gpio
801 - logger.log: "💧 Pumpe 1 EIN"
802 else:
803 - logger.log:
804 format: "🚨 Pumpe 1 BLOCKIERT - Kein Wasser oder Notaus aktiv!"
805 level: ERROR
806
807 - id: pumpe1_aus
808 then:
809 - switch.turn_off: pumpe1_gpio
810 - logger.log: "⚫ Pumpe 1 AUS"
811
812 # Pumpe 2
813 - id: pumpe2_an
814 mode: restart
815 then:
816 - if:
817 condition:
818 and:
819 - binary_sensor.is_on: wasserstand
820 - lambda: |-
821 std::string mode = id(betriebsmodus).current_option();
822 return mode != "Notaus";
823 then:
824 - script.execute:
825 id: interlock_off
826 except_pump: 2
827 - switch.turn_on: pumpe2_gpio
828 - logger.log: "💧 Pumpe 2 EIN"
829 else:
830 - logger.log:
831 format: "🚨 Pumpe 2 BLOCKIERT - Kein Wasser oder Notaus aktiv!"
832 level: ERROR
833
834 - id: pumpe2_aus
835 then:
836 - switch.turn_off: pumpe2_gpio
837 - logger.log: "⚫ Pumpe 2 AUS"
838
839 # Pumpe 3
840 - id: pumpe3_an
841 mode: restart
842 then:
843 - if:
844 condition:
845 and:
846 - binary_sensor.is_on: wasserstand
847 - lambda: |-
848 std::string mode = id(betriebsmodus).current_option();
849 return mode != "Notaus";
850 then:
851 - script.execute:
852 id: interlock_off
853 except_pump: 3
854 - switch.turn_on: pumpe3_gpio
855 - logger.log: "💧 Pumpe 3 EIN"
856 else:
857 - logger.log:
858 format: "🚨 Pumpe 3 BLOCKIERT - Kein Wasser oder Notaus aktiv!"
859 level: ERROR
860
861 - id: pumpe3_aus
862 then:
863 - switch.turn_off: pumpe3_gpio
864 - logger.log: "⚫ Pumpe 3 AUS"
865
866 # Pumpe 4
867 - id: pumpe4_an
868 mode: restart
869 then:
870 - if:
871 condition:
872 and:
873 - binary_sensor.is_on: wasserstand
874 - lambda: |-
875 std::string mode = id(betriebsmodus).current_option();
876 return mode != "Notaus";
877 then:
878 - script.execute:
879 id: interlock_off
880 except_pump: 4
881 - switch.turn_on: pumpe4_gpio
882 - logger.log: "💧 Pumpe 4 EIN"
883 else:
884 - logger.log:
885 format: "🚨 Pumpe 4 BLOCKIERT - Kein Wasser oder Notaus aktiv!"
886 level: ERROR
887
888 - id: pumpe4_aus
889 then:
890 - switch.turn_off: pumpe4_gpio
891 - logger.log: "⚫ Pumpe 4 AUS"
892
893 # ===================================
894 # PUMPEN mit Timeout-Steuerung
895 # ===================================
896
897 # Pumpe für bestimmte Zeit aktivieren (mit Timeout-Schutz)
898 - id: pumpe_timed
899 mode: queued
900 max_runs: 4
901 parameters:
902 pump_nr: int
903 duration: int
904 then:
905 - lambda: |-
906 int max_time = (int)id(max_laufzeit).state;
907 int actual_duration = (duration > max_time) ? max_time : duration;
908
909 ESP_LOGI("pumpe", "Aktiviere Pumpe %d für %ds (Max: %ds)", pump_nr, actual_duration, max_time);
910
911 // Pumpe einschalten
912 if (pump_nr == 1) id(pumpe1_an).execute();
913 else if (pump_nr == 2) id(pumpe2_an).execute();
914 else if (pump_nr == 3) id(pumpe3_an).execute();
915 else if (pump_nr == 4) id(pumpe4_an).execute();
916
917 # Non-blocking delay
918 - delay: !lambda "return duration * 1000;"
919
920 - lambda: |-
921 // Pumpe ausschalten
922 if (pump_nr == 1) id(pumpe1_aus).execute();
923 else if (pump_nr == 2) id(pumpe2_aus).execute();
924 else if (pump_nr == 3) id(pumpe3_aus).execute();
925 else if (pump_nr == 4) id(pumpe4_aus).execute();
926
927 # ===================================
928 # MODE-BUTTON: Betriebsmodus wechseln
929 # ===================================
930 - id: switch_mode
931 then:
932 - lambda: |-
933 std::string current = id(betriebsmodus).current_option();
934 std::string new_mode;
935
936 // Nur zwischen Auto und Manuell wechseln (Notaus separat)
937 if (current == "Manuell" || current == "Notaus") {
938 new_mode = "Auto";
939 } else {
940 new_mode = "Manuell";
941 }
942
943 id(betriebsmodus).publish_state(new_mode);
944 ESP_LOGI("mode", "Betriebsmodus: %s → %s", current.c_str(), new_mode.c_str());
945
946 # ===================================
947 # SET-BUTTON: Kurzdruck
948 # ===================================
949 - id: set_button_short
950 mode: single
951 then:
952 - lambda: |-
953 int anzahl = ${anzahl_pumpen};
954
955 // Nächste Pumpe
956 id(current_pump)++;
957 if (id(current_pump) > anzahl) {
958 id(current_pump) = 1;
959 }
960
961 ESP_LOGI("set_button", "🔄 Wechsel zu Pumpe %d", id(current_pump));
962
963 - script.execute:
964 id: pumpe_timed
965 pump_nr: !lambda "return id(current_pump);"
966 duration: !lambda "return (int)id(pumpen_dauer_set).state;"
967
968 # ===================================
969 # SET-BUTTON: Langdruck (solange gedrückt)
970 # ===================================
971 - id: set_button_long
972 mode: restart
973 then:
974 - logger.log:
975 format: "⏳ Pumpe %d aktiviert (solange gedrückt)"
976 args: ['id(current_pump)']
977
978 - lambda: |-
979 int pump = id(current_pump);
980 if (pump == 1) id(pumpe1_an).execute();
981 else if (pump == 2) id(pumpe2_an).execute();
982 else if (pump == 3) id(pumpe3_an).execute();
983 else if (pump == 4) id(pumpe4_an).execute();
984
985 # Warte bis Button losgelassen oder Timeout erreicht (non-blocking)
986 - wait_until:
987 timeout: !lambda "return (int)id(max_laufzeit).state * 1000;"
988 condition:
989 binary_sensor.is_off: set_button
990
991 # Timeout-Warnung falls erreicht
992 - if:
993 condition:
994 binary_sensor.is_on: set_button
995 then:
996 - logger.log:
997 format: "⚠️ Timeout erreicht - Pumpe wird gestoppt"
998 level: WARN
999
1000 # Button wurde losgelassen oder Timeout → Pumpe ausschalten
1001 - lambda: |-
1002 int pump = id(current_pump);
1003 if (pump == 1) id(pumpe1_aus).execute();
1004 else if (pump == 2) id(pumpe2_aus).execute();
1005 else if (pump == 3) id(pumpe3_aus).execute();
1006 else if (pump == 4) id(pumpe4_aus).execute();
1007
1008 - logger.log: "✅ Set-Button losgelassen / Pumpe gestoppt"
1009
1010 # ===================================
1011 # AUTOMATIK-STEUERUNG
1012 # ===================================
1013 - id: automatik_steuerung
1014 mode: single
1015 then:
1016 # Nur im Auto-Modus und nach Intervall ausführen
1017 - if:
1018 condition:
1019 lambda: |-
1020 // Nur im Auto-Modus
1021 std::string mode = id(betriebsmodus).current_option();
1022 if (mode != "Auto") {
1023 return false;
1024 }
1025
1026 // Prüfe Intervall
1027 static unsigned long last_check = 0;
1028 unsigned long now = millis();
1029 unsigned long interval = (unsigned long)id(auto_intervall).state * 1000;
1030
1031 if (now - last_check < interval) {
1032 return false;
1033 }
1034 last_check = now;
1035 return true;
1036 then:
1037 - logger.log: "═══════════════════════════════════"
1038 - logger.log: "🔍 Automatik-Prüfung gestartet"
1039
1040 # Prüfe Wasserstand
1041 - if:
1042 condition:
1043 binary_sensor.is_off: wasserstand
1044 then:
1045 - logger.log:
1046 format: "⚠️ Kein Wasser im Tank - Abbruch"
1047 level: WARN
1048 - script.stop: automatik_steuerung
1049
1050 # Sensor 1 prüfen
1051 - script.execute: auto_check_sensor_1
1052 - delay: ${pause_zwischen_pumpen}
1053
1054 # Sensor 2 prüfen
1055 - script.execute: auto_check_sensor_2
1056 - delay: ${pause_zwischen_pumpen}
1057
1058 # Sensor 3 prüfen (wenn aktiviert)
1059 - if:
1060 condition:
1061 lambda: return ${anzahl_pumpen} >= 3;
1062 then:
1063 - script.execute: auto_check_sensor_3
1064 - delay: ${pause_zwischen_pumpen}
1065
1066 # Sensor 4 prüfen (wenn aktiviert)
1067 - if:
1068 condition:
1069 lambda: return ${anzahl_pumpen} >= 4;
1070 then:
1071 - script.execute: auto_check_sensor_4
1072
1073 - logger.log: "✅ Automatik-Prüfung abgeschlossen"
1074 - logger.log: "═══════════════════════════════════"
1075
1076 # ===================================
1077 # AUTOMATIK: Einzelne Sensor-Checks
1078 # ===================================
1079
1080 # Sensor 1
1081 - id: auto_check_sensor_1
1082 mode: single
1083 then:
1084 - lambda: |-
1085 float sensor_value = id(feuchtigkeit1).state;
1086 float threshold = id(threshold_sensor1).state;
1087
1088 ESP_LOGI("auto", "📊 Sensor 1: %.3fV (Schwelle: %.2fV)", sensor_value, threshold);
1089
1090 if (isnan(sensor_value)) {
1091 ESP_LOGW("auto", "⚠️ Sensor 1: Fehler/NaN - KEINE Bewässerung!");
1092 return;
1093 }
1094
1095 // Kapazitive Sensoren: Hoher Wert = trocken, niedriger Wert = feucht
1096 if (sensor_value > threshold) {
1097 ESP_LOGI("auto", "💧 Sensor 1: %.3fV > %.2fV → ZU TROCKEN, bewässere!", sensor_value, threshold);
1098 id(pumpe_timed).execute(1, (int)id(pumpen_dauer_auto).state);
1099 } else {
1100 ESP_LOGI("auto", "✅ Sensor 1: %.3fV ≤ %.2fV - ausreichend feucht", sensor_value, threshold);
1101 }
1102
1103 # Sensor 2
1104 - id: auto_check_sensor_2
1105 mode: single
1106 then:
1107 - lambda: |-
1108 float sensor_value = id(feuchtigkeit2).state;
1109 float threshold = id(threshold_sensor2).state;
1110
1111 ESP_LOGI("auto", "📊 Sensor 2: %.3fV (Schwelle: %.2fV)", sensor_value, threshold);
1112
1113 if (isnan(sensor_value)) {
1114 ESP_LOGW("auto", "⚠️ Sensor 2: Fehler/NaN - KEINE Bewässerung!");
1115 return;
1116 }
1117
1118 // Kapazitive Sensoren: Hoher Wert = trocken, niedriger Wert = feucht
1119 if (sensor_value > threshold) {
1120 ESP_LOGI("auto", "💧 Sensor 2: %.3fV > %.2fV → ZU TROCKEN, bewässere!", sensor_value, threshold);
1121 id(pumpe_timed).execute(2, (int)id(pumpen_dauer_auto).state);
1122 } else {
1123 ESP_LOGI("auto", "✅ Sensor 2: %.3fV ≤ %.2fV - ausreichend feucht", sensor_value, threshold);
1124 }
1125
1126 # Sensor 3
1127 - id: auto_check_sensor_3
1128 mode: single
1129 then:
1130 - lambda: |-
1131 float sensor_value = id(feuchtigkeit3).state;
1132 float threshold = id(threshold_sensor3).state;
1133
1134 ESP_LOGI("auto", "📊 Sensor 3: %.3fV (Schwelle: %.2fV)", sensor_value, threshold);
1135
1136 if (isnan(sensor_value)) {
1137 ESP_LOGW("auto", "⚠️ Sensor 3: Fehler/NaN - KEINE Bewässerung!");
1138 return;
1139 }
1140
1141 // Kapazitive Sensoren: Hoher Wert = trocken, niedriger Wert = feucht
1142 if (sensor_value > threshold) {
1143 ESP_LOGI("auto", "💧 Sensor 3: %.3fV > %.2fV → ZU TROCKEN, bewässere!", sensor_value, threshold);
1144 id(pumpe_timed).execute(3, (int)id(pumpen_dauer_auto).state);
1145 } else {
1146 ESP_LOGI("auto", "✅ Sensor 3: %.3fV ≤ %.2fV - ausreichend feucht", sensor_value, threshold);
1147 }
1148
1149 # Sensor 4
1150 - id: auto_check_sensor_4
1151 mode: single
1152 then:
1153 - lambda: |-
1154 float sensor_value = id(feuchtigkeit4).state;
1155 float threshold = id(threshold_sensor4).state;
1156
1157 ESP_LOGI("auto", "📊 Sensor 4: %.3fV (Schwelle: %.2fV)", sensor_value, threshold);
1158
1159 if (isnan(sensor_value)) {
1160 ESP_LOGW("auto", "⚠️ Sensor 4: Fehler/NaN - KEINE Bewässerung!");
1161 return;
1162 }
1163
1164 // Kapazitive Sensoren: Hoher Wert = trocken, niedriger Wert = feucht
1165 if (sensor_value > threshold) {
1166 ESP_LOGI("auto", "💧 Sensor 4: %.3fV > %.2fV → ZU TROCKEN, bewässere!", sensor_value, threshold);
1167 id(pumpe_timed).execute(4, (int)id(pumpen_dauer_auto).state);
1168 } else {
1169 ESP_LOGI("auto", "✅ Sensor 4: %.3fV ≤ %.2fV - ausreichend feucht", sensor_value, threshold);
1170 }
1171
1172
1173
1174
1175# ============================================================================
1176# IDEEN / MÖGLICHE ERWEITERUNGEN
1177# ============================================================================
1178#
1179# Diese Features könnten in Zukunft ergänzt werden:
1180#
1181# 1. Bewässerungs-Zeitfenster:
1182# - Bewässerung nur zwischen bestimmten Uhrzeiten erlauben
1183# - z.B. nur zwischen 06:00 - 22:00 Uhr (nicht nachts)
1184# - Benötigt: time component (SNTP), 4x Number (von_stunde, von_minute, bis_stunde, bis_minute)
1185# - Implementierung: Prüfung in automatik_steuerung Script
1186#
1187# 2. Pause-Funktion:
1188# - Auto-Bewässerung für X Stunden pausieren
1189# - Nützlich nach manuellem Gießen oder bei Regen
1190# - Benötigt: Number (Pause-Dauer in Stunden), Button (Pause aktivieren)
1191# - Implementierung: Timestamp speichern, in automatik_steuerung prüfen
1192#
1193# ============================================================================
project.png
652.3 KB

schaltplan.png
210.2 KB
thumb.png
435.0 KB

wassertank.jpg
2134.6 KB