AI Planning Loop
Iris runs a setpoint planning cycle three times daily. Each cycle follows a structured process that validates the previous plan, gathers current conditions, reasons across all systems, and writes time-keyed waypoints to the setpoint_plan table.
The Cycle
Step 0: Validate Previous Plan
Before writing anything new, Iris reviews the last plan’s performance:
- Was the hypothesis correct?
- What was the actual stress outcome?
- Does this confirm or contradict an existing lesson?
Results go into plan_journal with a 1–10 score.
Step 1: Gather Context
gather-plan-context.sh collects 20+ data sections:
- Current zone conditions (4 zones × temp/RH/VPD)
- 24h stress patterns and trends
- 7-day DLI, DIF, water, and compliance history
- Weather forecast (16-day, 27 columns)
- Equipment runtime and health
- Active lessons from
planner_lessons - Previous plan journal entries
- ESP32 firmware min/max constraints
Step 2: Reason
Iris evaluates across all parameter families:
- Temperature: bands, staging, hysteresis, zone stratification
- VPD: thresholds, mister engage/all points, pulse tuning
- Misting: pulse duration, gap, zone weighting
- Economiser: enthalpy comparison (indoor vs outdoor)
- Irrigation: soil moisture, ET₀, VPD boost triggers
- Grow lights: DLI target vs forecast, circuit status
- Safety: seasonal review
Step 3: Write Waypoints
Time-keyed parameter changes for the next 8–12 hours:
INSERT INTO setpoint_plan (ts, parameter, value, plan_id, source, reason)
VALUES ('2026-03-28 18:00:00+00', 'vpd_high', 1.6, 'iris-20260328-1200', 'iris',
'Lower HUMID_S1 trigger for dry afternoon');Step 4: Write Journal Entry
Every plan includes:
- Hypothesis: What the planner expects and why
- Experiment: One specific thing being tested
- Expected outcome: Measurable, so the next cycle can score it
Step 5: Dispatch
The ingestor’s task loop picks up new waypoints every 5 minutes:
- Reads
v_active_plan(resolves supersession) - Compares planned values to current ESP32 state
- Pushes changes via aioesphomeapi (immediate)
- Writes to
setpoint_changes(DB record) - ESP32 also pulls from
/setpointsas fallback
The Learning Loop
| Table | Purpose |
|---|---|
plan_journal | Per-plan hypothesis, experiment, outcome, score |
planner_lessons | Persistent validated patterns (category, condition, lesson, confidence) |
Lessons accumulate confidence through validation:
- First observation: confidence =
low - 2+ validations:
medium - 5+ validations:
high
High-confidence lessons are mandatory — the planner must follow them or explicitly document why it’s overriding.
Example Lessons (seeded)
| Category | Condition | Lesson |
|---|---|---|
| misting | Pulse duration | 60s pulses are the sweet spot — 0.42 kPa VPD drop vs 0.12 for shorter |
| misting | Zone rotation | 1.5× VPD weight gives more even rotation than 2.0× |
| forecast | Open-Meteo bias | Consistently undershoots temp by 3–5°F. Add 4°F to forecast highs. |
| heating | Overnight protection | temp_low=60 with 2-stage works well for 30°F nights |
Goals (Priority Order)
- Minimize VPD stress hours
- Minimize heat stress hours (physics-limited)
- Maximize DLI
- Minimize water usage
- Minimize energy cost
- Maintain positive DIF (8–15°F day > night)
- Maximize compliance % (>50% target)