ESPHome code for Greenhouse (wind and temp)

Hello, I’m having some trouble writing an ESPHome code for a greenhouse controller. Here’s the logic I’m trying to implement:

  1. If the wind speed exceeds approximately 11 m/s, I want the system to close the greenhouse for 5 hours and ignore all other automations during that time.
  2. If the temperature goes above 25°C, the greenhouse should open, and if it drops below 20°C, it should close.

Any guidance on how to implement this would be greatly appreciated!

switch:    
  - platform: gpio
    id: motor1
    name: "Greenhouse Motor 1"
    pin:
      number: GPIO14
      inverted: true
  - platform: gpio
    id: motor2
    name: "Greenhouse Motor 2"
    pin:
      number: GPIO27
      inverted: true

one_wire:
  - platform: gpio
    pin: GPIO32
    id: temp1

uart:
  rx_pin: GPIO19
  tx_pin: GPIO05
  baud_rate: 4800

modbus:
  id: modbus1

modbus_controller:
  - id: wind_speed_meter
    address: 1
    modbus_id: modbus1
    setup_priority: -10
    command_throttle: 200ms
    update_interval: 1s

sensor:
  - platform: dallas_temp
    name: "Greenhouse Temp"
    one_wire_id : temp1
    id: plastenik_temp
  - platform: modbus_controller
    modbus_controller_id: wind_speed_meter
    name: "Wind speed"
    device_class: wind_speed
    register_type: read
    address: 0
    unit_of_measurement: "m/s"
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
      - multiply: 0.1
      - max:
          window_size: 5
          send_every: 2
      - exponential_moving_average:
          alpha: 0.1
          send_every: 3

Did you try looking through the documentation??

The issue I’m facing is that sensor automations aren’t working with the wind sensor (platform: modbus_controller). Typically, I use a Script Component with an Interval Component to control the temperature, but I’m struggling to implement the logic for wind >11 for 5 hours. My current thought is to use a virtual switch that stays on for 5 hours, but I’m not sure how to program the virtual switch to remain on for that duration.

What automations? There aren’t any automations to speak of in your Esphome config you posted.

Here’s your wind speed sensor. Is this working correctly at least?

- platform: modbus_controller
    modbus_controller_id: wind_speed_meter
    name: "Wind speed"
    device_class: wind_speed
    register_type: read
    address: 0
    unit_of_measurement: "m/s"
    value_type: U_WORD
    accuracy_decimals: 1
    filters:
      - multiply: 0.1
      - max:
          window_size: 5
          send_every: 2
      - exponential_moving_average:
          alpha: 0.1
          send_every: 3

I meant to say that modbus doesn’t seem to have automations based on sensor value. It only has the following automations on_command_sent, on_online and on_offline.

IDK if this is would help but, this is how I make dynamic update intervals so that I can change the update interval from the HA UI instead of having to change code and then flash board each time.

esphome:
  name: flow-meter-softener
  on_boot: 
    priority: -100
    then:
      - logger.log: "Setting Update Interval"
      - component.resume: 
          id: water_heater_temp
          update_interval: !lambda |-
            int time = id(water_heater_update).state*1000;
            return time;
      - component.update: 
          id: water_heater_temp

sensor:
  - platform: aht10
    variant: AHT10
    id: water_heater_temp
    i2c_id: bus_a
    temperature:
      name: "Hot Water Closet"
      id: closet_temp
      filters:
        - lambda: return x * (9.0/5.0) + 32.0;
      unit_of_measurement: "°F"   
    humidity:
      name: "Hot Water Closet %"
      id: closet_humidity
      unit_of_measurement: "%"
    update_interval: never

number:
  - platform: template
    id: water_heater_update
    name: "Dynamic Update"
    max_value: 9000
    min_value: 5
    initial_value: "5"
    unit_of_measurement: " Seconds"
    step: 1
    optimistic: True
    update_interval: never
    mode: box
    on_value: 
      then:
        - component.resume:
            id: water_heater_temp
            update_interval: !lambda |-
              int time = id(water_heater_update).state*1000;
              return time;

Why would it? It’s a sensor and just like any of the hundreds of possible sensors you could use, they all use the same “Sensor Automations” and it even mentions that in the documentation.

The other Automation topics like Actions,Conditions, etc, those are all Esphome in general, they aren’t just for one thing or another thing, they work with all the things.

Your right, I wasn’t able to get it to work so I just assumed it was not possible. I think i was able to achieve my goal (code below), still have to test it. Thank you for your help.

switch:    
  - platform: gpio
    id: motor1
    name: "Greenhouse Motor 1"
    pin:
      number: GPIO14
      inverted: true
  - platform: gpio
    id: motor2
    name: "Greenhouse Motor 2"
    pin:
      number: GPIO27
      inverted: true
  - platform: template
    name: "Wind Speed Switch"
    id: wind_speed_switch
    turn_on_action:
      - switch.turn_off: motor1 
      - switch.turn_off: motor2
      - delay: 5h
      - switch.turn_off: wind_speed_switch  # turns off after the delay
    turn_off_action:
      - logger.log: "Wind switch turned OFF"
    optimistic: true
    restore_mode: RESTORE_DEFAULT_OFF 

one_wire:
  - platform: gpio
    pin: GPIO32
    id: temp1

uart:
  rx_pin: GPIO19
  tx_pin: GPIO05
  baud_rate: 4800

modbus:
  id: modbus1

modbus_controller:
  - id: wind_speed_meter
    address: 1
    modbus_id: modbus1
    setup_priority: -10
    command_throttle: 200ms
    update_interval: 1s


sensor:
  - platform: dallas_temp
    name: "Greenhouse Temp"
    one_wire_id: temp1  
    id: greenhouse_temp
    on_value_range:
      - above: 25
        then:
          - if:
              condition:
                switch.is_off: wind_speed_switch  # Only proceed if wind_speed_switch is off
              then:
                - switch.turn_on: motor1
                - switch.turn_on: motor2
      - below: 20
        then:
          - switch.turn_off: motor1
          - switch.turn_off: motor2
  - platform: modbus_controller
    modbus_controller_id: wind_speed_meter
    name: "Wind speed"
    device_class: wind_speed
    register_type: read
    address: 0
    unit_of_measurement: "m/s"
    value_type: U_WORD
    accuracy_decimals: 1
    on_value_range:
      - above: 11
        then:
          - switch.turn_on: wind_speed_switch
    filters:
      - multiply: 0.1
      - max:
          window_size: 5
          send_every: 2
      - exponential_moving_average:
          alpha: 0.1
          send_every: 3

I know, I’m always right… except when rhe GF is around and then i cant get a flipping thing right lol.

Cool man, glad you got it working!

1 Like

I’ve noticed one issue: the on_value_range option only triggers when the value moves from outside the range to inside. This is problematic due to wind override. While I can work around it using script and interval components, I’m wondering if there’s an option to make on_value_range activate even when the value is within the range, as long as it satisfies the condition.

Use on_value with some conditions

1 Like
    on_value:
      if:
        condition:
          - sensor.in_range:
              id: greenhouse_temp
              above: 25.0
          - switch.is_off: wind_speed_switch  # Only proceed if wind_speed_switch is off
        then:
          - switch.turn_on: motor1
          - switch.turn_on: motor2

or use lambda:

condition:
   - lambda: |-
        return x > 25;
1 Like

that did the trick, Thanks everyone.