Automations · Home Assistant

Agricultural Automation Cookbook.

Reading time
~29 min · 5,802 words
FAQ
0 questions
Status
Draft 1 · under review
Section
All Home Assistant pages

This page is a reference collection of tested automation patterns for agricultural operations in Home Assistant. Each recipe is a specific pattern — a high-temperature alert, a moisture-triggered irrigation cycle, a DLI-target supplemental lighting automation — with its structure, its prerequisites, its variations, and its known failure modes. The recipes are not exhaustive. They are the patterns that have been tested across enough member operations to be trusted as starting points. A grower building their system can read a recipe, adapt it to their specific sensors and setpoints, and have a working automation in minutes. The recipes also document decisions that matter: why hysteresis appears in every threshold rule, why every wait has a timeout, why critical automations verify their actions rather than assume them. This seed version contains eight recipes covering climate alerts, irrigation, lighting, VPD, photoperiod, cold chain, multi-zone summaries, and safe equipment operation. The Cookbook is a living document — recipes are added as the collective's experience deepens, and existing recipes are revised when better approaches emerge.

How to use this cookbook.

The Cookbook is organized as a reference, not a tutorial. Each recipe stands alone; readers do not need to read the Cookbook in sequence. Use the page's navigation to jump to the recipe that matches the current need.

Read the prerequisites first. Every recipe assumes certain sensors, helpers, and naming conventions are in place. A recipe whose prerequisites are not met will not work; skimming the prerequisites before copying the pattern saves time.

Adapt rather than copy blindly. The recipes use illustrative entity names (`sensor.greenhousezone1_temperature`). Real operations have their own names. Replace the illustrative entity IDs with the operation's actual entities when implementing a recipe.

Respect the safety notes. Recipes that control physical equipment (irrigation valves, heating, lighting, ventilation) include safety considerations that are not optional. Hysteresis, timeouts, verification, fail-safe defaults — these details are the difference between a pattern that works for a weekend and one that works for a year.

Link to the related pages for depth. Each recipe links to the agricultural configuration pages and the automation pattern pages that explain the theory behind it. When something in a recipe is unclear, the deeper page usually has the explanation.

The recipe format.

Every recipe in the Cookbook follows the same structure so readers know what to expect.

What it does. One or two sentences describing the pattern's purpose in plain terms.

When to use it. The situations where this recipe fits, and when a different pattern would be more appropriate.

Prerequisites. The sensors, helpers, or other automations this recipe depends on.

The pattern. A narrative description of the recipe's logic, followed by a CC directive that generates working YAML at render time. The narrative explains the structure; the YAML gives the implementation. Readers who understand the pattern can implement it themselves; readers who want the YAML can copy and adapt it.

Variations. Two to four ways the recipe can be adjusted for different operations. Some variations simplify; some add sophistication.

Failure modes. Specific things that go wrong with this pattern in production. Forewarned is forearmed.

See also. Links to related recipes, agricultural configuration pages, and pattern pages.

Before using any recipe.

Prerequisites that apply across the Cookbook.

Integrations and sensors installed. Every recipe assumes the relevant sensors and actuators exist as Home Assistant entities. Adding a sensor is covered in [Your First Sensor](/home-assistant/getting-started/first-sensor); adding custom devices is covered in [ESPHome](/home-assistant/integrations/esphome).

Areas and naming conventions established. Per [Organizing Home Assistant for a Farm](/home-assistant/agriculture/organizing). The recipe YAML uses representative entity names; real deployments have their own naming conventions that the entity references need to match.

Automation and template fundamentals understood. [Automation Fundamentals](/home-assistant/automations/fundamentals), [Template Sensors](/home-assistant/automations/templates), [Scripts and Scenes](/home-assistant/automations/scripts-scenes), and [Advanced Automation Patterns](/home-assistant/automations/advanced-patterns) cover the building blocks the recipes use.

Hardware safety in place. Home Assistant automations handle operational control; hardware handles catastrophic cases. Every recipe assumes the operation has appropriate hardware protection (thermal cutoffs, float switches, fuses, contactors) for the equipment being controlled.

High-Temperature Alert with Hysteresis.

What it does. Sends a notification when a zone's temperature rises above a threshold, and sends a recovery notification when the temperature drops back to a lower threshold. The hysteresis gap prevents repeat alerts as the temperature bounces around the threshold.

When to use it. The foundational pattern for any temperature-out-of-range alerting. Applies to greenhouses, propagation zones, cold storage, and anywhere a temperature needs to stay within bounds. Not the right pattern for tight control loops (where [Climate Control Patterns](/home-assistant/agriculture/climate-control) applies) but the right pattern for reliable alerts.

Prerequisites.

- A temperature sensor for the zone (`sensor.greenhousezone1temperature` in the example). - A notification service configured (mobile app, SMS, Telegram, or similar). - Optional: an `inputboolean` interlock to disable the alert during known-maintenance periods.

The pattern. Two automations. The first triggers on temperature rising above the high threshold and staying there for at least a brief duration (to suppress spikes from sensor noise). It sends an alert with the zone name, current temperature, and threshold. The second triggers on temperature falling below the recovery threshold (several degrees lower) and sends a recovery notification. Between the two thresholds, the sensor can fluctuate without re-triggering either alert.

Variations.

- Lower threshold for cold storage or winter unheated spaces. Replace the above/below pair with the appropriate low-temperature thresholds. - Multiple zones with one pair of automations. Add multiple triggers (one per zone entity) with trigger IDs, and include the zone name in the alert through trigger-variable substitution. - Severity tiers. Three thresholds instead of two — warning, serious, critical — with different notification targets and message urgency. - Time-of-day sensitivity. Different thresholds during day and night, reflecting the crop's different tolerance by photoperiod.

Failure modes.

- Sensor noise causes rapid re-triggering. Add the `for:` duration requirement to the trigger so brief excursions do not alert. - Alert fatigue from too-tight thresholds. A threshold set too close to the normal operating range sends alerts constantly, and growers start ignoring them. Set thresholds above the normal range's natural fluctuation. - Recovery never fires because hysteresis gap is too wide. A gap of 10°F between trigger and recovery may produce alerts that "never recover" on slow-cooling days. Tune the gap to the operation's thermal dynamics.

See also. [Climate Control Patterns](/home-assistant/agriculture/climate-control) for tight-loop control, [Notification Services](/home-assistant/integrations/notifications) for alert routing options, and the "Dead-Man Switch" recipe below for detecting sensor failures that would otherwise hide behind this recipe's silence.

Moisture-Triggered Irrigation with Safety Caps.

What it does. Starts an irrigation cycle when soil moisture drops below a threshold, with caps on how often cycles can run per day and per hour.

When to use it. Most responsive irrigation scenarios — field crops, greenhouse soil zones, container production. Not the right pattern for scheduled-only irrigation (where a simple time-based automation is cleaner) or for systems where every irrigation decision is made by an external controller.

Prerequisites.

- A soil moisture sensor for the zone (`sensor.greenhousezone1soilmoisture`). - An irrigation valve controllable by Home Assistant (`switch.greenhousezone1valve`). - Optional: a flow meter for verification (`sensor.greenhousezone1flowrate`). - A helper counter `counter.zone1irrigationcyclestoday` that resets daily. - A helper `inputdatetime.zone1last_irrigation` updated at the end of each cycle.

The pattern. An automation triggered on moisture dropping below threshold. Conditions check that the daily cycle cap has not been hit, that enough time has passed since the last irrigation (minimum interval), and that the current time is within the irrigation window (daytime, or whatever the operation's schedule allows). On trigger, the automation calls a script that opens the valve, waits for a configured cycle duration, closes the valve, updates the last-irrigation helper, and increments the cycle counter. Optionally the script verifies flow during the cycle and alerts if flow is not detected when the valve should be open.

Variations.

- Fertigation instead of plain water. Add an injector control step before the valve opens, with its own verification. - Variable cycle length. Use a choose block in the script to pick cycle duration based on the depth of the moisture deficit — a small deficit gets a short cycle, a deep deficit gets a longer cycle. - Zone-shared pump. Before opening the zone valve, verify no other zone is currently irrigating by checking an `inputboolean.irrigationpump_busy` interlock. Set the interlock at the start of the cycle and clear it at the end. - Rain cancellation. A condition that checks a weather integration and skips irrigation during or immediately after significant rainfall.

Failure modes.

- Stuck valve continues irrigating. The automation commands closed; the valve does not close. Fix: flow-based verification after the close command; hardware timeout on the valve power circuit; scheduled "all valves closed" check at end-of-day. - Sensor drift causes runaway cycles. A moisture sensor drifting low reads below threshold constantly; the cap stops additional cycles but the grower sees many same-day cycles as a symptom. Fix: the daily cap is working as intended; the remediation is sensor calibration or replacement. - Cap too conservative. A cycle cap that was right for normal conditions cuts off needed irrigation during a heat wave. Fix: the cap is a safety net; during extreme conditions the grower may need to temporarily raise it through the input_number helper.

See also. [Irrigation Control](/home-assistant/agriculture/irrigation) for deeper treatment, [Advanced Automation Patterns](/home-assistant/automations/advanced-patterns) for the choose block and wait-for-trigger patterns, and the "Safe Valve Close" recipe below for the verify-and-retry pattern.

DLI-Target Supplemental Lighting.

What it does. Runs supplemental lighting as needed to hit a daily DLI target, turning off once the target is met. Saves electricity compared to fixed-schedule supplemental by running only when natural light is insufficient.

When to use it. Greenhouse operations with supplemental lighting and a DLI tracking sensor. Not needed for indoor operations where natural light is not a factor (use a simple photoperiod schedule instead).

Prerequisites.

- A PAR sensor for the zone (`sensor.greenhousezone1par`). - A DLI template sensor for the zone (`sensor.greenhousezone1dli`), implemented per [Template Sensors](/home-assistant/automations/templates). - A daily DLI target (`inputnumber.zone1dlitarget`, default 20 mol/m²/d for leafy crops). - A supplemental lighting switch or dimmer (`switch.greenhousezone1supplementallights`). - A daily reset that clears the DLI accumulator at the start of each day.

The pattern. Two automations and an optional template sensor. The first automation turns supplemental lighting on when natural PPFD drops below a threshold (e.g., 200 μmol/m²/s) for a sustained period, and the daily DLI target has not yet been met. The second automation turns supplemental off when either PPFD rises above a recovery threshold (hysteresis), or the DLI target is met, or the photoperiod ends. An optional third template sensor computes "DLI remaining to target," which can drive dashboard displays and informs whether to run supplemental during marginal natural-light conditions.

Variations.

- Dimmable supplemental. Instead of on/off, modulate intensity to maintain a total PPFD target, with the dim value calculated from current natural PPFD. - Time-of-use electricity rate awareness. Prefer on-peak hours for supplemental only if DLI is falling behind schedule; prefer off-peak for catch-up. - Weather forecast integration. If the afternoon is forecast to be sunny, tolerate a slower DLI accumulation through the morning; if forecast cloudy, run supplemental aggressively early. - Minimum runtime. Avoid brief on-off cycles from passing clouds by requiring supplemental to stay on for a minimum duration once triggered.

Failure modes.

- PAR sensor in partial shade reads wrong. Supplemental turns on when it should not. Fix: sensor placement matters; the sensor should see the same conditions the crop sees. - DLI target set for wrong crop. Supplemental runs far more than needed (target too high) or far less (target too low). Fix: match target to crop — see [Lighting Control](/home-assistant/agriculture/lighting) for starting ranges. - Stuck relay leaves supplemental on. The off command succeeds but the physical fixture stays on. Fix: power monitoring on the lighting circuit, PAR-based verification that supplemental actually turned off.

See also. [Lighting Control](/home-assistant/agriculture/lighting) for deeper treatment of lighting strategies, [Template Sensors](/home-assistant/automations/templates) for DLI implementation, and the "Dead-Man Switch" recipe for detecting PAR sensor failures.

VPD-Based Humidification Control.

What it does. Adjusts humidification or dehumidification to keep vapor pressure deficit within a target range for the zone's crop and stage.

When to use it. Any operation where VPD is the primary moisture-control target — most propagation, most fruiting and flowering operations, tight-tolerance commercial production. Not needed for operations where humidity alone suffices.

Prerequisites.

- Temperature and humidity sensors for the zone. - A VPD template sensor (per [Template Sensors](/home-assistant/automations/templates)). - Humidification or dehumidification equipment controllable by Home Assistant. - Target VPD range defined (e.g., `inputnumber.zone1vpdtargetmin` at 0.8, `inputnumber.zone1vpdtargetmax` at 1.2).

The pattern. Two automations working against the calculated VPD. When VPD falls below the target minimum (air is too saturated, transpiration suppressed), activate dehumidification. When VPD rises above the target maximum (air too dry, plants stress), activate humidification. Hysteresis applies — the activation thresholds and deactivation thresholds are separated by a gap to prevent equipment cycling.

Variations.

- Stage-specific targets. Use input_selects for growth stage; templates or automations pick target ranges based on the current stage. - Day-night differentials. Different VPD targets during photoperiod and dark period, matching crop physiology. - Leaf VPD instead of air VPD. When an IR leaf temperature sensor is available, use leaf VPD for tighter control. - Proportional response. Instead of on/off, modulate humidification intensity based on how far VPD is from target (requires variable-output equipment).

Failure modes.

- Temperature and humidity sensor drift produces wrong VPD. VPD calculation amplifies sensor inaccuracy. Fix: periodic calibration of source sensors; occasional comparison of two sensors in the same location. - Humidifier and dehumidifier fighting. Automations without proper interlocks run both simultaneously — wasted energy, no net effect. Fix: a condition on each ensuring the opposite equipment is off; or a single "climate mode" state machine that picks one direction at a time. - Equipment not sized for the zone. Control logic is fine but humidification capacity is inadequate; VPD stays out of range despite correct automation. Fix: sizing is a physical problem, not a software problem; the recipe does what it can.

See also. [VPD-Based Control](/home-assistant/agriculture/vpd-control) for deeper treatment, [Climate Control Patterns](/home-assistant/agriculture/climate-control) for ventilation coordination, and [Template Sensors](/home-assistant/automations/templates) for the VPD calculation.

Photoperiod Control with Light-Leak Detection.

What it does. Manages the main grow lights on a strict photoperiod schedule, and separately monitors for any light during the dark period that would interrupt photoperiod-sensitive flowering.

When to use it. Any indoor operation with photoperiod-sensitive crops — cannabis, chrysanthemums, poinsettias, many ornamentals. The light-leak detection catches the failure modes that cause the most damage (a stuck contactor, a light leak from an adjacent space, equipment LEDs during the dark period).

Prerequisites.

- A main grow light controlled by a switch or contactor (`switch.flowerroom1mainlights`). - A PAR or lux sensor in the room for verification (`sensor.flowerroom1par`). - Photoperiod schedule times (e.g., `inputdatetime.flowerroom1lightson` and `inputdatetime.flowerroom1lights_off`). - A notification target for light-leak alerts.

The pattern. Two automations for schedule control — one for lights-on, one for lights-off — using Home Assistant's native time triggers (which handle DST correctly). A third automation monitors the PAR sensor during the scheduled dark period and alerts if any light is detected. A fourth automation, optional but valuable, verifies the lights-off command actually took effect by checking the PAR sensor a few minutes after the command.

Variations.

- Manual override with expiration. An `inputboolean.flowerroom1override` that allows temporary light during the dark period for inspection, with an auto-expiry timer and alert if left on. - Graduated photoperiod shift. For operations moving from vegetative (18 hours) to flowering (12 hours), a scheduled transition that changes the photoperiod helpers over several days rather than instantly. - Multi-room photoperiod coordination. Multiple rooms on different schedules, with a check that no room's lights-on leaks into another room's dark period. - Sunrise simulation. A dimmable fixture ramped up over 15-30 minutes at lights-on rather than a hard on/off transition.

Failure modes.

- DST transition bug. A schedule written in fixed UTC shifts by an hour at DST transitions. Fix: always use local time in time triggers; test around DST dates. - Contactor welded closed. Lights stay on despite the off command. The verification automation catches this; the grower intervenes. Fix: this is the exact case the verification automation addresses. - Equipment LED during dark period. A piece of equipment with a bright status LED in the room triggers light-leak detection. Fix: either cover the LED or move the equipment; the alert is correctly identifying a real photoperiod risk. - Employee enters with a flashlight. Triggers a light-leak alert. Fix: the manual-override pattern (see variations) allows deliberate entry with time-limited light.

See also. [Lighting Control](/home-assistant/agriculture/lighting) for the deeper treatment of photoperiod management, [Automation Fundamentals](/home-assistant/automations/fundamentals) for time-trigger behavior, and the "Safe Valve Close" recipe for a related verify-after-command pattern.

Cold Chain Out-of-Range Alert with Persistent Log.

What it does. Detects when a cold storage temperature goes out of the acceptable range, alerts the responsible person, and writes a persistent log entry for compliance documentation.

When to use it. Packhouses, walk-in coolers, refrigerated transport staging, any cold storage where regulatory compliance requires documented temperature monitoring. Applicable beyond compliance — any cold chain where product loss from an extended excursion is costly.

Prerequisites.

- A temperature sensor in the cold storage (`sensor.walkincoolertemperature`). - Acceptable range defined (`inputnumber.walkincoolertempmax`, typically 40°F / 4°C; `inputnumber.walkincoolertempmin`, typically 32°F / 0°C). - A notification target, ideally one that reaches multiple people so a single absence does not miss the alert. - A logging destination — a notification service that writes to file, a database integration (InfluxDB, MariaDB), or a dedicated log file.

The pattern. Automations triggered on the temperature going above the max or below the min. An initial alert fires after a short sustained excursion (30-60 seconds to avoid noise spikes). An escalation alert fires if the condition persists for longer (5-15 minutes). Each trigger writes a log entry that includes the timestamp, the current temperature, the threshold, and the duration of the excursion. A recovery log entry is written when temperature returns to range.

Variations.

- Per-zone monitoring. Replicate the pattern per cooler, freezer, or room; naming conventions keep them distinguishable in logs. - Automatic door-open detection. A door sensor triggers a "door open" flag that suppresses the over-max alert for a configured duration (cold leaks out with the door open; the alert would be a nuisance). After the configured duration, the alert returns. - Mains power coordination. A power sensor that detects cooler electricity loss triggers an immediate high-priority alert (the cooler is off; temperature will soon drift out of range). - Time-to-threshold projection. A template that projects how long until the current trend crosses a threshold, and alerts when that projected time is short — "at current rate, max will be exceeded in 30 minutes."

Failure modes.

- Sensor placed in a cold spot or near a door. Temperature reads don't represent product temperature. Fix: sensor placement matters; ideally multiple sensors, or a placement selected to represent product-level temperature. - Defrost cycles trigger false alerts. Cold storage with periodic defrost cycles produces regular excursions that are normal. Fix: schedule exclusions aligned with defrost cycles; or use a more lenient threshold during defrost windows. - Log file fills up disk. Over years, a log file without rotation grows unbounded. Fix: log rotation configuration; or write to a database that handles retention. - Alert goes only to one person's phone. That person is unreachable when the alert fires. Fix: redundant notification paths (multiple people, multiple channels — SMS + app + email).

See also. [Cold Chain Monitoring](/home-assistant/agriculture/cold-chain) for deeper treatment, [Notification Services](/home-assistant/integrations/notifications) for alert routing options, and [Understanding Data](/fundamentals/understanding-data) for the logging and retention framework.

Multi-Zone Morning Status Summary.

What it does. Builds a summary of every zone's current conditions — temperature, humidity, VPD, DLI yesterday, soil moisture, last irrigation — and sends it to the grower at a scheduled time each morning.

When to use it. Operations with multiple greenhouse zones or growing rooms where the grower wants a one-message overview before starting the day. Reduces the need to check each zone's dashboard individually.

Prerequisites.

- The zones defined as areas in Home Assistant, with their sensors named consistently. - A list of zones to summarize (maintained in configuration or as an `inputtext` helper per operation). - A notification target. - Optional: the time for the summary, set via `inputdatetime.morningsummarytime`.

The pattern. A single automation triggered at the scheduled time. Its action uses a repeat with for_each to iterate over the list of zones, building up a summary message one zone at a time. Per zone, the summary includes key metrics (current temperature, humidity, VPD, yesterday's DLI, current soil moisture, time since last irrigation). The final action sends the accumulated message through the notification service. For operations with many zones, a multi-page format or a truncated "only zones with issues" variant is useful.

Variations.

- Evening summary. Parallel automation at end-of-day summarizing the day's events — total irrigation runtime, DLI achieved per zone, max and min temperatures, any alerts. - Issues-only mode. Instead of every zone, only zones with active alerts or concerning trends. Useful for operations where most zones are nominal most of the time. - Email format with graphs. For operations that want a richer summary, email with attached graph images (generated by Grafana or a similar tool) instead of plain-text notification. - Team distribution. Summary sent to multiple team members, with per-person filtering (some only get summaries for zones they are responsible for).

Failure modes.

- Zone added to the operation but not to the zonelist. The new zone silently does not appear in summaries. Fix: keep zonelist maintained as zones change; periodic review; or automate the list from an area-based query. - Sensor unavailable during summary generation. A missing value produces "unknown" in the summary or a template error. Fix: use availability-aware templates (per [Template Sensors](/home-assistant/automations/templates)) that produce "N/A" or similar rather than failing. - Summary too long for the notification service. Mobile notifications have length limits; SMS more so. Fix: truncate long summaries; split into multiple notifications; use email for full summaries and notifications for alerts only.

See also. [Multi-Zone Operations](/home-assistant/agriculture/multi-zone) for the broader multi-zone patterns, [Advanced Automation Patterns](/home-assistant/automations/advanced-patterns) for the repeat for_each pattern, and [Notification Services](/home-assistant/integrations/notifications) for delivery options.

Safe Valve Close with Verification and Retry.

What it does. Commands a valve closed and verifies the close took effect through flow-based confirmation. If confirmation fails, retries up to a configured number of times, and alerts the grower if the valve cannot be confirmed closed after retries.

When to use it. Any automation that closes an irrigation, fertigation, or water valve where a stuck-open valve would waste water, damage equipment, or harm the crop. The pattern fits as a script called from irrigation automations rather than as a standalone automation.

Prerequisites.

- The valve controllable through Home Assistant. - A flow sensor downstream of the valve (`sensor.zone1flowrate`). - A notification target for failure alerts. - Optional: an `inputboolean` that interlocks further irrigation for that zone until the valve state is resolved.

The pattern. A script with fields for the valve entity and the flow sensor entity. The script commands the valve closed, waits for flow to drop to zero (via waitfortemplate with a timeout), and checks whether the wait completed successfully. If the wait succeeded, the script logs the successful close and exits. If the wait timed out, the script retries — commanding close again (sometimes a second command works when the first did not), waiting again. After a configured number of retries, if the valve still is not confirmed closed, the script alerts the grower with the specific valve's identity, sets an interlock boolean, and exits.

Variations.

- Pressure-based verification. When flow sensors are not available but pressure sensors are, use pressure drop below a threshold as the confirmation signal. Useful for systems with pressure monitoring but no flow monitoring. - Timed-check fallback. Where neither flow nor pressure is available, a time-based "wait 30 seconds and hope" is a poor fallback; the better pattern is to upgrade the hardware to include confirmation. The script can include a "no-confirmation" path that logs and warns but does not pretend confirmation happened. - Escalation severity. On the first retry, log only; on the second, notify a secondary recipient; on the final failure, notify everyone including a fallback paging service. - Valve-slam-protection. If rapid close-retry cycles are bad for the valve, add a minimum delay between retries.

Failure modes.

- Flow sensor lags. Flow takes longer than the timeout to drop to zero because of a long pipeline or a slow-responding sensor. Fix: tune the timeout to the system; add a small margin. - Flow sensor stuck reporting zero. The valve is actually open but the flow sensor says no flow. The script "confirms" the close when it did not happen. Fix: periodic flow-sensor calibration or replacement; alerting on flow-sensor unavailability; secondary verification methods where the risk is high. - Manual override leaves the zone interlocked. The grower resolved the issue manually but forgot to clear the fault boolean. Subsequent automations refuse to act. Fix: clear-fault procedure documented; a dashboard button that clears all zone faults is useful; a scheduled weekly review of fault-state flags.

See also. [Advanced Automation Patterns](/home-assistant/automations/advanced-patterns) for the repeat, wait-for-template, and graceful-degradation patterns this recipe uses heavily, [Irrigation Control](/home-assistant/agriculture/irrigation) for the broader irrigation context, and the "Moisture-Triggered Irrigation" recipe above which should call this script for its close operation.

Common themes across recipes.

Patterns that recur throughout the Cookbook. Getting these right once applies everywhere.

Hysteresis, not hair-trigger. Every threshold rule has an activation threshold and a recovery threshold with a gap between them. The gap prevents equipment cycling and alert fatigue.

Timeouts on every wait. Every `waitfortrigger` and `waitfortemplate` has a timeout. No exceptions. An unwaited wait is a future problem.

Verification after commands that matter. Every command that controls physical equipment is followed by verification that the command took effect. Stuck relays, failed valves, wrong-state sensors are all caught by verification.

Hardware as the safety layer. Every recipe that controls physical equipment explicitly notes that hardware safety (thermal cutoffs, float switches, contactors) remains in place underneath. Home Assistant makes operations smarter; it does not replace safety hardware.

Specific names, specific numbers. Every recipe uses a specific illustrative entity name and specific numbers for thresholds. Growers adapt them; the specificity makes the recipe concrete rather than abstract.

Named failure modes. Every recipe includes the specific problems that affect it in production. The recipe is worth more than the YAML because the recipe tells growers what to watch for.