(somewhat) complex logic in Yaml file - am I doing it the right way?

Hi there

I want to do some if statements with logic in between. I am working on a self-watering planter, that measures soil moisture and ads water from an integrated magazine as needed. The goal is to keep it self-sufficiant for 2 months before it needs a charge or a re-fill of water.

So the logic is this: If there’s litle or no water, send an alert to HA, then go to sleep. Else, if it’s moist, don’t water, go to sleep. If it isn’t moist enough, water, then go to sleep for a short while, wakeup and start over.

I’ve been trying to do that with an on… statement like this (the entire code is pasted bellow):
This was my starting point: Automations and Templates — ESPHome
Thought the text there doesn’t say I should, I also tried with lampda |-

on_...:
  then: 
    - if:
      condition:
        lambda: 'return id(Moisture_flaura1).state < 60;'
      then:
        - logger.log: "below 61, watering"
        - switch.turn_on: pump
        - delay: 30s
        - logger.log: "below 61, nap time 1 min"
        - deep_sleep.enter:
            id: deep_sleep1
            sleep_duration: 1 min
      else:
        - if:
          condition:
            lambda: 'return id(Moisture_flaura1).state > 59;'
          then:
            - logger.log: "above 60. Nap time"
            - deep_sleep.enter:
                id: deep_sleep1
                sleep_duration: 1 min

But I keep getting all sorts of errors from that statement. I’ve been messing a lot with the indentions, because that is a common cause to trouble (at least when I wrote the code) but it doesn’t seem to fix it.

My first question is, if I am doing it the right way at all (keeping in mind that logic from the water level sensor has to be added to this as well)?
If so, why isn’t my copy paste from the documentation working for me? Is it supposed to be placed a particular place in the code and not in a root level indention as I have it?

The current code returns this when I try to install it on the ESP32 (from dollartek) that I am working on:

INFO Reading configuration /config/esphome/flaura1.yaml…
ERROR Unexpected exception while reading configuration:
Traceback (most recent call last):
File “/usr/local/bin/esphome”, line 33, in
sys.exit(load_entry_point(‘esphome’, ‘console_scripts’, ‘esphome’)())
File “/esphome/esphome/main.py”, line 931, in main
return run_esphome(sys.argv)
File “/esphome/esphome/main.py”, line 909, in run_esphome
config = read_config(dict(args.substitution) if args.substitution else {})
File “/esphome/esphome/config.py”, line 972, in read_config
res = load_config(command_line_substitutions)
File “/esphome/esphome/config.py”, line 827, in load_config
return _load_config(command_line_substitutions)
File “/esphome/esphome/config.py”, line 815, in _load_config
result = validate_config(config, command_line_substitutions)
File “/esphome/esphome/config.py”, line 742, in validate_config
result.run_validation_steps()
File “/esphome/esphome/config.py”, line 124, in run_validation_steps
task.step.run(self)
File “/esphome/esphome/config.py”, line 298, in run
component = get_component(self.domain)
File “/esphome/esphome/loader.py”, line 177, in get_component
assert “.” not in domain
AssertionError

Entire code:
(the code worked up until I started working with the on_… -thing

esphome:
  name: flaura1
  
#power on moisture sensor when not sleeping  
  on_boot:
    priority: 90
    then:
    - output.turn_on: moist_power

esp32:
  board: esp-wrover-kit
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "secret key"

ota:
  password: "ota password"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Flaura1 Fallback Hotspot"
    password: "password"

#def power pin for moisture sensor
output:
  - platform: gpio
    id: moist_power
    pin: 19

deep_sleep:
  id: deep_sleep1
  run_duration: 1000min

# the current state 0: woken from 2, measure. 1: water off thresh not reached, short-sleep. 2=water off thresh reached, longsleep.

#globals:
#  - id: state
#  type: int
#  initial_value: 0
#  restore_value: yes
  
  
#moisture sensor config
sensor:
  - platform: adc
    pin: GPIO33
    id: "Moisture_flaura1"
    update_interval: 1s
    name: "Moisture flaura1"

#Running median of moisture and mapping of values to 0-100 scale   
    filters:
    - median:
        window_size: 7
        send_every: 5
        send_first_at: 4
    - calibrate_linear:
        - 1.033 -> 0.00
        - 0.875 -> 100.00
#    - lambda: if (x < 1) return 0; else return (x);
#        accuracy_decimals: 0  <-- Triggers error

on_...:
  then: 
    - if:
      condition:
        lambda: 'return id(Moisture_flaura1).state < 60;'
      then:
        - logger.log: "below 61, watering"
        - switch.turn_on: pump
        - delay: 30s
        - logger.log: "below 61, nap time 1 min"
        - deep_sleep.enter:
            id: deep_sleep1
            sleep_duration: 1 min
      else:
        - if:
          condition:
            lambda: 'return id(Moisture_flaura1).state > 59;'
          then:
            - logger.log: "above 60. Nap time"
            - deep_sleep.enter:
                id: deep_sleep1
                sleep_duration: 1 min
        
switch:
  - platform: gpio
    pin: GPIO 23
    name: "Pump"
    id: pump
    inverted: true

cover:
  - platform: template
    name: "pump"
    open_action:
      # Cancel any previous action
      - switch.turn_off: pump
      # Turn the OPEN switch on briefly
      - switch.turn_on: pump
      - delay: 30s
      - switch.turn_off: pump
    close_action:
      - switch.turn_off: pump

You don’t literally write on_...:. It is on_something: like on_press: or on_value:

Ah, okay. So in this case, where I want to build on a combination of two sensor values, what should trigger it? On_What? Is there something like on_sensors_done_reading?

Which two sensors and what logic to you want to implement?

Can I also suggest that if you want to work together on this project, can we stick to one thread?

Going to to sleep conditionally is working for me fine, but what function/statement/whatever is smartest to use to evaluate the input of the moisture sensor and the water-level sensor together? (the latter is similar to an on/off button output, more or less).

Since yesterday, when I wrote the post, I figured the right approach could be something llike:

Inside the moisture sensor configuration:

on_value:
below watering threshold:
water, then go to sleep

above watering threshhold
go to sleep

And then, in the water-level sensor, there is similar logic for going to sleep when the waterlevel is to low. All I have to do is to make sure the waterlevel sensor is evaluated first (or live with the pump running dry once)

The downside of this is, that it doesn’t leave a lot of room for additional logic should the need arise as it seems you generally hit the limits of what is possible quickly. It also means that the moisture sensor and the water-level are disconnected, logic-wise. Is it the best way to do it? …it would be nice to have or two before heading into a (possibly) wrong direction.

Obviously you test water level before turning the pump on.

Well, it doesn’t really answer the question I asked (or at least the one I intended to ask).

The question is, how I solve the task in terms of what functions/declerations etc. is best used to solve the task, not what the in order of things should be. Is the on_value-approach inside the sensor configuration the better approach or would this logic best be solved in a different way?