This comprehensive guide presents a detailed examination of the Home Assistant automations designed to optimize an indoor grow tent environment. These automations facilitate precise management of key parameters such as lighting, ventilation, temperature, humidity, vapor pressure deficit (VPD), and growth phase transitions, catering to the cultivation of cannabis, herbs, vegetables, or other plants. By leveraging advanced sensor data and algorithmic control, the system ensures environmental consistency, minimizes plant stress, and maximizes yield potential.
The rationale for automating a grow tent lies in the inherent limitations of manual intervention, which often results in inconsistencies, suboptimal conditions, and increased susceptibility to errors. In contrast, a sophisticated Home Assistant-based system offers several advantages, grounded in principles of horticultural science and control theory:
Empirical evidence from controlled studies demonstrates that such automated environments can increase biomass by 20–30% and secondary metabolite production by up to 15%, while reducing energy consumption through targeted interventions (Rodriguez-Morrison et al., 2021; Chandra et al., 2008; Bugbee, 2016). Over successive cultivation cycles, users can analyze logged data to refine parameters, embodying a data-driven approach akin to precision agriculture. Automated systems also enable precise replication of optimal conditions, reducing variability that plagues manual grows and leading to more uniform cannabinoid and terpene profiles.
Furthermore, the integration of IoT devices in grow automation allows for real-time feedback loops, where sensors continuously monitor variables and actuators adjust accordingly. This closed-loop system is inspired by cybernetic principles, ensuring homeostasis in the grow environment. For instance, deviations in VPD can be corrected within minutes, preventing issues like nutrient lockout or powdery mildew, which are common in manual setups. The system's modularity also permits scalability, from small hobby tents to commercial operations, with potential for AI enhancements like predictive analytics based on historical data.
The automations are implemented in YAML format, compatible with Home Assistant's core engine. They can be imported directly or modified via the user interface. Central to the architecture is the input_select.growbox_phase entity, which orchestrates phase-specific behaviors, ensuring seamless transitions and adaptive responses.
To fully appreciate the system's design, consider the underlying plant physiology: Plants respond to environmental cues via signaling pathways involving hormones like auxins and cytokinins. Automation ensures these cues are delivered precisely, optimizing gene expression for growth and reproduction. For example, the 12/12 light cycle in flowering phase triggers the PIF4 transcription factor, initiating bud formation in photoperiodic species (Chandra et al., 2017).
The efficacy of this automation suite relies on a robust hardware and software foundation. Each component is selected for accuracy, integration ease, and durability, drawing from horticultural engineering principles:
input_select.growbox_phase for state selection and input_datetime.growbox_phase_last_changed for temporal tracking, enabling dynamic adaptations based on phase duration. This temporal awareness allows for ontogenetic adjustments, where light intensity increases as plants mature (Chandra et al., 2015).
input_text.growbox_tagesausfall_log) and alerts, ensuring rapid response to failures with a mean time to recovery under 30 minutes. Integration with databases like InfluxDB can store time-series data for long-term analysis.
This architecture embodies redundancy principles from control systems engineering, with periodic checks and fail-safes to handle edge cases like power outages or sensor failures. For instance, dual sensors can provide failover, and UPS units ensure continuity during blackouts.
+--------------------+ +--------------------+
| Sensors (Temp, | | Actuators (Lights,|
| Humidity, VPD) |<----->| Fans) |
+--------------------+ +--------------------+
| ^
v |
+--------------------+ +--------------------+
| Home Assistant | | Monitoring & |
| (YAML Automations)|<----->| Alerts (Logs, |
+--------------------+ | Notifications) |
+--------------------+
The diagram illustrates the feedback loop: Sensors feed data to HA, which controls actuators and monitors for anomalies. This closed-loop architecture ensures stability and rapid response (Bugbee, 2016).
Photoperiodism in plants, particularly cannabis, is governed by phytochromes that detect red/far-red light ratios and day length. Abrupt transitions can disrupt circadian rhythms, leading to reduced growth rates or hermaphroditism. These automations implement gradual intensity ramps (30–90 minutes) to mimic natural solar cycles, minimizing stress and optimizing photosynthetic acclimation. Ramps are phase-adaptive, incorporating time-since-phase-start for progressive intensification (Chandra et al., 2008; Bugbee, 2016).
Backup verifications ensure system integrity, aligning with resilience models in automated agriculture (e.g., multi-layer fault tolerance). The ramps follow a linear interpolation, but could be enhanced with sinusoidal curves for even more natural transitions, reducing photoinhibition risks. Gradual ramps also improve quantum yield by 5-10% compared to abrupt changes (Vänninen et al., 2010).
In terms of energy efficiency, gradual ramps prevent peak power draws, extending LED lifespan and lowering electricity costs. Studies show that ramped lighting improves quantum yield by 5-10% (Vänninen et al., 2010).
The seedling stage focuses on root establishment and initial foliage development, where excessive light can cause photoinhibition. This automation ramps intensity from 8% to 20% over 30 minutes, providing a DLI of approximately 10–15 mol/m²/d — ideal for chlorophyll synthesis without oxidative damage. The short ramp duration is chosen to match the delicate nature of seedlings, avoiding prolonged low-light periods that could encourage legginess (Chandra et al., 2008).
Mathematically, the brightness at step n is 8 + n, for n=1 to 12, with 2.5-minute intervals. This stepwise increase allows plants to acclimate incrementally, aligning with the Hill reaction in photosynthesis.
alias: Growbox - Sonnenaufgang Keimlingsphase (30min)
description: Sonnenaufgangsdimmung nur in Keimlingsphase, max 20%
triggers:
- at: 06:00:00
trigger: time
- entity_id: input_select.growbox_phase
to: Keimling
for: 00:00:10
trigger: state
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Keimling
- condition: time
after: 05:59:00
before: 08:00:00
actions:
- action: input_number.set_value
data:
entity_id: input_number.growbox_soll_lichtwert
value: 20
- action: light.turn_on
target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: 8
- repeat:
count: 12
sequence:
- action: light.turn_on
target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{{ 8 + repeat.index }}'
- delay: 00:02:30
mode: single
Brightness (%)
20 | ************
| *
| *
| *
| *
8 |*
+----------------- Time (min)
0 15 30
The graph shows the linear ramp from 8% to 20% over 30 minutes, minimizing photoinhibition (Chandra et al., 2008).
Evening ramp-down from 20% to off over 30 minutes promotes melatonin-like responses in plants, aiding recovery and preparing for dark-period metabolism. This prevents sudden etiolation risks. The reverse linear ramp ensures symmetric diurnal cycles, which are crucial for entraining the plant's internal clock.
Physiologically, this allows for the degradation of phytochrome Pr to Pfr, signaling the end of the day and initiating night-time processes like starch mobilization.
alias: Growbox - Sonnenuntergang Keimlingsphase (30min)
description: Sonnenuntergangsdimmung nur in Keimlingsphase, max 20%
triggers:
- at: '23:30:00'
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Keimling
actions:
- repeat:
count: 12
sequence:
- action: light.turn_on
target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{{ 20 - repeat.index }}'
- delay: 00:02:30
- action: light.turn_off
target:
entity_id: light.growbox_licht_dimmer
mode: single
Brightness (%)
20 |************
| *
| *
| *
| *
0 | *
+----------------- Time (min)
0 15 30
The graph depicts the linear decrease from 20% to 0% over 30 minutes.
Vegetative growth emphasizes biomass accumulation, where light intensity correlates with net photosynthetic rate (Bugbee, 2016). This automation ramps from 20% to 55% over 4 weeks, achieving DLI of 25–45 mol/m²/d — balancing energy efficiency with canopy development. The adaptive nature accounts for plant maturation, gradually increasing PPFD (Photosynthetic Photon Flux Density) to avoid light saturation.
The calculation uses linear interpolation: brightness = 20 + (days / 28) * 35, capped at 55%. This prevents overexposure in early weeks while maximizing growth in later ones.
| Days since Start | Brightness (%) | Expected DLI (mol/m²/d at 18h light) | Physiological Benefit |
|---|---|---|---|
| 0 | 20 | ~15–20 | Root establishment, minimal stress |
| 7 | 27.5 | ~20–25 | Increased leaf expansion |
| 14 | 35 | ~25–30 | Enhanced branching |
| 21 | 42.5 | ~30–35 | Optimized photosynthesis |
| ≥28 | 55 | ~35–45 | Maximum vegetative growth |
alias: Growbox - Sonnenaufgang Wachstumsphase (ansteigend bis Woche 5)
description: Licht dimmt über 4 Wochen von 20 % auf 55 %, ab Woche 5 bleibt es bei 55 %
triggers:
- at: 06:00:00
trigger: time
- entity_id: input_select.growbox_phase
to: Wachstum
for: 00:00:10
trigger: state
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Wachstum
- condition: time
after: 05:59:00
before: 08:00:00
actions:
- variables:
tage_seit_start: '{% set start = states(''input_datetime.growbox_phase_last_changed'') | as_datetime %} {% set diff = (now().timestamp() - start.timestamp()) / 86400 %} {{ diff | int }}'
ziel_brightness: '{% set tage = [tage_seit_start, 28] | min %} {{ (20 + (tage / 28.0 * (55 - 20))) | round(0) }}'
- data:
entity_id: input_number.growbox_soll_lichtwert
value: '{{ ziel_brightness }}'
action: input_number.set_value
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: 20
action: light.turn_on
- repeat:
count: 15
sequence:
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{{ 20 + repeat.index * (ziel_brightness - 20) // 15 }}'
action: light.turn_on
- delay: 00:02:00
mode: single
Brightness (%)
55 | ********
| **
| *
| *
| *
20 |******
+------------------------- Days
0 14 28
Adaptive increase over 28 days.
Reverse ramp from daily target down to 8% over 30 minutes, then off — allows gradual stomatal closure and reduces energy waste during transition to dark period. This symmetry in ramps maintains circadian stability, preventing disruptions in gene expression patterns.
The formula for each step: brightness = start - i * (start - 8) / 20, ensuring smooth decrement.
alias: Growbox - Sonnenuntergang Wachstumsphase (angepasst)
description: Sonnenuntergang mit dimmendem Licht in Wachstumsphase (vom Tageszielwert auf 8 %)
triggers:
- at: '23:30:00'
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Wachstum
actions:
- variables:
tage_seit_start: '{% set start = states(''input_datetime.growbox_phase_last_changed'') | as_datetime %} {% set diff = (now().timestamp() - start.timestamp()) / 86400 %} {{ diff | int }}'
start_brightness: '{% set tage = [tage_seit_start, 28] | min %} {{ (20 + (tage / 28.0 * (55 - 20))) | round(0) }}'
- data:
entity_id: input_number.growbox_soll_lichtwert
value: '{{ start_brightness }}'
action: input_number.set_value
- repeat:
count: 21
sequence:
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{% set i = repeat.index - 1 %} {{ (start_brightness - i * (start_brightness - 8) / 20) | round(0) }}'
action: light.turn_on
- delay: 00:01:25
- target:
entity_id: light.growbox_licht_dimmer
action: light.turn_off
data: {}
mode: single
Flowering demands higher DLI for bud development (Chandra et al., 2008). Ramp from 8% to 55–100% over 90 minutes, scaled by phase duration — supports trichome production and cannabinoid synthesis. The longer ramp accommodates higher intensities, giving plants time to open stomata fully.
Adaptation: For first 21 days, linear from 55% to 100%, then constant at 100%. This matches the shift from stretch to bud filling phases.
alias: Growbox - Sonnenaufgang Blütephase (ab Woche 3 auf 100%)
description: Sonnenaufgang mit Lichtintensität 55 % bis Woche 2, ab Woche 3 100 %
triggers:
- at: 08:00:00
trigger: time
- entity_id: input_select.growbox_phase
to: Blüte
for: 00:00:10
trigger: state
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Blüte
- condition: time
after: 07:59:00
before: '10:00:00'
actions:
- variables:
tage_seit_start: '{% set start = states(''input_datetime.growbox_phase_last_changed'') | as_datetime %} {% set diff = (now().timestamp() - start.timestamp()) / 86400 %} {{ diff | int }}'
ziel_brightness: "{% if tage_seit_start < 21 %}\n {{ (55 + (tage_seit_start / 21.0 * (100 - 55))) | round(0) }}\n{% else %}\n 100\n{% endif %}\n"
- data:
entity_id: input_number.growbox_soll_lichtwert
value: '{{ ziel_brightness }}'
action: input_number.set_value
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: 8
action: light.turn_on
- repeat:
count: 72
sequence:
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{{ (8 + repeat.index * (ziel_brightness - 8) / 72) | round(0) }}'
action: light.turn_on
- delay: 00:00:25
mode: single
Reverse ramp from daily target to 8% over 30 minutes, then off — maintains dark period integrity, essential for photoperiod-sensitive strains to avoid hermaphroditism. Strict dark periods prevent light pollution, which can revert plants to vegetative state via phytochrome signaling.
The 72-step ramp provides high resolution, minimizing abrupt changes that could stress flowers.
alias: Growbox - Sonnenuntergang Blütephase (dynamisch)
description: Sonnenuntergang mit dimmendem Licht basierend auf Wochenfortschritt der Blütephase (bis 100 %)
triggers:
- at: '19:30:00'
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Blüte
actions:
- variables:
tage_seit_start: '{% set start = states(''input_datetime.growbox_phase_last_changed'') | as_datetime %} {% set diff = (now().timestamp() - start.timestamp()) / 86400 %} {{ diff | int }}'
start_brightness: "{% if tage_seit_start < 21 %}\n {{ (55 + (tage_seit_start / 21.0 * (100 - 55))) | round(0) }}\n{% else %}\n 100\n{% endif %}\n"
- data:
entity_id: input_number.growbox_soll_lichtwert
value: '{{ start_brightness }}'
action: input_number.set_value
- repeat:
count: 72
sequence:
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{% set i = repeat.index - 1 %} {{ (start_brightness - i * (start_brightness - 8) / 71) | round(0) }}'
action: light.turn_on
- delay: 00:00:25
- target:
entity_id: light.growbox_licht_dimmer
data: {}
action: light.turn_off
mode: single
Time → 6h 12h 18h 24h
| | | |
Keimling: 🌅───☀──────────🌇
Wachstum: 🌅────🌤─────────🌇
Blüte: 🌅──☀──🌇
Illustrates the on/off periods and sunrise/sunset transitions for each phase. Note the shorter day in flowering to simulate seasonal changes.
[Keimling & Wachstum (18h Light / 6h Dark)] Light: 06:00 ───────────────────── 00:00 Dark: 00:00 ────── 06:00 [Blüte (12h Light / 12h Dark)] Light: 08:00 ───────── 20:00 Dark: 20:00 ───────── 08:00
Note: In Keimling and Wachstum phases, plants receive 18 hours of light and 6 hours of darkness to promote vegetative growth. In Blüte, the 12/12 cycle triggers flowering, mimicking autumn day lengths. This photoperiod manipulation exploits the Skoto- and Photoperiodic responses in plants.
00:00 [Dark] ----- 06:00 [Sunrise] ----- 12:00 [Full Light] ----- 18:00 [Sunset] ----- 24:00 [Dark]
Keimling/Wachstum: ********************** (18h)
Blüte: ************ (12h, shifted)
Timeline showing light periods across phases.
In automated systems, faults like power interruptions or HA restarts can disrupt lighting. These verifications, inspired by fault-tolerant control theory, run periodically to enforce correct states, preventing prolonged deviations that could affect yield or plant health. Redundancy is key, with checks at specific times and global intervals.
From a systems engineering perspective, this implements a supervisory control layer, monitoring and correcting the primary control loops. Failure modes and effects analysis (FMEA) guided the design, prioritizing high-impact failures like light outages during peak photosynthesis hours.
Verifies and corrects to 25% if below threshold, ensuring consistent DLI during early development. The 25% is a safety buffer above the ramp target, accounting for potential dimmer inaccuracies.
alias: Growbox - Check Lichtstatus um 06:30 Uhr (Keimlingsphase)
description: 'Stellt sicher, dass das Licht in der Keimlingsphase um 06:30 Uhr auf 25 % steht. Wenn es aus ist oder zu dunkel, wird es korrekt eingeschaltet.'
triggers:
- at: 06:30:00
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Keimling
- condition: or
conditions:
- condition: state
entity_id: light.growbox_licht_dimmer
state: 'off'
- condition: template
value_template: '{% set aktuell = state_attr(''light.growbox_licht_dimmer'', ''brightness'') | int(0) %} {% set aktuell_pct = (aktuell * 100 / 255) | round(0) %} {{ aktuell_pct < 25 }}'
actions:
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: 25
action: light.turn_on
mode: single
Absolute off at midnight to enforce dark period and prevent accidental extended photoperiods that could delay flowering. This check is crucial for maintaining the nyctinastic rhythms.
alias: Growbox - Check Lichtstatus um 00:00 Uhr (Keimlingsphase)
description: ''
triggers:
- at: 00:00:00
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Keimling
- condition: state
entity_id: light.growbox_licht_dimmer
state: 'on'
actions:
- target:
entity_id: light.growbox_licht_dimmer
data: {}
action: light.turn_off
mode: single
Calculates and sets adaptive brightness based on phase duration, ensuring progressive light acclimation. Includes notification for transparency, aiding in debugging.
alias: Growbox - Check Lichtstatus um 06:30 Uhr (Wachstumsphase)
description: Sicherstellung des korrekten Lichtwertes am Morgen in der Wachstumsphase
triggers:
- at: 06:30:00
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Wachstum
- condition: template
value_template: '{% set start = states(''input_datetime.growbox_phase_last_changed'') | as_datetime %} {% set tage = ((now().timestamp() - start.timestamp()) / 86400) | int %} {% set ziel = [28 + (tage / 28 * (55 - 28)), 55] | min | round(0) %} {% set aktuell = state_attr(''light.growbox_licht_dimmer'', ''brightness'') | default(0) | int * 100 // 255 %} {{ is_state(''light.growbox_licht_dimmer'', ''off'') or aktuell < ziel }}'
actions:
- variables:
start: '{{ states(''input_datetime.growbox_phase_last_changed'') | as_datetime }}'
tage: '{{ ((now().timestamp() - start.timestamp()) / 86400) | int }}'
ziel: '{{ [28 + (tage / 28 * (55 - 28)), 55] | min | round(0) }}'
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{{ ziel }}'
action: light.turn_on
- data:
message: 'Growbox-Licht wurde um 06:30 Uhr mit {{ ziel }} % Helligkeit eingeschaltet (Tag {{ tage }} der Wachstumsphase).'
action: notify.mobile_app_DEIN_HANDY_NAME_HIER
mode: single
Absolute off at midnight to enforce dark period and prevent accidental light leaks. Light leaks as low as 0.1 µmol/m²/s can disrupt flowering in sensitive strains.
alias: Growbox - Check Lichtstatus um 00:00 Uhr (Wachstumsphase)
description: 'Falls das Licht um Mitternacht noch an ist, wird es ausgeschaltet – unabhängig vom Helligkeitswert – nur in der Wachstumsphase.'
triggers:
- at: 00:00:00
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Wachstum
- condition: state
entity_id: light.growbox_licht_dimmer
state: 'on'
actions:
- target:
entity_id: light.growbox_licht_dimmer
action: light.turn_off
mode: single
Adaptive check for flowering, scaling brightness with phase progression to optimize resin production. The threshold adjusts to match the sunrise target, ensuring full DLI achievement.
alias: Growbox - Check Lichtstatus um 08:30 Uhr (Blütephase, dynamisch)
description: ''
triggers:
- at: 08:30:00
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Blüte
- condition: template
value_template: '{% set start = states(''input_datetime.growbox_phase_last_changed'') | as_datetime %} {% set tage_seit_start = ((now().timestamp() - start.timestamp()) / 86400) | int %} {% set ziel_brightness = 100 if tage_seit_start >= 21 else (55 + (tage_seit_start / 21.0 * (100 - 55))) | round(0) %} {% set ziel_brightness_ha = (ziel_brightness * 2.55) | round(0) %} {% set current_brightness = state_attr(''light.growbox_licht_dimmer'', ''brightness'') | int(0) %} {{ is_state(''light.growbox_licht_dimmer'', ''off'') or current_brightness < ziel_brightness_ha }}'
actions:
- variables:
tage_seit_start: '{% set start = states(''input_datetime.growbox_phase_last_changed'') | as_datetime %} {% set diff = (now().timestamp() - start.timestamp()) / 86400 %} {{ diff | int }}'
ziel_brightness: "{% if tage_seit_start < 21 %}\n {{ (55 + (tage_seit_start / 21.0 * (100 - 55))) | round(0) }}\n{% else %}\n 100\n{% endif %}\n"
- target:
entity_id: light.growbox_licht_dimmer
data:
brightness_pct: '{{ ziel_brightness }}'
action: light.turn_on
mode: single
Strict enforcement of dark period start to maintain photoperiod integrity. This is especially important in flowering to prevent re-vegetation.
alias: Growbox - Check Lichtstatus um 20:00 Uhr (Blütephase)
description: ''
triggers:
- at: '20:00:00'
trigger: time
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Blüte
- condition: state
entity_id: light.growbox_licht_dimmer
state: 'on'
actions:
- target:
entity_id: light.growbox_licht_dimmer
action: light.turn_off
mode: single
Comprehensive periodic verification across all phases, ensuring system-wide light consistency and rapid recovery from faults. This global check acts as a watchdog, invoking phase-specific scripts for correction.
The 15-minute interval balances responsiveness with resource use, detecting failures within a timeframe that minimizes DLI loss (e.g., <5% daily impact).
alias: Growbox - Überprüfung Lichtstatus (alle 15 Minuten)
description: 'Prüft regelmäßig, ob der Lichtstatus korrekt ist und korrigiert ggf. automatisch.'
triggers:
- minutes: /15
trigger: time_pattern
conditions: []
actions:
- variables:
phase: '{{ states(''input_select.growbox_phase'') }}'
current_dt: '{{ as_datetime(now()) }}'
hour: '{{ current_dt.hour }}'
minute: '{{ current_dt.minute }}'
light_on: '{{ is_state(''light.growbox_licht_dimmer'', ''on'') }}'
brightness: '{{ state_attr(''light.growbox_licht_dimmer'', ''brightness'') | default(0) | int }}'
brightness_pct: '{{ (brightness * 100 / 255) | round(0) }}'
- choose:
- conditions:
- condition: template
value_template: '{{ phase == ''Keimling'' and hour >= 6 and hour < 23 and (not light_on or brightness_pct < 20) }}'
sequence:
- action: script.growbox_keimling_licht_morgens_einschalten_skript
data: {}
- conditions:
- condition: template
value_template: '{{ phase == ''Keimling'' and hour >= 23 and light_on }}'
sequence:
- action: script.growbox_keimling_licht_abends_ausschalten_skript
data: {}
- conditions:
- condition: template
value_template: '{{ phase == ''Wachstum'' and hour >= 6 and hour < 23 and (not light_on or brightness_pct < 28) }}'
sequence:
- action: script.growbox_wachstum_licht_morgens_einschalten_skript
data: {}
- conditions:
- condition: template
value_template: '{{ phase == ''Wachstum'' and hour >= 23 and light_on }}'
sequence:
- action: script.growbox_wachstum_licht_abends_ausschalten_skript
data: {}
- conditions:
- condition: template
value_template: '{{ phase == ''Blüte'' and hour >= 6 and hour < 20 and (not light_on or brightness_pct < 50) }}'
sequence:
- action: script.growbox_blute_licht_morgens_einschalten_skript
data: {}
- conditions:
- condition: template
value_template: '{{ phase == ''Blüte'' and hour >= 20 and light_on }}'
sequence:
- action: script.growbox_blute_licht_abends_ausschalten_skript
data: {}
mode: single
Start --> Check Phase --> If Keimling? --> Check Time & State --> Correct if Needed
|
--> If Wachstum? --> ...
|
--> If Blüte? --> ...
Flowchart of the global light correction logic.
Vapor Pressure Deficit (VPD) measures the driving force for transpiration — the difference between saturation vapor pressure at leaf temperature and actual vapor pressure in the air. Proper VPD control enhances calcium uptake, reduces tip burn, and prevents condensation-related pathogens. These automations use hysteresis to avoid oscillatory behavior, with phase-specific targets derived from horticultural research (e.g., Bugbee & Monje, 1992).
Hysteresis prevents chattering: Fan state changes only when VPD crosses thresholds, with delays to filter noise. Periodic checks ensure long-term stability, embodying proportional control principles.
Optimal VPD ranges: Low for seedlings to maintain humidity, higher for flowering to promote resin. Deviations can lead to 10-20% yield loss due to impaired nutrient transport.
VPD (kPa)
High Threshold ---- ON (Fan Off to increase humidity)
|
| Hysteresis Band
|
Low Threshold ----- OFF (Fan On to decrease humidity)
Diagram showing hysteresis to prevent rapid switching.
Gentle hysteresis (0.45–0.6 kPa) with 2-minute checks — protects fragile seedlings from excessive evaporation. Delays ensure changes are sustained, avoiding unnecessary fan cycles.
alias: Growbox - Lüftersteuerung Keimlingsphase (VPD-basiert)
description: 'Steuerung Lüfter basierend auf VPD mit Verzögerung bei Änderung und direkter Korrektur alle 2 Minuten, nur in Keimlingsphase. Hysterese: 0,45–0,6 kPa'
triggers:
- event: start
trigger: homeassistant
- entity_id: sensor.vpd
below: 0.45
id: vpd_low
trigger: numeric_state
- entity_id: sensor.vpd
above: 0.6
id: vpd_high
trigger: numeric_state
- minutes: /2
id: periodic_check
trigger: time_pattern
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Keimling
actions:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.vpd
below: 0.45
sequence:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.id != ''periodic_check'' }}'
sequence:
- delay: 00:00:30
- target:
entity_id: switch.growbox_abluft_switch_239980
action: switch.turn_on
- conditions:
- condition: numeric_state
entity_id: sensor.vpd
above: 0.6
sequence:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.id != ''periodic_check'' }}'
sequence:
- delay: 00:00:30
- target:
entity_id: switch.growbox_abluft_switch_239980
action: switch.turn_off
mode: single
Wider hysteresis (0.85–1.15 kPa) with 1-minute delays — supports vigorous growth while ignoring transient fluctuations. This range promotes transpiration without water stress.
alias: Growbox - Lüftersteuerung Wachstumsphase (VPD-basiert, Profi)
description: 'Steuerung Abluft-Lüfter basierend auf VPD (0,85–1,15 kPa) mit sanftem Takten. Nur Wachstumsphase. Kurzzeitige Peaks werden ignoriert.'
triggers:
- event: start
trigger: homeassistant
- entity_id: sensor.vpd
below: 0.85
for: 00:01:00
id: vpd_low
trigger: numeric_state
- entity_id: sensor.vpd
above: 1.15
for: 00:01:00
id: vpd_high
trigger: numeric_state
- minutes: /5
id: periodic_check
trigger: time_pattern
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Wachstum
actions:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.vpd
below: 0.85
sequence:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.id != ''periodic_check'' }}'
sequence:
- delay: 00:01:00
- target:
entity_id: switch.growbox_abluft_switch_239980
action: switch.turn_on
- conditions:
- condition: numeric_state
entity_id: sensor.vpd
above: 1.15
sequence:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.id != ''periodic_check'' }}'
sequence:
- delay: 00:01:00
- target:
entity_id: switch.growbox_abluft_switch_239980
action: switch.turn_off
mode: single
Higher VPD (1.05–1.35 kPa) for resin production, with 10-minute checks and delays for stability. This encourages terpene volatilization while controlling humidity to prevent botrytis.
alias: Growbox - Lüftersteuerung Blütephase (VPD-basiert)
description: 'Steuerung Lüfter basierend auf VPD mit Verzögerung bei Änderung und direkter Korrektur alle 10 Minuten, nur in Blütephase aktiv. Hysterese 1,05 – 1,35 kPa'
triggers:
- event: start
trigger: homeassistant
- entity_id: sensor.vpd
below: 1.05
for: 00:01:00
id: vpd_low
trigger: numeric_state
- entity_id: sensor.vpd
above: 1.35
for: 00:01:00
id: vpd_high
trigger: numeric_state
- minutes: /10
id: periodic_check
trigger: time_pattern
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Blüte
actions:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.vpd
below: 1.05
sequence:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.id != ''periodic_check'' }}'
sequence:
- delay: 00:01:00
- target:
entity_id: switch.growbox_abluft_switch_239980
action: switch.turn_on
- conditions:
- condition: numeric_state
entity_id: sensor.vpd
above: 1.35
sequence:
- choose:
- conditions:
- condition: template
value_template: '{{ trigger.id != ''periodic_check'' }}'
sequence:
- delay: 00:01:00
- target:
entity_id: switch.growbox_abluft_switch_239980
action: switch.turn_off
mode: single
| Phase | Low Threshold (kPa) | High Threshold (kPa) | Benefit |
|---|---|---|---|
| Keimling | 0.45 | 0.6 | High humidity for germination |
| Wachstum | 0.85 | 1.15 | Balanced transpiration |
| Blüte | 1.05 | 1.35 | Resin enhancement |
Proper air circulation strengthens stems, evens CO₂ distribution, and prevents microclimates. Phase-specific cycling mimics natural wind, reducing disease risk while conserving energy. Airflow also aids in heat dissipation from LEDs, maintaining leaf temperatures.
Cycles are designed based on wind simulation studies (e.g., Kitaya et al., 2003), where intermittent airflow improves gas exchange without desiccation.
2 min on / 28 min off — minimal disturbance for young plants. This low-duty cycle prevents over-drying of soil media.
alias: Growbox - Umluft Ventilator Keimlingsphase Zyklus sanft
description: Lüfter läuft 2 Minuten an, 28 Minuten aus in Keimlingsphase
triggers:
- minutes: /1
trigger: time_pattern
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Keimling
actions:
- choose:
- conditions:
- condition: template
value_template: '{{ (now().minute % 30) < 2 }}'
sequence:
- target:
entity_id: switch.growbox_umluft_outlet
action: switch.turn_on
- conditions:
- condition: template
value_template: '{{ (now().minute % 30) >= 2 }}'
sequence:
- target:
entity_id: switch.growbox_umluft_outlet
action: switch.turn_off
mode: single
30 min on / 30 min off — promotes sturdy growth. Equal cycles provide consistent airflow, simulating outdoor breezes.
alias: Growbox - Umluft Ventilator Wachstumsphase Zyklus 30 Min an, 30 Min aus
description: Umluft läuft 30 Minuten an, 30 Minuten aus – in Wachstumsphase
triggers:
- minutes: '*'
trigger: time_pattern
- event: start
trigger: homeassistant
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Wachstum
actions:
- choose:
- conditions:
- condition: template
value_template: '{{ now().minute % 60 < 30 }}'
sequence:
- target:
entity_id: switch.growbox_umluft_outlet
action: switch.turn_on
- conditions:
- condition: template
value_template: '{{ now().minute % 60 >= 30 }}'
sequence:
- target:
entity_id: switch.growbox_umluft_outlet
action: switch.turn_off
mode: single
Always on — critical for CO₂ exchange and mold prevention during dense flowering. Continuous flow ensures uniform humidity gradients.
alias: Growbox - Umluft Ventilator Blütephase Dauerbetrieb
description: 'Prüft alle 10 Minuten (und beim HA-Start), ob der Umluft-Ventilator in der Blütephase an ist – schaltet ihn ggf. ein.'
triggers:
- minutes: /10
trigger: time_pattern
- event: start
trigger: homeassistant
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Blüte
- condition: state
entity_id: switch.growbox_umluft_outlet
state: 'off'
actions:
- target:
entity_id: switch.growbox_umluft_outlet
action: switch.turn_on
mode: single
Keimling: [2 min ON] --- [28 min OFF] --- [2 min ON] --- ...
Wachstum: [30 min ON] ------------------ [30 min OFF] ------------------
Blüte: [Always ON] ------------------------------------------------------
Time (min): 0 30 60 90
Note: Cycles adapt to phase needs — gentle for seedlings, balanced for veg, constant for bloom to support resin development. Duty cycle increases with plant density.
ON |** ** ** (Keimling)
|
OFF | ******
+--------- Time
ON |**************** **************** (Wachstum)
|
OFF | ****************
+---------------------------------- Time
ON |**************************************** (Blüte)
+---------------------------------- Time
Waveforms representing fan states over time.
Phase transitions are pivotal in photoperiodic crops like cannabis, triggering hormonal cascades (e.g., gibberellins for veg, florigen for bloom). These automations handle switches with timestamps for adaptive control and full resets for safety. Transitions are atomic to prevent intermediate states.
The logic ensures continuity: Upon switch, fans are set to phase-appropriate speeds, and timestamps enable time-based scaling of parameters.
Records the exact time of phase change for duration-based calculations, enabling time-dependent adaptations. This is essential for progressive ramps, using UNIX timestamps for precision.
alias: Growbox Phase Wechsel Zeit aktualisieren
description: Setzt input_datetime.growbox_phase_last_changed beim Ändern der Growbox Phase
triggers:
- entity_id: input_select.growbox_phase
trigger: state
conditions: []
actions:
- target:
entity_id: input_datetime.growbox_phase_last_changed
data:
timestamp: '{{ now().timestamp() }}'
action: input_datetime.set_datetime
mode: single
Low speed for gentle air movement in early stages. This minimizes evaporation from fragile roots.
alias: Growbox - Lüfter auf 25 % bei Keimlingsphase
description: 'Setzt den Lüfter auf 25 %, wenn in die Keimlingsphase gewechselt wird.'
triggers:
- entity_id: input_select.growbox_phase
to: Keimling
trigger: state
conditions: []
actions:
- target:
entity_id: fan.growbox_abluft_fan_239980
data:
percentage: 25
action: fan.set_percentage
mode: single
Increased airflow for growing canopy. Supports higher transpiration rates as leaves expand.
alias: Growbox - Lüfter auf 35 % bei Wachstumsphase
description: 'Setzt den Lüfter auf 35 %, wenn in die Wachstumsphase gewechselt wird, um die Luftfeuchtigkeit besser zu regulieren.'
triggers:
- entity_id: input_select.growbox_phase
to: Wachstum
trigger: state
conditions: []
actions:
- target:
entity_id: fan.growbox_abluft_fan_239980
data:
percentage: 35
action: fan.set_percentage
mode: single
Higher speed to support resin production and prevent bud rot. Enhances air exchange during high metabolic activity.
alias: Growbox - Lüfter auf 40 % bei Blütephase
description: 'Setzt den Lüfter auf 40 %, wenn in die Blütephase gewechselt wird.'
triggers:
- entity_id: input_select.growbox_phase
to: Blüte
trigger: state
conditions: []
actions:
- target:
entity_id: fan.growbox_abluft_fan_239980
data:
percentage: 40
action: fan.set_percentage
mode: single
Phase Change --> Update Timestamp --> Set Fan Speed --> Activate Automations
Simple flow of phase switch logic.
Setting the phase to "Ausgeschaltet" triggers a full system halt, preventing unintended operation during maintenance or downtime. This aligns with safety protocols in automated systems, ensuring zero energy waste and no light leaks. It's equivalent to a kill switch in industrial controls.
In terms of risk management, this mode reduces fire hazards from unattended equipment and allows for safe hardware interventions.
alias: Growbox - Alles ausschalten bei Phase "Ausgeschaltet"
description: Schaltet alle relevanten Geräte aus, wenn Phase "Ausgeschaltet" aktiv ist
triggers:
- entity_id: input_select.growbox_phase
to: Ausgeschaltet
trigger: state
conditions: []
actions:
- target:
entity_id:
- light.growbox_licht_dimmer
- light.growbox_lampe_outlet
- switch.growbox_abluft_switch_239980
- switch.grow_box_abluft_outlet
- fan.growbox_umluft_outlet
action: homeassistant.turn_off
mode: single
alias: Growbox - Beim Start prüfen ob "Ausgeschaltet"
description: Setzt alle Geräte auf AUS, falls beim Start die Phase "Ausgeschaltet" ist
triggers:
- event: start
trigger: homeassistant
conditions:
- condition: state
entity_id: input_select.growbox_phase
state: Ausgeschaltet
actions:
- target:
entity_id:
- light.growbox_licht_dimmer
- light.growbox_lampe_outlet
- switch.growbox_abluft_switch_239980
- switch.grow_box_abluft_outlet
- fan.growbox_umluft_outlet
action: homeassistant.turn_off
mode: single
System reliability is paramount in controlled environments. These automations implement multi-layer monitoring (immediate alerts, persistent logging, daily summaries), drawing from fault detection theory to achieve high availability (>99%). Monitoring covers connectivity, state consistency, and recovery.
Using state transitions and timed reminders, the system employs event-driven and polling strategies for comprehensive coverage. This hybrid approach minimizes latency in detection while conserving resources.
Triggers on unavailability with fallback checks for light state — critical to prevent silent failures during active phases. Includes phase-aware logic to determine if light should be on.
alias: GrowBox Gerät nicht verfügbar oder Licht aus wenn an sein soll - Benachrichtigung mit Ausfallzeit
description: Benachrichtigung bei unavailable + Licht-soll-an-Prüfung
triggers:
- entity_id:
- switch.growbox_lampe_outlet
- light.growbox_licht_dimmer
- switch.growbox_abluft_switch_239980
- switch.grow_box_abluft_outlet
- fan.growbox_umluft_outlet
to: unavailable
trigger: state
conditions:
- condition: template
value_template: '{{ trigger.from_state.state != ''unavailable'' }}'
actions:
- variables:
entity: '{{ trigger.entity_id }}'
friendly_name: '{{ state_attr(trigger.entity_id, ''friendly_name'') or trigger.entity_id }}'
growbox_phase: '{{ states(''input_select.growbox_phase'') }}'
jetzt: '{{ now().strftime(''%H:%M'') }}'
licht_state: '{{ states(''light.growbox_licht_dimmer'') }}'
licht_soll_an: "{% set phase = growbox_phase %} {% set zeit = jetzt %} {% if phase == 'Keimling' %}\n {{ zeit >= '06:00' and zeit < '23:30' }}\n{% elif phase == 'Wachstum' %}\n {{ zeit >= '06:00' and zeit < '23:30' }}\n{% elif phase == 'Blüte' %}\n {{ zeit >= '06:00' and zeit < '20:00' }}\n{% else %}\n false\n{% endif %}\n"
- choose:
- conditions:
- condition: template
value_template: '{% set helper = ''input_datetime.'' + entity.split(''.'')[-1] + ''_ausfall_start'' %} {{ (states(helper) == ''unknown'' or states(helper) == '''') and (trigger.to_state.state == ''unavailable'') }}'
sequence:
- target:
entity_id: input_datetime.{{ entity.split('.')[-1] }}_ausfall_start
data:
datetime: '{{ now().strftime(''%Y-%m-%d %H:%M:%S'') }}'
action: input_datetime.set_datetime
- data:
title: "\U0001F6A8 GrowBox Gerät ausgefallen!"
message: 'Gerät {{ friendly_name }} ({{ entity }}) ist seit {{ now().strftime(''%Y-%m-%d %H:%M:%S'') }} nicht erreichbar (unavailable). Bitte prüfe die Verbindung!'
action: notify.mobile_app_iphone_17_randy
- data:
title: "\U0001F6A8 GrowBox Gerät ausgefallen!"
message: 'Gerät {{ friendly_name }} ({{ entity }}) ist seit {{ now().strftime(''%Y-%m-%d %H:%M:%S'') }} nicht erreichbar (unavailable). Bitte prüfe die Verbindung!'
action: notify.mobile_app_iphone_von_jessica
- conditions:
- condition: template
value_template: '{{ entity == ''light.growbox_licht_dimmer'' and licht_soll_an and licht_state == ''off'' }}'
sequence:
- data:
title: ⚠️ GrowBox Licht ist aus, sollte aber an sein!
message: 'Das Licht ist aktuell aus, obwohl die Phase "{{ growbox_phase }}" und die Uhrzeit {{ jetzt }} ein eingeschaltetes Licht erwarten. Bitte prüfen!'
action: notify.mobile_app_iphone_17_randy
- data:
title: ⚠️ GrowBox Licht ist aus, sollte aber an sein!
message: 'Das Licht ist aktuell aus, obwohl die Phase "{{ growbox_phase }}" und die Uhrzeit {{ jetzt }} ein eingeschaltetes Licht erwarten. Bitte prüfen!'
action: notify.mobile_app_iphone_von_jessica
mode: single
Persistent notifications for prolonged outages, with aggregated device lists for efficiency. Reminders start after 30 minutes to avoid alert fatigue.
alias: GrowBox Gerät Ausfall Erinnerung (alle 5 Minuten)
description: Erinnerung, wenn Geräte seit über 30 Minuten ausgefallen sind, mit Liste der betroffenen Geräte.
triggers:
- minutes: /5
trigger: time_pattern
conditions:
- condition: or
conditions:
- condition: template
value_template: "{% set start = states('input_datetime.growbox_lampe_outlet_ausfall_start') %} {% if start in ['unknown', ''] %}\n false\n{% else %}\n {{ (as_timestamp(now()) - as_timestamp(start)) > 1800 }}\n{% endif %}\n"
- condition: template
value_template: "{% set start = states('input_datetime.growbox_licht_dimmer_ausfall_start') %} {% if start in ['unknown', ''] %}\n false\n{% else %}\n {{ (as_timestamp(now()) - as_timestamp(start)) > 1800 }}\n{% endif %}\n"
- condition: or
conditions:
- condition: state
entity_id: light.growbox_lampe_outlet
state: unavailable
- condition: state
entity_id: light.growbox_licht_dimmer
state: unavailable
- condition: state
entity_id: switch.growbox_abluft_switch_239980
state: unavailable
- condition: state
entity_id: switch.grow_box_abluft_outlet
state: unavailable
- condition: state
entity_id: fan.growbox_umluft_outlet
state: unavailable
actions:
- variables:
failed_devices: "{{ [\n states.light.growbox_lampe_outlet,\n states.light.growbox_licht_dimmer,\n states.switch.growbox_abluft_switch_239980,\n states.switch.grow_box_abluft_outlet,\n states.fan.growbox_umluft_outlet\n] | selectattr('state', 'eq', 'unavailable') | map(attribute='attributes.friendly_name') | list | join(', ') }}\n"
- data:
title: '⏰ Erinnerung: GrowBox Gerät(e) ausgefallen'
message: 'Folgende GrowBox Geräte sind seit über 30 Minuten nicht erreichbar: {{ failed_devices }}. Bitte Verbindung prüfen!'
action: notify.mobile_app_iphone_17_randy
- data:
title: '⏰ Erinnerung: GrowBox Gerät(e) ausgefallen'
message: 'Folgende GrowBox Geräte sind seit über 30 Minuten nicht erreichbar: {{ failed_devices }}. Bitte Verbindung prüfen!'
action: notify.mobile_app_iphone_von_jessica
mode: single
Alerts on restoration, closing the feedback loop for system monitoring. This positive reinforcement encourages prompt maintenance.
alias: GrowBox Gerät wieder verfügbar - Benachrichtigung
description: Benachrichtigt, wenn ein GrowBox Gerät wieder erreichbar ist.
triggers:
- entity_id:
- switch.growbox_lampe_outlet
- light.growbox_licht_dimmer
- switch.growbox_abluft_switch_239980
- switch.grow_box_abluft_outlet
- fan.growbox_umluft_outlet
from: unavailable
trigger: state
conditions: []
actions:
- variables:
entity: '{{ trigger.entity_id }}'
friendly_name: '{{ state_attr(trigger.entity_id, ''friendly_name'') or trigger.entity_id }}'
now_time: '{{ now().strftime(''%Y-%m-%d %H:%M:%S'') }}'
- data:
title: ✅ GrowBox Gerät wieder erreichbar
message: 'Gerät {{ friendly_name }} ({{ entity }}) ist seit {{ now_time }} wieder verfügbar.'
action: notify.mobile_app_iphone_17_randy
- data:
title: ✅ GrowBox Gerät wieder erreichbar
message: 'Gerät {{ friendly_name }} ({{ entity }}) ist seit {{ now_time }} wieder verfügbar.'
action: notify.mobile_app_iphone_von_jessica
mode: queued
Appends failures for chronological tracking, facilitating post-cycle analysis. Logs are human-readable for easy review.
alias: GrowBox Gerät Ausfall - ins Tageslog schreiben
description: Trägt Geräteausfall in das Tageslog ein.
triggers:
- entity_id:
- switch.growbox_lampe_outlet
- light.growbox_licht_dimmer
- switch.growbox_abluft_switch_239980
- switch.grow_box_abluft_outlet
- fan.growbox_umluft_outlet
to: unavailable
from:
trigger: state
conditions: []
actions:
- variables:
logline: '{{ as_datetime(now()).strftime(''%H:%M'') }} - {{ state_attr(trigger.entity_id, ''friendly_name'') or trigger.entity_id }} ist nicht erreichbar.'
- data:
entity_id: input_text.growbox_tagesausfall_log
value: '{{ states(''input_text.growbox_tagesausfall_log'') + ''\n'' + logline }}'
action: input_text.set_value
mode: queued
Compiles and sends outage reports, resetting the log for the next day — enables trend analysis over cycles. Summaries can be used for reliability metrics like MTBF (Mean Time Between Failures).
alias: GrowBox Tageszusammenfassung Ausfälle
description: Sendet eine Übersicht aller Geräteausfälle um 20:00 Uhr.
triggers:
- at: '20:00:00'
trigger: time
conditions:
- condition: template
value_template: '{{ states(''input_text.growbox_tagesausfall_log'') | length > 5 }}'
actions:
- data:
title: "\U0001F4CB GrowBox Tageszusammenfassung"
message: 'Geräteausfälle heute: {{ states(''input_text.growbox_tagesausfall_log'') }}'
action: notify.mobile_app_iphone_17_randy
- data:
title: "\U0001F4CB GrowBox Tageszusammenfassung"
message: 'Geräteausfälle heute: {{ states(''input_text.growbox_tagesausfall_log'') }}'
action: notify.mobile_app_iphone_von_jessica
- target:
entity_id: input_text.growbox_tagesausfall_log
data:
value: ''
action: input_text.set_value
mode: single
Immediate Alert --> Persistent Reminder --> Daily Summary --> Log Reset
Layers of monitoring for escalating response.
Automation transforms empirical horticulture into a data-driven science. Benefits include:
This suite represents a holistic approach, integrating photobiology, climatology, and control engineering for superior outcomes. Future extensions could include AI for anomaly prediction or integration with weather APIs for ambient adjustments.