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.
Hm… maybe you are right
Puhhhh but i dont have an idea how to do it in parallel or seriel but without the deep sleep setting.
Hm…
maybe during the check of the first sensor delete all the into deep_sleep stuff?
So the esp checks the first sensor, does his thing and continues to the second one. Only in the scond one you make the deep_sleep check.
Hi. Is hard too cut deep sleep switch and switch off this function? Used esp for other things and is important for me to never deep sleep esp32. I worried to switch on this function not intentionaly.
@Grieche could you please explain the switch part in the esp32 code? You use pin 22 for pump1, pin 23 for LED1 and pin 14 for LED2, but as presented in the schematics at the top- there is only one Input to the Relay from the ESP32 (yellow wire).
Which of these pins is the yellow wire one and what are the other ones?
Can they be any PIN/GPIO?
Hi,
its long time a go and only God knows know the code but i try to explain.
Regarding Pin22: This is the Yellow wire witch switches/triggers the relay.
Regarding Pin23 (LED1): This is just a status LED that the ESP is running. Just for myself. Its not relevant.
Regarding Pin14 (LED2): This is my visual feedback that a measuring happened and the moisture was over the threshld and so no pumping was triggered. It is also just a feedback, its not necessary for the code.
You have to look in the scematics of your esp32 witch Pins you can use as switches but you can use an switcheable Pin.
Dos this answer your questions?