Planning System
The greenhouse runs itself. Three times a day, an AI agent named Iris analyzes 72 hours of weather forecasts, current sensor data, equipment state, and accumulated lessons — then writes a complete setpoint plan that the ESP32 controller enforces autonomously.
How It Works
Forecast Data → Iris AI (3×/day) → 72h Setpoint Plan → ESP32 Controller → Equipment
↑ ↓
Deviation Monitor ← Observed vs Forecast (every 15 min) ←────┘
The Planning Cycle
6 AM — Morning Cycle: Iris gathers overnight data, checks the 72h forecast, validates yesterday’s plan outcomes, and writes a fresh plan covering the next three days. The overnight recap and today’s outlook are posted to Slack.
12 PM — Midday Cycle: Reviews the morning’s performance, adjusts afternoon setpoints if the forecast missed, and updates the remainder of the plan horizon. Solar peak data informs grow light and misting decisions.
6 PM — Evening Cycle: Scores the full day, extracts lessons, sets overnight heating parameters, and previews tomorrow. The end-of-day summary goes to Slack.
Atomic Plan Replacement
Each plan is a complete replacement — not a patch on top of the previous one. When Iris writes a new plan:
- Deactivate all future waypoints from all previous plans
- Insert the new 72h plan (10 core parameters × every transition point × 3 days)
- The ESP32 dispatcher reads only active waypoints, so the switchover is instant
This eliminates the “tug of war” problem where overlapping plans fought each other.
The 10 Core Parameters
Every plan explicitly sets these parameters at every transition point:
| Parameter | What It Controls | Typical Range |
|---|---|---|
temp_high | Cooling trigger (COOL_S1) | 78–85°F |
temp_low | Heating trigger (HEAT_S1) | 55–62°F |
vpd_high | Humidity target (HUMID_S1 trigger = vpd_high + hysteresis) | 1.4–2.2 kPa |
vpd_hysteresis | Deadband around VPD target | 0.2–0.5 kPa |
d_cool_stage_2 | Delta above temp_high for Stage 2 cooling | 2–5°F |
mister_engage_kpa | VPD threshold to start misting | 1.2–1.8 kPa |
mister_all_kpa | VPD threshold for all-zone misting | 1.4–2.2 kPa |
mister_pulse_on_s | Mister burst duration | 30–90s |
mister_pulse_gap_s | Gap between mister bursts | 20–60s |
mister_vpd_weight | Zone rotation weighting | 1.0–3.0 |
The Learning Loop
Iris doesn’t just react — it learns. Every plan includes a hypothesis and experiment:
- Before planning: Validate the previous plan’s outcome (score 1-10)
- During planning: Check accumulated lessons, design one experiment
- After planning: Record hypothesis + expected outcome in the plan journal
- Next cycle: Score the result, extract a lesson if something was learned
Lessons accumulate in a planner_lessons table with confidence levels. High-confidence lessons (validated 5+ times) are hard rules. Low-confidence lessons are suggestions.
Deviation Monitoring
The forecast isn’t always right. Every 15 minutes, a deviation monitor compares:
- Actual temperature vs forecasted temperature (threshold: ±5°F)
- Actual humidity vs forecasted humidity (threshold: ±15%)
- Actual solar radiation vs forecasted solar (threshold: ±200 W/m²)
When a deviation exceeds the threshold, the monitor triggers an unscheduled replan. Iris sees the deviation in its context and adjusts the full 72h plan against actual conditions instead of the wrong forecast.
Daily Plan Documents
Every day produces a plan document at plans with:
- Per-cycle sections (morning, midday, evening) with reasoning and waypoint tables
- 7-day stress context showing trends
- End-of-day climate summary, stress hours, costs, equipment runtimes
- Experiment tracking and outcome scores
These documents are the audit trail — you can see exactly what Iris decided, why, and how it turned out.
→ See Daily Plans for the full archive → See Controller for how the ESP32 enforces the plan → See Data Architecture for the database that stores everything