F2 crop steering: the daily operating manual
HomePrecisionF2 crop steering: the daily operating manual
Precision · Crop steering

F2 crop steering: the daily operating manual

By the end of this paper you can set up, calibrate, and run an autonomous irrigation controller for a veg grow room. It covers the P0–P3 daily cycle, moisture and salt targets, the controls you touch each day, the safety fail-safes built into the system, and how to diagnose what is wrong when something misbehaves.

Precision12 diagramsOperational guide~18 min read
Start here

Purpose and scope

Grain of salt

Operational / provisional: Default VWC numbers are one facility’s probe-native placeholders after hand-watering. Caplan drought supports controlled deficit as a concept, not a copy-paste of these exact setpoints. Calibrate media before arming automation.

F2 is an autonomous irrigation controller for a veg grow room. It is software that reads moisture and salt probes in the root zone and decides, on its own, when to fire a watering shot through a pump and valves. You set the targets. It does the watering.

Crop steering is the practice of choosing exactly how wet and how salty to keep the root zone in order to shift which kind of growth the plant prioritises. In the wild, a plant reads a drought as a signal that time is short and pivots toward reproduction—this system delivers that signal deliberately, at a controlled dose and moment. Vegetative steering (bulking) keeps the medium wet with many small waterings and a small drying-out. Generative steering (the flower or stress push) uses a bigger drying-out, a saltier root zone, and fewer, larger waterings. Even a mild, deliberate water deficit applied at the right time shifts a cannabis plant generatively without losing yield.[1]

The system runs in two cooperating layers. A Home Assistant integration gives you every on-screen control and reading. An AppDaemon engine (master_crop_steering_app.py) is the decision-making brain that fires the shots. The room is wired as 3 rows (zones), each with its own moisture and salt probe and its own valve, all fed from one shared tank, one pump, and one main line.

Layer 1
Home Assistant integration
The dashboard. Every control, setting and readout you see and touch.
Layer 2
AppDaemon engine
The autonomous brain. Reads probes, decides, fires shots through the hardware.
Layer 3
Hardware chain
Pump → main line → 3 zone valves. 3 probe pairs feed readings back up.
Figure 1. The two software layers and the hardware they drive. Controls flow down, probe readings flow back up.
Room layout: 3 rows from one tank1Veg tankshared watersource2Pumpone pump for allrows3Main linebranches to eachrow4Row 1/2/3 valvesone VWC + ECprobe eachOnly one row waters at a time.
Figure 2. One tank, one pump, one main line feeding three independently steered rows. Each row has its own probe pair and valve.
Two things to memorise
  • The ‘Phase (manual set)’ dropdown is an override. It shows what you last picked, not the live phase. Read sensor.crop_steering_current_phase for the truth.
  • Disarming is always safe by design. switch.crop_steering_system_enabled = OFF means nothing can fire, ever.
Vocabulary

Definitions

Three measurements run the whole system. Learn these first. Everything else builds on them.

VWC (volumetric water content)The medium holds water the way a sponge does—some of the space filled with liquid, the rest with air. VWC tells you how much of that space is water right now, expressed as a percentage. 60% VWC means water fills 60% of the medium's volume. This is the number all irrigation decisions start from.
EC (electrical conductivity)Salt dissolved in water makes it harder for plant roots to pull that water in—much as drinking salt water leaves you thirstier despite the liquid. EC measures how much dissolved salt is in the solution, in mS/cm, by testing how well electricity passes through it. Higher EC means a stronger, saltier solution; lower means weaker.
DrybackAfter each watering the medium slowly dries as the plant drinks. Think of it as the tidal cycle of the root zone: the high mark is right after a shot fires, the low mark is just before the next one. Dryback is the distance between those marks, shown as a percentage of the peak. A bigger gap pushes the plant toward generative growth; a smaller one keeps it building vegetatively. This gap is the primary steering dial.
ShotOne timed burst of water, sized as a percent of the medium's volume. The duration in seconds comes from substrate volume, dripper flow rate and shot size.
Field capacityThe saturated peak VWC right after irrigation drains. The medium's ‘full’ mark.
EC ratioMeasured EC divided by target EC. Above 1 means too salty, so water more to dilute. Below 1 means too weak, so hold back.
Vegetative vs GenerativeThe two steering modes. Each selects a different set of dryback and EC targets for the engine to chase.
Zone / phaseA zone (row) is one of the 3 independently steered sections. A phase is where a row sits in its daily P0–P3 cycle.
Where the core numbers live (typical veg ranges)Illustrative magnitudes only. Your calibrated numbers replace these.0918263530VWC %18Dryback %3EC mS/cm
Figure 3. The three living numbers behind every decision: how wet, how far it dries, and how salty.
Crop phase VWC dryback chart
Example. Phase polarity for autonomous steering: veg smaller drybacks, generative larger controlled drybacks.Educational diagram
A daily water-content cycleSaturate to field capacity, hold it, allow a controlled dryback, repeat. The size of the dryback is the steering lever.working bandtoo dry0255075100offP3 minonP1FCP2offwater content %
Diagram. The daily P0-P3 water-content cycle the controller runs: ramp to field capacity, maintain, controlled dryback.
Saturation, field capacity and drybackthe same block at three points in a daySaturatedjust irrigated, almostno airField capacityfree water drained,daily peakDryback lowplant drank, air +oxygen in
Diagram. Saturation, field capacity and dryback low, the points the daily cycle moves between.
Steering the plant with waterwetter, smaller swings = leafy; drier, bigger swings = flowerVegetativehigh water content, smalldryback, fast leafy growthGenerativelower water content, bigdryback, flower & ripening
Diagram. Steer vegetative or generative by where you hold the water and how big a dryback you allow.
Evidence assessment

Evidence and limitations

How sure is this paper?

We've gone to great lengths to keep these guides honest. One of the main ways we do that is self-review: we actively look for claims that are subjective, only lightly backed by literature, or based on grower practice rather than a controlled study — and we call those out instead of dressing them up as settled science.

Often there simply is no paper for the decision you're making. In those cases we're drawing on what other growers report and what has worked in our own rooms. That can still be useful — but it is not a lab proof. Do what works for your plants, your room, and your meters. If a table disagrees with your crop, believe the crop and log the difference.

Solid
Well supported by plant science, standards, or broad multi-source consensus
  • Emergency stop ≠ disarm is a correct safety design principle
  • Sensor-driven irrigation needs calibrated VWC, not raw factory %
Operational
What many growers and rooms actually run — start here, then tune
  • Phase machines and Home Assistant entity patterns for one facility class
Grain of salt
Subjective, thin literature, single studies, or “this works for us” practice
  • Default VWC numbers as universal substrate truth
  • Caplan drought as full proof of a specific P0–P3 recipe

See something glaringly wrong? Tell us and we'll fix it. Please open a GitHub issue with the paper name and what looks off (include a source if you have one): Report an accuracy issue. Local law, labels, and licences always override any recipe here. Inline notes labelled grain of salt flag the highest-risk over-trust points in the text.

Daily cycle

The P0–P3 daily cycle

Each row moves through four phases across the lights-on day, driven by the light schedule (defaults: lights on 10:00, off 22:00). The rhythm is always the same. Dry a little, refill, maintain, then wind down for the night.

  • P0 (morning dryback): after lights-on the system waters nothing and lets the medium dry a small amount (p0_dryback_drop_percent, e.g. 5–10%). Exits to P1 when that target is hit OR when p0_maximum_wait_time expires (default 120 min).
  • P1 (ramp-up): shots start at p1_initial_shot_size, grow by p1_shot_size_increment, are capped at p1_maximum_shot_size, spaced by p1_time_between_shots, and bounded by min/max shot counts. Exits when VWC ≥ p1_target_vwc.
  • P2 (maintenance): the bulk of the day. Waters whenever VWC drops below p2_vwc_threshold; if the EC ratio runs above ~1.2 it waters MORE (to dilute), below ~0.8 it holds back.
  • P3 (overnight): normal irrigation stops a set number of minutes before lights-off (p3_veg_last_irrigation / _gen_); only emergency top-ups fire below p3_emergency_vwc_threshold. Zones hold P3 all night.
VWC across one lights-on day (P0–P3)P0 gentle decline, P1 stair-step rise to target, P2 sawtooth maintenance, P3 overnight fall to the emergency floor.182226303410:00 onP0P1P2P2P222:00 offovernightVWC %
Figure 4. One steered day: a small morning dryback, a refill to target, a maintenance band, then a controlled overnight wind-down.
Phase transitions around the day1P3 overnightlights-on2P0 drybacktarget met /timeout3P1 ramp-upVWC ≥ target4P2 maintainbeforelights-off→ back toP3The loop repeats every lights-on cycle.
Figure 5. How a row walks the loop: overnight P3 into P0 at lights-on, up through P1 to P2, then back to P3 before dark.

The two steering modes pick which targets the engine chases. Vegetative means high VWC, modest dryback (~10–20%), lower EC (~3.0 mS/cm), many small shots. Generative means lower VWC, bigger dryback (~25–50%), higher EC (~4.5–6.0 mS/cm), fewer larger shots. Set the mode globally with select.crop_steering_steering_mode or per row. A row override beats the global, and ‘Follow Main’ means use the global.

The two steering recipes. Choose one per row, or let a row follow the main setting.
ModeVWC targetDrybackEC targetShot pattern
VegetativeHighModest (10–20%)~3.0 mS/cmMany small shots
GenerativeLowerBigger (25–50%)4.5–6.0 mS/cmFewer, larger shots
What you touch

Irrigation controls and targets

Day to day you touch a handful of controls. Two arm switches set how ‘on’ the system is. System enabled is the master arm. OFF means nothing irrigates ever, and the engine fails safe to OFF if it cannot read the switch. Auto irrigation only governs engine-driven shots. Turning it OFF still lets manual shots through, which is how you run ‘watch mode.’

The targets that steer growth are the per-phase VWC numbers (p1_target_vwc, p2_vwc_threshold), the dryback targets, and the per-phase and per-mode EC targets (ec_target_veg_p0..p3 and ec_target_gen_p0..p3). Per-row selects let you push one row generative while the others stay veg, set who waters first when only one row can fire, and group zones to coordinate them.

  • EC stacking switch ON lets the engine raise root-zone EC by reducing water, a generative push. Usually OFF for veg.
  • Hardware you can see: the pump (Tuya plug, ~490 W running), the main-line relay, and switch.f2_row1/2/3 zone valves. Only one waters at a time.
  • Per-row selects: steering_mode, crop_profile (Follow Main + 7 profiles), group (A–D), and priority (Critical / High / Normal / Low).
  • Shot duration is computed from substrate_volume, dripper_flow_rate, drippers_per_plant and shot size %. Set these correctly or every shot is the wrong size.
  • Per-row safety caps: max_daily_volume (L), shot_size_multiplier, and plant_count.
The two levels of ‘off’. Use ON/OFF together for watch mode while you calibrate.
System enabledAuto irrigationWhat happens
ONONNormal: autonomous shots fire AND manual shots work
ONOFFWatch mode: armed but observe-only, manual shots only
OFFeitherFully disarmed. Every shot blocked at the gate
Use watch mode before going autonomous

Run System enabled ON, Auto irrigation OFF while you confirm your numbers. The engine is armed and computing decisions but will not fire on its own. You can fire manual test shots and watch how the room responds before granting full autonomy.

How it decides

Irrigation decision gates

When the engine decides a shot is needed, that shot only fires if it passes every safety gate in order. A single failed gate blocks it. This is what stops an autonomous system making a bad call.

The gate chain (all must pass)1System armed?fail-safe:unreadable =blocked2Auto on?manual canbypass3Zone enabled & no override?row must be inplay4Not dosing/filling, tank not empty?low float mustread water5Source pH/EC in range, safety limits OK?then fire thehardwareAny failed gate blocks the shot.
Figure 6. Each check must pass before the next is tried. Only after the last gate does the hardware sequence run.
  • Order: system armed → auto-irrigation (manual bypasses) → zone enabled → no manual override → not dosing → tank not empty → source pH/EC in range (default pH 5.8–6.2) → safety limits (daily-volume cap, max-EC ceiling, max-frequency).
  • pH/EC out of range blocks the shot and sends a phone alert with an ‘Irrigate Anyway’ button.
  • Tank guard blocks only when the low float reads empty, so the system can keep watering as the tank drains down.
Hardware fire sequence (when all gates pass)1Pump ON2 s prime2Main line ON1 s settle3Zone valve ONhold calculatedduration4Shut downvalve →main → pumpOFFComponents shut off in reverse order to avoid water hammer and dead-heading the pump.
Figure 7. The physical watering sequence: build pressure first, open the row, hold for the computed duration, then back out in reverse.
What ungated source water does

Source water that drifts out of the pH or EC window can lock out nutrients or burn roots. Gating on it, and alerting you rather than watering quietly, guards against feeding a bad solution to the whole room.

Do this first

Calibration procedure

Calibration is the most important practical step. The system only behaves correctly if its number entities match your actual medium. The factory defaults are placeholders (50% VWC / 50% dryback), not your substrate. Dielectric moisture probes read differently in every medium, so a substrate-specific calibration is what makes the numbers mean anything.[2]

  1. 1
    Observe
    Hand-water normally for a few days and watch each row's VWC. The reading just after watering is roughly field capacity (the peak). The reading just before the next watering is the trough. Together they define that row's operating band.
  2. 2
    Set the band
    Set field_capacity just above the highest peak, p1_target_vwc to each row's post-water peak, and p2_vwc_threshold a few percent below that. A smaller gap means a tighter veg band.
  3. 3
    Set the drybacks
    Veg ~15–20%, gen ~25–45%. p0_dryback_drop_percent 5–15%. Set the emergency floor a few percent below the normal trough.
  4. 4
    Set EC targets
    Slightly above feed EC for veg, well above for generative. p2_ec_high/low_threshold are multipliers on target (1.2 dilutes above 120%, 0.8 conserves below 80%).
  5. 5
    Run and refine
    Let it run a few cycles in watch mode, compare predicted against actual, and tighten the numbers.
Reading one row's operating bandPeaks (after watering) and troughs (before next) from hand-watering set every threshold.P3 floortroughP2 bandP1 targetfield cap8% VWC21% VWC34% VWC
Figure 8. The band you read from hand-watering: the emergency floor sits below the trough; the P2 band sits below the P1 target; field capacity caps the top.

Root growth itself changes how the probe reads over a run, so re-check the band occasionally rather than calibrating once and forgetting it.[4]

The source's recommended F2 starting numbers, derived from its hand-watered ranges. Starting points, not final settings.
SettingRow 1Row 2Row 3What it does
p1_target_vwc262218Peak VWC P1 refills to
p2_vwc_threshold221915Water when VWC drops below this
vegetative_dryback_target181818How far P0 dries (%)
p0_dryback_drop888Morning dryback amount (%)
emergency floor151411P3 overnight top-up trigger
field_capacity (global)303030Saturated peak / ‘full’ mark
Defaults are placeholders, not your substrate

If you skip calibration and run the 50%/50% factory defaults, the steering is meaningless. The engine chases numbers that have nothing to do with your medium. Calibrate first, then arm.

Everyday tasks

Routine operating procedures

Most routine actions have a safe, prescribed method. Prefer the integration services over raw switch-flipping. The services run the full gated hardware sequence so you cannot skip a safety check by accident.

Quick-reference for the jobs you'll do most. When in doubt, use the service, not the raw switch.
TaskSafe methodCaution
Fire a manual shotService crop_steering.execute_irrigation_shot (zone, duration_seconds, shot_type: manual)Runs the full gated sequence
Raw hardware (last resort)Pump → main → valve ON; reverse to stopOne row at a time only
Force a phaseChange select.crop_steering_irrigation_phaseImmediate; bypasses normal transitions; selector then shows that phase
Irrigate Anyway overridePhone button after a pH/EC alert30-min bypass of the pH/EC gate ONLY; auto-clears when readings return in range
Disable vs pause a rowzone_N_enabled OFF (excluded) vs zone_N_manual_override ON (stays in steering)Pause = hand-water while steered
Switch to generativeSelect ‘Generative’ on steering mode (global or per-row)Per-row beats global
Reset water countersAutomatic: daily at midnight, weekly MondayRestart AppDaemon to re-init early
‘Irrigate Anyway’ is narrow on purpose

It grants a 30-minute bypass of the pH/EC gate only. Every other interlock still applies: system armed, tank not empty, daily-volume cap. It auto-clears the moment pH/EC return in range.

When it goes wrong

Safety interlocks and troubleshooting

The system has layered fail-safes: the pH/EC source-water gate, a tank dry-run guard (blocks only when the low float reads empty), a blocked-dripper guard that parks a row for 2 hours after too many failed shots, fail-safe reads (an unconfirmed arm switch is treated as disabled), and persistent state saved every 5 minutes so zones come back in their saved phase after a restart.

The EMERGENCY button does NOT disarm the engine

There are two ways to force-stop and they differ in a way that matters. The dashboard EMERGENCY, ALL OFF button (script.f2_irrigation_all_off) kills the three hardware pieces fast but leaves the engine armed. It may re-energise on its next ~60 s phase-check. To truly disarm, flip System enabled OFF. For anything beyond a brief stop, use both.

Two ways to stop, and what each one leaves behind. Only System enabled OFF disarms durably.
TriggerWhat it touchesEngine state after
Dashboard EMERGENCY buttonKills pump, main, valves fastStill ARMED, can re-fire next ~60 s check
System enabled OFFBlocks every shot at the gateDurably DISARMED
Engine auto emergency stopInternal: parks the affected rowArmed, but offending row held
  1. 1
    Fix the root cause
    Sort the physical problem first: empty tank, kinked line, bad probe, blocked dripper.
  2. 2
    Confirm hardware off
    Verify pump, main line and all valves read off.
  3. 3
    Check engine arm state
    Look at System enabled and Auto irrigation before re-arming.
  4. 4
    Re-arm and sanity-check
    Re-arm, then read sensor.crop_steering_current_phase for the live phase.
  5. 5
    Watch one cycle
    Do not walk away. Watch a full cycle fire correctly before trusting it again.
The troubleshooting list from the source. Most faults trace to a physical cause or a stale flag.
SymptomLikely causeWhat to do
Zones stuck in one phaseTransition condition never met / bad targetCheck the phase's exit threshold against live VWC
Valve open but no flowPump off, kinked line, blocked dripperCheck pump state and the line; clear the dripper
Status / Water-today reads unknownEngine not running or sensors unpopulatedRestart AppDaemon; confirm probes report
Repeated pH/EC alertsSource water genuinely out of range, or sensor driftTest the solution; verify the pH/EC probe
Row repeatedly parked as blocked dripper4+ failed shots in 30 minClear the physical dripper; row auto-releases after 2 h
‘Irrigation already in progress, skipping’ every cycleStuck flag after a mid-shot killRestart AppDaemon (ha addons restart a0d7b954_appdaemon). Phase + counters restore from disk
A known data gap to watch

The source flags that sensor.crop_steering_dryback_percentage and substrate EC reads can be suspiciously low (Row 1 at 0.48 mS/cm). Salinity strongly affects how dielectric probes report.[3] Check probe calibration before trusting EC steering.

Reality check

Expected results and limitations

This is a controller, not a magic autopilot
  • Steering quality is bounded by calibration. The factory 50%/50% defaults are placeholders. Replace them with numbers from your own medium before you trust autonomous mode.
  • Run watch mode first. Armed but observe-only, so you confirm thresholds and hand-test plumbing before granting full autonomy.
  • Recommended numbers are starting points. Refine them over several cycles. Treating them as final is how rooms get over- or under-watered.
  • Some sensors can mislead. Dryback-percentage may be unpopulated and EC can read suspiciously low. Verify probe calibration before trusting EC steering.
  • Fail-safes guard hardware, but they trust the sensors. A bad probe or float can still cause a wrong decision well inside the ‘safe’ envelope.

Treat F2 like a precise tool, not an oracle. Tracking your numbers over time the way a process-control chart does lets you separate a real signal from ordinary variation before acting on it.[5] For the cultivation theory behind the dryback and EC levers, read the coco crop steering paper. To understand the probes the whole system trusts, read root-zone sensing next.

Related papers

References

  1. Caplan, D., Dixon, M., & Zheng, Y. (2019). Increasing Inflorescence Dry Weight and Cannabinoid Content in Medical Cannabis Using Controlled Drought Stress. HortScience, 54(5), 964-969. https://doi.org/10.21273/HORTSCI13510-18
  2. Zawilski, B. M., Granouillac, F., Claverie, N., Lemaire, B., Brut, A., & Tallec, T. (2023). Calculation of soil water content using dielectric-permittivity-based sensors - benefits of soil-specific calibration. Geoscientific Instrumentation, Methods and Data Systems, 12, 45-56. https://doi.org/10.5194/gi-12-45-2023
  3. Qi, Q., Yang, H., Zhou, Q., Han, X., Jia, Z., Jiang, Y., Chen, Z., Hou, L., & Mei, S. (2024). Performance of Soil Moisture Sensors at Different Salinity Levels: Comparative Analysis and Calibration. Sensors, 24(19), 6323. https://doi.org/10.3390/s24196323
  4. Kang, S., van Iersel, M. W., & Kim, J. (2019). Plant root growth affects FDR soil moisture sensor calibration. Scientia Horticulturae, 252, 208-211. https://doi.org/10.1016/j.scienta.2019.03.052
  5. Mohammed MA. Statistical Process Control. Cambridge University Press (Elements of Improving Quality and Safety in Healthcare); 2024. https://doi.org/10.1017/9781009326834

Citations marked in-text as [n] map to this list. Primary literature and official guidance except where noted. Cannabis tissue culture is strongly genotype-dependent, verify dilutions, hormone doses and local regulations against the primary sources before relying on them.