Hello everybody,
this is my first post so please excuse my not-so-professional post.
Currently iam building a system that is able to measure the soil moisture and if its under a certain threshold it should pump water for a certain time. All this should not be to much electricity consuming because i would like to run it on battery.
The cherry would be if iam able to see in HA the last measured moisture, last time it pumped and force a pumping.
I can imagine that someone had the same idea and its already solved but i didnt find it. So if you provide a link to this topic it would be a big help.
Otherwiese i would like to get help in how to make some kind of loop that ist doing something like this:
wake up
Check if pumping is forced, if yes pump and go to short deep sleep
measure moisture
if under threshold pump and go in short deep sleep
if no pumping needed go back for longer deep sleep
Hello,
thank you for the fast answer. I have seen this one but i dont know how i can still embed this into my code.
especially if i want to kind of loop it.
Till now i have the problem that the pumpuing is once triggered an the never again. and where do you put this deep sleep command?
I am highly interested in your interest, but you took a high step step… you have interesting interesting ideas, but first you should understand the elementary functions of automation. everything is very accessible in the espd home documentation. I will only say one thing: your idea with autonomy is unsolvable.
Deep sleep runs in a loop, you’ll need to set an interval to check, below it’s 6 hours. If when it comes out of sleep and the sensor is below 50 it will suspend sleep.
It will water for 5s and wait for a minute, then water again for 5s in a loop until the sensor is above 50, then go back to the sleep routine.
Hallo,
thank your for your example. It helped me a lot!
It didnt worked perfectly because it had still the issue that if the Sensor value was still in the same range it didnt triggered the condition e.g. the pumping.
I modified it and now i have a solution witch is also still triggering if the value doesnt change the range and it is also in deep_sleep after pumping.
Now i try to find a solution how i can change in the HA UI the Moisture threshold and the Sleep time. My current idea ist this but it doesnt work correctly:
I still trying to figuring it out where the problem is. Becaus of this there are so many status LEDs and logging code. I just wanted to show my current status.
The below compiles fine for me. I am guessing it’s the sleep component is the problem, it’s showing that the duration is not templatable. I don’t know anyway to get around that, you’ll have to update the sketch to change that value.
Hello,
i think we solved it now.
I used your idea but at the end i figured it out that there was an issue to update the threshold value from HA. For this i added a condition to check for this value.
Here the code:
deep_sleep:
run_duration: 30s
sleep_duration: 60s
id: deep_sleep1
sensor:
- platform: adc # airdry: 2,8V; waterwet: 1,58V
pin: 34
name: "soil Humidity"
id: moisturesensor
attenuation: auto
unit_of_measurement: "%"
accuracy_decimals: 0
update_interval: 5s
filters:
- median: #median over the last 7 values
window_size: 7
send_every: 4
send_first_at: 1
- calibrate_linear: #setting the voltage values to equalent percantages
- 2.80 -> 0.00
- 1.58 -> 100.00
# limit the value to 0 and 100%
- lambda: |-
if (x < 0) return 0;
else if (x > 100) return 100;
else return (x);
on_value:
then:
- if:
condition: #check that the threshold value from HA UI is imported
sensor.in_range:
id: moisture_set
below: 100.0
then:
- if:
condition: #compare value from sensor with thresholdvalue
lambda: 'return id(moisturesensor).state < id(moisture_set).state;'
then:
- deep_sleep.prevent: deep_sleep1
- switch.turn_on: pump1
- delay: 10s
- switch.turn_off: pump1
- deep_sleep.enter:
id: deep_sleep1
sleep_duration: 30s
else:
- switch.turn_on: LED2
- delay: 15s
- switch.turn_off: LED2
- deep_sleep.enter: deep_sleep1
- platform: homeassistant
name: "Moisture Set Point"
entity_id: input_number.desired_moisture1
id: moisture_set
accuracy_decimals: 0
- platform: homeassistant
name: "Sleep Time"
entity_id: input_number.desired_sleeptime1
id: sleeptime_set
switch:
- platform: gpio
pin: 22
name: "pumping"
id: pump1
restore_mode: ALWAYS_OFF
icon: "mdi:water-pump"
- platform: gpio
pin: 23
name: "running"
id: LED1
inverted: true
- platform: gpio
pin: 14
name: "status"
id: LED2
restore_mode: ALWAYS_OFF
Hello,
i think i solved it. For the community here my Solution. In the future i will provide a description about the hole setup.
The HA UI that i use is this:
The esp32 wakes up after the set sleep time and is doing this:
measuring the moisture and sending the value to HA
If its under the set Threshold it pumps for 10s
Sending the last time pumped to HA
If pumped it goes just for a few minutes to deep sleep
Check if it is allowed to go to deep sleep (I have this to be able to update the code)
Only if no pumping is needed it goes to the set duration into deep sleep
In HA i had to make two input.number for the moisture threshold and the Sleep time duration, as well as one input.boolean for the prevention of deep sleep.
The code for the esp32 ist here:
Note: i commented the interesting parts that where complicated.
esphome:
name: esp32-gieskanne1
esp32:
board: az-delivery-devkit-v4
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
password: "xxxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp32-Gieskanne1"
password: "xxx"
captive_portal:
time:
- platform: homeassistant
id: homeassistant_time
deep_sleep:
run_duration: 30s
sleep_duration: 5min
id: deep_sleep1
sensor:
- platform: adc # airdry: 2,8V; waterwet: 1,58V
pin: 34
name: "soil Moisture"
id: moisturesensor
attenuation: auto
unit_of_measurement: "%"
accuracy_decimals: 0
update_interval: 5s
filters:
- median: #median over the last 7 values
window_size: 7
send_every: 4
send_first_at: 1
- calibrate_linear: #setting the volatge values to equalent percantages
- 2.80 -> 0.00
- 1.58 -> 100.00
# limit the value to 0 and 100%
- lambda: |-
if (x < 0) return 0;
else if (x > 100) return 100;
else return (x);
on_value:
then:
- if:
condition: #check that the threshold value from HA UI is imported
sensor.in_range:
id: moisture_set
below: 100.0
then:
- if:
condition: #compare value from sensor with threshold value, it is more complicated that "on_range" bcs it also triggers now when the value didnt changed
lambda: 'return id(moisturesensor).state < id(moisture_set).state;'
then:
- deep_sleep.prevent: deep_sleep1
- switch.turn_on: pump1
- delay: 10s
- switch.turn_off: pump1
- sensor.template.publish: #sending Timestamp of pumping to HA UI
id: pump1_last_update
state: !lambda 'return id(homeassistant_time).now().timestamp;'
- if:
condition: #prevent esp32 from entering deep_sleep for updating purpose
binary_sensor.is_on: preventdeepsleep_set
then:
- deep_sleep.prevent: deep_sleep1
else:
- deep_sleep.enter:
id: deep_sleep1
sleep_duration: 2min
else:
- switch.turn_on: LED2
- delay: 15s
- switch.turn_off: LED2
- if:
condition: #prevent esp32 from entering deep_sleep for updating purpose
binary_sensor.is_on: preventdeepsleep_set
then:
- deep_sleep.prevent: deep_sleep1
else:
- deep_sleep.enter:
id: deep_sleep1
sleep_duration: !lambda 'return id(sleeptime_set).state*60000;' #for converting in min *60000, for converting in h *3600000
- platform: homeassistant
name: "Moisture Set Point"
entity_id: input_number.desired_moisture1
id: moisture_set
accuracy_decimals: 0
- platform: homeassistant
name: "Sleep Time"
entity_id: input_number.desired_sleeptime1
id: sleeptime_set
- platform: template
name: "Pump1 last watered"
device_class: timestamp
id: pump1_last_update
binary_sensor:
- platform: homeassistant
name: "prevent deep_sleep"
entity_id: input_boolean.prevent_deep_sleep
id: preventdeepsleep_set
switch:
- platform: gpio
pin: 22
name: "pumping"
id: pump1
restore_mode: ALWAYS_OFF
icon: "mdi:water-pump"
- platform: gpio
pin: 23
name: "running"
id: LED1
inverted: true
- platform: gpio
pin: 14
name: "status"
id: LED2
restore_mode: ALWAYS_OFF
Following problems that i struggled with i solved here:
the “on_value_range” command only triggers when the new value is inside the range and the previous value was outside the range. With this it didnt triggered the pumping if the value was still under the threshold. So i used the “on-value” and if condition.
Becuse of the excessive use of deep_sleep for battery saving reasons, often on booting the script had the measured moisture value but dont had the threshold value from HA and went to completly strange conditions. For this i build an if condition to just check the threshold value if its available. (I think i abused it a bit. )
The part of the code that iam talking about is this:
on_value:
then:
- if:
condition: #check that the threshold value from HA UI is imported
sensor.in_range:
id: moisture_set
below: 100.0
then:
- if:
condition: #compare value from sensor with threshold value, it is more complicated that "on_range" bcs it also triggers now when the value didnt changed
lambda: 'return id(moisturesensor).state < id(moisture_set).state;'
So this is my walk of pain to this solution. I hope it helps further anonymus masochists in the future.
As i mentioned i will make a post in the future about the hole project with Part list and how it is set up in my plants.
Thank you very much for your work! Looks awesome on the first look and was exactly what I was looking for. As a beginner with HA and ESPHome your documentation helps a lot!
Can anyone point me to the right direction how i can integrate the moisture slider in the dashboard ?
I do not see the entities for every “sensor” with platform: homeassistant.
EDIT: I kinda understood it, it is a concept for sending Data from the HomeAssistant to ESPHome Device, so to get the code running one need to create appropriate helper and then add these on the Dashboard.
I converted a WD-01ADE dual pump watering controller. It is equipped with 2 pumps.
Removed the old chip and installed an ESP32. Also wired 2 moisture sensors to ADC inputs.
I tried your code and works flawlessly for a single pump.
Any ideas on how to adapt it for 2 pumps ? I am getting confused with sleep and if 2 sensors can evaluate conditions in parallel.
Hi,
i think if you just copy the code from the adc pin:
sensor:
- platform: adc # airdry: 2,8V; waterwet: 1,58V
pin: 34
name: "soil Moisture"
id: moisturesensor
attenuation: auto
unit_of_measurement: "%"
accuracy_decimals: 0
update_interval: 5s
filters:
- median: #median over the last 7 values
window_size: 7
send_every: 4
send_first_at: 1
- calibrate_linear: #setting the volatge values to equalent percantages
- 2.80 -> 0.00
- 1.58 -> 100.00
# limit the value to 0 and 100%
- lambda: |-
if (x < 0) return 0;
else if (x > 100) return 100;
else return (x);
on_value:
then:
- if:
condition: #check that the threshold value from HA UI is imported
sensor.in_range:
id: moisture_set
below: 100.0
then:
- if:
condition: #compare value from sensor with threshold value, it is more complicated that "on_range" bcs it also triggers now when the value didnt changed
lambda: 'return id(moisturesensor).state < id(moisture_set).state;'
then:
- deep_sleep.prevent: deep_sleep1
- switch.turn_on: pump1
- delay: 10s
- switch.turn_off: pump1
- sensor.template.publish: #sending Timestamp of pumping to HA UI
id: pump1_last_update
state: !lambda 'return id(homeassistant_time).now().timestamp;'
- if:
condition: #prevent esp32 from entering deep_sleep for updating purpose
binary_sensor.is_on: preventdeepsleep_set
then:
- deep_sleep.prevent: deep_sleep1
else:
- deep_sleep.enter:
id: deep_sleep1
sleep_duration: 2min
else:
- switch.turn_on: LED2
- delay: 15s
- switch.turn_off: LED2
- if:
condition: #prevent esp32 from entering deep_sleep for updating purpose
binary_sensor.is_on: preventdeepsleep_set
then:
- deep_sleep.prevent: deep_sleep1
else:
- deep_sleep.enter:
id: deep_sleep1
sleep_duration: !lambda 'return id(sleeptime_set).state*60000;' #for converting in min *60000, for converting in h *3600000
and just adapt to the input from the second Humidity Sensor and Pump it should work for the second pump.
If you want to get the Stats shown on the HA UI and control from there you need also to adapt the “moisture_set” and implement a second one.
I hope this helps.