· 4 months ago · Jun 08, 2025, 07:30 AM
1esphome:
2 name: smart-watering-system
3 friendly_name: Smart Watering System
4
5esp32:
6 board: esp32dev
7 framework:
8 type: arduino
9
10# Enable logging
11logger:
12
13# Enable Home Assistant API
14api:
15 encryption:
16 key: "generated_automatically"
17
18ota:
19 - platform: esphome
20 password: "generated_automatically"
21
22wifi:
23 ssid: your_wifi_ssid
24 password: your_wifi_password
25
26 manual_ip:
27 # Set this to the IP of the ESP
28 static_ip: 192.168.1.253
29 # Set this to the IP address of the router. Often ends with .1
30 gateway: 192.168.1.1
31 # The subnet of the network. 255.255.255.0 works for most home networks.
32 subnet: 255.255.255.0
33
34 # Enable fallback hotspot (captive portal) in case wifi connection fails
35 ap:
36 ssid: "Smart-Watering-System"
37 password: "generated_automatically"
38
39captive_portal:
40
41switch:
42 - platform: gpio
43 pin: GPIO16
44 name: "Water pump"
45 id: water_pump
46 on_turn_on:
47 then:
48 - if:
49 condition:
50 - binary_sensor.is_on: water_level_ok
51 then:
52 - light.turn_on: blue_led
53 else:
54 - delay: 1s
55 - switch.turn_off: water_pump
56 on_turn_off:
57 then:
58 - if:
59 condition:
60 - binary_sensor.is_on: water_level_ok
61 then:
62 - light.turn_off: blue_led
63
64button:
65 - platform: template
66 name: Start Watering
67 id: button_start
68 icon: "mdi:power-on"
69 on_press:
70 then:
71 - if:
72 condition:
73 - binary_sensor.is_on: water_level_ok
74 then:
75 - switch.turn_on: water_pump
76 - delay: !lambda "return id(watering_time).state*60*1000;"
77 - switch.turn_off: water_pump
78 else:
79 - switch.turn_off: water_pump
80
81 - platform: template
82 name: Stop Watering
83 id: button_stop
84 icon: "mdi:power-off"
85 on_press:
86 then:
87 - switch.turn_off: water_pump
88
89
90number:
91 - platform: template
92 name: Full Distance
93 icon: mdi:arrow-collapse-vertical
94 entity_category: config
95 id: full_distance_m
96 min_value: 0.01
97 max_value: 1.50
98 initial_value: 0.1
99 optimistic: true
100 step: 0.01
101 restore_value: true
102 unit_of_measurement: meters
103 mode: box
104
105 - platform: template
106 name: Empty Distance
107 icon: mdi:arrow-expand-vertical
108 entity_category: config
109 id: empty_distance_m
110 min_value: 0.01
111 max_value: 1.50
112 initial_value: 0.1
113 optimistic: true
114 step: 0.01
115 restore_value: true
116 unit_of_measurement: meters
117 mode: box
118
119 - platform: template
120 name: Safe Level Distance
121 icon: mdi:arrow-expand-vertical
122 entity_category: config
123 id: safe_distance_m
124 min_value: 0.01
125 max_value: 1.50
126 initial_value: 0.1
127 optimistic: true
128 step: 0.01
129 restore_value: true
130 unit_of_measurement: meters
131 mode: box
132
133 - platform: template
134 name: Watering Time
135 icon: mdi:clock-edit
136 id: watering_time
137 min_value: 1
138 max_value: 60
139 initial_value: 10
140 optimistic: true
141 step: 1
142 restore_value: true
143 unit_of_measurement: minutes
144 mode: box
145
146output:
147 - platform: gpio
148 pin: GPIO26
149 id: red_led_output
150 - platform: gpio
151 pin: GPIO23
152 id: yellow_led_1_output
153 - platform: gpio
154 pin: GPIO18
155 id: yellow_led_2_output
156 - platform: gpio
157 pin: GPIO19
158 id: green_led_output
159 - platform: gpio
160 pin: GPIO27
161 id: blue_led_output
162
163light:
164 - platform: binary
165 name: "Red LED"
166 id: red_led
167 disabled_by_default: True
168 output: red_led_output
169 internal: False
170 restore_mode: RESTORE_DEFAULT_OFF
171 effects:
172 - strobe:
173 name: Blink
174 colors:
175 - state: true
176 brightness: 100%
177 duration: 500ms
178 - state: false
179 duration: 500ms
180 - platform: binary
181 name: "Yellow LED 1"
182 id: yellow_led_1
183 disabled_by_default: True
184 output: yellow_led_1_output
185 restore_mode: RESTORE_DEFAULT_OFF
186 - platform: binary
187 name: "Yellow LED 2"
188 id: yellow_led_2
189 disabled_by_default: True
190 output: yellow_led_2_output
191 restore_mode: RESTORE_DEFAULT_OFF
192 - platform: binary
193 name: "Green LED"
194 id: green_led
195 disabled_by_default: True
196 output: green_led_output
197 restore_mode: RESTORE_DEFAULT_OFF
198 - platform: binary
199 name: "Blue LED"
200 id: blue_led
201 disabled_by_default: True
202 output: blue_led_output
203 effects:
204 - strobe:
205 name: Double Blink
206 colors:
207 - state: true
208 brightness: 100%
209 duration: 150ms
210 - state: false
211 duration: 200ms
212 - state: true
213 brightness: 100%
214 duration: 150ms
215 - state: false
216 duration: 500ms
217
218binary_sensor:
219 - platform: gpio
220 pin:
221 number: GPIO33
222 mode:
223 input: true
224 pullup: true
225 inverted: true
226 name: "Pushbutton"
227 id: start_button
228 filters:
229 - delayed_on: 100ms
230 on_press:
231 then:
232 - if:
233 condition:
234 - switch.is_off: water_pump
235 then:
236 - button.press: button_start
237 - delay: 1s
238 else:
239 - button.press: button_stop
240 - delay: 1s
241
242
243 - platform: template
244 name: "Water Level OK"
245 id: water_level_ok
246 lambda: |-
247 if (id(ultrasonic_sensor_distance).state < id(safe_distance_m).state) {
248 //there is enough water
249 return true;
250 } else {
251 //there is not enough water
252 return false;
253 }
254 on_state:
255 then:
256 - lambda: |-
257 if (x == false) {
258 id(blue_led).turn_on().set_effect("Double Blink").perform();
259 id(water_pump).turn_off();
260 } else {
261 //do nothing
262 }
263 on_press:
264 then:
265 - light.turn_off: blue_led
266
267 - platform: template
268 name: "Pump Status"
269 id: pump_status
270 device_class: running
271 lambda: |-
272 return id(water_pump).state;
273
274sensor:
275 - platform: ultrasonic
276 trigger_pin: GPIO22
277 echo_pin: GPIO21
278 name: "Level Sensor Distance"
279 id: ultrasonic_sensor_distance
280 device_class: distance
281 update_interval: 1s
282 pulse_time: 10us
283 timeout: 20m
284 filters:
285 - sliding_window_moving_average:
286 window_size: 15
287 send_every: 15
288
289 - platform: template
290 name: "Water Level"
291 id: water_level
292 lambda: |-
293 return id(ultrasonic_sensor_distance).state;
294 update_interval: 1s
295 accuracy_decimals: 0
296 unit_of_measurement: "%"
297 filters:
298 - lambda: return ((100 - 0)/(id(full_distance_m).state - id(empty_distance_m).state)) * x + (100 - (((100 - 0)/(id(full_distance_m).state - id(empty_distance_m).state)) * id(full_distance_m).state));
299 - clamp:
300 min_value: 0
301 max_value: 100
302 ignore_out_of_range: false
303 on_value_range:
304 - below: 20
305 then:
306 - light.turn_off: green_led
307 - light.turn_off: yellow_led_1
308 - light.turn_off: yellow_led_2
309 - light.turn_on:
310 id: red_led
311 effect: Blink
312 - above: 20
313 then:
314 - light.turn_on:
315 id: red_led
316 effect: None
317 - below: 40
318 then:
319 - light.turn_off: green_led
320 - light.turn_off: yellow_led_1
321 - light.turn_off: yellow_led_2
322 - above: 40
323 then:
324 - light.turn_on:
325 id: red_led
326 effect: None
327 - light.turn_on: yellow_led_1
328 - below: 60
329 then:
330 - light.turn_off: yellow_led_2
331 - light.turn_off: green_led
332 - above: 60
333 then:
334 - light.turn_on:
335 id: red_led
336 effect: None
337 - light.turn_on: yellow_led_1
338 - light.turn_on: yellow_led_2
339 - below: 80
340 then:
341 - light.turn_off: green_led
342
343 - above: 80
344 then:
345 - light.turn_on:
346 id: red_led
347 effect: None
348 - light.turn_on: yellow_led_1
349 - light.turn_on: yellow_led_2
350 - light.turn_on: green_led