šŸŒæ ESPlanty | Self-watering Solar Powered Plant | No plumbing & no powerpoints | # Irrigation , # Deep Sleep , # Battery

@Mar1us thank you, because after your message I provided more love to the code; it seems that now it works

  • The button to suspend deep sleep works
  • The input to control the deep sleep duration and the delay duration are working
  • The sunset condition seems ok (testing now)

essentially this is the behavior:

if the prevent deep sleep is on, the esp remains up
if the prevent deep sleep is off, it goes in deep sleep for the amount of minutes defined by the input sleep duration, then the script is delayed for the amount of time defined by the input number script delat duration. This is the normal condition, when the sun is below the horizontal then the esp goes in deep sleep until the next sunrise. (in order to calculate the sunst/sunrise duration I used the SUN2 component)

here the full code, testing it right now.
any feedback/comments is really apprecated

# Substitutions
# Define variables to be used throughout the configuration
substitutions:
  device_name: test
  friendly_name: "test"
  device_platform: espressif32
  device_board: nodemcu-32s
  device_ip: X.X.X.X

# Packages
# Include common configurations from external files
packages:
  wifi: !include common/device_wifi.yaml
  device_base: !include common/device_base_ESP32.yaml
  home_assistant_api: !include common/device_api.yaml
  sensor_wifi_ip_address: !include common/sensor_wifi_ip_address.yaml

# Enable logging
logger:
  level: VERBOSE

# API
api:

# Time configuration
time:
  - platform: homeassistant
    id: homeassistant_time

# Sun configuration
sun:
  latitude: 999999
  longitude: 99999
  id: sun_component
  on_sunset:
    then:
      - logger.log: "Sunset occurred, entering deep sleep mode until next sunrise"
      - logger.log:
          format: "Sleep duration until next sunrise: %f minutes"
          args: [ "id(sleep_duration_calc).state" ]
      - deep_sleep.enter:
          id: deep_sleep_control
          sleep_duration: !lambda "return id(sleep_duration_calc).state * 60000;"
# Deep sleep configuration
deep_sleep:
  id: deep_sleep_control

binary_sensor:
  # Get the state of the prevent_deep_sleep input_boolean from Home Assistant to control whether or not to enter deep sleep mode
  - platform: homeassistant
    id: prevent_deep_sleep
    entity_id: input_boolean.prevent_deep_sleep
    icon: "mdi:sleep-off"
    entity_category: diagnostic

sensor:
  # Get the sleep_duration value from Home Assistant to control how long to sleep for in deep sleep mode
  - platform: homeassistant
    id: sleep_duration
    entity_id: input_number.deep_sleep_sleep_duration
  # Get the delay_duration value from Home Assistant to control how long (in seconds) to wait before proceeding
  - platform: homeassistant
    id: delay_duration
    entity_id: input_number.deep_sleep_script_delay_duration    
##################
  - platform: template
    name: "Sleep Duration to next Sunrise"
    id: sleep_duration_calc
    unit_of_measurement: "min"
    lambda: |-
      if (id(tomorrow_sunrise_string).has_state() && id(today_sunset_string).has_state()) {
        struct tm tomorrow_sunrise_tm;
        strptime(id(tomorrow_sunrise_string).state.c_str(), "%Y-%m-%d %H:%M:%S", &tomorrow_sunrise_tm);
        time_t tomorrow_sunrise_time = mktime(&tomorrow_sunrise_tm);
        struct tm today_sunset_tm;
        strptime(id(today_sunset_string).state.c_str(), "%Y-%m-%d %H:%M:%S", &today_sunset_tm);
        time_t today_sunset_time = mktime(&today_sunset_tm);
        double sleep_duration_seconds = difftime(tomorrow_sunrise_time, today_sunset_time);
        return sleep_duration_seconds / 60.0;
      }
      return {};  
##################
text_sensor:
  - platform: homeassistant
    id: today_sunrise_string
    entity_id: sensor.suninfo_sunrise
    attribute: today
    internal: true
  - platform: homeassistant
    id: today_sunset_string
    entity_id: sensor.suninfo_sunset
    attribute: today
    internal: true
  - platform: homeassistant
    id: tomorrow_sunrise_string
    entity_id: sensor.suninfo_sunrise
    attribute: tomorrow
    internal: true
  - platform: homeassistant
    id: tomorrow_sunset_string
    entity_id: sensor.suninfo_sunset
    attribute: tomorrow
    internal: true
  - platform: template
    name: "Today Sunset"
    id: today_sunset
    lambda: |-
      if (id(today_sunset_string).has_state()) {
        struct tm t;
        strptime(id(today_sunset_string).state.c_str(), "%Y-%m-%d %H:%M:%S", &t);
        char buf[30];
        strftime(buf, sizeof(buf), "%B %d, %Y at %I:%M %p", &t);
        return std::string(buf);
      }
      return {};
  - platform: template
    name: "Tomorrow Sunrise"
    id: tomorrow_sunrise
    lambda: |-
      if (id(tomorrow_sunrise_string).has_state()) {
        struct tm t;
        strptime(id(tomorrow_sunrise_string).state.c_str(), "%Y-%m-%d %H:%M:%S", &t);
        char buf[9];
        strftime(buf, sizeof(buf), "%H:%M:%S", &t);
        return std::string(buf);
      }
      return {};                    
esphome:
  on_boot:
    priority: -10
    then:
      - logger.log:
          format: "Waiting for API to connect..."
      # Wait until API is connected and time is synchronized before proceeding
      - wait_until:
          api.connected:
      - logger.log:
          format: "API connected. Waiting for time to synchronize..."
      - wait_until:
          time.has_time:
      - logger.log:
          format: "Time synchronized. Checking prevent_deep_sleep binary sensor value..."
      # Check if the prevent_deep_sleep binary sensor value is on or off before proceeding
      - if:
          condition:
            lambda: 'return id(prevent_deep_sleep).state;'
          then:
            - logger.log:
                format: "prevent_deep_sleep binary sensor value is on"
          else:
            - logger.log:
                format: "prevent_deep_sleep binary sensor value is off"
      # Log that API is connected, time is synchronized, and prevent_deep_sleep binary sensor value is checked
      - logger.log:
          format: "API connected, time synchronized, and prevent_deep_sleep binary sensor value checked."
      - wait_until:
          lambda: "return id(today_sunset).has_state() && id(tomorrow_sunrise).has_state();"
      - wait_until:
          lambda: "return id(prevent_deep_sleep).has_state() && id(sleep_duration).has_state() && id(delay_duration).has_state();"

      - script.execute: consider_deep_sleep

script:
  - id: consider_deep_sleep
    mode: queued
    then:
      - logger.log:
          format: "Executing consider_deep_sleep script"
      - logger.log:
          format: "Delaying for %d minutes"
          args: [ "(int) id(delay_duration).state" ]
      - delay: !lambda "return id(delay_duration).state * 60000;"
      - logger.log:
          format: "After the delay"
      - if:
          condition:
            binary_sensor.is_on: prevent_deep_sleep
          then:
            - logger.log:
                format: "Skipping sleep, per prevent_deep_sleep"
          else:
            - logger.log:
                format: "Entering deep sleep mode"
            - if:
                condition:
                    - sun.is_above_horizon:
                        id: sun_component # Sun is above horizon.
                then:
                  - logger.log:
                      format: "Entering deep sleep normal"
                  - logger.log:
                      format: "Sleep for %d minutes"
                      args: [ "(int) id(sleep_duration).state" ]
                  - deep_sleep.enter: 
                      id: deep_sleep_control
                      sleep_duration:  !lambda "return id(sleep_duration).state * 60000;"
                else:
                  - logger.log:
                      format: "Entering deep sleep until sunrise"
                  - logger.log:
                      format: "Sleep duration until next sunrise: %f minutes"
                      args: [ "id(sleep_duration_calc).state" ]
                  - deep_sleep.enter: 
                      id: deep_sleep_control
                      sleep_duration:  !lambda "return id(sleep_duration_calc).state * 60000;"
      - script.execute: consider_deep_sleep
4 Likes

thank you so much, that helped me a lot

Hi Folks, I would like to have your opinion here
Deep sleep cycle it fine to reduce the power consumption, but the ESP must remain on during the watering cycle.

how you calculated the battery capacity/pump consumption/solar panel?
Iā€™m looking around to select the hw

I think Andreas Spiess has done good videos on this (at least the solar and battery parts). You might need to search a bit on his channel.

For the pump youā€™d prob just measure current with a multimeter?

wow, what a good guidelines i found here. thank you!

i have one issue stillā€¦ how is possible to make component update for uart_bus?

Typically you use component.update on the actual sensor.

Do you have any electrical schematic and materials list here ? I am trying to create the same thing for my dying rose plants. Would be helpful.

1 Like

Afraid not. I can do a materials list easy enough.

Schematic I can have a go at but will have to put aside some time.

I tried many schematics but end up burning something. Would be nice if I have them. Thank you

1 Like

Materials List
1st pass at materials list. May not be complete yet. I included a few extra links to things like soldering equipment and crimping kit I have.

Component Notes Link
Single 18650 Battery Holder Cheap probably ok. Ali Express
3.7V 18650 Battery Buy a good one locally. Get like a 3000-36000mAH one. Get a protected one. Do a little research about local buying options.
Solar Panel (5V) Make sure you get the right voltage. I bought from this Ali Store
Sunflower: Solar Power Manager 5V Investigate your buying options. Core Electronics
Pump Do a little research on pumps and buy a slightly better one Ali Express
VL53L0X Ali Express
BH1750 Ali Express
L298n If you want pump flow control via PWM, you should get the full size version rather than the mini. Ali Express
2 x Resistors (300kā„¦) More detail here.
ESP32 LILYGOĀ® TTGO T7 Mini32 V1.5 Get a good ESP32 for this project. Get one optimised for low energy / deep sleep with battery connections. Tried other boards but idel current too high. Ali Express
Capacitive soil moisture sensor Water proofed with nail polish and hot glue. These are notoriously short lived so read up on them. Ali Express
Treated Pine Sleepers I made my ā€œcut planā€ and got Bunnings to cut to size. Bunnings
Decking Screws For fixing the base box together Bunnings
Castors To roll your plant around
Water Jerry Can To use as water tank. Bunnings
Glass food storage container with Plastic lid Consider your solar panel size when sizing this. KMart , IKEA
Flexible Silicone wire Ali Express
Crimping Tool & Kit ā€¦. ā€¦
Soldering equipment Ali Express
Very short usb cable Connect ESP32 and Solar Power Manager
Tubing Check / confirm the Internal diameter for compatibility with pump. Ali Express
3d printer To print irrigation rings plus other bits and bobs like ā€œcomponent mount plateā€.
Hot Glue Gun For mounting components Ali Express
1 Like

Iā€™ve added a first cut materials list above.
Not sure when Iā€™ll get to doing a wiring diagram. Started one but I suck at them and struggle.

1 Like

Wiring Diagram

I think this is right.

A few points:

  1. Sensor power is supplied / managed via the power manager (not the esp32)
  2. Iā€™m not sure if the way all my grounds are linked is optimal, but it seems to work.
  3. Iā€™d suggest getting everthing except for the sensors connected and working first (including the voltage divider), and then add the sensors / pump one by one and test that they are working.
  4. Set a short deep sleep cycle of like 30 sec on 30 sec off etc during testing.
  5. I2C can be fussy and not keen on long wires. Solder at least on the sensor sides (dupont on other end ok? ).

Even the tiniest details would be helpful as I am a commerce student and hobbyist electronics and this would be my first automated project.

1 Like

This is probably ā€œquite an advanced 1st projectā€.

The build isnā€™t detailed step by step etc.

So you would need to be patient and persistent to work through it.

Wiring diagram is above.

1 Like

Thank you very much.

1 Like

It would be kickass if there was a google doc where everyone building this collaborately could document the step by step. Why hasnā€™t anyone done this yet?

You can be the first;) Itā€™s not done because no-one has done it;)

Some of my projects where I donā€™t think there would be too much interest I tend to lag a bit on the detailed documentation and just do it a bit more ā€œon demandā€.

Documentation contributions welcome though.

Sometimes itā€™s worth just dumping stuff to help close the gaps on a thread like this and then that can help build the how-to. Like I did that kind of thing over here.

Hey there, buddy!

I just had to drop you a line to express my immense gratitude for sharing this projectā€”itā€™s like stumbling upon a hidden gem in a digital treasure trove! Seriously, itā€™s been an absolute game-changer for me in getting to grips with ESPHome. :star2:

Your coding finesse has me in awe, my friend. Iā€™m diving deep into your code, uncovering new approaches, and soaking up knowledge like a sponge. Itā€™s like a thrilling adventure, and your project is the map leading me to programming enlightenment! :rocket::bulb:

Thanks a million for your generosity. Letā€™s keep this coding journey rolling! :raised_hands:

1 Like

Thanks for the kind words.

I assure you itā€™s really more of an assembly of other peopleā€™s work on the forums which I learnt and put together one brick at a time, rather than great programming skills on my part.

Iā€™ve been contemplating which of my deep projects I can use your new trick on BTW;) Thereā€™s always more to learnā€¦

Hey there!

Donā€™t sell yourself short, buddy! Researching, understanding, assembling, and creating something new is commendable. Incorporating the knowledge and reasoning of others into our own is a very dignified way to learn and grow. Iā€™m sure your ability to gather and apply othersā€™ ideas is an impressive skill in itself.

I want to thank you again for sharing this project with us. Itā€™s shedding light on many aspects that were previously elusive to me, and Iā€™m thrilled to see how I can apply these new insights to my own projects. Your contribution is truly inspiring and valuable to me.

Thanks again, and letā€™s keep in touch!

Big hugs! :hugs::star2:

1 Like