← Wiki

Concept

Recipe: closed-loop greenhouse climate controller

Also known as: greenhouse controller recipe, VPD controller recipe

Reference design composed from the farm-tech toolkit: a single-greenhouse climate controller that reads temperature, humidity, light, and soil moisture; controls vents, fans, shade, irrigation valves, and supplemental lighting; computes vapor-pressure deficit (VPD) and Daily Light Integral (DLI); and produces a complete observability dashboard. Demonstrates the canonical Home Assistant + ESPHome + ESP32 stack as the right composition for a single-building automation problem.

Problem statement

A 30 ft × 60 ft hoop-house or attached greenhouse needs:

  • Daytime temperature 70–85°F, nighttime 55–65°F
  • Humidity below 80% (above invites botrytis)
  • Vapor-pressure deficit (VPD) in the 0.8–1.2 kPa range during photosynthesis hours
  • Daily Light Integral (DLI) ≥12 mol·m⁻²·day⁻¹ for tomato-class crops; supplement on dark days
  • Per-bed irrigation tied to soil moisture
  • Continuous alerting if any condition goes out of safe range

Architecture

[ESP32 #1 — sensor node]         [ESP32 #2 — actuator node]
  BME280 (canopy T/RH)              4× relay → solenoid valves (irrigation)
  PAR sensor (TSL2591)              2× relay → exhaust fans
  4× capacitive soil-moisture       2× relay → supplemental lights
  leaf-wetness sensor               servo → roof-vent actuator

        WiFi / native API ───►   Home Assistant on Raspberry Pi 5

                              dashboards · automations · alerts

Key automations (Home Assistant YAML, conceptual)

automation:
  - alias: "Vent on high temp"
    trigger: numeric_state(canopy_temp, above: 85)
    action:
      - servo.set_position: open
      - switch.turn_on: exhaust_fans

  - alias: "Supplemental light if DLI behind"
    trigger: time(15:00)
    condition: numeric_state(dli_today, below: 8)
    action:
      - switch.turn_on: grow_lights
      - delay: until DLI ≥ 12 OR sunset
      - switch.turn_off: grow_lights

  - alias: "Irrigate bed-3 on low moisture"
    trigger: numeric_state(bed_3_moisture, below: 30)
    condition: time(06:00 - 18:00)  # avoid wet leaves overnight
    action:
      - switch.turn_on: valve_3
      - delay: 8 minutes
      - switch.turn_off: valve_3

  - alias: "Disease-pressure alert"
    trigger: leaf_wet_hours > 8 AND temp 18-26°C
    action:
      - notify: "Apple scab / botrytis pressure — consider spray window"

What ESPHome makes free

Each ESP32’s firmware is ~50 lines of YAML — sensor declarations, actuator declarations, native-API encryption keys. No C++. No cross-compilation pipeline. Updates are OTA over WiFi. New sensors are added by editing YAML and reflashing.

Cost

  • 2× ESP32 dev boards: $20
  • BME280, PAR sensor, 4× soil moisture, leaf-wetness: ~$60
  • 4× relay module + 4× solenoid valves: $80
  • Servo or linear actuator for vent: $30
  • Pi 5 (4 GB) + SD + power: $100
  • Total: ~$290 for full closed-loop control of one greenhouse.

See also

Auto-generated from this entry’s typed relations: frontmatter, grouped by relation type so the editorial signal isn’t flattened.

  • Combines: [[esp32]] · [[esphome]] · [[bme280-environmental-sensor]] · [[par-light-sensor]] · [[capacitive-soil-moisture-sensor]] · [[leaf-wetness-sensor]] · [[solenoid-valve]] · [[servo-motor]] · [[home-assistant]] · [[raspberry-pi]]

What links here, and how

Inbound connections from across the wiki, grouped by lens and by relationship. These appear automatically — every entity page declares what it links to, and that data populates here on the targets.

Practical

contains

parallels

  • Light as a working substrate greenhouse climate control is largely a light-management problem; supplementing DLI is the load-bearing automation

2 inbound links · 10 outbound